Open TurboStew opened 8 months ago
I can confirm this is a problem.
The root cause is that the SysTick_Handler, which provides the tick count as the basis for RTOS sleep_until() and sleep_for(), is called at twice the speed. In the Apollo3 datasheet, there is already a warning e.g. on page 78
_In TurboSPOT Mode on the Apollo3 Blue SoC, the SYSTICK increments at
twice the normal (48 MHz) clock rate. Some RTOSes may use SYSTICK for
scheduler timing by default, in which case scheduler event timing will be wrong
when using TurboSPOT Mode. It is recommended not to use SYSTICK and
TurboSPOT Mode together unless proper compensation is made._
As no compensation is made in the current library this problem is occurring.
This bug is NOT impacting millis() or Micros() as those are based on a low power timer of the Apollo3-chip. It does impact all the RTOS time / delay functions. It also impacts one of "mbed OS Ethernet drivers", but none of these MBED Ethernet drivers are used in the Sparkfun implementation.
I have created a test sketch (in the attached zip-file) that will blink the LED every 5 seconds. Without modification it will blink half of that time, 2.5mS.
Solution The systick counter needs to be adjusted when enabling burst and disabling burst mode. This can be done in the file am_hal_burst.c by adjusting the LOAD (reload value for systick) from 48000 (normal mode) to 96000 (burst mode). After making this change the pre-compiled MBED library (libmbed-os.a) needs to be created and stored in the different variants-folders. This has been tested on an Artemis ATP.
Attached is the zip-file with the adjusted am_hal_burst.c and the test sketch. regards, Paul sleep_burst.zip
When in turbo mode, the time for things like sleep_until() are running 2x speed. such as:
using namespace std::chrono_literals; rtos::ThisThread::sleep_until(5ms);
only sleeps for 2.5ms. All works properly when NOT in turbo mode..... Using an Artemis ATP and library 2.2.1. Using a scope and an output pin to verify.