This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to configure the UARTE0 correct?

Hi all

I'm struggling with the easyDMA UART of nrf52. I've got a preview nrf52-DK here where I wanted to make a simple example with the following code but I never reach the ENDRX event even if I send 20 or more bytes to the DK (pin 8). Also in debug mode I can't see that any byte reaches the rxbuffer.

Do you guys see why is that? What did I make wrong in the initiation?

Thank you all in advance for your support!

#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "nrf_delay.h"
#include "nrf_gpio.h"
#include "boards.h"
#include "nrf_uarte.h"

const uint8_t leds_list[LEDS_NUMBER] = LEDS_LIST;

void UARTE0_UART0_IRQHandler(){

	if(NRF_UARTE0->EVENTS_ENDRX){
		LEDS_INVERT(1 << leds_list[3]);
	}

}


int main(void)
{

	uint8_t txBuffer[20] = {0};
	uint8_t rxBuffer[20] = {0};

    NRF_UARTE0->BAUDRATE = NRF_UARTE_BAUDRATE_9600;
    NRF_UARTE0->PSEL.TXD = TX_PIN_NUMBER;
    NRF_UARTE0->PSEL.RXD = RX_PIN_NUMBER;
    NRF_UARTE0->CONFIG = NRF_UARTE_HWFC_DISABLED;
    NRF_UARTE0->ENABLE = (UARTE_ENABLE_ENABLE_Enabled << UARTE_ENABLE_ENABLE_Pos);

    NRF_UARTE0->TXD.PTR = (uint32_t)((uint8_t *) txBuffer);
    NRF_UARTE0->TXD.MAXCNT = sizeof(txBuffer);
    NRF_UARTE0->TASKS_STARTTX = 0;

    NRF_UARTE0->RXD.PTR = (uint32_t)((uint8_t *) rxBuffer);
    NRF_UARTE0->RXD.MAXCNT = sizeof(rxBuffer);
    NRF_UARTE0->TASKS_STARTRX = 1;


    NRF_UARTE0->INTENCLR = 0xFFFFFFFF;
    NRF_UARTE0->INTENSET = NRF_UARTE_INT_ENDRX_MASK;

    NVIC_ClearPendingIRQ(UARTE0_UART0_IRQn);
    NVIC_SetPriority(UARTE0_UART0_IRQn, 1);
    NVIC_EnableIRQ(UARTE0_UART0_IRQn);



    // Configure LED-pins as outputs.
    LEDS_CONFIGURE(LEDS_MASK);
    if(NRF_UARTE0->EVENTS_RXSTARTED){
    	LEDS_INVERT(1 << leds_list[1]);
    }


    while (true)
    {


    }
}
  • Hi, ran the exact same code on the preview kit and did receive the EVENTS_ENDRX with the correct data. Have you checked if tx works?

    Description of my setup:

    • on board Segger chip used as usb<->uart bridge
    • Terra term (serial terminal) on windows 7

    Just a note, generally you should have static allocation of your buffers, Although it shouldn't be a problem in this example.

    Attachment:

  • Agreed with static allocation. It's very important. If you were to move this setup code out of main and into its own function, the buffers will need to be declared static (or allocated with alloc()). If this is not done, then the buffers will not exist and the DMA will potentially overwrite the memory of some other data in the system.

  • Thank you both for you're response and you're hint with the static allocation of the buffers!

    Unfortunately the whole system still doesn't work for me. I have the DK connected to my PC and I see the COM Port in my device manger. I'm also able to connect the COM port to a terminal app (tera term and hterm) but I can't send or receive any data (I also tested with different PC's) :-(.

    Did the LED[3] switch off in your testsystem? Are you also using Pin 6 (TX) and 8 (RX)? Is there maybe a special driver I have to install? Or did you have to make any special configuration for the Segger chip? As IDE I'm using eclipse with gcc.

    Here's the updated code with TX and static buffers:

    #include <stdbool.h>
    #include <stdint.h>
    #include <string.h>
    #include "nrf_delay.h"
    #include "nrf_gpio.h"
    #include "boards.h"
    #include "nrf_uarte.h"
    
    const uint8_t leds_list[LEDS_NUMBER] = LEDS_LIST;
    
    void UARTE0_UART0_IRQHandler(){
    
        if(NRF_UARTE0->EVENTS_ENDRX){
            LEDS_INVERT(1 << leds_list[3]);
        }
    
    }
    
    
    int main(void)
    {
    
    	static uint8_t txBuffer[5] = {'h','e','l','l','o',};
    	static uint8_t rxBuffer[20] = {0};
    
        NRF_UARTE0->BAUDRATE = NRF_UARTE_BAUDRATE_9600;
        NRF_UARTE0->PSEL.TXD = TX_PIN_NUMBER;
        NRF_UARTE0->PSEL.RXD = RX_PIN_NUMBER;
        NRF_UARTE0->CONFIG = NRF_UARTE_HWFC_DISABLED;
        NRF_UARTE0->ENABLE = (UARTE_ENABLE_ENABLE_Enabled << UARTE_ENABLE_ENABLE_Pos);
    
        NRF_UARTE0->TXD.PTR = (uint32_t)((uint8_t *) txBuffer);
        NRF_UARTE0->TXD.MAXCNT = sizeof(txBuffer);
        NRF_UARTE0->TASKS_STARTTX = 0;
    
        NRF_UARTE0->RXD.PTR = (uint32_t)((uint8_t *) rxBuffer);
        NRF_UARTE0->RXD.MAXCNT = sizeof(rxBuffer);
        NRF_UARTE0->TASKS_STARTRX = 1;
    
    
        NRF_UARTE0->INTENCLR = 0xFFFFFFFF;
        NRF_UARTE0->INTENSET = NRF_UARTE_INT_ENDRX_MASK;
    
        NVIC_ClearPendingIRQ(UARTE0_UART0_IRQn);
        NVIC_SetPriority(UARTE0_UART0_IRQn, 1);
        NVIC_EnableIRQ(UARTE0_UART0_IRQn);
    
    
    
        // Configure LED-pins as outputs.
        LEDS_CONFIGURE(LEDS_MASK);
        if(NRF_UARTE0->EVENTS_RXSTARTED){
            LEDS_INVERT(1 << leds_list[1]);
        }
    
    
        while (true)
        {
        	NRF_UARTE0->TASKS_STARTTX;
        }
    }
    
  • Hi, tried with GCC as well with the same result. LED was also inverted on EVENTS_ENDRX event. Are you using Eclipse managed make or using the SDK makefiles to build this project? Reason I ask is that there can be potentially be a problem with the build settings if Makefile is generated by Eclipse.

    Please try with the default UART example using Make outside of Eclipse just to see if UART is working at all. Building example applications in the command line is explained in the "before we begin" section here in case you haven't done it before.

  • Hi, I'm using the SDK makefiles in the blinky example. I have set up the whole IDE with the tutorial you linked in your comment and the UART example there is working (the only thing not working there was the "jlink" command maybe this is the problem?). I have also setup the UART example to eclipse according to the tutorial (-> only had to edit the "CFLAGS"-command in the makefile and add some properties) and it worked perfectly fine.

    The Makefile (from the blinky example) I'm using in eclipse looks like following. Am I missing something here?

    PROJECT_NAME := blinky_blank_pca10036
    
    export OUTPUT_FILENAME
    #MAKEFILE_NAME := $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
    MAKEFILE_NAME := $(MAKEFILE_LIST)
    MAKEFILE_DIR := $(dir $(MAKEFILE_NAME) ) 
    
    TEMPLATE_PATH = ../../../../../../components/toolchain/gcc
    ifeq ($(OS),Windows_NT)
    include $(TEMPLATE_PATH)/Makefile.windows
    else
    include $(TEMPLATE_PATH)/Makefile.posix
    endif
    
    MK := mkdir
    RM := rm -rf
    
    #echo suspend
    ifeq ("$(VERBOSE)","1")
    NO_ECHO := 
    else
    NO_ECHO := @
    endif
    
    # Toolchain commands
    CC              := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-gcc'
    AS              := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-as'
    AR              := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ar' -r
    LD              := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ld'
    NM              := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-nm'
    OBJDUMP         := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objdump'
    OBJCOPY         := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objcopy'
    SIZE            := '$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-size'
    
    #function for removing duplicates in a list
    remduplicates = $(strip $(if $1,$(firstword $1) $(call remduplicates,$(filter-out $(firstword $1),$1))))
    
    #source common to all targets
    C_SOURCE_FILES += \
    ../../../../../../components/toolchain/system_nrf52.c \
    ../../../main.c \
    ../../../../../../components/drivers_nrf/delay/nrf_delay.c \
    
    #assembly files common to all targets
    ASM_SOURCE_FILES  = ../../../../../../components/toolchain/gcc/gcc_startup_nrf52.s
    
    #includes common to all targets
    INC_PATHS  = -I../../../../../../components/toolchain/gcc
    INC_PATHS += -I../../../../../../components/toolchain
    INC_PATHS += -I../../..
    INC_PATHS += -I../../../../../bsp
    INC_PATHS += -I../../../../../../components/device
    INC_PATHS += -I../../../../../../components/drivers_nrf/delay
    INC_PATHS += -I../../../../../../components/drivers_nrf/hal
    
    OBJECT_DIRECTORY = _build
    LISTING_DIRECTORY = $(OBJECT_DIRECTORY)
    OUTPUT_BINARY_DIRECTORY = $(OBJECT_DIRECTORY)
    
    # Sorting removes duplicates
    BUILD_DIRECTORIES := $(sort $(OBJECT_DIRECTORY) $(OUTPUT_BINARY_DIRECTORY) $(LISTING_DIRECTORY) )
    
    #flags common to all targets
    CFLAGS  = -DCONFIG_GPIO_AS_PINRESET
    CFLAGS += -DBOARD_PCA10036
    CFLAGS += -DNRF52
    CFLAGS += -DBSP_DEFINES_ONLY
    CFLAGS += -mcpu=cortex-m4
    CFLAGS += -mthumb -mabi=aapcs --std=gnu99
    CFLAGS += -Wall -Werror -O0 -g3
    CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
    # keep every function in separate section. This will allow linker to dump unused functions
    CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing
    CFLAGS += -fno-builtin --short-enums
    
    # keep every function in separate section. This will allow linker to dump unused functions
    LDFLAGS += -Xlinker -Map=$(LISTING_DIRECTORY)/$(OUTPUT_FILENAME).map
    LDFLAGS += -mthumb -mabi=aapcs -L $(TEMPLATE_PATH) -T$(LINKER_SCRIPT)
    LDFLAGS += -mcpu=cortex-m4
    LDFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
    # let linker to dump unused sections
    LDFLAGS += -Wl,--gc-sections
    # use newlib in nano version
    LDFLAGS += --specs=nano.specs -lc -lnosys
    
    # Assembler flags
    ASMFLAGS += -x assembler-with-cpp
    ASMFLAGS += -DCONFIG_GPIO_AS_PINRESET
    ASMFLAGS += -DBOARD_PCA10036
    ASMFLAGS += -DNRF52
    ASMFLAGS += -DBSP_DEFINES_ONLY
    #default target - first one defined
    default: clean nrf52832_xxaa
    
    #building all targets
    all: clean
    	$(NO_ECHO)$(MAKE) -f $(MAKEFILE_NAME) -C $(MAKEFILE_DIR) -e cleanobj
    	$(NO_ECHO)$(MAKE) -f $(MAKEFILE_NAME) -C $(MAKEFILE_DIR) -e nrf52832_xxaa 
    
    #target for printing all targets
    help:
    	@echo following targets are available:
    	@echo 	nrf52832_xxaa
    
    
    C_SOURCE_FILE_NAMES = $(notdir $(C_SOURCE_FILES))
    C_PATHS = $(call remduplicates, $(dir $(C_SOURCE_FILES) ) )
    C_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(C_SOURCE_FILE_NAMES:.c=.o) )
    
    ASM_SOURCE_FILE_NAMES = $(notdir $(ASM_SOURCE_FILES))
    ASM_PATHS = $(call remduplicates, $(dir $(ASM_SOURCE_FILES) ))
    ASM_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(ASM_SOURCE_FILE_NAMES:.s=.o) )
    
    vpath %.c $(C_PATHS)
    vpath %.s $(ASM_PATHS)
    
    OBJECTS = $(C_OBJECTS) $(ASM_OBJECTS)
    
    nrf52832_xxaa: OUTPUT_FILENAME := nrf52832_xxaa
    nrf52832_xxaa: LINKER_SCRIPT=blinky_gcc_nrf52.ld
    nrf52832_xxaa: $(BUILD_DIRECTORIES) $(OBJECTS)
    	@echo Linking target: $(OUTPUT_FILENAME).out
    	$(NO_ECHO)$(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
    	$(NO_ECHO)$(MAKE) -f $(MAKEFILE_NAME) -C $(MAKEFILE_DIR) -e finalize
    
    ## Create build directories
    $(BUILD_DIRECTORIES):
    	echo $(MAKEFILE_NAME)
    	$(MK) $@
    
    # Create objects from C SRC files
    $(OBJECT_DIRECTORY)/%.o: %.c
    	@echo Compiling file: $(notdir $<)
    	$(NO_ECHO)$(CC) $(CFLAGS) $(INC_PATHS) -c -o $@ $<
    
    # Assemble files
    $(OBJECT_DIRECTORY)/%.o: %.s
    	@echo Compiling file: $(notdir $<)
    	$(NO_ECHO)$(CC) $(ASMFLAGS) $(INC_PATHS) -c -o $@ $<
    
    
    # Link
    $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out: $(BUILD_DIRECTORIES) $(OBJECTS)
    	@echo Linking target: $(OUTPUT_FILENAME).out
    	$(NO_ECHO)$(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
    
    
    ## Create binary .bin file from the .out file
    $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
    	@echo Preparing: $(OUTPUT_FILENAME).bin
    	$(NO_ECHO)$(OBJCOPY) -O binary $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin
    
    ## Create binary .hex file from the .out file
    $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
    	@echo Preparing: $(OUTPUT_FILENAME).hex
    	$(NO_ECHO)$(OBJCOPY) -O ihex $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex
    
    finalize: genbin genhex echosize
    
    genbin:
    	@echo Preparing: $(OUTPUT_FILENAME).bin
    	$(NO_ECHO)$(OBJCOPY) -O binary $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin
    
    ## Create binary .hex file from the .out file
    genhex: 
    	@echo Preparing: $(OUTPUT_FILENAME).hex
    	$(NO_ECHO)$(OBJCOPY) -O ihex $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex
    
    echosize:
    	-@echo ''
    	$(NO_ECHO)$(SIZE) $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
    	-@echo ''
    
    clean:
    	$(RM) $(BUILD_DIRECTORIES)
    
    cleanobj:
    	$(RM) $(BUILD_DIRECTORIES)/*.o
    
    flash: $(MAKECMDGOALS)
    	@echo Flashing: $(OUTPUT_BINARY_DIRECTORY)/$<.hex
    	nrfjprog --erasepage 0x0-0x80000 -f nrf52
    	nrfjprog --program $(OUTPUT_BINARY_DIRECTORY)/$<.hex -f nrf52
    	nrfjprog --reset
    
    ## Flash softdevice
    
Related