8000 nrf/modules/machine: Implement deepsleep(). · micropython/micropython@e002e18 · GitHub
[go: up one dir, main page]

Skip to content

Commit e002e18

Browse files
committed
nrf/modules/machine: Implement deepsleep().
Replace the previous dummy implementation of machine.deepsleep() with one that invokes the nRF's deep sleep state "System OFF". The argument is ignored, nRF microcontrollers are incapable of waking on a timer as all clocks are off in the deep sleep state. Pins are configured as wake sources using an additional argument "sense" to the machine.Pin constructor. machine.reset_cause() returns the newly added DEEPSLEEP_RESET, like on other ports – the previous mapping to PWRON_RESET seemed wrong. Signed-off-by: Christian Walther <cwalther@gmx.ch>
1 parent adc0459 commit e002e18

File tree

4 files changed

+71
-8
lines changed

4 files changed

+71
-8
lines changed

docs/library/machine.Pin.rst

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Usage Model::
4242
Constructors
4343
------------
4444

45-
.. class:: Pin(id, mode=-1, pull=-1, *, value=None, drive=0, alt=-1)
45+
.. class:: Pin(id, mode=-1, pull=-1, *, value=None, drive=0, alt=-1, sense=-1)
4646

4747
Access the pin peripheral (GPIO pin) associated with the given ``id``. If
4848
additional arguments are given in the constructor then they are used to initialise
@@ -97,6 +97,15 @@ Constructors
9797
one pin alternate function is supported the this argument is not required. Not all
9898
ports implement this argument.
9999

100+
- ``sense`` specifies whether and on what input value the pin contributes to the
101+
*DETECT* signal, which wakes an nRF51/52 system from deep sleep. It can be one of:
102+
103+
- ``Pin.SENSE_DISABLED`` - Do not wake from this pin.
104+
- ``Pin.SENSE_LOW`` - Wake when pin is low.
105+
- ``Pin.SENSE_HIGH`` - Wake when pin is high.
106+
107+
Availability: nrf port.
108+
100109
As specified above, the Pin class allows to set an alternate function for a particular
101110
pin, but it does not specify any further operations on such a pin. Pins configured in
102111
alternate-function mode are usually not used as GPIO but are instead driven by other
@@ -108,7 +117,7 @@ Constructors
108117
Methods
109118
-------
110119

111-
.. method:: Pin.init(mode=-1, pull=-1, *, value=None, drive=0, alt=-1)
120+
.. method:: Pin.init(mode=-1, pull=-1, *, value=None, drive=0, alt=-1, sense=-1)
112121

113122
Re-initialise the pin using the given parameters. Only those arguments that
114123
are specified will be set. The rest of the pin peripheral state will remain
@@ -274,3 +283,13 @@ not all constants are available on all ports.
274283
Pin.IRQ_HIGH_LEVEL
275284

276285
Selects the IRQ trigger type.
286+
287+
.. data:: Pin.SENSE_DISABLED
288+
Pin.SENSE_LOW
289+
Pin.SENSE_HIGH
290+
291+
Selects the *SENSE* configuration of the pin, which determines
292+
whether and on what input value it contributes to the *DETECT*
293+
signal, which wakes the system from deep sleep.
294+
295+
Availability: nrf port.

docs/library/machine.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,15 @@ Power related functions
160160
return `machine.DEEPSLEEP` and this can be used to distinguish a deepsleep wake
161161
from other resets.
162162

163+
*nrf port:*
164+
165+
* The *time_ms* argument to `deepsleep` is ignored, the sleep is always indefinite.
166+
nRF microcontrollers are incapable of waking on a timer as all clocks are off in
167+
the deep sleep state.
168+
169+
* Pins are configured as wake sources using the ``sense`` argument to the
170+
`Pin` constructor.
171+
163172
.. function:: wake_reason()
164173

165174
Get the wake reason. See :ref:`constants <machine_constants>` for the possible return values.

ports/nrf/modules/machine/modmachine.c

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,20 @@
4949
#if MICROPY_PY_MACHINE_RTCOUNTER
5050
#include "rtcounter.h"
5151
#endif
52+
#if defined(POWER_SYSTEMOFF_SYSTEMOFF_Enter)
53+
// nRF51/52
54+
#include "nrf_power.h"
55+
#elif defined(REGULATORS_SYSTEMOFF_SYSTEMOFF_Enable)
56+
// nRF91
57+
#include "nrf_regulators.h"
58+
#endif
5259

60+
#define PYB_RESET_POWER_ON (32)
5361
#define PYB_RESET_HARD (0)
5462
#define PYB_RESET_WDT (1)
5563
#define PYB_RESET_SOFT (2)
5664
#define PYB_RESET_LOCKUP (3)
57-
#define PYB_RESET_POWER_ON (16)
65+
#define PYB_RESET_DEEPSLEEP (16)
5866
#define PYB_RESET_LPCOMP (17)
5967
#define PYB_RESET_DIF (18)
6068
#define PYB_RESET_NFC (19)
@@ -93,11 +101,12 @@
93101
MICROPY_PY_MACHINE_RTCOUNTER_ENTRY \
94102
MICROPY_PY_MACHINE_TIMER_ENTRY \
95103
MICROPY_PY_MACHINE_TEMP_ENTRY \
104+
{ MP_ROM_QSTR(MP_QSTR_PWRON_RESET), MP_ROM_INT(PYB_RESET_POWER_ON) }, \
96105
{ MP_ROM_QSTR(MP_QSTR_HARD_RESET), MP_ROM_INT(PYB_RESET_HARD) }, \
97106
{ MP_ROM_QSTR(MP_QSTR_WDT_RESET), MP_ROM_INT(PYB_RESET_WDT) }, \
98107
{ MP_ROM_QSTR(MP_QSTR_SOFT_RESET), MP_ROM_INT(PYB_RESET_SOFT) }, \
99108
{ MP_ROM_QSTR(MP_QSTR_LOCKUP_RESET), MP_ROM_INT(PYB_RESET_LOCKUP) }, \
100-
{ MP_ROM_QSTR(MP_QSTR_PWRON_RESET), MP_ROM_INT(PYB_RESET_POWER_ON) }, \
109+
{ MP_ROM_QSTR(MP_QSTR_DEEPSLEEP_RESET), MP_ROM_INT(PYB_RESET_DEEPSLEEP) }, \
101110
{ MP_ROM_QSTR(MP_QSTR_LPCOMP_RESET), MP_ROM_INT(PYB_RESET_LPCOMP) }, \
102111
{ MP_ROM_QSTR(MP_QSTR_DEBUG_IF_RESET), MP_ROM_INT(PYB_RESET_DIF) }, \
103112
MICROPY_PY_MACHINE_NFC_RESET_ENTRY \
@@ -115,7 +124,7 @@ void machine_init(void) {
115124
} else if (state & POWER_RESETREAS_LOCKUP_Msk) {
116125
reset_cause = PYB_RESET_LOCKUP;
117126
} else if (state & POWER_RESETREAS_OFF_Msk) {
118-
reset_cause = PYB_RESET_POWER_ON;
127+
reset_cause = PYB_RESET_DEEPSLEEP;
119128
#if !defined(NRF9160_XXAA)
120129
} else if (state & POWER_RESETREAS_LPCOMP_Msk) {
121130
reset_cause = PYB_RESET_LPCOMP;
@@ -126,10 +135,12 @@ void machine_init(void) {
126135
} else if (state & POWER_RESETREAS_NFC_Msk) {
127136
reset_cause = PYB_RESET_NFC;
128137
#endif
138+
} else {
139+
reset_cause = PYB_RESET_POWER_ON;
129140
}
130141

131142
// clear reset reason
132-
NRF_POWER->RESETREAS = (1 << reset_cause);
143+
NRF_POWER->RESETREAS = 0xFFFFFFFF;
133144
}
134145

135146
// machine.info([dump_alloc_table])
@@ -200,7 +211,18 @@ STATIC void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
200211
}
201212

202213
NORETURN STATIC void mp_machine_deepsleep(size_t n_args, const mp_obj_t *args) {
203-
mp_machine_reset();
214+
#if defined(POWER_SYSTEMOFF_SYSTEMOFF_Enter)
215+
// nRF51/52
216+
nrf_power_system_off(NRF_POWER);
217+
#elif defined(REGULATORS_SYSTEMOFF_SYSTEMOFF_Enable)
218+
// nRF91
219+
nrf_regulators_system_off(NRF_REGULATORS);
220+
#else
221+
#error figure out how to enter System OFF mode on this chip
222+
#endif
223+
// never reached, just to convince the compiler of NORETURN
224+
for (;;) {
225+
}
204226
}
205227

206228
STATIC mp_int_t mp_machine_reset_cause(void) {

ports/nrf/modules/machine/pin.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ STATIC mp_obj_t pin_ob 10000 j_init_helper(const pin_obj_t *self, mp_uint_t n_args, con
348348
{ MP_QSTR_af, MP_ARG_INT, {.u_int = -1}}, // legacy
349349
{ MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}},
350350
{ MP_QSTR_alt, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1}},
351+
{ MP_QSTR_sense, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1}},
351352
};
352353

353354
// parse args
@@ -373,13 +374,21 @@ STATIC mp_obj_t pin_obj_init_helper(const pin_obj_t *self, mp_uint_t n_args, con
373374
nrf_gpio_pin_input_t input = (mode == NRF_GPIO_PIN_DIR_INPUT) ? NRF_GPIO_PIN_INPUT_CONNECT
374375
: NRF_GPIO_PIN_INPUT_DISCONNECT;
375376

377+
// sense mode (default unmodified)
378+
nrf_gpio_pin_sense_t sense = (nrf_gpio_pin_sense_t)args[5].u_int;
379+
if (sense == (nrf_gpio_pin_sense_t)-1) {
380+
sense = nrf_gpio_pin_sense_get(self->pin);
381+
} else if (sense != NRF_GPIO_PIN_NOSENSE && sense != NRF_GPIO_PIN_SENSE_LOW && sense != NRF_GPIO_PIN_SENSE_HIGH) {
382+
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pin sense: %d"), sense);
383+
}
384+
376385
if (mode == NRF_GPIO_PIN_DIR_OUTPUT || mode == NRF_GPIO_PIN_DIR_INPUT) {
377386
nrf_gpio_cfg(self->pin,
378387
mode,
379388
input,
380389
pull,
381390
NRF_GPIO_PIN_S0S1,
382-
NRF_GPIO_PIN_NOSENSE);
391+
sense);
383392
} else {
384393
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pin mode: %d"), mode);
385394
}
@@ -591,6 +600,10 @@ STATIC const mp_rom_map_elem_t pin_locals_dict_table[] = {
591600
{ MP_ROM_QSTR(MP_QSTR_AF_OD), MP_ROM_INT(GPIO_MODE_AF_OD) },
592601
{ MP_ROM_QSTR(MP_QSTR_PULL_NONE), MP_ROM_INT(GPIO_NOPULL) },
593602
*/
603+
{ MP_ROM_QSTR(MP_QSTR_SENSE_DISABLED), MP_ROM_INT(NRF_GPIO_PIN_NOSENSE) },
604+
{ MP_ROM_QSTR(MP_QSTR_SENSE_LOW), MP_ROM_INT(NRF_GPIO_PIN_SENSE_LOW) },
605+
{ MP_ROM_QSTR(MP_QSTR_SENSE_HIGH), MP_ROM_INT(NRF_GPIO_PIN_SENSE_HIGH) },
606+
594607
#include "genhdr/pins_af_const.h"
595608
};
596609

0 commit comments

Comments
 (0)
0