Skip to content

Commit abec47a

Browse files
MrSurlydpgeorge
authored andcommitted
esp32/modesp32: Add new module "esp32" to support extra wake features.
The machine.Pin class is also updated to support these wake-on-pin features.
1 parent 44033a1 commit abec47a

5 files changed

Lines changed: 221 additions & 8 deletions

File tree

ports/esp32/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ SRC_C = \
147147
network_lan.c \
148148
modsocket.c \
149149
modesp.c \
150+
modesp32.c \
150151
moduhashlib.c \
151152
espneopixel.c \
152153
machine_hw_spi.c \

ports/esp32/machine_pin.c

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535
#include "py/mphal.h"
3636
#include "modmachine.h"
3737
#include "extmod/virtpin.h"
38+
#include "machine_rtc.h"
39+
#include "modesp32.h"
40+
41+
extern machine_rtc_config_t machine_rtc_config;
3842

3943
typedef struct _machine_pin_obj_t {
4044
mp_obj_base_t base;
@@ -219,10 +223,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pin_value_obj, 1, 2, machine_
219223

220224
// pin.irq(handler=None, trigger=IRQ_FALLING|IRQ_RISING)
221225
STATIC mp_obj_t machine_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
222-
enum { ARG_handler, ARG_trigger, ARG_hard };
226+
enum { ARG_handler, ARG_trigger, ARG_wake };
223227
static const mp_arg_t allowed_args[] = {
224228
{ MP_QSTR_handler, MP_ARG_OBJ, {.u_obj = mp_const_none} },
225229
{ MP_QSTR_trigger, MP_ARG_INT, {.u_int = GPIO_PIN_INTR_POSEDGE | GPIO_PIN_INTR_NEGEDGE} },
230+
{ MP_QSTR_wake, MP_ARG_OBJ, {.u_obj = mp_const_none} },
226231
};
227232
machine_pin_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
228233
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@@ -232,14 +237,48 @@ STATIC mp_obj_t machine_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_
232237
// configure irq
233238
mp_obj_t handler = args[ARG_handler].u_obj;
234239
uint32_t trigger = args[ARG_trigger].u_int;
235-
if (handler == mp_const_none) {
236-
handler = MP_OBJ_NULL;
237-
trigger = 0;
240+
mp_obj_t wake_obj = args[ARG_wake].u_obj;
241+
242+
if ((trigger == GPIO_PIN_INTR_LOLEVEL || trigger == GPIO_PIN_INTR_HILEVEL) && wake_obj != mp_const_none) {
243+
mp_int_t wake;
244+
if (mp_obj_get_int_maybe(wake_obj, &wake)) {
245+
if (wake < 2 || wake > 7) {
246+
mp_raise_ValueError("bad wake value");
247+
}
248+
} else {
249+
mp_raise_ValueError("bad wake value");
250+
}
251+
252+
if (machine_rtc_config.wake_on_touch) { // not compatible
253+
mp_raise_ValueError("no resources");
254+
}
255+
256+
if (!RTC_IS_VALID_EXT_PIN(self->id)) {
257+
mp_raise_ValueError("invalid pin for wake");
258+
}
259+
260+
if (machine_rtc_config.ext0_pin == -1) {
261+
machine_rtc_config.ext0_pin = self->id;
262+
} else if (machine_rtc_config.ext0_pin != self->id) {
263+
mp_raise_ValueError("no resources");
264+
}
265+
266+
machine_rtc_config.ext0_level = trigger == GPIO_PIN_INTR_LOLEVEL ? 0 : 1;
267+
machine_rtc_config.ext0_wake_types = wake;
268+
} else {
269+
if (machine_rtc_config.ext0_pin == self->id) {
270+
machine_rtc_config.ext0_pin = -1;
271+
}
272+
273+
if (handler == mp_const_none) {
274+
handler = MP_OBJ_NULL;
275+
trigger = 0;
276+
}
277+
gpio_isr_handler_remove(self->id);
278+
MP_STATE_PORT(machine_pin_irq_handler)[self->id] = handler;
279+
gpio_set_intr_type(self->id, trigger);
280+
gpio_isr_handler_add(self->id, machine_pin_isr_handler, (void*)self);
238281
}
239-
gpio_isr_handler_remove(self->id);
240-
MP_STATE_PORT(machine_pin_irq_handler)[self->id] = handler;
241-
gpio_set_intr_type(self->id, trigger);
242-
gpio_isr_handler_add(self->id, machine_pin_isr_handler, (void*)self);
243282
}
244283

245284
// return the irq object
@@ -261,6 +300,8 @@ STATIC const mp_rom_map_elem_t machine_pin_locals_dict_table[] = {
261300
{ MP_ROM_QSTR(MP_QSTR_PULL_DOWN), MP_ROM_INT(GPIO_PULLDOWN_ONLY) },
262301
{ MP_ROM_QSTR(MP_QSTR_IRQ_RISING), MP_ROM_INT(GPIO_PIN_INTR_POSEDGE) },
263302
{ MP_ROM_QSTR(MP_QSTR_IRQ_FALLING), MP_ROM_INT(GPIO_PIN_INTR_NEGEDGE) },
303+
{ MP_ROM_QSTR(MP_QSTR_WAKE_LOW), MP_ROM_INT(GPIO_PIN_INTR_LOLEVEL) },
304+
{ MP_ROM_QSTR(MP_QSTR_WAKE_HIGH), MP_ROM_INT(GPIO_PIN_INTR_HILEVEL) },
264305
};
265306

266307
STATIC mp_uint_t pin_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {

ports/esp32/modesp32.c

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2017 "Eric Poulsen" <eric@zyxod.com>
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include <stdio.h>
28+
#include <string.h>
29+
30+
#include <time.h>
31+
#include <sys/time.h>
32+
#include "driver/gpio.h"
33+
34+
#include "py/nlr.h"
35+
#include "py/obj.h"
36+
#include "py/runtime.h"
37+
#include "py/mphal.h"
38+
#include "timeutils.h"
39+
#include "modmachine.h"
40+
#include "machine_rtc.h"
41+
#include "modesp32.h"
42+
43+
extern machine_rtc_config_t machine_rtc_config;
44+
45+
STATIC mp_obj_t esp32_wake_on_touch(const mp_obj_t wake) {
46+
47+
if (machine_rtc_config.ext0_pin != -1) {
48+
mp_raise_ValueError("no resources");
49+
}
50+
//nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "touchpad wakeup not available for this version of ESP-IDF"));
51+
52+
machine_rtc_config.wake_on_touch = mp_obj_is_true(wake);
53+
return mp_const_none;
54+
}
55+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_wake_on_touch_obj, esp32_wake_on_touch);
56+
57+
STATIC mp_obj_t esp32_wake_on_ext0(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
58+
59+
if (machine_rtc_config.wake_on_touch) {
60+
mp_raise_ValueError("no resources");
61+
}
62+
enum {ARG_pin, ARG_level};
63+
const mp_arg_t allowed_args[] = {
64+
{ MP_QSTR_pin, MP_ARG_OBJ, {.u_obj = mp_obj_new_int(machine_rtc_config.ext0_pin)} },
65+
{ MP_QSTR_level, MP_ARG_BOOL, {.u_bool = machine_rtc_config.ext0_level} },
66+
};
67+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
68+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
69+
70+
if (args[ARG_pin].u_obj == mp_const_none) {
71+
machine_rtc_config.ext0_pin = -1; // "None"
72+
} else {
73+
gpio_num_t pin_id = machine_pin_get_id(args[ARG_pin].u_obj);
74+
if (pin_id != machine_rtc_config.ext0_pin) {
75+
if (!RTC_IS_VALID_EXT_PIN(pin_id)) {
76+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "invalid pin"));
77+
}
78+
machine_rtc_config.ext0_pin = pin_id;
79+
}
80+
}
81+
82+
machine_rtc_config.ext0_level = args[ARG_level].u_bool;
83+
machine_rtc_config.ext0_wake_types = MACHINE_WAKE_SLEEP | MACHINE_WAKE_DEEPSLEEP;
84+
85+
return mp_const_none;
86+
}
87+
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(esp32_wake_on_ext0_obj, 0, esp32_wake_on_ext0);
88+
89+
STATIC mp_obj_t esp32_wake_on_ext1(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
90+
enum {ARG_pins, ARG_level};
91+
const mp_arg_t allowed_args[] = {
92+
{ MP_QSTR_pins, MP_ARG_OBJ, {.u_obj = mp_const_none} },
93+
{ MP_QSTR_level, MP_ARG_BOOL, {.u_bool = machine_rtc_config.ext1_level} },
94+
};
95+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
96+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
97+
uint64_t ext1_pins = machine_rtc_config.ext1_pins;
98+
99+
100+
// Check that all pins are allowed
101+
if (args[ARG_pins].u_obj != mp_const_none) {
102+
mp_uint_t len = 0;
103+
mp_obj_t *elem;
104+
mp_obj_get_array(args[ARG_pins].u_obj, &len, &elem);
105+
ext1_pins = 0;
106+
107+
for (int i = 0; i < len; i++) {
108+
109+
gpio_num_t pin_id = machine_pin_get_id(elem[i]);
110+
if (!RTC_IS_VALID_EXT_PIN(pin_id)) {
111+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "invalid pin"));
112+
break;
113+
}
114+
ext1_pins |= (1ll << pin_id);
115+
}
116+
}
117+
118+
machine_rtc_config.ext1_level = args[ARG_level].u_bool;
119+
machine_rtc_config.ext1_pins = ext1_pins;
120+
121+
return mp_const_none;
122+
}
123+
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(esp32_wake_on_ext1_obj, 0, esp32_wake_on_ext1);
124+
125+
STATIC const mp_rom_map_elem_t esp32_module_globals_table[] = {
126+
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_esp32) },
127+
128+
{ MP_OBJ_NEW_QSTR(MP_QSTR_wake_on_touch), (mp_obj_t)&esp32_wake_on_touch_obj },
129+
{ MP_OBJ_NEW_QSTR(MP_QSTR_wake_on_ext0), (mp_obj_t)&esp32_wake_on_ext0_obj },
130+
{ MP_OBJ_NEW_QSTR(MP_QSTR_wake_on_ext1), (mp_obj_t)&esp32_wake_on_ext1_obj },
131+
{ MP_OBJ_NEW_QSTR(MP_QSTR_WAKEUP_ALL_LOW), mp_const_false },
132+
{ MP_OBJ_NEW_QSTR(MP_QSTR_WAKEUP_ANY_HIGH), mp_const_true },
133+
};
134+
135+
STATIC MP_DEFINE_CONST_DICT(esp32_module_globals, esp32_module_globals_table);
136+
137+
const mp_obj_module_t esp32_module = {
138+
.base = { &mp_type_module },
139+
.globals = (mp_obj_dict_t*)&esp32_module_globals,
140+
};

ports/esp32/modesp32.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#ifndef MICROPY_INCLUDED_ESP32_MODESP32_H
2+
#define MICROPY_INCLUDED_ESP32_MODESP32_H
3+
4+
#define RTC_VALID_EXT_PINS \
5+
( \
6+
(1ll << 0) | \
7+
(1ll << 2) | \
8+
(1ll << 4) | \
9+
(1ll << 12) | \
10+
(1ll << 13) | \
11+
(1ll << 14) | \
12+
(1ll << 15) | \
13+
(1ll << 25) | \
14+
(1ll << 26) | \
15+
(1ll << 27) | \
16+
(1ll << 32) | \
17+
(1ll << 33) | \
18+
(1ll << 34) | \
19+
(1ll << 35) | \
20+
(1ll << 36) | \
21+
(1ll << 37) | \
22+
(1ll << 38) | \
23+
(1ll << 39) \
24+
)
25+
26+
#define RTC_LAST_EXT_PIN 39
27+
#define RTC_IS_VALID_EXT_PIN(pin_id) ((1ll << (pin_id)) & RTC_VALID_EXT_PINS)
28+
29+
#endif // MICROPY_INCLUDED_ESP32_MODESP32_H

ports/esp32/mpconfigport.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@
162162

163163
// extra built in modules to add to the list of known ones
164164
extern const struct _mp_obj_module_t esp_module;
165+
extern const struct _mp_obj_module_t esp32_module;
165166
extern const struct _mp_obj_module_t utime_module;
166167
extern const struct _mp_obj_module_t uos_module;
167168
extern const struct _mp_obj_module_t mp_module_usocket;
@@ -171,6 +172,7 @@ extern const struct _mp_obj_module_t mp_module_onewire;
171172

172173
#define MICROPY_PORT_BUILTIN_MODULES \
173174
{ MP_OBJ_NEW_QSTR(MP_QSTR_esp), (mp_obj_t)&esp_module }, \
175+
{ MP_OBJ_NEW_QSTR(MP_QSTR_esp32), (mp_obj_t)&esp32_module }, \
174176
{ MP_OBJ_NEW_QSTR(MP_QSTR_utime), (mp_obj_t)&utime_module }, \
175177
{ MP_OBJ_NEW_QSTR(MP_QSTR_uos), (mp_obj_t)&uos_module }, \
176178
{ MP_OBJ_NEW_QSTR(MP_QSTR_usocket), (mp_obj_t)&mp_module_usocket }, \

0 commit comments

Comments
 (0)