diff --git a/radio/src/crc16.cpp b/radio/src/crc.cpp similarity index 66% rename from radio/src/crc16.cpp rename to radio/src/crc.cpp index caa3c94b9..a5f1d09c1 100644 --- a/radio/src/crc16.cpp +++ b/radio/src/crc.cpp @@ -18,10 +18,10 @@ * GNU General Public License for more details. */ -#include +#include "crc.h" // CRC16 implementation according to CCITT standards -static const unsigned short crc16tab[256] = { +static const unsigned short crc16tab_1021[256] = { 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, @@ -56,11 +56,52 @@ static const unsigned short crc16tab[256] = { 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 }; -uint16_t crc16(const uint8_t * buf, uint32_t len) +static const unsigned short crc16tab_1189[256] = { + 0x0000,0x1189,0x2312,0x329b,0x4624,0x57ad,0x6536,0x74bf, + 0x8c48,0x9dc1,0xaf5a,0xbed3,0xca6c,0xdbe5,0xe97e,0xf8f7, + 0x1081,0x0108,0x3393,0x221a,0x56a5,0x472c,0x75b7,0x643e, + 0x9cc9,0x8d40,0xbfdb,0xae52,0xdaed,0xcb64,0xf9ff,0xe876, + 0x2102,0x308b,0x0210,0x1399,0x6726,0x76af,0x4434,0x55bd, + 0xad4a,0xbcc3,0x8e58,0x9fd1,0xeb6e,0xfae7,0xc87c,0xd9f5, + 0x3183,0x200a,0x1291,0x0318,0x77a7,0x662e,0x54b5,0x453c, + 0xbdcb,0xac42,0x9ed9,0x8f50,0xfbef,0xea66,0xd8fd,0xc974, + 0x4204,0x538d,0x6116,0x709f,0x0420,0x15a9,0x2732,0x36bb, + 0xce4c,0xdfc5,0xed5e,0xfcd7,0x8868,0x99e1,0xab7a,0xbaf3, + 0x5285,0x430c,0x7197,0x601e,0x14a1,0x0528,0x37b3,0x263a, + 0xdecd,0xcf44,0xfddf,0xec56,0x98e9,0x8960,0xbbfb,0xaa72, + 0x6306,0x728f,0x4014,0x519d,0x2522,0x34ab,0x0630,0x17b9, + 0xef4e,0xfec7,0xcc5c,0xddd5,0xa96a,0xb8e3,0x8a78,0x9bf1, + 0x7387,0x620e,0x5095,0x411c,0x35a3,0x242a,0x16b1,0x0738, + 0xffcf,0xee46,0xdcdd,0xcd54,0xb9eb,0xa862,0x9af9,0x8b70, + 0x8408,0x9581,0xa71a,0xb693,0xc22c,0xd3a5,0xe13e,0xf0b7, + 0x0840,0x19c9,0x2b52,0x3adb,0x4e64,0x5fed,0x6d76,0x7cff, + 0x9489,0x8500,0xb79b,0xa612,0xd2ad,0xc324,0xf1bf,0xe036, + 0x18c1,0x0948,0x3bd3,0x2a5a,0x5ee5,0x4f6c,0x7df7,0x6c7e, + 0xa50a,0xb483,0x8618,0x9791,0xe32e,0xf2a7,0xc03c,0xd1b5, + 0x2942,0x38cb,0x0a50,0x1bd9,0x6f66,0x7eef,0x4c74,0x5dfd, + 0xb58b,0xa402,0x9699,0x8710,0xf3af,0xe226,0xd0bd,0xc134, + 0x39c3,0x284a,0x1ad1,0x0b58,0x7fe7,0x6e6e,0x5cf5,0x4d7c, + 0xc60c,0xd785,0xe51e,0xf497,0x8028,0x91a1,0xa33a,0xb2b3, + 0x4a44,0x5bcd,0x6956,0x78df,0x0c60,0x1de9,0x2f72,0x3efb, + 0xd68d,0xc704,0xf59f,0xe416,0x90a9,0x8120,0xb3bb,0xa232, + 0x5ac5,0x4b4c,0x79d7,0x685e,0x1ce1,0x0d68,0x3ff3,0x2e7a, + 0xe70e,0xf687,0xc41c,0xd595,0xa12a,0xb0a3,0x8238,0x93b1, + 0x6b46,0x7acf,0x4854,0x59dd,0x2d62,0x3ceb,0x0e70,0x1ff9, + 0xf78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330, + 0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78 +}; + +static const unsigned short * crc16tab[] = { + crc16tab_1021, + crc16tab_1189 +}; + +uint16_t crc16(uint8_t index, const uint8_t * buf, uint32_t len, uint16_t start) { - uint16_t crc = 0; + uint16_t crc = start; + const unsigned short * tab = crc16tab[index]; for (uint32_t i=0; i>8) ^ *buf++) & 0x00FF]; + crc = (crc<<8) ^ tab[((crc>>8) ^ *buf++) & 0x00FF]; } return crc; } diff --git a/radio/src/crc.h b/radio/src/crc.h new file mode 100644 index 000000000..7f6c46d26 --- /dev/null +++ b/radio/src/crc.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __CRC_H__ +#define __CRC_H__ + +#include + +enum { + CRC_1021, + CRC_1189, +}; + +uint8_t crc8(const uint8_t * ptr, uint32_t len); +uint16_t crc16(uint8_t index, const uint8_t * buf, uint32_t len, uint16_t start = 0); + +#endif diff --git a/radio/src/gui/480x272/view_statistics.cpp b/radio/src/gui/480x272/view_statistics.cpp index 98eae593c..7d15bc2e9 100644 --- a/radio/src/gui/480x272/view_statistics.cpp +++ b/radio/src/gui/480x272/view_statistics.cpp @@ -166,9 +166,21 @@ bool menuStatsDebug(event_t event) y += FH; #endif +#if defined(DEBUG_LATENCY) + lcdDrawText(MENUS_MARGIN_LEFT, y, "Hearbeat"); + if (heartbeatCapture.valid) + lcdDrawNumber(MENU_STATS_COLUMN1, y, heartbeatCapture.count, LEFT); + else + lcdDrawText(MENU_STATS_COLUMN1, y, "---"); + y += FH; +#endif + +#if 0 + // TODO in a debug mode? lcdDrawText(MENUS_MARGIN_LEFT, y, "Telem RX Errs"); lcdDrawNumber(MENU_STATS_COLUMN1, y, telemetryErrors, LEFT); y += FH; +#endif #if defined(INTERNAL_GPS) lcdDrawText(MENUS_MARGIN_LEFT, y, "Internal GPS"); diff --git a/radio/src/io/frsky_firmware_update.cpp b/radio/src/io/frsky_firmware_update.cpp index 71b3c3689..b976528b0 100644 --- a/radio/src/io/frsky_firmware_update.cpp +++ b/radio/src/io/frsky_firmware_update.cpp @@ -101,7 +101,7 @@ void FrskyDeviceFirmwareUpdate::startup() switch(module) { #if defined(INTMODULE_USART) case INTERNAL_MODULE: - intmoduleSerialStart(57600, true); + intmoduleSerialStart(INTMODULE_FLASH_BAUDRATE, true); break; #endif @@ -118,6 +118,36 @@ void FrskyDeviceFirmwareUpdate::startup() SPORT_UPDATE_POWER_ON(); } +bool FrskyDeviceFirmwareUpdate::readBuffer(uint8_t * buffer, uint8_t count, uint32_t timeout) +{ + uint32_t elapsed = 0; + uint8_t index = 0; + + watchdogSuspend(timeout); + + switch(module) { +#if defined(INTMODULE_USART) + case INTERNAL_MODULE: + while (index < count && elapsed < timeout) { + if (intmoduleFifo.pop(buffer[index])) { + ++index; + } + else { + RTOS_WAIT_MS(1); + if (++elapsed == timeout) + return false; + } + } + break; +#endif + + default: + break; + } + + return true; +} + const uint8_t * FrskyDeviceFirmwareUpdate::readFullDuplexFrame(ModuleFifo & fifo, uint32_t timeout) { uint8_t len = 0; @@ -215,7 +245,7 @@ void FrskyDeviceFirmwareUpdate::sendFrame() uint8_t * ptr = outputTelemetryBuffer.data; *ptr++ = 0x7E; *ptr++ = 0xFF; - frame[7] = crc16(frame, 7); + frame[7] = crc16(CRC_1021, frame, 7); for (int i=0; i<8; i++) { if (frame[i] == 0x7E || frame[i] == 0x7D) { *ptr++ = 0x7D; @@ -298,6 +328,61 @@ const char * FrskyDeviceFirmwareUpdate::uploadFile(const char * filename) } } +#if defined(PCBHORUS) + uint8_t frame[8]; + + if (!readBuffer(frame, 8, 100) || frame[0] != 0x01) { + return TR("Not responding", "Device not responding"); + } + + intmoduleSendByte(0x81); + readBuffer(frame, 1, 100); + + if (!readBuffer(frame, 8, 100) || frame[0] != 0x02) { + return TR("Not responding", "Device not responding"); + } + + intmoduleSendByte(0x82); + readBuffer(frame, 1, 100); + + uint8_t index = 0; + while (1) { + drawProgressScreen(getBasename(filename), STR_WRITING, file.fptr, file.obj.objsize); + + if (f_read(&file, buffer, 1024, &count) != FR_OK) { + f_close(&file); + return "Error reading file"; + } + + if (!readBuffer(frame, 2, 100)) + return "Data refused"; + + if (frame[0] != 0x11 || frame[1] != index) + return "Wrong request"; + + if (count == 0) { + f_close(&file); + intmoduleSendByte(0xA1); + RTOS_WAIT_MS(50); + return nullptr; + } + + if (count < 1024) + memset(((uint8_t *)buffer) + count, 0, 1024 - count); + + intmoduleSendByte(frame[0] + 0x80); + intmoduleSendByte(frame[1]); + + uint16_t crc_16 = crc16(CRC_1189, (uint8_t *)buffer, 1024, crc16(CRC_1189, &frame[1], 1)); + for (unsigned i = 0; i < sizeof(buffer); i++) { + intmoduleSendByte(((uint8_t *)buffer)[i]); + } + intmoduleSendByte(crc_16 >> 8); + intmoduleSendByte(crc_16); + + index++; + } +#else RTOS_WAIT_MS(200); telemetryClearFifo(); @@ -333,6 +418,7 @@ const char * FrskyDeviceFirmwareUpdate::uploadFile(const char * filename) return nullptr; } } +#endif } const char * FrskyDeviceFirmwareUpdate::endTransfer() @@ -347,6 +433,28 @@ const char * FrskyDeviceFirmwareUpdate::endTransfer() return nullptr; } +const char * FrskyDeviceFirmwareUpdate::doFlashFirmware(const char * filename) +{ + const char * result; + +#if defined(PCBHORUS) + if (module == INTERNAL_MODULE) { + intmoduleSerialStart(38400, true); + GPIO_SetBits(INTMODULE_BOOTCMD_GPIO, INTMODULE_BOOTCMD_GPIO_PIN); + result = uploadFile(filename); + GPIO_ResetBits(INTMODULE_BOOTCMD_GPIO, INTMODULE_BOOTCMD_GPIO_PIN); + return result; + } +#endif + + result = sendPowerOn(); + if (!result) result = sendReqVersion(); + if (!result) result = uploadFile(filename); + if (!result) result = endTransfer(); + + return result; +} + const char * FrskyDeviceFirmwareUpdate::flashFirmware(const char * filename) { pausePulses(); @@ -369,10 +477,7 @@ const char * FrskyDeviceFirmwareUpdate::flashFirmware(const char * filename) startup(); - const char * result = sendPowerOn(); - if (!result) result = sendReqVersion(); - if (!result) result = uploadFile(filename); - if (!result) result = endTransfer(); + const char * result = doFlashFirmware(filename); AUDIO_PLAY(AU_SPECIAL_SOUND_BEEP1 ); BACKLIGHT_ENABLE(); diff --git a/radio/src/io/frsky_firmware_update.h b/radio/src/io/frsky_firmware_update.h index dea3adb33..e23b5cb98 100644 --- a/radio/src/io/frsky_firmware_update.h +++ b/radio/src/io/frsky_firmware_update.h @@ -79,12 +79,14 @@ class FrskyDeviceFirmwareUpdate { void startFrame(uint8_t command); void sendFrame(); + bool readBuffer(uint8_t * buffer, uint8_t count, uint32_t timeout); const uint8_t * readFullDuplexFrame(ModuleFifo & fifo, uint32_t timeout); const uint8_t * readHalfDuplexFrame(uint32_t timeout); const uint8_t * readFrame(uint32_t timeout); bool waitState(State state, uint32_t timeout); void processFrame(const uint8_t * frame); + const char * doFlashFirmware(const char * filename); const char * sendPowerOn(); const char * sendReqVersion(); const char * uploadFile(const char * filename); diff --git a/radio/src/opentx.h b/radio/src/opentx.h index 7e1ce57df..952296a1c 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -946,9 +946,7 @@ inline void customFunctionsReset() } #include "telemetry/telemetry.h" - -uint8_t crc8(const uint8_t * ptr, uint32_t len); -uint16_t crc16(const uint8_t * ptr, uint32_t len); +#include "crc.h" #define PLAY_REPEAT(x) (x) /* Range 0 to 15 */ #define PLAY_NOW 0x10 diff --git a/radio/src/targets/common/arm/CMakeLists.txt b/radio/src/targets/common/arm/CMakeLists.txt index 43e9b6868..641468504 100644 --- a/radio/src/targets/common/arm/CMakeLists.txt +++ b/radio/src/targets/common/arm/CMakeLists.txt @@ -190,7 +190,7 @@ set(SRC telemetry/frsky_d.cpp telemetry/frsky_sport.cpp telemetry/frsky_pxx2.cpp - crc16.cpp + crc.cpp vario.cpp ) diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index dc890cd1e..d9d6360eb 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -571,6 +571,7 @@ #define INTMODULE_BOOTCMD_GPIO GPIOI #define INTMODULE_BOOTCMD_GPIO_PIN GPIO_Pin_9 // PI.09 #endif +#define INTMODULE_FLASH_BAUDRATE 38400 #if defined(PCBX10) || PCBREV >= 13 #define INTMODULE_RCC_APB1Periph RCC_APB1Periph_TIM2 #define INTMODULE_RCC_APB2Periph RCC_APB2Periph_USART1 diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index bfac13e42..604ea7e8f 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -864,9 +864,10 @@ #define INTMODULE_DMA_FLAG_TC DMA_IT_TCIF7 #define INTMODULE_DMA_CHANNEL DMA_Channel_4 #if defined(PCBXLITES) - #define INTMODULE_BOOTCMD_GPIO GPIOC - #define INTMODULE_BOOTCMD_GPIO_PIN GPIO_Pin_8 // PC.08 + #define INTMODULE_BOOTCMD_GPIO GPIOC + #define INTMODULE_BOOTCMD_GPIO_PIN GPIO_Pin_8 // PC.08 #endif +#define INTMODULE_FLASH_BAUDRATE 57600 #elif defined(PCBX9E) || defined(PCBX9DP) || defined(RADIO_X7) #define INTMODULE_PULSES #define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_DMA2)