The motivation for doing this is so that we can allow
common_hal_mcu_disable_interrupts in IRQ context, something that works
on other ports, but not on nRF with SD enabled. This is because
when SD is enabled, calling sd_softdevice_is_enabled in the context
of an interrupt with priority 2 or 3 causes a HardFault. We have chosen
to give the USB interrupt priority 2 on nRF, the highest priority that
is compatible with SD.
Since at least SoftDevice s130 v2.0.1, sd_nvic_critical_region_enter/exit
have been implemented as inline functions and are safe to call even if
softdevice is not enabled. Reference kindly provided by danh:
https://devzone.nordicsemi.com/f/nordic-q-a/29553/sd_nvic_critical_region_enter-exit-missing-in-s130-v2
Switching to these as the default/only way to enable/disable interrupts
simplifies things, and fixes several problems and potential problems:
* Interrupts at priority 2 or 3 could not call common_hal_mcu_disable_interrupts
because the call to sd_softdevice_is_enabled would HardFault
* Hypothetically, the state of sd_softdevice_is_enabled
could change from the disable to the enable call, meaning the calls
would not match (__disable_irq() could be balanced with
sd_nvic_critical_region_exit).
This also fixes a problem I believe would exist if disable() were called
twice when SD is enabled. There is a single "is_nested_critical_region"
flag, and the second call would set it to 1. Both of the enable()
calls that followed would call critical_region_exit(1), and interrupts
would not properly be reenabled. In the new version of the code,
we use our own nesting_count value to track the intended state, so
now nested disable()s only call critical_region_enter() once, only
updating is_nested_critical_region once; and only the second enable()
call will call critical_region_exit, with the right value of i_n_c_r.
Finally, in port_sleep_until_interrupt, if !sd_enabled, we really do
need to __disable_irq, rather than using the common_hal_mcu routines;
the reason why is documented in a comment.
As part of the reset process, save the current tick count to an
uninitialized memory location. That way, the current tick value will be
preserved across reboots.
A reboot will cause us to lose a certain number of ticks, depending on
how long a reboot takes, however if reboots are infrequent then this
will not be a large amount of time lost.
Signed-off-by: Sean Cross <sean@xobs.io>
ARM recommends issuing a DSB instruction propr to issuing WFI, as it is
required on many parts suchas Cortex-M7. This is effectively a no-op on
the Cortex-M4 used in most NRF parts, however it ensures that we won't
be surprised when new parts come out.
See
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0321a/BIHICBGB.html
for more information.
Signed-off-by: Sean Cross <sean@xobs.io>
In order to ensure we don't have any outstanding requests, disable
interrupts prior to issuing `WFI`.
As part of this process, check to see if there are any pending USB
requests, and only execute the `WFI` if there is no pending data.
This fixes#2855 on NRF.
Signed-off-by: Sean Cross <sean@xobs.io>
On NRF, the `rtc_reset()` function is never called. As a result,
calls to `time.time()` return a cryptic error>
```
>>> import time
>>> time.time()
'' object has no attribute 'datetime'
>>>
```
This is because `MP_STATE_VM(rtc_time_source)` is not initialized
due to `rtc_reset()` never being called.
If `CIRCUITPY_RTC` is enabled, call `rtc_reset()` as part of the
`reset_port()` call. This ensures that `time.time()` works as expected.
Signed-off-by: Sean Cross <sean@xobs.io>
Circuit Python supports saving a single word of data across reboots.
Previously, this data was placed immediately following the .bss.
However, this appeared to not work, as Circuit Python zeroes out the
heap when it starts up, and the heap begins immediately after the .bss.
Switch to using the new .uninitialized section in order to store this
word across resets.
Signed-off-by: Sean Cross <sean@xobs.io>
Previously, it was placed following .bss. However, now that there is a
new section after .bss, the heap must be moved forward.
Signed-off-by: Sean Cross <sean@xobs.io>