kopia lustrzana https://github.com/pjalocha/esp32-ogn-tracker
Split off the Bluetooth serial port code to prepare for BLE
rodzic
0a985e4789
commit
c6f4f5204d
53
FollowMe.cfg
53
FollowMe.cfg
|
@ -4,9 +4,7 @@
|
|||
#define DEFAULT_PPSdelay 100
|
||||
#define DEFAULT_FreqPlan 0
|
||||
|
||||
|
||||
// #define WITH_HELTEC // HELTEC module: PCB LED on GPI025
|
||||
// #define WITH_HELTEC_V2 // HELTEC module v2
|
||||
// #define WITH_TTGO // TTGO module: PCB LED on GPIO2, GPIO25 free to use as DAC2 output
|
||||
// #define WITH_TBEAM // T-Beam module
|
||||
// #define WITH_TBEAM_V10 // T-Beam module
|
||||
|
@ -15,20 +13,19 @@
|
|||
|
||||
// #define WITH_ILI9341 // 320x240 M5stack
|
||||
// #define WITH_ST7789 // IPS 240x240 ST7789
|
||||
// #define WITH_TFT_LCD // TFT LCD
|
||||
// #define WITH_TFT_LCD // TFT LCD (incomplete)
|
||||
// #define WITH_OLED // OLED display on the I2C: some TTGO modules are without OLED display
|
||||
// #define WITH_OLED2 // 2nd OLED display, I2C address next higher
|
||||
#define WITH_U8G2_OLED // I2C OLED through the U8g2 library
|
||||
#define WITH_U8G2_SH1106 // correct controller for the bigger OLED
|
||||
#define WITH_U8G2_FLIP // flip the OLED screen (rotate by 180deg)
|
||||
#define WITH_U8G2_SH1106 // the bigger OLED controller
|
||||
#define WITH_U8G2_FLIP // flip the OLED screen
|
||||
|
||||
#define WITH_RFM95 // RF chip selection: both HELTEC and TTGO use sx1276 which is same as RFM95
|
||||
#define WITH_RFM95 // RF chip selection: FollowMe, HELTEC and TTGO use sx1276 which is same as RFM95 module
|
||||
|
||||
#define WITH_LORAWAN
|
||||
// #define WITH_SLEEP // with software sleep mode controlled by the long-press on the button
|
||||
|
||||
// #define WITH_AXP // with AXP192 power controller (T-BEAM V1.0)
|
||||
#define WITH_BQ // with BQ24295 power controller (FollowMe)
|
||||
#define WITH_BQ // with BQ24295 power controller (new FollowMe)
|
||||
|
||||
// #define WITH_LED_RX
|
||||
// #define WITH_LED_TX
|
||||
|
@ -43,21 +40,15 @@
|
|||
// #define WITH_MAVLINK
|
||||
|
||||
// #define WITH_GPS_UBX_PASS // to pass directly UBX packets to/from GPS
|
||||
// #define WITH_GPS_NMEA_PASS // to pass directly NMEA to/from GPS
|
||||
// #define WITH_GPS_NMEA_PASS // to pass directly NMEA to/from GPS
|
||||
|
||||
// #define WITH_BMP180 // BMP180 pressure sensor
|
||||
// #define WITH_BMP280 // BMP280 pressure sensor
|
||||
#define WITH_BME280 // BMP280 with humidity (but still works with BMP280)
|
||||
#define WITH_BME280 // BMP280 with humidity (still works with BMP280)
|
||||
// #define WITH_MS5607 // MS5607 pressure sensor
|
||||
// #define WITH_MS5611 // MS5611 pressure sensor
|
||||
|
||||
// #define WITH_BMX055 // BMX055 magnetic and IMU sensor
|
||||
|
||||
// #define WITH_FANET
|
||||
#define WITH_PFLAA // PFLAU and PFLAA for compatibility with XCsoar and LK8000
|
||||
// #define WITH_POGNT
|
||||
// #define WITH_GDL90
|
||||
// #define WITH_PGAV5
|
||||
#define WITH_PFLAA // $PFLAU and $PFLAA for compatibility with XCsoar and LK8000
|
||||
// #define WITH_POGNT // $POGNT for traffic info
|
||||
#define WITH_LOOKOUT
|
||||
|
||||
#define WITH_CONFIG // interpret the console input: $POGNS to change parameters
|
||||
|
@ -68,21 +59,27 @@
|
|||
// #define WITH_KNOB
|
||||
// #define WITH_VARIO
|
||||
|
||||
#define WITH_LORAWAN // LoRaWAN TTN connectivity
|
||||
// #define WITH_PAW // beta-code for PilotAware transmission
|
||||
// #define WITH_FANET // beta-code for FANET transmissions, but breaks LoRaWAN, to be improved
|
||||
|
||||
#define WITH_AP // create WiFi Access Point for data, setup and log files
|
||||
#define WITH_AP_BUTTON // activate Access Point only when button pressed at startup
|
||||
#define WITH_HTTP // HTTP server, works with AP and Stratux
|
||||
#define WITH_BT_SPP // (classic) Bluetooth serial port for smartphone/tablet link
|
||||
|
||||
// #define WITH_STRATUX // beta-code: connect to Stratux WiFi and send GPS and traffic info
|
||||
// #define WITH_APRS // alpha-code: attempt to connect to the wifi router for uploading the log files to APRS
|
||||
|
||||
#define WITH_SD // use the SD card in SPI mode and FAT file system
|
||||
#define WITH_SPIFFS_FAT
|
||||
#define WITH_SPIFFS // use SPIFFS file system in Flash
|
||||
#define WITH_SPIFFS_FAT // FAT system in internal flash
|
||||
#define WITH_LOG // log own positions and other received to SPIFFS
|
||||
#define WITH_SDLOG // log own position and other data to uSD card
|
||||
#define WITH_LOG // log own positions and other received to SPIFFS and possibly to uSD
|
||||
#define WITH_SDLOG //
|
||||
|
||||
// #define WITH_BT_SPP // Bluetooth serial port for smartphone/tablet link
|
||||
|
||||
// #define WITH_STRATUX // connect to Stratux as a client to send GPS and Pressure data
|
||||
#define WITH_AP // WiFi AcessPoint and TCP decoder port
|
||||
// #define WITH_APRS // attempt to connect to the wifi router and then APRS
|
||||
// #define WITH_ENCRYPT // Encrypt (optionally) the position
|
||||
|
||||
#if defined(WITH_STRATUX) || defined(WITH_APRS) || defined(WITH_AP)
|
||||
#define WITH_WIFI
|
||||
#endif
|
||||
|
||||
// #define WITH_ENCRYPT // Encrypt (optionally) the position
|
||||
|
||||
|
|
|
@ -17,14 +17,15 @@
|
|||
// #define WITH_OLED // OLED display on the I2C: some TTGO modules are without OLED display
|
||||
// #define WITH_OLED2 // 2nd OLED display, I2C address next higher
|
||||
#define WITH_U8G2_OLED // I2C OLED through the U8g2 library
|
||||
#define WITH_U8G2_FLIP
|
||||
#define WITH_U8G2_SH1106 // the bigger OLED controller
|
||||
#define WITH_U8G2_FLIP // flip the OLED screen
|
||||
|
||||
#define WITH_RFM95 // RF chip selection: both HELTEC and TTGO use sx1276 which is same as RFM95
|
||||
#define WITH_RFM95 // RF chip selection: FollowMe, HELTEC and TTGO use sx1276 which is same as RFM95 module
|
||||
|
||||
// #define WITH_SLEEP // with software sleep mode controlled by the long-press on the button
|
||||
|
||||
// #define WITH_AXP // with AXP192 power controller (T-BEAM V1.0)
|
||||
// #define WITH_BQ // with BQ24295 power controller (FollowMe)
|
||||
// #define WITH_BQ // with BQ24295 power controller (new FollowMe)
|
||||
|
||||
// #define WITH_LED_RX
|
||||
// #define WITH_LED_TX
|
||||
|
@ -39,15 +40,15 @@
|
|||
// #define WITH_MAVLINK
|
||||
|
||||
// #define WITH_GPS_UBX_PASS // to pass directly UBX packets to/from GPS
|
||||
// #define WITH_GPS_NMEA_PASS // to pass directly NMEA to/from GPS
|
||||
// #define WITH_GPS_NMEA_PASS // to pass directly NMEA to/from GPS
|
||||
|
||||
// #define WITH_BMP180 // BMP180 pressure sensor
|
||||
// #define WITH_BMP280 // BMP280 pressure sensor
|
||||
#define WITH_BME280 // BMP280 with humidity (but still works with BMP280)
|
||||
#define WITH_BME280 // BMP280 with humidity (still works with BMP280)
|
||||
// #define WITH_MS5607 // MS5607 pressure sensor
|
||||
|
||||
#define WITH_PFLAA // PFLAU and PFLAA for compatibility with XCsoar and LK8000
|
||||
// #define WITH_POGNT
|
||||
#define WITH_PFLAA // $PFLAU and $PFLAA for compatibility with XCsoar and LK8000
|
||||
// #define WITH_POGNT // $POGNT for traffic info
|
||||
#define WITH_LOOKOUT
|
||||
|
||||
#define WITH_CONFIG // interpret the console input: $POGNS to change parameters
|
||||
|
@ -58,20 +59,23 @@
|
|||
// #define WITH_KNOB
|
||||
// #define WITH_VARIO
|
||||
|
||||
#define WITH_LORAWAN
|
||||
#define WITH_LORAWAN // LoRaWAN TTN connectivity
|
||||
// #define WITH_PAW // beta-code for PilotAware transmission
|
||||
// #define WITH_FANET // beta-code for FANET transmissions, but breaks LoRaWAN, to be improved
|
||||
|
||||
#define WITH_AP // creat WiFi Access Point for data, setup and log files
|
||||
// #define WITH_STRATUX // connect to Stratux WiFi as a client
|
||||
// #define WITH_BT_SPP // Bluetooth serial port for smartphone/tablet link
|
||||
// #define WITH_APRS // attempt to connect to the wifi router for uploading the log files to APRS
|
||||
#define WITH_AP // create WiFi Access Point for data, setup and log files
|
||||
#define WITH_AP_BUTTON // activate Access Point only when button pressed at startup
|
||||
#define WITH_HTTP // HTTP server, works with AP and Stratux
|
||||
#define WITH_BT_SPP // (classic) Bluetooth serial port for smartphone/tablet link
|
||||
|
||||
#define WITH_HTTP // HTTP server, works with AP dna should work with Stratux as well
|
||||
// #define WITH_STRATUX // beta-code: connect to Stratux WiFi and send GPS and traffic info
|
||||
// #define WITH_APRS // alpha-code: attempt to connect to the wifi router for uploading the log files to APRS
|
||||
|
||||
#define WITH_SD // use the SD card in SPI mode and FAT file system
|
||||
#define WITH_SPIFFS_FAT
|
||||
#define WITH_SPIFFS // use SPIFFS file system in Flash
|
||||
#define WITH_LOG // log own positions and other received to SPIFFS and possibly to uSD
|
||||
#define WITH_SDLOG
|
||||
#define WITH_SDLOG //
|
||||
|
||||
// #define WITH_ENCRYPT // Encrypt (optionally) the position
|
||||
|
||||
|
|
|
@ -4,9 +4,7 @@
|
|||
#define DEFAULT_PPSdelay 100
|
||||
#define DEFAULT_FreqPlan 0
|
||||
|
||||
|
||||
// #define WITH_HELTEC // HELTEC module: PCB LED on GPI025
|
||||
// #define WITH_HELTEC_V2 // HELTEC module v2
|
||||
// #define WITH_TTGO // TTGO module: PCB LED on GPIO2, GPIO25 free to use as DAC2 output
|
||||
// #define WITH_TBEAM // T-Beam module
|
||||
#define WITH_TBEAM_V10 // T-Beam module
|
||||
|
@ -15,11 +13,10 @@
|
|||
|
||||
// #define WITH_ILI9341 // 320x240 M5stack
|
||||
// #define WITH_ST7789 // IPS 240x240 ST7789
|
||||
// #define WITH_TFT_LCD // TFT LCD
|
||||
// #define WITH_TFT_LCD // TFT LCD (incomplete)
|
||||
// #define WITH_OLED // OLED display on the I2C: some TTGO modules are without OLED display
|
||||
// #define WITH_OLED2 // 2nd OLED display, I2C address next higher
|
||||
// #define WITH_U8G2_OLED // I2C OLED through the U8g2 library
|
||||
// #define WITH_U8G2_SH1106
|
||||
|
||||
#define WITH_RFM95 // RF chip selection: both HELTEC and TTGO use sx1276 which is same as RFM95
|
||||
|
||||
|
@ -45,9 +42,8 @@
|
|||
|
||||
// #define WITH_BMP180 // BMP180 pressure sensor
|
||||
// #define WITH_BMP280 // BMP280 pressure sensor
|
||||
// #define WITH_BME280 // BMP280 with humidity (but still works with BMP280)
|
||||
#define WITH_BME280 // BMP280 with humidity (but still works with BMP280)
|
||||
// #define WITH_MS5607 // MS5607 pressure sensor
|
||||
// #define WITH_MS5611 // MS5611 pressure sensor
|
||||
|
||||
#define WITH_PFLAA // PFLAU and PFLAA for compatibility with XCsoar and LK8000
|
||||
// #define WITH_POGNT
|
||||
|
@ -55,21 +51,30 @@
|
|||
|
||||
#define WITH_CONFIG // interpret the console input: $POGNS to change parameters
|
||||
|
||||
// #define WITH_BEEPER // with digital buzzer
|
||||
#define WITH_BEEPER // with digital buzzer
|
||||
// #define WITH_SOUND // with analog sound produced by DAC on pin 25
|
||||
|
||||
// #define WITH_KNOB
|
||||
// #define WITH_VARIO
|
||||
|
||||
#define WITH_LORAWAN
|
||||
|
||||
#define WITH_AP // WiFi Access Point: can work together with BT_SPP
|
||||
#define WITH_AP_BUTTON // only starts when button pressed at sartup
|
||||
#define WITH_BT_SPP // Bluetooth serial port for smartphone/tablet link: can work together with WiFi Access point
|
||||
// #define WITH_STRATUX // beta-code: connect to Stratux WiFi and serve as GPS and OGN transmitter/receiver
|
||||
// #define WITH_APRS // alpha-code: attempt to connect to the wifi router for uploading the log files to APRS
|
||||
|
||||
#define WITH_HTTP // HTTP server, works with AP dna should work with Stratux as well
|
||||
|
||||
// #define WITH_SD // use the SD card in SPI mode and FAT file system
|
||||
#define WITH_SPIFFS_FAT
|
||||
#define WITH_SPIFFS // use SPIFFS file system in Flash
|
||||
#define WITH_LOG // log own positions and other received to SPIFFS and possibly to uSD
|
||||
|
||||
// #define WITH_STRATUX
|
||||
#define WITH_BT_SPP // Bluetooth serial port for smartphone/tablet link
|
||||
// #define WITH_WIFI // attempt to connect to the wifi router for uploading the log files
|
||||
// #define WITH_SPIFFS_LOG // log transmitted and received packets to SPIFFS
|
||||
|
||||
// #define WITH_ENCRYPT // Encrypt (optionally) the position
|
||||
|
||||
#if defined(WITH_STRATUX) || defined(WITH_APRS) || defined(WITH_AP)
|
||||
#define WITH_WIFI
|
||||
#endif
|
||||
|
||||
|
|
|
@ -59,10 +59,11 @@
|
|||
|
||||
#define WITH_LORAWAN
|
||||
|
||||
#define WITH_AP
|
||||
// #define WITH_STRATUX
|
||||
// #define WITH_BT_SPP // Bluetooth serial port for smartphone/tablet link
|
||||
// #define WITH_APRS // attempt to connect to the wifi router for uploading the log files to APRS
|
||||
#define WITH_AP // WiFi Access Point: can work together with BT_SPP
|
||||
#define WITH_AP_BUTTON // only starts when button pressed at sartup
|
||||
#define WITH_BT_SPP // Bluetooth serial port for smartphone/tablet link: can work together with WiFi Access point
|
||||
// #define WITH_STRATUX // beta-code: connect to Stratux WiFi and serve as GPS and OGN transmitter/receiver
|
||||
// #define WITH_APRS // alpha-code: attempt to connect to the wifi router for uploading the log files to APRS
|
||||
|
||||
#define WITH_HTTP // HTTP server, works with AP dna should work with Stratux as well
|
||||
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
|
||||
// ~/esp-idf/components/bt/bluedroid/api/include/esp_spp_api.h
|
||||
// esp_err_t esp_spp_write(uint32_t handle, int len, uint8_t *p_data);
|
||||
|
||||
// #ifdef WITH_BT_SPP
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#include "esp_bt.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "esp_gap_bt_api.h"
|
||||
#include "esp_bt_device.h"
|
||||
#include "esp_spp_api.h"
|
||||
|
||||
#include "format.h"
|
||||
#include "fifo.h"
|
||||
|
||||
static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_CB;
|
||||
static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_AUTHENTICATE;
|
||||
static const esp_spp_role_t role_slave = ESP_SPP_ROLE_SLAVE;
|
||||
|
||||
static FIFO<char, 1024> BT_SPP_TxFIFO; // buffer for console output to be sent over BT
|
||||
static FIFO<uint8_t, 256> BT_SPP_RxFIFO; // buffer for BT data to be send to the console
|
||||
static uint32_t BT_SPP_Conn = 0; // BT incoming connection handle
|
||||
static uint32_t BT_SPP_TxCong = 0; // congestion control
|
||||
// static TickType_t BT_SPP_LastTxPush=0; // [ms]
|
||||
|
||||
// static esp_bd_addr_t BT_SPP_MAC; // BT incoming connection MAC - could be used for pilot id in the flight log
|
||||
// static uint32_t BT_SPP_Wait = 0; // bytes waiting to be written into BT_SPP
|
||||
|
||||
// static const char *BT_SPP_Welcome = "ESP32 OGN-Tracker\n";
|
||||
|
||||
bool BT_SPP_isConnected(void) { return BT_SPP_Conn; } // is a client connected to BT_SPP ?
|
||||
|
||||
static void setPilotID(esp_bd_addr_t MAC, size_t Len=6) // set PilotID in the parameters from the BT SPP client MAC (thus Pilot's smartphone)
|
||||
{ char *ID = Parameters.PilotID;
|
||||
ID[0]='B'; ID[1]='T'; ID[2]='_'; ID+=3;
|
||||
for(int Idx=0; Idx<Len; Idx++)
|
||||
{ Format_Hex(ID, MAC[Idx]); ID+=2; }
|
||||
ID[0]=0; }
|
||||
|
||||
static void clrPilotID(void) // clear the Pilot_ID when BT SPP gets disconnected
|
||||
{ Parameters.PilotID[0]=0; }
|
||||
|
||||
static size_t BT_SPP_TxPush(size_t MaxLen=128) // transmit part of the TxFIFO to the BT link
|
||||
{ // BT_SPP_LastTxPush = xTaskGetTickCount(); // [ms] remember last time the TxPush was done
|
||||
char *Data; size_t Len=BT_SPP_TxFIFO.getReadBlock(Data); // see how much data is there in the queue for transmission
|
||||
if(Len==0) return 0; // if block is empty then give up
|
||||
if(Len>MaxLen) Len=MaxLen; // limit the block size
|
||||
esp_err_t Ret=esp_spp_write(BT_SPP_Conn, Len, (uint8_t *)Data); // write the block to the BT
|
||||
if(Ret!=ESP_OK) return 0; // if an error then give up
|
||||
BT_SPP_TxFIFO.flushReadBlock(Len); // remove the transmitted block from the FIFO
|
||||
return Len; } // return number of transmitted bytes
|
||||
|
||||
static void esp_spp_cb(esp_spp_cb_event_t Event, esp_spp_cb_param_t *Param)
|
||||
{ switch (Event)
|
||||
{ case ESP_SPP_INIT_EVT: // [0]
|
||||
esp_bt_dev_set_device_name(Parameters.BTname);
|
||||
// esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); // for older ESP-IDF
|
||||
esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
|
||||
esp_spp_start_srv(sec_mask, role_slave, 0, "SPP_SERVER");
|
||||
break;
|
||||
case ESP_SPP_DISCOVERY_COMP_EVT: // [8]
|
||||
break;
|
||||
case ESP_SPP_START_EVT: // [28] SPP server started succesfully
|
||||
break;
|
||||
case ESP_SPP_SRV_OPEN_EVT: // [34] server connection opens: new handle comes
|
||||
BT_SPP_TxFIFO.Clear(); // clear the TxFIFO
|
||||
BT_SPP_Conn = Param->srv_open.handle; // store handle for esp_spp_write()
|
||||
BT_SPP_TxCong = 0; // assume no congestion
|
||||
setPilotID(Param->srv_open.rem_bda, sizeof(esp_bd_addr_t)); // PilotID is now taken from the connected BT client
|
||||
// memcpy(BT_SPP_MAC, Param->srv_open.rem_bda, sizeof(esp_bd_addr_t));
|
||||
// esp_spp_write(Param->srv_open.handle, BT_SPP_Wait, (uint8_t *)BT_SPP_Welcome); // write Welcome message to the BT_SPP
|
||||
#ifdef DEBUG_PRINT
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
Format_String(CONS_UART_Write, "BT_SPP: ");
|
||||
Format_MAC(CONS_UART_Write, Param->srv_open.rem_bda, sizeof(esp_bd_addr_t));
|
||||
Format_String(CONS_UART_Write, " connected\n");
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
#endif
|
||||
break;
|
||||
case ESP_SPP_OPEN_EVT: // [26] connection opens: what's the difference to ESP_SPP_SRV_OPEN_EVT ?
|
||||
// Param->open.handle, Param->open.rem_bda
|
||||
break;
|
||||
case ESP_SPP_CLOSE_EVT: // [27] connection closes for given handle
|
||||
BT_SPP_Conn=0; // clear the handle: signal the BT connection is off
|
||||
clrPilotID();
|
||||
#ifdef DEBUG_PRINT
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
Format_String(CONS_UART_Write, "BT_SPP: \n");
|
||||
// Format_MAC(CONS_UART_Write, BT_SPP_MAC);
|
||||
Format_String(CONS_UART_Write, " disconnected\n");
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
#endif
|
||||
break;
|
||||
case ESP_SPP_DATA_IND_EVT: // [30] data is sent by the client
|
||||
BT_SPP_RxFIFO.Write(Param->data_ind.data, Param->data_ind.len);
|
||||
#ifdef DEBUG_PRINT
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
// Param->data_ind.handle, Param->data_ind.data, Param->data_ind.len
|
||||
Format_String(CONS_UART_Write, "BT_SPP: [");
|
||||
Format_UnsDec(CONS_UART_Write, Param->data_ind.len);
|
||||
Format_String(CONS_UART_Write, "]\n");
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
#endif
|
||||
break;
|
||||
case ESP_SPP_CONG_EVT: // [31] congestion on the outgoing data
|
||||
BT_SPP_TxCong = Param->cong.cong;
|
||||
break;
|
||||
case ESP_SPP_WRITE_EVT: // [33] (queued) data has been sent to the client
|
||||
BT_SPP_TxCong = Param->write.cong;
|
||||
break;
|
||||
default:
|
||||
#ifdef DEBUG_PRINT
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
Format_String(CONS_UART_Write, "BT_SPP: Event ");
|
||||
Format_UnsDec(CONS_UART_Write, (uint32_t)Event);
|
||||
Format_String(CONS_UART_Write, "\n");
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void esp_bt_gap_cb(esp_bt_gap_cb_event_t Event, esp_bt_gap_cb_param_t *Param)
|
||||
{
|
||||
switch (Event) // event numbers are in esp-idf/components/bt/bluedroid/api/include/api/esp_gap_bt_api.h
|
||||
{
|
||||
case ESP_BT_GAP_AUTH_CMPL_EVT:
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
if (Param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS)
|
||||
{ Format_String(CONS_UART_Write, "BT_GAP: ");
|
||||
Format_String(CONS_UART_Write, (const char *)Param->auth_cmpl.device_name);
|
||||
Format_String(CONS_UART_Write, " authenticated\n"); }
|
||||
else
|
||||
{ Format_String(CONS_UART_Write, "BT_GAP: Authentication failure (");
|
||||
Format_SignDec(CONS_UART_Write, Param->auth_cmpl.stat);
|
||||
Format_String(CONS_UART_Write, ")\n"); }
|
||||
// ESP_LOGI(SPP_TAG, "authentication success: %s", param->auth_cmpl.device_name);
|
||||
// esp_log_buffer_hex(SPP_TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN);
|
||||
// ESP_LOGE(SPP_TAG, "authentication failed, status:%d", param->auth_cmpl.stat);
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
break;
|
||||
case ESP_BT_GAP_PIN_REQ_EVT:
|
||||
/*
|
||||
ESP_LOGI(SPP_TAG, "ESP_BT_GAP_PIN_REQ_EVT min_16_digit:%d", param->pin_req.min_16_digit);
|
||||
if (param->pin_req.min_16_digit) {
|
||||
ESP_LOGI(SPP_TAG, "Input pin code: 0000 0000 0000 0000");
|
||||
esp_bt_pin_code_t pin_code = {0};
|
||||
esp_bt_gap_pin_reply(param->pin_req.bda, true, 16, pin_code);
|
||||
} else {
|
||||
ESP_LOGI(SPP_TAG, "Input pin code: 1234");
|
||||
esp_bt_pin_code_t pin_code;
|
||||
pin_code[0] = '1';
|
||||
pin_code[1] = '2';
|
||||
pin_code[2] = '3';
|
||||
pin_code[3] = '4';
|
||||
esp_bt_gap_pin_reply(param->pin_req.bda, true, 4, pin_code);
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
Format_String(CONS_UART_Write, "BT_GAP: Event ");
|
||||
Format_UnsDec(CONS_UART_Write, (uint32_t)Event);
|
||||
Format_String(CONS_UART_Write, "\n");
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
}
|
||||
|
||||
int BT_SPP_Read (uint8_t &Byte) // read a character from the BT serial port (buffer)
|
||||
{ // if(!BT_SPP_Conn) return 0;
|
||||
return BT_SPP_RxFIFO.Read(Byte); }
|
||||
|
||||
void BT_SPP_Write (char Byte) // send a character to the BT serial port
|
||||
{ if(!BT_SPP_Conn) return; // if BT connection is active
|
||||
BT_SPP_TxFIFO.Write(Byte); // write the byte into the TxFIFO
|
||||
// TickType_t Behind = xTaskGetTickCount() - BT_SPP_LastTxPush; // [ms]
|
||||
// if(Behind>=20) BT_SPP_TxPush();
|
||||
if( (BT_SPP_TxCong==0) && ( (Byte=='\n') || (BT_SPP_TxFIFO.Full()>=64) ) ) // if no congestion and EOL or 64B waiting already
|
||||
{ BT_SPP_TxPush(); } // read a block from TxFIFO ad push it into the BT_SPP
|
||||
}
|
||||
|
||||
int BT_SPP_Init(void)
|
||||
{ esp_err_t Err=ESP_OK;
|
||||
if(Parameters.BTname[0]==0) return Err;
|
||||
|
||||
esp_bt_controller_config_t BTconf = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); // the default mode is defined by the menuconfig settings
|
||||
Err = esp_bt_controller_mem_release(ESP_BT_MODE_BLE);
|
||||
Err = esp_bt_controller_init(&BTconf); if(Err!=ESP_OK) return Err;
|
||||
Err = esp_bt_controller_enable((esp_bt_mode_t)BTconf.mode); if(Err!=ESP_OK) return Err; // mode must be same as in BTconf
|
||||
Err = esp_bluedroid_init(); if(Err!=ESP_OK) return Err; // init the BT stack
|
||||
Err = esp_bluedroid_enable(); if(Err!=ESP_OK) return Err; // enable the BT stack
|
||||
Err = esp_bt_gap_register_callback(esp_bt_gap_cb); if(Err!=ESP_OK) return Err;
|
||||
Err = esp_spp_register_callback(esp_spp_cb); if(Err!=ESP_OK) return Err;
|
||||
Err = esp_spp_init(esp_spp_mode); if(Err!=ESP_OK) return Err;
|
||||
|
||||
// Set default parameters for Secure Simple Pairing */
|
||||
esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
|
||||
esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_NONE; // _IO;
|
||||
esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
|
||||
|
||||
// Set default parameters for Legacy Pairing: fixed PIN
|
||||
esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_FIXED;
|
||||
esp_bt_pin_code_t pin_code = { '0', '1', '2', '3' };
|
||||
esp_bt_gap_set_pin(pin_type, 4, pin_code);
|
||||
|
||||
// set the UUID so this BT device is recognized as a serial port: thanks to Linar for this code
|
||||
esp_bt_cod_t cod;
|
||||
cod.minor = 0b000101;
|
||||
cod.major = 0b00001;
|
||||
cod.service = 0b00000001101; // 0b00000001101 = serial port, 0b00000010000 = generic
|
||||
esp_bt_gap_set_cod(cod, ESP_BT_INIT_COD);
|
||||
|
||||
return Err; }
|
||||
|
||||
// #endif // WITH_BT_SPP
|
||||
|
||||
// ========================================================================================================
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef __BT_H__
|
||||
#define __BT_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
int BT_SPP_Init(void);
|
||||
bool BT_SPP_isConnected(void);
|
||||
int BT_SPP_Read (uint8_t &Byte);
|
||||
void BT_SPP_Write (char Byte);
|
||||
|
||||
#endif // __BT_H__
|
|
@ -23,6 +23,10 @@
|
|||
#include "wifi.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_BT_SPP
|
||||
#include "bt.h"
|
||||
#endif
|
||||
|
||||
#include "gps.h"
|
||||
// #include "ubx.h"
|
||||
// #include "timesync.h"
|
||||
|
|
222
main/hal.cpp
222
main/hal.cpp
|
@ -16,6 +16,10 @@
|
|||
#include "esp_system.h"
|
||||
#include "esp_freertos_hooks.h"
|
||||
|
||||
#ifdef WITH_BT_SPP
|
||||
#include "bt.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_LORAWAN
|
||||
#include "lorawan.h"
|
||||
#endif
|
||||
|
@ -40,15 +44,6 @@
|
|||
#include "sdmmc_cmd.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_BT_SPP
|
||||
#include "esp_bt.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "esp_gap_bt_api.h"
|
||||
#include "esp_bt_device.h"
|
||||
#include "esp_spp_api.h"
|
||||
#include "fifo.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_AP
|
||||
#include "ap.h"
|
||||
#endif
|
||||
|
@ -642,215 +637,6 @@ bool Button_isPressed(void) { return !gpio_get_level(PIN_BUTTON); }
|
|||
|
||||
// ========================================================================================================
|
||||
|
||||
// ~/esp-idf/components/bt/bluedroid/api/include/esp_spp_api.h
|
||||
// esp_err_t esp_spp_write(uint32_t handle, int len, uint8_t *p_data);
|
||||
|
||||
#ifdef WITH_BT_SPP
|
||||
|
||||
static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_CB;
|
||||
static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_AUTHENTICATE;
|
||||
static const esp_spp_role_t role_slave = ESP_SPP_ROLE_SLAVE;
|
||||
|
||||
static FIFO<char, 1024> BT_SPP_TxFIFO; // buffer for console output to be sent over BT
|
||||
static FIFO<uint8_t, 256> BT_SPP_RxFIFO; // buffer for BT data to be send to the console
|
||||
static uint32_t BT_SPP_Conn = 0; // BT incoming connection handle
|
||||
static uint32_t BT_SPP_TxCong = 0; // congestion control
|
||||
// static TickType_t BT_SPP_LastTxPush=0; // [ms]
|
||||
|
||||
// static esp_bd_addr_t BT_SPP_MAC; // BT incoming connection MAC - could be used for pilot id in the flight log
|
||||
// static uint32_t BT_SPP_Wait = 0; // bytes waiting to be written into BT_SPP
|
||||
|
||||
// static const char *BT_SPP_Welcome = "ESP32 OGN-Tracker\n";
|
||||
|
||||
bool BT_SPP_isConnected(void) { return BT_SPP_Conn; } // is a client conencted to BT_SPP ?
|
||||
|
||||
static void setPilotID(esp_bd_addr_t MAC, size_t Len=6) // set PilotID in the parameters from the BT SPP client MAC (thus Pilot's smartphone)
|
||||
{ char *ID = Parameters.PilotID;
|
||||
ID[0]='B'; ID[1]='T'; ID[2]='_'; ID+=3;
|
||||
for(int Idx=0; Idx<Len; Idx++)
|
||||
{ Format_Hex(ID, MAC[Idx]); ID+=2; }
|
||||
ID[0]=0; }
|
||||
|
||||
static void clrPilotID(void) // clear the Pilot_ID when BT SPP gets disconnected
|
||||
{ Parameters.PilotID[0]=0; }
|
||||
|
||||
static size_t BT_SPP_TxPush(size_t MaxLen=128) // transmit part of the TxFIFO to the BT link
|
||||
{ // BT_SPP_LastTxPush = xTaskGetTickCount(); // [ms] remember last time the TxPush was done
|
||||
char *Data; size_t Len=BT_SPP_TxFIFO.getReadBlock(Data); // see how much data is there in the queue for transmission
|
||||
if(Len==0) return 0; // if block is empty then give up
|
||||
if(Len>MaxLen) Len=MaxLen; // limit the block size
|
||||
esp_err_t Ret=esp_spp_write(BT_SPP_Conn, Len, (uint8_t *)Data); // write the block to the BT
|
||||
if(Ret!=ESP_OK) return 0; // if an error then give up
|
||||
BT_SPP_TxFIFO.flushReadBlock(Len); // remove the transmitted block from the FIFO
|
||||
return Len; } // return number of transmitted bytes
|
||||
|
||||
static void esp_spp_cb(esp_spp_cb_event_t Event, esp_spp_cb_param_t *Param)
|
||||
{ switch (Event)
|
||||
{ case ESP_SPP_INIT_EVT: // [0]
|
||||
esp_bt_dev_set_device_name(Parameters.BTname);
|
||||
// esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); // for older ESP-IDF
|
||||
esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
|
||||
esp_spp_start_srv(sec_mask, role_slave, 0, "SPP_SERVER");
|
||||
break;
|
||||
case ESP_SPP_DISCOVERY_COMP_EVT: // [8]
|
||||
break;
|
||||
case ESP_SPP_START_EVT: // [28] SPP server started succesfully
|
||||
break;
|
||||
case ESP_SPP_SRV_OPEN_EVT: // [34] server connection opens: new handle comes
|
||||
BT_SPP_TxFIFO.Clear(); // clear the TxFIFO
|
||||
BT_SPP_Conn = Param->srv_open.handle; // store handle for esp_spp_write()
|
||||
BT_SPP_TxCong = 0; // assume no congestion
|
||||
setPilotID(Param->srv_open.rem_bda, sizeof(esp_bd_addr_t)); // PilotID is now taken from the connected BT client
|
||||
// memcpy(BT_SPP_MAC, Param->srv_open.rem_bda, sizeof(esp_bd_addr_t));
|
||||
// esp_spp_write(Param->srv_open.handle, BT_SPP_Wait, (uint8_t *)BT_SPP_Welcome); // write Welcome message to the BT_SPP
|
||||
#ifdef DEBUG_PRINT
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
Format_String(CONS_UART_Write, "BT_SPP: ");
|
||||
Format_MAC(CONS_UART_Write, Param->srv_open.rem_bda, sizeof(esp_bd_addr_t));
|
||||
Format_String(CONS_UART_Write, " connected\n");
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
#endif
|
||||
break;
|
||||
case ESP_SPP_OPEN_EVT: // [26] connection opens: what's the difference to ESP_SPP_SRV_OPEN_EVT ?
|
||||
// Param->open.handle, Param->open.rem_bda
|
||||
break;
|
||||
case ESP_SPP_CLOSE_EVT: // [27] connection closes for given handle
|
||||
BT_SPP_Conn=0; // clear the handle: signal the BT connection is off
|
||||
clrPilotID();
|
||||
#ifdef DEBUG_PRINT
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
Format_String(CONS_UART_Write, "BT_SPP: \n");
|
||||
// Format_MAC(CONS_UART_Write, BT_SPP_MAC);
|
||||
Format_String(CONS_UART_Write, " disconnected\n");
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
#endif
|
||||
break;
|
||||
case ESP_SPP_DATA_IND_EVT: // [30] data is sent by the client
|
||||
BT_SPP_RxFIFO.Write(Param->data_ind.data, Param->data_ind.len);
|
||||
#ifdef DEBUG_PRINT
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
// Param->data_ind.handle, Param->data_ind.data, Param->data_ind.len
|
||||
Format_String(CONS_UART_Write, "BT_SPP: [");
|
||||
Format_UnsDec(CONS_UART_Write, Param->data_ind.len);
|
||||
Format_String(CONS_UART_Write, "]\n");
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
#endif
|
||||
break;
|
||||
case ESP_SPP_CONG_EVT: // [31] congestion on the outgoing data
|
||||
BT_SPP_TxCong = Param->cong.cong;
|
||||
break;
|
||||
case ESP_SPP_WRITE_EVT: // [33] (queued) data has been sent to the client
|
||||
BT_SPP_TxCong = Param->write.cong;
|
||||
break;
|
||||
default:
|
||||
#ifdef DEBUG_PRINT
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
Format_String(CONS_UART_Write, "BT_SPP: Event ");
|
||||
Format_UnsDec(CONS_UART_Write, (uint32_t)Event);
|
||||
Format_String(CONS_UART_Write, "\n");
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void esp_bt_gap_cb(esp_bt_gap_cb_event_t Event, esp_bt_gap_cb_param_t *Param)
|
||||
{
|
||||
switch (Event) // event numbers are in esp-idf/components/bt/bluedroid/api/include/api/esp_gap_bt_api.h
|
||||
{
|
||||
case ESP_BT_GAP_AUTH_CMPL_EVT:
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
if (Param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS)
|
||||
{ Format_String(CONS_UART_Write, "BT_GAP: ");
|
||||
Format_String(CONS_UART_Write, (const char *)Param->auth_cmpl.device_name);
|
||||
Format_String(CONS_UART_Write, " authenticated\n"); }
|
||||
else
|
||||
{ Format_String(CONS_UART_Write, "BT_GAP: Authentication failure (");
|
||||
Format_SignDec(CONS_UART_Write, Param->auth_cmpl.stat);
|
||||
Format_String(CONS_UART_Write, ")\n"); }
|
||||
// ESP_LOGI(SPP_TAG, "authentication success: %s", param->auth_cmpl.device_name);
|
||||
// esp_log_buffer_hex(SPP_TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN);
|
||||
// ESP_LOGE(SPP_TAG, "authentication failed, status:%d", param->auth_cmpl.stat);
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
break;
|
||||
case ESP_BT_GAP_PIN_REQ_EVT:
|
||||
/*
|
||||
ESP_LOGI(SPP_TAG, "ESP_BT_GAP_PIN_REQ_EVT min_16_digit:%d", param->pin_req.min_16_digit);
|
||||
if (param->pin_req.min_16_digit) {
|
||||
ESP_LOGI(SPP_TAG, "Input pin code: 0000 0000 0000 0000");
|
||||
esp_bt_pin_code_t pin_code = {0};
|
||||
esp_bt_gap_pin_reply(param->pin_req.bda, true, 16, pin_code);
|
||||
} else {
|
||||
ESP_LOGI(SPP_TAG, "Input pin code: 1234");
|
||||
esp_bt_pin_code_t pin_code;
|
||||
pin_code[0] = '1';
|
||||
pin_code[1] = '2';
|
||||
pin_code[2] = '3';
|
||||
pin_code[3] = '4';
|
||||
esp_bt_gap_pin_reply(param->pin_req.bda, true, 4, pin_code);
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
Format_String(CONS_UART_Write, "BT_GAP: Event ");
|
||||
Format_UnsDec(CONS_UART_Write, (uint32_t)Event);
|
||||
Format_String(CONS_UART_Write, "\n");
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
}
|
||||
|
||||
static int BT_SPP_Read (uint8_t &Byte) // read a character from the BT serial port (buffer)
|
||||
{ // if(!BT_SPP_Conn) return 0;
|
||||
return BT_SPP_RxFIFO.Read(Byte); }
|
||||
|
||||
static void BT_SPP_Write (char Byte) // send a character to the BT serial port
|
||||
{ if(!BT_SPP_Conn) return; // if BT connection is active
|
||||
BT_SPP_TxFIFO.Write(Byte); // write the byte into the TxFIFO
|
||||
// TickType_t Behind = xTaskGetTickCount() - BT_SPP_LastTxPush; // [ms]
|
||||
// if(Behind>=20) BT_SPP_TxPush();
|
||||
if( (BT_SPP_TxCong==0) && ( (Byte=='\n') || (BT_SPP_TxFIFO.Full()>=64) ) ) // if no congestion and EOL or 64B waiting already
|
||||
{ BT_SPP_TxPush(); } // read a block from TxFIFO ad push it into the BT_SPP
|
||||
}
|
||||
|
||||
int BT_SPP_Init(void)
|
||||
{ esp_err_t Err=ESP_OK;
|
||||
if(Parameters.BTname[0]==0) return Err;
|
||||
|
||||
esp_bt_controller_config_t BTconf = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); // the default mode is defined by the menuconfig settings
|
||||
Err = esp_bt_controller_mem_release(ESP_BT_MODE_BLE);
|
||||
Err = esp_bt_controller_init(&BTconf); if(Err!=ESP_OK) return Err;
|
||||
Err = esp_bt_controller_enable((esp_bt_mode_t)BTconf.mode); if(Err!=ESP_OK) return Err; // mode must be same as in BTconf
|
||||
Err = esp_bluedroid_init(); if(Err!=ESP_OK) return Err; // init the BT stack
|
||||
Err = esp_bluedroid_enable(); if(Err!=ESP_OK) return Err; // enable the BT stack
|
||||
Err = esp_bt_gap_register_callback(esp_bt_gap_cb); if(Err!=ESP_OK) return Err;
|
||||
Err = esp_spp_register_callback(esp_spp_cb); if(Err!=ESP_OK) return Err;
|
||||
Err = esp_spp_init(esp_spp_mode); if(Err!=ESP_OK) return Err;
|
||||
|
||||
// Set default parameters for Secure Simple Pairing */
|
||||
esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
|
||||
esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_NONE; // _IO;
|
||||
esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
|
||||
|
||||
// Set default parameters for Legacy Pairing: fixed PIN
|
||||
esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_FIXED;
|
||||
esp_bt_pin_code_t pin_code = { '0', '1', '2', '3' };
|
||||
esp_bt_gap_set_pin(pin_type, 4, pin_code);
|
||||
|
||||
// set the UUID so this BT device is recognized as a serial port: thanks to Linar for this code
|
||||
esp_bt_cod_t cod;
|
||||
cod.minor = 0b000101;
|
||||
cod.major = 0b00001;
|
||||
cod.service = 0b00000001101; // 0b00000001101 = serial port, 0b00000010000 = generic
|
||||
esp_bt_gap_set_cod(cod, ESP_BT_INIT_COD);
|
||||
|
||||
return Err; }
|
||||
|
||||
#endif // WITH_BT_SPP
|
||||
|
||||
// ========================================================================================================
|
||||
|
||||
// Console UART
|
||||
|
||||
SemaphoreHandle_t CONS_Mutex;
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
|
||||
#include "fifo.h"
|
||||
|
||||
#ifdef WITH_BT_SPP
|
||||
#include "bt.h"
|
||||
#endif
|
||||
|
||||
// ============================================================================================================
|
||||
|
||||
#define WITH_ESP32
|
||||
|
@ -186,11 +190,6 @@ void IO_Configuration(void); // Configure I/O
|
|||
|
||||
int NVS_Init(void); // initialize non-volatile-storage in the Flash
|
||||
|
||||
#ifdef WITH_BT_SPP
|
||||
int BT_SPP_Init(void);
|
||||
bool BT_SPP_isConnected(void);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_SPIFFS
|
||||
int SPIFFS_Register(const char *Path="/spiffs", const char *Label="intlog", size_t MaxOpenFiles=5);
|
||||
int SPIFFS_Info(size_t &Total, size_t &Used, const char *Label="intlog");
|
||||
|
|
|
@ -28,6 +28,10 @@
|
|||
#include "stratux.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_BT_SPP
|
||||
#include "bt.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_AP
|
||||
#include "ap.h"
|
||||
#endif
|
||||
|
|
|
@ -124,7 +124,7 @@ class FlashParameters
|
|||
// char Copilot[16]
|
||||
// char Category[16]
|
||||
|
||||
uint32_t PageMask;
|
||||
uint32_t PageMask; // enable/disable individual pages on the LCD or OLED screen
|
||||
|
||||
#ifdef WITH_BT_SPP
|
||||
char BTname[16];
|
||||
|
|
Ładowanie…
Reference in New Issue