mirror of
https://github.com/espruino/Espruino.git
synced 2025-12-08 19:06:15 +00:00
318 lines
9.9 KiB
C
318 lines
9.9 KiB
C
/*
|
|
* This file is part of Espruino, a JavaScript interpreter for Microcontrollers
|
|
*
|
|
* Copyright (C) 2013 Gordon Williams <gw@pur3.co.uk>
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
* ESP32 specific exposed components.
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
#include <stdio.h>
|
|
|
|
#include "jswrap_esp32.h"
|
|
#include "jshardwareAnalog.h"
|
|
#include "jsutils.h"
|
|
#include "jsinteractive.h"
|
|
#include "jsparse.h"
|
|
#include "jsflash.h"
|
|
|
|
#include "esp_system.h"
|
|
#include "esp_sleep.h"
|
|
#include "esp_heap_caps.h"
|
|
#include "esp_ota_ops.h"
|
|
|
|
#include "driver/rtc_io.h"
|
|
|
|
#ifdef BLUETOOTH
|
|
#include "BLE/esp32_bluetooth_utils.h"
|
|
#endif
|
|
#include "jshardwareESP32.h"
|
|
|
|
#include "jsutils.h"
|
|
#include "jsinteractive.h"
|
|
#include "jsparse.h"
|
|
|
|
/*JSON{
|
|
"type": "class",
|
|
"class" : "ESP32",
|
|
"ifdef" : "ESP32"
|
|
}
|
|
Class containing utility functions for the
|
|
[ESP32](http://www.espruino.com/ESP32)
|
|
*/
|
|
|
|
/*JSON{
|
|
"type" : "staticmethod",
|
|
"class" : "ESP32",
|
|
"ifdef" : "ESP32",
|
|
"name" : "setAtten",
|
|
"generate" : "jswrap_ESP32_setAtten",
|
|
"params" : [
|
|
["pin", "pin", "Pin for Analog read"],
|
|
["atten", "int", "Attenuate factor"]
|
|
]
|
|
}*/
|
|
void jswrap_ESP32_setAtten(Pin pin,int atten){
|
|
printf("Atten:%d\n",atten);
|
|
rangeADC(pin, atten);
|
|
}
|
|
|
|
/*JSON{
|
|
"type" : "staticmethod",
|
|
"class" : "ESP32",
|
|
"ifdef" : "ESP32",
|
|
"name" : "reboot",
|
|
"generate" : "jswrap_ESP32_reboot"
|
|
}
|
|
Perform a hardware reset/reboot of the ESP32.
|
|
*/
|
|
void jswrap_ESP32_reboot() {
|
|
jshReboot();
|
|
} // End of jswrap_ESP32_reboot
|
|
|
|
|
|
/*JSON{
|
|
"type" : "staticmethod",
|
|
"class" : "ESP32",
|
|
"ifdef" : "ESP32",
|
|
"name" : "deepSleep",
|
|
"generate" : "jswrap_ESP32_deepSleep",
|
|
"params" : [ ["us", "int", "Sleeptime in us"] ]
|
|
}
|
|
Put device in deepsleep state for "us" microseconds.
|
|
*/
|
|
void jswrap_ESP32_deepSleep(int us) {
|
|
esp_sleep_enable_timer_wakeup((uint64_t)(us));
|
|
esp_deep_sleep_start(); // This function does not return.
|
|
} // End of jswrap_ESP32_deepSleep
|
|
|
|
/*JSON{
|
|
"type" : "staticmethod",
|
|
"class" : "ESP32",
|
|
"ifdef" : "ESP32",
|
|
"name" : "deepSleepExt0",
|
|
"generate" : "jswrap_ESP32_deepSleep_ext0",
|
|
"params" : [
|
|
["pin", "pin", "Pin to trigger wakeup"],
|
|
["level", "int", "Logic level to trigger"]
|
|
]
|
|
}
|
|
Put device in deepsleep state until interrupted by pin "pin".
|
|
Eligible pin numbers are restricted to those [GPIOs designated
|
|
as RTC GPIOs](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/gpio.html#gpio-summary).
|
|
*/
|
|
void jswrap_ESP32_deepSleep_ext0(Pin pin, int level) {
|
|
if (!rtc_gpio_is_valid_gpio(pin)) {
|
|
jsExceptionHere(JSET_ERROR, "Invalid pin");
|
|
return;
|
|
}
|
|
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
|
esp_deep_sleep_enable_gpio_wakeup(1<<pin, level);
|
|
#else
|
|
esp_sleep_enable_ext0_wakeup(pin, level);
|
|
#endif
|
|
esp_deep_sleep_start(); // This function does not return.
|
|
} // End of jswrap_ESP32_deepSleep_ext0
|
|
|
|
/*JSON{
|
|
"type" : "staticmethod",
|
|
"class" : "ESP32",
|
|
"ifdef" : "ESP32",
|
|
"name" : "deepSleepExt1",
|
|
"generate" : "jswrap_ESP32_deepSleep_ext1",
|
|
"params" : [
|
|
["pinVar", "JsVar", "Array of Pins to trigger wakeup"],
|
|
["mode", "int", "Trigger mode"]
|
|
]
|
|
}
|
|
Put device in deepsleep state until interrupted by pins in the "pinVar" array.
|
|
The trigger "mode" determines the pin state which will wake up the device.
|
|
Valid modes are:
|
|
|
|
* `0: ESP_EXT1_WAKEUP_ALL_LOW` - all nominated pins must be set LOW to trigger wakeup
|
|
* `1: ESP_EXT1_WAKEUP_ANY_HIGH` - any of nominated pins set HIGH will trigger wakeup
|
|
|
|
Eligible pin numbers are restricted to those [GPIOs designated
|
|
as RTC GPIOs](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/gpio.html#gpio-summary).
|
|
*/
|
|
void jswrap_ESP32_deepSleep_ext1(JsVar *pinVar, JsVarInt mode) {
|
|
uint64_t pinSum = 0;
|
|
if (jsvIsArray(pinVar)) {
|
|
JsvIterator it;
|
|
jsvIteratorNew(&it, pinVar, JSIF_DEFINED_ARRAY_ElEMENTS);
|
|
while (jsvIteratorHasElement(&it)) {
|
|
Pin pin = jshGetPinFromVarAndUnLock(jsvIteratorGetValue(&it));
|
|
if (!rtc_gpio_is_valid_gpio(pin)) {
|
|
jsvIteratorFree(&it);
|
|
jsExceptionHere(JSET_ERROR, "Invalid pin");
|
|
return;
|
|
}
|
|
pinSum += 1<<pin;
|
|
|
|
jsvIteratorNext(&it);
|
|
}
|
|
jsvIteratorFree(&it);
|
|
} else {
|
|
// We really expected an array of pins but
|
|
// handle case of a single pin anyway
|
|
Pin pin = jshGetPinFromVar(pinVar);
|
|
if (!rtc_gpio_is_valid_gpio(pin)) {
|
|
jsExceptionHere(JSET_ERROR, "Invalid pin");
|
|
return;
|
|
}
|
|
pinSum = 1<<pin;
|
|
}
|
|
|
|
if ((mode < 0) || (mode > 1)) {
|
|
jsExceptionHere(JSET_ERROR, "Invalid mode (%d)!", mode);
|
|
return;
|
|
}
|
|
|
|
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
|
esp_deep_sleep_enable_gpio_wakeup(pinSum, mode);
|
|
#else
|
|
esp_sleep_enable_ext1_wakeup(pinSum, mode);
|
|
#endif
|
|
esp_deep_sleep_start(); // This function does not return.
|
|
} // End of jswrap_ESP32_deepSleep_ext1
|
|
|
|
/*JSON{
|
|
"type" : "staticmethod",
|
|
"class" : "ESP32",
|
|
"ifdef" : "ESP32",
|
|
"name" : "getWakeupCause",
|
|
"generate" : "jswrap_ESP32_getWakeupCause",
|
|
"return" : ["int", "The cause of the ESP32's wakeup from sleep"]
|
|
}
|
|
Returns a variable identifying the cause of wakeup from deep sleep.
|
|
Possible causes include:
|
|
|
|
* `0: ESP_SLEEP_WAKEUP_UNDEFINED` - reset was not caused by exit from deep sleep
|
|
* `2: ESP_SLEEP_WAKEUP_EXT0` - Wakeup caused by external signal using RTC_IO
|
|
* `3: ESP_SLEEP_WAKEUP_EXT1` - Wakeup caused by external signal using RTC_CNTL
|
|
* `4: ESP_SLEEP_WAKEUP_TIMER` - Wakeup caused by timer
|
|
* `5: ESP_SLEEP_WAKEUP_TOUCHPAD` - Wakeup caused by touchpad
|
|
* `6: ESP_SLEEP_WAKEUP_ULP` - Wakeup caused by ULP program
|
|
|
|
*/
|
|
int jswrap_ESP32_getWakeupCause() {
|
|
return esp_sleep_get_wakeup_cause();
|
|
} // End of jswrap_ESP32_getWakeupCause
|
|
|
|
|
|
/*JSON{
|
|
"type" : "staticmethod",
|
|
"class" : "ESP32",
|
|
"ifdef" : "ESP32",
|
|
"name" : "getState",
|
|
"generate" : "jswrap_ESP32_getState",
|
|
"return" : ["JsVar", "The state of the ESP32"]
|
|
}
|
|
Returns an object that contains details about the state of the ESP32 with the
|
|
following fields:
|
|
|
|
* `sdkVersion` - Version of the SDK.
|
|
* `freeHeap` - Amount of free heap in bytes.
|
|
* `BLE` - Status of BLE, enabled if true.
|
|
* `Wifi` - Status of Wifi, enabled if true.
|
|
* `minHeap` - Minimum heap, calculated by heap_caps_get_minimum_free_size
|
|
|
|
*/
|
|
JsVar *jswrap_ESP32_getState() {
|
|
// Create a new variable and populate it with the properties of the ESP32 that we
|
|
// wish to return.
|
|
JsVar *esp32State = jsvNewObject();
|
|
jsvObjectSetChildAndUnLock(esp32State, "sdkVersion", jsvNewFromString(esp_get_idf_version()));
|
|
jsvObjectSetChildAndUnLock(esp32State, "freeHeap", jsvNewFromInteger(esp_get_free_heap_size()));
|
|
jsvObjectSetChildAndUnLock(esp32State, "BLE", jsvNewFromBool(ESP32_Get_NVS_Status(ESP_NETWORK_BLE)));
|
|
jsvObjectSetChildAndUnLock(esp32State, "Wifi", jsvNewFromBool(ESP32_Get_NVS_Status(ESP_NETWORK_WIFI)));
|
|
jsvObjectSetChildAndUnLock(esp32State, "minHeap", jsvNewFromInteger(heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT)));
|
|
return esp32State;
|
|
} // End of jswrap_ESP32_getState
|
|
|
|
#ifdef BLUETOOTH
|
|
/*JSON{
|
|
"type" : "staticmethod",
|
|
"class" : "ESP32",
|
|
"ifdef" : "ESP32",
|
|
"name" : "setBLE_Debug",
|
|
"generate" : "jswrap_ESP32_setBLE_Debug",
|
|
"params" : [
|
|
["level", "int", "which events should be shown (GAP=1, GATTS=2, GATTC=4). Use 255 for everything"]
|
|
],
|
|
"ifdef" : "BLUETOOTH"
|
|
}
|
|
*/
|
|
void jswrap_ESP32_setBLE_Debug(int level){
|
|
ESP32_setBLE_Debug(level);
|
|
}
|
|
|
|
/*JSON{
|
|
"type" : "staticmethod",
|
|
"class" : "ESP32",
|
|
"ifdef" : "ESP32",
|
|
"name" : "enableBLE",
|
|
"generate" : "jswrap_ESP32_enableBLE",
|
|
"params" : [
|
|
["enable", "bool", "switches Bluetooth on or off" ]
|
|
],
|
|
"ifdef" : "BLUETOOTH"
|
|
}
|
|
Switches Bluetooth off/on, removes saved code from Flash, resets the board, and
|
|
on restart creates jsVars depending on available heap (actual additional 1800)
|
|
*/
|
|
void jswrap_ESP32_enableBLE(bool enable) { //may be later, we will support BLEenable(ALL/SERVER/CLIENT)
|
|
ESP32_Set_NVS_Status(ESP_NETWORK_BLE,enable);
|
|
jsfRemoveCodeFromFlash();
|
|
esp_restart();
|
|
}
|
|
#endif
|
|
/*JSON{
|
|
"type" : "staticmethod",
|
|
"class" : "ESP32",
|
|
"ifdef" : "ESP32",
|
|
"name" : "enableWifi",
|
|
"generate" : "jswrap_ESP32_enableWifi",
|
|
"params" : [
|
|
["enable", "bool", "switches Wifi on or off" ]
|
|
]
|
|
}
|
|
Switches Wifi off/on, removes saved code from Flash, resets the board, and on
|
|
restart creates jsVars depending on available heap (actual additional 3900)
|
|
*/
|
|
void jswrap_ESP32_enableWifi(bool enable) { //may be later, we will support BLEenable(ALL/SERVER/CLIENT)
|
|
ESP32_Set_NVS_Status(ESP_NETWORK_WIFI,enable);
|
|
jsfRemoveCodeFromFlash();
|
|
esp_restart();
|
|
}
|
|
|
|
/*JSON{
|
|
"type" : "staticmethod",
|
|
"class" : "ESP32",
|
|
"ifdef" : "ESP32",
|
|
"name" : "setOTAValid",
|
|
"generate" : "jswrap_ESP32_setOTAValid",
|
|
"params" : [
|
|
["isValid", "bool", "Set whether this app is valid or not. If `isValid==false` the device will reboot." ]
|
|
]
|
|
}
|
|
This function is useful for ESP32 [OTA Updates](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/ota.html)
|
|
|
|
Normally Espruino is uploaded to the `factory` partition so this isn't so useful,
|
|
but it is possible to upload Espruino to the `ota_0` partition (or ota_1 if a different table has been added).
|
|
|
|
If this is the case, you can use this function to mark the currently running version of Espruino as good or bad.
|
|
* If set as valid, Espruino will continue running, and the fact that everything is ok is written to flash
|
|
* If set as invalid (false) Espruino will mark itself as not working properly and will reboot. The ESP32 bootloader
|
|
will then start and will load any other partition it can find that is marked as ok.
|
|
*/
|
|
void jswrap_ESP32_setOTAValid(bool isValid) {
|
|
if (isValid) esp_ota_mark_app_valid_cancel_rollback();
|
|
else esp_ota_mark_app_invalid_rollback_and_reboot();
|
|
}
|
|
|