@@ -182,7 +182,13 @@ void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
182182 configPRE_SLEEP_PROCESSING ( xModifiableIdleTime );
183183 if ( xModifiableIdleTime > 0 )
184184 {
185- #if 0 // With FreeRTOS sd_app_evt_wait increases power consumption with FreeRTOS compared to _WFE (NRFFOSDK-11174)
185+ #if (__FPU_USED == 1 )
186+ // nRF52832 errata 87: prevent FPU from keeping CPU on
187+ // https://infocenter.nordicsemi.com/topic/errata_nRF52832_Rev2/ERR/nRF52832/Rev2/latest/anomaly_832_87.html?cp=4_2_1_0_1_24
188+ __set_FPSCR (__get_FPSCR () & ~(0x0000009F ));
189+ (void ) __get_FPSCR ();
190+ NVIC_ClearPendingIRQ (FPU_IRQn );
191+ #endif
186192#ifdef SOFTDEVICE_PRESENT // TODO
187193 uint8_t sd_en = 0 ;
188194 (void ) sd_softdevice_is_enabled (& sd_en );
@@ -193,7 +199,6 @@ void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
193199 }
194200 else
195201#endif
196- #endif // (NRFFOSDK-11174)
197202 {
198203 /* No SD - we would just block interrupts globally.
199204 * BASEPRI cannot be used for that because it would prevent WFE from wake up.
@@ -227,9 +232,27 @@ void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
227232 diff = xExpectedIdleTime ;
228233 }
229234
230- if (diff > 0 )
235+ // nRF-provided fix for delay() wakeup 1ms spin-loop power waste
236+ // See https://devzone.nordicsemi.com/f/nordic-q-a/63828/vtaskdelay-on-nrf52-freertos-port-wastes-cpu-power
237+ BaseType_t switch_req = pdFALSE ;
238+
239+ if (diff > 1 )
240+ {
241+ vTaskStepTick (diff - 1 );
242+ switch_req = xTaskIncrementTick ();
243+ }
244+ else if (diff == 1 )
245+ {
246+ switch_req = xTaskIncrementTick ();
247+ }
248+
249+ /* Increment the RTOS tick as usual which checks if there is a need for rescheduling */
250+ if ( switch_req != pdFALSE )
231251 {
232- vTaskStepTick (diff );
252+ /* A context switch is required. Context switching is performed in
253+ the PendSV interrupt. Pend the PendSV interrupt. */
254+ SCB -> ICSR = SCB_ICSR_PENDSVSET_Msk ;
255+ __SEV ();
233256 }
234257 }
235258 }
0 commit comments