mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-21 10:12:50 +00:00
Put a bit of order in the src directory, group and name things appropriately
This commit is contained in:
160
src/platform/esp32/BluetoothSoftwareUpdate.cpp
Normal file
160
src/platform/esp32/BluetoothSoftwareUpdate.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
#ifndef USE_NEW_ESP32_BLUETOOTH
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "../concurrency/LockGuard.h"
|
||||
#include "../graphics/Screen.h"
|
||||
#include "../main.h"
|
||||
#include "BluetoothSoftwareUpdate.h"
|
||||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "RadioLibInterface.h"
|
||||
#include "configuration.h"
|
||||
#include "nimble/BluetoothUtil.h"
|
||||
|
||||
#include <CRC32.h>
|
||||
#include <Update.h>
|
||||
|
||||
int16_t updateResultHandle = -1;
|
||||
|
||||
static CRC32 crc;
|
||||
|
||||
static uint32_t updateExpectedSize, updateActualSize;
|
||||
static uint8_t update_result;
|
||||
static uint8_t update_region;
|
||||
|
||||
static concurrency::Lock *updateLock;
|
||||
|
||||
/// Handle writes & reads to total size
|
||||
int update_size_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
|
||||
{
|
||||
concurrency::LockGuard g(updateLock);
|
||||
|
||||
// Check if there is enough to OTA Update
|
||||
chr_readwrite32le(&updateExpectedSize, ctxt);
|
||||
|
||||
if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR && updateExpectedSize != 0) {
|
||||
updateActualSize = 0;
|
||||
crc.reset();
|
||||
if (Update.isRunning())
|
||||
Update.abort();
|
||||
bool canBegin = Update.begin(updateExpectedSize, update_region);
|
||||
DEBUG_MSG("Setting region %d update size %u, result %d\n", update_region, updateExpectedSize, canBegin);
|
||||
if (!canBegin) {
|
||||
// Indicate failure by forcing the size to 0 (client will read it back)
|
||||
updateExpectedSize = 0;
|
||||
} else {
|
||||
// This totally breaks abstraction to up up into the app layer for this, but quick hack to make sure we only
|
||||
// talk to one service during the sw update.
|
||||
// DEBUG_MSG("FIXME, crufty shutdown of mesh bluetooth for sw update.");
|
||||
// void stopMeshBluetoothService();
|
||||
// stopMeshBluetoothService();
|
||||
|
||||
screen->startFirmwareUpdateScreen();
|
||||
if (RadioLibInterface::instance)
|
||||
RadioLibInterface::instance->disable(); // FIXME, nasty hack - the RF95 ISR/SPI code on ESP32 can fail while we
|
||||
// are writing flash - shut the radio off during updates
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAX_BLOCKSIZE_FOR_BT 512
|
||||
|
||||
/// Handle writes to data
|
||||
int update_data_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
|
||||
{
|
||||
concurrency::LockGuard g(updateLock);
|
||||
|
||||
static uint8_t
|
||||
data[MAX_BLOCKSIZE_FOR_BT]; // we temporarily copy here because I'm worried that a fast sender might be able overwrite srcbuf
|
||||
|
||||
uint16_t len = 0;
|
||||
|
||||
auto rc = ble_hs_mbuf_to_flat(ctxt->om, data, sizeof(data), &len);
|
||||
assert(rc == 0);
|
||||
|
||||
// DEBUG_MSG("Writing %u\n", len);
|
||||
crc.update(data, len);
|
||||
Update.write(data, len);
|
||||
updateActualSize += len;
|
||||
powerFSM.trigger(EVENT_FIRMWARE_UPDATE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Handle writes to crc32
|
||||
int update_crc32_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
|
||||
{
|
||||
concurrency::LockGuard g(updateLock);
|
||||
uint32_t expectedCRC = 0;
|
||||
chr_readwrite32le(&expectedCRC, ctxt);
|
||||
|
||||
uint32_t actualCRC = crc.finalize();
|
||||
DEBUG_MSG("expected CRC %u\n", expectedCRC);
|
||||
|
||||
uint8_t result = 0xff;
|
||||
|
||||
if (updateActualSize != updateExpectedSize) {
|
||||
DEBUG_MSG("Expected %u bytes, but received %u bytes!\n", updateExpectedSize, updateActualSize);
|
||||
result = 0xe1; // FIXME, use real error codes
|
||||
} else if (actualCRC != expectedCRC) // Check the CRC before asking the update to happen.
|
||||
{
|
||||
DEBUG_MSG("Invalid CRC! expected=%u, actual=%u\n", expectedCRC, actualCRC);
|
||||
result = 0xe0; // FIXME, use real error codes
|
||||
} else {
|
||||
if (Update.end()) {
|
||||
if (update_region == U_SPIFFS) {
|
||||
DEBUG_MSG("Filesystem updated!\n");
|
||||
nodeDB.saveToDisk(); // Since we just wiped the filesystem, we need to save our current state
|
||||
} else {
|
||||
DEBUG_MSG("Appload updated, rebooting in 5 seconds!\n");
|
||||
rebootAtMsec = millis() + 5000;
|
||||
}
|
||||
} else {
|
||||
DEBUG_MSG("Error Occurred. Error #: %d\n", Update.getError());
|
||||
}
|
||||
result = Update.getError();
|
||||
}
|
||||
|
||||
if (RadioLibInterface::instance)
|
||||
RadioLibInterface::instance->startReceive(); // Resume radio
|
||||
|
||||
assert(updateResultHandle >= 0);
|
||||
update_result = result;
|
||||
DEBUG_MSG("BLE notify update result\n");
|
||||
auto res = ble_gattc_notify(curConnectionHandle, updateResultHandle);
|
||||
assert(res == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int update_result_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
|
||||
{
|
||||
return chr_readwrite8(&update_result, sizeof(update_result), ctxt);
|
||||
}
|
||||
|
||||
int update_region_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
|
||||
{
|
||||
return chr_readwrite8(&update_region, sizeof(update_region), ctxt);
|
||||
}
|
||||
|
||||
/*
|
||||
See bluetooth-api.md
|
||||
|
||||
*/
|
||||
void reinitUpdateService()
|
||||
{
|
||||
if (!updateLock)
|
||||
updateLock = new concurrency::Lock();
|
||||
|
||||
auto res = ble_gatts_count_cfg(gatt_update_svcs); // assigns handles? see docstring for note about clearing the handle list
|
||||
// before calling SLEEP SUPPORT
|
||||
assert(res == 0);
|
||||
|
||||
res = ble_gatts_add_svcs(gatt_update_svcs);
|
||||
assert(res == 0);
|
||||
}
|
||||
|
||||
#endif //#ifndef USE_NEW_ESP32_BLUETOOTH
|
||||
29
src/platform/esp32/BluetoothSoftwareUpdate.h
Normal file
29
src/platform/esp32/BluetoothSoftwareUpdate.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef USE_NEW_ESP32_BLUETOOTH
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "nimble/NimbleDefs.h"
|
||||
|
||||
void reinitUpdateService();
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int update_size_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
|
||||
int update_data_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
|
||||
int update_result_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
|
||||
int update_crc32_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
|
||||
int update_region_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
|
||||
|
||||
extern const struct ble_gatt_svc_def gatt_update_svcs[];
|
||||
|
||||
extern const ble_uuid128_t update_result_uuid, update_region_uuid;
|
||||
|
||||
extern int16_t updateResultHandle;
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif //#ifndef USE_NEW_ESP32_BLUETOOTH
|
||||
12
src/platform/esp32/CallbackCharacteristic.h
Normal file
12
src/platform/esp32/CallbackCharacteristic.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include "BLECharacteristic.h"
|
||||
#include "PowerFSM.h" // FIXME - someday I want to make this OTA thing a separate lb at at that point it can't touch this
|
||||
|
||||
/**
|
||||
* A characterstic with a set of overridable callbacks
|
||||
*/
|
||||
class CallbackCharacteristic : public BLECharacteristic, public BLECharacteristicCallbacks
|
||||
{
|
||||
public:
|
||||
CallbackCharacteristic(const char *uuid, uint32_t btprops) : BLECharacteristic(uuid, btprops) { setCallbacks(this); }
|
||||
};
|
||||
259
src/platform/esp32/ESP32Bluetooth.cpp
Normal file
259
src/platform/esp32/ESP32Bluetooth.cpp
Normal file
@@ -0,0 +1,259 @@
|
||||
#ifdef USE_NEW_ESP32_BLUETOOTH
|
||||
|
||||
#include "configuration.h"
|
||||
#include "ESP32Bluetooth.h"
|
||||
#include "BluetoothCommon.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "sleep.h"
|
||||
#include "main.h"
|
||||
#include "mesh/PhoneAPI.h"
|
||||
#include "mesh/mesh-pb-constants.h"
|
||||
#include <NimBLEDevice.h>
|
||||
|
||||
//static BLEService meshBleService = BLEService(BLEUuid(MESH_SERVICE_UUID_16));
|
||||
//static BLECharacteristic fromNum = BLECharacteristic(BLEUuid(FROMNUM_UUID_16));
|
||||
//static BLECharacteristic fromRadio = BLECharacteristic(BLEUuid(FROMRADIO_UUID_16));
|
||||
//static BLECharacteristic toRadio = BLECharacteristic(BLEUuid(TORADIO_UUID_16));
|
||||
|
||||
//static BLEDis bledis; // DIS (Device Information Service) helper class instance
|
||||
//static BLEBas blebas; // BAS (Battery Service) helper class instance
|
||||
//static BLEDfu bledfu; // DFU software update helper service
|
||||
|
||||
// This scratch buffer is used for various bluetooth reads/writes - but it is safe because only one bt operation can be in
|
||||
// proccess at once
|
||||
// static uint8_t trBytes[_max(_max(_max(_max(ToRadio_size, RadioConfig_size), User_size), MyNodeInfo_size), FromRadio_size)];
|
||||
static uint8_t fromRadioBytes[FromRadio_size];
|
||||
|
||||
NimBLECharacteristic *FromNumCharacteristic;
|
||||
NimBLEServer *bleServer;
|
||||
|
||||
static bool passkeyShowing;
|
||||
static uint32_t doublepressed;
|
||||
|
||||
/**
|
||||
* Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies)
|
||||
*/
|
||||
void BluetoothPhoneAPI::onNowHasData(uint32_t fromRadioNum)
|
||||
{
|
||||
PhoneAPI::onNowHasData(fromRadioNum);
|
||||
|
||||
DEBUG_MSG("BLE notify fromNum\n");
|
||||
//fromNum.notify32(fromRadioNum);
|
||||
|
||||
uint8_t val[4];
|
||||
put_le32(val, fromRadioNum);
|
||||
|
||||
std::string fromNumByteString(&val[0], &val[0] + sizeof(val));
|
||||
|
||||
FromNumCharacteristic->setValue(fromNumByteString);
|
||||
FromNumCharacteristic->notify();
|
||||
}
|
||||
|
||||
/// Check the current underlying physical link to see if the client is currently connected
|
||||
bool BluetoothPhoneAPI::checkIsConnected() {
|
||||
if (bleServer && bleServer->getConnectedCount() > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
PhoneAPI *bluetoothPhoneAPI;
|
||||
|
||||
class ESP32BluetoothToRadioCallback : public NimBLECharacteristicCallbacks {
|
||||
virtual void onWrite(NimBLECharacteristic *pCharacteristic) {
|
||||
DEBUG_MSG("To Radio onwrite\n");
|
||||
auto val = pCharacteristic->getValue();
|
||||
|
||||
bluetoothPhoneAPI->handleToRadio(val.data(), val.length());
|
||||
}
|
||||
};
|
||||
|
||||
class ESP32BluetoothFromRadioCallback : public NimBLECharacteristicCallbacks {
|
||||
virtual void onRead(NimBLECharacteristic *pCharacteristic) {
|
||||
DEBUG_MSG("From Radio onread\n");
|
||||
size_t numBytes = bluetoothPhoneAPI->getFromRadio(fromRadioBytes);
|
||||
|
||||
std::string fromRadioByteString(fromRadioBytes, fromRadioBytes + numBytes);
|
||||
|
||||
pCharacteristic->setValue(fromRadioByteString);
|
||||
}
|
||||
};
|
||||
|
||||
class ESP32BluetoothServerCallback : public NimBLEServerCallbacks {
|
||||
virtual uint32_t onPassKeyRequest() {
|
||||
|
||||
uint32_t passkey = 0;
|
||||
|
||||
if (doublepressed > 0 && (doublepressed + (30 * 1000)) > millis()) {
|
||||
DEBUG_MSG("User has overridden passkey\n");
|
||||
passkey = defaultBLEPin;
|
||||
} else {
|
||||
DEBUG_MSG("Using random passkey\n");
|
||||
passkey = random(
|
||||
100000, 999999); // This is the passkey to be entered on peer - we pick a number >100,000 to ensure 6 digits
|
||||
}
|
||||
DEBUG_MSG("*** Enter passkey %d on the peer side ***\n", passkey);
|
||||
|
||||
powerFSM.trigger(EVENT_BLUETOOTH_PAIR);
|
||||
screen->startBluetoothPinScreen(passkey);
|
||||
passkeyShowing = true;
|
||||
|
||||
return passkey;
|
||||
}
|
||||
|
||||
virtual void onAuthenticationComplete(ble_gap_conn_desc *desc) {
|
||||
DEBUG_MSG("BLE authentication complete\n");
|
||||
|
||||
if (passkeyShowing) {
|
||||
passkeyShowing = false;
|
||||
screen->stopBluetoothPinScreen();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static ESP32BluetoothToRadioCallback *toRadioCallbacks;
|
||||
static ESP32BluetoothFromRadioCallback *fromRadioCallbacks;
|
||||
|
||||
void ESP32Bluetooth::shutdown()
|
||||
{
|
||||
// Shutdown bluetooth for minimum power draw
|
||||
DEBUG_MSG("Disable bluetooth\n");
|
||||
//Bluefruit.Advertising.stop();
|
||||
}
|
||||
|
||||
void ESP32Bluetooth::setup()
|
||||
{
|
||||
// Initialise the Bluefruit module
|
||||
DEBUG_MSG("Initialise the ESP32 bluetooth module\n");
|
||||
//Bluefruit.autoConnLed(false);
|
||||
//Bluefruit.begin();
|
||||
|
||||
// Set the advertised device name (keep it short!)
|
||||
//Bluefruit.setName(getDeviceName());
|
||||
|
||||
// Set the connect/disconnect callback handlers
|
||||
//Bluefruit.Periph.setConnectCallback(connect_callback);
|
||||
//Bluefruit.Periph.setDisconnectCallback(disconnect_callback);
|
||||
|
||||
// Configure and Start the Device Information Service
|
||||
DEBUG_MSG("Configuring the Device Information Service\n");
|
||||
// FIXME, we should set a mfg string based on our HW_VENDOR enum
|
||||
// bledis.setManufacturer(HW_VENDOR);
|
||||
//bledis.setModel(optstr(HW_VERSION));
|
||||
//bledis.setFirmwareRev(optstr(APP_VERSION));
|
||||
//bledis.begin();
|
||||
|
||||
// Start the BLE Battery Service and set it to 100%
|
||||
//DEBUG_MSG("Configuring the Battery Service\n");
|
||||
//blebas.begin();
|
||||
//blebas.write(0); // Unknown battery level for now
|
||||
|
||||
//bledfu.begin(); // Install the DFU helper
|
||||
|
||||
// Setup the Heart Rate Monitor service using
|
||||
// BLEService and BLECharacteristic classes
|
||||
DEBUG_MSG("Configuring the Mesh bluetooth service\n");
|
||||
//setupMeshService();
|
||||
|
||||
// Supposedly debugging works with soft device if you disable advertising
|
||||
//if (isSoftDeviceAllowed) {
|
||||
// Setup the advertising packet(s)
|
||||
// DEBUG_MSG("Setting up the advertising payload(s)\n");
|
||||
// startAdv();
|
||||
|
||||
// DEBUG_MSG("Advertising\n");
|
||||
//}
|
||||
|
||||
//NimBLEDevice::deleteAllBonds();
|
||||
|
||||
NimBLEDevice::init(getDeviceName());
|
||||
NimBLEDevice::setPower(ESP_PWR_LVL_P9);
|
||||
|
||||
NimBLEDevice::setSecurityAuth(true, true, true);
|
||||
NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY);
|
||||
bleServer = NimBLEDevice::createServer();
|
||||
|
||||
ESP32BluetoothServerCallback *serverCallbacks = new ESP32BluetoothServerCallback();
|
||||
bleServer->setCallbacks(serverCallbacks);
|
||||
|
||||
NimBLEService *bleService = bleServer->createService(MESH_SERVICE_UUID);
|
||||
//NimBLECharacteristic *pNonSecureCharacteristic = bleService->createCharacteristic("1234", NIMBLE_PROPERTY::READ );
|
||||
//NimBLECharacteristic *pSecureCharacteristic = bleService->createCharacteristic("1235", NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::READ_AUTHEN);
|
||||
|
||||
//define the characteristics that the app is looking for
|
||||
NimBLECharacteristic *ToRadioCharacteristic = bleService->createCharacteristic(TORADIO_UUID, NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_AUTHEN | NIMBLE_PROPERTY::WRITE_ENC);
|
||||
NimBLECharacteristic *FromRadioCharacteristic = bleService->createCharacteristic(FROMRADIO_UUID, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_AUTHEN | NIMBLE_PROPERTY::READ_ENC);
|
||||
FromNumCharacteristic = bleService->createCharacteristic(FROMNUM_UUID, NIMBLE_PROPERTY::NOTIFY | NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_AUTHEN | NIMBLE_PROPERTY::READ_ENC);
|
||||
|
||||
bluetoothPhoneAPI = new BluetoothPhoneAPI();
|
||||
|
||||
toRadioCallbacks = new ESP32BluetoothToRadioCallback();
|
||||
ToRadioCharacteristic->setCallbacks(toRadioCallbacks);
|
||||
|
||||
fromRadioCallbacks = new ESP32BluetoothFromRadioCallback();
|
||||
FromRadioCharacteristic->setCallbacks(fromRadioCallbacks);
|
||||
|
||||
//uint8_t val[4];
|
||||
//uint32_t zero = 0;
|
||||
//put_le32(val, zero);
|
||||
//std::string fromNumByteString(&val[0], &val[0] + sizeof(val));
|
||||
//FromNumCharacteristic->setValue(fromNumByteString);
|
||||
|
||||
bleService->start();
|
||||
//pNonSecureCharacteristic->setValue("Hello Non Secure BLE");
|
||||
//pSecureCharacteristic->setValue("Hello Secure BLE");
|
||||
|
||||
//FromRadioCharacteristic->setValue("FromRadioString");
|
||||
//ToRadioCharacteristic->setCallbacks()
|
||||
|
||||
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
||||
pAdvertising->addServiceUUID(MESH_SERVICE_UUID);
|
||||
pAdvertising->start();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Given a level between 0-100, update the BLE attribute
|
||||
void updateBatteryLevel(uint8_t level)
|
||||
{
|
||||
//blebas.write(level);
|
||||
}
|
||||
|
||||
void ESP32Bluetooth::clearBonds()
|
||||
{
|
||||
DEBUG_MSG("Clearing bluetooth bonds!\n");
|
||||
//bond_print_list(BLE_GAP_ROLE_PERIPH);
|
||||
//bond_print_list(BLE_GAP_ROLE_CENTRAL);
|
||||
|
||||
//Bluefruit.Periph.clearBonds();
|
||||
//Bluefruit.Central.clearBonds();
|
||||
|
||||
}
|
||||
|
||||
void clearNVS() {
|
||||
NimBLEDevice::deleteAllBonds();
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
void disablePin() {
|
||||
DEBUG_MSG("User Override, disabling bluetooth pin requirement\n");
|
||||
// keep track of when it was pressed, so we know it was within X seconds
|
||||
|
||||
// Flash the LED
|
||||
setLed(true);
|
||||
delay(100);
|
||||
setLed(false);
|
||||
delay(100);
|
||||
setLed(true);
|
||||
delay(100);
|
||||
setLed(false);
|
||||
delay(100);
|
||||
setLed(true);
|
||||
delay(100);
|
||||
setLed(false);
|
||||
|
||||
doublepressed = millis();
|
||||
}
|
||||
|
||||
#endif
|
||||
33
src/platform/esp32/ESP32Bluetooth.h
Normal file
33
src/platform/esp32/ESP32Bluetooth.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifdef USE_NEW_ESP32_BLUETOOTH
|
||||
|
||||
#pragma once
|
||||
|
||||
extern uint16_t fromNumValHandle;
|
||||
|
||||
class BluetoothPhoneAPI : public PhoneAPI
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies)
|
||||
*/
|
||||
virtual void onNowHasData(uint32_t fromRadioNum) override;
|
||||
|
||||
/// Check the current underlying physical link to see if the client is currently connected
|
||||
virtual bool checkIsConnected() override;
|
||||
};
|
||||
|
||||
extern PhoneAPI *bluetoothPhoneAPI;
|
||||
|
||||
class ESP32Bluetooth
|
||||
{
|
||||
public:
|
||||
void setup();
|
||||
void shutdown();
|
||||
void clearBonds();
|
||||
};
|
||||
|
||||
void setBluetoothEnable(bool on);
|
||||
void clearNVS();
|
||||
void disablePin();
|
||||
|
||||
#endif
|
||||
78
src/platform/esp32/ESP32CryptoEngine.cpp
Normal file
78
src/platform/esp32/ESP32CryptoEngine.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "CryptoEngine.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#include "crypto/includes.h"
|
||||
|
||||
#include "crypto/common.h"
|
||||
|
||||
// #include "esp_system.h"
|
||||
|
||||
#include "crypto/aes.h"
|
||||
#include "crypto/aes_wrap.h"
|
||||
#include "mbedtls/aes.h"
|
||||
|
||||
|
||||
|
||||
class ESP32CryptoEngine : public CryptoEngine
|
||||
{
|
||||
|
||||
mbedtls_aes_context aes;
|
||||
|
||||
public:
|
||||
ESP32CryptoEngine() { mbedtls_aes_init(&aes); }
|
||||
|
||||
~ESP32CryptoEngine() { mbedtls_aes_free(&aes); }
|
||||
|
||||
/**
|
||||
* Set the key used for encrypt, decrypt.
|
||||
*
|
||||
* As a special case: If all bytes are zero, we assume _no encryption_ and send all data in cleartext.
|
||||
*
|
||||
* @param numBytes must be 16 (AES128), 32 (AES256) or 0 (no crypt)
|
||||
* @param bytes a _static_ buffer that will remain valid for the life of this crypto instance (i.e. this class will cache the
|
||||
* provided pointer)
|
||||
*/
|
||||
virtual void setKey(const CryptoKey &k) override
|
||||
{
|
||||
CryptoEngine::setKey(k);
|
||||
|
||||
if (key.length != 0) {
|
||||
auto res = mbedtls_aes_setkey_enc(&aes, key.bytes, key.length * 8);
|
||||
assert(!res);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt a packet
|
||||
*
|
||||
* @param bytes is updated in place
|
||||
*/
|
||||
virtual void encrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes) override
|
||||
{
|
||||
if (key.length > 0) {
|
||||
uint8_t stream_block[16];
|
||||
static uint8_t scratch[MAX_BLOCKSIZE];
|
||||
size_t nc_off = 0;
|
||||
|
||||
DEBUG_MSG("ESP32 crypt fr=%x, num=%x, numBytes=%d!\n", fromNode, (uint32_t) packetId, numBytes);
|
||||
initNonce(fromNode, packetId);
|
||||
assert(numBytes <= MAX_BLOCKSIZE);
|
||||
memcpy(scratch, bytes, numBytes);
|
||||
memset(scratch + numBytes, 0,
|
||||
sizeof(scratch) - numBytes); // Fill rest of buffer with zero (in case cypher looks at it)
|
||||
|
||||
auto res = mbedtls_aes_crypt_ctr(&aes, numBytes, &nc_off, nonce, stream_block, scratch, bytes);
|
||||
assert(!res);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void decrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes) override
|
||||
{
|
||||
// For CTR, the implementation is the same
|
||||
encrypt(fromNode, packetId, numBytes, bytes);
|
||||
}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
CryptoEngine *crypto = new ESP32CryptoEngine();
|
||||
73
src/platform/esp32/NimbleSoftwareUpdate.c
Normal file
73
src/platform/esp32/NimbleSoftwareUpdate.c
Normal file
@@ -0,0 +1,73 @@
|
||||
#ifndef USE_NEW_ESP32_BLUETOOTH
|
||||
#include "BluetoothSoftwareUpdate.h"
|
||||
|
||||
// NRF52 wants these constants as byte arrays
|
||||
// Generated here https://yupana-engineering.com/online-uuid-to-c-array-converter - but in REVERSE BYTE ORDER
|
||||
|
||||
// "cb0b9a0b-a84c-4c0d-bdbb-442e3144ee30"
|
||||
const ble_uuid128_t update_service_uuid =
|
||||
BLE_UUID128_INIT(0x30, 0xee, 0x44, 0x31, 0x2e, 0x44, 0xbb, 0xbd, 0x0d, 0x4c, 0x4c, 0xa8, 0x0b, 0x9a, 0x0b, 0xcb);
|
||||
|
||||
// "e74dd9c0-a301-4a6f-95a1-f0e1dbea8e1e" write|read
|
||||
const ble_uuid128_t update_size_uuid =
|
||||
BLE_UUID128_INIT(0x1e, 0x8e, 0xea, 0xdb, 0xe1, 0xf0, 0xa1, 0x95, 0x6f, 0x4a, 0x01, 0xa3, 0xc0, 0xd9, 0x4d, 0xe7);
|
||||
|
||||
// "e272ebac-d463-4b98-bc84-5cc1a39ee517" write
|
||||
const ble_uuid128_t update_data_uuid =
|
||||
BLE_UUID128_INIT(0x17, 0xe5, 0x9e, 0xa3, 0xc1, 0x5c, 0x84, 0xbc, 0x98, 0x4b, 0x63, 0xd4, 0xac, 0xeb, 0x72, 0xe2);
|
||||
|
||||
// "4826129c-c22a-43a3-b066-ce8f0d5bacc6" write
|
||||
const ble_uuid128_t update_crc32_uuid =
|
||||
BLE_UUID128_INIT(0xc6, 0xac, 0x5b, 0x0d, 0x8f, 0xce, 0x66, 0xb0, 0xa3, 0x43, 0x2a, 0xc2, 0x9c, 0x12, 0x26, 0x48);
|
||||
|
||||
// "5e134862-7411-4424-ac4a-210937432c77" read|notify
|
||||
const ble_uuid128_t update_result_uuid =
|
||||
BLE_UUID128_INIT(0x77, 0x2c, 0x43, 0x37, 0x09, 0x21, 0x4a, 0xac, 0x24, 0x44, 0x11, 0x74, 0x62, 0x48, 0x13, 0x5e);
|
||||
|
||||
// "5e134862-7411-4424-ac4a-210937432c67" write
|
||||
const ble_uuid128_t update_region_uuid =
|
||||
BLE_UUID128_INIT(0x67, 0x2c, 0x43, 0x37, 0x09, 0x21, 0x4a, 0xac, 0x24, 0x44, 0x11, 0x74, 0x62, 0x48, 0x13, 0x5e);
|
||||
|
||||
const struct ble_gatt_svc_def gatt_update_svcs[] = {
|
||||
{
|
||||
/*** Service: Security test. */
|
||||
.type = BLE_GATT_SVC_TYPE_PRIMARY,
|
||||
.uuid = &update_service_uuid.u,
|
||||
.characteristics =
|
||||
(struct ble_gatt_chr_def[]){{
|
||||
.uuid = &update_size_uuid.u,
|
||||
.access_cb = update_size_callback,
|
||||
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_AUTHEN | BLE_GATT_CHR_F_READ |
|
||||
BLE_GATT_CHR_F_READ_AUTHEN,
|
||||
},
|
||||
{
|
||||
.uuid = &update_data_uuid.u,
|
||||
.access_cb = update_data_callback,
|
||||
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_AUTHEN,
|
||||
},
|
||||
{
|
||||
.uuid = &update_crc32_uuid.u,
|
||||
.access_cb = update_crc32_callback,
|
||||
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_AUTHEN,
|
||||
},
|
||||
{
|
||||
.uuid = &update_result_uuid.u,
|
||||
.access_cb = update_result_callback,
|
||||
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_AUTHEN | BLE_GATT_CHR_F_NOTIFY,
|
||||
},
|
||||
{
|
||||
.uuid = &update_region_uuid.u,
|
||||
.access_cb = update_region_callback,
|
||||
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_AUTHEN,
|
||||
},
|
||||
{
|
||||
0, /* No more characteristics in this service. */
|
||||
}},
|
||||
},
|
||||
|
||||
{
|
||||
0, /* No more services. */
|
||||
},
|
||||
};
|
||||
|
||||
#endif //#ifndef USE_NEW_ESP32_BLUETOOTH
|
||||
60
src/platform/esp32/SimpleAllocator.cpp
Normal file
60
src/platform/esp32/SimpleAllocator.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#include "SimpleAllocator.h"
|
||||
#include "assert.h"
|
||||
|
||||
|
||||
SimpleAllocator::SimpleAllocator() { reset(); }
|
||||
|
||||
void *SimpleAllocator::alloc(size_t size)
|
||||
{
|
||||
assert(nextFree + size <= sizeof(bytes));
|
||||
void *res = &bytes[nextFree];
|
||||
nextFree += size;
|
||||
Serial.printf("Total simple allocs %u\n", nextFree);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void SimpleAllocator::reset() { nextFree = 0; }
|
||||
|
||||
void *operator new(size_t size, SimpleAllocator &p)
|
||||
{
|
||||
return p.alloc(size);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// This was a dumb idea, turn off for now
|
||||
|
||||
SimpleAllocator *activeAllocator;
|
||||
|
||||
AllocatorScope::AllocatorScope(SimpleAllocator &a)
|
||||
{
|
||||
assert(!activeAllocator);
|
||||
activeAllocator = &a;
|
||||
}
|
||||
|
||||
AllocatorScope::~AllocatorScope()
|
||||
{
|
||||
assert(activeAllocator);
|
||||
activeAllocator = NULL;
|
||||
}
|
||||
|
||||
/// Global new/delete, uses a simple allocator if it is in scope
|
||||
|
||||
void *operator new(size_t sz) throw(std::bad_alloc)
|
||||
{
|
||||
void *mem = activeAllocator ? activeAllocator->alloc(sz) : malloc(sz);
|
||||
if (mem)
|
||||
return mem;
|
||||
else
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
void operator delete(void *ptr) throw()
|
||||
{
|
||||
if (activeAllocator)
|
||||
Serial.println("Warning: leaking an active allocator object"); // We don't properly handle this yet
|
||||
else
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
#endif
|
||||
42
src/platform/esp32/SimpleAllocator.h
Normal file
42
src/platform/esp32/SimpleAllocator.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
|
||||
#define POOL_SIZE 16384
|
||||
|
||||
/**
|
||||
* An allocator (and placement new operator) that allocates storage from a fixed sized buffer.
|
||||
* It will panic if that buffer fills up.
|
||||
* If you are _sure_ no outstanding references to blocks in this buffer still exist, you can call
|
||||
* reset() to start from scratch.
|
||||
*
|
||||
* Currently the only usecase for this class is the ESP32 bluetooth stack, where once we've called deinit(false)
|
||||
* we are sure all those bluetooth objects no longer exist, and we'll need to recreate them when we restart bluetooth
|
||||
*/
|
||||
class SimpleAllocator
|
||||
{
|
||||
uint8_t bytes[POOL_SIZE] = {};
|
||||
|
||||
uint32_t nextFree = 0;
|
||||
|
||||
public:
|
||||
SimpleAllocator();
|
||||
|
||||
void *alloc(size_t size);
|
||||
|
||||
/** If you are _sure_ no outstanding references to blocks in this buffer still exist, you can call
|
||||
* reset() to start from scratch.
|
||||
* */
|
||||
void reset();
|
||||
};
|
||||
|
||||
void *operator new(size_t size, SimpleAllocator &p);
|
||||
|
||||
/**
|
||||
* Temporarily makes the specified Allocator be used for _all_ allocations. Useful when calling library routines
|
||||
* that don't know about pools
|
||||
*/
|
||||
class AllocatorScope {
|
||||
public:
|
||||
explicit AllocatorScope(SimpleAllocator &a);
|
||||
~AllocatorScope();
|
||||
};
|
||||
106
src/platform/esp32/architecture.h
Normal file
106
src/platform/esp32/architecture.h
Normal file
@@ -0,0 +1,106 @@
|
||||
#pragma once
|
||||
|
||||
#define ARCH_ESP32
|
||||
|
||||
//
|
||||
// defaults for ESP32 architecture
|
||||
//
|
||||
|
||||
#ifndef HAS_WIFI
|
||||
#define HAS_WIFI 1
|
||||
#endif
|
||||
#ifndef HAS_SCREEN
|
||||
#define HAS_SCREEN 1
|
||||
#endif
|
||||
#ifndef HAS_WIRE
|
||||
#define HAS_WIRE 1
|
||||
#endif
|
||||
#ifndef HAS_GPS
|
||||
#define HAS_GPS 1
|
||||
#endif
|
||||
#ifndef HAS_BUTTON
|
||||
#define HAS_BUTTON 1
|
||||
#endif
|
||||
#ifndef HAS_TELEMETRY
|
||||
#define HAS_TELEMETRY 1
|
||||
#endif
|
||||
#ifndef HAS_RADIO
|
||||
#define HAS_RADIO 1
|
||||
#endif
|
||||
#ifndef HAS_RTC
|
||||
#define HAS_RTC 1
|
||||
#endif
|
||||
|
||||
//
|
||||
// set HW_VENDOR
|
||||
//
|
||||
|
||||
// This string must exactly match the case used in release file names or the android updater won't work
|
||||
|
||||
#if defined(TBEAM_V10)
|
||||
#define HW_VENDOR HardwareModel_TBEAM
|
||||
#elif defined(TBEAM_V07)
|
||||
#define HW_VENDOR HardwareModel_TBEAM0p7
|
||||
#elif defined(DIY_V1)
|
||||
#define HW_VENDOR HardwareModel_DIY_V1
|
||||
#elif defined(RAK_11200)
|
||||
#define HW_VENDOR HardwareModel_RAK11200
|
||||
#elif defined(ARDUINO_HELTEC_WIFI_LORA_32_V2)
|
||||
#ifdef HELTEC_V2_0
|
||||
#define HW_VENDOR HardwareModel_HELTEC_V2_0
|
||||
#endif
|
||||
#ifdef HELTEC_V2_1
|
||||
#define HW_VENDOR HardwareModel_HELTEC_V2_1
|
||||
#endif
|
||||
#elif defined(ARDUINO_HELTEC_WIFI_LORA_32)
|
||||
#define HW_VENDOR HardwareModel_HELTEC_V1
|
||||
#elif defined(TLORA_V1)
|
||||
#define HW_VENDOR HardwareModel_TLORA_V1
|
||||
#elif defined(TLORA_V2)
|
||||
#define HW_VENDOR HardwareModel_TLORA_V2
|
||||
#elif defined(TLORA_V1_3)
|
||||
#define HW_VENDOR HardwareModel_TLORA_V1_1p3
|
||||
#elif defined(TLORA_V2_1_16)
|
||||
#define HW_VENDOR HardwareModel_TLORA_V2_1_1p6
|
||||
#elif defined(GENIEBLOCKS)
|
||||
#define HW_VENDOR HardwareModel_GENIEBLOCKS
|
||||
#elif defined(PRIVATE_HW)
|
||||
#define HW_VENDOR HardwareModel_PRIVATE_HW
|
||||
#elif defined(NANO_G1)
|
||||
#define HW_VENDOR HardwareModel_NANO_G1
|
||||
#elif defined(M5STACK)
|
||||
#define HW_VENDOR HardwareModel_M5STACK
|
||||
#elif defined(STATION_G1)
|
||||
#define HW_VENDOR HardwareModel_STATION_G1
|
||||
#endif
|
||||
|
||||
//
|
||||
// Standard definitions for ESP32 targets
|
||||
//
|
||||
|
||||
#define GPS_SERIAL_NUM 1
|
||||
#ifndef GPS_RX_PIN
|
||||
#define GPS_RX_PIN 34
|
||||
#endif
|
||||
#ifndef GPS_TX_PIN
|
||||
#ifdef USE_JTAG
|
||||
#define GPS_TX_PIN -1
|
||||
#else
|
||||
#define GPS_TX_PIN 12
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// LoRa SPI
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// NRF52 boards will define this in variant.h
|
||||
#ifndef RF95_SCK
|
||||
#define RF95_SCK 5
|
||||
#define RF95_MISO 19
|
||||
#define RF95_MOSI 27
|
||||
#define RF95_NSS 18
|
||||
#endif
|
||||
|
||||
#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32
|
||||
|
||||
184
src/platform/esp32/main-esp32.cpp
Normal file
184
src/platform/esp32/main-esp32.cpp
Normal file
@@ -0,0 +1,184 @@
|
||||
#include "BluetoothSoftwareUpdate.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "configuration.h"
|
||||
#include "esp_task_wdt.h"
|
||||
#include "main.h"
|
||||
|
||||
#ifdef USE_NEW_ESP32_BLUETOOTH
|
||||
#include "ESP32Bluetooth.h"
|
||||
#include "mesh/http/WiFiAPClient.h"
|
||||
#else
|
||||
#include "nimble/BluetoothUtil.h"
|
||||
#endif
|
||||
|
||||
#include "sleep.h"
|
||||
#include "target_specific.h"
|
||||
#include "utils.h"
|
||||
#include <Preferences.h>
|
||||
#include <driver/rtc_io.h>
|
||||
#include <nvs.h>
|
||||
#include <nvs_flash.h>
|
||||
|
||||
#ifdef USE_NEW_ESP32_BLUETOOTH
|
||||
ESP32Bluetooth *esp32Bluetooth;
|
||||
#endif
|
||||
|
||||
void getMacAddr(uint8_t *dmac)
|
||||
{
|
||||
assert(esp_efuse_mac_get_default(dmac) == ESP_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
static void printBLEinfo() {
|
||||
int dev_num = esp_ble_get_bond_device_num();
|
||||
|
||||
esp_ble_bond_dev_t *dev_list = (esp_ble_bond_dev_t *)malloc(sizeof(esp_ble_bond_dev_t) * dev_num);
|
||||
esp_ble_get_bond_device_list(&dev_num, dev_list);
|
||||
for (int i = 0; i < dev_num; i++) {
|
||||
// esp_ble_remove_bond_device(dev_list[i].bd_addr);
|
||||
}
|
||||
|
||||
} */
|
||||
#ifdef USE_NEW_ESP32_BLUETOOTH
|
||||
void setBluetoothEnable(bool on) {
|
||||
|
||||
if (!isWifiAvailable()) {
|
||||
if (!esp32Bluetooth) {
|
||||
esp32Bluetooth = new ESP32Bluetooth();
|
||||
}
|
||||
if (on) {
|
||||
esp32Bluetooth->setup();
|
||||
} else {
|
||||
esp32Bluetooth->shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void esp32Setup()
|
||||
{
|
||||
uint32_t seed = esp_random();
|
||||
DEBUG_MSG("Setting random seed %u\n", seed);
|
||||
randomSeed(seed); // ESP docs say this is fairly random
|
||||
|
||||
DEBUG_MSG("Total heap: %d\n", ESP.getHeapSize());
|
||||
DEBUG_MSG("Free heap: %d\n", ESP.getFreeHeap());
|
||||
DEBUG_MSG("Total PSRAM: %d\n", ESP.getPsramSize());
|
||||
DEBUG_MSG("Free PSRAM: %d\n", ESP.getFreePsram());
|
||||
|
||||
nvs_stats_t nvs_stats;
|
||||
auto res = nvs_get_stats(NULL, &nvs_stats);
|
||||
assert(res == ESP_OK);
|
||||
DEBUG_MSG("NVS: UsedEntries %d, FreeEntries %d, AllEntries %d, NameSpaces %d\n", nvs_stats.used_entries, nvs_stats.free_entries,
|
||||
nvs_stats.total_entries, nvs_stats.namespace_count);
|
||||
|
||||
DEBUG_MSG("Setup Preferences in Flash Storage\n");
|
||||
|
||||
// Create object to store our persistant data
|
||||
Preferences preferences;
|
||||
preferences.begin("meshtastic", false);
|
||||
|
||||
uint32_t rebootCounter = preferences.getUInt("rebootCounter", 0);
|
||||
rebootCounter++;
|
||||
preferences.putUInt("rebootCounter", rebootCounter);
|
||||
preferences.end();
|
||||
DEBUG_MSG("Number of Device Reboots: %d\n", rebootCounter);
|
||||
|
||||
// enableModemSleep();
|
||||
|
||||
// Since we are turning on watchdogs rather late in the release schedule, we really don't want to catch any
|
||||
// false positives. The wait-to-sleep timeout for shutting down radios is 30 secs, so pick 45 for now.
|
||||
// #define APP_WATCHDOG_SECS 45
|
||||
#define APP_WATCHDOG_SECS 90
|
||||
|
||||
res = esp_task_wdt_init(APP_WATCHDOG_SECS, true);
|
||||
assert(res == ESP_OK);
|
||||
|
||||
res = esp_task_wdt_add(NULL);
|
||||
assert(res == ESP_OK);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Turn off for now
|
||||
|
||||
uint32_t axpDebugRead()
|
||||
{
|
||||
axp.debugCharging();
|
||||
DEBUG_MSG("vbus current %f\n", axp.getVbusCurrent());
|
||||
DEBUG_MSG("charge current %f\n", axp.getBattChargeCurrent());
|
||||
DEBUG_MSG("bat voltage %f\n", axp.getBattVoltage());
|
||||
DEBUG_MSG("batt pct %d\n", axp.getBattPercentage());
|
||||
DEBUG_MSG("is battery connected %d\n", axp.isBatteryConnect());
|
||||
DEBUG_MSG("is USB connected %d\n", axp.isVBUSPlug());
|
||||
DEBUG_MSG("is charging %d\n", axp.isChargeing());
|
||||
|
||||
return 30 * 1000;
|
||||
}
|
||||
|
||||
Periodic axpDebugOutput(axpDebugRead);
|
||||
#endif
|
||||
|
||||
|
||||
/// loop code specific to ESP32 targets
|
||||
void esp32Loop()
|
||||
{
|
||||
esp_task_wdt_reset(); // service our app level watchdog
|
||||
//loopBLE();
|
||||
|
||||
// for debug printing
|
||||
// radio.radioIf.canSleep();
|
||||
}
|
||||
|
||||
void cpuDeepSleep(uint64_t msecToWake)
|
||||
{
|
||||
/*
|
||||
Some ESP32 IOs have internal pullups or pulldowns, which are enabled by default.
|
||||
If an external circuit drives this pin in deep sleep mode, current consumption may
|
||||
increase due to current flowing through these pullups and pulldowns.
|
||||
|
||||
To isolate a pin, preventing extra current draw, call rtc_gpio_isolate() function.
|
||||
For example, on ESP32-WROVER module, GPIO12 is pulled up externally.
|
||||
GPIO12 also has an internal pulldown in the ESP32 chip. This means that in deep sleep,
|
||||
some current will flow through these external and internal resistors, increasing deep
|
||||
sleep current above the minimal possible value.
|
||||
|
||||
Note: we don't isolate pins that are used for the LORA, LED, i2c, spi or the wake button
|
||||
*/
|
||||
static const uint8_t rtcGpios[] = {/* 0, */ 2,
|
||||
/* 4, */
|
||||
#ifndef USE_JTAG
|
||||
13,
|
||||
/* 14, */ /* 15, */
|
||||
#endif
|
||||
/* 25, */ 26, /* 27, */
|
||||
32, 33, 34, 35,
|
||||
36, 37
|
||||
/* 38, 39 */};
|
||||
|
||||
for (int i = 0; i < sizeof(rtcGpios); i++)
|
||||
rtc_gpio_isolate((gpio_num_t)rtcGpios[i]);
|
||||
|
||||
// FIXME, disable internal rtc pullups/pulldowns on the non isolated pins. for inputs that we aren't using
|
||||
// to detect wake and in normal operation the external part drives them hard.
|
||||
|
||||
// We want RTC peripherals to stay on
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
||||
|
||||
#ifdef BUTTON_PIN
|
||||
// Only GPIOs which are have RTC functionality can be used in this bit map: 0,2,4,12-15,25-27,32-39.
|
||||
uint64_t gpioMask = (1ULL << BUTTON_PIN);
|
||||
|
||||
#ifdef BUTTON_NEED_PULLUP
|
||||
gpio_pullup_en((gpio_num_t)BUTTON_PIN);
|
||||
#endif
|
||||
|
||||
// Not needed because both of the current boards have external pullups
|
||||
// FIXME change polarity in hw so we can wake on ANY_HIGH instead - that would allow us to use all three buttons (instead of
|
||||
// just the first) gpio_pullup_en((gpio_num_t)BUTTON_PIN);
|
||||
|
||||
esp_sleep_enable_ext1_wakeup(gpioMask, ESP_EXT1_WAKEUP_ALL_LOW);
|
||||
#endif
|
||||
|
||||
esp_sleep_enable_timer_wakeup(msecToWake * 1000ULL); // call expects usecs
|
||||
esp_deep_sleep_start(); // TBD mA sleep current (battery)
|
||||
}
|
||||
Reference in New Issue
Block a user