diff --git a/radio/src/bluetooth.cpp b/radio/src/bluetooth.cpp index 08c4f7849a..d65dad9bae 100644 --- a/radio/src/bluetooth.cpp +++ b/radio/src/bluetooth.cpp @@ -19,6 +19,7 @@ */ #include "opentx.h" +#include "io/frsky_firmware_update.h" #if defined(PCBHORUS) || defined(PCBX7) || defined(PCBXLITE) || defined(USEHORUSBT) #define BLUETOOTH_COMMAND_NAME "AT+NAME" @@ -717,13 +718,21 @@ const char * Bluetooth::doFlashFirmware(const char * filename) return "Error opening file"; } + FrSkyFirmwareInformation * information = (FrSkyFirmwareInformation *)buffer; + if (f_read(&file, buffer, sizeof(FrSkyFirmwareInformation), &count) != FR_OK || count != sizeof(FrSkyFirmwareInformation)) { + f_close(&file); + return "Format error"; + } + drawProgressScreen(getBasename(filename), STR_FLASH_ERASE, 0, 0); - result = bootloaderEraseFlash(CC26XX_FIRMWARE_BASE, f_size(&file)); - if (result) + result = bootloaderEraseFlash(CC26XX_FIRMWARE_BASE, information->size); + if (result) { + f_close(&file); return result; + } - uint32_t size = min(CC26XX_FIRMWARE_SIZE, f_size(&file)); + uint32_t size = information->size; drawProgressScreen(getBasename(filename), STR_FLASH_WRITE, 0, size); result = bootloaderStartWriteFlash(CC26XX_FIRMWARE_BASE, size); @@ -785,4 +794,4 @@ void Bluetooth::flashFirmware(const char * filename) state = BLUETOOTH_STATE_OFF; resumePulses(); -} \ No newline at end of file +} diff --git a/radio/src/gui/480x272/radio_sdmanager.cpp b/radio/src/gui/480x272/radio_sdmanager.cpp index da012f4767..9923e45ef6 100644 --- a/radio/src/gui/480x272/radio_sdmanager.cpp +++ b/radio/src/gui/480x272/radio_sdmanager.cpp @@ -19,7 +19,7 @@ */ #include -#include +#include #include "opentx.h" #include "storage/modelslist.h" @@ -142,18 +142,18 @@ void onSdManagerMenu(const char * result) } else if (result == STR_FLASH_INTERNAL_MODULE) { getSelectionFullPath(lfn); - DeviceFirmwareUpdate device(INTERNAL_MODULE); - device.flashFile(lfn); + FrskyDeviceFirmwareUpdate device(INTERNAL_MODULE); + device.flashFirmware(lfn); } else if (result == STR_FLASH_EXTERNAL_MODULE) { getSelectionFullPath(lfn); - DeviceFirmwareUpdate device(EXTERNAL_MODULE); - device.flashFile(lfn); + FrskyDeviceFirmwareUpdate device(EXTERNAL_MODULE); + device.flashFirmware(lfn); } else if (result == STR_FLASH_EXTERNAL_DEVICE) { getSelectionFullPath(lfn); - DeviceFirmwareUpdate device(SPORT_MODULE); - device.flashFile(lfn); + FrskyDeviceFirmwareUpdate device(SPORT_MODULE); + device.flashFirmware(lfn); } #if defined(LUA) else if (result == STR_EXECUTE_FILE) { diff --git a/radio/src/gui/common/stdlcd/radio_sdmanager.cpp b/radio/src/gui/common/stdlcd/radio_sdmanager.cpp index f6a6346b0d..0a8f8faf47 100644 --- a/radio/src/gui/common/stdlcd/radio_sdmanager.cpp +++ b/radio/src/gui/common/stdlcd/radio_sdmanager.cpp @@ -19,7 +19,7 @@ */ #include "opentx.h" -#include "io/frsky_device_firmware_update.h" +#include "io/frsky_firmware_update.h" #define REFRESH_FILES() do { reusableBuffer.sdManager.offset = 65535; menuVerticalPosition = 0; } while(0) #define NODE_TYPE(fname) fname[SD_SCREEN_FILE_LENGTH+1] @@ -186,19 +186,19 @@ void onSdManagerMenu(const char * result) } else if (result == STR_FLASH_INTERNAL_MODULE) { getSelectionFullPath(lfn); - DeviceFirmwareUpdate device(INTERNAL_MODULE); - device.flashFile(lfn); + FrskyDeviceFirmwareUpdate device(INTERNAL_MODULE); + device.flashFirmware(lfn); } else if (result == STR_FLASH_EXTERNAL_MODULE) { // needed on X-Lite (as the R9M needs 2S while the external device flashing port only provides 5V) getSelectionFullPath(lfn); - DeviceFirmwareUpdate device(EXTERNAL_MODULE); - device.flashFile(lfn); + FrskyDeviceFirmwareUpdate device(EXTERNAL_MODULE); + device.flashFirmware(lfn); } else if (result == STR_FLASH_EXTERNAL_DEVICE) { getSelectionFullPath(lfn); - DeviceFirmwareUpdate device(SPORT_MODULE); - device.flashFile(lfn); + FrskyDeviceFirmwareUpdate device(SPORT_MODULE); + device.flashFirmware(lfn); } #if defined(BLUETOOTH) else if (result == STR_FLASH_BLUETOOTH_MODULE) { @@ -206,6 +206,13 @@ void onSdManagerMenu(const char * result) bluetooth.flashFirmware(lfn); } #endif +#if defined(HARDWARE_POWER_CONTROL_CHIP) + else if (result == STR_FLASH_POWER_CONTROL_CHIP) { + getSelectionFullPath(lfn); + FrskyChipFirmwareUpdate device; + device.flashFirmware(lfn); + } +#endif #if defined(PXX2) else if (result == STR_FLASH_RECEIVER_OTA) { memclear(&reusableBuffer.sdManager.otaUpdateInformation, sizeof(OtaUpdateInformation)); @@ -354,14 +361,29 @@ void menuRadioSdManager(event_t _event) POPUP_MENU_ADD_ITEM(STR_FLASH_EXTERNAL_DEVICE); POPUP_MENU_ADD_ITEM(STR_FLASH_INTERNAL_MODULE); POPUP_MENU_ADD_ITEM(STR_FLASH_EXTERNAL_MODULE); -#if defined(PXX2) - POPUP_MENU_ADD_ITEM(STR_FLASH_RECEIVER_OTA); -#endif } + else if (!READ_ONLY() && !strcasecmp(ext, UPDATE_FIRMWARE_EXT)) { + FrSkyFirmwareInformation information; + if (readFirmwareInformation(line, information) == nullptr) { + if (information.productFamily == FIRMWARE_FAMILY_INTERNAL_MODULE) + POPUP_MENU_ADD_ITEM(STR_FLASH_INTERNAL_MODULE); + if (information.productFamily == FIRMWARE_FAMILY_EXTERNAL_MODULE) + POPUP_MENU_ADD_ITEM(STR_FLASH_EXTERNAL_MODULE); + if (HAS_SPORT_UPDATE_CONNECTOR() && (information.productFamily == FIRMWARE_FAMILY_RECEIVER || information.productFamily == FIRMWARE_FAMILY_SENSOR)) + POPUP_MENU_ADD_ITEM(STR_FLASH_EXTERNAL_DEVICE); +#if defined(PXX2) + if (information.productFamily == FIRMWARE_FAMILY_RECEIVER) + POPUP_MENU_ADD_ITEM(STR_FLASH_RECEIVER_OTA); #endif #if defined(BLUETOOTH) - if (!READ_ONLY() && !strcasecmp(ext, BLUETOOTH_FIRMWARE_EXT)) { - POPUP_MENU_ADD_ITEM(STR_FLASH_BLUETOOTH_MODULE); + if (information.productFamily == FIRMWARE_FAMILY_BLUETOOTH_CHIP) + POPUP_MENU_ADD_ITEM(STR_FLASH_BLUETOOTH_MODULE); +#endif +#if defined(HARDWARE_POWER_CONTROL_CHIP) + if (information.productFamily == FIRMWARE_FAMILY_POWER_CONTROL_CHIP) + POPUP_MENU_ADD_ITEM(STR_FLASH_POWER_CONTROL_CHIP); +#endif + } } #endif } diff --git a/radio/src/io/frsky_device_firmware_update.cpp b/radio/src/io/frsky_firmware_update.cpp similarity index 53% rename from radio/src/io/frsky_device_firmware_update.cpp rename to radio/src/io/frsky_firmware_update.cpp index d03ed74430..7be4b2b6b1 100644 --- a/radio/src/io/frsky_device_firmware_update.cpp +++ b/radio/src/io/frsky_firmware_update.cpp @@ -19,7 +19,7 @@ */ #include "opentx.h" -#include "frsky_device_firmware_update.h" +#include "frsky_firmware_update.h" #define PRIM_REQ_POWERUP 0 #define PRIM_REQ_VERSION 1 @@ -33,7 +33,35 @@ #define PRIM_END_DOWNLOAD 0x83 #define PRIM_DATA_CRC_ERR 0x84 -void DeviceFirmwareUpdate::processFrame(const uint8_t * frame) +const char * readFirmwareInformation(const char * filename, FrSkyFirmwareInformation & data) +{ + FIL file; + UINT count; + + if (f_open(&file, filename, FA_READ) != FR_OK) { + return "Error opening file"; + } + + if (f_read(&file, &data, sizeof(data), &count) != FR_OK || count != sizeof(data)) { + f_close(&file); + return "Error reading file"; + } + + uint32_t size = f_size(&file); + f_close(&file); + + if (data.headerVersion != 1 && data.fourcc != 0x4B535246) { + return "Wrong format"; + } + + if (size != sizeof(data) + data.size) { + return "Wrong size"; + } + + return nullptr; +} + +void FrskyDeviceFirmwareUpdate::processFrame(const uint8_t * frame) { if (frame[0] == 0x5E && frame[1] == 0x50) { switch (frame[2]) { @@ -68,7 +96,7 @@ void DeviceFirmwareUpdate::processFrame(const uint8_t * frame) } } -void DeviceFirmwareUpdate::startup() +void FrskyDeviceFirmwareUpdate::startup() { switch(module) { #if defined(INTMODULE_USART) @@ -90,7 +118,7 @@ void DeviceFirmwareUpdate::startup() SPORT_UPDATE_POWER_ON(); } -const uint8_t * DeviceFirmwareUpdate::readFullDuplexFrame(ModuleFifo & fifo, uint32_t timeout) +const uint8_t * FrskyDeviceFirmwareUpdate::readFullDuplexFrame(ModuleFifo & fifo, uint32_t timeout) { uint8_t len = 0; bool bytestuff = false; @@ -121,7 +149,7 @@ const uint8_t * DeviceFirmwareUpdate::readFullDuplexFrame(ModuleFifo & fifo, uin return &frame[1]; } -const uint8_t * DeviceFirmwareUpdate::readHalfDuplexFrame(uint32_t timeout) +const uint8_t * FrskyDeviceFirmwareUpdate::readHalfDuplexFrame(uint32_t timeout) { for (int i=timeout; i>=0; i--) { uint8_t byte ; @@ -135,7 +163,7 @@ const uint8_t * DeviceFirmwareUpdate::readHalfDuplexFrame(uint32_t timeout) return nullptr; } -const uint8_t * DeviceFirmwareUpdate::readFrame(uint32_t timeout) +const uint8_t * FrskyDeviceFirmwareUpdate::readFrame(uint32_t timeout) { switch(module) { #if defined(INTMODULE_USART) @@ -148,7 +176,7 @@ const uint8_t * DeviceFirmwareUpdate::readFrame(uint32_t timeout) } } -bool DeviceFirmwareUpdate::waitState(State newState, uint32_t timeout) +bool FrskyDeviceFirmwareUpdate::waitState(State newState, uint32_t timeout) { #if defined(SIMU) UNUSED(state); @@ -172,7 +200,7 @@ bool DeviceFirmwareUpdate::waitState(State newState, uint32_t timeout) #endif } -void DeviceFirmwareUpdate::startFrame(uint8_t command) +void FrskyDeviceFirmwareUpdate::startFrame(uint8_t command) { frame[0] = 0x50; frame[1] = command; @@ -180,7 +208,7 @@ void DeviceFirmwareUpdate::startFrame(uint8_t command) } // TODO merge this function -void DeviceFirmwareUpdate::sendFrame() +void FrskyDeviceFirmwareUpdate::sendFrame() { uint8_t * ptr = outputTelemetryBuffer.data; *ptr++ = 0x7E; @@ -207,7 +235,7 @@ void DeviceFirmwareUpdate::sendFrame() } } -const char * DeviceFirmwareUpdate::sendPowerOn() +const char * FrskyDeviceFirmwareUpdate::sendPowerOn() { state = SPORT_POWERUP_REQ; waitState(SPORT_IDLE, 50); // Wait 50ms and clear the fifo @@ -238,7 +266,7 @@ const char * DeviceFirmwareUpdate::sendPowerOn() #endif } -const char * DeviceFirmwareUpdate::sendReqVersion() +const char * FrskyDeviceFirmwareUpdate::sendReqVersion() { waitState(SPORT_IDLE, 20); // Clear the fifo state = SPORT_VERSION_REQ; @@ -252,7 +280,7 @@ const char * DeviceFirmwareUpdate::sendReqVersion() return "Version request failed"; } -const char * DeviceFirmwareUpdate::uploadFile(const char *filename) +const char * FrskyDeviceFirmwareUpdate::uploadFile(const char * filename) { FIL file; uint32_t buffer[1024 / sizeof(uint32_t)]; @@ -297,7 +325,7 @@ const char * DeviceFirmwareUpdate::uploadFile(const char *filename) } } -const char * DeviceFirmwareUpdate::endTransfer() +const char * FrskyDeviceFirmwareUpdate::endTransfer() { if (!waitState(SPORT_DATA_REQ, 2000)) return "Device refused data"; @@ -309,7 +337,7 @@ const char * DeviceFirmwareUpdate::endTransfer() return nullptr; } -void DeviceFirmwareUpdate::flashFile(const char * filename) +void FrskyDeviceFirmwareUpdate::flashFirmware(const char * filename) { pausePulses(); @@ -366,3 +394,253 @@ void DeviceFirmwareUpdate::flashFile(const char * filename) state = SPORT_IDLE; resumePulses(); } + +const char * FrskyChipFirmwareUpdate::waitAnswer(uint8_t & status) +{ + telemetryPortSetDirectionInput(); + + uint8_t buffer[12]; + for (uint8_t i = 0; i < sizeof(buffer); i++) { + uint32_t retry = 0; + while(1) { + if (telemetryGetByte(&buffer[i])) { + if ((i == 0 && buffer[0] != 0x7F) || + (i == 1 && buffer[1] != 0xFE) || + (i == 10 && buffer[10] != 0x0D) || + (i == 11 && buffer[11] != 0x0A)) { + i = 0; + continue; + } + break; + } + if (++retry == 20000) { + return "No answer"; + } + RTOS_WAIT_MS(1); + } + } + status = buffer[8]; + return nullptr; +} + +const char * FrskyChipFirmwareUpdate::startBootloader() +{ + telemetryPortSetDirectionOutput(); + + sportSendByte(0x01); + + for (uint8_t i = 0; i < 30; i++) + sportSendByte(0x7E); + + for (uint32_t i = 0; i < 100; i++) { + RTOS_WAIT_MS(20); + sportSendByte(0x7F); + } + + sportSendByte(0xFA); + + /*for (uint8_t i=0; i < 30; i++) + sportSendByte(0x7E); + for (uint8_t i=0; i < 50; i++) + sportSendByte(0x7F);*/ + + uint8_t status; + const char * result = waitAnswer(status); + if (result) + return result; + + return status == 0x08 ? nullptr : "Bootloader failed"; +} + +void FrskyChipFirmwareUpdate::sendByte(uint8_t byte, bool crcFlag) +{ + sportSendByte(byte); + if (crcFlag) { + crc ^= byte; + } +} + +const char * FrskyChipFirmwareUpdate::sendUpgradeCommand(char command, uint32_t packetsCount) +{ + telemetryPortSetDirectionOutput(); + + crc = 0; + + // Head + sendByte(0x7F, false); + sendByte(0xFE, false); + + // Addr + sendByte(0xFA); + + // Cmd + sendByte(command); + + // Packets count + sendByte(packetsCount >> 8); + sendByte(packetsCount); + + // Len + sendByte('E' == command ? 0x00 : 0x0C); + sendByte(0x40); + + // Data + for (uint8_t i=0; i < 0x40; i++) + sendByte('E' == command ? 0xF7 : 0x7F); + + // Checksum + sendByte(crc, false); + + // Tail + sendByte(0x0D, false); + sendByte(0x0A, false); + + uint8_t status; + const char * result = waitAnswer(status); + if (result) + return result; + + return status == 0x00 ? nullptr : "Upgrade failed"; +} + +const char * FrskyChipFirmwareUpdate::sendUpgradeData(uint8_t index, uint8_t * data) +{ + telemetryPortSetDirectionOutput(); + + crc = 0; + + // Head + sendByte(0x7F, false); + sendByte(0xFE, false); + + // Addr + sendByte(0xFA); + + // Cmd + sendByte('W'); + + // Packets count + sendByte(index >> 8); + sendByte(index); + + // Len + sendByte(0x00); + sendByte(0x40); + + // Data + for (uint8_t i = 0; i < 0x40; i++) + sendByte(*data++); + + // Checksum + sendByte(crc, false); + + // Tail + sendByte(0x0D, false); + sendByte(0x0A, false); + + uint8_t status; + const char * result = waitAnswer(status); + if (result) + return result; + + return status == 0x00 ? nullptr : "Upgrade failed"; +} + +const char * FrskyChipFirmwareUpdate::doFlashFirmware(const char * filename) +{ + const char * result; + FIL file; + uint8_t buffer[64]; + UINT count; + + result = startBootloader(); + if (result) + return result; + + if (f_open(&file, filename, FA_READ) != FR_OK) { + return "Error opening file"; + } + + FrSkyFirmwareInformation * information = (FrSkyFirmwareInformation *)buffer; + if (f_read(&file, buffer, sizeof(FrSkyFirmwareInformation), &count) != FR_OK || count != sizeof(FrSkyFirmwareInformation)) { + f_close(&file); + return "Format error"; + } + + uint32_t packetsCount = (information->size + sizeof(buffer) - 1) / sizeof(buffer); + drawProgressScreen(getBasename(filename), STR_FLASH_WRITE, 0, packetsCount); + + result = sendUpgradeCommand('A', packetsCount); + if (result) + return result; + + uint32_t index = 0; + while (1) { + drawProgressScreen(getBasename(filename), STR_FLASH_WRITE, index, packetsCount); + if (f_read(&file, buffer, sizeof(buffer), &count) != FR_OK) { + f_close(&file); + return "Error reading file"; + } + result = sendUpgradeData(index + 1, buffer); + if (result) + return result; + if (++index == packetsCount) + break; + } + + f_close(&file); + + return sendUpgradeCommand('E', packetsCount); +} + +void FrskyChipFirmwareUpdate::flashFirmware(const char * filename) +{ + drawProgressScreen(getBasename(filename), STR_DEVICE_RESET, 0, 0); + + pausePulses(); + + uint8_t intPwr = IS_INTERNAL_MODULE_ON(); + uint8_t extPwr = IS_EXTERNAL_MODULE_ON(); + + INTERNAL_MODULE_OFF(); + EXTERNAL_MODULE_OFF(); + SPORT_UPDATE_POWER_OFF(); + + /* wait 2s off */ + watchdogSuspend(2000); + RTOS_WAIT_MS(2000); + + telemetryInit(PROTOCOL_TELEMETRY_FRSKY_SPORT); + + const char * result = doFlashFirmware(filename); + + AUDIO_PLAY(AU_SPECIAL_SOUND_BEEP1 ); + BACKLIGHT_ENABLE(); + + if (result) { + POPUP_WARNING(STR_FIRMWARE_UPDATE_ERROR); + SET_WARNING_INFO(result, strlen(result), 0); + } + else { + POPUP_INFORMATION(STR_FIRMWARE_UPDATE_SUCCESS); + } + + INTERNAL_MODULE_OFF(); + EXTERNAL_MODULE_OFF(); + SPORT_UPDATE_POWER_OFF(); + + /* wait 2s off */ + watchdogSuspend(2000); + RTOS_WAIT_MS(2000); + + if (intPwr) { + INTERNAL_MODULE_ON(); + setupPulses(INTERNAL_MODULE); + } + if (extPwr) { + EXTERNAL_MODULE_ON(); + setupPulses(EXTERNAL_MODULE); + } + + resumePulses(); +} diff --git a/radio/src/io/frsky_device_firmware_update.h b/radio/src/io/frsky_firmware_update.h similarity index 55% rename from radio/src/io/frsky_device_firmware_update.h rename to radio/src/io/frsky_firmware_update.h index 729120895f..768bd0e199 100644 --- a/radio/src/io/frsky_device_firmware_update.h +++ b/radio/src/io/frsky_firmware_update.h @@ -18,13 +18,36 @@ * GNU General Public License for more details. */ -#ifndef _FRSKY_DEVICE_FIRMWARE_UPDATE_H_ -#define _FRSKY_DEVICE_FIRMWARE_UPDATE_H_ +#ifndef _FRSKY_FIRMWARE_UPDATE_H_ +#define _FRSKY_FIRMWARE_UPDATE_H_ #include "dataconstants.h" #include "frsky_pxx2.h" -class DeviceFirmwareUpdate { +enum FrskyFirmwareProductFamily { + FIRMWARE_FAMILY_INTERNAL_MODULE, + FIRMWARE_FAMILY_EXTERNAL_MODULE, + FIRMWARE_FAMILY_RECEIVER, + FIRMWARE_FAMILY_SENSOR, + FIRMWARE_FAMILY_BLUETOOTH_CHIP, + FIRMWARE_FAMILY_POWER_CONTROL_CHIP, +}; + +PACK(struct FrSkyFirmwareInformation { + uint32_t fourcc; + uint8_t headerVersion; + uint8_t firmwareVersionMajor; + uint8_t firmwareVersionMinor; + uint8_t firmwareVersionRevision; + uint32_t size; + uint8_t productFamily; + uint8_t productId; + uint16_t crc; +}); + +const char * readFirmwareInformation(const char * filename, FrSkyFirmwareInformation & data); + +class FrskyDeviceFirmwareUpdate { enum State { SPORT_IDLE, SPORT_POWERUP_REQ, @@ -38,11 +61,11 @@ class DeviceFirmwareUpdate { }; public: - DeviceFirmwareUpdate(ModuleIndex module): + FrskyDeviceFirmwareUpdate(ModuleIndex module): module(module) { } - void flashFile(const char * filename); + void flashFirmware(const char * filename); protected: uint8_t state = SPORT_IDLE; @@ -67,4 +90,24 @@ class DeviceFirmwareUpdate { const char * endTransfer(); }; -#endif // _FRSKY_DEVICE_FIRMWARE_UPDATE_H_ +class FrskyChipFirmwareUpdate { + public: + FrskyChipFirmwareUpdate() + { + } + + void flashFirmware(const char * filename); + + protected: + uint8_t crc; + + void sendByte(uint8_t byte, bool crc = true); + const char * waitAnswer(uint8_t & status); + const char * startBootloader(); + const char * sendUpgradeCommand(char command, uint32_t packetsCount); + const char * sendUpgradeData(uint8_t index, uint8_t * data); + + const char * doFlashFirmware(const char * filename); +}; + +#endif // _FRSKY_FIRMWARE_UPDATE_H_ diff --git a/radio/src/sdcard.cpp b/radio/src/sdcard.cpp index 326d6f96b1..59a2f239b7 100644 --- a/radio/src/sdcard.cpp +++ b/radio/src/sdcard.cpp @@ -213,7 +213,7 @@ const char * getFileExtension(const char * filename, uint8_t size, uint8_t extMa if (!extMaxLen) { extMaxLen = LEN_FILE_EXTENSION_MAX; } - if (fnlen != NULL) { + if (fnlen != nullptr) { *fnlen = (uint8_t)len; } for (int i=len-1; i >= 0 && len-i <= extMaxLen; --i) { @@ -224,10 +224,10 @@ const char * getFileExtension(const char * filename, uint8_t size, uint8_t extMa return &filename[i]; } } - if (extlen != NULL) { + if (extlen != nullptr) { *extlen = 0; } - return NULL; + return nullptr; } /** diff --git a/radio/src/sdcard.h b/radio/src/sdcard.h index fb2734d46a..e4c71a5349 100644 --- a/radio/src/sdcard.h +++ b/radio/src/sdcard.h @@ -68,7 +68,7 @@ const char RADIO_SETTINGS_PATH[] = RADIO_PATH "/radio.bin"; #define FIRMWARE_EXT ".bin" #define EEPROM_EXT ".bin" #define SPORT_FIRMWARE_EXT ".frk" -#define BLUETOOTH_FIRMWARE_EXT ".bin" +#define UPDATE_FIRMWARE_EXT ".frsk" #define LEN_FILE_EXTENSION_MAX 5 // longest used, including the dot, excluding null term. diff --git a/radio/src/targets/horus/CMakeLists.txt b/radio/src/targets/horus/CMakeLists.txt index 5161192e3a..a980d12c72 100644 --- a/radio/src/targets/horus/CMakeLists.txt +++ b/radio/src/targets/horus/CMakeLists.txt @@ -157,7 +157,7 @@ add_definitions(-DBLUETOOTH) set(SRC ${SRC} bluetooth.cpp - io/frsky_device_firmware_update.cpp + io/frsky_firmware_update.cpp ) set(STM32LIB_SRC diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h index 87dc1effae..22046b4b9f 100644 --- a/radio/src/targets/horus/board.h +++ b/radio/src/targets/horus/board.h @@ -595,7 +595,9 @@ int32_t getVolume(void); // Telemetry driver #define TELEMETRY_FIFO_SIZE 512 void telemetryPortInit(uint32_t baudrate, uint8_t mode); +void telemetryPortSetDirectionInput(void); void telemetryPortSetDirectionOutput(void); +void sportSendByte(uint8_t byte); void sportSendBuffer(const uint8_t * buffer, uint32_t count); uint8_t telemetryGetByte(uint8_t * byte); extern uint32_t telemetryErrors; diff --git a/radio/src/targets/horus/telemetry_driver.cpp b/radio/src/targets/horus/telemetry_driver.cpp index 491325d219..f9e278da62 100644 --- a/radio/src/targets/horus/telemetry_driver.cpp +++ b/radio/src/targets/horus/telemetry_driver.cpp @@ -138,6 +138,12 @@ void telemetryPortSetDirectionInput() TELEMETRY_USART->CR1 |= USART_CR1_RE; // turn on receiver } +void sportSendByte(uint8_t byte) +{ + while (!(TELEMETRY_USART->SR & USART_SR_TXE)); + USART_SendData(TELEMETRY_USART, byte); +} + void sportSendBuffer(const uint8_t * buffer, uint32_t count) { telemetryPortSetDirectionOutput(); diff --git a/radio/src/targets/taranis/CMakeLists.txt b/radio/src/targets/taranis/CMakeLists.txt index a3bbbf735d..d31e2e1a81 100644 --- a/radio/src/targets/taranis/CMakeLists.txt +++ b/radio/src/targets/taranis/CMakeLists.txt @@ -105,7 +105,7 @@ elseif(PCB STREQUAL X9LITE) set(LUA_EXPORT lua_export_x9lite) set(FLAVOUR x9lite) add_definitions(-DBOARD_NAME="x9lite") - add_definitions(-DPCBX9LITE -DPCBX9 -DSOFTWARE_VOLUME) + add_definitions(-DPCBX9LITE -DPCBX9 -DSOFTWARE_VOLUME -DHARDWARE_POWER_CONTROL_CHIP) add_definitions(-DEEPROM_VARIANT=0x0800) set(PXX2 ON) set(GUI_DIR 128x64) @@ -143,7 +143,7 @@ elseif(PCB STREQUAL XLITES) set(HAPTIC YES) set(LUA_EXPORT lua_export_xlites) set(FLAVOUR xlites) - add_definitions(-DPCBXLITES -DPCBXLITE -DSOFTWARE_VOLUME -DEXTERNAL_ANTENNA -DSTICKS_PWM) + add_definitions(-DPCBXLITES -DPCBXLITE -DSOFTWARE_VOLUME -DEXTERNAL_ANTENNA -DSTICKS_PWM -DHARDWARE_POWER_CONTROL_CHIP) add_definitions(-DEEPROM_VARIANT=0x1000) add_definitions(-DPWR_BUTTON_${PWR_BUTTON}) set(GUI_DIR 128x64) @@ -229,7 +229,7 @@ add_definitions(-DAUDIO -DVOICE -DRTCLOCK) set(SRC ${SRC} - io/frsky_device_firmware_update.cpp + io/frsky_firmware_update.cpp ) set(GUI_SRC diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h index 989a71233a..afc6d6c5ec 100644 --- a/radio/src/targets/taranis/board.h +++ b/radio/src/targets/taranis/board.h @@ -676,7 +676,9 @@ void debugPutc(const char c); // Telemetry driver void telemetryPortInit(uint32_t baudrate, uint8_t mode); +void telemetryPortSetDirectionInput(void); void telemetryPortSetDirectionOutput(void); +void sportSendByte(uint8_t byte); void sportSendBuffer(const uint8_t * buffer, uint32_t count); uint8_t telemetryGetByte(uint8_t * byte); extern uint32_t telemetryErrors; diff --git a/radio/src/targets/taranis/telemetry_driver.cpp b/radio/src/targets/taranis/telemetry_driver.cpp index a05b6753e6..ffdaefd17f 100644 --- a/radio/src/targets/taranis/telemetry_driver.cpp +++ b/radio/src/targets/taranis/telemetry_driver.cpp @@ -83,12 +83,24 @@ void telemetryPortSetDirectionOutput() TELEMETRY_USART->CR1 &= ~USART_CR1_RE; // turn off receiver } +void sportWaitTransmissionComplete() +{ + while (!(TELEMETRY_USART->SR & USART_SR_TC)); +} + void telemetryPortSetDirectionInput() { + sportWaitTransmissionComplete(); TELEMETRY_DIR_INPUT(); TELEMETRY_USART->CR1 |= USART_CR1_RE; // turn on receiver } +void sportSendByte(uint8_t byte) +{ + while (!(TELEMETRY_USART->SR & USART_SR_TXE)); + USART_SendData(TELEMETRY_USART, byte); +} + void sportSendBuffer(const uint8_t * buffer, uint32_t count) { telemetryPortSetDirectionOutput(); diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index 57996e2227..426ed7dbf6 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -429,6 +429,7 @@ const char STR_WRITING[] = TR_WRITING; const char STR_FLASH_EXTERNAL_DEVICE[] = TR_FLASH_EXTERNAL_DEVICE; const char STR_FLASH_RECEIVER_OTA[] = TR_FLASH_RECEIVER_OTA; const char STR_FLASH_BLUETOOTH_MODULE[] = TR_FLASH_BLUETOOTH_MODULE; +const char STR_FLASH_POWER_CONTROL_CHIP[] = TR_FLASH_POWER_CONTROL_CHIP; const char STR_CONFIRM_FORMAT[] = TR_CONFIRM_FORMAT; const char STR_CONFIRMRESET[] = TR_CONFIRMRESET; const char STR_TOO_MANY_LUA_SCRIPTS[] = TR_TOO_MANY_LUA_SCRIPTS; diff --git a/radio/src/translations.h b/radio/src/translations.h index 4b42d33d14..73b0721d91 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -606,6 +606,7 @@ extern const char STR_FLASH_BOOTLOADER[]; extern const char STR_FLASH_EXTERNAL_DEVICE[]; extern const char STR_FLASH_RECEIVER_OTA[]; extern const char STR_FLASH_BLUETOOTH_MODULE[]; +extern const char STR_FLASH_POWER_CONTROL_CHIP[]; extern const char STR_CURRENT_VERSION[]; extern const char STR_FLASH_INTERNAL_MODULE[]; extern const char STR_FLASH_EXTERNAL_MODULE[]; diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index d990c68730..30c712dd76 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -894,6 +894,7 @@ #define TR_FLASH_EXTERNAL_DEVICE TR("Flash S.Portem", "Flash S.Portem") #define TR_FLASH_RECEIVER_OTA "Flash příjímače OTA" #define TR_FLASH_BLUETOOTH_MODULE TR("Flash modulu BT", "Flash modulu Bluetooth") +#define TR_FLASH_POWER_CONTROL_CHIP "Flash battery chip" #define TR_CURRENT_VERSION TR("Současná ver. ", "Současná verze: ") #define TR_FLASH_INTERNAL_MODULE TR("Flash vnitř. modulu", "Flash vnitřního modulu") #define TR_FLASH_EXTERNAL_MODULE TR("Flash ext. modulu", "Flash externího zařízení") diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index ce85c99aff..c2f30de2b0 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -901,6 +901,7 @@ #define TR_FLASH_EXTERNAL_DEVICE TR("Flash ext. Gerät","Flash externes Gerät") #define TR_FLASH_RECEIVER_OTA "Flash receiver OTA" #define TR_FLASH_BLUETOOTH_MODULE TR("Flash BT module", "Flash Bluetooth module") +#define TR_FLASH_POWER_CONTROL_CHIP "Flash battery chip" #define TR_CURRENT_VERSION TR("Current vers. ", "Current version: ") #define TR_FLASH_INTERNAL_MODULE TR("Flash int. XJT","Flash internes XJT-Modul") #define TR_FLASH_EXTERNAL_MODULE TR("Flash ext. mod","Flash extern module") diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index f3d6fbc01a..f47fdbf19d 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -896,6 +896,7 @@ #define TR_FLASH_EXTERNAL_DEVICE TR("Flash S.Port", "Flash S.Port device") #define TR_FLASH_RECEIVER_OTA "Flash receiver OTA" #define TR_FLASH_BLUETOOTH_MODULE TR("Flash BT module", "Flash Bluetooth module") +#define TR_FLASH_POWER_CONTROL_CHIP "Flash battery chip" #define TR_CURRENT_VERSION TR("Curr Vers: ", "Current version: ") #define TR_FLASH_INTERNAL_MODULE TR("Flash int. module", "Flash internal module") #define TR_FLASH_EXTERNAL_MODULE TR("Flash ext. module", "Flash external module") diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index dac013a0c8..5800e5eca2 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -916,6 +916,7 @@ #define TR_FLASH_EXTERNAL_DEVICE "Flash External Device" #define TR_FLASH_RECEIVER_OTA "Flash receiver OTA" #define TR_FLASH_BLUETOOTH_MODULE TR("Flash BT module", "Flash Bluetooth module") +#define TR_FLASH_POWER_CONTROL_CHIP "Flash battery chip" #define TR_CURRENT_VERSION TR("Current vers. ", "Current version: ") #define TR_FLASH_INTERNAL_MODULE "Flash Internal Module" #define TR_FLASH_EXTERNAL_MODULE "Flash external module" diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index cfe5c9cd4a..75b662127b 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -909,6 +909,7 @@ #define TR_FLASH_EXTERNAL_DEVICE "Flash External Device" #define TR_FLASH_RECEIVER_OTA "Flash receiver OTA" #define TR_FLASH_BLUETOOTH_MODULE TR("Flash BT module", "Flash Bluetooth module") +#define TR_FLASH_POWER_CONTROL_CHIP "Flash battery chip" #define TR_CURRENT_VERSION TR("Current vers. ", "Current version: ") #define TR_FLASH_INTERNAL_MODULE "Flash Internal Module" #define TR_FLASH_EXTERNAL_MODULE "Flash external module" diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index 93da75f89c..568e2edc3c 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -911,6 +911,7 @@ #define TR_FLASH_EXTERNAL_DEVICE TR("Flasher S.Port", "Flasher S.Port externe") #define TR_FLASH_RECEIVER_OTA "Flash receiver OTA" #define TR_FLASH_BLUETOOTH_MODULE TR("Flash BT module", "Flash Bluetooth module") +#define TR_FLASH_POWER_CONTROL_CHIP "Flash battery chip" #define TR_CURRENT_VERSION "Version courante :" #define TR_FLASH_INTERNAL_MODULE TR("Flasher module int.", "Flasher module interne") #define TR_FLASH_EXTERNAL_MODULE TR("Flasher module ext.", "Flasher module externe") diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index db7d7989d4..7c04f49a87 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -910,6 +910,7 @@ #define TR_FLASH_EXTERNAL_DEVICE "Progr. Dispositivo Esterno" #define TR_FLASH_RECEIVER_OTA "Flash receiver OTA" #define TR_FLASH_BLUETOOTH_MODULE TR("Flash BT module", "Flash Bluetooth module") +#define TR_FLASH_POWER_CONTROL_CHIP "Flash battery chip" #define TR_CURRENT_VERSION TR("Current vers. ", "Current version: ") #define TR_FLASH_INTERNAL_MODULE "Progr. Modulo Interno" #define TR_FLASH_EXTERNAL_MODULE "Flash external module" diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index eee09834c4..dd4c5e6a77 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -899,6 +899,7 @@ TR_GYR_VSRCRAW #define TR_FLASH_EXTERNAL_DEVICE "Flash extern Apparaat" #define TR_FLASH_RECEIVER_OTA "Flash receiver OTA" #define TR_FLASH_BLUETOOTH_MODULE TR("Flash BT module", "Flash Bluetooth module") +#define TR_FLASH_POWER_CONTROL_CHIP "Flash battery chip" #define TR_CURRENT_VERSION TR("Current vers. ", "Current version: ") #define TR_FLASH_INTERNAL_MODULE "Flash interne XJT-Module" #define TR_FLASH_EXTERNAL_MODULE "Flash external module" diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index 6232660696..a6cf832cad 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -910,6 +910,7 @@ #define TR_FLASH_EXTERNAL_DEVICE "Sflashuj Moduł Zewnętrzny" #define TR_FLASH_RECEIVER_OTA "Flash receiver OTA" #define TR_FLASH_BLUETOOTH_MODULE TR("Flash BT module", "Flash Bluetooth module") +#define TR_FLASH_POWER_CONTROL_CHIP "Flash battery chip" #define TR_CURRENT_VERSION TR("Current vers. ", "Current version: ") #define TR_FLASH_INTERNAL_MODULE "Sflashuj Moduł Wewnętrzny" #define TR_FLASH_EXTERNAL_MODULE "Flash external module" diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index 4fb4324575..20f8847107 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -900,6 +900,7 @@ #define TR_FLASH_EXTERNAL_DEVICE "Flash External Device" #define TR_FLASH_RECEIVER_OTA "Flash receiver OTA" #define TR_FLASH_BLUETOOTH_MODULE TR("Flash BT module", "Flash Bluetooth module") +#define TR_FLASH_POWER_CONTROL_CHIP "Flash battery chip" #define TR_CURRENT_VERSION TR("Current vers. ", "Current version: ") #define TR_FLASH_INTERNAL_MODULE "Flash Internal Module" #define TR_FLASH_EXTERNAL_MODULE "Flash external module" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index c34d7c13e9..18ade31228 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -910,6 +910,7 @@ #define TR_FLASH_EXTERNAL_DEVICE "Flash External Device" #define TR_FLASH_RECEIVER_OTA "Flash receiver OTA" #define TR_FLASH_BLUETOOTH_MODULE TR("Flash BT module", "Flash Bluetooth module") +#define TR_FLASH_POWER_CONTROL_CHIP "Flash battery chip" #define TR_CURRENT_VERSION TR("Current vers. ", "Current version: ") #define TR_FLASH_INTERNAL_MODULE "Flash Internal Module" #define TR_FLASH_EXTERNAL_MODULE "Flash external module"