mirror of
https://github.com/EdgeTX/edgetx.git
synced 2025-07-25 09:15:21 +03:00
Added support for flashing AVR multi on horus targets (#6888)
* Added support for flashing AVR multi on horus targets taranis soft serial Added support for flashing AVR multi on horus targets taranis soft serial * Added support for multi V2 signature (hex code) * Check multi signature before flashing * small clean-up * Cosmetics * Fix v2 signature check * Cosmetics
This commit is contained in:
parent
f1d8083064
commit
aaafe445db
26 changed files with 544 additions and 88 deletions
|
@ -220,6 +220,7 @@ void onSdManagerMenu(const char * result)
|
|||
FrskyDeviceFirmwareUpdate device(SPORT_MODULE);
|
||||
device.flashFirmware(lfn);
|
||||
}
|
||||
#if defined(MULTIMODULE)
|
||||
#if defined(INTERNAL_MODULE_MULTI)
|
||||
else if (result == STR_FLASH_INTERNAL_MULTI) {
|
||||
getSelectionFullPath(lfn);
|
||||
|
@ -230,6 +231,7 @@ void onSdManagerMenu(const char * result)
|
|||
getSelectionFullPath(lfn);
|
||||
multiFlashFirmware(EXTERNAL_MODULE, lfn);
|
||||
}
|
||||
#endif
|
||||
#if defined(BLUETOOTH)
|
||||
else if (result == STR_FLASH_BLUETOOTH_MODULE) {
|
||||
getSelectionFullPath(lfn);
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
|
||||
#define UPDATE_MULTI_EXT_BIN ".bin"
|
||||
|
||||
//#define DEBUG_EXT_MODULE_FLASH
|
||||
|
||||
class MultiFirmwareUpdateDriver
|
||||
{
|
||||
public:
|
||||
|
@ -39,6 +37,7 @@ class MultiFirmwareUpdateDriver
|
|||
virtual bool getByte(uint8_t& byte) const = 0;
|
||||
virtual void sendByte(uint8_t byte) const = 0;
|
||||
virtual void clear() const = 0;
|
||||
virtual void deinit() const {}
|
||||
|
||||
private:
|
||||
bool getRxByte(uint8_t& byte) const;
|
||||
|
@ -47,6 +46,7 @@ class MultiFirmwareUpdateDriver
|
|||
const char * getDeviceSignature(uint8_t* signature) const;
|
||||
const char * loadAddress(uint32_t offset) const;
|
||||
const char * progPage(uint8_t* buffer, uint16_t size) const;
|
||||
void leaveProgMode() const;
|
||||
};
|
||||
|
||||
#if defined(INTERNAL_MODULE_MULTI)
|
||||
|
@ -77,16 +77,21 @@ class MultiInternalUpdateDriver: public MultiFirmwareUpdateDriver
|
|||
{
|
||||
intmoduleFifo.clear();
|
||||
}
|
||||
|
||||
void deinit() const override
|
||||
{
|
||||
clear();
|
||||
}
|
||||
};
|
||||
|
||||
static const MultiInternalUpdateDriver multiInternalUpdateDriver;
|
||||
|
||||
#endif
|
||||
|
||||
class MultiExternalUpdateDriver: public MultiFirmwareUpdateDriver
|
||||
class MultiExternalSoftSerialUpdateDriver: public MultiFirmwareUpdateDriver
|
||||
{
|
||||
public:
|
||||
MultiExternalUpdateDriver() = default;
|
||||
MultiExternalSoftSerialUpdateDriver() = default;
|
||||
|
||||
protected:
|
||||
void init() const override
|
||||
|
@ -102,7 +107,7 @@ class MultiExternalUpdateDriver: public MultiFirmwareUpdateDriver
|
|||
#endif
|
||||
|
||||
EXTERNAL_MODULE_ON();
|
||||
telemetryPortInit(57600, TELEMETRY_SERIAL_DEFAULT);
|
||||
telemetryPortInvertedInit(57600);
|
||||
}
|
||||
|
||||
bool getByte(uint8_t& byte) const override
|
||||
|
@ -119,9 +124,15 @@ class MultiExternalUpdateDriver: public MultiFirmwareUpdateDriver
|
|||
{
|
||||
telemetryClearFifo();
|
||||
}
|
||||
|
||||
void deinit() const override
|
||||
{
|
||||
telemetryPortInvertedInit(0);
|
||||
clear();
|
||||
}
|
||||
};
|
||||
|
||||
static const MultiExternalUpdateDriver multiExternalUpdateDriver;
|
||||
static const MultiExternalSoftSerialUpdateDriver multiExternalSoftSerialUpdateDriver;
|
||||
|
||||
bool MultiFirmwareUpdateDriver::getRxByte(uint8_t& byte) const
|
||||
{
|
||||
|
@ -150,10 +161,10 @@ bool MultiFirmwareUpdateDriver::checkRxByte(uint8_t byte) const
|
|||
|
||||
const char * MultiFirmwareUpdateDriver::waitForInitialSync() const
|
||||
{
|
||||
clear();
|
||||
|
||||
uint8_t byte;
|
||||
int retries = 1000;
|
||||
|
||||
clear();
|
||||
do {
|
||||
// Send sync request
|
||||
sendByte(STK_GET_SYNC);
|
||||
|
@ -214,16 +225,14 @@ const char * MultiFirmwareUpdateDriver::loadAddress(uint32_t offset) const
|
|||
const char * MultiFirmwareUpdateDriver::progPage(uint8_t* buffer, uint16_t size) const
|
||||
{
|
||||
sendByte(STK_PROG_PAGE);
|
||||
// page size 256
|
||||
sendByte(1);
|
||||
sendByte(0);
|
||||
|
||||
// page size
|
||||
sendByte(size >> 8);
|
||||
sendByte(size & 0xFF);
|
||||
|
||||
// flash/eeprom flag
|
||||
sendByte(0);
|
||||
|
||||
// #if defined(DEBUG_EXT_MODULE_FLASH)
|
||||
// TRACE("writing at 0x%X", writeOffset << 1);
|
||||
// #endif
|
||||
|
||||
for (uint16_t i=0; i < size; i++) {
|
||||
sendByte(buffer[i]);
|
||||
}
|
||||
|
@ -245,6 +254,16 @@ const char * MultiFirmwareUpdateDriver::progPage(uint8_t* buffer, uint16_t size)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void MultiFirmwareUpdateDriver::leaveProgMode() const
|
||||
{
|
||||
sendByte(STK_LEAVE_PROGMODE);
|
||||
sendByte(CRC_EOP);
|
||||
|
||||
// eat last sync byte
|
||||
checkRxByte(STK_INSYNC);
|
||||
deinit();
|
||||
}
|
||||
|
||||
const char * MultiFirmwareUpdateDriver::flashFirmware(FIL* file, const char* label) const
|
||||
{
|
||||
const char* result = nullptr;
|
||||
|
@ -255,24 +274,39 @@ const char * MultiFirmwareUpdateDriver::flashFirmware(FIL* file, const char* lab
|
|||
RTOS_WAIT_MS(500);
|
||||
|
||||
result = waitForInitialSync();
|
||||
if (result != nullptr)
|
||||
if (result) {
|
||||
leaveProgMode();
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned char signature[4]; // 3 bytes signature + STK_OK
|
||||
result = getDeviceSignature(signature);
|
||||
if (result != nullptr)
|
||||
if (result) {
|
||||
leaveProgMode();
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t buffer[256]; // page size = 256
|
||||
uint32_t writeOffset = 0x1000; // start offset (word address)
|
||||
uint8_t buffer[256];
|
||||
uint16_t pageSize = 128;
|
||||
uint32_t writeOffset = 0;
|
||||
|
||||
if (signature[0] != 0x1E) {
|
||||
leaveProgMode();
|
||||
return "Wrong signature";
|
||||
}
|
||||
|
||||
if (signature[1] == 0x55 && signature[2] == 0xAA) {
|
||||
pageSize = 256;
|
||||
writeOffset = 0x1000; // start offset (word address)
|
||||
}
|
||||
|
||||
while (!f_eof(file)) {
|
||||
|
||||
drawProgressScreen(label, STR_WRITING, file->fptr, file->obj.objsize);
|
||||
|
||||
UINT count=0;
|
||||
memclear(buffer, 256);
|
||||
if (f_read(file, buffer, 256, &count) != FR_OK) {
|
||||
memclear(buffer, pageSize);
|
||||
if (f_read(file, buffer, pageSize, &count) != FR_OK) {
|
||||
result = "Error reading file";
|
||||
break;
|
||||
}
|
||||
|
@ -283,28 +317,23 @@ const char * MultiFirmwareUpdateDriver::flashFirmware(FIL* file, const char* lab
|
|||
clear();
|
||||
|
||||
result = loadAddress(writeOffset);
|
||||
if (result != nullptr) {
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
|
||||
result = progPage(buffer, 256);
|
||||
if (result != nullptr) {
|
||||
result = progPage(buffer, pageSize);
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
|
||||
writeOffset += 128; // page / 2
|
||||
writeOffset += pageSize / 2;
|
||||
}
|
||||
|
||||
if (f_eof(file)) {
|
||||
drawProgressScreen(label, STR_WRITING, file->fptr, file->obj.objsize);
|
||||
}
|
||||
|
||||
sendByte(STK_LEAVE_PROGMODE);
|
||||
sendByte(CRC_EOP);
|
||||
|
||||
// eat last sync byte
|
||||
checkRxByte(STK_INSYNC);
|
||||
|
||||
leaveProgMode();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -316,19 +345,9 @@ const char * MultiFirmwareUpdateDriver::flashFirmware(FIL* file, const char* lab
|
|||
#define MULTI_SIGN_TELEM_INVERSION_OFFSET 13
|
||||
#define MULTI_SIGN_VERSION_OFFSET 15
|
||||
|
||||
const char * MultiFirmwareInformation::readMultiFirmwareInformation(const char * filename)
|
||||
const char * MultiFirmwareInformation::readV1Signature(const char * buffer)
|
||||
{
|
||||
FIL file;
|
||||
f_open(&file, filename, FA_READ);
|
||||
char buffer[MULTI_SIGN_SIZE];
|
||||
UINT count;
|
||||
|
||||
f_lseek(&file, f_size(&file) - MULTI_SIGN_SIZE);
|
||||
if (f_read(&file, buffer, MULTI_SIGN_SIZE, &count) != FR_OK || count != MULTI_SIGN_SIZE) {
|
||||
return "Error reading file";
|
||||
}
|
||||
|
||||
if(!memcmp(buffer, "multi-stm", 9))
|
||||
if (!memcmp(buffer, "multi-stm", 9))
|
||||
boardType = FIRMWARE_MULTI_STM;
|
||||
else if (!memcmp(buffer, "multi-avr", 9))
|
||||
boardType = FIRMWARE_MULTI_AVR;
|
||||
|
@ -348,9 +367,9 @@ const char * MultiFirmwareInformation::readMultiFirmwareInformation(const char *
|
|||
bootloaderCheck = false;
|
||||
|
||||
if(buffer[MULTI_SIGN_TELEM_TYPE_OFFSET] == 't')
|
||||
telemetryType = FIRMWARE_MULTI_TELEM_MULTI;
|
||||
telemetryType = FIRMWARE_MULTI_TELEM_MULTI_STATUS;
|
||||
else if (buffer[MULTI_SIGN_TELEM_TYPE_OFFSET] == 's')
|
||||
telemetryType = FIRMWARE_MULTI_TELEM_STATUS;
|
||||
telemetryType = FIRMWARE_MULTI_TELEM_MULTI_TELEMETRY;
|
||||
else
|
||||
telemetryType = FIRMWARE_MULTI_TELEM_NONE;
|
||||
|
||||
|
@ -362,23 +381,115 @@ const char * MultiFirmwareInformation::readMultiFirmwareInformation(const char *
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
const char * MultiFirmwareInformation::readV2Signature(const char * buffer)
|
||||
{
|
||||
// new format
|
||||
uint32_t options = 0;
|
||||
const char * beg = buffer + 7;
|
||||
const char * cursor = beg;
|
||||
|
||||
while (cursor - beg < 8) {
|
||||
options <<= 4;
|
||||
if (*cursor >= '0' && *cursor <= '9')
|
||||
options |= *cursor - '0';
|
||||
else if (*cursor >= 'a' && *cursor <= 'f')
|
||||
options |= *cursor - 'a' + 10;
|
||||
else if (*cursor >= 'A' && *cursor <= 'F')
|
||||
options |= *cursor - 'A' + 10;
|
||||
else
|
||||
break; // should be '-'
|
||||
cursor++;
|
||||
}
|
||||
|
||||
if (cursor - beg < 8)
|
||||
return "Invalid signature";
|
||||
|
||||
const char * multiFlashFirmware(uint8_t moduleIdx, const char * filename)
|
||||
boardType = options & 0x3;
|
||||
optibootSupport = options & 0x80 ? true : false;
|
||||
telemetryInversion = options & 0x200 ? true : false;
|
||||
bootloaderCheck = options & 0x100 ? true : false;
|
||||
|
||||
telemetryType = FIRMWARE_MULTI_TELEM_NONE;
|
||||
if (options & 0x400)
|
||||
telemetryType = FIRMWARE_MULTI_TELEM_MULTI_STATUS;
|
||||
if (options & 0x800)
|
||||
telemetryType = FIRMWARE_MULTI_TELEM_MULTI_TELEMETRY;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char * MultiFirmwareInformation::readMultiFirmwareInformation(const char * filename)
|
||||
{
|
||||
FIL file;
|
||||
const char * result = nullptr;
|
||||
if (f_open(&file, filename, FA_READ) != FR_OK)
|
||||
return "Error opening file";
|
||||
|
||||
const char * ext = getFileExtension(filename);
|
||||
if (ext && strcasecmp(ext, UPDATE_MULTI_EXT_BIN)) {
|
||||
return "Wrong file extension";
|
||||
const char * err = readMultiFirmwareInformation(&file);
|
||||
f_close(&file);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
const char * MultiFirmwareInformation::readMultiFirmwareInformation(FIL * file)
|
||||
{
|
||||
char buffer[MULTI_SIGN_SIZE];
|
||||
UINT count;
|
||||
|
||||
if (f_size(file) < MULTI_SIGN_SIZE)
|
||||
return "File too small";
|
||||
|
||||
f_lseek(file, f_size(file) - MULTI_SIGN_SIZE);
|
||||
if (f_read(file, buffer, MULTI_SIGN_SIZE, &count) != FR_OK || count != MULTI_SIGN_SIZE) {
|
||||
return "Error reading file";
|
||||
}
|
||||
|
||||
if (!memcmp(buffer, "multi-x", 7)) {
|
||||
return readV2Signature(buffer);
|
||||
}
|
||||
|
||||
return readV1Signature(buffer);
|
||||
}
|
||||
|
||||
bool multiFlashFirmware(uint8_t moduleIdx, const char * filename)
|
||||
{
|
||||
FIL file;
|
||||
|
||||
if (f_open(&file, filename, FA_READ) != FR_OK) {
|
||||
return "Error opening file";
|
||||
POPUP_WARNING("Not a valid file");
|
||||
return false;
|
||||
}
|
||||
|
||||
MultiFirmwareInformation firmwareFile;
|
||||
if (firmwareFile.readMultiFirmwareInformation(&file)) {
|
||||
f_close(&file);
|
||||
POPUP_WARNING("Not a valid file");
|
||||
return false;
|
||||
}
|
||||
f_lseek(&file, 0);
|
||||
|
||||
if (moduleIdx == EXTERNAL_MODULE) {
|
||||
if (!firmwareFile.isMultiExternalFirmware()) {
|
||||
f_close(&file);
|
||||
POPUP_WARNING(STR_NEEDS_FILE);
|
||||
SET_WARNING_INFO(STR_EXT_MULTI_SPEC, strlen(STR_EXT_MULTI_SPEC), 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!firmwareFile.isMultiInternalFirmware()) {
|
||||
f_close(&file);
|
||||
POPUP_WARNING(STR_NEEDS_FILE);
|
||||
SET_WARNING_INFO(STR_INT_MULTI_SPEC, strlen(STR_INT_MULTI_SPEC), 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const MultiFirmwareUpdateDriver* driver = &multiExternalSoftSerialUpdateDriver;
|
||||
#if defined(INTERNAL_MODULE_MULTI)
|
||||
if (moduleIdx == INTERNAL_MODULE)
|
||||
driver = &multiInternalUpdateDriver;
|
||||
#endif
|
||||
|
||||
pausePulses();
|
||||
|
||||
#if defined(INTERNAL_MODULE_MULTI)
|
||||
|
@ -397,14 +508,7 @@ const char * multiFlashFirmware(uint8_t moduleIdx, const char * filename)
|
|||
watchdogSuspend(2000);
|
||||
RTOS_WAIT_MS(2000);
|
||||
|
||||
// TODO: real update here
|
||||
const MultiFirmwareUpdateDriver* driver = &multiExternalUpdateDriver;
|
||||
#if defined(INTERNAL_MODULE_MULTI)
|
||||
if (moduleIdx == INTERNAL_MODULE)
|
||||
driver = &multiInternalUpdateDriver;
|
||||
#endif
|
||||
|
||||
result = driver->flashFirmware(&file, getBasename(filename));
|
||||
const char * result = driver->flashFirmware(&file, getBasename(filename));
|
||||
f_close(&file);
|
||||
|
||||
AUDIO_PLAY(AU_SPECIAL_SOUND_BEEP1 );
|
||||
|
@ -425,8 +529,10 @@ const char * multiFlashFirmware(uint8_t moduleIdx, const char * filename)
|
|||
/* wait 2s off */
|
||||
watchdogSuspend(2000);
|
||||
RTOS_WAIT_MS(2000);
|
||||
telemetryClearFifo();
|
||||
|
||||
// reset telemetry protocol
|
||||
telemetryInit(255);
|
||||
|
||||
#if defined(INTERNAL_MODULE_MULTI)
|
||||
if (intPwr) {
|
||||
INTERNAL_MODULE_ON();
|
||||
|
@ -439,9 +545,8 @@ const char * multiFlashFirmware(uint8_t moduleIdx, const char * filename)
|
|||
setupPulsesExternalModule();
|
||||
}
|
||||
|
||||
//state = SPORT_IDLE;
|
||||
resumePulses();
|
||||
|
||||
return result;
|
||||
return result == nullptr;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#ifndef OPENTX_MULTI_FIRMWARE_H
|
||||
#define OPENTX_MULTI_FIRMWARE_H
|
||||
|
||||
#include "ff.h"
|
||||
|
||||
/* Signature format is multi-[board type]-[bootloader support][check for bootloader][multi telemetry type][telemetry inversion][debug]-[firmware version]
|
||||
Where:
|
||||
[board type] is avr, stm, or orx
|
||||
|
@ -36,15 +38,15 @@
|
|||
class MultiFirmwareInformation {
|
||||
public:
|
||||
enum MultiFirmwareBoardType {
|
||||
FIRMWARE_MULTI_AVR = 0,
|
||||
FIRMWARE_MULTI_STM,
|
||||
FIRMWARE_MULTI_AVR,
|
||||
FIRMWARE_MULTI_ORX,
|
||||
};
|
||||
|
||||
enum MultiFirmwareTelemetryType {
|
||||
FIRMWARE_MULTI_TELEM_MULTI,
|
||||
FIRMWARE_MULTI_TELEM_STATUS,
|
||||
FIRMWARE_MULTI_TELEM_NONE,
|
||||
FIRMWARE_MULTI_TELEM_NONE = 0,
|
||||
FIRMWARE_MULTI_TELEM_MULTI_STATUS, // erSkyTX
|
||||
FIRMWARE_MULTI_TELEM_MULTI_TELEMETRY, // OpenTX
|
||||
};
|
||||
|
||||
bool isMultiStmFirmware() const
|
||||
|
@ -69,15 +71,16 @@ class MultiFirmwareInformation {
|
|||
|
||||
bool isMultiInternalFirmware() const
|
||||
{
|
||||
return (boardType == FIRMWARE_MULTI_STM && telemetryInversion == false && optibootSupport == true && telemetryType == FIRMWARE_MULTI_TELEM_STATUS);
|
||||
return (boardType == FIRMWARE_MULTI_STM && telemetryInversion == false && optibootSupport == true && bootloaderCheck == true && telemetryType == FIRMWARE_MULTI_TELEM_MULTI_TELEMETRY);
|
||||
}
|
||||
|
||||
bool isMultiExternalFirmware() const
|
||||
{
|
||||
return (telemetryInversion == false && optibootSupport == true && telemetryType == FIRMWARE_MULTI_TELEM_STATUS);
|
||||
return (boardType == FIRMWARE_MULTI_STM && telemetryInversion == true && optibootSupport == true && bootloaderCheck == true && telemetryType == FIRMWARE_MULTI_TELEM_MULTI_TELEMETRY);
|
||||
}
|
||||
|
||||
const char * readMultiFirmwareInformation(const char * filename);
|
||||
const char * readMultiFirmwareInformation(FIL * file);
|
||||
|
||||
private:
|
||||
uint8_t boardType;
|
||||
|
@ -89,8 +92,11 @@ class MultiFirmwareInformation {
|
|||
uint8_t firmwareVersionMinor;
|
||||
uint8_t firmwareVersionRevision;
|
||||
uint8_t firmwareVersionSubRevision;
|
||||
|
||||
const char * readV1Signature(const char * buffer);
|
||||
const char * readV2Signature(const char * buffer);
|
||||
};
|
||||
|
||||
const char* multiFlashFirmware(uint8_t module, const char * filename);
|
||||
bool multiFlashFirmware(uint8_t module, const char * filename);
|
||||
|
||||
#endif //OPENTX_MULTI_FIRMWARE_H
|
||||
|
|
|
@ -83,5 +83,8 @@ void check_intmodule_heartbeat()
|
|||
extern "C" void INTMODULE_HEARTBEAT_EXTI_IRQHandler()
|
||||
{
|
||||
check_intmodule_heartbeat();
|
||||
#if defined(TELEMETRY_EXTI_REUSE_INTERRUPT_INTMODULE_HEARTBEAT)
|
||||
check_telemetry_exti();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -133,6 +133,10 @@ extern "C" void ROTARY_ENCODER_EXTI_IRQHandler1(void)
|
|||
#if !defined(BOOT) && defined(INTMODULE_HEARTBEAT_REUSE_INTERRUPT_ROTARY_ENCODER)
|
||||
check_intmodule_heartbeat();
|
||||
#endif
|
||||
|
||||
#if !defined(BOOT) && defined(TELEMETRY_EXTI_REUSE_INTERRUPT_ROTARY_ENCODER)
|
||||
check_telemetry_exti();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(ROTARY_ENCODER_EXTI_IRQn2)
|
||||
|
|
|
@ -120,6 +120,7 @@ void boardInit()
|
|||
HAPTIC_RCC_APB2Periph |
|
||||
INTMODULE_RCC_APB2Periph |
|
||||
EXTMODULE_RCC_APB2Periph |
|
||||
TELEMETRY_RCC_APB2Periph |
|
||||
BT_RCC_APB2Periph |
|
||||
BACKLIGHT_RCC_APB2Periph,
|
||||
ENABLE);
|
||||
|
|
|
@ -568,6 +568,9 @@ bool telemetryGetByte(uint8_t * byte);
|
|||
void telemetryClearFifo();
|
||||
extern uint32_t telemetryErrors;
|
||||
|
||||
// soft-serial
|
||||
void telemetryPortInvertedInit(uint32_t baudrate);
|
||||
|
||||
// Sport update driver
|
||||
#if defined(PCBX10) && !defined(RADIO_T16)
|
||||
void sportUpdatePowerOn();
|
||||
|
|
|
@ -365,6 +365,7 @@
|
|||
// Telemetry
|
||||
#define TELEMETRY_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA1)
|
||||
#define TELEMETRY_RCC_APB1Periph RCC_APB1Periph_USART2
|
||||
#define TELEMETRY_RCC_APB2Periph RCC_APB2Periph_TIM10
|
||||
#define TELEMETRY_DIR_GPIO GPIOD
|
||||
#define TELEMETRY_DIR_GPIO_PIN GPIO_Pin_4 // PD.04
|
||||
#define TELEMETRY_GPIO GPIOD
|
||||
|
@ -374,6 +375,15 @@
|
|||
#define TELEMETRY_GPIO_PinSource_RX GPIO_PinSource6
|
||||
#define TELEMETRY_GPIO_AF GPIO_AF_USART2
|
||||
#define TELEMETRY_USART USART2
|
||||
#define TELEMETRY_EXTI_PortSource EXTI_PortSourceGPIOD
|
||||
#define TELEMETRY_EXTI_PinSource EXTI_PinSource6
|
||||
#define TELEMETRY_EXTI_LINE EXTI_Line6
|
||||
#define TELEMETRY_EXTI_IRQn EXTI9_5_IRQn
|
||||
#define TELEMETRY_EXTI_IRQHandler EXTI9_5_IRQHandler
|
||||
#define TELEMETRY_EXTI_TRIGGER EXTI_Trigger_Rising
|
||||
#define TELEMETRY_TIMER TIM11
|
||||
#define TELEMETRY_TIMER_IRQn TIM1_TRG_COM_TIM11_IRQn
|
||||
#define TELEMETRY_TIMER_IRQHandler TIM1_TRG_COM_TIM11_IRQHandler
|
||||
#if defined(PCBX12S)
|
||||
#define TELEMETRY_DMA_Stream_RX DMA1_Stream5
|
||||
#define TELEMETRY_DMA_Channel_RX DMA_Channel_4
|
||||
|
|
|
@ -28,6 +28,17 @@ DMAFifo<TELEMETRY_FIFO_SIZE> telemetryDMAFifo __DMA (TELEMETRY_DMA_Stream_RX);
|
|||
uint8_t telemetryFifoMode;
|
||||
#endif
|
||||
|
||||
static void telemetryInitDirPin()
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_InitStructure.GPIO_Pin = TELEMETRY_DIR_GPIO_PIN;
|
||||
GPIO_Init(TELEMETRY_DIR_GPIO, &GPIO_InitStructure);
|
||||
GPIO_ResetBits(TELEMETRY_DIR_GPIO, TELEMETRY_DIR_GPIO_PIN);
|
||||
}
|
||||
|
||||
void telemetryPortInit(uint32_t baudrate, uint8_t mode)
|
||||
{
|
||||
if (baudrate == 0) {
|
||||
|
@ -55,11 +66,7 @@ void telemetryPortInit(uint32_t baudrate, uint8_t mode)
|
|||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_Init(TELEMETRY_GPIO, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = TELEMETRY_DIR_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(TELEMETRY_DIR_GPIO, &GPIO_InitStructure);
|
||||
GPIO_ResetBits(TELEMETRY_DIR_GPIO, TELEMETRY_DIR_GPIO_PIN);
|
||||
telemetryInitDirPin();
|
||||
|
||||
USART_InitStructure.USART_BaudRate = baudrate;
|
||||
if (mode & TELEMETRY_SERIAL_8E2) {
|
||||
|
@ -126,6 +133,95 @@ void telemetryPortInit(uint32_t baudrate, uint8_t mode)
|
|||
#endif
|
||||
}
|
||||
|
||||
// soft serial vars
|
||||
static uint8_t rxBitCount;
|
||||
static uint8_t rxByte;
|
||||
|
||||
void telemetryPortInvertedInit(uint32_t baudrate)
|
||||
{
|
||||
if (baudrate == 0) {
|
||||
NVIC_DisableIRQ(TELEMETRY_EXTI_IRQn);
|
||||
NVIC_DisableIRQ(TELEMETRY_TIMER_IRQn);
|
||||
|
||||
EXTI_InitTypeDef EXTI_InitStructure;
|
||||
EXTI_StructInit(&EXTI_InitStructure);
|
||||
EXTI_InitStructure.EXTI_Line = TELEMETRY_EXTI_LINE;
|
||||
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
|
||||
EXTI_InitStructure.EXTI_Trigger = TELEMETRY_EXTI_TRIGGER;
|
||||
EXTI_InitStructure.EXTI_LineCmd = DISABLE;
|
||||
EXTI_Init(&EXTI_InitStructure);
|
||||
return;
|
||||
}
|
||||
|
||||
rxBitCount = 0;
|
||||
|
||||
// configure bit sample timer
|
||||
RCC->APB2ENR |= RCC_APB2ENR_TIM11EN;
|
||||
TELEMETRY_TIMER->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1; // 0.5uS
|
||||
TELEMETRY_TIMER->CCER = 0;
|
||||
TELEMETRY_TIMER->CCMR1 = 0;
|
||||
TELEMETRY_TIMER->CR1 = TIM_CR1_CEN;
|
||||
TELEMETRY_TIMER->DIER = TIM_DIER_UIE;
|
||||
|
||||
NVIC_SetPriority(TELEMETRY_TIMER_IRQn, 0);
|
||||
NVIC_EnableIRQ(TELEMETRY_TIMER_IRQn);
|
||||
|
||||
// init TELEMETRY_RX_GPIO_PIN
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
|
||||
GPIO_InitStructure.GPIO_Pin = TELEMETRY_RX_GPIO_PIN;
|
||||
GPIO_Init(TELEMETRY_GPIO, &GPIO_InitStructure);
|
||||
|
||||
telemetryInitDirPin();
|
||||
|
||||
// Connect EXTI line to TELEMETRY RX pin
|
||||
SYSCFG_EXTILineConfig(TELEMETRY_EXTI_PortSource, TELEMETRY_EXTI_PinSource);
|
||||
|
||||
// Configure EXTI for raising edge (start bit)
|
||||
EXTI_InitTypeDef EXTI_InitStructure;
|
||||
EXTI_StructInit(&EXTI_InitStructure);
|
||||
EXTI_InitStructure.EXTI_Line = TELEMETRY_EXTI_LINE;
|
||||
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
|
||||
EXTI_InitStructure.EXTI_Trigger = TELEMETRY_EXTI_TRIGGER;
|
||||
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
|
||||
EXTI_Init(&EXTI_InitStructure);
|
||||
|
||||
NVIC_SetPriority(TELEMETRY_EXTI_IRQn, 0);
|
||||
NVIC_EnableIRQ(TELEMETRY_EXTI_IRQn);
|
||||
}
|
||||
|
||||
void telemetryPortInvertedRxBit()
|
||||
{
|
||||
if (rxBitCount < 8) {
|
||||
if (rxBitCount == 0) {
|
||||
TELEMETRY_TIMER->ARR = 34;
|
||||
rxByte = 0;
|
||||
}
|
||||
else {
|
||||
rxByte >>= 1;
|
||||
}
|
||||
|
||||
if (GPIO_ReadInputDataBit(TELEMETRY_GPIO, TELEMETRY_RX_GPIO_PIN) == Bit_RESET)
|
||||
rxByte |= 0x80;
|
||||
|
||||
++rxBitCount;
|
||||
}
|
||||
else if (rxBitCount == 8) {
|
||||
|
||||
telemetryNoDMAFifo.push(rxByte);
|
||||
rxBitCount = 0;
|
||||
|
||||
// disable timer
|
||||
TELEMETRY_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
|
||||
// re-enable start bit interrupt
|
||||
EXTI->IMR |= EXTI_IMR_MR6;
|
||||
}
|
||||
}
|
||||
|
||||
void telemetryPortSetDirectionOutput()
|
||||
{
|
||||
TELEMETRY_DIR_GPIO->BSRRL = TELEMETRY_DIR_GPIO_PIN; // output enable
|
||||
|
@ -253,6 +349,29 @@ extern "C" void TELEMETRY_USART_IRQHandler(void)
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void TELEMETRY_EXTI_IRQHandler(void)
|
||||
{
|
||||
if (EXTI_GetITStatus(TELEMETRY_EXTI_LINE) != RESET) {
|
||||
|
||||
if (rxBitCount == 0) {
|
||||
|
||||
TELEMETRY_TIMER->ARR = 48; // 1,5 cycle from start at 57600bps
|
||||
TELEMETRY_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
|
||||
// disable start bit interrupt
|
||||
EXTI->IMR &= ~EXTI_IMR_MR6;
|
||||
}
|
||||
|
||||
EXTI_ClearITPendingBit(TELEMETRY_EXTI_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void TELEMETRY_TIMER_IRQHandler()
|
||||
{
|
||||
TELEMETRY_TIMER->SR &= ~TIM_SR_UIF;
|
||||
telemetryPortInvertedRxBit();
|
||||
}
|
||||
|
||||
// TODO we should have telemetry in an higher layer, functions above should move to a sport_driver.cpp
|
||||
bool telemetryGetByte(uint8_t * byte)
|
||||
{
|
||||
|
|
|
@ -192,6 +192,8 @@ void check_intmodule_heartbeat();
|
|||
#define check_intmodule_heartbeat()
|
||||
#endif
|
||||
|
||||
void check_telemetry_exti();
|
||||
|
||||
// SBUS
|
||||
int sbusGetByte(uint8_t * byte);
|
||||
|
||||
|
@ -680,6 +682,9 @@ bool telemetryGetByte(uint8_t * byte);
|
|||
void telemetryClearFifo();
|
||||
extern uint32_t telemetryErrors;
|
||||
|
||||
// soft-serial
|
||||
void telemetryPortInvertedInit(uint32_t baudrate);
|
||||
|
||||
// PCBREV driver
|
||||
#if defined(PCBX7)
|
||||
#define IS_PCBREV_40() (GPIO_ReadInputDataBit(PCBREV_GPIO, PCBREV_GPIO_PIN) == Bit_SET)
|
||||
|
|
|
@ -1284,6 +1284,23 @@
|
|||
#define TELEMETRY_DMA_TX_FLAG_TC DMA_IT_TCIF6
|
||||
#define TELEMETRY_USART_IRQHandler USART2_IRQHandler
|
||||
#define TELEMETRY_USART_IRQn USART2_IRQn
|
||||
#define TELEMETRY_EXTI_PortSource EXTI_PortSourceGPIOD
|
||||
#define TELEMETRY_EXTI_PinSource EXTI_PinSource6
|
||||
#define TELEMETRY_EXTI_LINE EXTI_Line6
|
||||
#define TELEMETRY_EXTI_IRQn EXTI9_5_IRQn
|
||||
#define TELEMETRY_EXTI_TRIGGER EXTI_Trigger_Rising
|
||||
|
||||
#if defined(RADIO_X7)
|
||||
#define TELEMETRY_EXTI_REUSE_INTERRUPT_ROTARY_ENCODER
|
||||
#elif defined(PCBXLITE) || defined(PCBX9LITE) || (defined(PCBX9DP) && PCBREV >= 2019)
|
||||
#define TELEMETRY_EXTI_IRQHandler EXTI9_5_IRQHandler
|
||||
#else
|
||||
#define TELEMETRY_EXTI_REUSE_INTERRUPT_INTMODULE_HEARTBEAT
|
||||
#endif
|
||||
|
||||
#define TELEMETRY_TIMER TIM11
|
||||
#define TELEMETRY_TIMER_IRQn TIM1_TRG_COM_TIM11_IRQn
|
||||
#define TELEMETRY_TIMER_IRQHandler TIM1_TRG_COM_TIM11_IRQHandler
|
||||
|
||||
// PCBREV
|
||||
#if defined(PCBX7)
|
||||
|
|
|
@ -23,6 +23,17 @@
|
|||
Fifo<uint8_t, TELEMETRY_FIFO_SIZE> telemetryFifo;
|
||||
uint32_t telemetryErrors = 0;
|
||||
|
||||
static void telemetryInitDirPin()
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_InitStructure.GPIO_Pin = TELEMETRY_DIR_GPIO_PIN;
|
||||
GPIO_Init(TELEMETRY_DIR_GPIO, &GPIO_InitStructure);
|
||||
TELEMETRY_DIR_INPUT();
|
||||
}
|
||||
|
||||
void telemetryPortInit(uint32_t baudrate, uint8_t mode)
|
||||
{
|
||||
if (baudrate == 0) {
|
||||
|
@ -48,11 +59,7 @@ void telemetryPortInit(uint32_t baudrate, uint8_t mode)
|
|||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_Init(TELEMETRY_GPIO, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = TELEMETRY_DIR_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(TELEMETRY_DIR_GPIO, &GPIO_InitStructure);
|
||||
TELEMETRY_DIR_INPUT();
|
||||
telemetryInitDirPin();
|
||||
|
||||
USART_DeInit(TELEMETRY_USART);
|
||||
USART_InitTypeDef USART_InitStructure;
|
||||
|
@ -77,6 +84,110 @@ void telemetryPortInit(uint32_t baudrate, uint8_t mode)
|
|||
NVIC_EnableIRQ(TELEMETRY_USART_IRQn);
|
||||
}
|
||||
|
||||
// soft serial vars
|
||||
static uint8_t rxBitCount;
|
||||
static uint8_t rxByte;
|
||||
|
||||
//TODO:
|
||||
// - only 57600 supported for now
|
||||
// - handle other bitrates as well?
|
||||
//
|
||||
void telemetryPortInvertedInit(uint32_t baudrate)
|
||||
{
|
||||
if (baudrate == 0) {
|
||||
|
||||
//TODO:
|
||||
// - handle conflict with HEARTBEAT disabled for trainer input...
|
||||
// - probably need to stop trainer input/output and restore after this is closed
|
||||
#if !defined(TELEMETRY_EXTI_REUSE_INTERRUPT_ROTARY_ENCODER) && !defined(TELEMETRY_EXTI_REUSE_INTERRUPT_INTMODULE_HEARTBEAT)
|
||||
NVIC_DisableIRQ(TELEMETRY_EXTI_IRQn);
|
||||
#endif
|
||||
NVIC_DisableIRQ(TELEMETRY_TIMER_IRQn);
|
||||
|
||||
EXTI_InitTypeDef EXTI_InitStructure;
|
||||
EXTI_StructInit(&EXTI_InitStructure);
|
||||
EXTI_InitStructure.EXTI_Line = TELEMETRY_EXTI_LINE;
|
||||
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
|
||||
EXTI_InitStructure.EXTI_Trigger = TELEMETRY_EXTI_TRIGGER;
|
||||
EXTI_InitStructure.EXTI_LineCmd = DISABLE;
|
||||
EXTI_Init(&EXTI_InitStructure);
|
||||
return;
|
||||
}
|
||||
|
||||
rxBitCount = 0;
|
||||
|
||||
// configure bit sample timer
|
||||
RCC->APB2ENR |= RCC_APB2ENR_TIM11EN;
|
||||
TELEMETRY_TIMER->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1; // 0.5uS
|
||||
TELEMETRY_TIMER->CCER = 0;
|
||||
TELEMETRY_TIMER->CCMR1 = 0;
|
||||
TELEMETRY_TIMER->CR1 = TIM_CR1_CEN;
|
||||
TELEMETRY_TIMER->DIER = TIM_DIER_UIE;
|
||||
|
||||
NVIC_SetPriority(TELEMETRY_TIMER_IRQn, 0);
|
||||
NVIC_EnableIRQ(TELEMETRY_TIMER_IRQn);
|
||||
|
||||
// init TELEMETRY_RX_GPIO_PIN
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
|
||||
GPIO_InitStructure.GPIO_Pin = TELEMETRY_RX_GPIO_PIN;
|
||||
GPIO_Init(TELEMETRY_GPIO, &GPIO_InitStructure);
|
||||
|
||||
telemetryInitDirPin();
|
||||
|
||||
// Connect EXTI line to TELEMETRY RX pin
|
||||
SYSCFG_EXTILineConfig(TELEMETRY_EXTI_PortSource, TELEMETRY_EXTI_PinSource);
|
||||
|
||||
// Configure EXTI for raising edge (start bit)
|
||||
EXTI_InitTypeDef EXTI_InitStructure;
|
||||
EXTI_StructInit(&EXTI_InitStructure);
|
||||
EXTI_InitStructure.EXTI_Line = TELEMETRY_EXTI_LINE;
|
||||
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
|
||||
EXTI_InitStructure.EXTI_Trigger = TELEMETRY_EXTI_TRIGGER;
|
||||
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
|
||||
EXTI_Init(&EXTI_InitStructure);
|
||||
|
||||
//TODO:
|
||||
// - handle conflict with HEARTBEAT disabled for trainer input...
|
||||
// - probably need to stop trainer input/output and restore after this is closed
|
||||
#if !defined(TELEMETRY_EXTI_REUSE_INTERRUPT_ROTARY_ENCODER) && !defined(TELEMETRY_EXTI_REUSE_INTERRUPT_INTMODULE_HEARTBEAT)
|
||||
NVIC_SetPriority(TELEMETRY_EXTI_IRQn, 0);
|
||||
NVIC_EnableIRQ(TELEMETRY_EXTI_IRQn);
|
||||
#endif
|
||||
}
|
||||
|
||||
void telemetryPortInvertedRxBit()
|
||||
{
|
||||
if (rxBitCount < 8) {
|
||||
if (rxBitCount == 0) {
|
||||
TELEMETRY_TIMER->ARR = 34;
|
||||
rxByte = 0;
|
||||
}
|
||||
else {
|
||||
rxByte >>= 1;
|
||||
}
|
||||
|
||||
if (GPIO_ReadInputDataBit(TELEMETRY_GPIO, TELEMETRY_RX_GPIO_PIN) == Bit_RESET)
|
||||
rxByte |= 0x80;
|
||||
|
||||
++rxBitCount;
|
||||
}
|
||||
else if (rxBitCount == 8) {
|
||||
|
||||
telemetryFifo.push(rxByte);
|
||||
rxBitCount = 0;
|
||||
|
||||
// disable timer
|
||||
TELEMETRY_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
|
||||
// re-enable start bit interrupt
|
||||
EXTI->IMR |= EXTI_IMR_MR6;
|
||||
}
|
||||
}
|
||||
|
||||
void telemetryPortSetDirectionOutput()
|
||||
{
|
||||
TELEMETRY_DIR_OUTPUT();
|
||||
|
@ -217,6 +328,36 @@ extern "C" void TELEMETRY_USART_IRQHandler(void)
|
|||
}
|
||||
}
|
||||
|
||||
void check_telemetry_exti()
|
||||
{
|
||||
if (EXTI_GetITStatus(TELEMETRY_EXTI_LINE) != RESET) {
|
||||
|
||||
if (rxBitCount == 0) {
|
||||
|
||||
TELEMETRY_TIMER->ARR = 48; // 1,5 cycle from start at 57600bps
|
||||
TELEMETRY_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
|
||||
// disable start bit interrupt
|
||||
EXTI->IMR &= ~EXTI_IMR_MR6;
|
||||
}
|
||||
|
||||
EXTI_ClearITPendingBit(TELEMETRY_EXTI_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(TELEMETRY_EXTI_IRQHandler)
|
||||
extern "C" void TELEMETRY_EXTI_IRQHandler(void)
|
||||
{
|
||||
check_telemetry_exti();
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C" void TELEMETRY_TIMER_IRQHandler()
|
||||
{
|
||||
TELEMETRY_TIMER->SR &= ~TIM_SR_UIF;
|
||||
telemetryPortInvertedRxBit();
|
||||
}
|
||||
|
||||
// TODO we should have telemetry in an higher layer, functions above should move to a sport_driver.cpp
|
||||
bool telemetryGetByte(uint8_t * byte)
|
||||
{
|
||||
|
|
|
@ -35,6 +35,7 @@ extern uint8_t currentTrainerMode;
|
|||
|
||||
void checkTrainerSignalWarning();
|
||||
void checkTrainerSettings();
|
||||
void forceResetTrainerSettings();
|
||||
|
||||
// Needs to be inlined to avoid slow function calls in ISR routines
|
||||
inline void captureTrainerPulses(uint16_t capture)
|
||||
|
|
|
@ -677,6 +677,9 @@ const char STR_PROTOCOL_INVALID[] = TR_PROTOCOL_INVALID;
|
|||
const char STR_MODULE_STATUS[] = TR_MODULE_STATUS;
|
||||
const char STR_MODULE_SYNC[] = TR_MODULE_SYNC;
|
||||
const char STR_MULTI_SERVOFREQ[] = TR_MULTI_SERVOFREQ;
|
||||
const char STR_NEEDS_FILE[] = TR_NEEDS_FILE;
|
||||
const char STR_EXT_MULTI_SPEC[] = TR_EXT_MULTI_SPEC;
|
||||
const char STR_INT_MULTI_SPEC[] = TR_INT_MULTI_SPEC;
|
||||
#endif
|
||||
|
||||
#if LCD_W < 212
|
||||
|
|
|
@ -537,6 +537,9 @@ extern const char STR_WAITING_FOR_TX[];
|
|||
#define STR_UPDATE_LIST STR_DELAYDOWN
|
||||
#endif
|
||||
|
||||
extern const char STR_NEEDS_FILE[];
|
||||
extern const char STR_EXT_MULTI_SPEC[];
|
||||
extern const char STR_INT_MULTI_SPEC[];
|
||||
extern const char STR_CAT_NOT_EMPTY[];
|
||||
extern const char STR_WARNING[];
|
||||
extern const char STR_STORAGE_WARNING[];
|
||||
|
|
|
@ -714,6 +714,9 @@
|
|||
#define TR_SPECTRUM_ANALYSER_EXT "Spektální an. (EXT)"
|
||||
#define TR_SPECTRUM_ANALYSER_INT "Spektální an. (INT)"
|
||||
#define TR_SDCARD_FULL "Plná SD karta"
|
||||
#define TR_NEEDS_FILE "NEEDS FILE"
|
||||
#define TR_EXT_MULTI_SPEC "opentx-inv"
|
||||
#define TR_INT_MULTI_SPEC "stm-opentx-noinv"
|
||||
#define TR_INCOMPATIBLE "Nekompatibilní"
|
||||
#define TR_WARNING "KONTROLA"
|
||||
#define TR_EEPROMWARN "EEPROM"
|
||||
|
|
|
@ -715,7 +715,10 @@
|
|||
#define TR_POWER_METER_INT "Power Meter (INT)"
|
||||
#define TR_SPECTRUM_ANALYSER_EXT "Spectrum (EXT)"
|
||||
#define TR_SPECTRUM_ANALYSER_INT "Spectrum (INT)"
|
||||
#define TR_SDCARD_FULL "SD-Karte voll"
|
||||
#define TR_SDCARD_FULL "SD-Karte voll"
|
||||
#define TR_NEEDS_FILE "NEEDS FILE"
|
||||
#define TR_EXT_MULTI_SPEC "opentx-inv"
|
||||
#define TR_INT_MULTI_SPEC "stm-opentx-noinv"
|
||||
#define TR_INCOMPATIBLE "Nicht kompatibel"
|
||||
#define TR_WARNING "WARNUNG"
|
||||
#define TR_EEPROMWARN "EEPROM"
|
||||
|
|
|
@ -715,6 +715,9 @@
|
|||
#define TR_SPECTRUM_ANALYSER_EXT "Spectrum (EXT)"
|
||||
#define TR_SPECTRUM_ANALYSER_INT "Spectrum (INT)"
|
||||
#define TR_SDCARD_FULL "SD card full"
|
||||
#define TR_NEEDS_FILE "NEEDS FILE"
|
||||
#define TR_EXT_MULTI_SPEC "opentx-inv"
|
||||
#define TR_INT_MULTI_SPEC "stm-opentx-noinv"
|
||||
#define TR_INCOMPATIBLE "Incompatible"
|
||||
#define TR_WARNING "WARNING"
|
||||
#define TR_EEPROMWARN "EEPROM"
|
||||
|
|
|
@ -738,7 +738,10 @@
|
|||
#define TR_POWER_METER_INT "Power Meter (INT)"
|
||||
#define TR_SPECTRUM_ANALYSER_EXT "Spectrum (EXT)"
|
||||
#define TR_SPECTRUM_ANALYSER_INT "Spectrum (INT)"
|
||||
#define TR_SDCARD_FULL "SD Card Full"
|
||||
#define TR_SDCARD_FULL "SD Card Full"
|
||||
#define TR_NEEDS_FILE "NEEDS FILE"
|
||||
#define TR_EXT_MULTI_SPEC "opentx-inv"
|
||||
#define TR_INT_MULTI_SPEC "stm-opentx-noinv"
|
||||
#define TR_INCOMPATIBLE "Incompatible"
|
||||
#define TR_WARNING "AVISO"
|
||||
#define TR_EEPROMWARN "EEPROM"
|
||||
|
|
|
@ -732,7 +732,10 @@
|
|||
#define TR_POWER_METER_INT "Power Meter (INT)"
|
||||
#define TR_SPECTRUM_ANALYSER_EXT "Spectrum (EXT)"
|
||||
#define TR_SPECTRUM_ANALYSER_INT "Spectrum (INT)"
|
||||
#define TR_SDCARD_FULL "SD Card Full"
|
||||
#define TR_SDCARD_FULL "SD Card Full"
|
||||
#define TR_NEEDS_FILE "NEEDS FILE"
|
||||
#define TR_EXT_MULTI_SPEC "opentx-inv"
|
||||
#define TR_INT_MULTI_SPEC "stm-opentx-noinv"
|
||||
#define TR_INCOMPATIBLE "Incompatible"
|
||||
#define TR_WARNING "WARNING"
|
||||
#define TR_EEPROMWARN "FINSKA"
|
||||
|
|
|
@ -736,6 +736,9 @@
|
|||
#define TR_SPECTRUM_ANALYSER_EXT TR("Spectre (EXT)", "Analyseur spectre (EXT)")
|
||||
#define TR_SPECTRUM_ANALYSER_INT TR("Spectre (INT)", "Analyseur spectre (INT)")
|
||||
#define TR_SDCARD_FULL "Carte SD pleine"
|
||||
#define TR_NEEDS_FILE "NEEDS FILE"
|
||||
#define TR_EXT_MULTI_SPEC "opentx-inv"
|
||||
#define TR_INT_MULTI_SPEC "stm-opentx-noinv"
|
||||
#define TR_INCOMPATIBLE "Incompatible"
|
||||
#define TR_WARNING "ALERTE"
|
||||
#define TR_EEPROMWARN "EEPROM"
|
||||
|
|
|
@ -733,7 +733,10 @@
|
|||
#define TR_POWER_METER_INT "Power Meter (INT)"
|
||||
#define TR_SPECTRUM_ANALYSER_EXT "Spectrum (EXT)"
|
||||
#define TR_SPECTRUM_ANALYSER_INT "Spectrum (INT)"
|
||||
#define TR_SDCARD_FULL "SD Card Piena"
|
||||
#define TR_SDCARD_FULL "SD Card Piena"
|
||||
#define TR_NEEDS_FILE "NEEDS FILE"
|
||||
#define TR_EXT_MULTI_SPEC "opentx-inv"
|
||||
#define TR_INT_MULTI_SPEC "stm-opentx-noinv"
|
||||
#define TR_INCOMPATIBLE "Incompatibile"
|
||||
#define TR_WARNING "AVVISO"
|
||||
#define TR_EEPROMWARN "EEPROM"
|
||||
|
|
|
@ -720,7 +720,10 @@
|
|||
#define TR_POWER_METER_INT "Power Meter (INT)"
|
||||
#define TR_SPECTRUM_ANALYSER_EXT "Spectrum (EXT)"
|
||||
#define TR_SPECTRUM_ANALYSER_INT "Spectrum (INT)"
|
||||
#define TR_SDCARD_FULL "SD-Kaart vol"
|
||||
#define TR_SDCARD_FULL "SD-Kaart vol"
|
||||
#define TR_NEEDS_FILE "NEEDS FILE"
|
||||
#define TR_EXT_MULTI_SPEC "opentx-inv"
|
||||
#define TR_INT_MULTI_SPEC "stm-opentx-noinv"
|
||||
#define TR_INCOMPATIBLE "Niet compatibel"
|
||||
#define TR_WARNING "MELDING"
|
||||
#define TR_EEPROMWARN "EEPROM"
|
||||
|
|
|
@ -733,7 +733,10 @@
|
|||
#define TR_POWER_METER_INT "Power Meter (INT)"
|
||||
#define TR_SPECTRUM_ANALYSER_EXT "Spectrum (EXT)"
|
||||
#define TR_SPECTRUM_ANALYSER_INT "Spectrum (INT)"
|
||||
#define TR_SDCARD_FULL "Karta Pełna "
|
||||
#define TR_SDCARD_FULL "Karta Pełna "
|
||||
#define TR_NEEDS_FILE "NEEDS FILE"
|
||||
#define TR_EXT_MULTI_SPEC "opentx-inv"
|
||||
#define TR_INT_MULTI_SPEC "stm-opentx-noinv"
|
||||
#define TR_INCOMPATIBLE "Niekompatybilne"
|
||||
#define TR_WARNING "UWAGA"
|
||||
#define TR_EEPROMWARN "EEPROM"
|
||||
|
|
|
@ -723,7 +723,10 @@
|
|||
#define TR_POWER_METER_INT "Power Meter (INT)"
|
||||
#define TR_SPECTRUM_ANALYSER_EXT "Spectrum (EXT)"
|
||||
#define TR_SPECTRUM_ANALYSER_INT "Spectrum (INT)"
|
||||
#define TR_SDCARD_FULL "SD Card Full"
|
||||
#define TR_SDCARD_FULL "SD Card Full"
|
||||
#define TR_NEEDS_FILE "NEEDS FILE"
|
||||
#define TR_EXT_MULTI_SPEC "opentx-inv"
|
||||
#define TR_INT_MULTI_SPEC "stm-opentx-noinv"
|
||||
#define TR_INCOMPATIBLE "Incompativel"
|
||||
#define TR_WARNING "AVISO"
|
||||
#define TR_EEPROMWARN "EEPROM"
|
||||
|
|
|
@ -732,7 +732,10 @@
|
|||
#define TR_POWER_METER_INT "Power Meter (INT)"
|
||||
#define TR_SPECTRUM_ANALYSER_EXT "Spectrum (EXT)"
|
||||
#define TR_SPECTRUM_ANALYSER_INT "Spectrum (INT)"
|
||||
#define TR_SDCARD_FULL "SD-kort Fullt"
|
||||
#define TR_SDCARD_FULL "SD-kort Fullt"
|
||||
#define TR_NEEDS_FILE "NEEDS FILE"
|
||||
#define TR_EXT_MULTI_SPEC "opentx-inv"
|
||||
#define TR_INT_MULTI_SPEC "stm-opentx-noinv"
|
||||
#define TR_INCOMPATIBLE "Inkompatibel"
|
||||
#define TR_WARNING "VARNING"
|
||||
#define TR_EEPROMWARN "EEPROM"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue