diff --git a/radio/src/io/frsky_firmware_update.cpp b/radio/src/io/frsky_firmware_update.cpp index fd3f7fe3c..c3012b862 100644 --- a/radio/src/io/frsky_firmware_update.cpp +++ b/radio/src/io/frsky_firmware_update.cpp @@ -355,7 +355,7 @@ const char * FrskyDeviceFirmwareUpdate::endTransfer() return nullptr; } -void FrskyDeviceFirmwareUpdate::flashFirmware(const char * filename) +const char * FrskyDeviceFirmwareUpdate::flashFirmware(const char * filename) { pausePulses(); @@ -416,6 +416,8 @@ void FrskyDeviceFirmwareUpdate::flashFirmware(const char * filename) state = SPORT_IDLE; resumePulses(); + + return result; } #define CHIP_FIRMWARE_UPDATE_TIMEOUT 20000 /* 20s */ @@ -452,8 +454,6 @@ const char * FrskyChipFirmwareUpdate::waitAnswer(uint8_t & status) const char * FrskyChipFirmwareUpdate::startBootloader() { - telemetryPortSetDirectionOutput(); - sportSendByte(0x01); for (uint8_t i = 0; i < 30; i++) @@ -489,8 +489,6 @@ void FrskyChipFirmwareUpdate::sendByte(uint8_t byte, bool crcFlag) const char * FrskyChipFirmwareUpdate::sendUpgradeCommand(char command, uint32_t packetsCount) { - telemetryPortSetDirectionOutput(); - crc = 0; // Head @@ -532,8 +530,6 @@ const char * FrskyChipFirmwareUpdate::sendUpgradeCommand(char command, uint32_t const char * FrskyChipFirmwareUpdate::sendUpgradeData(uint32_t index, uint8_t * data) { - telemetryPortSetDirectionOutput(); - crc = 0; // Head @@ -620,7 +616,7 @@ const char * FrskyChipFirmwareUpdate::doFlashFirmware(const char * filename) return sendUpgradeCommand('E', packetsCount); } -void FrskyChipFirmwareUpdate::flashFirmware(const char * filename) +const char * FrskyChipFirmwareUpdate::flashFirmware(const char * filename, bool wait) { drawProgressScreen(getBasename(filename), STR_DEVICE_RESET, 0, 0); @@ -636,9 +632,11 @@ void FrskyChipFirmwareUpdate::flashFirmware(const char * filename) SPORT_UPDATE_POWER_OFF(); - /* wait 2s off */ - watchdogSuspend(2000); - RTOS_WAIT_MS(2000); + if (wait) { + /* wait 2s off */ + watchdogSuspend(2000); + RTOS_WAIT_MS(2000); + } telemetryInit(PROTOCOL_TELEMETRY_FRSKY_SPORT); @@ -655,13 +653,6 @@ void FrskyChipFirmwareUpdate::flashFirmware(const char * filename) POPUP_INFORMATION(STR_FIRMWARE_UPDATE_SUCCESS); } -#if defined(HARDWARE_INTERNAL_MODULE) - INTERNAL_MODULE_OFF(); -#endif - - EXTERNAL_MODULE_OFF(); - SPORT_UPDATE_POWER_OFF(); - /* wait 2s off */ watchdogSuspend(2000); RTOS_WAIT_MS(2000); @@ -679,4 +670,6 @@ void FrskyChipFirmwareUpdate::flashFirmware(const char * filename) } resumePulses(); + + return result; } diff --git a/radio/src/io/frsky_firmware_update.h b/radio/src/io/frsky_firmware_update.h index f0724a6db..dea3adb33 100644 --- a/radio/src/io/frsky_firmware_update.h +++ b/radio/src/io/frsky_firmware_update.h @@ -22,6 +22,7 @@ #define _FRSKY_FIRMWARE_UPDATE_H_ #include "dataconstants.h" +#include "definitions.h" #include "frsky_pxx2.h" enum FrskyFirmwareProductFamily { @@ -65,7 +66,7 @@ class FrskyDeviceFirmwareUpdate { module(module) { } - void flashFirmware(const char * filename); + const char * flashFirmware(const char * filename); protected: uint8_t state = SPORT_IDLE; @@ -96,7 +97,7 @@ class FrskyChipFirmwareUpdate { { } - void flashFirmware(const char * filename); + const char * flashFirmware(const char * filename, bool wait = true); protected: uint8_t crc; diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index d43959145..c635c147e 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -18,6 +18,7 @@ * GNU General Public License for more details. */ +#include #include "opentx.h" RadioData g_eeGeneral; @@ -1753,10 +1754,19 @@ void opentxInit() unexpectedShutdown = 1; } -#if defined(SDCARD) && !defined(PCBMEGA2560) +#if defined(SDCARD) // SDCARD related stuff, only done if not unexpectedShutdown if (!unexpectedShutdown) { sdInit(); + +#if defined(AUTOUPDATE) + if (f_stat(AUTOUPDATE_FILENAME, nullptr) == FR_OK) { + FrskyChipFirmwareUpdate device; + if (device.flashFirmware(AUTOUPDATE_FILENAME, false) == nullptr) + f_unlink(AUTOUPDATE_FILENAME); + } +#endif + logsInit(); } #endif diff --git a/radio/src/sdcard.h b/radio/src/sdcard.h index 5f39d936a..2b86198a4 100644 --- a/radio/src/sdcard.h +++ b/radio/src/sdcard.h @@ -37,6 +37,7 @@ #define SYSTEM_SUBDIR "SYSTEM" #define BITMAPS_PATH ROOT_PATH "IMAGES" #define FIRMWARES_PATH ROOT_PATH "FIRMWARE" +#define AUTOUPDATE_FILENAME FIRMWARES_PATH "/autoupdate.frsk" #define EEPROMS_PATH ROOT_PATH "EEPROM" #define SCRIPTS_PATH ROOT_PATH "SCRIPTS" #define WIZARD_PATH SCRIPTS_PATH "/WIZARD" diff --git a/radio/src/targets/horus/telemetry_driver.cpp b/radio/src/targets/horus/telemetry_driver.cpp index 6d9276ef1..8b782f759 100644 --- a/radio/src/targets/horus/telemetry_driver.cpp +++ b/radio/src/targets/horus/telemetry_driver.cpp @@ -140,10 +140,40 @@ void telemetryPortSetDirectionInput() void sportSendByte(uint8_t byte) { + telemetryPortSetDirectionOutput(); + while (!(TELEMETRY_USART->SR & USART_SR_TXE)); USART_SendData(TELEMETRY_USART, byte); } +void sportSendByteLoop(uint8_t byte) +{ + telemetryPortSetDirectionOutput(); + + outputTelemetryBuffer.data[0] = byte; + + DMA_InitTypeDef DMA_InitStructure; + DMA_DeInit(TELEMETRY_DMA_Stream_TX); + DMA_InitStructure.DMA_Channel = TELEMETRY_DMA_Channel_TX; + DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&TELEMETRY_USART->DR); + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; + DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(outputTelemetryBuffer.data); + DMA_InitStructure.DMA_BufferSize = 1; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; + DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_Init(TELEMETRY_DMA_Stream_TX, &DMA_InitStructure); + DMA_Cmd(TELEMETRY_DMA_Stream_TX, ENABLE); + USART_DMACmd(TELEMETRY_USART, USART_DMAReq_Tx, ENABLE); +} + 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 aabd04a3c..2be5745fb 100644 --- a/radio/src/targets/taranis/CMakeLists.txt +++ b/radio/src/targets/taranis/CMakeLists.txt @@ -4,6 +4,7 @@ option(INTERNAL_MODULE_PPM "Support for PPM internal module hack" OFF) option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module replacement" OFF) option(PXX1 "PXX1 protocol support" ON) option(PXX2 "PXX2 protocol support" OFF) +option(AUTOUPDATE "Auto update internal chips from SD" OFF) if(PCB STREQUAL X9E) set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)") @@ -204,6 +205,10 @@ if(PCB STREQUAL X9E OR PCB STREQUAL X7 OR PCB STREQUAL XLITE OR PCB STREQUAL XLI ) endif() +if(AUTOUPDATE) + add_definitions(-DAUTOUPDATE) +endif() + set(HSE_VALUE 12000000) set(SDCARD YES) set(EEPROM EEPROM_RLC) diff --git a/radio/src/targets/taranis/board.cpp b/radio/src/targets/taranis/board.cpp index cd7cfec62..d6f949a50 100644 --- a/radio/src/targets/taranis/board.cpp +++ b/radio/src/targets/taranis/board.cpp @@ -137,6 +137,11 @@ void boardInit() pwrInit(); +#if defined(AUTOUPDATE) + telemetryPortInit(FRSKY_SPORT_BAUDRATE, TELEMETRY_SERIAL_WITHOUT_DMA); + sportSendByteLoop(0x7E); +#endif + #if defined(STATUS_LEDS) ledInit(); ledGreen(); diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h index 97dfe397e..e5ea488be 100644 --- a/radio/src/targets/taranis/board.h +++ b/radio/src/targets/taranis/board.h @@ -704,6 +704,7 @@ void telemetryPortInit(uint32_t baudrate, uint8_t mode); void telemetryPortSetDirectionInput(void); void telemetryPortSetDirectionOutput(void); void sportSendByte(uint8_t byte); +void sportSendByteLoop(uint8_t byte); void sportSendBuffer(const uint8_t * buffer, uint32_t count); uint8_t telemetryGetByte(uint8_t * byte); void telemetryClearFifo(); diff --git a/radio/src/targets/taranis/telemetry_driver.cpp b/radio/src/targets/taranis/telemetry_driver.cpp index dc82fcd81..f46331bc0 100644 --- a/radio/src/targets/taranis/telemetry_driver.cpp +++ b/radio/src/targets/taranis/telemetry_driver.cpp @@ -97,10 +97,40 @@ void telemetryPortSetDirectionInput() void sportSendByte(uint8_t byte) { + telemetryPortSetDirectionOutput(); + while (!(TELEMETRY_USART->SR & USART_SR_TXE)); USART_SendData(TELEMETRY_USART, byte); } +void sportSendByteLoop(uint8_t byte) +{ + telemetryPortSetDirectionOutput(); + + outputTelemetryBuffer.data[0] = byte; + + DMA_InitTypeDef DMA_InitStructure; + DMA_DeInit(TELEMETRY_DMA_Stream_TX); + DMA_InitStructure.DMA_Channel = TELEMETRY_DMA_Channel_TX; + DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&TELEMETRY_USART->DR); + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; + DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(outputTelemetryBuffer.data); + DMA_InitStructure.DMA_BufferSize = 1; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; + DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_Init(TELEMETRY_DMA_Stream_TX, &DMA_InitStructure); + DMA_Cmd(TELEMETRY_DMA_Stream_TX, ENABLE); + USART_DMACmd(TELEMETRY_USART, USART_DMAReq_Tx, ENABLE); +} + void sportSendBuffer(const uint8_t * buffer, uint32_t count) { telemetryPortSetDirectionOutput(); diff --git a/tools/build-frsky.py b/tools/build-frsky.py index 8a6078adf..7d1efd68f 100755 --- a/tools/build-frsky.py +++ b/tools/build-frsky.py @@ -12,6 +12,7 @@ options = { "XLITES": { "LUA": "NO_MODEL_SCRIPTS", "GVARS": "YES", + "AUTOUPDATE": "YES", "PXX1": "YES", "XJT": "NO", "R9M_SIZE_STD": "NO", @@ -23,6 +24,7 @@ options = { "X9LITE": { "LUA": "NO_MODEL_SCRIPTS", "GVARS": "YES", + "AUTOUPDATE": "YES", "PXX1": "YES", "XJT": "NO", "R9M_SIZE_STD": "NO",