add pretend-to-sleep functionality

This commit is contained in:
microDev 2020-12-30 22:11:22 +05:30
parent ecd7c0878e
commit c7f68022ef
No known key found for this signature in database
GPG Key ID: 2C0867BE60967730
8 changed files with 91 additions and 39 deletions

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-12-18 20:40+0530\n"
"POT-Creation-Date: 2020-12-22 22:54+0530\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -1463,7 +1463,7 @@ msgstr ""
msgid "Only one alarm.time alarm can be set."
msgstr ""
#: ports/esp32s2/common-hal/alarm/__init__.c
#: ports/esp32s2/common-hal/alarm/touch/TouchAlarm.c
msgid "Only one alarm.touch alarm can be set."
msgstr ""
@ -1841,7 +1841,7 @@ msgstr ""
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: ports/esp32s2/common-hal/alarm/__init__.c
#: ports/esp32s2/common-hal/alarm/touch/TouchAlarm.c
msgid "TouchAlarm not available in light sleep"
msgstr ""

View File

@ -103,7 +103,6 @@ mp_obj_t common_hal_alarm_get_wake_alarm(void) {
// Set up light sleep or deep sleep alarms.
STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
bool time_alarm_set = false;
bool touch_alarm_set = false;
alarm_time_time_alarm_obj_t *time_alarm = MP_OBJ_NULL;
for (size_t i = 0; i < n_alarms; i++) {
@ -115,23 +114,13 @@ STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t
}
time_alarm = MP_OBJ_TO_PTR(alarms[i]);
time_alarm_set = true;
} else if (MP_OBJ_IS_TYPE(alarms[i], &alarm_touch_touchalarm_type)) {
if (!touch_alarm_set) {
if (deep_sleep) {
alarm_touch_touchalarm_set_alarm(MP_OBJ_TO_PTR(alarms[i]));
touch_alarm_set = true;
} else {
mp_raise_NotImplementedError(translate("TouchAlarm not available in light sleep"));
}
} else {
mp_raise_ValueError(translate("Only one alarm.touch alarm can be set."));
}
}
}
if (time_alarm_set) {
alarm_time_timealarm_set_alarm(time_alarm);
}
alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms);
}
STATIC void _idle_until_alarm(void) {

View File

@ -27,9 +27,12 @@
#include "shared-bindings/alarm/touch/TouchAlarm.h"
#include "shared-bindings/microcontroller/__init__.h"
#include "peripherals/touch.h"
#include "esp_sleep.h"
#include "peripherals/touch.h"
#include "supervisor/esp_port.h"
static volatile bool woke_up = false;
static touch_pad_t touch_channel = TOUCH_PAD_MAX;
void common_hal_alarm_touch_touchalarm_construct(alarm_touch_touchalarm_obj_t *self, const mcu_pin_obj_t *pin) {
if (pin->touch_channel == TOUCH_PAD_MAX) {
@ -39,7 +42,7 @@ void common_hal_alarm_touch_touchalarm_construct(alarm_touch_touchalarm_obj_t *s
self->pin = pin;
}
mp_obj_t alarm_touch_touchalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
mp_obj_t alarm_touch_touchalarm_get_wakeup_alarm(const size_t n_alarms, const mp_obj_t *alarms) {
// First, check to see if we match any given alarms.
for (size_t i = 0; i < n_alarms; i++) {
if (MP_OBJ_IS_TYPE(alarms[i], &alarm_touch_touchalarm_type)) {
@ -47,8 +50,6 @@ mp_obj_t alarm_touch_touchalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t
}
}
gpio_num_t pin_number = esp_sleep_get_touchpad_wakeup_status();
alarm_touch_touchalarm_obj_t *alarm = m_new_obj(alarm_touch_touchalarm_obj_t);
alarm->base.type = &alarm_touch_touchalarm_type;
alarm->pin = NULL;
@ -56,7 +57,7 @@ mp_obj_t alarm_touch_touchalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t
// Map the pin number back to a pin object.
for (size_t i = 0; i < mcu_pin_globals.map.used; i++) {
const mcu_pin_obj_t* pin_obj = MP_OBJ_TO_PTR(mcu_pin_globals.map.table[i].value);
if (pin_obj->number == pin_number) {
if (pin_obj->touch_channel == touch_channel) {
alarm->pin = mcu_pin_globals.map.table[i].value;
break;
}
@ -65,16 +66,67 @@ mp_obj_t alarm_touch_touchalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t
return alarm;
}
static touch_pad_t touch_channel = TOUCH_PAD_MAX;
// This is used to wake the main CircuitPython task.
void touch_interrupt(void *arg) {
(void) arg;
woke_up = true;
BaseType_t task_wakeup;
vTaskNotifyGiveFromISR(circuitpython_task, &task_wakeup);
if (task_wakeup) {
portYIELD_FROM_ISR();
}
}
void alarm_touch_touchalarm_set_alarm(alarm_touch_touchalarm_obj_t *self) {
touch_channel = (touch_pad_t)self->pin->number;
esp_sleep_enable_touchpad_wakeup();
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms) {
bool touch_alarm_set = false;
alarm_touch_touchalarm_obj_t *touch_alarm = MP_OBJ_NULL;
for (size_t i = 0; i < n_alarms; i++) {
if (MP_OBJ_IS_TYPE(alarms[i], &alarm_touch_touchalarm_type)) {
if (!touch_alarm_set) {
if (deep_sleep) {
touch_alarm = MP_OBJ_TO_PTR(alarms[i]);
touch_alarm_set = true;
} else {
mp_raise_NotImplementedError(translate("TouchAlarm not available in light sleep"));
}
} else {
mp_raise_ValueError(translate("Only one alarm.touch alarm can be set."));
}
}
}
if (!touch_alarm_set) {
return;
}
touch_channel = touch_alarm->pin->touch_channel;
// configure interrupt for pretend to deep sleep
// this will be disabled if we actually deep sleep
// intialize touchpad
peripherals_touch_reset();
peripherals_touch_never_reset(true);
peripherals_touch_init(touch_channel);
// wait for touch data to reset
mp_hal_delay_ms(10);
// configure trigger threshold
uint32_t touch_value;
touch_pad_read_benchmark(touch_channel, &touch_value);
touch_pad_set_thresh(touch_channel, touch_value * 0.1); //10%
// configure touch interrupt
touch_pad_timeout_set(true, SOC_TOUCH_PAD_THRESHOLD_MAX);
touch_pad_isr_register(touch_interrupt, NULL, TOUCH_PAD_INTR_MASK_ALL);
touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE | TOUCH_PAD_INTR_MASK_TIMEOUT);
}
void alarm_touch_touchalarm_prepare_for_deep_sleep(void) {
// intialize touchpad
peripherals_touch_never_reset(false);
peripherals_touch_reset();
peripherals_touch_init(touch_channel);
// configure touchpad for sleep
@ -84,15 +136,22 @@ void alarm_touch_touchalarm_prepare_for_deep_sleep(void) {
// wait for touch data to reset
mp_hal_delay_ms(10);
// configure trigger threshold
uint32_t touch_value;
touch_pad_sleep_channel_read_smooth(touch_channel, &touch_value);
touch_pad_sleep_set_threshold(touch_channel, touch_value * 0.1); //10%
// enable touchpad wakeup
esp_sleep_enable_touchpad_wakeup();
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
}
bool alarm_touch_touchalarm_woke_us_up(void) {
return false;
return woke_up;
}
void alarm_touch_touchalarm_reset(void) {
woke_up = false;
touch_channel = TOUCH_PAD_MAX;
peripherals_touch_never_reset(false);
}

View File

@ -36,9 +36,9 @@ typedef struct {
} alarm_touch_touchalarm_obj_t;
// Find the alarm object that caused us to wake up or create an equivalent one.
mp_obj_t alarm_touch_touchalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms);
mp_obj_t alarm_touch_touchalarm_get_wakeup_alarm(const size_t n_alarms, const mp_obj_t *alarms);
// Check for the wake up alarm from pretend deep sleep.
void alarm_touch_touchalarm_set_alarm(alarm_touch_touchalarm_obj_t *self);
void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms);
void alarm_touch_touchalarm_prepare_for_deep_sleep(void);
bool alarm_touch_touchalarm_woke_us_up(void);
void alarm_touch_touchalarm_reset(void);

View File

@ -27,12 +27,11 @@
#include "shared-bindings/touchio/TouchIn.h"
#include "py/runtime.h"
#include "driver/touch_pad.h"
#include "peripherals/touch.h"
static uint16_t get_raw_reading(touchio_touchin_obj_t *self) {
uint32_t touch_value;
touch_pad_read_raw_data((touch_pad_t)self->pin->touch_channel, &touch_value);
touch_pad_read_raw_data(self->pin->touch_channel, &touch_value);
if (touch_value > UINT16_MAX) {
return UINT16_MAX;
}
@ -47,14 +46,11 @@ void common_hal_touchio_touchin_construct(touchio_touchin_obj_t* self,
claim_pin(pin);
// initialize touchpad
peripherals_touch_init((touch_pad_t)pin->touch_channel);
peripherals_touch_init(pin->touch_channel);
// wait for touch data to reset
mp_hal_delay_ms(10);
// Initial values for pins will vary, depending on what peripherals the pins
// share on-chip.
// Set a "touched" threshold not too far above the initial value.
// For simple finger touch, the values may vary as much as a factor of two,
// but for touches using fruit or other objects, the difference is much less.

View File

@ -44,7 +44,7 @@ typedef struct {
gpio_num_t number;
uint8_t adc_index:2;
uint8_t adc_channel:6;
uint8_t touch_channel;
touch_pad_t touch_channel;
} mcu_pin_obj_t;
extern const mcu_pin_obj_t pin_GPIO0;

View File

@ -24,18 +24,25 @@
* THE SOFTWARE.
*/
#include "components/soc/include/hal/gpio_types.h"
// above include fixes build error in idf@v4.2
#include "peripherals/touch.h"
static bool touch_inited = false;
static bool touch_never_reset = false;
void peripherals_touch_reset(void) {
if (touch_inited) {
if (touch_inited && !touch_never_reset) {
touch_pad_deinit();
touch_inited = false;
}
}
void peripherals_touch_init(touch_pad_t touchpad) {
void peripherals_touch_never_reset(const bool enable) {
touch_never_reset = enable;
}
void peripherals_touch_init(const touch_pad_t touchpad) {
if (!touch_inited) {
touch_pad_init();
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);

View File

@ -30,6 +30,7 @@
#include "driver/touch_pad.h"
extern void peripherals_touch_reset(void);
extern void peripherals_touch_init(touch_pad_t touchpad);
extern void peripherals_touch_never_reset(const bool enable);
extern void peripherals_touch_init(const touch_pad_t touchpad);
#endif // MICROPY_INCLUDED_ESP32S2_PERIPHERALS_TOUCH_HANDLER_H