Skip to content
Snippets Groups Projects
Commit c4fe452c authored by schneider's avatar schneider
Browse files

feat(pycardium): Use epic_sleep() call while sleeping

parent 679bf054
No related branches found
No related tags found
1 merge request!480Pycardium: Use sleep API call while sleeping
...@@ -210,5 +210,5 @@ void sleep_deepsleep(void) ...@@ -210,5 +210,5 @@ void sleep_deepsleep(void)
void epic_sleep(uint32_t ms) void epic_sleep(uint32_t ms)
{ {
vTaskDelay(ms); vTaskDelay(pdMS_TO_TICKS(ms));
} }
...@@ -21,7 +21,8 @@ ...@@ -21,7 +21,8 @@
#include <string.h> #include <string.h>
// Smallest interval which can be reached exactly // Smallest interval which can be reached exactly
#define SYSTICK_INTERVAL_US 15625ULL // * 8 to allow up to 100 ms epic calls
#define SYSTICK_INTERVAL_US (15625ULL * 8ULL)
#define SYSTICK_FREQ_HZ (1000000 / SYSTICK_INTERVAL_US) #define SYSTICK_FREQ_HZ (1000000 / SYSTICK_INTERVAL_US)
/* /*
...@@ -225,51 +226,6 @@ static void systick_delay_precise(uint32_t us) ...@@ -225,51 +226,6 @@ static void systick_delay_precise(uint32_t us)
} }
} }
static void systick_delay_sleep(uint32_t us)
{
uint64_t final_time = systick_get_us() + (uint64_t)us - 2;
while (1) {
uint64_t now = systick_get_us();
if ((now + SYSTICK_INTERVAL_US) > final_time) {
break;
}
/*
* Sleep with WFI if more than SYSTICK_INTERVAL_US of delay
* is remaining. The SysTick interrupt is guaranteed to
* happen within any timespan of SYSTICK_INTERVAL_US.
*
* Use a critical section encompassing both the check and the
* WFI to prevent a race-condition where the interrupt happens
* just in between the check and WFI.
*/
uint32_t irqsaved = __get_PRIMASK();
__set_PRIMASK(0);
if ((now + SYSTICK_INTERVAL_US) < final_time) {
__WFI();
}
__set_PRIMASK(irqsaved);
/*
* Handle pending MicroPython 'interrupts'. This call could
* potentially not return here when a handler raises an
* exception. Those will propagate outwards and thus make the
* delay return early.
*
* One example of this happeing is the KeyboardInterrupt
* (CTRL+C) which will abort the running code and exit to REPL.
*/
mp_handle_pending(true);
}
uint64_t now = systick_get_us();
if (now < final_time) {
systick_delay_precise(final_time - now);
}
}
static void systick_delay(uint32_t us) static void systick_delay(uint32_t us)
{ {
if (us == 0) if (us == 0)
...@@ -282,10 +238,30 @@ static void systick_delay(uint32_t us) ...@@ -282,10 +238,30 @@ static void systick_delay(uint32_t us)
* happening and also checks for MicroPython interrupts every now and * happening and also checks for MicroPython interrupts every now and
* then. * then.
*/ */
if (us < SYSTICK_INTERVAL_US) { if (us < 1000) {
systick_delay_precise(us); systick_delay_precise(us);
} else { } else {
systick_delay_sleep(us); uint64_t now = systick_get_us();
uint64_t final_time = now + us;
while (final_time - systick_get_us() > SYSTICK_INTERVAL_US) {
uint32_t sleep_time =
(final_time - systick_get_us()) / 1000;
if (sleep_time > 100)
sleep_time = 100;
epic_sleep(sleep_time);
mp_handle_pending(true);
}
now = systick_get_us();
if (final_time - now > 1000) {
epic_sleep((final_time - now) / 1000);
}
now = systick_get_us();
if (final_time > now) {
systick_delay_precise(final_time - now);
}
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment