diff --git a/Bluetooth.h b/Bluetooth.h index e9a07e3..cd5e1d0 100644 --- a/Bluetooth.h +++ b/Bluetooth.h @@ -29,10 +29,12 @@ #elif MCU_VARIANT == MCU_NRF52 #include #include - BLEUart SerialBT; + #define BLE_MTU 512+3 + BLEUart SerialBT(BLE_MTU); BLEDis bledis; BLEBas blebas; bool SerialBT_init = false; + extern void led_indicate_info(int); #endif #define BT_PAIRING_TIMEOUT 35000 @@ -442,7 +444,7 @@ char bt_devname[11]; cable_state = CABLE_STATE_DISCONNECTED; BLEConnection* conn = Bluefruit.Connection(conn_handle); conn->requestPHY(BLE_GAP_PHY_2MBPS); - conn->requestMtuExchange(512+3); + conn->requestMtuExchange(BLE_MTU); conn->requestDataLengthUpdate(); } @@ -509,10 +511,9 @@ void bt_disconnect_callback(uint16_t conn_handle, uint8_t reason) { // start device information service bledis.begin(); + // Guard to ensure SerialBT service is not duplicated through BT being power cycled if (!SerialBT_init) { - SerialBT.bufferTXD(true); // enable buffering - SerialBT.setPermission(SECMODE_ENC_WITH_MITM, SECMODE_ENC_WITH_MITM); // enable encryption for BLE serial SerialBT.begin(); SerialBT_init = true; diff --git a/Boards.h b/Boards.h index 17e7e73..cf9ab57 100644 --- a/Boards.h +++ b/Boards.h @@ -82,7 +82,7 @@ #define MODEL_A1 0xA1 // T3S3 SX1262 868/915 MHz #define MODEL_AB 0xAB // T3S3 SX1276 868/915 MHz #define MODEL_A5 0xA5 // T3S3 SX1278 433 MHz - #define MODEL_AB 0xAB // T3S3 SX1280 2.4 GHz w/ PA + #define MODEL_AC 0xAC // T3S3 SX1280 2.4 GHz w/ PA #define PRODUCT_TECHO 0x15 // LilyGO T-Echo devices #define BOARD_TECHO 0x43 @@ -727,7 +727,7 @@ -1 // pin_tcxo_enable } }; - #elif BOARD_VARIANT == MODEL_AB // SX1280 with PA + #elif BOARD_VARIANT == MODEL_AC // SX1280 with PA const uint8_t interfaces[INTERFACE_COUNT] = {SX1280}; const bool interface_cfg[INTERFACE_COUNT][3] = { // SX1280 diff --git a/Config.h b/Config.h index 66c6284..5d15274 100644 --- a/Config.h +++ b/Config.h @@ -90,7 +90,7 @@ uint8_t last_rssi_raw = 0x00; uint8_t last_snr_raw = 0x80; uint8_t seq[INTERFACE_COUNT]; - uint16_t read_len = 0; + uint16_t read_len[INTERFACE_COUNT]; bool serial_in_frame = false; diff --git a/Display.h b/Display.h index c9f9b3f..ba27ea4 100644 --- a/Display.h +++ b/Display.h @@ -94,7 +94,7 @@ void busyCallback(const void* p) { #define SCL_OLED 17 #define SDA_OLED 18 #endif -#elif BOARD_MODEL == BOARD_OPENCOM_XL +#elif BOARD_MODEL == BOARD_RAK4631 || BOARD_MODEL == BOARD_OPENCOM_XL #if DISPLAY == OLED // RAK1921/SSD1306 #define DISP_RST -1 @@ -135,7 +135,7 @@ void busyCallback(const void* p) { #include "Graphics.h" -#if BOARD_MODEL == BOARD_OPENCOM_XL +#if BOARD_MODEL == BOARD_RAK4631 || BOARD_MODEL == BOARD_OPENCOM_XL #if DISPLAY == EINK_BW GxEPD2_BW display(DISPLAY_MODEL(pin_disp_cs, pin_disp_dc, pin_disp_reset, pin_disp_busy)); float disp_target_fps = 0.2; @@ -316,7 +316,7 @@ bool display_init() { // waiting for the display to update, it will poll the serial buffer to // check for any commands from the host. display.epd2.setBusyCallback(busyCallback); - #elif BOARD_MODEL == BOARD_OPENCOM_XL + #elif BOARD_MODEL == BOARD_RAK4631 || BOARD_MODEL == BOARD_OPENCOM_XL #if DISPLAY == OLED #elif DISPLAY == EINK_BW || DISPLAY == EINK_3C pinMode(pin_disp_en, INPUT_PULLUP); @@ -386,7 +386,7 @@ bool display_init() { #elif BOARD_MODEL == BOARD_HELTEC32_V2 disp_mode = DISP_MODE_PORTRAIT; display.setRotation(1); - #elif BOARD_MODEL == BOARD_OPENCOM_XL + #elif BOARD_MODEL == BOARD_RAK4631 || BOARD_MODEL == BOARD_OPENCOM_XL #if DISPLAY == OLED #elif DISPLAY == EINK_BW || DISPLAY == EINK_3C disp_mode = DISP_MODE_PORTRAIT; @@ -397,7 +397,7 @@ bool display_init() { #elif BOARD_MODEL == BOARD_HELTEC32_V3 disp_mode = DISP_MODE_PORTRAIT; display.setRotation(1); - #elif BOARD_MODEL == BOARD_RAK4631 + #elif BOARD_MODEL == BOARD_RAK4631 || BOARD_MODEL == BOARD_OPENCOM_XL disp_mode = DISP_MODE_LANDSCAPE; display.setRotation(0); #elif BOARD_MODEL == BOARD_TDECK diff --git a/Makefile b/Makefile index 8994971..b561d66 100644 --- a/Makefile +++ b/Makefile @@ -94,7 +94,7 @@ firmware-t3s3_sx126x: arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x42\" \"-DBOARD_VARIANT=0xA1\"" firmware-t3s3_sx1280_pa: - arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x42\" \"-DBOARD_VARIANT=0xAB\"" + arduino-cli compile --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc" $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x42\" \"-DBOARD_VARIANT=0xAC\"" firmware-e22_esp32: arduino-cli compile --fqbn esp32:esp32:esp32 $(COMMON_BUILD_FLAGS) --build-property "compiler.cpp.extra_flags=\"-DBOARD_MODEL=0x44\" \"-DEXTERNAL_LEDS=true\"" diff --git a/Power.h b/Power.h index e6d7ed6..40c7d9f 100644 --- a/Power.h +++ b/Power.h @@ -62,7 +62,7 @@ bool bat_voltage_dropping = false; float bat_delay_v = 0; float bat_state_change_v = 0; -#elif BOARD_MODEL == BOARD_OPENCOM_XL +#elif BOARD_MODEL == BOARD_RAK4631 || BOARD_MODEL == BOARD_OPENCOM_XL #include "nrfx_power.h" #define BAT_C_SAMPLES 7 #define BAT_D_SAMPLES 2 @@ -292,7 +292,7 @@ void measure_battery() { battery_ready = false; } - #elif BOARD_MODEL == BOARD_OPENCOM_XL + #elif BOARD_MODEL == BOARD_RAK4631 || BOARD_MODEL == BOARD_OPENCOM_XL battery_installed = true; battery_indeterminate = false; diff --git a/Radio.cpp b/Radio.cpp index 843c0dd..5693b52 100644 --- a/Radio.cpp +++ b/Radio.cpp @@ -110,6 +110,7 @@ void ISR_VECT onDio0Rise() { // Therefore, the modem is set into receive mode each time a packet is received. interface_obj[i]->receive(); } + break; } } taskEXIT_CRITICAL_FROM_ISR(int_status); @@ -740,7 +741,7 @@ void sx126x::sleep() void sx126x::enableTCXO() { if (_tcxo) { - #if BOARD_MODEL == BOARD_OPENCOM_XL || BOARD_MODEL == BOARD_HELTEC32_V3 + #if BOARD_MODEL == BOARD_RAK4631 || BOARD_MODEL == BOARD_OPENCOM_XL || BOARD_MODEL == BOARD_HELTEC32_V3 uint8_t buf[4] = {MODE_TCXO_3_3V_6X, 0x00, 0x00, 0xFF}; #elif BOARD_MODEL == BOARD_TBEAM uint8_t buf[4] = {MODE_TCXO_1_8V_6X, 0x00, 0x00, 0xFF}; @@ -2240,7 +2241,8 @@ void sx128x::disableTCXO() { void sx128x::setTxPower(int level, int outputPin) { uint8_t tx_buf[2]; - #if BOARD_VARIANT == MODEL_21 + #if BOARD_VARIANT == MODEL_13 || BOARD_VARIANT == MODEL_21 + // RAK4631 with WisBlock SX1280 module (LIBSYS002) if (level > 27) { level = 27; } else if (level < 0) { @@ -2346,7 +2348,7 @@ void sx128x::setTxPower(int level, int outputPin) { executeOpcode(OP_TX_PARAMS_8X, tx_buf, 2); - #elif BOARD_VARIANT == MODEL_AB + #elif BOARD_VARIANT == MODEL_AC // T3S3 SX1280 PA if (level > 20) { level = 20; diff --git a/Utilities.h b/Utilities.h index 7259b2c..0efc7c8 100644 --- a/Utilities.h +++ b/Utilities.h @@ -247,8 +247,7 @@ uint8_t boot_vector = 0x00; void led_rx_off() { analogWrite(pin_led_rx, 0); } void led_tx_on() { analogWrite(pin_led_tx, 1); } void led_tx_off() { analogWrite(pin_led_tx, 0); } - #endif - #if BOARD_MODEL == BOARD_RAK4631 + #elif BOARD_MODEL == BOARD_RAK4631 void led_rx_on() { digitalWrite(pin_led_rx, HIGH); } void led_rx_off() { digitalWrite(pin_led_rx, LOW); } void led_tx_on() { digitalWrite(pin_led_tx, HIGH); } @@ -1060,7 +1059,7 @@ void setTXPower(RadioInterface* radio, int txp) { if (model == MODEL_A8) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN); if (model == MODEL_A9) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN); if (model == MODEL_AA) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN); - if (model == MODEL_AB) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN); + if (model == MODEL_AC) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN); if (model == MODEL_B3) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN); if (model == MODEL_B4) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN); @@ -1438,6 +1437,8 @@ bool eeprom_model_valid() { if (model == MODEL_C4 || model == MODEL_C9) { #elif BOARD_MODEL == BOARD_HELTEC32_V3 if (model == MODEL_C5 || model == MODEL_CA) { + #elif BOARD_MODEL == BOARD_RAK4631 + if (model == MODEL_11 || model == MODEL_12 || model == MODEL_13 || model == MODEL_14) { #elif BOARD_MODEL == BOARD_OPENCOM_XL if (model == MODEL_21) { #elif BOARD_MODEL == BOARD_HUZZAH32 diff --git a/opencom_xl_firmware.ino b/opencom_xl_firmware.ino index 72094e1..301596b 100644 --- a/opencom_xl_firmware.ino +++ b/opencom_xl_firmware.ino @@ -19,7 +19,7 @@ #if MCU_VARIANT == MCU_NRF52 #define INTERFACE_SPI - #if BOARD_MODEL == BOARD_OPENCOM_XL + #if BOARD_MODEL == BOARD_RAK4631 || BOARD_MODEL == BOARD_OPENCOM_XL // Required because on RAK4631, non-default SPI pins must be initialised when class is declared. SPIClass interface_spi[1] = { // SX1262 @@ -172,6 +172,7 @@ void setup() { memset(packet_lengths_buf, 0, sizeof(packet_starts_buf)); memset(seq, 0xFF, sizeof(seq)); + memset(read_len, 0, sizeof(read_len)); modem_packet_queue = xQueueCreate(MODEM_QUEUE_SIZE, sizeof(modem_packet_t*)); @@ -359,7 +360,7 @@ inline void kiss_write_packet(int index) { // Add index of interface the packet came from serial_write(cmd_byte); - for (uint16_t i = 0; i < read_len; i++) { + for (uint16_t i = 0; i < read_len[index]; i++) { #if MCU_VARIANT == MCU_NRF52 portENTER_CRITICAL(); uint8_t byte = pbuf[i]; @@ -374,7 +375,7 @@ inline void kiss_write_packet(int index) { } serial_write(FEND); - read_len = 0; + read_len[index] = 0; #if MCU_VARIANT == MCU_ESP32 && HAS_BLE bt_flush(); @@ -382,14 +383,15 @@ inline void kiss_write_packet(int index) { } inline void getPacketData(RadioInterface* radio, uint16_t len) { + uint8_t index = radio->getIndex(); #if MCU_VARIANT != MCU_NRF52 - while (len-- && read_len < MTU) { - pbuf[read_len++] = radio->read(); + while (len-- && read_len[index] < MTU) { + pbuf[read_len[index]++] = radio->read(); } #else BaseType_t int_mask = taskENTER_CRITICAL_FROM_ISR(); - while (len-- && read_len < MTU) { - pbuf[read_len++] = radio->read(); + while (len-- && read_len[index] < MTU) { + pbuf[read_len[index]++] = radio->read(); } taskEXIT_CRITICAL_FROM_ISR(int_mask); #endif @@ -398,7 +400,7 @@ inline void getPacketData(RadioInterface* radio, uint16_t len) { inline bool queue_packet(RadioInterface* radio, uint8_t index) { // Allocate packet struct, but abort if there // is not enough memory available. - modem_packet_t *modem_packet = (modem_packet_t*)malloc(sizeof(modem_packet_t) + read_len); + modem_packet_t *modem_packet = (modem_packet_t*)malloc(sizeof(modem_packet_t) + read_len[index]); if(!modem_packet) { memory_low = true; return false; } // Get packet RSSI and SNR @@ -412,8 +414,8 @@ inline bool queue_packet(RadioInterface* radio, uint8_t index) { // Send packet to event queue, but free the // allocated memory again if the queue is // unable to receive the packet. - modem_packet->len = read_len; - memcpy(modem_packet->data, pbuf, read_len); + modem_packet->len = read_len[index]; + memcpy(modem_packet->data, pbuf, read_len[index]); if (!modem_packet_queue || xQueueSendFromISR(modem_packet_queue, &modem_packet, NULL) != pdPASS) { free(modem_packet); return false; @@ -441,9 +443,9 @@ void ISR_VECT receive_callback(uint8_t index, int packet_size) { // packet, so we set the seq variable // and add the data to the buffer #if MCU_VARIANT == MCU_NRF52 - int_mask = taskENTER_CRITICAL_FROM_ISR(); read_len = 0; taskEXIT_CRITICAL_FROM_ISR(int_mask); + int_mask = taskENTER_CRITICAL_FROM_ISR(); read_len[index] = 0; taskEXIT_CRITICAL_FROM_ISR(int_mask); #else - read_len = 0; + read_len[index] = 0; #endif seq[index] = sequence; @@ -466,9 +468,9 @@ void ISR_VECT receive_callback(uint8_t index, int packet_size) { // that we are seeing the first part of // a new split packet. #if MCU_VARIANT == MCU_NRF52 - int_mask = taskENTER_CRITICAL_FROM_ISR(); read_len = 0; taskEXIT_CRITICAL_FROM_ISR(int_mask); + int_mask = taskENTER_CRITICAL_FROM_ISR(); read_len[index] = 0; taskEXIT_CRITICAL_FROM_ISR(int_mask); #else - read_len = 0; + read_len[index] = 0; #endif seq[index] = sequence; @@ -483,9 +485,9 @@ void ISR_VECT receive_callback(uint8_t index, int packet_size) { // If we already had part of a split // packet in the buffer, we clear it. #if MCU_VARIANT == MCU_NRF52 - int_mask = taskENTER_CRITICAL_FROM_ISR(); read_len = 0; taskEXIT_CRITICAL_FROM_ISR(int_mask); + int_mask = taskENTER_CRITICAL_FROM_ISR(); read_len[index] = 0; taskEXIT_CRITICAL_FROM_ISR(int_mask); #else - read_len = 0; + read_len[index] = 0; #endif seq[index] = SEQ_UNSET; } @@ -497,7 +499,7 @@ void ISR_VECT receive_callback(uint8_t index, int packet_size) { } else { // In promiscuous mode, raw packets are // output directly to the host - read_len = 0; + read_len[index] = 0; getPacketData(selected_radio, packet_size); @@ -1341,10 +1343,10 @@ void loop() { #if MCU_VARIANT == MCU_ESP32 modem_packet_t *modem_packet = NULL; if(modem_packet_queue && xQueueReceive(modem_packet_queue, &modem_packet, 0) == pdTRUE && modem_packet) { - read_len = modem_packet->len; + packet_interface = modem_packet->interface; + read_len[packet_interface] = modem_packet->len; last_rssi = modem_packet->rssi; last_snr_raw = modem_packet->snr_raw; - packet_interface = modem_packet->interface; memcpy(&pbuf, modem_packet->data, modem_packet->len); free(modem_packet); modem_packet = NULL; @@ -1357,11 +1359,11 @@ void loop() { #elif MCU_VARIANT == MCU_NRF52 modem_packet_t *modem_packet = NULL; if(modem_packet_queue && xQueueReceive(modem_packet_queue, &modem_packet, 0) == pdTRUE && modem_packet) { - memcpy(&pbuf, modem_packet->data, modem_packet->len); - read_len = modem_packet->len; + packet_interface = modem_packet->interface; + read_len[packet_interface] = modem_packet->len; last_rssi = modem_packet->rssi; last_snr_raw = modem_packet->snr_raw; - packet_interface = modem_packet->interface; + memcpy(&pbuf, modem_packet->data, modem_packet->len); free(modem_packet); modem_packet = NULL;