EFM32 Giant Gecko USART Problems

I have the development board mentioned in this website: https://eewiki.net/display/microcontroller/Getting+Started+with+EFM32+Giant+Gecko+ARM+Cortex-M3. I copied the UART example from there and integrated it with a FreeRTOS demo included in Simplicity Studio. What I have is a single task running that outputs bytes on USART1. Everything works fine until I add a call to vTaskDelay(). The last two bytes of my output string gets lost or corrupted, not in memory, but on the output line. I have tried different baudrates, different strings, different delay values, and the results are all similar. Here is the task: ~~~ static void UartTest(void *pParameters) {
int i, j;
const char introString[] = "nrEFM32 GG Benchmark test started!nrnr";
const char testString[40] = "abcdefghijnr";
const portTickType delay = pdMS_TO_TICKS(1000);

// Print intro string
for(i=0; i<strlen(introString); i++) {
    while( !(USART1->STATUS & (1 << 6)) ); // wait for TX buffer to empty
    USART1->TXDATA = introString[i];       // print each character of the test string
}

for(j=0; j<20; j++) {

    // Print test string
    for(i=0; i<strlen(testString); i++) {
        while( !(USART1->STATUS & (1 << 6)) ); // wait for TX buffer to empty
        USART1->TXDATA = testString[i];       // print each character of the test string
    }

    //vTaskDelay(delay);   // This is the line of code that corrupts the output.
}
} ~~~ Here is how I initialize the UART ~~~ void SetupUart(void) {
CMU_ClockDivSet(cmuClock_HF, cmuClkDiv_1);       // Set HF clock divider to /2 to keep core frequency < 32MHz
CMU_OscillatorEnable(cmuOsc_HFXO, true, true);   // Enable XTAL Osc and wait to stabilize
CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO); // Select HF XTAL osc as system clock source. 48MHz XTAL, but we divided the system clock by 2, therefore our HF clock will be 24MHz

CMU_ClockEnable(cmuClock_HFPER, true);
CMU_ClockEnable(cmuClock_GPIO, true);            // Enable GPIO peripheral clock
CMU_ClockEnable(cmuClock_USART1, true);          // Enable USART1 peripheral clock

GPIO_PinModeSet(UART_TXPORT, UART_TXPIN, gpioModePushPull, 1); // Configure UART TX pin as digital output, initialize high since UART TX idles high (otherwise glitches can occur)
GPIO_PinModeSet(UART_RXPORT, UART_RXPIN, gpioModeInput, 0);    // Configure UART RX pin as input (no filter)

USART_InitAsync_TypeDef uartInit =
{
    .enable       = usartDisable,   // Wait to enable the transmitter and receiver
    .refFreq      = 0,              // Setting refFreq to 0 will invoke the CMU_ClockFreqGet() function and measure the HFPER clock
    .baudrate     = 115200,          // Desired baud rate
    .oversampling = usartOVS16,     // Set oversampling value to x16
    .databits     = usartDatabits8, // 8 data bits
    .parity       = usartNoParity,  // No parity bits
    .stopbits     = usartStopbits1, // 1 stop bit
    .mvdis        = false,          // Use majority voting
    .prsRxEnable  = false,          // Not using PRS input
    .prsRxCh      = usartPrsRxCh0,  // Doesn't matter which channel we select
};

USART_InitAsync(USART1, &uartInit);                                              // Apply configuration struct to USART1
USART1->ROUTE = UART_ROUTE_RXPEN | UART_ROUTE_TXPEN | UART_ROUTE_LOCATION_LOC1; // Clear RX/TX buffers and shift regs, enable transmitter and receiver pins

USART_IntClear(USART1, _UART_IF_MASK); // Clear any USART interrupt flags
NVIC_ClearPendingIRQ(UART1_RX_IRQn);   // Clear pending RX interrupt flag in NVIC
NVIC_ClearPendingIRQ(UART1_TX_IRQn);   // Clear pending TX interrupt flag in NVIC

USART_Enable(USART1, usartEnable);     // Enable transmitter and receiver
} ~~~ The main function: ~~~ int main(void) { /* Chip errata */ CHIP_Init(); // If first word of user data page is non-zero, enable eA Profiler trace BSP_TraceProfilerSetup(); // Initialize LED driver BSPLedsInit(); // Setting state of leds BSPLedSet(0); BSP_LedSet(1); SetupUart(); // Initialize SLEEP driver, no calbacks are used SLEEP_Init(NULL, NULL);

if (configSLEEP_MODE < 3)

// do not let to sleep deeper than define SLEEPSleepBlockBegin((SLEEPEnergyModet)(configSLEEPMODE+1));

endif

// Parameters for tasks. static TaskParamst parametersToTask1 = { pdMSTOTICKS(1000), 0 }; static TaskParamst parametersToTask2 = { pdMSTOTICKS(1000), 1 }; // Create two task for blinking leds. //xTaskCreate( LedBlink, (const char *) “LedBlink1”, STACK_SIZE_FOR_TASK, &parametersToTask1, TASK_PRIORITY, NULL); //xTaskCreate( LedBlink, (const char *) “LedBlink2”, STACK_SIZE_FOR_TASK, &parametersToTask2, TASK_PRIORITY, NULL); // Create task for USART1 test. xTaskCreate( UartTest, (const char *) “UartTest”, STACK_SIZE_FOR_TASK, NULL, TASK_PRIORITY, NULL); // Start FreeRTOS Scheduler vTaskStartScheduler(); return 0; } ~~~ Here is the configuration options from FreeRTOSConfig.h: ~~~ /* Implement FreeRTOS configASSERT as emlib assert */

define configASSERT( x ) EFM_ASSERT( x )

/* Modes of operations of operation system*/

define configUSE_PREEMPTION ( 1 )

/* Energy saving modes */

define configUSETICKLESSIDLE ( 0 )

/* Available options when configUSETICKLESSIDLE set to 1 * or configUSESLEEPMODEINIDLE set to 1 : * 1 – EM1, 2 – EM2, 3 – EM3, timer in EM3 is not very accurate*/

define configSLEEP_MODE ( 2 )

/* Definition used only if configUSETICKLESSIDLE == 0 */

define configUSESLEEPMODEINIDLE ( 1 )

~~~

EFM32 Giant Gecko USART Problems

I see you have configUSETICKLESSIDLE set to 0, but as you got the project from simplicity studio it is possible that it is entering a low power mode regardless of the configUSETICKLESSIDLE setting (perhaps even just entering a low power mode from the idle task). Try waiting for the characters to actually have been transmitted before calling vTaskDelay() – as you are doing before writing the next character to the output: while( !(USART1->STATUS & (1 << 6)) ); vTaskDelay( … ); As an aside, it will be much more efficient to use interrupt driven output or ideally just use a DMA to send all the characters at once (if the chip has the ability) with no software overhead.

EFM32 Giant Gecko USART Problems

Thank you. I will try waiting for the characters to be transmitted. I plan to use the DMA, but right now, I’m just making a quick demo to see characters out of the UART, and this seemed to be the simplest example.

EFM32 Giant Gecko USART Problems

Your hunch was correct. It was a low power mode that was causing the problem. Apparently, I have to stick with power mode EM1 to use the USART properly, even at low baud rates. I am used to the MSP430 where the UART worked at lower power modes as long as the baud rate wasn’t too high.