Skip to content

Commit 61e4d26

Browse files
authored
Merge pull request #1 from Peetz0r/dev-deepsleep
Dev bluetooth plus deepsleep
2 parents 1d2a575 + cdb281f commit 61e4d26

File tree

5 files changed

+340
-1
lines changed

5 files changed

+340
-1
lines changed

esp32/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,9 @@ SRC_C = \
172172
modsocket.c \
173173
modesp.c \
174174
espneopixel.c \
175+
machine_rtc.c \
175176
network_bluetooth.c \
177+
176178
machine_hw_spi.c \
177179
mpthreadport.c \
178180
$(SRC_MOD)

esp32/machine_rtc.c

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
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+
42+
typedef struct _machine_rtc_obj_t {
43+
mp_obj_base_t base;
44+
} machine_rtc_obj_t;
45+
46+
#define MACHINE_RTC_VALID_EXT_PINS \
47+
( \
48+
(1ll << 0) | \
49+
(1ll << 2) | \
50+
(1ll << 4) | \
51+
(1ll << 12) | \
52+
(1ll << 13) | \
53+
(1ll << 14) | \
54+
(1ll << 15) | \
55+
(1ll << 25) | \
56+
(1ll << 26) | \
57+
(1ll << 27) | \
58+
(1ll << 32) | \
59+
(1ll << 33) | \
60+
(1ll << 34) | \
61+
(1ll << 35) | \
62+
(1ll << 36) | \
63+
(1ll << 37) | \
64+
(1ll << 38) | \
65+
(1ll << 39) \
66+
)
67+
68+
#define MACHINE_RTC_LAST_EXT_PIN 39
69+
70+
// singleton RTC object
71+
STATIC const machine_rtc_obj_t machine_rtc_obj = {{&machine_rtc_type}};
72+
73+
machine_rtc_config_t machine_rtc_config = { 0 };
74+
75+
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) {
76+
// check arguments
77+
mp_arg_check_num(n_args, n_kw, 0, 0, false);
78+
79+
// return constant object
80+
return (mp_obj_t)&machine_rtc_obj;
81+
}
82+
83+
STATIC mp_obj_t machine_rtc_datetime_helper(mp_uint_t n_args, const mp_obj_t *args) {
84+
if (n_args == 1) {
85+
// Get time
86+
87+
struct timeval tv;
88+
struct tm tm;
89+
90+
gettimeofday(&tv, NULL);
91+
92+
gmtime_r(&tv.tv_sec, &tm);
93+
94+
mp_obj_t tuple[8] = {
95+
mp_obj_new_int(tm.tm_year + 1900),
96+
mp_obj_new_int(tm.tm_mon + 1),
97+
mp_obj_new_int(tm.tm_mday),
98+
mp_obj_new_int(tm.tm_wday + 1),
99+
mp_obj_new_int(tm.tm_hour),
100+
mp_obj_new_int(tm.tm_min),
101+
mp_obj_new_int(tm.tm_sec),
102+
mp_obj_new_int(tv.tv_usec)
103+
};
104+
105+
return mp_obj_new_tuple(8, tuple);
106+
} else {
107+
// Set time
108+
109+
mp_obj_t *items;
110+
mp_obj_get_array_fixed_n(args[1], 8, &items);
111+
struct tm tm;
112+
struct timeval tv;
113+
114+
tm.tm_year = mp_obj_get_int(items[0]) - 1900;
115+
tm.tm_mon = mp_obj_get_int(items[1]) - 1;
116+
tm.tm_mday = mp_obj_get_int(items[2]);
117+
tm.tm_hour = mp_obj_get_int(items[4]);
118+
tm.tm_min = mp_obj_get_int(items[5]);
119+
tm.tm_sec = mp_obj_get_int(items[6]);
120+
121+
tv.tv_sec = mktime(&tm);
122+
tv.tv_usec = mp_obj_get_int(items[7]);
123+
124+
settimeofday(&tv, NULL);
125+
126+
return mp_const_none;
127+
}
128+
}
129+
STATIC mp_obj_t machine_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) {
130+
return machine_rtc_datetime_helper(n_args, args);
131+
}
132+
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_rtc_datetime_obj, 1, 2, machine_rtc_datetime);
133+
134+
STATIC mp_obj_t machine_rtc_init(mp_obj_t self_in, mp_obj_t date) {
135+
mp_obj_t args[2] = {self_in, date};
136+
machine_rtc_datetime_helper(2, args);
137+
return mp_const_none;
138+
}
139+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_rtc_init_obj, machine_rtc_init);
140+
141+
STATIC mp_obj_t machine_rtc_memory(mp_uint_t n_args, const mp_obj_t *args) {
142+
143+
if (n_args == 1) {
144+
// read RTC memory
145+
146+
// FIXME; need to update IDF
147+
148+
return mp_const_none;
149+
} else {
150+
// write RTC memory
151+
152+
// FIXME; need to update IDF
153+
154+
return mp_const_none;
155+
}
156+
157+
}
158+
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_rtc_memory_obj, 1, 2, machine_rtc_memory);
159+
160+
STATIC mp_obj_t machine_rtc_wake_on_touch(mp_obj_t self_in, const mp_obj_t wake) {
161+
(void)self_in; // unused
162+
163+
machine_rtc_config.wake_on_touch = mp_obj_is_true(wake);
164+
return mp_const_none;
165+
}
166+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_rtc_wake_on_touch_obj, machine_rtc_wake_on_touch);
167+
168+
STATIC mp_obj_t machine_rtc_wake_on_ext0(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
169+
enum {ARG_pin, ARG_level};
170+
const mp_arg_t allowed_args[] = {
171+
{ MP_QSTR_pin, MP_ARG_OBJ, {.u_obj = mp_obj_new_int(machine_rtc_config.ext0_pin)} },
172+
{ MP_QSTR_level, MP_ARG_BOOL, {.u_bool = machine_rtc_config.ext0_level} },
173+
};
174+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
175+
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
176+
177+
if (args[ARG_pin].u_obj == mp_const_none) {
178+
machine_rtc_config.ext0_pin = -1; // "None"
179+
} else {
180+
gpio_num_t pin_id = machine_pin_get_id(args[ARG_pin].u_obj);
181+
if (pin_id != machine_rtc_config.ext0_pin) {
182+
if (!((1ll << pin_id) & MACHINE_RTC_VALID_EXT_PINS)) {
183+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "invalid pin"));
184+
}
185+
machine_rtc_config.ext0_pin = pin_id;
186+
}
187+
}
188+
189+
machine_rtc_config.ext0_level = args[ARG_level].u_bool;
190+
191+
return mp_const_none;
192+
}
193+
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_rtc_wake_on_ext0_obj, 1, machine_rtc_wake_on_ext0);
194+
195+
STATIC mp_obj_t machine_rtc_wake_on_ext1(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
196+
enum {ARG_pins, ARG_level};
197+
const mp_arg_t allowed_args[] = {
198+
{ MP_QSTR_pins, MP_ARG_OBJ, {.u_obj = mp_const_none} },
199+
{ MP_QSTR_level, MP_ARG_BOOL, {.u_bool = machine_rtc_config.ext1_level} },
200+
};
201+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
202+
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
203+
uint64_t ext1_pins = machine_rtc_config.ext1_pins;
204+
205+
206+
// Check that all pins are allowed
207+
if (args[ARG_pins].u_obj != mp_const_none) {
208+
mp_uint_t len = 0;
209+
mp_obj_t *elem;
210+
mp_obj_get_array(args[ARG_pins].u_obj, &len, &elem);
211+
ext1_pins = 0;
212+
213+
for (int i = 0; i < len; i++) {
214+
215+
gpio_num_t pin_id = machine_pin_get_id(elem[i]);
216+
// mp_int_t pin = mp_obj_get_int(elem[i]);
217+
uint64_t pin_bit = (1ll << pin_id);
218+
219+
if (!(pin_bit & MACHINE_RTC_VALID_EXT_PINS)) {
220+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "invalid pin"));
221+
break;
222+
}
223+
ext1_pins |= pin_bit;
224+
}
225+
}
226+
227+
machine_rtc_config.ext1_level = args[ARG_level].u_bool;
228+
machine_rtc_config.ext1_pins = ext1_pins;
229+
230+
return mp_const_none;
231+
}
232+
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_rtc_wake_on_ext1_obj, 1, machine_rtc_wake_on_ext1);
233+
234+
STATIC const mp_map_elem_t machine_rtc_locals_dict_table[] = {
235+
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&machine_rtc_datetime_obj },
236+
{ MP_OBJ_NEW_QSTR(MP_QSTR_datetime), (mp_obj_t)&machine_rtc_datetime_obj },
237+
{ MP_OBJ_NEW_QSTR(MP_QSTR_memory), (mp_obj_t)&machine_rtc_memory_obj },
238+
// FIXME -- need to enable touch IRQ for this to work,
239+
// doesn't seem possible in the IDF presently.
240+
// { MP_OBJ_NEW_QSTR(MP_QSTR_wake_on_touch), (mp_obj_t)&machine_rtc_wake_on_touch_obj },
241+
{ MP_OBJ_NEW_QSTR(MP_QSTR_wake_on_ext0), (mp_obj_t)&machine_rtc_wake_on_ext0_obj },
242+
{ MP_OBJ_NEW_QSTR(MP_QSTR_wake_on_ext1), (mp_obj_t)&machine_rtc_wake_on_ext1_obj },
243+
{ MP_OBJ_NEW_QSTR(MP_QSTR_WAKEUP_ALL_LOW), mp_const_false },
244+
{ MP_OBJ_NEW_QSTR(MP_QSTR_WAKEUP_ANY_HIGH), mp_const_true },
245+
};
246+
STATIC MP_DEFINE_CONST_DICT(machine_rtc_locals_dict, machine_rtc_locals_dict_table);
247+
248+
const mp_obj_type_t machine_rtc_type = {
249+
{ &mp_type_type },
250+
.name = MP_QSTR_RTC,
251+
.make_new = machine_rtc_make_new,
252+
.locals_dict = (mp_obj_t)&machine_rtc_locals_dict,
253+
};

esp32/machine_rtc.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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+
#ifndef MICROPY_INCLUDED_ESP32_MACINE_RTC_H
28+
#define MICROPY_INCLUDED_ESP32_MACINE_RTC_H
29+
30+
typedef struct {
31+
uint64_t ext1_pins; // set bit == pin#
32+
int8_t ext0_pin; // just the pin#, -1 == None
33+
bool wake_on_touch : 1;
34+
bool ext0_level : 1;
35+
bool ext1_level : 1;
36+
} machine_rtc_config_t;
37+
38+
39+
#endif

esp32/modmachine.c

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "freertos/task.h"
3535
#include "rom/ets_sys.h"
3636
#include "esp_system.h"
37+
#include "driver/touch_pad.h"
3738

3839
#include "py/obj.h"
3940
#include "py/runtime.h"
@@ -42,9 +43,12 @@
4243
#include "extmod/machine_i2c.h"
4344
#include "extmod/machine_spi.h"
4445
#include "modmachine.h"
46+
#include "machine_rtc.h"
4547

4648
#if MICROPY_PY_MACHINE
4749

50+
extern machine_rtc_config_t machine_rtc_config;
51+
4852
STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
4953
if (n_args == 0) {
5054
// get
@@ -54,7 +58,7 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
5458
mp_int_t freq = mp_obj_get_int(args[0]) / 1000000;
5559
if (freq != 80 && freq != 160 && freq != 240) {
5660
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
57-
"frequency can only be either 80Mhz, 160MHz or 240MHz"));
61+
"frequency can only be either 80Mhz, 160MHz or 240MHz"));
5862
}
5963
/*
6064
system_update_cpu_freq(freq);
@@ -64,6 +68,43 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
6468
}
6569
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_freq_obj, 0, 1, machine_freq);
6670

71+
STATIC mp_obj_t machine_deepsleep(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
72+
73+
enum {ARG_sleep_ms};
74+
const mp_arg_t allowed_args[] = {
75+
{ MP_QSTR_sleep_ms, MP_ARG_INT, { .u_int = 0 } },
76+
};
77+
78+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
79+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
80+
81+
82+
mp_int_t expiry = args[ARG_sleep_ms].u_int;
83+
84+
if (expiry != 0) {
85+
esp_deep_sleep_enable_timer_wakeup(expiry * 1000);
86+
}
87+
88+
if (machine_rtc_config.ext0_pin != -1) {
89+
esp_deep_sleep_enable_ext0_wakeup(machine_rtc_config.ext0_pin, machine_rtc_config.ext0_level ? 1 : 0);
90+
}
91+
92+
if (machine_rtc_config.ext1_pins != 0) {
93+
esp_deep_sleep_enable_ext1_wakeup(
94+
machine_rtc_config.ext1_pins,
95+
machine_rtc_config.ext1_level ? ESP_EXT1_WAKEUP_ANY_HIGH : ESP_EXT1_WAKEUP_ALL_LOW);
96+
}
97+
98+
if (machine_rtc_config.wake_on_touch) {
99+
esp_deep_sleep_enable_touchpad_wakeup();
100+
}
101+
102+
esp_deep_sleep_start();
103+
return mp_const_none;
104+
}
105+
106+
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_deepsleep_obj, 0, machine_deepsleep);
107+
67108
STATIC mp_obj_t machine_reset(void) {
68109
esp_restart();
69110
return mp_const_none;
@@ -105,6 +146,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
105146

106147
{ MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&machine_freq_obj) },
107148
{ MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&machine_reset_obj) },
149+
{ MP_ROM_QSTR(MP_QSTR_deepsleep), MP_ROM_PTR(&machine_deepsleep_obj) },
108150
{ MP_ROM_QSTR(MP_QSTR_unique_id), MP_ROM_PTR(&machine_unique_id_obj) },
109151
{ MP_ROM_QSTR(MP_QSTR_idle), MP_ROM_PTR(&machine_idle_obj) },
110152

@@ -113,11 +155,13 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
113155

114156
{ MP_ROM_QSTR(MP_QSTR_time_pulse_us), MP_ROM_PTR(&machine_time_pulse_us_obj) },
115157

158+
116159
{ MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) },
117160
{ MP_ROM_QSTR(MP_QSTR_TouchPad), MP_ROM_PTR(&machine_touchpad_type) },
118161
{ MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) },
119162
{ MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&machine_dac_type) },
120163
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) },
164+
{ MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&machine_rtc_type) },
121165
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&mp_machine_soft_spi_type) },
122166
};
123167

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy