2018-01-03 14:18:06 +01:00
|
|
|
/*
|
2018-02-28 14:46:02 +01:00
|
|
|
* This file is part of the MicroPython ESP32 project, https://github.com/loboris/MicroPython_ESP32_psRAM_LoBo
|
2018-01-03 14:18:06 +01:00
|
|
|
*
|
|
|
|
|
* Development of the code in this file was sponsored by Microbric Pty Ltd
|
|
|
|
|
*
|
|
|
|
|
* The MIT License (MIT)
|
|
|
|
|
*
|
|
|
|
|
* Copyright (c) 2013-2015 Damien P. George
|
|
|
|
|
* Copyright (c) 2016 Paul Sokolovsky
|
2018-02-28 14:46:02 +01:00
|
|
|
* Copyright (c) 2018 LoBo (https://github.com/loboris)
|
2018-01-03 14:18:06 +01:00
|
|
|
*
|
|
|
|
|
* 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 <stdint.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
#include "sdkconfig.h"
|
2018-01-03 14:18:06 +01:00
|
|
|
#include "freertos/FreeRTOS.h"
|
|
|
|
|
#include "freertos/task.h"
|
|
|
|
|
#include "freertos/semphr.h"
|
2018-12-04 14:06:15 +08:00
|
|
|
#include "esp_task_wdt.h"
|
2018-01-03 14:18:06 +01:00
|
|
|
#include "rom/ets_sys.h"
|
2018-12-04 14:06:15 +08:00
|
|
|
#include "rom/rtc.h"
|
|
|
|
|
#include "rom/gpio.h"
|
|
|
|
|
#include "soc/rtc.h"
|
|
|
|
|
#include "soc/uart_reg.h"
|
|
|
|
|
#include "soc/timer_group_reg.h"
|
|
|
|
|
#include "soc/io_mux_reg.h"
|
|
|
|
|
#include "soc/sens_reg.h"
|
2018-01-03 14:18:06 +01:00
|
|
|
#include "esp_system.h"
|
|
|
|
|
#include "soc/dport_reg.h"
|
|
|
|
|
#include "soc/rtc_cntl_reg.h"
|
|
|
|
|
#include "rom/uart.h"
|
2018-12-04 14:06:15 +08:00
|
|
|
#include "esp_sleep.h"
|
2018-01-03 14:18:06 +01:00
|
|
|
#include "esp_heap_caps.h"
|
|
|
|
|
#include "esp_log.h"
|
2018-12-04 14:06:15 +08:00
|
|
|
#include "esp_err.h"
|
|
|
|
|
#include "esp_pm.h"
|
|
|
|
|
#include "esp_wifi.h"
|
|
|
|
|
#include "driver/uart.h"
|
2018-01-03 14:18:06 +01:00
|
|
|
|
|
|
|
|
#include "py/obj.h"
|
|
|
|
|
#include "py/runtime.h"
|
|
|
|
|
#include "extmod/machine_mem.h"
|
|
|
|
|
#include "extmod/machine_signal.h"
|
|
|
|
|
#include "extmod/machine_pulse.h"
|
|
|
|
|
#include "extmod/vfs_native.h"
|
|
|
|
|
#include "modmachine.h"
|
|
|
|
|
#include "mpsleep.h"
|
|
|
|
|
#include "machine_rtc.h"
|
|
|
|
|
#include "uart.h"
|
2018-12-04 14:06:15 +08:00
|
|
|
#include "modnetwork.h"
|
2018-01-03 14:18:06 +01:00
|
|
|
|
|
|
|
|
#if MICROPY_PY_MACHINE
|
|
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
//extern uint8_t temprature_sens_read();
|
|
|
|
|
extern uint16_t rom_phy_get_vdd33();
|
|
|
|
|
|
|
|
|
|
// === Global variables ===
|
|
|
|
|
bool mpy_use_spiram = false;
|
2018-01-03 14:18:06 +01:00
|
|
|
nvs_handle mpy_nvs_handle = 0;
|
2018-12-04 14:06:15 +08:00
|
|
|
machine_rtc_config_t RTC_DATA_ATTR machine_rtc_config = {0};
|
|
|
|
|
bool i2s_driver_installed = false;
|
|
|
|
|
int mpy_heap_size = CONFIG_MICROPY_HEAP_SIZE * 1024;
|
|
|
|
|
int MPY_DEFAULT_STACK_SIZE = 16*1024;
|
|
|
|
|
int MPY_MAX_STACK_SIZE = 32*1024;
|
|
|
|
|
int MPY_DEFAULT_HEAP_SIZE = 80*1024;
|
|
|
|
|
int MPY_MIN_HEAP_SIZE = 48*1024;
|
|
|
|
|
int MPY_MAX_HEAP_SIZE = 96*1024;
|
|
|
|
|
int hdr_maxlen = 512;
|
|
|
|
|
int body_maxlen = 1024;
|
|
|
|
|
int ssh2_hdr_maxlen = 512;
|
|
|
|
|
int ssh2_body_maxlen = 1024;
|
|
|
|
|
|
|
|
|
|
// === Variables stored in RTC_SLOW_MEM ===
|
|
|
|
|
static uint64_t RTC_DATA_ATTR s_t_wake;
|
|
|
|
|
static uint64_t RTC_DATA_ATTR stub_timeout;
|
|
|
|
|
static uint64_t RTC_DATA_ATTR stub_timer;
|
|
|
|
|
static uint32_t RTC_DATA_ATTR stub_temp;
|
|
|
|
|
static uint32_t RTC_DATA_ATTR stub_flag;
|
|
|
|
|
static uint16_t RTC_DATA_ATTR stub_timer_inc;
|
|
|
|
|
static const char RTC_RODATA_ATTR wake_fmt_str[] = "[%u] info=%u\n";
|
|
|
|
|
|
|
|
|
|
//-----------------------------------
|
|
|
|
|
static void RTC_IRAM_ATTR wake_stub()
|
|
|
|
|
{
|
|
|
|
|
// Clear MMU for CPU 0
|
|
|
|
|
_DPORT_REG_WRITE(DPORT_PRO_CACHE_CTRL1_REG, _DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG) | DPORT_PRO_CACHE_MMU_IA_CLR);
|
|
|
|
|
_DPORT_REG_WRITE(DPORT_PRO_CACHE_CTRL1_REG, _DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG) & (~DPORT_PRO_CACHE_MMU_IA_CLR));
|
|
|
|
|
|
|
|
|
|
// ROM code has not started yet, so we need to set delay factor used by ets_delay_us first.
|
|
|
|
|
ets_update_cpu_frequency_rom(ets_get_detected_xtal_freq() / 1000000);
|
|
|
|
|
|
|
|
|
|
// Update time
|
|
|
|
|
SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
|
|
|
|
|
while (GET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_VALID) == 0) {
|
|
|
|
|
;
|
|
|
|
|
}
|
|
|
|
|
SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_TIME_VALID_INT_CLR);
|
|
|
|
|
// Get current time
|
|
|
|
|
const uint64_t s_t_now = (uint64_t)READ_PERI_REG(RTC_CNTL_TIME0_REG) | (((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32);
|
|
|
|
|
|
|
|
|
|
// Check reset reason
|
|
|
|
|
if (rtc_get_reset_reason(0) != DEEPSLEEP_RESET) {
|
|
|
|
|
// Not a deepsleep reset, continue booting
|
|
|
|
|
goto do_wakeup;
|
|
|
|
|
}
|
|
|
|
|
// Check wake up cause
|
|
|
|
|
if (REG_GET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_CAUSE) & RTC_EXT0_TRIG_EN) {
|
|
|
|
|
// === EXT0 wake up ===
|
|
|
|
|
if ((machine_rtc_config.ext0_pin >= 0) && (machine_rtc_config.ext0_count > 0)) {
|
|
|
|
|
if (machine_rtc_config.pulse_count == 0) machine_rtc_config.ext0_last_time = s_t_now;
|
|
|
|
|
else {
|
|
|
|
|
if ((s_t_now - machine_rtc_config.ext0_last_time) > stub_timeout) {
|
|
|
|
|
machine_rtc_config.pulse_count = 0;
|
|
|
|
|
}
|
|
|
|
|
machine_rtc_config.ext0_last_time = s_t_now;
|
|
|
|
|
}
|
|
|
|
|
// Wait inactive ext0 pin level
|
|
|
|
|
while(1) {
|
|
|
|
|
while (1) {
|
|
|
|
|
if (machine_rtc_config.ext0_level) stub_flag = (REG_GET_FIELD(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT) & BIT(machine_rtc_config.ext0_rtcpin)) != 0;
|
|
|
|
|
else stub_flag = (REG_GET_FIELD(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT) & BIT(machine_rtc_config.ext0_rtcpin)) == 0;
|
|
|
|
|
if (!stub_flag) break;
|
|
|
|
|
REG_WRITE(TIMG_WDTFEED_REG(0), 1);
|
|
|
|
|
}
|
|
|
|
|
// Debounce, 10 ms
|
|
|
|
|
ets_delay_us(10000);
|
|
|
|
|
REG_WRITE(TIMG_WDTFEED_REG(0), 1);
|
|
|
|
|
if (machine_rtc_config.ext0_level) stub_flag = (REG_GET_FIELD(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT) & BIT(machine_rtc_config.ext0_rtcpin)) != 0;
|
|
|
|
|
else stub_flag = (REG_GET_FIELD(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT) & BIT(machine_rtc_config.ext0_rtcpin)) == 0;
|
|
|
|
|
if (stub_flag) break;
|
|
|
|
|
}
|
|
|
|
|
machine_rtc_config.pulse_count++;
|
|
|
|
|
ets_printf(wake_fmt_str, 0, machine_rtc_config.pulse_count);
|
|
|
|
|
if (machine_rtc_config.pulse_count >= machine_rtc_config.ext0_count) goto do_wakeup;
|
|
|
|
|
ets_delay_us(1000);
|
|
|
|
|
REG_WRITE(TIMG_WDTFEED_REG(0), 1);
|
|
|
|
|
goto do_sleep;
|
|
|
|
|
}
|
|
|
|
|
else goto do_wakeup;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (REG_GET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_CAUSE) & RTC_EXT1_TRIG_EN) {
|
|
|
|
|
// === EXT1 wake up ===
|
|
|
|
|
if (machine_rtc_config.ext1_level == EXT1_WAKEUP_ALL_HIGH) {
|
|
|
|
|
// some of the pins is high, but we want ALL to be high
|
|
|
|
|
stub_flag = 0;
|
|
|
|
|
for(stub_temp = 0; stub_temp < EXT1_WAKEUP_MAX_PINS; stub_temp++) {
|
|
|
|
|
if (machine_rtc_config.ext1_pins[stub_temp] >= 0) stub_flag |= BIT(machine_rtc_config.ext1_rtcpins[stub_temp]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (stub_flag) {
|
|
|
|
|
// Wait for all high
|
|
|
|
|
stub_temp = 0;
|
|
|
|
|
while ((REG_GET_FIELD(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT) & stub_flag) != stub_flag) {
|
|
|
|
|
ets_delay_us(1000);
|
|
|
|
|
REG_WRITE(TIMG_WDTFEED_REG(0), 1);
|
|
|
|
|
if ((REG_GET_FIELD(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT) & stub_flag) == 0) goto do_sleep;
|
|
|
|
|
stub_temp++;
|
|
|
|
|
if (stub_temp > 2000) goto do_sleep;
|
|
|
|
|
}
|
|
|
|
|
goto do_wakeup;
|
|
|
|
|
}
|
|
|
|
|
else goto do_wakeup;
|
|
|
|
|
}
|
|
|
|
|
goto do_wakeup;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!(REG_GET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_CAUSE) & RTC_TIMER_TRIG_EN)) {
|
|
|
|
|
// Not a timer wake up, continue booting
|
|
|
|
|
goto do_wakeup;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// === Reset reason: DEEPSLEEP_RESET & Wake up cause: Timer ===
|
|
|
|
|
if ((machine_rtc_config.deepsleep_time) && (machine_rtc_config.deepsleep_interval)) {
|
|
|
|
|
// == Set the out pin to active level if configured
|
|
|
|
|
if (machine_rtc_config.stub_outpin >= 0) {
|
|
|
|
|
gpio_pad_select_gpio(machine_rtc_config.stub_outpin);
|
|
|
|
|
if (machine_rtc_config.stub_outpin < 32)
|
|
|
|
|
gpio_output_set(machine_rtc_config.stub_outpin_level << machine_rtc_config.stub_outpin,
|
|
|
|
|
(machine_rtc_config.stub_outpin_level ? 0 : 1) << machine_rtc_config.stub_outpin,
|
|
|
|
|
1<<machine_rtc_config.stub_outpin,0);
|
|
|
|
|
else
|
|
|
|
|
gpio_output_set_high(machine_rtc_config.stub_outpin_level << (machine_rtc_config.stub_outpin-32),
|
|
|
|
|
(machine_rtc_config.stub_outpin_level ? 0 : 1) << (machine_rtc_config.stub_outpin-32),
|
|
|
|
|
1<<(machine_rtc_config.stub_outpin-32),0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// == Check remaining sleep time
|
|
|
|
|
if (machine_rtc_config.deepsleep_time > machine_rtc_config.deepsleep_interval) {
|
|
|
|
|
machine_rtc_config.deepsleep_time -= machine_rtc_config.deepsleep_interval;
|
|
|
|
|
s_t_wake = s_t_now + machine_rtc_config.wakeup_delay_ticks;
|
|
|
|
|
// Set the pointer of the wake stub function.
|
|
|
|
|
REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)&wake_stub);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (machine_rtc_config.wakeup_delay_ticks_last) {
|
|
|
|
|
s_t_wake = s_t_now + machine_rtc_config.wakeup_delay_ticks_last;
|
|
|
|
|
// Next time use the default wake stab
|
|
|
|
|
REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)&esp_wake_deep_sleep);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)&esp_wake_deep_sleep);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// == Check if we need to wait in wake stub
|
|
|
|
|
if (machine_rtc_config.stub_wait) {
|
|
|
|
|
if (machine_rtc_config.stub_wait < 1000) {
|
|
|
|
|
ets_delay_us(machine_rtc_config.stub_wait);
|
|
|
|
|
REG_WRITE(TIMG_WDTFEED_REG(0), 1);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
stub_timer = 0;
|
|
|
|
|
while (stub_timer < machine_rtc_config.stub_wait) {
|
|
|
|
|
ets_delay_us(stub_timer_inc);
|
|
|
|
|
REG_WRITE(TIMG_WDTFEED_REG(0), 1);
|
|
|
|
|
stub_timer += stub_timer_inc;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// == Reset the led pin if configured
|
|
|
|
|
if (machine_rtc_config.stub_outpin >= 0) {
|
|
|
|
|
if (machine_rtc_config.stub_outpin < 32)
|
|
|
|
|
gpio_output_set(machine_rtc_config.stub_outpin_level << machine_rtc_config.stub_outpin,
|
|
|
|
|
(machine_rtc_config.stub_outpin_level ? 1 : 0) << machine_rtc_config.stub_outpin,
|
|
|
|
|
1<<machine_rtc_config.stub_outpin,0);
|
|
|
|
|
else
|
|
|
|
|
gpio_output_set_high(machine_rtc_config.stub_outpin_level << (machine_rtc_config.stub_outpin-32),
|
|
|
|
|
(machine_rtc_config.stub_outpin_level ? 1 : 0) << (machine_rtc_config.stub_outpin-32),
|
|
|
|
|
1<<(machine_rtc_config.stub_outpin-32),0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else goto do_wakeup;
|
|
|
|
|
|
|
|
|
|
// === Go back to deepsleep ===
|
|
|
|
|
// Write clock value to RTC:
|
|
|
|
|
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER0_REG, s_t_wake & UINT32_MAX);
|
|
|
|
|
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER1_REG, s_t_wake >> 32);
|
|
|
|
|
|
|
|
|
|
do_sleep:
|
|
|
|
|
ets_printf(wake_fmt_str, 88, 88);
|
|
|
|
|
// Wait for UART to end transmitting.
|
|
|
|
|
while (REG_GET_FIELD(UART_STATUS_REG(0), UART_ST_UTX_OUT)) {
|
|
|
|
|
REG_WRITE(TIMG_WDTFEED_REG(0), 1); // feed the watchdog
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)&wake_stub);
|
|
|
|
|
// Go to sleep.
|
|
|
|
|
CLEAR_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
|
|
|
|
|
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
|
|
|
|
|
|
|
|
|
|
// A few CPU cycles may be necessary for the sleep to start...
|
|
|
|
|
while (true) {
|
|
|
|
|
;
|
|
|
|
|
}
|
|
|
|
|
// never reaches here.
|
|
|
|
|
|
|
|
|
|
do_wakeup:
|
|
|
|
|
ets_printf(wake_fmt_str, 99, 99);
|
|
|
|
|
// Wait for UART to end transmitting.
|
|
|
|
|
while (REG_GET_FIELD(UART_STATUS_REG(0), UART_ST_UTX_OUT)) {
|
|
|
|
|
REG_WRITE(TIMG_WDTFEED_REG(0), 1); // feed the watchdog
|
|
|
|
|
}
|
|
|
|
|
REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)&wake_stub);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2018-01-03 14:18:06 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------
|
|
|
|
|
void prepareSleepReset(uint8_t hrst, char *msg)
|
|
|
|
|
{
|
|
|
|
|
// Umount external & internal fs
|
2018-12-04 14:06:15 +08:00
|
|
|
externalUmount();
|
|
|
|
|
internalUmount();
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
if (!hrst) {
|
|
|
|
|
if (msg) mp_hal_stdout_tx_str(msg);
|
|
|
|
|
/*
|
|
|
|
|
// stop and deinitialize WiFi
|
|
|
|
|
if (wifi_network_state == WIFI_STATE_STARTED) {
|
|
|
|
|
wifi_network_state = WIFI_STATE_STOPPED;
|
|
|
|
|
wifi_sta_isconnected = false;
|
|
|
|
|
wifi_sta_has_ipaddress = false;
|
|
|
|
|
wifi_sta_changed_ipaddress = false;
|
|
|
|
|
wifi_ap_isconnected = false;
|
|
|
|
|
wifi_ap_sta_isconnected = false;
|
|
|
|
|
esp_wifi_stop();
|
|
|
|
|
esp_wifi_deinit();
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
// deinitialise peripherals
|
|
|
|
|
//ToDo: deinitialize other peripherals, threads, services, ...
|
|
|
|
|
machine_pins_deinit();
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
mp_deinit();
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
}
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
|
STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
|
|
|
|
|
if (n_args == 0) {
|
2018-12-04 14:06:15 +08:00
|
|
|
// get CPU frequency
|
|
|
|
|
return mp_obj_new_int(rtc_clk_cpu_freq_value(rtc_clk_cpu_freq_get()));
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
|
|
|
|
else {
|
2018-12-04 14:06:15 +08:00
|
|
|
// set CPU frequency
|
|
|
|
|
int freq = mp_obj_get_int(args[0]);
|
|
|
|
|
if (freq > 240) freq /= 1000000;
|
|
|
|
|
rtc_cpu_freq_t max_freq;
|
|
|
|
|
if (!rtc_clk_cpu_freq_from_mhz(freq, &max_freq)) {
|
|
|
|
|
char msg[128];
|
|
|
|
|
sprintf(msg, "Available frequencies: 2MHz, 80Mhz, 160MHz, 240MHz or %uMHz (XTAL)", rtc_clk_xtal_freq_get());
|
|
|
|
|
mp_raise_ValueError(msg);
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
2018-12-04 14:06:15 +08:00
|
|
|
#ifdef CONFIG_PM_ENABLE
|
|
|
|
|
esp_pm_config_esp32_t pm_config;
|
|
|
|
|
pm_config.max_cpu_freq = max_freq;
|
|
|
|
|
pm_config.min_cpu_freq = RTC_CPU_FREQ_XTAL;
|
|
|
|
|
pm_config.light_sleep_enable = false;
|
|
|
|
|
if (esp_pm_configure(&pm_config) != ESP_OK) {
|
|
|
|
|
mp_raise_msg(&mp_type_OSError, "Error configuring frequency");
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
rtc_clk_cpu_freq_set(max_freq);
|
|
|
|
|
uart_set_baudrate(UART_NUM_0, CONFIG_CONSOLE_UART_BAUDRATE);
|
2018-01-03 14:18:06 +01:00
|
|
|
return mp_const_none;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_freq_obj, 0, 1, machine_freq);
|
|
|
|
|
|
|
|
|
|
//-----------------------------------
|
|
|
|
|
STATIC mp_obj_t machine_reset(void) {
|
|
|
|
|
prepareSleepReset(1, NULL);
|
|
|
|
|
|
|
|
|
|
esp_restart(); // This function does not return.
|
|
|
|
|
|
|
|
|
|
return mp_const_none;
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_obj, machine_reset);
|
|
|
|
|
|
|
|
|
|
//---------------------------------------
|
|
|
|
|
STATIC mp_obj_t machine_unique_id(void) {
|
|
|
|
|
uint8_t chipid[6];
|
|
|
|
|
esp_efuse_mac_get_default(chipid);
|
|
|
|
|
return mp_obj_new_bytes(chipid, 6);
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_unique_id_obj, machine_unique_id);
|
|
|
|
|
|
|
|
|
|
//----------------------------------
|
|
|
|
|
STATIC mp_obj_t machine_idle(void) {
|
|
|
|
|
taskYIELD();
|
|
|
|
|
return mp_const_none;
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_idle_obj, machine_idle);
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------
|
|
|
|
|
STATIC mp_obj_t machine_disable_irq(void) {
|
|
|
|
|
uint32_t state = MICROPY_BEGIN_ATOMIC_SECTION();
|
|
|
|
|
return mp_obj_new_int(state);
|
|
|
|
|
}
|
|
|
|
|
MP_DEFINE_CONST_FUN_OBJ_0(machine_disable_irq_obj, machine_disable_irq);
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------
|
|
|
|
|
STATIC mp_obj_t machine_enable_irq(mp_obj_t state_in) {
|
|
|
|
|
uint32_t state = mp_obj_get_int(state_in);
|
|
|
|
|
MICROPY_END_ATOMIC_SECTION(state);
|
|
|
|
|
return mp_const_none;
|
|
|
|
|
}
|
|
|
|
|
MP_DEFINE_CONST_FUN_OBJ_1(machine_enable_irq_obj, machine_enable_irq);
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------
|
|
|
|
|
static void print_heap_info(multi_heap_info_t *info)
|
|
|
|
|
{
|
2018-12-04 14:06:15 +08:00
|
|
|
mp_printf(&mp_plat_print, " Free: %u\n", info->total_free_bytes);
|
|
|
|
|
mp_printf(&mp_plat_print, " Allocated: %u\n", info->total_allocated_bytes);
|
|
|
|
|
mp_printf(&mp_plat_print, " Minimum free: %u\n", info->minimum_free_bytes);
|
|
|
|
|
mp_printf(&mp_plat_print, " Total blocks: %u\n", info->total_blocks);
|
|
|
|
|
mp_printf(&mp_plat_print, "Largest free block: %u\n", info->largest_free_block);
|
|
|
|
|
mp_printf(&mp_plat_print, " Allocated blocks: %u\n", info->allocated_blocks);
|
|
|
|
|
mp_printf(&mp_plat_print, " Free blocks: %u\n", info->free_blocks);
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------
|
|
|
|
|
STATIC mp_obj_t machine_heap_info(void) {
|
2018-12-04 14:06:15 +08:00
|
|
|
multi_heap_info_t info;
|
2018-01-03 14:18:06 +01:00
|
|
|
|
|
|
|
|
mp_printf(&mp_plat_print, "Heap outside of MicroPython heap:\n---------------------------------\n");
|
|
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
heap_caps_get_info(&info, MALLOC_CAP_INTERNAL | MALLOC_CAP_32BIT | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
|
|
|
|
print_heap_info(&info);
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
if (mpy_use_spiram) {
|
|
|
|
|
#if CONFIG_SPIRAM_USE_MEMMAP
|
|
|
|
|
mp_printf(&mp_plat_print, "\nSPIRAM info (MEMMAP used):\n--------------------------\n");
|
|
|
|
|
mp_printf(&mp_plat_print, " Total: %u\n", CONFIG_SPIRAM_SIZE);
|
|
|
|
|
mp_printf(&mp_plat_print, "Used for MPy heap: %u\n", mpy_heap_size);
|
|
|
|
|
mp_printf(&mp_plat_print, " Free (not used): %u\n", CONFIG_SPIRAM_SIZE - mpy_heap_size);
|
|
|
|
|
#else
|
|
|
|
|
mp_printf(&mp_plat_print, "\nSPIRAM info:\n------------\n");
|
|
|
|
|
heap_caps_get_info(&info, MALLOC_CAP_SPIRAM);
|
|
|
|
|
print_heap_info(&info);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
return mp_const_none;
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
|
|
|
|
MP_DEFINE_CONST_FUN_OBJ_0(machine_heap_info_obj, machine_heap_info);
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------
|
|
|
|
|
STATIC mp_obj_t machine_deepsleep(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
|
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
enum {ARG_sleep_ms, ARG_stub_ms, ARG_stub_led, ARG_stub_ledlevel, ARG_stub_wait};
|
2018-01-03 14:18:06 +01:00
|
|
|
const mp_arg_t allowed_args[] = {
|
2018-12-04 14:06:15 +08:00
|
|
|
{ MP_QSTR_sleep_ms, MP_ARG_INT, { .u_int = 0 } },
|
|
|
|
|
{ MP_QSTR_stub_ms, MP_ARG_INT, { .u_int = 0 } },
|
|
|
|
|
{ MP_QSTR_stub_led, MP_ARG_INT, { .u_int = -1 } },
|
|
|
|
|
{ MP_QSTR_stub_ledlevel, MP_ARG_BOOL, { .u_bool = false } },
|
|
|
|
|
{ MP_QSTR_stub_wait, MP_ARG_INT, { .u_int = 0 } },
|
2018-01-03 14:18:06 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
|
|
|
|
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
|
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
esp_set_deep_sleep_wake_stub(&esp_wake_deep_sleep);
|
|
|
|
|
//REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)&esp_wake_deep_sleep);
|
|
|
|
|
machine_rtc_config.stub_outpin = -1;
|
|
|
|
|
machine_rtc_config.pulse_count = 0;
|
|
|
|
|
machine_rtc_config.deepsleep_interval = 0;
|
|
|
|
|
machine_rtc_config.stub_wait = 0;
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
uint32_t s_rtc_clk_cal = (uint64_t)REG_READ(RTC_SLOW_CLK_CAL_REG);
|
|
|
|
|
stub_timeout = (uint64_t)(2000000) * (1 << RTC_CLK_CAL_FRACT) / s_rtc_clk_cal;
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
int64_t stub_sleep = 0;
|
|
|
|
|
int64_t sleep_time = args[ARG_sleep_ms].u_int;
|
|
|
|
|
if (sleep_time < 0) sleep_time = 0;
|
|
|
|
|
if (sleep_time > 0) {
|
|
|
|
|
stub_sleep = args[ARG_stub_ms].u_int;
|
|
|
|
|
if (stub_sleep < 0) stub_sleep = 0;
|
|
|
|
|
if (stub_sleep >= sleep_time) stub_sleep = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int led_pin = args[ARG_stub_led].u_int;
|
|
|
|
|
if ((led_pin < -1) || (led_pin > 34)) {
|
|
|
|
|
mp_raise_ValueError("Wrong led pin !");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int64_t wait_in_stub = 0;
|
|
|
|
|
if (stub_sleep > 0) {
|
|
|
|
|
wait_in_stub = (int64_t)args[ARG_stub_wait].u_int;
|
|
|
|
|
if (wait_in_stub < 0) wait_in_stub = 0;
|
|
|
|
|
if (wait_in_stub > (stub_sleep*1000)) wait_in_stub = stub_sleep*1000;
|
|
|
|
|
machine_rtc_config.stub_wait = wait_in_stub;
|
|
|
|
|
stub_timer_inc = 1;
|
|
|
|
|
if (wait_in_stub > 100000) stub_timer_inc = 100;
|
|
|
|
|
else stub_timer_inc = 10;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sleep_time > 0) {
|
|
|
|
|
if (stub_sleep) esp_sleep_enable_timer_wakeup(stub_sleep * 1000);
|
|
|
|
|
else esp_sleep_enable_timer_wakeup(sleep_time * 1000);
|
|
|
|
|
machine_rtc_config.deepsleep_time = sleep_time;
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
2018-02-05 18:14:30 +01:00
|
|
|
else {
|
|
|
|
|
if ((machine_rtc_config.ext0_pin < 0) && (machine_rtc_config.ext1_pins == 0) && (!machine_rtc_config.wake_on_touch)) {
|
|
|
|
|
mp_raise_ValueError("No other wake-up sources configured, sleep time cannot be 0 !");
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
if (machine_rtc_config.ext0_pin >= 0) {
|
|
|
|
|
ESP_LOGD("DEEP SLEEP", "EXT0=%d\n", machine_rtc_config.ext0_pin);
|
|
|
|
|
esp_sleep_enable_ext0_wakeup((gpio_num_t)machine_rtc_config.ext0_pin, machine_rtc_config.ext0_level ? 1 : 0);
|
|
|
|
|
esp_set_deep_sleep_wake_stub(&wake_stub);
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
|
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
uint64_t ext1_pins = 0;
|
|
|
|
|
for (int i = 0; i < EXT1_WAKEUP_MAX_PINS; i++) {
|
|
|
|
|
if (machine_rtc_config.ext1_pins[i] >= 0) {
|
|
|
|
|
uint64_t pin_bit = (1ll << machine_rtc_config.ext1_pins[i]);
|
|
|
|
|
ext1_pins |= pin_bit;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (ext1_pins != 0) {
|
|
|
|
|
ESP_LOGD("DEEP SLEEP", "EXT1 = [%llx]\n", ext1_pins);
|
|
|
|
|
//esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
|
|
|
|
uint8_t ext1_level = machine_rtc_config.ext1_level;
|
|
|
|
|
if (machine_rtc_config.ext1_level == EXT1_WAKEUP_ALL_HIGH) ext1_level = ESP_EXT1_WAKEUP_ANY_HIGH;
|
|
|
|
|
esp_sleep_enable_ext1_wakeup(ext1_pins, ext1_level);
|
|
|
|
|
esp_set_deep_sleep_wake_stub(&wake_stub);
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (machine_rtc_config.wake_on_touch) {
|
2018-12-04 14:06:15 +08:00
|
|
|
esp_sleep_enable_touchpad_wakeup();
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
|
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
ESP_LOGD("DEEP SLEEP", "Sleep time: time=%llu, interval=%llu, pin=%d, level=%d, wait=%llu\n",
|
|
|
|
|
sleep_time, stub_sleep, led_pin, args[ARG_stub_ledlevel].u_bool, wait_in_stub);
|
|
|
|
|
prepareSleepReset(0, NULL);
|
|
|
|
|
|
|
|
|
|
if ((stub_sleep) || (led_pin >= 0)) {
|
|
|
|
|
if (led_pin >= 0) {
|
|
|
|
|
gpio_pad_select_gpio(led_pin);
|
|
|
|
|
gpio_set_direction(led_pin, GPIO_MODE_OUTPUT);
|
|
|
|
|
gpio_set_level(led_pin, (uint8_t)args[ARG_stub_ledlevel].u_bool ^ 1);
|
|
|
|
|
machine_rtc_config.stub_outpin = (uint8_t)led_pin;
|
|
|
|
|
machine_rtc_config.stub_outpin_level = (uint8_t)args[ARG_stub_ledlevel].u_bool;
|
|
|
|
|
}
|
|
|
|
|
else machine_rtc_config.stub_outpin = -1;
|
|
|
|
|
|
|
|
|
|
if (stub_sleep) {
|
|
|
|
|
// Get number of microseconds per RTC clock tick (scaled by 2^19)
|
|
|
|
|
// Calculate RTC clock value for wakeup
|
|
|
|
|
machine_rtc_config.wakeup_delay_ticks = (stub_sleep * 1000) * (1 << RTC_CLK_CAL_FRACT) / s_rtc_clk_cal;
|
|
|
|
|
machine_rtc_config.wakeup_delay_ticks_last = ((sleep_time % stub_sleep) * 1000) * (1 << RTC_CLK_CAL_FRACT) / s_rtc_clk_cal;;
|
|
|
|
|
|
|
|
|
|
// Set the wake stub function
|
|
|
|
|
machine_rtc_config.deepsleep_interval = stub_sleep;
|
|
|
|
|
}
|
|
|
|
|
esp_set_deep_sleep_wake_stub(&wake_stub);
|
|
|
|
|
}
|
2018-01-03 14:18:06 +01:00
|
|
|
|
|
|
|
|
esp_deep_sleep_start(); // This function does not return.
|
|
|
|
|
|
|
|
|
|
return mp_const_none;
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_deepsleep_obj, 0, machine_deepsleep);
|
|
|
|
|
|
|
|
|
|
//------------------------------------------
|
|
|
|
|
STATIC mp_obj_t machine_wake_reason (void) {
|
|
|
|
|
mpsleep_reset_cause_t reset_reason = mpsleep_get_reset_cause ();
|
|
|
|
|
mpsleep_wake_reason_t wake_reason = mpsleep_get_wake_reason();
|
|
|
|
|
mp_obj_t tuple[2];
|
|
|
|
|
|
2018-02-05 18:14:30 +01:00
|
|
|
tuple[0] = mp_obj_new_int(reset_reason);
|
|
|
|
|
tuple[1] = mp_obj_new_int(wake_reason);
|
2018-01-03 14:18:06 +01:00
|
|
|
return mp_obj_new_tuple(2, tuple);
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_wake_reason_obj, machine_wake_reason);
|
|
|
|
|
|
|
|
|
|
//----------------------------------------
|
|
|
|
|
STATIC mp_obj_t machine_wake_desc (void) {
|
|
|
|
|
char reason[24] = { 0 };
|
|
|
|
|
mp_obj_t tuple[2];
|
|
|
|
|
|
|
|
|
|
mpsleep_get_reset_desc(reason);
|
2018-12-04 14:06:15 +08:00
|
|
|
tuple[0] = mp_obj_new_str(reason, strlen(reason));
|
2018-01-03 14:18:06 +01:00
|
|
|
mpsleep_get_wake_desc(reason);
|
2018-12-04 14:06:15 +08:00
|
|
|
tuple[1] = mp_obj_new_str(reason, strlen(reason));
|
2018-01-03 14:18:06 +01:00
|
|
|
return mp_obj_new_tuple(2, tuple);
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_wake_desc_obj, machine_wake_desc);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
|
STATIC mp_obj_t machine_stdin_get (mp_obj_t sz_in, mp_obj_t timeout_in) {
|
|
|
|
|
mp_int_t timeout = mp_obj_get_int(timeout_in);
|
|
|
|
|
mp_int_t sz = mp_obj_get_int(sz_in);
|
|
|
|
|
if (sz == 0) {
|
|
|
|
|
return mp_const_none;
|
|
|
|
|
}
|
|
|
|
|
int c = -1;
|
|
|
|
|
vstr_t vstr;
|
|
|
|
|
mp_int_t recv = 0;
|
|
|
|
|
|
|
|
|
|
vstr_init_len(&vstr, sz);
|
|
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
xSemaphoreTake(uart0_mutex, UART_SEMAPHORE_WAIT);
|
|
|
|
|
uart0_raw_input = 1;
|
|
|
|
|
xSemaphoreGive(uart0_mutex);
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
while (recv < sz) {
|
|
|
|
|
c = mp_hal_stdin_rx_chr(timeout);
|
|
|
|
|
if (c < 0) break;
|
|
|
|
|
vstr.buf[recv++] = (byte)c;
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xSemaphoreTake(uart0_mutex, UART_SEMAPHORE_WAIT);
|
2018-12-04 14:06:15 +08:00
|
|
|
uart0_raw_input = 0;
|
|
|
|
|
xSemaphoreGive(uart0_mutex);
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
if (recv == 0) {
|
2018-01-03 14:18:06 +01:00
|
|
|
return mp_const_none;
|
2018-12-04 14:06:15 +08:00
|
|
|
}
|
2018-01-03 14:18:06 +01:00
|
|
|
return mp_obj_new_str_from_vstr(&mp_type_str, &vstr);;
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_stdin_get_obj, machine_stdin_get);
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------
|
|
|
|
|
STATIC mp_obj_t machine_stdout_put (mp_obj_t buf_in) {
|
|
|
|
|
mp_buffer_info_t bufinfo;
|
|
|
|
|
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
|
|
|
|
|
mp_int_t len = bufinfo.len;
|
|
|
|
|
char *buf = bufinfo.buf;
|
|
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
xSemaphoreTake(uart0_mutex, UART_SEMAPHORE_WAIT);
|
|
|
|
|
uart0_raw_input = 1;
|
|
|
|
|
xSemaphoreGive(uart0_mutex);
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
mp_hal_stdout_tx_strn(buf, len);
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
xSemaphoreTake(uart0_mutex, UART_SEMAPHORE_WAIT);
|
|
|
|
|
uart0_raw_input = 0;
|
|
|
|
|
xSemaphoreGive(uart0_mutex);
|
2018-01-03 14:18:06 +01:00
|
|
|
|
|
|
|
|
return mp_obj_new_int_from_uint(bufinfo.len);
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_stdout_put_obj, machine_stdout_put);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Assumes 0 <= max <= RAND_MAX
|
|
|
|
|
// Returns in the closed interval [0, max]
|
|
|
|
|
//--------------------------------------------
|
2018-12-04 14:06:15 +08:00
|
|
|
uint64_t random_at_most(uint32_t max) {
|
|
|
|
|
uint64_t // max <= RAND_MAX < ULONG_MAX, so this is okay.
|
|
|
|
|
num_bins = (uint64_t) max + 1,
|
|
|
|
|
num_rand = (uint64_t) 0xFFFFFFFF + 1,
|
|
|
|
|
bin_size = num_rand / num_bins,
|
|
|
|
|
defect = num_rand % num_bins;
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
uint32_t x;
|
|
|
|
|
do {
|
|
|
|
|
x = esp_random();
|
|
|
|
|
}
|
|
|
|
|
while (num_rand - defect <= (uint64_t)x); // This is carefully written not to overflow
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
// Truncated division is intentional
|
|
|
|
|
return x/bin_size;
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
|
STATIC mp_obj_t machine_random(size_t n_args, const mp_obj_t *args)
|
|
|
|
|
{
|
2018-12-04 14:06:15 +08:00
|
|
|
if (n_args == 1) {
|
|
|
|
|
uint32_t rmax = mp_obj_get_int(args[0]);
|
|
|
|
|
return mp_obj_new_int_from_uint(random_at_most(rmax));
|
|
|
|
|
}
|
|
|
|
|
uint32_t rmin = mp_obj_get_int(args[0]);
|
|
|
|
|
uint32_t rmax = mp_obj_get_int(args[1]);
|
|
|
|
|
return mp_obj_new_int_from_uint(rmin + random_at_most(rmax - rmin));
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
|
|
|
|
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_random_obj, 1, 2, machine_random);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ==== NVS Support ===================================================================
|
|
|
|
|
|
|
|
|
|
static void checkNVS()
|
|
|
|
|
{
|
|
|
|
|
if (mpy_nvs_handle == 0) {
|
2018-12-04 14:06:15 +08:00
|
|
|
mp_raise_msg(&mp_type_OSError, "NVS not available!");
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
STATIC mp_obj_t mod_machine_nvs_set_int (mp_obj_t _key, mp_obj_t _value) {
|
2018-12-04 14:06:15 +08:00
|
|
|
checkNVS();
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
const char *key = mp_obj_str_get_str(_key);
|
2018-01-03 14:18:06 +01:00
|
|
|
uint32_t value = mp_obj_get_int_truncated(_value);
|
|
|
|
|
|
|
|
|
|
esp_err_t esp_err = nvs_set_i32(mpy_nvs_handle, key, value);
|
|
|
|
|
if (ESP_OK == esp_err) {
|
|
|
|
|
nvs_commit(mpy_nvs_handle);
|
|
|
|
|
}
|
|
|
|
|
else if (ESP_ERR_NVS_NOT_ENOUGH_SPACE == esp_err || ESP_ERR_NVS_PAGE_FULL == esp_err || ESP_ERR_NVS_NO_FREE_PAGES == esp_err) {
|
2018-12-04 14:06:15 +08:00
|
|
|
mp_raise_msg(&mp_type_OSError, "No space available.");
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
|
|
|
|
else if (ESP_ERR_NVS_INVALID_NAME == esp_err || ESP_ERR_NVS_KEY_TOO_LONG == esp_err) {
|
2018-12-04 14:06:15 +08:00
|
|
|
mp_raise_msg(&mp_type_OSError, "Key invalid or too long");
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
|
|
|
|
return mp_const_none;
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_machine_nvs_set_int_obj, mod_machine_nvs_set_int);
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------
|
|
|
|
|
STATIC mp_obj_t mod_machine_nvs_get_int (mp_obj_t _key) {
|
2018-12-04 14:06:15 +08:00
|
|
|
checkNVS();
|
2018-01-03 14:18:06 +01:00
|
|
|
|
|
|
|
|
const char *key = mp_obj_str_get_str(_key);
|
|
|
|
|
int value = 0;
|
|
|
|
|
|
|
|
|
|
if (ESP_ERR_NVS_NOT_FOUND == nvs_get_i32(mpy_nvs_handle, key, &value)) {
|
|
|
|
|
return mp_const_none;
|
|
|
|
|
}
|
|
|
|
|
return mp_obj_new_int(value);
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_machine_nvs_get_int_obj, mod_machine_nvs_get_int);
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
STATIC mp_obj_t mod_machine_nvs_set_str (mp_obj_t _key, mp_obj_t _value) {
|
2018-12-04 14:06:15 +08:00
|
|
|
checkNVS();
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
const char *key = mp_obj_str_get_str(_key);
|
|
|
|
|
const char *value = mp_obj_str_get_str(_value);
|
2018-01-03 14:18:06 +01:00
|
|
|
|
|
|
|
|
esp_err_t esp_err = nvs_set_str(mpy_nvs_handle, key, value);
|
|
|
|
|
if (ESP_OK == esp_err) {
|
|
|
|
|
nvs_commit(mpy_nvs_handle);
|
|
|
|
|
}
|
|
|
|
|
else if (ESP_ERR_NVS_NOT_ENOUGH_SPACE == esp_err || ESP_ERR_NVS_PAGE_FULL == esp_err || ESP_ERR_NVS_NO_FREE_PAGES == esp_err) {
|
2018-12-04 14:06:15 +08:00
|
|
|
mp_raise_msg(&mp_type_OSError, "No space available.");
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
|
|
|
|
else if (ESP_ERR_NVS_INVALID_NAME == esp_err || ESP_ERR_NVS_KEY_TOO_LONG == esp_err) {
|
2018-12-04 14:06:15 +08:00
|
|
|
mp_raise_msg(&mp_type_OSError, "Key invalid or too long");
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
|
|
|
|
return mp_const_none;
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_machine_nvs_set_str_obj, mod_machine_nvs_set_str);
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------
|
|
|
|
|
STATIC mp_obj_t mod_machine_nvs_get_str (mp_obj_t _key) {
|
2018-12-04 14:06:15 +08:00
|
|
|
checkNVS();
|
2018-01-03 14:18:06 +01:00
|
|
|
|
|
|
|
|
const char *key = mp_obj_str_get_str(_key);
|
|
|
|
|
size_t len = 0;
|
|
|
|
|
mp_obj_t strval = mp_const_none;
|
|
|
|
|
|
|
|
|
|
esp_err_t ret = nvs_get_str(mpy_nvs_handle, key, NULL, &len);
|
|
|
|
|
if ((ret == ESP_OK ) && (len > 0)) {
|
|
|
|
|
char *value = malloc(len);
|
|
|
|
|
if (value) {
|
|
|
|
|
esp_err_t ret = nvs_get_str(mpy_nvs_handle, key, value, &len);
|
|
|
|
|
if ((ret == ESP_OK ) && (len > 0)) {
|
2018-12-04 14:06:15 +08:00
|
|
|
strval = mp_obj_new_str(value, strlen(value));
|
2018-01-03 14:18:06 +01:00
|
|
|
free(value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return strval;
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_machine_nvs_get_str_obj, mod_machine_nvs_get_str);
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------
|
|
|
|
|
STATIC mp_obj_t mod_machine_nvs_erase (mp_obj_t _key) {
|
2018-12-04 14:06:15 +08:00
|
|
|
checkNVS();
|
2018-01-03 14:18:06 +01:00
|
|
|
|
|
|
|
|
const char *key = mp_obj_str_get_str(_key);
|
|
|
|
|
|
|
|
|
|
if (ESP_ERR_NVS_NOT_FOUND == nvs_erase_key(mpy_nvs_handle, key)) {
|
|
|
|
|
mp_raise_ValueError("Key not found");
|
|
|
|
|
}
|
|
|
|
|
return mp_const_none;
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_machine_nvs_erase_obj, mod_machine_nvs_erase);
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------
|
|
|
|
|
STATIC mp_obj_t mod_machine_nvs_erase_all (void) {
|
2018-12-04 14:06:15 +08:00
|
|
|
checkNVS();
|
2018-01-03 14:18:06 +01:00
|
|
|
|
|
|
|
|
if (ESP_OK != nvs_erase_all(mpy_nvs_handle)) {
|
2018-12-04 14:06:15 +08:00
|
|
|
mp_raise_msg(&mp_type_OSError, "Operation failed.");
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
|
|
|
|
return mp_const_none;
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_machine_nvs_erase_all_obj, mod_machine_nvs_erase_all);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ==== ESP32 log level ===================================================================
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
|
static int vprintf_redirected(const char *fmt, va_list ap)
|
|
|
|
|
{
|
|
|
|
|
int ret = mp_vprintf(&mp_plat_print, fmt, ap);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
static vprintf_like_t orig_log_func = NULL;
|
|
|
|
|
static vprintf_like_t prev_log_func = NULL;
|
2018-01-03 14:18:06 +01:00
|
|
|
static vprintf_like_t mp_log_func = &vprintf_redirected;
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
STATIC mp_obj_t mod_machine_log_level (mp_obj_t tag_in, mp_obj_t level_in) {
|
2018-12-04 14:06:15 +08:00
|
|
|
const char *tag = mp_obj_str_get_str(tag_in);
|
2018-01-03 14:18:06 +01:00
|
|
|
int32_t level = mp_obj_get_int(level_in);
|
|
|
|
|
if ((level < 0) || (level > 5)) {
|
2018-12-04 14:06:15 +08:00
|
|
|
mp_raise_ValueError("Log level 0~5 expected");
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
|
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
esp_log_level_set(tag, level);
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
return mp_const_none;
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_machine_log_level_obj, mod_machine_log_level);
|
|
|
|
|
|
|
|
|
|
//---------------------------------------
|
|
|
|
|
STATIC mp_obj_t mod_machine_logto_mp () {
|
2018-12-04 14:06:15 +08:00
|
|
|
if (orig_log_func == NULL) {
|
|
|
|
|
orig_log_func = esp_log_set_vprintf(mp_log_func);
|
|
|
|
|
}
|
|
|
|
|
return mp_const_none;
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_machine_logto_mp_obj, mod_machine_logto_mp);
|
|
|
|
|
|
|
|
|
|
//----------------------------------------
|
|
|
|
|
STATIC mp_obj_t mod_machine_logto_esp () {
|
2018-12-04 14:06:15 +08:00
|
|
|
if (orig_log_func != NULL) {
|
|
|
|
|
prev_log_func = esp_log_set_vprintf(orig_log_func);
|
|
|
|
|
orig_log_func = NULL;
|
|
|
|
|
}
|
|
|
|
|
return mp_const_none;
|
2018-01-03 14:18:06 +01:00
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_machine_logto_esp_obj, mod_machine_logto_esp);
|
|
|
|
|
|
2018-02-28 14:46:02 +01:00
|
|
|
//-----------------------------------
|
|
|
|
|
STATIC mp_obj_t mod_machine_tsens() {
|
2018-12-04 14:06:15 +08:00
|
|
|
int temper = 0;
|
|
|
|
|
|
|
|
|
|
// --- Using code from esp-idf/components/esp32/test/test_tsens.c ---
|
|
|
|
|
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 3, SENS_FORCE_XPD_SAR_S);
|
2018-02-28 14:46:02 +01:00
|
|
|
SET_PERI_REG_BITS(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_CLK_DIV, 10, SENS_TSENS_CLK_DIV_S);
|
|
|
|
|
CLEAR_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_POWER_UP);
|
|
|
|
|
CLEAR_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_DUMP_OUT);
|
|
|
|
|
SET_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_POWER_UP_FORCE);
|
|
|
|
|
SET_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_POWER_UP);
|
|
|
|
|
ets_delay_us(100);
|
|
|
|
|
SET_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_DUMP_OUT);
|
|
|
|
|
ets_delay_us(5);
|
|
|
|
|
//while(REG_GET_FIELD(SENS_SAR_SLAVE_ADDR3_REG, SENS_TSENS_RDY_OUT) == 0) {
|
|
|
|
|
// ;
|
|
|
|
|
//}
|
2018-12-04 14:06:15 +08:00
|
|
|
temper = GET_PERI_REG_BITS2(SENS_SAR_SLAVE_ADDR3_REG, SENS_TSENS_OUT, SENS_TSENS_OUT_S);
|
2018-02-28 14:46:02 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
// --- Using function from esp-idf/components/esp32/lib/librtc.a ---
|
|
|
|
|
//temper = temprature_sens_read();
|
2018-02-28 14:46:02 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
// The returned temperature is in Fahrenheit, convert to Celsius
|
|
|
|
|
float ftemper = (float)(temper - 32) / 1.8;
|
|
|
|
|
|
|
|
|
|
mp_obj_t tuple[2];
|
2018-02-28 14:46:02 +01:00
|
|
|
|
|
|
|
|
tuple[0] = mp_obj_new_int_from_uint(temper);
|
|
|
|
|
tuple[1] = mp_obj_new_float(ftemper);
|
|
|
|
|
return mp_obj_new_tuple(2, tuple);
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_machine_tsens_obj, mod_machine_tsens);
|
|
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
//------------------------------------
|
|
|
|
|
STATIC mp_obj_t mod_machine_vdd33() {
|
|
|
|
|
uint16_t val = rom_phy_get_vdd33();
|
|
|
|
|
|
|
|
|
|
return mp_obj_new_int(val);
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_machine_vdd33_obj, mod_machine_vdd33);
|
|
|
|
|
|
2018-02-28 14:46:02 +01:00
|
|
|
//--------------------------------------------------------------
|
|
|
|
|
STATIC mp_obj_t mod_machine_stdin_disable(mp_obj_t pattern_in) {
|
2018-12-04 14:06:15 +08:00
|
|
|
bool has_pattern = false;
|
|
|
|
|
mp_buffer_info_t pattern_buff;
|
|
|
|
|
mp_obj_type_t *type = mp_obj_get_type(pattern_in);
|
|
|
|
|
char pattern[16] = {'\0'};
|
|
|
|
|
if (type->buffer_p.get_buffer != NULL) {
|
|
|
|
|
int ret = type->buffer_p.get_buffer(pattern_in, &pattern_buff, MP_BUFFER_READ);
|
|
|
|
|
if (ret == 0) {
|
|
|
|
|
if ((pattern_buff.len > 0) && (pattern_buff.len < 16)) has_pattern = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!has_pattern) {
|
|
|
|
|
mp_raise_ValueError("invalid pattern (15 chars allowed)");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memcpy(pattern, pattern_buff.buf, pattern_buff.len);
|
|
|
|
|
disableStdin(pattern);
|
2018-02-28 14:46:02 +01:00
|
|
|
return mp_const_none;
|
|
|
|
|
}
|
2018-12-04 14:06:15 +08:00
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_machine_stdin_disable_obj, mod_machine_stdin_disable);
|
|
|
|
|
|
|
|
|
|
//---------------------------------------
|
|
|
|
|
STATIC mp_obj_t mod_machine_reset_wdt() {
|
|
|
|
|
mp_hal_reset_wdt();
|
|
|
|
|
return mp_const_none;
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_machine_reset_wdt_obj, mod_machine_reset_wdt);
|
|
|
|
|
|
|
|
|
|
//-------------------------------------
|
|
|
|
|
STATIC mp_obj_t mod_machine_set_wdt() {
|
|
|
|
|
mp_hal_set_wdt_tmo();
|
|
|
|
|
return mp_const_none;
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_machine_set_wdt_obj, mod_machine_set_wdt);
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
|
STATIC mp_obj_t mod_machine_wdt(size_t n_args, const mp_obj_t *args) {
|
|
|
|
|
#ifdef CONFIG_MICROPY_USE_TASK_WDT
|
|
|
|
|
esp_err_t res;
|
|
|
|
|
res = esp_task_wdt_status(NULL);
|
|
|
|
|
if (n_args > 0) {
|
|
|
|
|
if ((mp_obj_is_true(args[0])) && (res != ESP_OK)) esp_task_wdt_add(NULL);
|
|
|
|
|
else if ((!mp_obj_is_true(args[0])) && (res == ESP_OK)) esp_task_wdt_delete(NULL);
|
|
|
|
|
}
|
|
|
|
|
res = esp_task_wdt_status(NULL);
|
|
|
|
|
if (res == ESP_OK) return mp_const_true;
|
|
|
|
|
return mp_const_false;
|
|
|
|
|
#else
|
|
|
|
|
return mp_const_false;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_machine_wdt_obj, 0, 1, mod_machine_wdt);
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
|
static void _set_stack_heap(char *key, int value, int valmin, int valmax)
|
|
|
|
|
{
|
|
|
|
|
checkNVS();
|
|
|
|
|
|
|
|
|
|
if ((value != 0) && ((value < valmin) || (value > valmax))) {
|
|
|
|
|
mp_raise_msg(&mp_type_OSError, "Invalid size");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
esp_err_t esp_err = nvs_set_i32(mpy_nvs_handle, key, value);
|
|
|
|
|
if (ESP_OK == esp_err) {
|
|
|
|
|
nvs_commit(mpy_nvs_handle);
|
|
|
|
|
}
|
|
|
|
|
else if (ESP_ERR_NVS_NOT_ENOUGH_SPACE == esp_err || ESP_ERR_NVS_PAGE_FULL == esp_err || ESP_ERR_NVS_NO_FREE_PAGES == esp_err) {
|
|
|
|
|
mp_raise_msg(&mp_type_OSError, "No space available for NVS variable.");
|
|
|
|
|
}
|
|
|
|
|
else if (ESP_ERR_NVS_INVALID_NAME == esp_err || ESP_ERR_NVS_KEY_TOO_LONG == esp_err) {
|
|
|
|
|
mp_raise_msg(&mp_type_OSError, "NVS Key invalid or too long");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------
|
|
|
|
|
STATIC mp_obj_t mod_machine_set_stack_size (mp_obj_t _value)
|
|
|
|
|
{
|
|
|
|
|
int value = mp_obj_get_int_truncated(_value);
|
|
|
|
|
value &= 0x7FFFFFFC;
|
|
|
|
|
_set_stack_heap("MPY_StackSize", value, MPY_MIN_STACK_SIZE, MPY_MAX_STACK_SIZE);
|
|
|
|
|
return mp_const_none;
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_machine_set_stack_size_obj, mod_machine_set_stack_size);
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------
|
|
|
|
|
STATIC mp_obj_t mod_machine_set_heap_size (mp_obj_t _value)
|
|
|
|
|
{
|
|
|
|
|
int value = mp_obj_get_int_truncated(_value);
|
|
|
|
|
value &= 0x7FFFFFFC;
|
|
|
|
|
_set_stack_heap("MPY_HeapSize", value, MPY_MIN_HEAP_SIZE, MPY_MAX_HEAP_SIZE);
|
|
|
|
|
return mp_const_none;
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_machine_set_heap_size_obj, mod_machine_set_heap_size);
|
|
|
|
|
|
2018-01-03 14:18:06 +01:00
|
|
|
|
|
|
|
|
//===============================================================
|
|
|
|
|
STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
|
2018-12-04 14:06:15 +08:00
|
|
|
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_umachine) },
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
{ MP_ROM_QSTR(MP_QSTR_mem8), MP_ROM_PTR(&machine_mem8_obj) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_mem16), MP_ROM_PTR(&machine_mem16_obj) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_mem32), MP_ROM_PTR(&machine_mem32_obj) },
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
{ MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&machine_freq_obj) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&machine_reset_obj) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_resetWDT), MP_ROM_PTR(&mod_machine_reset_wdt_obj) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_setWDT), MP_ROM_PTR(&mod_machine_set_wdt_obj) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_WDT), MP_ROM_PTR(&mod_machine_wdt_obj) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_unique_id), MP_ROM_PTR(&machine_unique_id_obj) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_idle), MP_ROM_PTR(&machine_idle_obj) },
|
|
|
|
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_deepsleep), MP_ROM_PTR(&machine_deepsleep_obj) },
|
|
|
|
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_wake_reason), MP_ROM_PTR(&machine_wake_reason_obj) },
|
|
|
|
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_wake_description), MP_ROM_PTR(&machine_wake_desc_obj) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_heap_info), MP_ROM_PTR(&machine_heap_info_obj) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_stdin_disable), MP_ROM_PTR(&mod_machine_stdin_disable_obj) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_SetStackSize), MP_ROM_PTR(&mod_machine_set_stack_size_obj) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_SetHeapSize), MP_ROM_PTR(&mod_machine_set_heap_size_obj) },
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_nvs_setint), MP_ROM_PTR(&mod_machine_nvs_set_int_obj) },
|
|
|
|
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_nvs_getint), MP_ROM_PTR(&mod_machine_nvs_get_int_obj) },
|
|
|
|
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_nvs_setstr), MP_ROM_PTR(&mod_machine_nvs_set_str_obj) },
|
|
|
|
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_nvs_getstr), MP_ROM_PTR(&mod_machine_nvs_get_str_obj) },
|
|
|
|
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_nvs_erase), MP_ROM_PTR(&mod_machine_nvs_erase_obj) },
|
|
|
|
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_nvs_erase_all), MP_ROM_PTR(&mod_machine_nvs_erase_all_obj) },
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_loglevel), MP_ROM_PTR(&mod_machine_log_level_obj) },
|
|
|
|
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_redirectlog), MP_ROM_PTR(&mod_machine_logto_mp_obj) },
|
|
|
|
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_restorelog), MP_ROM_PTR(&mod_machine_logto_esp_obj) },
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
{ MP_ROM_QSTR(MP_QSTR_stdin_get), MP_ROM_PTR(&machine_stdin_get_obj) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_stdout_put), MP_ROM_PTR(&machine_stdout_put_obj) },
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
{ MP_ROM_QSTR(MP_QSTR_disable_irq), MP_ROM_PTR(&machine_disable_irq_obj) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_enable_irq), MP_ROM_PTR(&machine_enable_irq_obj) },
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
{ MP_ROM_QSTR(MP_QSTR_time_pulse_us), MP_ROM_PTR(&machine_time_pulse_us_obj) },
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
{ MP_ROM_QSTR(MP_QSTR_random), MP_ROM_PTR(&machine_random_obj) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_internal_temp), MP_ROM_PTR(&mod_machine_tsens_obj) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_internal_vdd), MP_ROM_PTR(&mod_machine_vdd33_obj) },
|
2018-01-03 14:18:06 +01:00
|
|
|
|
2018-12-04 14:06:15 +08:00
|
|
|
{ MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&machine_timer_type) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_Signal), MP_ROM_PTR(&machine_signal_type) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_TouchPad), MP_ROM_PTR(&machine_touchpad_type) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&machine_dac_type) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_hw_i2c_type) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_hw_spi_type) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) },
|
|
|
|
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&mach_rtc_type) },
|
|
|
|
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_Neopixel), MP_ROM_PTR(&machine_neopixel_type) },
|
|
|
|
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_DHT), MP_ROM_PTR(&machine_dht_type) },
|
|
|
|
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_Onewire), MP_ROM_PTR(&machine_onewire_type) },
|
|
|
|
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_I2S), MP_ROM_PTR(&machine_i2s_type) },
|
|
|
|
|
#ifdef CONFIG_MICROPY_USE_GPS
|
|
|
|
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_GPS), MP_ROM_PTR(&machine_gps_type) },
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef CONFIG_MICROPY_USE_RFCOMM
|
|
|
|
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_RFCOMM), MP_ROM_PTR(&machine_rfcomm_type) },
|
|
|
|
|
#endif
|
|
|
|
|
// Constants
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_LOG_NONE), MP_ROM_INT(ESP_LOG_NONE) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_LOG_ERROR), MP_ROM_INT(ESP_LOG_ERROR) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_LOG_WARN), MP_ROM_INT(ESP_LOG_WARN) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_LOG_INFO), MP_ROM_INT(ESP_LOG_INFO) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_LOG_DEBUG), MP_ROM_INT(ESP_LOG_DEBUG) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_LOG_VERBOSE), MP_ROM_INT(ESP_LOG_VERBOSE) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_EXT1_ANYHIGH), MP_ROM_INT(ESP_EXT1_WAKEUP_ANY_HIGH) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_EXT1_ALLLOW), MP_ROM_INT(ESP_EXT1_WAKEUP_ALL_LOW) },
|
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_EXT1_ANYLOW), MP_ROM_INT(EXT1_WAKEUP_ALL_HIGH) },
|
2018-01-03 14:18:06 +01:00
|
|
|
};
|
|
|
|
|
STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table);
|
|
|
|
|
|
|
|
|
|
//=========================================
|
|
|
|
|
const mp_obj_module_t mp_module_machine = {
|
2018-12-04 14:06:15 +08:00
|
|
|
.base = { &mp_type_module },
|
|
|
|
|
.globals = (mp_obj_dict_t*)&machine_module_globals,
|
2018-01-03 14:18:06 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif // MICROPY_PY_MACHINE
|