Skip to content

Commit f9869bd

Browse files
committed
ports/esp32:* Implementation of deep sleep, esp32 module, machine.RTC
1 parent 42c4dd0 commit f9869bd

File tree

11 files changed

+584
-38
lines changed

11 files changed

+584
-38
lines changed

ports/esp32/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,13 @@ 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 \
153154
machine_wdt.c \
154155
mpthreadport.c \
156+
machine_rtc.c \
155157
$(SRC_MOD)
156158

157159
EXTMOD_SRC_C = $(addprefix extmod/,\
@@ -251,6 +253,7 @@ ESPIDF_ESP32_O = $(addprefix $(ESPCOMP)/esp32/,\
251253
dport_access.o \
252254
wifi_init.o \
253255
wifi_internal.o \
256+
sleep_modes.o \
254257
)
255258

256259
ESPIDF_HEAP_O = $(addprefix $(ESPCOMP)/heap/,\

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/machine_rtc.c

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
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+
* Copyright (c) 2017 "Tom Manning" <tom@manningetal.com>
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in
17+
* all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#include <stdio.h>
29+
#include <string.h>
30+
31+
#include <time.h>
32+
#include <sys/time.h>
33+
#include "driver/gpio.h"
34+
35+
#include "py/nlr.h"
36+
#include "py/obj.h"
37+
#include "py/runtime.h"
38+
#include "py/mphal.h"
39+
#include "timeutils.h"
40+
#include "modmachine.h"
41+
#include "machine_rtc.h"
42+
43+
typedef struct _machine_rtc_obj_t {
44+
mp_obj_base_t base;
45+
} machine_rtc_obj_t;
46+
47+
#define MEM_MAGIC 0x75507921
48+
/* There is 8K of rtc_slow_memory, but some is used by the system software
49+
If the USER_MAXLEN is set to high, the following compile error will happen:
50+
region `rtc_slow_seg' overflowed by N bytes
51+
The current system software allows almost 4096 to be used.
52+
To avoid running into issues if the system software uses more, 2048 was picked as a max length
53+
*/
54+
#define MEM_USER_MAXLEN 2048
55+
RTC_DATA_ATTR uint32_t rtc_user_mem_magic;
56+
RTC_DATA_ATTR uint32_t rtc_user_mem_len;
57+
RTC_DATA_ATTR uint8_t rtc_user_mem_data[MEM_USER_MAXLEN];
58+
59+
// singleton RTC object
60+
STATIC const machine_rtc_obj_t machine_rtc_obj = {{&machine_rtc_type}};
61+
62+
machine_rtc_config_t machine_rtc_config = {
63+
.ext1_pins = 0,
64+
.ext0_pin = -1
65+
};
66+
67+
STATIC mp_obj_t machine_rtc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
68+
// check arguments
69+
mp_arg_check_num(n_args, n_kw, 0, 0, false);
70+
71+
// return constant object
72+
return (mp_obj_t)&machine_rtc_obj;
73+
}
74+
75+
STATIC mp_obj_t machine_rtc_datetime_helper(mp_uint_t n_args, const mp_obj_t *args) {
76+
if (n_args == 1) {
77+
// Get time
78+
79+
struct timeval tv;
80+
struct tm tm;
81+
82+
gettimeofday(&tv, NULL);
83+
84+
gmtime_r(&tv.tv_sec, &tm);
85+
86+
mp_obj_t tuple[8] = {
87+
mp_obj_new_int(tm.tm_year + 1930),
88+
mp_obj_new_int(tm.tm_mon + 1),
89+
mp_obj_new_int(tm.tm_mday),
90+
mp_obj_new_int(tm.tm_wday + 1),
91+
mp_obj_new_int(tm.tm_hour),
92+
mp_obj_new_int(tm.tm_min),
93+
mp_obj_new_int(tm.tm_sec),
94+
mp_obj_new_int(tv.tv_usec)
95+
};
96+
97+
return mp_obj_new_tuple(8, tuple);
98+
} else {
99+
// Set time
100+
101+
mp_obj_t *items;
102+
mp_obj_get_array_fixed_n(args[1], 8, &items);
103+
struct tm tm;
104+
struct timeval tv;
105+
106+
tm.tm_year = mp_obj_get_int(items[0]) - 1930;
107+
tm.tm_mon = mp_obj_get_int(items[1]) - 1;
108+
tm.tm_mday = mp_obj_get_int(items[2]);
109+
tm.tm_hour = mp_obj_get_int(items[4]);
110+
tm.tm_min = mp_obj_get_int(items[5]);
111+
tm.tm_sec = mp_obj_get_int(items[6]);
112+
113+
tv.tv_sec = mktime(&tm);
114+
tv.tv_usec = mp_obj_get_int(items[7]);
115+
116+
settimeofday(&tv, NULL);
117+
118+
return mp_const_none;
119+
}
120+
}
121+
STATIC mp_obj_t machine_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) {
122+
return machine_rtc_datetime_helper(n_args, args);
123+
}
124+
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_rtc_datetime_obj, 1, 2, machine_rtc_datetime);
125+
126+
STATIC mp_obj_t machine_rtc_init(mp_obj_t self_in, mp_obj_t date) {
127+
mp_obj_t args[2] = {self_in, date};
128+
machine_rtc_datetime_helper(2, args);
129+
130+
if (rtc_user_mem_magic != MEM_MAGIC) {
131+
rtc_user_mem_magic = MEM_MAGIC;
132+
rtc_user_mem_len = 0;
133+
}
134+
return mp_const_none;
135+
}
136+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_rtc_init_obj, machine_rtc_init);
137+
138+
STATIC mp_obj_t machine_rtc_memory(mp_uint_t n_args, const mp_obj_t *args) {
139+
if (n_args == 1) {
140+
// read RTC memory
141+
uint32_t len = rtc_user_mem_len;
142+
uint8_t rtcram[MEM_USER_MAXLEN];
143+
memcpy( (char *) rtcram, (char *) rtc_user_mem_data, len);
144+
return mp_obj_new_bytes(rtcram, len);
145+
} else {
146+
// write RTC memory
147+
mp_buffer_info_t bufinfo;
148+
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
149+
150+
if (bufinfo.len > MEM_USER_MAXLEN) {
151+
mp_raise_ValueError("buffer too long");
152+
}
153+
memcpy( (char *) rtc_user_mem_data, (char *) bufinfo.buf, bufinfo.len);
154+
rtc_user_mem_len = bufinfo.len;
155+
return mp_const_none;
156+
}
157+
}
158+
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_rtc_memory_obj, 1, 2, machine_rtc_memory);
159+
160+
STATIC const mp_map_elem_t machine_rtc_locals_dict_table[] = {
161+
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&machine_rtc_datetime_obj },
162+
{ MP_OBJ_NEW_QSTR(MP_QSTR_datetime), (mp_obj_t)&machine_rtc_datetime_obj },
163+
{ MP_OBJ_NEW_QSTR(MP_QSTR_memory), (mp_obj_t)&machine_rtc_memory_obj },
164+
};
165+
STATIC MP_DEFINE_CONST_DICT(machine_rtc_locals_dict, machine_rtc_locals_dict_table);
166+
167+
const mp_obj_type_t machine_rtc_type = {
168+
{ &mp_type_type },
169+
.name = MP_QSTR_RTC,
170+
.make_new = machine_rtc_make_new,
171+
.locals_dict = (mp_obj_t)&machine_rtc_locals_dict,
172+
};

ports/esp32/machine_rtc.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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+
* Copyright (c) 2017 "Tom Manning" <tom@manningetal.com>
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in
17+
* all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#ifndef MICROPY_INCLUDED_ESP32_MACHINE_RTC_H
29+
#define MICROPY_INCLUDED_ESP32_MACHINE_RTC_H
30+
#include "modmachine.h"
31+
32+
typedef struct {
33+
uint64_t ext1_pins; // set bit == pin#
34+
int8_t ext0_pin; // just the pin#, -1 == None
35+
bool wake_on_touch : 1;
36+
bool ext0_level : 1;
37+
wake_type_t ext0_wake_types;
38+
bool ext1_level : 1;
39+
} machine_rtc_config_t;
40+
41+
42+
#endif

ports/esp32/modesp.c

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#include <stdio.h>
3131

3232
#include "rom/gpio.h"
33-
#include "esp_log.h"
3433
#include "esp_spi_flash.h"
3534

3635
#include "py/runtime.h"
@@ -39,23 +38,6 @@
3938
#include "drivers/dht/dht.h"
4039
#include "modesp.h"
4140

42-
STATIC mp_obj_t esp_osdebug(size_t n_args, const mp_obj_t *args) {
43-
esp_log_level_t level = LOG_LOCAL_LEVEL;
44-
if (n_args == 2) {
45-
level = mp_obj_get_int(args[1]);
46-
}
47-
if (args[0] == mp_const_none) {
48-
// Disable logging
49-
esp_log_level_set("*", ESP_LOG_ERROR);
50-
} else {
51-
// Enable logging at the given level
52-
// TODO args[0] should set the UART to which debug is sent
53-
esp_log_level_set("*", level);
54-
}
55-
return mp_const_none;
56-
}
57-
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_osdebug_obj, 1, 2, esp_osdebug);
58-
5941
STATIC mp_obj_t esp_flash_read(mp_obj_t offset_in, mp_obj_t buf_in) {
6042
mp_int_t offset = mp_obj_get_int(offset_in);
6143
mp_buffer_info_t bufinfo;
@@ -125,8 +107,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(esp_neopixel_write_obj, esp_neopixel_write_);
125107
STATIC const mp_rom_map_elem_t esp_module_globals_table[] = {
126108
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_esp) },
127109

128-
{ MP_ROM_QSTR(MP_QSTR_osdebug), MP_ROM_PTR(&esp_osdebug_obj) },
129-
130110
{ MP_ROM_QSTR(MP_QSTR_flash_read), MP_ROM_PTR(&esp_flash_read_obj) },
131111
{ MP_ROM_QSTR(MP_QSTR_flash_write), MP_ROM_PTR(&esp_flash_write_obj) },
132112
{ MP_ROM_QSTR(MP_QSTR_flash_erase), MP_ROM_PTR(&esp_flash_erase_obj) },
@@ -138,14 +118,6 @@ STATIC const mp_rom_map_elem_t esp_module_globals_table[] = {
138118

139119
{ MP_ROM_QSTR(MP_QSTR_neopixel_write), MP_ROM_PTR(&esp_neopixel_write_obj) },
140120
{ MP_ROM_QSTR(MP_QSTR_dht_readinto), MP_ROM_PTR(&dht_readinto_obj) },
141-
142-
// Constants for second arg of osdebug()
143-
{ MP_ROM_QSTR(MP_QSTR_LOG_NONE), MP_ROM_INT((mp_uint_t)ESP_LOG_NONE)},
144-
{ MP_ROM_QSTR(MP_QSTR_LOG_ERROR), MP_ROM_INT((mp_uint_t)ESP_LOG_ERROR)},
145-
{ MP_ROM_QSTR(MP_QSTR_LOG_WARNING), MP_ROM_INT((mp_uint_t)ESP_LOG_WARN)},
146-
{ MP_ROM_QSTR(MP_QSTR_LOG_INFO), MP_ROM_INT((mp_uint_t)ESP_LOG_INFO)},
147-
{ MP_ROM_QSTR(MP_QSTR_LOG_DEBUG), MP_ROM_INT((mp_uint_t)ESP_LOG_DEBUG)},
148-
{ MP_ROM_QSTR(MP_QSTR_LOG_VERBOSE), MP_ROM_INT((mp_uint_t)ESP_LOG_VERBOSE)},
149121
};
150122

151123
STATIC MP_DEFINE_CONST_DICT(esp_module_globals, esp_module_globals_table);

0 commit comments

Comments
 (0)