Extract EXTI, create base sleep framework
This commit is contained in:
parent
766e79ad3d
commit
f1792c8474
8
main.c
8
main.c
|
@ -157,9 +157,9 @@ STATIC void start_mp(supervisor_allocation* heap) {
|
||||||
|
|
||||||
#if CIRCUITPY_ALARM
|
#if CIRCUITPY_ALARM
|
||||||
// Record which alarm woke us up, if any. An object may be created so the heap must be functional.
|
// Record which alarm woke us up, if any. An object may be created so the heap must be functional.
|
||||||
alarm_save_wake_alarm();
|
common_hal_alarm_save_wake_alarm();
|
||||||
// Reset alarm module only after we retrieved the wakeup alarm.
|
// Reset alarm module only after we retrieved the wakeup alarm.
|
||||||
alarm_reset();
|
common_hal_alarm_reset();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CIRCUITPY_NETWORK
|
#if CIRCUITPY_NETWORK
|
||||||
|
@ -357,7 +357,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
|
||||||
// an alarm alerts faster than our USB delay or if we pretended to deep
|
// an alarm alerts faster than our USB delay or if we pretended to deep
|
||||||
// sleep.
|
// sleep.
|
||||||
#if CIRCUITPY_ALARM
|
#if CIRCUITPY_ALARM
|
||||||
if (asleep && alarm_woken_from_sleep()) {
|
if (asleep && common_hal_alarm_woken_from_sleep()) {
|
||||||
serial_write_compressed(translate("Woken up by alarm.\n"));
|
serial_write_compressed(translate("Woken up by alarm.\n"));
|
||||||
board_init();
|
board_init();
|
||||||
supervisor_set_run_reason(RUN_REASON_STARTUP);
|
supervisor_set_run_reason(RUN_REASON_STARTUP);
|
||||||
|
@ -409,7 +409,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
|
||||||
if (!supervisor_workflow_active()) {
|
if (!supervisor_workflow_active()) {
|
||||||
// Enter true deep sleep. When we wake up we'll be back at the
|
// Enter true deep sleep. When we wake up we'll be back at the
|
||||||
// top of main(), not in this loop.
|
// top of main(), not in this loop.
|
||||||
alarm_enter_deep_sleep();
|
common_hal_alarm_enter_deep_sleep();
|
||||||
// Does not return.
|
// Does not return.
|
||||||
} else {
|
} else {
|
||||||
serial_write_compressed(translate("Pretending to deep sleep until alarm, CTRL-C or file write.\n"));
|
serial_write_compressed(translate("Pretending to deep sleep until alarm, CTRL-C or file write.\n"));
|
||||||
|
|
|
@ -54,7 +54,7 @@ const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void alarm_reset(void) {
|
void common_hal_alarm_reset(void) {
|
||||||
alarm_sleep_memory_reset();
|
alarm_sleep_memory_reset();
|
||||||
alarm_pin_pinalarm_reset();
|
alarm_pin_pinalarm_reset();
|
||||||
alarm_time_timealarm_reset();
|
alarm_time_timealarm_reset();
|
||||||
|
@ -75,10 +75,12 @@ STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) {
|
||||||
return esp_sleep_get_wakeup_cause();
|
return esp_sleep_get_wakeup_cause();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool alarm_woken_from_sleep(void) {
|
bool common_hal_alarm_woken_from_sleep(void) {
|
||||||
return _get_wakeup_cause() != ESP_SLEEP_WAKEUP_UNDEFINED;
|
return _get_wakeup_cause() != ESP_SLEEP_WAKEUP_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When called to populate the global dict, the module functions create new alarm objects.
|
||||||
|
// Otherwise, they scan the existing alarms for matches.
|
||||||
STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
esp_sleep_wakeup_cause_t cause = _get_wakeup_cause();
|
esp_sleep_wakeup_cause_t cause = _get_wakeup_cause();
|
||||||
switch (cause) {
|
switch (cause) {
|
||||||
|
@ -104,6 +106,8 @@ STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function is used to create a new alarm object for the global dict after deep sleep,
|
||||||
|
// rather than finding an existing one during runtime.
|
||||||
mp_obj_t common_hal_alarm_get_wake_alarm(void) {
|
mp_obj_t common_hal_alarm_get_wake_alarm(void) {
|
||||||
return _get_wake_alarm(0, NULL);
|
return _get_wake_alarm(0, NULL);
|
||||||
}
|
}
|
||||||
|
@ -120,8 +124,9 @@ STATIC void _idle_until_alarm(void) {
|
||||||
while (!mp_hal_is_interrupted()) {
|
while (!mp_hal_is_interrupted()) {
|
||||||
RUN_BACKGROUND_TASKS;
|
RUN_BACKGROUND_TASKS;
|
||||||
// Allow ctrl-C interrupt.
|
// Allow ctrl-C interrupt.
|
||||||
if (alarm_woken_from_sleep()) {
|
if (common_hal_alarm_woken_from_sleep()) {
|
||||||
alarm_save_wake_alarm();
|
// This saves the return of common_hal_alarm_get_wake_alarm through Shared Bindings
|
||||||
|
common_hal_alarm_save_wake_alarm();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
port_idle_until_interrupt();
|
port_idle_until_interrupt();
|
||||||
|
@ -139,7 +144,7 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t wake_alarm = _get_wake_alarm(n_alarms, alarms);
|
mp_obj_t wake_alarm = _get_wake_alarm(n_alarms, alarms);
|
||||||
alarm_reset();
|
alarm_pin_pinalarm_reset_alarms(n_alarms, alarms);
|
||||||
return wake_alarm;
|
return wake_alarm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +152,7 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala
|
||||||
_setup_sleep_alarms(true, n_alarms, alarms);
|
_setup_sleep_alarms(true, n_alarms, alarms);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NORETURN alarm_enter_deep_sleep(void) {
|
void NORETURN common_hal_alarm_enter_deep_sleep(void) {
|
||||||
alarm_pin_pinalarm_prepare_for_deep_sleep();
|
alarm_pin_pinalarm_prepare_for_deep_sleep();
|
||||||
alarm_touch_touchalarm_prepare_for_deep_sleep();
|
alarm_touch_touchalarm_prepare_for_deep_sleep();
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,6 @@
|
||||||
|
|
||||||
const alarm_sleep_memory_obj_t alarm_sleep_memory_obj;
|
const alarm_sleep_memory_obj_t alarm_sleep_memory_obj;
|
||||||
|
|
||||||
extern void alarm_reset(void);
|
extern void common_hal_alarm_reset(void);
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_ALARM__INIT__H
|
#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_ALARM__INIT__H
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
#include "shared-bindings/alarm_io/__init__.h"
|
|
||||||
|
|
||||||
#include "esp_sleep.h"
|
|
||||||
#include "driver/rtc_io.h"
|
|
||||||
|
|
||||||
mp_obj_t common_hal_alarm_io_pin_state (alarm_io_obj_t *self_in) {
|
|
||||||
if (!rtc_gpio_is_valid_gpio(self_in->gpio)) {
|
|
||||||
mp_raise_ValueError(translate("io must be rtc io"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self_in->pull && !self_in->level) {
|
|
||||||
for (uint8_t i = 0; i<=4; i+=2) {
|
|
||||||
if (self_in->gpio == i) {
|
|
||||||
mp_raise_ValueError(translate("IOs 0, 2 & 4 do not support internal pullup in sleep"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(esp_sleep_enable_ext0_wakeup(self_in->gpio, self_in->level)) {
|
|
||||||
case ESP_ERR_INVALID_ARG:
|
|
||||||
mp_raise_ValueError(translate("trigger level must be 0 or 1"));
|
|
||||||
case ESP_ERR_INVALID_STATE:
|
|
||||||
mp_raise_RuntimeError(translate("wakeup conflict"));
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self_in->pull) { (self_in->level) ? rtc_gpio_pulldown_en(self_in->gpio) : rtc_gpio_pullup_en(self_in->gpio); }
|
|
||||||
|
|
||||||
return self_in;
|
|
||||||
}
|
|
||||||
|
|
||||||
void common_hal_alarm_io_disable (void) {
|
|
||||||
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_EXT0 | ESP_SLEEP_WAKEUP_EXT1);
|
|
||||||
}
|
|
|
@ -220,6 +220,8 @@ SRC_C += \
|
||||||
boards/$(BOARD)/board.c \
|
boards/$(BOARD)/board.c \
|
||||||
boards/$(BOARD)/pins.c \
|
boards/$(BOARD)/pins.c \
|
||||||
peripherals/timers.c \
|
peripherals/timers.c \
|
||||||
|
peripherals/exti.c \
|
||||||
|
peripherals/rtc.c \
|
||||||
peripherals/stm32$(MCU_SERIES_LOWER)/clocks.c \
|
peripherals/stm32$(MCU_SERIES_LOWER)/clocks.c \
|
||||||
peripherals/stm32$(MCU_SERIES_LOWER)/$(MCU_VARIANT_LOWER)/pins.c \
|
peripherals/stm32$(MCU_SERIES_LOWER)/$(MCU_VARIANT_LOWER)/pins.c \
|
||||||
peripherals/stm32$(MCU_SERIES_LOWER)/$(MCU_VARIANT_LOWER)/gpio.c \
|
peripherals/stm32$(MCU_SERIES_LOWER)/$(MCU_VARIANT_LOWER)/gpio.c \
|
||||||
|
|
|
@ -37,3 +37,6 @@ bool board_requests_safe_mode(void) {
|
||||||
void reset_board(void) {
|
void reset_board(void) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void board_deinit(void) {
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Lucian Copeland for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "py/runtime.h"
|
||||||
|
#include "common-hal/alarm/SleepMemory.h"
|
||||||
|
|
||||||
|
void alarm_sleep_memory_reset(void) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t common_hal_alarm_sleep_memory_get_length(alarm_sleep_memory_obj_t *self) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool common_hal_alarm_sleep_memory_set_bytes(alarm_sleep_memory_obj_t *self, uint32_t start_index, const uint8_t* values, uint32_t len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void common_hal_alarm_sleep_memory_get_bytes(alarm_sleep_memory_obj_t *self, uint32_t start_index, uint8_t* values, uint32_t len) {
|
||||||
|
return;
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Lucian Copeland for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_SLEEPMEMORY_H
|
||||||
|
#define MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_SLEEPMEMORY_H
|
||||||
|
|
||||||
|
#include "py/obj.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
mp_obj_base_t base;
|
||||||
|
} alarm_sleep_memory_obj_t;
|
||||||
|
|
||||||
|
extern void alarm_sleep_memory_reset(void);
|
||||||
|
|
||||||
|
#endif // MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_SLEEPMEMORY_H
|
|
@ -0,0 +1,158 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Lucian Copeland for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "py/gc.h"
|
||||||
|
#include "py/obj.h"
|
||||||
|
#include "py/objtuple.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
#include "lib/utils/interrupt_char.h"
|
||||||
|
|
||||||
|
#include "shared-bindings/alarm/__init__.h"
|
||||||
|
#include "shared-bindings/alarm/pin/PinAlarm.h"
|
||||||
|
#include "shared-bindings/alarm/time/TimeAlarm.h"
|
||||||
|
|
||||||
|
#include "shared-bindings/microcontroller/__init__.h"
|
||||||
|
|
||||||
|
#include "supervisor/port.h"
|
||||||
|
#include "supervisor/shared/workflow.h"
|
||||||
|
|
||||||
|
#define STM_WAKEUP_GPIO 1
|
||||||
|
#define STM_WAKEUP_TIMER 2
|
||||||
|
|
||||||
|
void common_hal_alarm_reset(void) {
|
||||||
|
// alarm_sleep_memory_reset();
|
||||||
|
alarm_pin_pinalarm_reset();
|
||||||
|
// alarm_time_timealarm_reset();
|
||||||
|
// alarm_touch_touchalarm_reset();
|
||||||
|
// esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC uint8_t _get_wakeup_cause(void) {
|
||||||
|
if (alarm_pin_pinalarm_woke_us_up()) {
|
||||||
|
return STM_WAKEUP_GPIO;
|
||||||
|
}
|
||||||
|
if (alarm_time_timealarm_woke_us_up()) {
|
||||||
|
return STM_WAKEUP_TIMER;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool common_hal_alarm_woken_from_sleep(void) {
|
||||||
|
return _get_wakeup_cause() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
|
if (alarm_pin_pinalarm_woke_us_up()) {
|
||||||
|
return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms);
|
||||||
|
}
|
||||||
|
// esp_sleep_wakeup_cause_t cause = _get_wakeup_cause();
|
||||||
|
// switch (cause) {
|
||||||
|
// case ESP_SLEEP_WAKEUP_TIMER: {
|
||||||
|
// return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// case ESP_SLEEP_WAKEUP_GPIO:
|
||||||
|
// case ESP_SLEEP_WAKEUP_EXT0:
|
||||||
|
// case ESP_SLEEP_WAKEUP_EXT1: {
|
||||||
|
// return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// case ESP_SLEEP_WAKEUP_TOUCHPAD: {
|
||||||
|
// return alarm_touch_touchalarm_get_wakeup_alarm(n_alarms, alarms);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// case ESP_SLEEP_WAKEUP_UNDEFINED:
|
||||||
|
// default:
|
||||||
|
// // Not a deep sleep reset.
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// return mp_const_none;
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t common_hal_alarm_get_wake_alarm(void) {
|
||||||
|
//return _get_wake_alarm(0, NULL);
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms);
|
||||||
|
// alarm_time_timealarm_set_alarms(deep_sleep, n_alarms, alarms);
|
||||||
|
// alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC void _idle_until_alarm(void) {
|
||||||
|
// Poll for alarms.
|
||||||
|
while (!mp_hal_is_interrupted()) {
|
||||||
|
RUN_BACKGROUND_TASKS;
|
||||||
|
// Allow ctrl-C interrupt.
|
||||||
|
if (common_hal_alarm_woken_from_sleep()) {
|
||||||
|
common_hal_alarm_save_wake_alarm();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// port_idle_until_interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
|
// if (supervisor_workflow_active()) {
|
||||||
|
// mp_raise_NotImplementedError(translate("Cannot sleep with USB connected"));
|
||||||
|
// }
|
||||||
|
_setup_sleep_alarms(false, n_alarms, alarms);
|
||||||
|
|
||||||
|
// If USB is active, only pretend to sleep. Otherwise, light sleep
|
||||||
|
if (supervisor_workflow_active()) {
|
||||||
|
_idle_until_alarm();
|
||||||
|
} else {
|
||||||
|
port_disable_tick();
|
||||||
|
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
|
||||||
|
port_enable_tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t wake_alarm = _get_wake_alarm(n_alarms, alarms);
|
||||||
|
common_hal_alarm_reset();
|
||||||
|
return wake_alarm;
|
||||||
|
}
|
||||||
|
|
||||||
|
void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
|
_setup_sleep_alarms(true, n_alarms, alarms);
|
||||||
|
}
|
||||||
|
|
||||||
|
//#define NORETURN __attribute__((noreturn))
|
||||||
|
void NORETURN common_hal_alarm_enter_deep_sleep(void) {
|
||||||
|
// alarm_pin_pinalarm_prepare_for_deep_sleep();
|
||||||
|
// alarm_touch_touchalarm_prepare_for_deep_sleep();
|
||||||
|
while(1);
|
||||||
|
|
||||||
|
// The ESP-IDF caches the deep sleep settings and applies them before sleep.
|
||||||
|
// We don't need to worry about resetting them in the interim.
|
||||||
|
// esp_deep_sleep_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void common_hal_alarm_gc_collect(void) {
|
||||||
|
gc_collect_ptr(common_hal_alarm_get_wake_alarm());
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Lucian Copeland for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM__INIT__H
|
||||||
|
#define MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM__INIT__H
|
||||||
|
|
||||||
|
#include "common-hal/alarm/SleepMemory.h"
|
||||||
|
|
||||||
|
const alarm_sleep_memory_obj_t alarm_sleep_memory_obj;
|
||||||
|
|
||||||
|
extern void common_hal_alarm_reset(void);
|
||||||
|
|
||||||
|
#endif // MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM__INIT__H
|
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Lucian Copeland for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "py/runtime.h"
|
||||||
|
|
||||||
|
#include "shared-bindings/alarm/pin/PinAlarm.h"
|
||||||
|
#include "shared-bindings/microcontroller/__init__.h"
|
||||||
|
#include "shared-bindings/microcontroller/Pin.h"
|
||||||
|
|
||||||
|
#include "peripherals/exti.h"
|
||||||
|
|
||||||
|
STATIC bool woke_up;
|
||||||
|
|
||||||
|
STATIC uint16_t alarm_pin_triggered;
|
||||||
|
|
||||||
|
STATIC void pin_alarm_callback(uint8_t num) {
|
||||||
|
alarm_pin_triggered |= (1 << num);
|
||||||
|
woke_up = true;
|
||||||
|
HAL_GPIO_EXTI_IRQHandler(pin_mask(num));
|
||||||
|
}
|
||||||
|
|
||||||
|
void common_hal_alarm_pin_pinalarm_construct(alarm_pin_pinalarm_obj_t *self, mcu_pin_obj_t *pin, bool value, bool edge, bool pull) {
|
||||||
|
if (!edge) {
|
||||||
|
mp_raise_NotImplementedError(translate("Only edge detection is available on this hardware"));
|
||||||
|
}
|
||||||
|
if (!stm_peripherals_exti_is_free(pin->number)) {
|
||||||
|
mp_raise_RuntimeError(translate("Pin interrupt already in use"));
|
||||||
|
}
|
||||||
|
stm_peripherals_exti_reserve(pin->number);
|
||||||
|
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||||
|
GPIO_InitStruct.Pin = pin_mask(pin->number);
|
||||||
|
GPIO_InitStruct.Mode = value ? GPIO_MODE_IT_RISING : GPIO_MODE_IT_FALLING;
|
||||||
|
// Pull is automatically set to oppose value.
|
||||||
|
// TODO: match digitalIO API instead?
|
||||||
|
if (value) {
|
||||||
|
GPIO_InitStruct.Pull = pull ? GPIO_PULLDOWN : GPIO_NOPULL;
|
||||||
|
} else {
|
||||||
|
GPIO_InitStruct.Pull = pull ? GPIO_PULLUP : GPIO_NOPULL;
|
||||||
|
}
|
||||||
|
HAL_GPIO_Init(pin_port(pin->port), &GPIO_InitStruct);
|
||||||
|
|
||||||
|
stm_peripherals_exti_set_callback(pin_alarm_callback,pin->number);
|
||||||
|
|
||||||
|
self->pin = pin;
|
||||||
|
self->value = value;
|
||||||
|
self->pull = pull;
|
||||||
|
}
|
||||||
|
|
||||||
|
mcu_pin_obj_t *common_hal_alarm_pin_pinalarm_get_pin(alarm_pin_pinalarm_obj_t *self) {
|
||||||
|
return self->pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool common_hal_alarm_pin_pinalarm_get_value(alarm_pin_pinalarm_obj_t *self) {
|
||||||
|
return self->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool common_hal_alarm_pin_pinalarm_get_edge(alarm_pin_pinalarm_obj_t *self) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool common_hal_alarm_pin_pinalarm_get_pull(alarm_pin_pinalarm_obj_t *self) {
|
||||||
|
return self->pull;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool alarm_pin_pinalarm_woke_us_up(void) {
|
||||||
|
return woke_up;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
|
for (size_t i = 0; i < n_alarms; i++) {
|
||||||
|
if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pinalarm_type)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]);
|
||||||
|
if (alarm_pin_triggered & (1 << alarm->pin->number)) {
|
||||||
|
return alarms[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Placeholder for deep sleep
|
||||||
|
alarm_pin_pinalarm_obj_t *alarm = m_new_obj(alarm_pin_pinalarm_obj_t);
|
||||||
|
alarm->base.type = &alarm_pin_pinalarm_type;
|
||||||
|
alarm->pin = NULL;
|
||||||
|
return alarm;
|
||||||
|
}
|
||||||
|
|
||||||
|
void alarm_pin_pinalarm_reset(void) {
|
||||||
|
alarm_pin_triggered = 0;
|
||||||
|
woke_up = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
|
for (size_t i = 0; i < n_alarms; i++) {
|
||||||
|
if (MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pinalarm_type)) {
|
||||||
|
alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]);
|
||||||
|
stm_peripherals_exti_enable(alarm->pin->number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void alarm_pin_pinalarm_reset_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
|
alarm_pin_triggered = 0;
|
||||||
|
for (size_t i = 0; i < n_alarms; i++) {
|
||||||
|
if (MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pinalarm_type)) {
|
||||||
|
alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]);
|
||||||
|
stm_peripherals_exti_disable(alarm->pin->number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void alarm_pin_pinalarm_prepare_for_deep_sleep(void) {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Lucian Copeland for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "py/obj.h"
|
||||||
|
#include "py/objtuple.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
mp_obj_base_t base;
|
||||||
|
mcu_pin_obj_t *pin;
|
||||||
|
bool value;
|
||||||
|
bool pull;
|
||||||
|
} alarm_pin_pinalarm_obj_t;
|
||||||
|
|
||||||
|
void alarm_pin_pinalarm_reset(void);
|
||||||
|
void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
|
||||||
|
void alarm_pin_pinalarm_reset_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
|
||||||
|
void alarm_pin_pinalarm_prepare_for_deep_sleep(void);
|
||||||
|
mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms);
|
||||||
|
bool alarm_pin_pinalarm_woke_us_up(void);
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Lucian Copeland for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "py/runtime.h"
|
||||||
|
|
||||||
|
#include "shared-bindings/alarm/time/TimeAlarm.h"
|
||||||
|
#include "shared-bindings/time/__init__.h"
|
||||||
|
|
||||||
|
void common_hal_alarm_time_timealarm_construct(alarm_time_timealarm_obj_t *self, mp_float_t monotonic_time) {
|
||||||
|
self->monotonic_time = monotonic_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_float_t common_hal_alarm_time_timealarm_get_monotonic_time(alarm_time_timealarm_obj_t *self) {
|
||||||
|
return self->monotonic_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
|
// // First, check to see if we match
|
||||||
|
// for (size_t i = 0; i < n_alarms; i++) {
|
||||||
|
// if (MP_OBJ_IS_TYPE(alarms[i], &alarm_time_timealarm_type)) {
|
||||||
|
// return alarms[i];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// alarm_time_timealarm_obj_t *timer = m_new_obj(alarm_time_timealarm_obj_t);
|
||||||
|
// timer->base.type = &alarm_time_timealarm_type;
|
||||||
|
// // TODO: Set monotonic_time based on the RTC state.
|
||||||
|
// timer->monotonic_time = 0.0f;
|
||||||
|
// return timer;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// This is run in the timer task. We use it to wake the main CircuitPython task.
|
||||||
|
// void timer_callback(void *arg) {
|
||||||
|
// (void) arg;
|
||||||
|
// woke_up = true;
|
||||||
|
// xTaskNotifyGive(circuitpython_task);
|
||||||
|
// }
|
||||||
|
|
||||||
|
bool alarm_time_timealarm_woke_us_up(void) {
|
||||||
|
// return woke_up;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// void alarm_time_timealarm_reset(void) {
|
||||||
|
// esp_timer_stop(pretend_sleep_timer);
|
||||||
|
// esp_timer_delete(pretend_sleep_timer);
|
||||||
|
// pretend_sleep_timer = NULL;
|
||||||
|
// woke_up = false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
|
// HAL_RTCEx_SetWakeUpTimer_IT(&RTCHandle, 0xA017, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
|
||||||
|
// HAL_RTCEx_SetWakeUpTimer_IT(&_hrtc, rtc_clock_frequency / 1024 / 2, RTC_WAKEUPCLOCK_RTCCLK_DIV2);
|
||||||
|
// HAL_NVIC_SetPriority(RTC_WKUP_IRQn, 1, 0U);
|
||||||
|
// HAL_NVIC_EnableIRQ(RTC_WKUP_IRQn);
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Lucian Copeland for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "py/obj.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
mp_obj_base_t base;
|
||||||
|
mp_float_t monotonic_time; // values compatible with time.monotonic_time()
|
||||||
|
} alarm_time_timealarm_obj_t;
|
||||||
|
|
||||||
|
// // Find the alarm object that caused us to wake up or create an equivalent one.
|
||||||
|
// mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms);
|
||||||
|
// // Check for the wake up alarm from pretend deep sleep.
|
||||||
|
bool alarm_time_timealarm_woke_us_up(void);
|
||||||
|
// void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
|
||||||
|
// void alarm_time_timealarm_reset(void);
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Lucian Copeland for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "shared-bindings/alarm/touch/TouchAlarm.h"
|
||||||
|
#include "shared-bindings/microcontroller/__init__.h"
|
||||||
|
|
||||||
|
void common_hal_alarm_touch_touchalarm_construct(alarm_touch_touchalarm_obj_t *self, const mcu_pin_obj_t *pin) {
|
||||||
|
mp_raise_NotImplementedError(translate("Touch alarms not available"));
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Lucian Copeland for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_TOUCHALARM_H
|
||||||
|
#define MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_TOUCHALARM_H
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
mp_obj_base_t base;
|
||||||
|
const mcu_pin_obj_t *pin;
|
||||||
|
} alarm_touch_touchalarm_obj_t;
|
||||||
|
|
||||||
|
#endif // MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_TOUCHALARM_H
|
|
@ -35,17 +35,17 @@
|
||||||
#include "shared-bindings/pulseio/PulseIn.h"
|
#include "shared-bindings/pulseio/PulseIn.h"
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
|
|
||||||
|
#include "peripherals/exti.h"
|
||||||
|
|
||||||
#include STM32_HAL_H
|
#include STM32_HAL_H
|
||||||
|
|
||||||
#define STM32_GPIO_PORT_SIZE 16
|
#define STM32_GPIO_PORT_SIZE 16
|
||||||
static pulseio_pulsein_obj_t* _objs[STM32_GPIO_PORT_SIZE];
|
STATIC pulseio_pulsein_obj_t* callback_obj_ref[STM32_GPIO_PORT_SIZE];
|
||||||
|
|
||||||
STATIC TIM_HandleTypeDef tim_handle;
|
STATIC TIM_HandleTypeDef tim_handle;
|
||||||
static uint32_t overflow_count = 0;
|
STATIC uint32_t overflow_count = 0;
|
||||||
STATIC uint8_t refcount = 0;
|
STATIC uint8_t refcount = 0;
|
||||||
|
|
||||||
static void assign_EXTI_Interrupt(pulseio_pulsein_obj_t* self, uint8_t num);
|
|
||||||
|
|
||||||
void pulsein_timer_event_handler(void)
|
void pulsein_timer_event_handler(void)
|
||||||
{
|
{
|
||||||
// Detect TIM Update event
|
// Detect TIM Update event
|
||||||
|
@ -59,7 +59,7 @@ void pulsein_timer_event_handler(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pulsein_exti_event_handler(uint8_t num) {
|
STATIC void pulsein_exti_event_handler(uint8_t num) {
|
||||||
// Grab the current time first.
|
// Grab the current time first.
|
||||||
uint32_t current_overflow = overflow_count;
|
uint32_t current_overflow = overflow_count;
|
||||||
uint32_t current_count = tim_handle.Instance->CNT;
|
uint32_t current_count = tim_handle.Instance->CNT;
|
||||||
|
@ -67,7 +67,7 @@ static void pulsein_exti_event_handler(uint8_t num) {
|
||||||
// Interrupt register must be cleared manually
|
// Interrupt register must be cleared manually
|
||||||
EXTI->PR = 1 << num;
|
EXTI->PR = 1 << num;
|
||||||
|
|
||||||
pulseio_pulsein_obj_t* self = _objs[num];
|
pulseio_pulsein_obj_t* self = callback_obj_ref[num];
|
||||||
if ( !self ) return;
|
if ( !self ) return;
|
||||||
|
|
||||||
if (self->first_edge) {
|
if (self->first_edge) {
|
||||||
|
@ -97,11 +97,11 @@ static void pulsein_exti_event_handler(uint8_t num) {
|
||||||
void pulsein_reset(void) {
|
void pulsein_reset(void) {
|
||||||
// Disable all active interrupts and clear array
|
// Disable all active interrupts and clear array
|
||||||
for (uint i = 0; i < STM32_GPIO_PORT_SIZE; i++) {
|
for (uint i = 0; i < STM32_GPIO_PORT_SIZE; i++) {
|
||||||
if (_objs[i] != NULL) {
|
if (callback_obj_ref[i] != NULL) {
|
||||||
HAL_NVIC_DisableIRQ(_objs[i]->irq);
|
stm_peripherals_exti_disable(callback_obj_ref[i]->pin->number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memset(_objs, 0, sizeof(_objs));
|
memset(callback_obj_ref, 0, sizeof(callback_obj_ref));
|
||||||
|
|
||||||
HAL_TIM_Base_DeInit(&tim_handle);
|
HAL_TIM_Base_DeInit(&tim_handle);
|
||||||
tim_clock_disable(stm_peripherals_timer_get_index(tim_handle.Instance));
|
tim_clock_disable(stm_peripherals_timer_get_index(tim_handle.Instance));
|
||||||
|
@ -112,15 +112,14 @@ void pulsein_reset(void) {
|
||||||
void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, const mcu_pin_obj_t* pin,
|
void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, const mcu_pin_obj_t* pin,
|
||||||
uint16_t maxlen, bool idle_state) {
|
uint16_t maxlen, bool idle_state) {
|
||||||
// STM32 has one shared EXTI for each pin number, 0-15
|
// STM32 has one shared EXTI for each pin number, 0-15
|
||||||
uint8_t p_num = pin->number;
|
if (!stm_peripherals_exti_is_free(pin->number)) {
|
||||||
if(_objs[p_num]) {
|
mp_raise_RuntimeError(translate("Pin interrupt already in use"));
|
||||||
mp_raise_ValueError(translate("Pin number already reserved by EXTI"));
|
|
||||||
}
|
}
|
||||||
_objs[p_num] = self;
|
|
||||||
|
|
||||||
// Allocate pulse buffer
|
// Allocate pulse buffer
|
||||||
self->buffer = (uint16_t *) m_malloc(maxlen * sizeof(uint16_t), false);
|
self->buffer = (uint16_t *) m_malloc(maxlen * sizeof(uint16_t), false);
|
||||||
if (self->buffer == NULL) {
|
if (self->buffer == NULL) {
|
||||||
|
//TODO: free the EXTI here?
|
||||||
mp_raise_msg_varg(&mp_type_MemoryError, translate("Failed to allocate RX buffer of %d bytes"),
|
mp_raise_msg_varg(&mp_type_MemoryError, translate("Failed to allocate RX buffer of %d bytes"),
|
||||||
maxlen * sizeof(uint16_t));
|
maxlen * sizeof(uint16_t));
|
||||||
}
|
}
|
||||||
|
@ -165,16 +164,21 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, const mcu
|
||||||
// Add to active PulseIns
|
// Add to active PulseIns
|
||||||
refcount++;
|
refcount++;
|
||||||
|
|
||||||
// EXTI pins can also be read as an input
|
if (!stm_peripherals_exti_reserve(pin->number)) {
|
||||||
|
mp_raise_RuntimeError(translate("Pin interrupt already in use"));
|
||||||
|
}
|
||||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||||
GPIO_InitStruct.Pin = pin_mask(pin->number);
|
GPIO_InitStruct.Pin = pin_mask(pin->number);
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
|
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
|
||||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
HAL_GPIO_Init(pin_port(pin->port), &GPIO_InitStruct);
|
HAL_GPIO_Init(pin_port(pin->port), &GPIO_InitStruct);
|
||||||
|
|
||||||
|
stm_peripherals_exti_set_callback(pulsein_exti_event_handler, pin->number);
|
||||||
|
// Store PulseIn object for use in callback
|
||||||
|
callback_obj_ref[pin->number] = self;
|
||||||
// Interrupt starts immediately
|
// Interrupt starts immediately
|
||||||
assign_EXTI_Interrupt(self, pin->number);
|
stm_peripherals_exti_enable(pin->number);
|
||||||
HAL_NVIC_EnableIRQ(self->irq);
|
|
||||||
common_hal_mcu_pin_claim(pin);
|
common_hal_mcu_pin_claim(pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +191,8 @@ void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//Remove pulsein slot from shared array
|
//Remove pulsein slot from shared array
|
||||||
_objs[self->pin->number] = NULL;
|
callback_obj_ref[self->pin->number] = NULL;
|
||||||
|
stm_peripherals_exti_free(self->pin->number);
|
||||||
reset_pin_number(self->pin->port, self->pin->number);
|
reset_pin_number(self->pin->port, self->pin->number);
|
||||||
self->pin = NULL;
|
self->pin = NULL;
|
||||||
|
|
||||||
|
@ -198,7 +203,7 @@ void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self) {
|
void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self) {
|
||||||
HAL_NVIC_DisableIRQ(self->irq);
|
stm_peripherals_exti_disable(self->pin->number);
|
||||||
self->paused = true;
|
self->paused = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,27 +237,27 @@ void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, uint16_t tri
|
||||||
self->last_count = 0;
|
self->last_count = 0;
|
||||||
self->last_overflow = 0;
|
self->last_overflow = 0;
|
||||||
|
|
||||||
HAL_NVIC_EnableIRQ(self->irq);
|
stm_peripherals_exti_enable(self->pin->number);
|
||||||
}
|
}
|
||||||
|
|
||||||
void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self) {
|
void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self) {
|
||||||
HAL_NVIC_DisableIRQ(self->irq);
|
stm_peripherals_exti_disable(self->pin->number);
|
||||||
self->start = 0;
|
self->start = 0;
|
||||||
self->len = 0;
|
self->len = 0;
|
||||||
HAL_NVIC_EnableIRQ(self->irq);
|
stm_peripherals_exti_enable(self->pin->number);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, int16_t index) {
|
uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, int16_t index) {
|
||||||
HAL_NVIC_DisableIRQ(self->irq);
|
stm_peripherals_exti_disable(self->pin->number);
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
index += self->len;
|
index += self->len;
|
||||||
}
|
}
|
||||||
if (index < 0 || index >= self->len) {
|
if (index < 0 || index >= self->len) {
|
||||||
HAL_NVIC_EnableIRQ(self->irq);
|
stm_peripherals_exti_enable(self->pin->number);
|
||||||
mp_raise_IndexError_varg(translate("%q index out of range"), MP_QSTR_PulseIn);
|
mp_raise_IndexError_varg(translate("%q index out of range"), MP_QSTR_PulseIn);
|
||||||
}
|
}
|
||||||
uint16_t value = self->buffer[(self->start + index) % self->maxlen];
|
uint16_t value = self->buffer[(self->start + index) % self->maxlen];
|
||||||
HAL_NVIC_EnableIRQ(self->irq);
|
stm_peripherals_exti_enable(self->pin->number);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,11 +265,11 @@ uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self) {
|
||||||
if (self->len == 0) {
|
if (self->len == 0) {
|
||||||
mp_raise_IndexError_varg(translate("pop from empty %q"), MP_QSTR_PulseIn);
|
mp_raise_IndexError_varg(translate("pop from empty %q"), MP_QSTR_PulseIn);
|
||||||
}
|
}
|
||||||
HAL_NVIC_DisableIRQ(self->irq);
|
stm_peripherals_exti_disable(self->pin->number);
|
||||||
uint16_t value = self->buffer[self->start];
|
uint16_t value = self->buffer[self->start];
|
||||||
self->start = (self->start + 1) % self->maxlen;
|
self->start = (self->start + 1) % self->maxlen;
|
||||||
self->len--;
|
self->len--;
|
||||||
HAL_NVIC_EnableIRQ(self->irq);
|
stm_peripherals_exti_enable(self->pin->number);
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -280,62 +285,3 @@ bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t* self) {
|
||||||
uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self) {
|
uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self) {
|
||||||
return self->len;
|
return self->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void assign_EXTI_Interrupt(pulseio_pulsein_obj_t* self, uint8_t num) {
|
|
||||||
if (num == 0) {
|
|
||||||
self->irq = EXTI0_IRQn;
|
|
||||||
} else if (num == 1) {
|
|
||||||
self->irq = EXTI1_IRQn;
|
|
||||||
} else if (num == 2) {
|
|
||||||
self->irq = EXTI2_IRQn;
|
|
||||||
} else if (num == 3) {
|
|
||||||
self->irq = EXTI3_IRQn;
|
|
||||||
} else if (num == 4) {
|
|
||||||
self->irq = EXTI4_IRQn;
|
|
||||||
} else if (num >= 5 && num <= 9 ) {
|
|
||||||
self->irq = EXTI9_5_IRQn;
|
|
||||||
} else if (num >= 10 && num <= 15) {
|
|
||||||
self->irq = EXTI15_10_IRQn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EXTI0_IRQHandler(void)
|
|
||||||
{
|
|
||||||
pulsein_exti_event_handler(0);
|
|
||||||
}
|
|
||||||
void EXTI1_IRQHandler(void)
|
|
||||||
{
|
|
||||||
pulsein_exti_event_handler(1);
|
|
||||||
}
|
|
||||||
void EXTI2_IRQHandler(void)
|
|
||||||
{
|
|
||||||
pulsein_exti_event_handler(2);
|
|
||||||
}
|
|
||||||
void EXTI3_IRQHandler(void)
|
|
||||||
{
|
|
||||||
pulsein_exti_event_handler(3);
|
|
||||||
}
|
|
||||||
void EXTI4_IRQHandler(void)
|
|
||||||
{
|
|
||||||
pulsein_exti_event_handler(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EXTI9_5_IRQHandler(void)
|
|
||||||
{
|
|
||||||
uint32_t pending = EXTI->PR;
|
|
||||||
for (uint i = 5; i <= 9; i++) {
|
|
||||||
if(pending & (1 << i)) {
|
|
||||||
pulsein_exti_event_handler(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EXTI15_10_IRQHandler(void)
|
|
||||||
{
|
|
||||||
uint32_t pending = EXTI->PR;
|
|
||||||
for (uint i = 10; i <= 15; i++) {
|
|
||||||
if(pending & (1 << i)) {
|
|
||||||
pulsein_exti_event_handler(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -35,7 +35,6 @@ typedef struct {
|
||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
|
|
||||||
const mcu_pin_obj_t* pin;
|
const mcu_pin_obj_t* pin;
|
||||||
IRQn_Type irq;
|
|
||||||
bool idle_state;
|
bool idle_state;
|
||||||
bool paused;
|
bool paused;
|
||||||
volatile bool first_edge;
|
volatile bool first_edge;
|
||||||
|
|
|
@ -4,6 +4,7 @@ INTERNAL_LIBM ?= 1
|
||||||
USB_SERIAL_NUMBER_LENGTH ?= 24
|
USB_SERIAL_NUMBER_LENGTH ?= 24
|
||||||
|
|
||||||
ifeq ($(MCU_VARIANT),STM32F405xx)
|
ifeq ($(MCU_VARIANT),STM32F405xx)
|
||||||
|
CIRCUITPY_ALARM = 1
|
||||||
CIRCUITPY_CANIO = 1
|
CIRCUITPY_CANIO = 1
|
||||||
CIRCUITPY_FRAMEBUFFERIO ?= 1
|
CIRCUITPY_FRAMEBUFFERIO ?= 1
|
||||||
CIRCUITPY_RGBMATRIX ?= 1
|
CIRCUITPY_RGBMATRIX ?= 1
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Lucian Copeland for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "py/mpconfig.h"
|
||||||
|
#include "py/gc.h"
|
||||||
|
#include "py/obj.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
|
||||||
|
#include "peripherals/exti.h"
|
||||||
|
|
||||||
|
|
||||||
|
STATIC bool stm_exti_reserved[STM32_GPIO_PORT_SIZE];
|
||||||
|
STATIC void (*stm_exti_callback[STM32_GPIO_PORT_SIZE])(uint8_t num);
|
||||||
|
|
||||||
|
void exti_reset(void) {
|
||||||
|
for (size_t i = 0;i < STM32_GPIO_PORT_SIZE; i++) {
|
||||||
|
stm_exti_reserved[i] = false;
|
||||||
|
stm_exti_callback[i] = NULL;
|
||||||
|
stm_peripherals_exti_disable(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool stm_peripherals_exti_is_free(uint8_t num) {
|
||||||
|
return !stm_exti_reserved[num];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool stm_peripherals_exti_reserve(uint8_t num) {
|
||||||
|
if (!stm_peripherals_exti_is_free(num)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
stm_exti_reserved[num] = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stm_peripherals_exti_enable(uint8_t num) {
|
||||||
|
HAL_NVIC_EnableIRQ(stm_peripherals_exti_get_irq(num));
|
||||||
|
}
|
||||||
|
|
||||||
|
void stm_peripherals_exti_disable(uint8_t num) {
|
||||||
|
HAL_NVIC_DisableIRQ(stm_peripherals_exti_get_irq(num));
|
||||||
|
}
|
||||||
|
|
||||||
|
void stm_peripherals_exti_set_callback(void(*callback)(uint8_t num), uint8_t number) {
|
||||||
|
stm_exti_callback[number] = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stm_peripherals_exti_free(uint8_t num) {
|
||||||
|
stm_exti_reserved[num] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
IRQn_Type stm_peripherals_exti_get_irq(uint8_t num) {
|
||||||
|
if (num == 0) {
|
||||||
|
return EXTI0_IRQn;
|
||||||
|
} else if (num == 1) {
|
||||||
|
return EXTI1_IRQn;
|
||||||
|
} else if (num == 2) {
|
||||||
|
return EXTI2_IRQn;
|
||||||
|
} else if (num == 3) {
|
||||||
|
return EXTI3_IRQn;
|
||||||
|
} else if (num == 4) {
|
||||||
|
return EXTI4_IRQn;
|
||||||
|
} else if (num >= 5 && num <= 9 ) {
|
||||||
|
return EXTI9_5_IRQn;
|
||||||
|
} else if (num >= 10 && num <= 15) {
|
||||||
|
return EXTI15_10_IRQn;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EXTI0_IRQHandler(void)
|
||||||
|
{
|
||||||
|
stm_exti_callback[0](0);
|
||||||
|
}
|
||||||
|
void EXTI1_IRQHandler(void)
|
||||||
|
{
|
||||||
|
stm_exti_callback[1](1);
|
||||||
|
}
|
||||||
|
void EXTI2_IRQHandler(void)
|
||||||
|
{
|
||||||
|
stm_exti_callback[2](2);
|
||||||
|
}
|
||||||
|
void EXTI3_IRQHandler(void)
|
||||||
|
{
|
||||||
|
stm_exti_callback[3](3);
|
||||||
|
}
|
||||||
|
void EXTI4_IRQHandler(void)
|
||||||
|
{
|
||||||
|
stm_exti_callback[4](4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EXTI9_5_IRQHandler(void)
|
||||||
|
{
|
||||||
|
uint32_t pending = EXTI->PR;
|
||||||
|
for (uint i = 5; i <= 9; i++) {
|
||||||
|
if(pending & (1 << i)) {
|
||||||
|
stm_exti_callback[i](i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EXTI15_10_IRQHandler(void)
|
||||||
|
{
|
||||||
|
uint32_t pending = EXTI->PR;
|
||||||
|
for (uint i = 10; i <= 15; i++) {
|
||||||
|
if(pending & (1 << i)) {
|
||||||
|
stm_exti_callback[i](i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Lucian Copeland for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MICROPY_INCLUDED_STM32_PERIPHERALS_EXTI_H__
|
||||||
|
#define __MICROPY_INCLUDED_STM32_PERIPHERALS_EXTI_H__
|
||||||
|
|
||||||
|
#include STM32_HAL_H
|
||||||
|
|
||||||
|
#define STM32_GPIO_PORT_SIZE 16
|
||||||
|
|
||||||
|
void exti_reset(void);
|
||||||
|
bool stm_peripherals_exti_is_free(uint8_t num);
|
||||||
|
bool stm_peripherals_exti_reserve(uint8_t num);
|
||||||
|
void stm_peripherals_exti_enable(uint8_t num);
|
||||||
|
void stm_peripherals_exti_disable(uint8_t num);
|
||||||
|
void stm_peripherals_exti_set_callback(void(*callback)(uint8_t num), uint8_t number);
|
||||||
|
void stm_peripherals_exti_free(uint8_t num);
|
||||||
|
IRQn_Type stm_peripherals_exti_get_irq(uint8_t num);
|
||||||
|
|
||||||
|
#endif // __MICROPY_INCLUDED_STM32_PERIPHERALS_EXTI_H__
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Lucian Copeland for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Lucian Copeland for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
|
@ -50,6 +50,9 @@
|
||||||
#if CIRCUITPY_SDIOIO
|
#if CIRCUITPY_SDIOIO
|
||||||
#include "common-hal/sdioio/SDCard.h"
|
#include "common-hal/sdioio/SDCard.h"
|
||||||
#endif
|
#endif
|
||||||
|
#if CIRCUITPY_PULSEIO || CIRCUITPY_ALARM
|
||||||
|
#include "exti.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "clocks.h"
|
#include "clocks.h"
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
|
@ -247,6 +250,9 @@ void reset_port(void) {
|
||||||
#if CIRCUITPY_PWMIO
|
#if CIRCUITPY_PWMIO
|
||||||
pwmout_reset();
|
pwmout_reset();
|
||||||
#endif
|
#endif
|
||||||
|
#if CIRCUITPY_PULSEIO || CIRCUITPY_ALARM
|
||||||
|
exti_reset();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_to_bootloader(void) {
|
void reset_to_bootloader(void) {
|
||||||
|
@ -380,6 +386,7 @@ void RTC_WKUP_IRQHandler(void) {
|
||||||
supervisor_tick();
|
supervisor_tick();
|
||||||
__HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&_hrtc, RTC_FLAG_WUTF);
|
__HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&_hrtc, RTC_FLAG_WUTF);
|
||||||
__HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG();
|
__HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG();
|
||||||
|
_hrtc.State = HAL_RTC_STATE_READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile bool alarmed_already = false;
|
volatile bool alarmed_already = false;
|
||||||
|
|
|
@ -228,7 +228,7 @@ mp_obj_t alarm_get_wake_alarm(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize .wake_alarm value.
|
// Initialize .wake_alarm value.
|
||||||
void alarm_save_wake_alarm(void) {
|
void common_hal_alarm_save_wake_alarm(void) {
|
||||||
// Equivalent of:
|
// Equivalent of:
|
||||||
// alarm.wake_alarm = alarm
|
// alarm.wake_alarm = alarm
|
||||||
mp_map_elem_t *elem =
|
mp_map_elem_t *elem =
|
||||||
|
|
|
@ -41,20 +41,20 @@ extern mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const
|
||||||
// it will exit idle as if deep sleep was exited.
|
// it will exit idle as if deep sleep was exited.
|
||||||
extern void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms);
|
extern void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms);
|
||||||
// Deep sleep is entered outside of the VM so we omit the `common_hal_` prefix.
|
// Deep sleep is entered outside of the VM so we omit the `common_hal_` prefix.
|
||||||
extern NORETURN void alarm_enter_deep_sleep(void);
|
extern NORETURN void common_hal_alarm_enter_deep_sleep(void);
|
||||||
|
|
||||||
// Fetches value from module dict.
|
// Fetches value from module dict.
|
||||||
extern mp_obj_t alarm_get_wake_alarm(void);
|
extern mp_obj_t common_hal_alarm_get_wake_alarm(void);
|
||||||
|
|
||||||
extern void common_hal_alarm_gc_collect(void);
|
extern void common_hal_alarm_gc_collect(void);
|
||||||
extern mp_obj_t common_hal_alarm_get_wake_alarm(void);
|
extern mp_obj_t common_hal_alarm_get_wake_alarm(void);
|
||||||
|
|
||||||
// Used by wake-up code.
|
// Used by wake-up code.
|
||||||
void alarm_save_wake_alarm(void);
|
void common_hal_alarm_save_wake_alarm(void);
|
||||||
|
|
||||||
|
|
||||||
// True if an alarm is alerting. This is most useful for pretend deep sleep.
|
// True if an alarm is alerting. This is most useful for pretend deep sleep.
|
||||||
extern bool alarm_woken_from_sleep(void);
|
extern bool common_hal_alarm_woken_from_sleep(void);
|
||||||
|
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H
|
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H
|
||||||
|
|
|
@ -58,6 +58,7 @@ mp_obj_t MP_WEAK rtc_get_time_source_time(void) {
|
||||||
//|
|
//|
|
||||||
STATIC mp_obj_t alarm_time_timealarm_make_new(const mp_obj_type_t *type,
|
STATIC mp_obj_t alarm_time_timealarm_make_new(const mp_obj_type_t *type,
|
||||||
mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||||
|
|
||||||
alarm_time_timealarm_obj_t *self = m_new_obj(alarm_time_timealarm_obj_t);
|
alarm_time_timealarm_obj_t *self = m_new_obj(alarm_time_timealarm_obj_t);
|
||||||
self->base.type = &alarm_time_timealarm_type;
|
self->base.type = &alarm_time_timealarm_type;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue