2024-10-01 03:57 AM
Hello everyone,
I'm using Board NUCLEO-U031R8 for testing now, and I started with cubeMX and initial component below:
The task is startup and print information and delay 1 second, then entering an endless loop that includes a 1-second running delay and a 4-second sleep delay, and everything works fine in 1 second running delay.
But when sending bytes in sleep, it would occur overrun error when received length > 2, so i toggle an output while interrupt occur. and i saw an weird interrupt while receiving bytes, the record here.
To I modify tickless idle part, I disable sysTick and start LPTIM then go stop1 mode in PreSleepProcessing(), and restore everything and call vTaskStepTick() in the end of PostSleepProcessing(), and commit out the vTaskStepTick() in vPortSuppressTicksAndSleep() of port.c
Task function:
void StartDefaultTask(void *argument) {
// initial GPIO
LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB);
LL_GPIO_SetPinMode(LED4_GPIO, LED4_PIN, LL_GPIO_MODE_OUTPUT); // LED4 = PA5 = D13
LL_GPIO_SetPinMode(OUT1_GPIO, OUT1_PIN, LL_GPIO_MODE_OUTPUT); // OUT1 = PA8 = D7
LL_GPIO_SetPinMode(OUT2_GPIO, OUT2_PIN, LL_GPIO_MODE_OUTPUT); // OUT2 = PB5 = D4
LL_GPIO_SetPinOutputType(LED4_GPIO, LED4_PIN, LL_GPIO_OUTPUT_PUSHPULL);
LL_GPIO_SetPinOutputType(OUT1_GPIO, OUT1_PIN, LL_GPIO_OUTPUT_PUSHPULL);
LL_GPIO_SetPinOutputType(OUT2_GPIO, OUT2_PIN, LL_GPIO_OUTPUT_PUSHPULL);
LPUART_SendStr("BOOT\n");
LL_mDelay(1000);
LPUART_SendStr("Start!\n");
/* Infinite loop */
for(;;)
{
LL_GPIO_SetOutputPin(LED4_GPIO, LED4_PIN);
LL_mDelay(1000); // delay with no sleep
LPUART_SendStr("SLEEP\n");
LL_GPIO_ResetOutputPin(LED4_GPIO, LED4_PIN);
osDelay(pdMS_TO_TICKS(4000)); // delay to entry sleep (tickless idle)
LPUART_SendStr("WAKE\n");
// print out if any UART error.
if (_ParErrCnt > 0) { LPUART_SendStr(",ParityErr"); LPUART_SendNum(_ParErrCnt, 10); _ParErrCnt = 0; }
if (_FrameErrCnt > 0) { LPUART_SendStr(",FrameErr"); LPUART_SendNum(_FrameErrCnt, 10); _FrameErrCnt = 0; }
if (_NoiseErrCnt > 0) { LPUART_SendStr(",NoiseErr"); LPUART_SendNum(_NoiseErrCnt, 10); _NoiseErrCnt = 0; }
if (_OverRunErrCnt > 0) { LPUART_SendStr(",OverRunErr"); LPUART_SendNum(_OverRunErrCnt, 10); _OverRunErrCnt = 0; }
}
Tickless functions:
void PreSleepProcessing(uint32_t ulExpectedIdleTime) {
LL_SYSTICK_DisableIT();
LPTIM_Start(ulExpectedIdleTime);
timeBeforeSleep = 0;
LL_LPUART_EnableInStopMode(LPUART1); // Set LPUART1->CR1.UESM
// ----------------------------- Sleep ------------------------------
LL_PWR_SetPowerMode(LL_PWR_MODE_STOP1); // Set PWR->CR1.LPMS
LL_LPM_EnableDeepSleep(); // Set SCB->SCR
__WFI();
LL_LPM_EnableSleep(); // Clear SCB->SCR
LL_LPUART_DisableInStopMode(LPUART1); // Clear LPUART1->CR1.UESM
// ------------------------------------------------------------------
// Wake-up
}
void PostSleepProcessing(uint32_t ulExpectedIdleTime) {
sleepTime = LL_LPTIM_GetCounter(LPTIM1) - timeBeforeSleep;
LPTIM_Stop();
LL_SYSTICK_EnableIT(); // HAL_ResumeTick();
// NOTE: call vTaskStepTick() here, commit out the vTaskStepTick() in function vPortSetupTimerInterrupt() which in file port.c
vTaskStepTick( sleepTime );
}
LPUART IRQHandler:
void USART3_LPUART1_IRQHandler(void)
{
LL_GPIO_TogglePin(OUT1_GPIO, OUT1_PIN);
if (LL_LPUART_IsActiveFlag_WKUP(LPUART1) && LL_LPUART_IsEnabledIT_WKUP(LPUART1)) {
LL_LPUART_ClearFlag_WKUP(LPUART1);
}
// Check UART error and clear
uint32_t uart_isr = LPUART1->ISR;
if (uart_isr & 0x0F) {
if(uart_isr & LL_LPUART_ISR_PE) {
LPUART1->ICR = LL_LPUART_ICR_PECF;
_ParErrCnt++;
}
if(uart_isr & LL_LPUART_ISR_FE) {
LL_LPUART_RequestRxDataFlush(LPUART1);
LPUART1->ICR = LL_LPUART_ICR_FECF;
_FrameErrCnt++;
}
if(uart_isr & LL_LPUART_ISR_NE) {
LL_LPUART_RequestRxDataFlush(LPUART1);
LPUART1->ICR = LL_LPUART_ICR_NCF;
_NoiseErrCnt++;
}
if(uart_isr & LL_LPUART_ISR_ORE) {
LPUART1->ICR = LL_LPUART_ICR_ORECF;
_OverRunErrCnt++;
}
}
if (LL_LPUART_IsActiveFlag_RXNE_RXFNE(LPUART1)) {
uint8_t ch = LL_LPUART_ReceiveData8(LPUART1);
rxBuf[rxIdx++] = ch;
if (ch == '\n') rxFlag = rxIdx;
}
LL_GPIO_TogglePin(OUT1_GPIO, OUT1_PIN);
}
The test project is upload if anyone needed.
If there are any mistakes or oversights, please correct me.
Regards
Kein.