From 31540410cfaac2848240c0e95e3408d9a7f1bc4c Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Tue, 23 Apr 2024 00:52:57 +0200 Subject: [PATCH] Base structure for BLE support on ESP32-S3 boards --- Bluetooth.h | 316 +++++++++++++++++++++++++++++---------------- Boards.h | 34 +++-- Device.h | 2 +- RNode_Firmware.ino | 25 +--- Utilities.h | 6 +- 5 files changed, 233 insertions(+), 150 deletions(-) diff --git a/Bluetooth.h b/Bluetooth.h index e7231a1..64eac7d 100644 --- a/Bluetooth.h +++ b/Bluetooth.h @@ -14,21 +14,30 @@ // along with this program. If not, see . #if MCU_VARIANT == MCU_ESP32 -#include "BluetoothSerial.h" -#include "esp_bt_main.h" -#include "esp_bt_device.h" + #elif MCU_VARIANT == MCU_NRF52 -#include -#include #endif #if MCU_VARIANT == MCU_ESP32 -BluetoothSerial SerialBT; + #if HAS_BLUETOOTH == true + #include "BluetoothSerial.h" + #include "esp_bt_main.h" + #include "esp_bt_device.h" + BluetoothSerial SerialBT; + #elif HAS_BLE == true + #include "esp_bt_main.h" + #include "esp_bt_device.h" + // TODO: Remove + #define SerialBT Serial + #endif + #elif MCU_VARIANT == MCU_NRF52 -BLEUart SerialBT; -BLEDis bledis; -BLEBas blebas; + #include + #include + BLEUart SerialBT; + BLEDis bledis; + BLEBas blebas; #endif #define BT_PAIRING_TIMEOUT 35000 @@ -42,114 +51,201 @@ char bt_dh[BT_DEV_HASH_LEN]; char bt_devname[11]; #if MCU_VARIANT == MCU_ESP32 + #if HAS_BLUETOOTH == true - void bt_confirm_pairing(uint32_t numVal) { - bt_ssp_pin = numVal; - kiss_indicate_btpin(); - if (bt_allow_pairing) { - SerialBT.confirmReply(true); - } else { - SerialBT.confirmReply(false); - } - } - - void bt_stop() { - if (bt_state != BT_STATE_OFF) { - SerialBT.end(); - bt_allow_pairing = false; - bt_state = BT_STATE_OFF; - } - } - - void bt_start() { - if (bt_state == BT_STATE_OFF) { - SerialBT.begin(bt_devname); - bt_state = BT_STATE_ON; - } - } - - void bt_enable_pairing() { - if (bt_state == BT_STATE_OFF) bt_start(); - bt_allow_pairing = true; - bt_pairing_started = millis(); - bt_state = BT_STATE_PAIRING; - } - - void bt_disable_pairing() { - bt_allow_pairing = false; - bt_ssp_pin = 0; - bt_state = BT_STATE_ON; - } - - void bt_pairing_complete(boolean success) { - if (success) { - bt_disable_pairing(); - } else { - bt_ssp_pin = 0; - } - } - - void bt_connection_callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param){ - if(event == ESP_SPP_SRV_OPEN_EVT) { - bt_state = BT_STATE_CONNECTED; - cable_state = CABLE_STATE_DISCONNECTED; - } - - if(event == ESP_SPP_CLOSE_EVT ){ - bt_state = BT_STATE_ON; - } - } - - bool bt_setup_hw() { - if (!bt_ready) { - if (EEPROM.read(eeprom_addr(ADDR_CONF_BT)) == BT_ENABLE_BYTE) { - bt_enabled = true; + void bt_confirm_pairing(uint32_t numVal) { + bt_ssp_pin = numVal; + kiss_indicate_btpin(); + if (bt_allow_pairing) { + SerialBT.confirmReply(true); } else { - bt_enabled = false; + SerialBT.confirmReply(false); } - if (btStart()) { - if (esp_bluedroid_init() == ESP_OK) { - if (esp_bluedroid_enable() == ESP_OK) { - const uint8_t* bda_ptr = esp_bt_dev_get_address(); - char *data = (char*)malloc(BT_DEV_ADDR_LEN+1); - for (int i = 0; i < BT_DEV_ADDR_LEN; i++) { - data[i] = bda_ptr[i]; - } - data[BT_DEV_ADDR_LEN] = EEPROM.read(eeprom_addr(ADDR_SIGNATURE)); - unsigned char *hash = MD5::make_hash(data, BT_DEV_ADDR_LEN); - memcpy(bt_dh, hash, BT_DEV_HASH_LEN); - sprintf(bt_devname, "RNode %02X%02X", bt_dh[14], bt_dh[15]); - free(data); + } - SerialBT.enableSSP(); - SerialBT.onConfirmRequest(bt_confirm_pairing); - SerialBT.onAuthComplete(bt_pairing_complete); - SerialBT.register_callback(bt_connection_callback); - - bt_ready = true; - return true; + void bt_stop() { + if (bt_state != BT_STATE_OFF) { + SerialBT.end(); + bt_allow_pairing = false; + bt_state = BT_STATE_OFF; + } + } + void bt_start() { + if (bt_state == BT_STATE_OFF) { + SerialBT.begin(bt_devname); + bt_state = BT_STATE_ON; + } + } + + void bt_enable_pairing() { + if (bt_state == BT_STATE_OFF) bt_start(); + bt_allow_pairing = true; + bt_pairing_started = millis(); + bt_state = BT_STATE_PAIRING; + } + + void bt_disable_pairing() { + bt_allow_pairing = false; + bt_ssp_pin = 0; + bt_state = BT_STATE_ON; + } + + void bt_pairing_complete(boolean success) { + if (success) { + bt_disable_pairing(); + } else { + bt_ssp_pin = 0; + } + } + + void bt_connection_callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param){ + if(event == ESP_SPP_SRV_OPEN_EVT) { + bt_state = BT_STATE_CONNECTED; + cable_state = CABLE_STATE_DISCONNECTED; + } + + if(event == ESP_SPP_CLOSE_EVT ){ + bt_state = BT_STATE_ON; + } + } + + bool bt_setup_hw() { + if (!bt_ready) { + if (EEPROM.read(eeprom_addr(ADDR_CONF_BT)) == BT_ENABLE_BYTE) { + bt_enabled = true; + } else { + bt_enabled = false; + } + if (btStart()) { + if (esp_bluedroid_init() == ESP_OK) { + if (esp_bluedroid_enable() == ESP_OK) { + const uint8_t* bda_ptr = esp_bt_dev_get_address(); + char *data = (char*)malloc(BT_DEV_ADDR_LEN+1); + for (int i = 0; i < BT_DEV_ADDR_LEN; i++) { + data[i] = bda_ptr[i]; + } + data[BT_DEV_ADDR_LEN] = EEPROM.read(eeprom_addr(ADDR_SIGNATURE)); + unsigned char *hash = MD5::make_hash(data, BT_DEV_ADDR_LEN); + memcpy(bt_dh, hash, BT_DEV_HASH_LEN); + sprintf(bt_devname, "RNode %02X%02X", bt_dh[14], bt_dh[15]); + free(data); + + SerialBT.enableSSP(); + SerialBT.onConfirmRequest(bt_confirm_pairing); + SerialBT.onAuthComplete(bt_pairing_complete); + SerialBT.register_callback(bt_connection_callback); + + bt_ready = true; + return true; + + } else { return false; } } else { return false; } } else { return false; } } else { return false; } - } else { return false; } - } - - bool bt_init() { - bt_state = BT_STATE_OFF; - if (bt_setup_hw()) { - if (bt_enabled && !console_active) bt_start(); - return true; - } else { - return false; - } - } - - void update_bt() { - if (bt_allow_pairing && millis()-bt_pairing_started >= BT_PAIRING_TIMEOUT) { - bt_disable_pairing(); } - } + + bool bt_init() { + bt_state = BT_STATE_OFF; + if (bt_setup_hw()) { + if (bt_enabled && !console_active) bt_start(); + return true; + } else { + return false; + } + } + + void update_bt() { + if (bt_allow_pairing && millis()-bt_pairing_started >= BT_PAIRING_TIMEOUT) { + bt_disable_pairing(); + } + } + + #elif HAS_BLE == true + void bt_stop() { + if (bt_state != BT_STATE_OFF) { + bt_allow_pairing = false; + bt_state = BT_STATE_OFF; + } + } + + void bt_disable_pairing() { + bt_allow_pairing = false; + bt_ssp_pin = 0; + bt_state = BT_STATE_ON; + } + + void bt_connect_callback(uint16_t conn_handle) { + bt_state = BT_STATE_CONNECTED; + cable_state = CABLE_STATE_DISCONNECTED; + } + + void bt_disconnect_callback(uint16_t conn_handle, uint8_t reason) { + bt_state = BT_STATE_ON; + } + + bool bt_setup_hw() { + if (!bt_ready) { + if (EEPROM.read(eeprom_addr(ADDR_CONF_BT)) == BT_ENABLE_BYTE) { + bt_enabled = true; + } else { + bt_enabled = false; + } + if (btStart()) { + if (esp_bluedroid_init() == ESP_OK) { + if (esp_bluedroid_enable() == ESP_OK) { + const uint8_t* bda_ptr = esp_bt_dev_get_address(); + char *data = (char*)malloc(BT_DEV_ADDR_LEN+1); + for (int i = 0; i < BT_DEV_ADDR_LEN; i++) { + data[i] = bda_ptr[i]; + } + data[BT_DEV_ADDR_LEN] = EEPROM.read(eeprom_addr(ADDR_SIGNATURE)); + unsigned char *hash = MD5::make_hash(data, BT_DEV_ADDR_LEN); + memcpy(bt_dh, hash, BT_DEV_HASH_LEN); + sprintf(bt_devname, "RNode %02X%02X", bt_dh[14], bt_dh[15]); + free(data); + + // TODO: Implement GAP & GATT for RNode comms over BLE + + bt_ready = true; + return true; + + } else { return false; } + } else { return false; } + } else { return false; } + } else { return false; } + } + + void bt_start() { + if (bt_state == BT_STATE_OFF) { + bt_state = BT_STATE_ON; + // TODO: Implement + } + } + + bool bt_init() { + bt_state = BT_STATE_OFF; + if (bt_setup_hw()) { + if (bt_enabled && !console_active) bt_start(); + return true; + } else { + return false; + } + } + + void bt_enable_pairing() { + if (bt_state == BT_STATE_OFF) bt_start(); + bt_allow_pairing = true; + bt_pairing_started = millis(); + bt_state = BT_STATE_PAIRING; + } + + void update_bt() { + if (bt_allow_pairing && millis()-bt_pairing_started >= BT_PAIRING_TIMEOUT) { + bt_disable_pairing(); + } + } + #endif #elif MCU_VARIANT == MCU_NRF52 uint8_t eeprom_read(uint32_t mapped_addr); @@ -244,8 +340,8 @@ bool bt_setup_hw() { void bt_start() { if (bt_state == BT_STATE_OFF) { Bluefruit.setName(bt_devname); - bledis.setManufacturer("Adafruit Industries"); - bledis.setModel("Bluefruit Feather52"); + bledis.setManufacturer(BLE_MANUFACTURER); + bledis.setModel(BLE_MODEL); // start device information service bledis.begin(); diff --git a/Boards.h b/Boards.h index 8fe602e..cfc48d7 100644 --- a/Boards.h +++ b/Boards.h @@ -18,14 +18,14 @@ #ifndef BOARDS_H #define BOARDS_H - #define PLATFORM_AVR 0x90 - #define PLATFORM_ESP32 0x80 - #define PLATFORM_NRF52 0x70 + #define PLATFORM_AVR 0x90 + #define PLATFORM_ESP32 0x80 + #define PLATFORM_NRF52 0x70 - #define MCU_1284P 0x91 - #define MCU_2560 0x92 - #define MCU_ESP32 0x81 - #define MCU_NRF52 0x71 + #define MCU_1284P 0x91 + #define MCU_2560 0x92 + #define MCU_ESP32 0x81 + #define MCU_NRF52 0x71 #define BOARD_RNODE 0x31 #define BOARD_HMBRW 0x32 @@ -252,14 +252,11 @@ #elif BOARD_MODEL == BOARD_HELTEC32_V3 #define IS_ESP32S3 true #define HAS_DISPLAY true - //ESP32-S3 no bluetooth classic #define HAS_BLUETOOTH false - // TODO BLE - #define HAS_BLE false + #define HAS_BLE true // Cannot run wifi and BLE at same time? #define HAS_CONSOLE false #define HAS_EEPROM true - // Only one LED on pin 35 #if defined(EXTERNAL_LEDS) const int pin_led_rx = 13; const int pin_led_tx = 14; @@ -283,8 +280,6 @@ const int pin_miso = 11; const int pin_sclk = 9; - - #elif BOARD_MODEL == BOARD_RNODE_NG_20 #define HAS_DISPLAY true #define HAS_BLUETOOTH true @@ -341,9 +336,9 @@ #define HAS_TCXO true #define HAS_DISPLAY true + #define HAS_CONSOLE false + #define HAS_BLUETOOTH false #define HAS_BLE true - #define HAS_BLUETOOTH false // TODO: Implement - #define HAS_CONSOLE false // TODO: Implement #define HAS_PMU true #define HAS_NP false #define HAS_SD false @@ -384,8 +379,9 @@ #elif MCU_VARIANT == MCU_NRF52 #if BOARD_MODEL == BOARD_RAK4630 #define HAS_EEPROM false - #define HAS_DISPLAY false // set for debugging - #define HAS_BLUETOOTH true + #define HAS_DISPLAY true + #define HAS_BLUETOOTH false + #define HAS_BLE true #define HAS_CONSOLE false #define HAS_PMU false #define HAS_NP false @@ -398,8 +394,10 @@ #define CONFIG_QUEUE_MAX_LENGTH 200 #define EEPROM_SIZE 200 #define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED + #define BLE_MANUFACTURER "RAK Wireless" + #define BLE_MODEL "RAK4640" - // following pins are for the sx1262 + // Following pins are for the sx1262 const int pin_rxen = 37; const int pin_reset = 38; const int pin_cs = 42; diff --git a/Device.h b/Device.h index 0b9f5e5..b7a11a6 100644 --- a/Device.h +++ b/Device.h @@ -154,7 +154,7 @@ bool device_init() { mbedtls_md_init(&ctx); mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0); mbedtls_md_starts(&ctx); - #if HAS_BLUETOOTH == true + #if HAS_BLUETOOTH == true || HAS_BLE == true mbedtls_md_update(&ctx, dev_bt_mac, BT_DEV_ADDR_LEN); #else // TODO: Get from BLE stack instead diff --git a/RNode_Firmware.ino b/RNode_Firmware.ino index 7f026a5..7f0c839 100644 --- a/RNode_Firmware.ino +++ b/RNode_Firmware.ino @@ -33,7 +33,7 @@ volatile uint16_t queued_bytes = 0; volatile uint16_t queue_cursor = 0; volatile uint16_t current_packet_start = 0; volatile bool serial_buffering = false; -#if HAS_BLUETOOTH +#if HAS_BLUETOOTH || HAS_BLE == true bool bt_init_ran = false; #endif @@ -160,12 +160,9 @@ void setup() { pmu_ready = init_pmu(); #endif - #if HAS_BLUETOOTH + #if HAS_BLUETOOTH || HAS_BLE == true bt_init(); bt_init_ran = true; - #elif HAS_BLE - // TODO: Implement BLE on ESP32S3 instead of this hack - bt_ready = true; #endif if (console_active) { @@ -910,7 +907,7 @@ void serialCallback(uint8_t sbyte) { } #endif } else if (command == CMD_BT_CTRL) { - #if HAS_BLUETOOTH + #if HAS_BLUETOOTH || HAS_BLE if (sbyte == 0x00) { bt_stop(); bt_conf_save(false); @@ -1111,15 +1108,7 @@ void validate_status() { if (device_init()) { hw_ready = true; } else { - #if !HAS_BLUETOOTH && !HAS_BLE - // Without bluetooth, bt_ready and device_init_done - // are not set - // and neither is hw_ready (see device_init()) - hw_ready = true; - device_init_done = true; - #else - hw_ready = false; - #endif + hw_ready = false; } #else hw_ready = true; @@ -1297,7 +1286,7 @@ void loop() { if (pmu_ready) update_pmu(); #endif - #if HAS_BLUETOOTH + #if HAS_BLUETOOTH || HAS_BLE == true if (!console_active && bt_ready) update_bt(); #endif } @@ -1329,7 +1318,7 @@ void buffer_serial() { uint8_t c = 0; - #if HAS_BLUETOOTH + #if HAS_BLUETOOTH || HAS_BLE == true while ( c < MAX_CYCLES && ( (bt_state != BT_STATE_CONNECTED && Serial.available()) || (bt_state == BT_STATE_CONNECTED && SerialBT.available()) ) @@ -1344,7 +1333,7 @@ void buffer_serial() { if (!fifo_isfull_locked(&serialFIFO)) { fifo_push_locked(&serialFIFO, Serial.read()); } - #elif HAS_BLUETOOTH + #elif HAS_BLUETOOTH || HAS_BLE == true if (bt_state == BT_STATE_CONNECTED) { if (!fifo_isfull(&serialFIFO)) { fifo_push(&serialFIFO, SerialBT.read()); diff --git a/Utilities.h b/Utilities.h index 5f9bdf7..9400367 100644 --- a/Utilities.h +++ b/Utilities.h @@ -47,7 +47,7 @@ sx128x *LoRa = &sx128x_modem; #include "Display.h" #endif -#if HAS_BLUETOOTH == true +#if HAS_BLUETOOTH == true || HAS_BLE == true void kiss_indicate_btpin(); #include "Bluetooth.h" #endif @@ -629,7 +629,7 @@ int8_t led_standby_direction = 0; #endif void serial_write(uint8_t byte) { - #if HAS_BLUETOOTH + #if HAS_BLUETOOTH || HAS_BLE == true if (bt_state != BT_STATE_CONNECTED) { Serial.write(byte); } else { @@ -829,7 +829,7 @@ void kiss_indicate_battery() { } void kiss_indicate_btpin() { - #if HAS_BLUETOOTH + #if HAS_BLUETOOTH || HAS_BLE == true serial_write(FEND); serial_write(CMD_BT_PIN); escaped_serial_write(bt_ssp_pin>>24);