Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


Loading

EFM32 Giant Gecko USART Problems

Posted by richdinoso on April 5, 2017

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[] = "\n\rEFM32 GG Benchmark test started!\n\r\n\r";
const char testString[40] = "abcdefghij\n\r";
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", STACKSIZEFORTASK, &parametersToTask1, TASKPRIORITY, NULL); //xTaskCreate( LedBlink, (const char *) "LedBlink2", STACKSIZEFORTASK, &parametersToTask2, TASKPRIORITY, NULL);

// Create task for USART1 test. xTaskCreate( UartTest, (const char *) "UartTest", STACKSIZEFORTASK, NULL, TASKPRIORITY, 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

Posted by rtel on April 5, 2017

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

Posted by richdinoso on April 5, 2017

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

Posted by richdinoso on April 5, 2017

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.


[ Back to the top ]    [ About FreeRTOS ]    [ Privacy ]    [ Sitemap ]    [ ]


Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

Meet Richard Barry and learn about running FreeRTOS on RISC-V at FOSDEM 2019

Version 10.1.1 of the FreeRTOS kernel is available for immediate download. MIT licensed.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


Careers

FreeRTOS and other embedded software careers at AWS.



FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Renesas

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS

Xilinx Microblaze and Zynq partner