From 2da113479676c53590735afdd0e0940a524f7620 Mon Sep 17 00:00:00 2001 From: bsongis Date: Wed, 16 Jul 2014 13:29:08 +0200 Subject: [PATCH] Quick & dirty fix to allow open of backup models from Taranis --- companion/src/file.cpp | 71 +++++++++++++++++++ companion/src/file.h | 1 + .../src/firmwares/opentx/opentxinterface.cpp | 38 +++++++++- 3 files changed, 108 insertions(+), 2 deletions(-) diff --git a/companion/src/file.cpp b/companion/src/file.cpp index 280912b5d..bed78afb4 100644 --- a/companion/src/file.cpp +++ b/companion/src/file.cpp @@ -344,6 +344,77 @@ unsigned int RleFile::readRlc12(uint8_t *buf, unsigned int i_len, bool rlc2) } } +unsigned int RleFile::importRlc2(QByteArray & dst, QByteArray & src) +{ + // TODO reset dst + + unsigned int i_len = src.size(); + unsigned int i_ofs = 0; + uint8_t *buf = (uint8_t *)dst.data(); + m_pos = 0; + m_ofs = 0; + m_zeroes = 0; + m_bRlc = 0; + m_err = ERR_NONE; //error reasons + + + if (IS_SKY9X(board)) { + int len = std::min((int)i_len, (int)m_size + (int)sizeof(t_eeprom_header) - (int)m_pos); + if (len > 0) { + eeprom_read_block(buf, (m_fileId << 12) + m_pos, len); + m_pos += len; + } + return len; + } + else { + unsigned int i=0; + for( ; 1; ) { + uint8_t ln = std::min(m_zeroes, i_len-i); + memset(&buf[i], 0, ln); + i += ln; + m_zeroes -= ln; + if(m_zeroes) break; + + ln = std::min(m_bRlc, i_len-i); + memcpy(&buf[i], ((uint8_t *)src.data()) + i_ofs, ln); + i_ofs += ln; + uint8_t lr = ln; + + i += lr ; + m_bRlc -= lr; + if(m_bRlc) break; + + // if (read(&m_bRlc, 1) !=1) break; //read how many bytes to read + m_bRlc = *(((uint8_t *)src.data()) + i_ofs); + i_ofs += 1; + + if (!(m_bRlc & 0x7f)) { + qDebug() << "RLC decoding error!"; + return 0; + } + + if (1/*rlc2*/) { + if(m_bRlc&0x80){ // if contains high byte + m_zeroes =(m_bRlc>>4) & 0x7; + m_bRlc = m_bRlc & 0x0f; + } + else if(m_bRlc&0x40){ + m_zeroes = m_bRlc & 0x3f; + m_bRlc = 0; + } + //else m_bRlc + } + else { + if(m_bRlc&0x80){ // if contains high byte + m_zeroes = m_bRlc & 0x7f; + m_bRlc = 0; + } + } + } + return i; + } +} + unsigned int RleFile::write1(uint8_t b) { return write(&b, 1); diff --git a/companion/src/file.h b/companion/src/file.h index bcfcb4f44..93918d0cd 100644 --- a/companion/src/file.h +++ b/companion/src/file.h @@ -140,6 +140,7 @@ public: { return readRlc12(buf, i_len, true); } + unsigned int importRlc2(QByteArray & dst, QByteArray & src); uint8_t byte_checksum(uint8_t *p, unsigned int size); unsigned int ee32_check_header(struct t_eeprom_header *hptr); diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index ff1fe846d..641bcf29b 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -164,7 +164,20 @@ bool OpenTxEepromInterface::loadModelVariant(unsigned int index, ModelData &mode else { // load from SD Backup, size is stored in index QByteArray eepromData((char *)data, index); - open9xModel.Import(eepromData); + QByteArray modelData(sizeof(model), 0); // ModelData should be always bigger than the EEPROM struct + // memcpy(eepromData.data(), data, index); + // efile->openRd(FILE_MODEL(0)); + int numbytes = efile->importRlc2(modelData, eepromData); + if (numbytes) { + open9xModel.Import(modelData); + // open9xModel.Dump(); + model.used = true; + } + else { + model.clear(); + } + // open9xModel.Import(eepromData); + // model.used = true; } return true; @@ -921,11 +934,32 @@ bool OpenTxEepromInterface::loadBackup(RadioData &radioData, uint8_t *eeprom, in { std::cout << "trying " << getName() << " backup import..."; - if (esize < 8 || memcmp(eeprom, "o9x", 3) != 0 || eeprom[3] != 0x30+board) { + if (esize < 8 || memcmp(eeprom, "o9x", 3) != 0) { std::cout << " no\n"; return false; } + BoardEnum backupBoard = (BoardEnum)-1; + switch (eeprom[3]) { + case 0x33: + backupBoard = BOARD_TARANIS; + break; + case 0x32: + backupBoard = BOARD_SKY9X; + break; + case 0x31: + backupBoard = BOARD_GRUVIN9X; + break; + default: + std::cout << " unknown board\n"; + return false; + } + + if (backupBoard != board) { + std::cout << " not right board\n"; + return false; + } + uint8_t version = eeprom[4]; uint8_t bcktype = eeprom[5]; uint16_t size = ((uint16_t)eeprom[7] << 8) + eeprom[6];