Skip to content

Commit b35674f

Browse files
authored
Merge pull request #555 from Nenik/master
Power fixes
2 parents 2775463 + 2970c50 commit b35674f

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

cores/nRF5/freertos/portable/CMSIS/nrf52/port_cmsis_systick.c

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)