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
BSP
LedsInit();
// 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
SLEEP
SleepBlockBegin((SLEEPEnergyMode
t)(configSLEEPMODE+1));
endif
// Parameters for tasks.
static TaskParams
t parametersToTask1 = { pdMSTO
TICKS(1000), 0 };
static TaskParamst parametersToTask2 = { pdMS
TOTICKS(1000), 1 };
// Create two task for blinking leds.
//xTaskCreate( LedBlink, (const char *) “LedBlink1”, STACK_SIZE_FOR_TASK, ¶metersToTask1, TASK_PRIORITY, NULL);
//xTaskCreate( LedBlink, (const char *) “LedBlink2”, STACK_SIZE_FOR_TASK, ¶metersToTask2, 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 configUSE
TICKLESSIDLE set to 1
* or configUSE
SLEEPMODE
INIDLE set to 1 :
* 1 – EM1, 2 – EM2, 3 – EM3, timer in EM3 is not very accurate*/
define configSLEEP_MODE ( 2 )
/* Definition used only if configUSE
TICKLESSIDLE == 0 */
define configUSESLEEPMODEINIDLE ( 1 )
~~~