diff --git a/companion/src/avroutputdialog.cpp b/companion/src/avroutputdialog.cpp index 6dcb22d68..9293bd0f1 100644 --- a/companion/src/avroutputdialog.cpp +++ b/companion/src/avroutputdialog.cpp @@ -279,7 +279,7 @@ QString avrOutputDialog::getProgrammer() if (IS_TARANIS(eepromInterface->getBoard())) { return "DFU Util"; } - else if (eepromInterface->getBoard()==BOARD_SKY9X) { + else if IS_SKY9X(eepromInterface->getBoard()) { return "SAM-BA"; } else { diff --git a/companion/src/burnconfigdialog.cpp b/companion/src/burnconfigdialog.cpp index b802ba414..b4b865adf 100644 --- a/companion/src/burnconfigdialog.cpp +++ b/companion/src/burnconfigdialog.cpp @@ -39,7 +39,8 @@ burnConfigDialog::burnConfigDialog(QWidget *parent) : ui->samba_location->hide(); ui->samba_port->hide(); ui->sb_browse->hide(); - } else if (eepromInterface->getBoard()==BOARD_SKY9X) { + } + else if (IS_SKY9X(eepromInterface->getBoard())) { setWindowTitle(tr("SAM-BA Configuration")); ui->avrArgs->hide(); ui->avrdude_location->hide(); @@ -55,7 +56,8 @@ burnConfigDialog::burnConfigDialog(QWidget *parent) : ui->label_dfu1->hide(); ui->dfu_location->hide(); ui->dfu_browse->hide(); - } else { + } + else { setWindowTitle(tr("AVRDUDE Configuration")); ui->label_sb1->hide(); ui->label_sb3->hide(); @@ -112,7 +114,6 @@ void burnConfigDialog::getSettings() dfuLoc = QFileInfo("/usr/bin/dfu-util").absoluteFilePath(); #endif - dfuArgs = g.dfuArguments().split(" ", QString::SkipEmptyParts); avrArgs = g.avrArguments().split(" ", QString::SkipEmptyParts); avrProgrammer = g.programmer(); @@ -408,7 +409,7 @@ void burnConfigDialog::on_advCtrChkB_toggled(bool checked) ui->label_dfu2->show(); ui->dfuArgs->show(); } - else if (eepromInterface->getBoard()==BOARD_SKY9X) { + else if (IS_SKY9X(eepromInterface->getBoard())) { ui->label_sb2->show(); ui->arm_mcu->show(); } @@ -425,7 +426,7 @@ void burnConfigDialog::on_advCtrChkB_toggled(bool checked) ui->label_dfu2->hide(); ui->dfuArgs->hide(); } - else if (eepromInterface->getBoard()==BOARD_SKY9X) { + else if (IS_SKY9X(eepromInterface->getBoard())) { ui->label_sb2->hide(); ui->arm_mcu->hide(); } diff --git a/companion/src/burnconfigdialog.ui b/companion/src/burnconfigdialog.ui index f47568331..94a7f783f 100644 --- a/companion/src/burnconfigdialog.ui +++ b/companion/src/burnconfigdialog.ui @@ -671,6 +671,11 @@ m2560 for v4.1 boards at91sam3s4-9x + + + at91sam3s8-9xr + + diff --git a/companion/src/eeprominterface.cpp b/companion/src/eeprominterface.cpp index 4b19b330e..cc266de4f 100644 --- a/companion/src/eeprominterface.cpp +++ b/companion/src/eeprominterface.cpp @@ -1221,8 +1221,9 @@ void RegisterEepromInterfaces() eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_M128)); eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_GRUVIN9X)); eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_SKY9X)); + eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_9XRPRO)); eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_TARANIS)); - eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_TARANIS_PLUS)); + eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_TARANIS_PLUS)); if (g.rev4aSupport()) eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_TARANIS_REV4a)); eepromInterfaces.push_back(new Gruvin9xInterface(BOARD_STOCK)); diff --git a/companion/src/eeprominterface.h b/companion/src/eeprominterface.h index c9ee5d1f2..4e2ba8786 100644 --- a/companion/src/eeprominterface.h +++ b/companion/src/eeprominterface.h @@ -37,6 +37,7 @@ #define EESIZE_TARANIS (32*1024) #define EESIZE_TARANIS_REV4a (64*1024) #define EESIZE_SKY9X (128*4096) +#define EESIZE_9XRPRO (128*4096) #define EESIZE_RLC_MAX EESIZE_TARANIS_REV4a template t LIMIT(t mi, t x, t ma) { return std::min(std::max(mi, x), ma); } @@ -47,6 +48,7 @@ enum BoardEnum { BOARD_MEGA2560, BOARD_GRUVIN9X, BOARD_SKY9X, + BOARD_9XRPRO, BOARD_TARANIS, BOARD_TARANIS_PLUS, BOARD_TARANIS_REV4a @@ -55,9 +57,10 @@ enum BoardEnum { #define IS_9X(board) (board==BOARD_STOCK || board==BOARD_M128) #define IS_STOCK(board) (board==BOARD_STOCK) #define IS_2560(board) (board==BOARD_GRUVIN9X || board==BOARD_MEGA2560) -#define IS_ARM(board) (board==BOARD_SKY9X || board==BOARD_TARANIS || board==BOARD_TARANIS_REV4a || board==BOARD_TARANIS_PLUS) +#define IS_SKY9X(board) (board==BOARD_SKY9X || board==BOARD_9XRPRO) #define IS_TARANIS(board) (board==BOARD_TARANIS || board==BOARD_TARANIS_REV4a || board==BOARD_TARANIS_PLUS) #define IS_TARANIS_PLUS(board) (board==BOARD_TARANIS_PLUS) +#define IS_ARM(board) (IS_TARANIS(board) || IS_SKY9X(board)) const uint8_t modn12x3[4][4]= { {1, 2, 3, 4}, diff --git a/companion/src/file.cpp b/companion/src/file.cpp index 404a40db8..390bd2685 100644 --- a/companion/src/file.cpp +++ b/companion/src/file.cpp @@ -37,7 +37,7 @@ void EFile::EeFsCreate(uint8_t *eeprom, int size, BoardEnum board) this->eeprom_size = size; this->board = board; - if (board == BOARD_SKY9X) { + if (IS_SKY9X(board)) { memset(eeprom, 0xFF, size); } else if (IS_TARANIS(board)) { @@ -101,7 +101,7 @@ bool EFile::EeFsOpen(uint8_t *eeprom, int size, BoardEnum board) this->eeprom_size = size; this->board = board; - if (board == BOARD_SKY9X) { + if (IS_SKY9X(board)) { return 1; } else if (IS_TARANIS(board)) { @@ -254,7 +254,7 @@ unsigned int EFile::size(unsigned int id) unsigned int EFile::openRd(unsigned int i_fileId) { - if (board == BOARD_SKY9X) { + if (IS_SKY9X(board)) { m_fileId = get_current_block_number(i_fileId * 2, &m_size); m_pos = sizeof(t_eeprom_header); return 1; @@ -298,7 +298,7 @@ unsigned int EFile::readRlc12(uint8_t *buf, unsigned int i_len, bool rlc2) { memset(buf, 0, i_len); - if (board == BOARD_SKY9X) { + 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); @@ -464,7 +464,7 @@ unsigned int EFile::writeRlc1(unsigned int i_fileId, unsigned int typ, const uin */ unsigned int EFile::writeRlc2(unsigned int i_fileId, unsigned int typ, const uint8_t *buf, unsigned int i_len) { - if (board == BOARD_SKY9X) { + if (IS_SKY9X(board)) { openRd(i_fileId); eeprom_write_block(buf, (m_fileId << 12) + m_pos, i_len); t_eeprom_header header; diff --git a/companion/src/firmwares/opentx/opentxeeprom.cpp b/companion/src/firmwares/opentx/opentxeeprom.cpp index dcd9fdeaa..d7ef3fb50 100644 --- a/companion/src/firmwares/opentx/opentxeeprom.cpp +++ b/companion/src/firmwares/opentx/opentxeeprom.cpp @@ -14,7 +14,7 @@ #define MAX_POTS(board) (IS_TARANIS(board) ? 5 : 3) #define MAX_SWITCHES(board) (IS_TARANIS(board) ? 8 : 7) #define MAX_SWITCHES_POSITION(board) (IS_TARANIS(board) ? 22 : 9) -#define MAX_ROTARY_ENCODERS(board) (board==BOARD_GRUVIN9X ? 2 : (board==BOARD_SKY9X ? 1 : 0)) +#define MAX_ROTARY_ENCODERS(board) (board==BOARD_GRUVIN9X ? 2 : (IS_SKY9X(board) ? 1 : 0)) #define MAX_FLIGHT_MODES(board, version) (IS_ARM(board) ? 9 : (IS_DBLRAM(board, version) ? 6 : 5)) #define MAX_MIXERS(board, version) (IS_ARM(board) ? 64 : 32) #define MAX_CHANNELS(board, version) (IS_ARM(board) ? 32 : 16) @@ -1373,7 +1373,7 @@ class AndSwitchesConversionTable: public ConversionTable { addConversion(RawSwitch(SWITCH_TYPE_VIRTUAL, i), val++); } } - else if (board == BOARD_SKY9X) { + else if (IS_SKY9X(board)) { for (int i=1; i<=8; i++) { int s = switchIndex(i, board, version); addConversion(RawSwitch(SWITCH_TYPE_SWITCH, -s), -val); diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index f73e56b28..4b5dad7b5 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -71,6 +71,8 @@ const char * OpenTxEepromInterface::getName() return "OpenTX for FrSky Taranis Rev4a"; case BOARD_SKY9X: return "OpenTX for Sky9x board / 9X"; + case BOARD_9XRPRO: + return "OpenTX for 9XR-PRO"; default: return "OpenTX for an unknown board"; } @@ -87,6 +89,8 @@ const int OpenTxEepromInterface::getEEpromSize() return EESIZE_GRUVIN9X; case BOARD_SKY9X: return EESIZE_SKY9X; + case BOARD_9XRPRO: + return EESIZE_9XRPRO; case BOARD_TARANIS: case BOARD_TARANIS_PLUS: return EESIZE_TARANIS; @@ -194,7 +198,7 @@ bool OpenTxEepromInterface::loadModel(uint8_t version, ModelData &model, uint8_t if (board == BOARD_GRUVIN9X) { return loadModel(model, data, index, 0 /*no more stick mode messed*/); } - else if (board == BOARD_SKY9X) { + else if (IS_SKY9X(board)) { return loadModel(model, data, index, 0 /*no more stick mode messed*/); } else { @@ -205,7 +209,7 @@ bool OpenTxEepromInterface::loadModel(uint8_t version, ModelData &model, uint8_t if (board == BOARD_GRUVIN9X) { return loadModel(model, data, index, 0 /*no more stick mode messed*/); } - else if (board == BOARD_SKY9X) { + else if (IS_SKY9X(board)) { return loadModel(model, data, index, 0 /*no more stick mode messed*/); } else { @@ -216,7 +220,7 @@ bool OpenTxEepromInterface::loadModel(uint8_t version, ModelData &model, uint8_t if (board == BOARD_GRUVIN9X) { return loadModel(model, data, index, 0 /*no more stick mode messed*/); } - else if (board == BOARD_SKY9X) { + else if (IS_SKY9X(board)) { return loadModel(model, data, index, 0 /*no more stick mode messed*/); } else { @@ -227,7 +231,7 @@ bool OpenTxEepromInterface::loadModel(uint8_t version, ModelData &model, uint8_t if (board == BOARD_GRUVIN9X) { return loadModel(model, data, index, 0 /*no more stick mode messed*/); } - else if (board == BOARD_SKY9X) { + else if (IS_SKY9X(board)) { return loadModel(model, data, index, 0 /*no more stick mode messed*/); } else { @@ -235,7 +239,7 @@ bool OpenTxEepromInterface::loadModel(uint8_t version, ModelData &model, uint8_t } } else if (version == 212) { - if (board == BOARD_SKY9X) { + if (IS_SKY9X(board)) { return loadModel(model, data, index); } else { @@ -365,6 +369,7 @@ int OpenTxEepromInterface::save(uint8_t *eeprom, RadioData &radioData, uint32_t case BOARD_TARANIS_PLUS: case BOARD_TARANIS_REV4a: case BOARD_SKY9X: + case BOARD_9XRPRO: version = 216; break; case BOARD_GRUVIN9X: @@ -412,7 +417,7 @@ int OpenTxEepromInterface::save(uint8_t *eeprom, RadioData &radioData, uint32_t int OpenTxEepromInterface::getSize(ModelData &model) { - if (board == BOARD_SKY9X) + if (IS_SKY9X(board)) return 0; if (model.isempty()) @@ -435,7 +440,7 @@ int OpenTxEepromInterface::getSize(ModelData &model) int OpenTxEepromInterface::getSize(GeneralSettings &settings) { - if (board == BOARD_SKY9X) + if (IS_SKY9X(board)) return 0; uint8_t tmp[EESIZE_RLC_MAX]; @@ -512,7 +517,7 @@ int OpenTxFirmware::getCapability(const Capability capability) case Timers: return 2; case PermTimers: - if (board == BOARD_GRUVIN9X || board == BOARD_SKY9X || IS_TARANIS(board) ) + if (board == BOARD_GRUVIN9X || IS_ARM(board)) return 1; else return 0; @@ -546,7 +551,7 @@ int OpenTxFirmware::getCapability(const Capability capability) case RotaryEncoders: if (board == BOARD_GRUVIN9X) return 2; - else if (board == BOARD_SKY9X) + else if (IS_SKY9X(board)) return 1; else return 0; @@ -636,13 +641,13 @@ int OpenTxFirmware::getCapability(const Capability capability) case HasFailsafe: if (IS_TARANIS(board)) return 32; // - return (board==BOARD_SKY9X ? 16 : 0); + return (IS_SKY9X(board) ? 16 : 0); case NumModules: return (IS_ARM(board) ? 2 : 1); case HasPPMStart: return (IS_ARM(board) ? true : false); case HasCurrentCalibration: - return (board==BOARD_SKY9X ? true : false); + return (IS_SKY9X(board) ? true : false); case HasVolume: return (IS_ARM(board) ? true : false); case HasBrightness: @@ -732,7 +737,7 @@ int OpenTxEepromInterface::isAvailable(Protocol proto, int port) return 0; } } - else if (board==BOARD_SKY9X) { + else if (IS_SKY9X(board)) { switch (port) { case 0: switch (proto) { @@ -774,8 +779,6 @@ int OpenTxEepromInterface::isAvailable(Protocol proto, int port) } } - - template size_t getSizeA(T (&)[SIZE]) { return SIZE; @@ -949,6 +952,7 @@ QString OpenTxFirmware::getReleaseNotesUrl() case BOARD_M128: case BOARD_GRUVIN9X: case BOARD_SKY9X: + case BOARD_9XRPRO: url.append("9x.txt"); break; case BOARD_TARANIS: @@ -965,35 +969,36 @@ QString OpenTxFirmware::getReleaseNotesUrl() QString OpenTxFirmware::getStampUrl() { - QString url = g.compileServer(); - if (url.isEmpty()){ - url= OPENTX_FIRMWARE_DOWNLOADS; - g.compileServer(url); - } - url.append("/stamp-opentx-"); - switch(board) { - case BOARD_STOCK: - url.append("9x.txt"); - break; - case BOARD_M128: - url.append("9x128.txt"); - break; - case BOARD_GRUVIN9X: - url.append("gruvin9x.txt"); - break; - case BOARD_SKY9X: - url.append("sky9x.txt"); - break; - case BOARD_TARANIS: - case BOARD_TARANIS_PLUS: - case BOARD_TARANIS_REV4a: - url.append("taranis.txt"); - break; - default: - url.clear(); - break; - } - return url; + QString url = g.compileServer(); + if (url.isEmpty()){ + url= OPENTX_FIRMWARE_DOWNLOADS; + g.compileServer(url); + } + url.append("/stamp-opentx-"); + switch(board) { + case BOARD_STOCK: + url.append("9x.txt"); + break; + case BOARD_M128: + url.append("9x128.txt"); + break; + case BOARD_GRUVIN9X: + url.append("gruvin9x.txt"); + break; + case BOARD_SKY9X: + case BOARD_9XRPRO: + url.append("sky9x.txt"); + break; + case BOARD_TARANIS: + case BOARD_TARANIS_PLUS: + case BOARD_TARANIS_REV4a: + url.append("taranis.txt"); + break; + default: + url.clear(); + break; + } + return url; } SimulatorInterface * OpenTxFirmware::getSimulator() @@ -1006,6 +1011,7 @@ SimulatorInterface * OpenTxFirmware::getSimulator() case BOARD_GRUVIN9X: return new Open9xGruvin9xSimulator(); case BOARD_SKY9X: + case BOARD_9XRPRO: return new Open9xSky9xSimulator(); case BOARD_TARANIS: case BOARD_TARANIS_PLUS: @@ -1213,6 +1219,53 @@ void registerOpenTxFirmwares() openTx->addOption("bluetooth", QObject::tr("Bluetooth interface")); openTx->addOptions(fai_options); firmwares.push_back(openTx); + + /* SKY9X board */ + openTx = new OpenTxFirmware("opentx-9xrpro", QObject::tr("OpenTX for 9XR-PRO"), BOARD_9XRPRO, true); + openTx->setVariantBase(FRSKY_VARIANT); + openTx->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support")); + openTx->addOption("templates", QObject::tr("Enable TEMPLATES menu")); + openTx->addOption("nofp", QObject::tr("No flight modes")); + openTx->addOption("nocurves", QObject::tr("Disable curves menus")); + openTx->addOption("ppmca", QObject::tr("PPM center adjustment in limits")); + openTx->addOption("ppmus", QObject::tr("PPM values displayed in us")); + openTx->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT); + openTx->addOption("symlimits", QObject::tr("Symetrical Limits")); + openTx->addOption("potscroll", QObject::tr("Pots use in menus navigation")); + openTx->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving some of them")); + openTx->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving some of them")); + openTx->addOption("dblkeys", QObject::tr("Enable resetting values by pressing up and down at the same time")); + openTx->addOption("nographics", QObject::tr("No graphical check boxes and sliders")); + openTx->addOption("battgraph", QObject::tr("Battery graph")); + openTx->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items")); + openTx->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); + openTx->addOption("tsticks", QObject::tr("Use FrSky Taranis sticks in a 9X/9XR")); + openTx->addOption("bluetooth", QObject::tr("Bluetooth interface")); + openTx->addOptions(fai_options); + firmwares.push_back(openTx); + openTx = new OpenTxFirmware("opentx-sky9x", QObject::tr("OpenTX for Sky9x board / 9X"), BOARD_SKY9X, true); + openTx->setVariantBase(FRSKY_VARIANT); + openTx->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support")); + openTx->addOption("templates", QObject::tr("Enable TEMPLATES menu")); + openTx->addOption("nofp", QObject::tr("No flight modes")); + openTx->addOption("nocurves", QObject::tr("Disable curves menus")); + openTx->addOption("ppmca", QObject::tr("PPM center adjustment in limits")); + openTx->addOption("ppmus", QObject::tr("Channel values displayed in us")); + openTx->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT); + openTx->addOption("symlimits", QObject::tr("Symetrical Limits")); + openTx->addOption("potscroll", QObject::tr("Pots use in menus navigation")); + openTx->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving the control")); + openTx->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving the control")); + openTx->addOption("dblkeys", QObject::tr("Enable resetting values by pressing up and down at the same time")); + openTx->addOption("nographics", QObject::tr("No graphical check boxes and sliders")); + openTx->addOption("battgraph", QObject::tr("Battery graph")); + openTx->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items")); + openTx->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); + openTx->addOption("tsticks", QObject::tr("Use FrSky Taranis sticks in a 9X/9XR")); + openTx->addOption("bluetooth", QObject::tr("Bluetooth interface")); + openTx->addOptions(fai_options); + firmwares.push_back(openTx); + #endif /* Taranis board */ diff --git a/companion/src/firmwares/opentx/opentxinterface.h b/companion/src/firmwares/opentx/opentxinterface.h index b2039dd26..6d8559879 100644 --- a/companion/src/firmwares/opentx/opentxinterface.h +++ b/companion/src/firmwares/opentx/opentxinterface.h @@ -114,8 +114,8 @@ class OpenTxFirmware: public FirmwareInterface { virtual int getCapability(const Capability); virtual SimulatorInterface * getSimulator(); - - + + }; void registerOpenTxFirmwares(); diff --git a/companion/src/mainwindow.cpp b/companion/src/mainwindow.cpp index 046ea3b9c..0e55eac9b 100644 --- a/companion/src/mainwindow.cpp +++ b/companion/src/mainwindow.cpp @@ -818,7 +818,7 @@ QString MainWindow::GetAvrdudeLocation() EEPROMInterface *eepromInterface = GetEepromInterface(); if (IS_TARANIS(eepromInterface->getBoard())) { return bcd.getDFU(); - } else if (eepromInterface->getBoard()==BOARD_SKY9X) { + } else if (IS_SKY9X(GetEepromInterface()->getBoard())) { return bcd.getSAMBA(); } else { return bcd.getAVRDUDE(); @@ -905,7 +905,7 @@ QStringList MainWindow::GetReceiveEEpromCommand(const QString &filename) EEPROMInterface *eepromInterface = GetEepromInterface(); if (IS_TARANIS(eepromInterface->getBoard())) { // return NULL; // to be implemented - } else if (eepromInterface->getBoard() == BOARD_SKY9X) { + } else if (IS_SKY9X(eepromInterface->getBoard())) { ret=GetSambaArguments(QString("SERIALFLASH::Init 0\n") + "receive_file {SerialFlash AT25} \"" + filename + "\" 0x0 0x80000 0\n"); } else { ret=GetAvrdudeArguments("eeprom:r:", filename); @@ -919,7 +919,7 @@ QStringList MainWindow::GetSendEEpromCommand(const QString &filename) EEPROMInterface *eepromInterface = GetEepromInterface(); if (IS_TARANIS(eepromInterface->getBoard())) { // return NULL; // to be implemented - } else if (eepromInterface->getBoard() == BOARD_SKY9X) { + } else if (IS_SKY9X(eepromInterface->getBoard())) { ret=GetSambaArguments(QString("SERIALFLASH::Init 0\n") + "send_file {SerialFlash AT25} \"" + filename + "\" 0x0 0\n"); } else { ret=GetAvrdudeArguments("eeprom:w:", filename); @@ -935,6 +935,8 @@ QStringList MainWindow::GetSendFlashCommand(const QString &filename) ret=GetDFUUtilArguments("-D", filename); } else if (eepromInterface->getBoard() == BOARD_SKY9X) { ret=GetSambaArguments(QString("send_file {Flash} \"") + filename + "\" 0x400000 0\n" + "FLASH::ScriptGPNMV 2\n"); + } else if (eepromInterface->getBoard() == BOARD_9XRPRO) { + ret=GetSambaArguments(QString("send_file {Flash} \"") + filename + "\" 0x400000 0\n" + "FLASH::ScriptGPNMV 2\n"); } else { ret=GetAvrdudeArguments("flash:w:", filename); } @@ -948,6 +950,8 @@ QStringList MainWindow::GetReceiveFlashCommand(const QString &filename) return GetDFUUtilArguments("-U", filename); } else if (eepromInterface->getBoard() == BOARD_SKY9X) { return GetSambaArguments(QString("receive_file {Flash} \"") + filename + "\" 0x400000 0x40000 0\n"); + } else if (eepromInterface->getBoard() == BOARD_9XRPRO) { + return GetSambaArguments(QString("receive_file {Flash} \"") + filename + "\" 0x400000 0x80000 0\n"); } else { return GetAvrdudeArguments("flash:r:", filename); } diff --git a/companion/src/mdichild.cpp b/companion/src/mdichild.cpp index 0fccbf92a..6b4f3dac7 100644 --- a/companion/src/mdichild.cpp +++ b/companion/src/mdichild.cpp @@ -71,7 +71,6 @@ MdiChild::MdiChild(): fileChanged(false) { ui->setupUi(this); - this->setWindowIcon(CompanionIcon("open.png")); ui->SimulateTxButton->setIcon(CompanionIcon("simulate.png")); setAttribute(Qt::WA_DeleteOnClose); @@ -118,7 +117,6 @@ void MdiChild::copy() ui->modelsList->copy(); } - void MdiChild::paste() { ui->modelsList->paste(); @@ -137,7 +135,7 @@ bool MdiChild::hasSelection() void MdiChild::updateTitle() { QString title = userFriendlyCurrentFile() + "[*]"+" ("+GetEepromInterface()->getName()+QString(")"); - if (GetEepromInterface()->getBoard() != BOARD_SKY9X) + if (!IS_SKY9X(GetEepromInterface()->getBoard())) title += QString(" - %1 ").arg(EEPromAvail) + tr("free bytes"); setWindowTitle(title); } @@ -155,7 +153,7 @@ void MdiChild::on_SimulateTxButton_clicked() startSimulation(this, radioData, -1); } -void MdiChild::checkAndInitModel( int row ) +void MdiChild::checkAndInitModel(int row) { ModelData &model = radioData.models[row - 1]; if (model.isempty()) { @@ -360,7 +358,7 @@ bool MdiChild::save() bool MdiChild::saveAs(bool isNew) { QString fileName; - if (GetEepromInterface()->getBoard() == BOARD_SKY9X) { + if (IS_SKY9X(GetEepromInterface()->getBoard())) { curFile.replace(".eepe", ".bin"); QFileInfo fi(curFile); #ifdef __APPLE__ @@ -396,7 +394,7 @@ bool MdiChild::saveFile(const QString &fileName, bool setCurrent) { QString myFile; myFile = fileName; - if (GetEepromInterface()->getBoard() == BOARD_SKY9X) { + if (IS_SKY9X(GetEepromInterface()->getBoard())) { myFile.replace(".eepe", ".bin"); } QFile file(myFile); @@ -672,7 +670,7 @@ void MdiChild::print(int model, QString filename) else if (ui->modelsList->currentRow() > 0) { pd = new PrintDialog(this, GetCurrentFirmware()/*firmware*/, &radioData.generalSettings, &radioData.models[ui->modelsList->currentRow()-1]); } - + if (pd) { pd->setAttribute(Qt::WA_DeleteOnClose, true); pd->show(); diff --git a/companion/src/modelslist.cpp b/companion/src/modelslist.cpp index 26d99e9e7..611e449bd 100644 --- a/companion/src/modelslist.cpp +++ b/companion/src/modelslist.cpp @@ -290,7 +290,7 @@ void ModelsListWidget::refreshList() QString item = QString().sprintf("%02d: ", i+1); if (!radioData->models[i].isempty()) { - if (eepromInterface && eepromInterface->getBoard() == BOARD_SKY9X) { + if (eepromInterface && IS_SKY9X(eepromInterface->getBoard())) { if (radioData->models[i].name[0]==0) { QString modelname="Model"; modelname.append(QString().sprintf("%02d", i+1)); @@ -334,7 +334,7 @@ void ModelsListWidget::refreshList() this->item(radioData->generalSettings.currModel+1)->setFont(f); } - if (eepromInterface && eepromInterface->getBoard() != BOARD_SKY9X) { + if (eepromInterface && !IS_SKY9X(eepromInterface->getBoard())) { ((MdiChild*)parent())->setEEpromAvail((availableEEpromSize/16)*15); } } diff --git a/companion/src/simulation/simulatordialog.cpp b/companion/src/simulation/simulatordialog.cpp index e1d3b7bc0..0b1679026 100644 --- a/companion/src/simulation/simulatordialog.cpp +++ b/companion/src/simulation/simulatordialog.cpp @@ -834,8 +834,8 @@ void SimulatorDialog::setValues() logicalSwitchLabels[i]->setStyleSheet(outputs.vsw[i] ? CSWITCH_ON : CSWITCH_OFF); } - for (int fm=0; fmsetText(QString("%1").arg(outputs.gvars[fm][gv])); } } diff --git a/radio/src/Makefile b/radio/src/Makefile index 2ef55326c..0aef1c9b1 100644 --- a/radio/src/Makefile +++ b/radio/src/Makefile @@ -50,7 +50,7 @@ DELAY = 5 #----------- BUILD OPTIONS --------------------------- # PCB version -# Values: 9X, 9X128, 9X2561, 9XR, 9XR128, 9XR2561, GRUVIN9X, MEGA2560, SKY9X, TARANIS +# Values: 9X, 9X128, 9X2561, 9XR, 9XR128, 9XR2561, GRUVIN9X, MEGA2560, SKY9X, 9XRPRO, TARANIS # Old values STD and STD128 are mapped to 9X and 9X128 for compatibility PCB = 9X @@ -287,7 +287,7 @@ INCDIRS = . translations EXTRAINCDIRS = # MCU name -ifneq ($(PCB), $(filter $(PCB), STD 9X 9XR STD128 9X128 9XR128 9X2561 9XR2561 GRUVIN9X MEGA2560 SKY9X TARANIS)) +ifneq ($(PCB), $(filter $(PCB), STD 9X 9XR STD128 9X128 9XR128 9X2561 9XR2561 GRUVIN9X MEGA2560 SKY9X 9XRPRO TARANIS)) $(error Sorry, the PCB $(PCB) is not supported yet in OpenTX) endif @@ -547,19 +547,25 @@ ifeq ($(PCB), MEGA2560) CPPDEFS += -DROTARY_ENCODERS=${ROTARY_ENCODERS} endif -ifeq ($(PCB), SKY9X) - # 9x radio with a sky9x replacement board +ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO)) + # 9x/9XR radio with a sky9x replacement board ARCH = ARM - CPPDEFS = -Dat91sam3s4 - ifeq ($(PCBREV), REVA) + CPPDEFS = -Dat91sam3s4 + ifeq ($(PCB), 9XRPRO) + CPPDEFS += -DREVX + LDSCRIPT = targets/sky9x/sam3s8c_flash.ld + else ifeq ($(PCBREV), REVA) CPPDEFS += -DREVA LDSCRIPT = targets/sky9x/sam3s2c_flash.ld + CPPSRC += targets/sky9x/coproc_driver.cpp else ifeq ($(PCBREV), REVB) - CPPDEFS += -DREVB + CPPDEFS += -DREVB -DCOPROCESSOR LDSCRIPT = targets/sky9x/sam3s4c_flash.ld + CPPSRC += targets/sky9x/coproc_driver.cpp else - CPPDEFS += -DREVC + CPPDEFS += -DREVC -DCOPROCESSOR LDSCRIPT = targets/sky9x/sam3s4c_flash.ld + CPPSRC += targets/sky9x/coproc_driver.cpp endif TRGT = arm-none-eabi- MCU = cortex-m3 @@ -580,7 +586,7 @@ ifeq ($(PCB), SKY9X) EEPROMSRC = eeprom_common.cpp eeprom_raw.cpp eeprom_conversions.cpp PULSESSRC = protocols/pulses_arm.cpp protocols/ppm_arm.cpp protocols/pxx_arm.cpp protocols/dsm2_arm.cpp CPPSRC += audio_arm.cpp haptic.cpp gui/view_about.cpp - CPPSRC += targets/sky9x/pwr_driver.cpp targets/sky9x/adc_driver.cpp targets/sky9x/coproc_driver.cpp targets/sky9x/rotenc_driver.cpp targets/sky9x/eeprom_driver.cpp targets/sky9x/pulses_driver.cpp targets/sky9x/keys_driver.cpp targets/sky9x/audio_driver.cpp targets/sky9x/buzzer_driver.cpp targets/sky9x/haptic_driver.cpp targets/sky9x/sdcard_driver.cpp targets/sky9x/massstorage.cpp + CPPSRC += targets/sky9x/pwr_driver.cpp targets/sky9x/adc_driver.cpp targets/sky9x/rotenc_driver.cpp targets/sky9x/eeprom_driver.cpp targets/sky9x/pulses_driver.cpp targets/sky9x/keys_driver.cpp targets/sky9x/audio_driver.cpp targets/sky9x/buzzer_driver.cpp targets/sky9x/haptic_driver.cpp targets/sky9x/sdcard_driver.cpp targets/sky9x/massstorage.cpp ifeq ($(SDCARD), YES) CPPDEFS += -DVOICE @@ -741,8 +747,8 @@ FORMAT = ihex TARGET = opentx # List C++ source files here. (C dependencies are automatically generated.) -ifeq ($(PCB), $(filter $(PCB), SKY9X TARANIS)) - TTS_SRC = translations/tts_cz.cpp translations/tts_de.cpp translations/tts_en.cpp translations/tts_es.cpp translations/tts_fr.cpp translations/tts_it.cpp translations/tts_pl.cpp translations/tts_pt.cpp translations/tts_sk.cpp translations/tts_se.cpp +ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO TARANIS)) + TTS_SRC = translations/tts_cz.cpp translations/tts_de.cpp translations/tts_en.cpp translations/tts_es.cpp translations/tts_fr.cpp translations/tts_it.cpp translations/tts_pt.cpp translations/tts_sk.cpp translations/tts_se.cpp translations/tts_pl.cpp else STD_TTS_SRC = translations/tts_$(shell sh -c "echo $(TTS) | tr '[:upper:]' '[:lower:]'").cpp TTS_SRC = $(shell sh -c "if test -f $(STD_TTS_SRC); then echo $(STD_TTS_SRC); else echo translations/tts_en.cpp; fi") diff --git a/radio/src/gui/menu_general.cpp b/radio/src/gui/menu_general.cpp index 3cce79fa7..89a4e277f 100644 --- a/radio/src/gui/menu_general.cpp +++ b/radio/src/gui/menu_general.cpp @@ -1179,8 +1179,8 @@ void menuGeneralVersion(uint8_t event) SIMPLE_MENU(STR_MENUVERSION, menuTabDiag, e_Vers, 1); lcd_putsLeft(2*FH, vers_stamp); - -#if defined(PCBSKY9X) && !defined(REVA) + +#if defined(COPROCESSOR) if (Coproc_valid == 1) { lcd_putsLeft(6*FH, PSTR("CoPr:")); lcd_outdez8(10*FW, 6*FH, Coproc_read); diff --git a/radio/src/gui/view_statistics.cpp b/radio/src/gui/view_statistics.cpp index dc7608410..21932b52b 100644 --- a/radio/src/gui/view_statistics.cpp +++ b/radio/src/gui/view_statistics.cpp @@ -156,7 +156,7 @@ void menuStatisticsDebug(uint8_t event) putsTelemetryValue(20*FW+2, 3*FH, maxTemperature+g_eeGeneral.temperatureCalib, UNIT_TEMPERATURE, 0); #endif -#if defined(PCBSKY9X) +#if defined(COPROCESSOR) lcd_putsLeft(4*FH, STR_COPROC_TEMP); if (Coproc_read==0) { diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index b35a146b8..e5d15f270 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -298,10 +298,24 @@ volatile tmr10ms_t g_tmr10ms; #if defined(CPUARM) volatile uint8_t rtc_count = 0; uint32_t watchdogTimeout = 0; + void watchdogSetTimeout(uint32_t timeout) { watchdogTimeout = timeout; } + +void opentxBootloader() +{ + BACKLIGHT_ON(); + + lcd_clear(); + lcd_putcAtt( 48, 24, 'U', DBLSIZE ) ; + lcd_putcAtt( 60, 24, 'S', DBLSIZE ) ; + lcd_putcAtt( 72, 24, 'B', DBLSIZE ) ; + lcdRefresh() ; + + usbBootloader(); +} #endif void per10ms() @@ -326,7 +340,7 @@ void per10ms() /* Update global Date/Time every 100 per10ms cycles */ if (++g_ms100 == 100) { g_rtcTime++; // inc global unix timestamp one second -#if defined(PCBSKY9X) +#if defined(COPROCESSOR) if (g_rtcTime < 60 || rtc_count<5) { rtcInit(); rtc_count++; @@ -5682,15 +5696,7 @@ int main(void) g_eeGeneral.backlightBright = 0; g_eeGeneral.contrast = 25; - BACKLIGHT_ON(); - - lcd_clear(); - lcd_putcAtt( 48, 24, 'U', DBLSIZE ) ; - lcd_putcAtt( 60, 24, 'S', DBLSIZE ) ; - lcd_putcAtt( 72, 24, 'B', DBLSIZE ) ; - lcdRefresh() ; - - usbBootloader(); + opentxBootloader(); } CoInitOS(); diff --git a/radio/src/targets/sky9x/audio_driver.cpp b/radio/src/targets/sky9x/audio_driver.cpp index 5f18edda4..4cfe0b25b 100644 --- a/radio/src/targets/sky9x/audio_driver.cpp +++ b/radio/src/targets/sky9x/audio_driver.cpp @@ -136,6 +136,11 @@ void audioInit() pioptr->PIO_PER = 0x02000000L ; // Enable bit A25 (Stock buzzer) pioptr->PIO_OER = 0x02000000L ; // Set bit A25 as output #endif + +#if defined(REVX) + configure_pins( PIO_PC26, PIN_ENABLE | PIN_LOW | PIN_OUTPUT | PIN_PORTC | PIN_NO_PULLUP ) ; + PIOC->PIO_CODR = PIO_PC26 ; +#endif } void audioEnd() @@ -157,21 +162,11 @@ static const int8_t volumeScale[VOLUME_LEVEL_MAX+1] = void setVolume(uint8_t volume) { - coprocVolumeRequired = volumeScale[min(volume, VOLUME_LEVEL_MAX)]; + volumeRequired = volumeScale[min(volume, VOLUME_LEVEL_MAX)]; __disable_irq() ; - coprocCheck() ; + i2cCheck() ; __enable_irq() ; } -#if 0 -void getVolume() -{ - coprocVolumeReadPending = 1 ; - __disable_irq() ; - coprocCheck() ; - __enable_irq() ; -} -#endif - diff --git a/radio/src/targets/sky9x/board_sky9x.cpp b/radio/src/targets/sky9x/board_sky9x.cpp index a33453da3..1492bf1fa 100644 --- a/radio/src/targets/sky9x/board_sky9x.cpp +++ b/radio/src/targets/sky9x/board_sky9x.cpp @@ -528,6 +528,34 @@ void configure_pins( uint32_t pins, uint16_t config ) } } +void opentxBootloader(); + +// Set up for volume control (TWI0) +// Need PA3 and PA4 set to peripheral A +void i2cInit() +{ + register Pio *pioptr ; + register uint32_t timing ; + + PMC->PMC_PCER0 |= 0x00080000L ; // Enable peripheral clock to TWI0 + + /* Configure PIO */ + pioptr = PIOA ; + pioptr->PIO_ABCDSR[0] &= ~0x00000018 ; // Peripheral A + pioptr->PIO_ABCDSR[1] &= ~0x00000018 ; // Peripheral A + pioptr->PIO_PDR = 0x00000018 ; // Assign to peripheral + + timing = Master_frequency * 5 / 1000000 ; // 5uS high and low + timing += 15 - 4 ; + timing /= 16 ; + timing |= timing << 8 ; + + TWI0->TWI_CWGR = 0x00040000 | timing ; // TWI clock set + TWI0->TWI_CR = TWI_CR_MSEN | TWI_CR_SVDIS ; // Master mode enable + TWI0->TWI_MMR = 0x002F0000 ; // Device 5E (>>1) and master is writing + NVIC_EnableIRQ(TWI0_IRQn) ; +} + void boardInit() { register Pio *pioptr ; @@ -538,33 +566,35 @@ void boardInit() PMC->PMC_PCER0 = (1<PIO_PER = PIO_PC25 ; // Enable bit C25 (USB-detect) + +#if defined(REVX) + if (usbPlugged()) { + lcdInit() ; + opentxBootloader(); + } +#endif + #if defined(REVA) // On REVB, PA21 is used as AD8, and measures current consumption. pioptr = PIOA ; pioptr->PIO_PER = PIO_PA21 ; // Enable bit A21 (EXT3) pioptr->PIO_OER = PIO_PA21 ; // Set bit A21 as output pioptr->PIO_SODR = PIO_PA21 ; // Set bit A21 ON -#else - pwrInit() ; -#endif - // pioptr->PIO_PUER = 0x80000000 ; // Enable pullup on bit A31 (EXIT) - // pioptr->PIO_PER = 0x80000000 ; // Enable bit A31 - - pioptr = PIOC ; - pioptr->PIO_PER = PIO_PC25 ; // Enable bit C25 (USB-detect) - // pioptr->PIO_OER = 0x80000000L ; // Set bit C31 as output - // pioptr->PIO_SODR = 0x80000000L ; // Set bit C31 - -#if defined(REVA) // Configure RF_power (PC17) and PPM-jack-in (PC19), neither need pullups pioptr->PIO_PER = 0x000A0000L ; // Enable bit C19, C17 pioptr->PIO_ODR = 0x000A0000L ; // Set bits C19 and C17 as input #endif +#if !defined(REVA) + pwrInit() ; +#endif + config_free_pins() ; // Next section configures the key inputs on the LCD data + pioptr = PIOC; #if defined(REVA) pioptr->PIO_PER = 0x0000003DL ; // Enable bits 2,3,4,5, 0 pioptr->PIO_OER = PIO_PC0 ; // Set bit 0 output @@ -605,11 +635,11 @@ void boardInit() adcInit() ; init_pwm() ; - __enable_irq() ; + __enable_irq(); - audioInit() ; + audioInit(); - coprocInit() ; + i2cInit(); eepromInit(); diff --git a/radio/src/targets/sky9x/board_sky9x.h b/radio/src/targets/sky9x/board_sky9x.h index 89d8be49a..7b11167ab 100644 --- a/radio/src/targets/sky9x/board_sky9x.h +++ b/radio/src/targets/sky9x/board_sky9x.h @@ -224,13 +224,14 @@ void buzzerSound(uint8_t duration); void buzzerHeartbeat(); #define BUZZER_HEARTBEAT buzzerHeartbeat +// i2c driver +void i2cCheck(); + // Coproc driver void coprocInit(); void coprocWriteData(uint8_t *data, uint32_t size); void coprocReadData(bool onlytemp=false); -void coprocCheck(); -extern int8_t coprocVolumeRequired; -extern uint8_t coprocVolumeReadPending; +extern int8_t volumeRequired; extern uint8_t Coproc_read; extern int8_t Coproc_valid; extern int8_t Coproc_temp; diff --git a/radio/src/targets/sky9x/coproc_driver.cpp b/radio/src/targets/sky9x/coproc_driver.cpp index 8591a52ae..af33f4099 100644 --- a/radio/src/targets/sky9x/coproc_driver.cpp +++ b/radio/src/targets/sky9x/coproc_driver.cpp @@ -36,8 +36,7 @@ #include "../../opentx.h" -int8_t coprocVolumeRequired ; -uint8_t coprocVolumeReadPending ; +int8_t volumeRequired ; uint8_t coprocReadDataPending ; uint8_t coprocWriteDataPending ; uint8_t CoProc_appgo_pending ; @@ -51,7 +50,6 @@ static uint8_t *Twi_read_address ; static uint8_t TwiOperation ; #define TWI_NONE 0 -#define TWI_READ_VOL 1 #define TWI_WRITE_VOL 2 #define TWI_READ_COPROC 3 #define TWI_COPROC_APPGO 4 @@ -72,24 +70,21 @@ uint32_t coprocWriteDataSize ; // This is called from an interrupt routine, or // interrupts must be disabled while it is called // from elsewhere. -void coprocCheck() +void i2cCheck() { - if ( TWI0->TWI_IMR & TWI_IMR_TXCOMP ) - { + if ( TWI0->TWI_IMR & TWI_IMR_TXCOMP ) { return ; // Busy } - if ( coprocVolumeRequired >= 0 ) // Set volume to this value - { + if ( volumeRequired >= 0 ) { // Set volume to this value TWI0->TWI_MMR = 0x002F0000 ; // Device 5E (>>1) and master is writing TwiOperation = TWI_WRITE_VOL ; - TWI0->TWI_THR = coprocVolumeRequired ; // Send data - coprocVolumeRequired = -1 ; + TWI0->TWI_THR = volumeRequired ; // Send data + volumeRequired = -1 ; TWI0->TWI_IER = TWI_IER_TXCOMP ; TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx } - else if (coprocReadDataPending) - { + else if (coprocReadDataPending) { Coproc_valid = 0 ; coprocReadDataPending = 0 ; TWI0->TWI_MMR = 0x00351000 ; // Device 35 and master is reading @@ -98,25 +93,14 @@ void coprocCheck() TWI0->TWI_RPR = (uint32_t)&Co_proc_status[0] ; #endif TWI0->TWI_RCR = COPROC_RX_BUXSIZE - 1 ; - if ( TWI0->TWI_SR & TWI_SR_RXRDY ) - { + if ( TWI0->TWI_SR & TWI_SR_RXRDY ) { (void) TWI0->TWI_RHR ; } TWI0->TWI_PTCR = TWI_PTCR_RXTEN ; // Start transfers TWI0->TWI_CR = TWI_CR_START ; // Start Rx TWI0->TWI_IER = TWI_IER_RXBUFF | TWI_IER_TXCOMP ; } - else if (coprocVolumeReadPending) - { - coprocVolumeReadPending = 0 ; - TWI0->TWI_MMR = 0x002F1000 ; // Device 5E (>>1) and master is reading - TwiOperation = TWI_READ_VOL ; - Twi_read_address = &Volume_read ; - TWI0->TWI_CR = TWI_CR_START | TWI_CR_STOP ; // Start and stop Tx - TWI0->TWI_IER = TWI_IER_TXCOMP ; - } - else if ( CoProc_appgo_pending ) - { + else if ( CoProc_appgo_pending ) { CoProc_appgo_pending = 0 ; TWI0->TWI_MMR = 0x00350000 ; // Device 35 and master is writing TwiOperation = TWI_COPROC_APPGO ; @@ -124,8 +108,7 @@ void coprocCheck() TWI0->TWI_IER = TWI_IER_TXCOMP ; TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx } - else if ( coprocWriteDataPending ) - { + else if ( coprocWriteDataPending ) { coprocWriteDataPending = 0 ; TWI0->TWI_MMR = 0x00350000 ; // Device 35 and master is writing TwiOperation = TWI_WRITE_COPROC ; @@ -144,7 +127,7 @@ void coprocReadData(bool onlytemp) get_onlytemp = onlytemp; coprocReadDataPending = 1 ; __disable_irq() ; - coprocCheck() ; + i2cCheck() ; __enable_irq() ; } @@ -154,57 +137,13 @@ void coprocWriteData(uint8_t *data, uint32_t size) coprocWriteDataSize = size; coprocWriteDataPending = 1; __disable_irq(); - coprocCheck(); + i2cCheck(); __enable_irq(); } -#if 0 -void appgo_coprocessor() -{ - CoProc_appgo_pending = 1 ; - __disable_irq() ; - coprocCheck() ; - __enable_irq() ; -} -#endif - -// Set up for volume control (TWI0) -// Need PA3 and PA4 set to peripheral A -void coprocInit() -{ - register Pio *pioptr ; - register uint32_t timing ; - - PMC->PMC_PCER0 |= 0x00080000L ; // Enable peripheral clock to TWI0 - - /* Configure PIO */ - pioptr = PIOA ; - pioptr->PIO_ABCDSR[0] &= ~0x00000018 ; // Peripheral A - pioptr->PIO_ABCDSR[1] &= ~0x00000018 ; // Peripheral A - pioptr->PIO_PDR = 0x00000018 ; // Assign to peripheral - - timing = Master_frequency * 5 / 1000000 ; // 5uS high and low - timing += 15 - 4 ; - timing /= 16 ; - timing |= timing << 8 ; - - TWI0->TWI_CWGR = 0x00040000 | timing ; // TWI clock set - TWI0->TWI_CR = TWI_CR_MSEN | TWI_CR_SVDIS ; // Master mode enable - TWI0->TWI_MMR = 0x002F0000 ; // Device 5E (>>1) and master is writing - NVIC_EnableIRQ(TWI0_IRQn) ; -} - #if !defined(SIMU) extern "C" void TWI0_IRQHandler() { - if ( TwiOperation == TWI_READ_VOL ) - { - if ( TWI0->TWI_SR & TWI_SR_RXRDY ) - { - *Twi_read_address = TWI0->TWI_RHR ; // Read data - } - } - if ( TwiOperation == TWI_READ_COPROC ) { if ( TWI0->TWI_SR & TWI_SR_RXBUFF ) @@ -275,6 +214,6 @@ extern "C" void TWI0_IRQHandler() { } TwiOperation = TWI_NONE ; - coprocCheck() ; + i2cCheck() ; } #endif diff --git a/radio/src/targets/sky9x/lcd_driver.cpp b/radio/src/targets/sky9x/lcd_driver.cpp index 9fa3a85e3..4bbedc638 100644 --- a/radio/src/targets/sky9x/lcd_driver.cpp +++ b/radio/src/targets/sky9x/lcd_driver.cpp @@ -88,7 +88,6 @@ const uint8_t Lcd_lookup[] = void lcdSendCtl(uint8_t val) { register Pio *pioptr ; -// register uint32_t x ; #if defined(REVA) pioptr = PIOC ; @@ -98,9 +97,13 @@ void lcdSendCtl(uint8_t val) pioptr->PIO_ODSR = Lcd_lookup[val] ; #else pioptr = PIOC ; - pioptr->PIO_CODR = LCD_CS1 ; // Select LCD + #if !defined(REVX) + pioptr->PIO_CODR = LCD_CS1 ; // Select LCD + #endif PIOA->PIO_CODR = LCD_A0 ; - pioptr->PIO_CODR = LCD_RnW ; // Write + #if !defined(REVX) + pioptr->PIO_CODR = LCD_RnW ; // Write + #endif pioptr->PIO_ODSR = val ; #endif @@ -117,7 +120,10 @@ void lcdSendCtl(uint8_t val) #else PIOA->PIO_SODR = LCD_A0 ; // Data #endif + +#if !defined(REVX) pioptr->PIO_SODR = LCD_CS1 ; // Deselect LCD +#endif } void lcdInit() @@ -126,6 +132,10 @@ void lcdInit() // /home/thus/txt/datasheets/lcd/KS0713.pdf // ~/txt/flieger/ST7565RV17.pdf from http://www.glyn.de/content.asp?wdid=132&sid= + // read the inputs, and lock the LCD lines + lcdInputs = PIOC->PIO_PDSR; // 6 LEFT, 5 RIGHT, 4 DOWN, 3 UP () + lcdLock = 1 ; + #if defined(REVA) pioptr = PIOC ; pioptr->PIO_PER = 0x0C00B0FFL ; // Enable bits 27,26,15,13,12,7-0 @@ -136,10 +146,16 @@ void lcdInit() #else configure_pins( LCD_A0, PIN_ENABLE | PIN_LOW | PIN_OUTPUT | PIN_PORTA | PIN_NO_PULLUP ) ; pioptr = PIOC ; - pioptr->PIO_PER = 0x0C0030FFL ; // Enable bits 27,26,13,12,7-0 - pioptr->PIO_CODR = LCD_E | LCD_RnW ; - pioptr->PIO_SODR = LCD_RES | LCD_CS1 ; - pioptr->PIO_OER = 0x0C0030FFL ; // Set bits 27,26,13,12,7-0 output + #if defined(REVX) + pioptr->PIO_PER = PIO_PC27 | PIO_PC12 | 0xFF ; + pioptr->PIO_CODR = LCD_E ; + pioptr->PIO_CODR = LCD_RnW | LCD_CS1 ; // No longer needed, used elsewhere + #else + pioptr->PIO_PER = PIO_PC27 | PIO_PC26 | PIO_PC13 | PIO_PC12 | 0xFF ; + pioptr->PIO_CODR = LCD_E | LCD_RnW | LCD_CS1 ; + #endif + pioptr->PIO_SODR = LCD_RES ; + pioptr->PIO_OER = PIO_PC27 | PIO_PC26 | PIO_PC13 | PIO_PC12 | 0xFF ; // Set bits 27,26,13,12,7-0 output pioptr->PIO_OWER = 0x000000FFL ; // Allow write to ls 8 bits in ODSR #endif @@ -178,6 +194,8 @@ void lcdInit() pioptr->PIO_PUER = 0x0000003AL ; // Set bits 1, 3, 4, 5 with pullups pioptr->PIO_ODSR = 0 ; // Drive D0 low #endif + + lcdLock = 0 ; } void lcdSetRefVolt(uint8_t val) @@ -246,9 +264,13 @@ void lcdRefresh() lcdSendCtl(0x10); //column addr 0 lcdSendCtl(y | 0xB0); //page addr y - pioptr->PIO_CODR = LCD_CS1; // Select LCD + #if !defined(REVX) + pioptr->PIO_CODR = LCD_CS1; // Select LCD + #endif PIOA->PIO_SODR = LCD_A0; // Data - pioptr->PIO_CODR = LCD_RnW; // Write + #if !defined(REVX) + pioptr->PIO_CODR = LCD_RnW; // Write + #endif #if defined(REVA) x = lookup[*p]; @@ -282,7 +304,9 @@ void lcdRefresh() // } pioptr->PIO_CODR = ebit; // End E pulse } - pioptr->PIO_SODR = LCD_CS1; // Deselect LCD + #if !defined(REVX) + pioptr->PIO_SODR = LCD_CS1; // Deselect LCD + #endif } pioptr->PIO_ODSR = 0xFF ; // Drive lines high diff --git a/radio/src/targets/sky9x/pwr_driver.cpp b/radio/src/targets/sky9x/pwr_driver.cpp index 6d51d53cd..1d6714078 100644 --- a/radio/src/targets/sky9x/pwr_driver.cpp +++ b/radio/src/targets/sky9x/pwr_driver.cpp @@ -38,57 +38,39 @@ uint32_t pwrCheck() { -#ifdef SIMU +#if defined(SIMU) return e_power_on; -#endif - -#if defined(REVC) - if ( PIOC->PIO_PDSR & PIO_PC17 ) // Power on - { - return e_power_on ; - } - - if ( PIOA->PIO_PDSR & PIO_PA8 ) // Trainer plugged in - { - return e_power_trainer ; - } +#elif defined(REVA) + if (PIOC->PIO_PDSR & PIO_PC25) + return e_power_usb; + else if (PIOA->PIO_PDSR & PIO_PA8) + return e_power_trainer; + else + return e_power_on; #elif defined(REVB) - if ( PIOC->PIO_PDSR & PIO_PC17 ) // Power on - { - return e_power_on ; - } - - if (usbPlugged()) - { - return e_power_usb ; // Detected USB - } - - if ( PIOA->PIO_PDSR & PIO_PA8 ) // Trainer plugged in - { - return e_power_trainer ; - } + if (PIOC->PIO_PDSR & PIO_PC17) + return e_power_on; + else if (usbPlugged()) + return e_power_usb; + else if ( PIOA->PIO_PDSR & PIO_PA8 ) + return e_power_trainer; + else + return e_power_off; #else - if ( PIOC->PIO_PDSR & PIO_PC25 ) - { - return e_power_usb ; // Detected USB - } - - if ( PIOA->PIO_PDSR & PIO_PA8 ) // Trainer plugged in - { - return e_power_trainer ; - } - - return e_power_on; + if (PIOC->PIO_PDSR & PIO_PC17) + return e_power_on; + else if (PIOA->PIO_PDSR & PIO_PA8) + return e_power_trainer; + else + return e_power_off; #endif - - return e_power_off; } // turn off soft power void pwrOff() { #if !defined(REVA) - configure_pins( PIO_PA8, PIN_ENABLE | PIN_OUTPUT | PIN_LOW | PIN_PORTA | PIN_NO_PULLUP ) ; + configure_pins(PIO_PA8, PIN_ENABLE | PIN_OUTPUT | PIN_LOW | PIN_PORTA | PIN_NO_PULLUP); #endif } @@ -96,7 +78,7 @@ void pwrOff() void pwrInit() { // Configure RF_power (PC17) - configure_pins( PIO_PC17, PIN_ENABLE | PIN_INPUT | PIN_PORTC | PIN_NO_PULLUP | PIN_PULLDOWN ) ; - configure_pins( PIO_PA8, PIN_ENABLE | PIN_INPUT | PIN_PORTA | PIN_PULLUP ) ; // Enable bit A8 (Soft Power) + configure_pins(PIO_PC17, PIN_ENABLE | PIN_INPUT | PIN_PORTC | PIN_NO_PULLUP | PIN_PULLDOWN); + configure_pins(PIO_PA8, PIN_ENABLE | PIN_INPUT | PIN_PORTA | PIN_PULLUP); // Enable bit A8 (Soft Power) } #endif diff --git a/radio/src/targets/sky9x/rtc_driver.cpp b/radio/src/targets/sky9x/rtc_driver.cpp index 4e72f2a93..1cfd15f3a 100644 --- a/radio/src/targets/sky9x/rtc_driver.cpp +++ b/radio/src/targets/sky9x/rtc_driver.cpp @@ -36,6 +36,216 @@ #include "../opentx.h" +#if defined(REVX) +// TODO change this, not the right place +#define TWI_NONE 0 +#define TWI_WRITE_VOL 2 +#define TWI_WAIT_COMP 7 +#define TWI_READ_RTC 8 +#define TWI_WRITE_RTC 9 +#define TWI_WAIT_RTCSTOP 10 +#define TWI_WRITE_MFP 11 +int8_t volumeRequired ; +int8_t Rtc_read_pending; +uint8_t Rtc_write_pending ; +int8_t Rtc_valid ; +uint8_t MFPsetting = 0 ; +uint8_t CALsetting = 0 ; +uint8_t *Twi_read_address ; +uint8_t TwiOperation ; +#define RTC_RX_BUXSIZE 10 +#define RTC_SIZE 7 +uint8_t Rtc_status[RTC_RX_BUXSIZE] ; +uint8_t *Rtc_write_ptr ; +uint32_t Rtc_write_count ; +uint8_t RtcConfig[8] ; // For initial config and writing to RTC +// 0x80, 0, 0, 0x08, 0, 0, 0, 0x80 + +uint32_t fromBCD(uint8_t bcd_value) +{ + return (((bcd_value & 0xF0) * 10) >> 4) + (bcd_value & 0x0F); +} + +uint32_t toBCD(uint32_t value) +{ + div_t qr = div(value, 10); + return (qr.quot << 4) + qr.rem; +} + +// This is called from an interrupt routine, or +// interrupts must be disabled while it is called +// from elsewhere. +void i2cCheck() +{ + if ( TWI0->TWI_IMR & TWI_IMR_TXCOMP ) { + return ; // Busy + } + + if ( volumeRequired >= 0 ) // Set volume to this value + { + TWI0->TWI_MMR = 0x002F0000 ; // Device 5E (>>1) and master is writing + TwiOperation = TWI_WRITE_VOL ; + TWI0->TWI_THR = volumeRequired ; // Send data + volumeRequired = -1 ; + TWI0->TWI_IER = TWI_IER_TXCOMP ; + TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx + } + else if ( Rtc_read_pending ) + { + Rtc_valid = 0 ; + Rtc_read_pending = 0 ; + TWI0->TWI_MMR = 0x006F1100 ; // Device 6F and master is reading, 1 byte addr + TWI0->TWI_IADR = 0 ; + TwiOperation = TWI_READ_RTC ; +#ifndef SIMU + TWI0->TWI_RPR = (uint32_t)&Rtc_status[0] ; +#endif + TWI0->TWI_RCR = RTC_SIZE - 1 ; + if ( TWI0->TWI_SR & TWI_SR_RXRDY ) + { + (void) TWI0->TWI_RHR ; + } + + TWI0->TWI_PTCR = TWI_PTCR_RXTEN ; // Start transfers + TWI0->TWI_CR = TWI_CR_START ; // Start Rx + TWI0->TWI_IER = TWI_IER_RXBUFF | TWI_IER_TXCOMP ; + } + else if ( Rtc_write_pending ) + { + if ( Rtc_write_pending & (2|4) ) + { + TWI0->TWI_MMR = 0x006F0100 ; // Device 6F and master is writing, 1 byte addr + TwiOperation = TWI_WRITE_MFP ; + if ( Rtc_write_pending & 2 ) + { + TWI0->TWI_IADR = 7 ; + TWI0->TWI_THR = MFPsetting ; // Send data + Rtc_write_pending &= ~2 ; + } + else + { + TWI0->TWI_IADR = 8 ; + TWI0->TWI_THR = CALsetting ; // Send data + Rtc_write_pending &= ~4 ; + } + TWI0->TWI_IER = TWI_IER_TXCOMP ; + TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx + } + else + { + Rtc_write_pending &= ~1 ; + TWI0->TWI_MMR = 0x006F0100 ; // Device 6F and master is writing, 1 byte addr + TWI0->TWI_IADR = 0 ; + TwiOperation = TWI_WRITE_RTC ; +#ifndef SIMU + TWI0->TWI_TPR = (uint32_t)Rtc_write_ptr+1 ; +#endif + TWI0->TWI_TCR = Rtc_write_count-1 ; + TWI0->TWI_THR = *Rtc_write_ptr ; // First byte + TWI0->TWI_PTCR = TWI_PTCR_TXTEN ; // Start data transfer + TWI0->TWI_IER = TWI_IER_TXBUFE | TWI_IER_TXCOMP ; + } + } +} + +void writeRTC(uint8_t *ptr) +{ + uint32_t year; + RtcConfig[0] = 0x80 | toBCD(*ptr++); + RtcConfig[1] = toBCD(*ptr++); + RtcConfig[2] = toBCD(*ptr++); + RtcConfig[3] = 0x08; + RtcConfig[4] = toBCD(*ptr++); + RtcConfig[5] = toBCD( *ptr++); + year = *ptr++; + year |= *ptr << 8; + RtcConfig[6] = toBCD(year - 2000); + RtcConfig[7] = MFPsetting; + Rtc_write_ptr = RtcConfig; + Rtc_write_count = 8; + __disable_irq(); + Rtc_write_pending |= 1; + i2cCheck(); + __enable_irq(); +} + +void readRTC() +{ + Rtc_read_pending = 1 ; + __disable_irq() ; + i2cCheck() ; + __enable_irq() ; +} + +// TODO should be inside an i2c_driver.cpp +#ifndef SIMU +extern "C" void TWI0_IRQHandler() +{ + uint32_t status ; + status = TWI0->TWI_SR ; // Read only once, some bits cleared on read + + if ( TwiOperation == TWI_READ_RTC ) + { + if ( status & TWI_SR_RXBUFF ) + { + TWI0->TWI_IDR = TWI_IDR_RXBUFF ; + TwiOperation = TWI_WAIT_RTCSTOP ; + TWI0->TWI_CR = TWI_CR_STOP ; // Stop Rx + TWI0->TWI_RCR = 1 ; // Last byte + return ; + } + else + { + // must be TXCOMP, prob. NAK in data + if ( TWI0->TWI_RCR > 0 ) + { + Rtc_valid = -1 ; + TWI0->TWI_CR = TWI_CR_STOP ; // Stop Rx + } + } + } + + if ( TwiOperation == TWI_WAIT_RTCSTOP ) + { + Rtc_valid = 1 ; + // Set the date and time + struct gtm utm; + + utm.tm_sec = fromBCD( Rtc_status[0] & 0x7F ) ; + utm.tm_min = fromBCD( Rtc_status[1] & 0x7F ) ; + utm.tm_hour = fromBCD( Rtc_status[2] & 0x3F ) ; + utm.tm_mday = fromBCD( Rtc_status[4] & 0x3F ) ; + utm.tm_mon = fromBCD( Rtc_status[5] & 0x1F ) ; + utm.tm_year = fromBCD( Rtc_status[6] ) + 2000 ; + g_rtcTime = gmktime(&utm); + + TWI0->TWI_PTCR = TWI_PTCR_RXTDIS ; // Stop transfers + if ( status & TWI_SR_RXRDY ) + { + (void) TWI0->TWI_RHR ; // Discard any rubbish data + } + } + + if ( status & TWI_SR_NACK ) + { + TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx + } + + TWI0->TWI_IDR = TWI_IDR_TXCOMP | TWI_IDR_TXBUFE | TWI_IDR_RXBUFF ; + TWI0->TWI_PTCR = TWI_PTCR_TXTDIS | TWI_PTCR_RXTDIS ; // Stop transfers + if ( ( status & TWI_SR_TXCOMP ) == 0 ) + { + TWI0->TWI_IER = TWI_IER_TXCOMP ; + TwiOperation = TWI_WAIT_COMP ; + return ; + } + + TwiOperation = TWI_NONE ; + i2cCheck() ; +} +#endif +#endif + struct t_i2cTime { uint8_t setCode ; @@ -55,10 +265,16 @@ void rtcSetTime(struct gtm * t) I2CTime.Time[4] = t->tm_mon+1 ; I2CTime.Time[5] = (uint8_t) (t->tm_year+1900); I2CTime.Time[6] = (t->tm_year+1900) >> 8; +#if defined(REVX) + writeRTC((uint8_t *)&I2CTime.Time[0]) ; +#else coprocWriteData((uint8_t *) &I2CTime, 8); +#endif } void rtcInit() { - coprocReadData(); +#if defined(REVX) + readRTC(); +#endif } diff --git a/radio/src/targets/sky9x/sam3s2c_flash.ld b/radio/src/targets/sky9x/sam3s2c_flash.ld index f2e1fddc5..54dde2569 100644 --- a/radio/src/targets/sky9x/sam3s2c_flash.ld +++ b/radio/src/targets/sky9x/sam3s2c_flash.ld @@ -129,8 +129,11 @@ SECTIONS . = ALIGN(4); /* Align the end of the section */ } > RAM - _ebss = .; /* Provide the name for the end of this section */ + _ebss = .; /* Provide the name for the end of this section */ + . = ALIGN(4); /* Align the end of the section */ + __end = .; + _end = .; /* * The ".stack" section is our stack. diff --git a/radio/src/targets/sky9x/sam3s8c_flash.ld b/radio/src/targets/sky9x/sam3s8c_flash.ld new file mode 100644 index 000000000..38943f5d9 --- /dev/null +++ b/radio/src/targets/sky9x/sam3s8c_flash.ld @@ -0,0 +1,147 @@ +/**************************************************************************** +* Copyright (c) 2011 by Michael Fischer. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* 3. Neither the name of the author nor the names of its contributors may +* be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +* +***************************************************************************** +* History: +* +* 22.05.2011 mifi First Version +****************************************************************************/ + + +/* + * In this linker script there is no heap available. + * The stack start at the end of the ram segment. + */ + + +/* + * Take a look in the "The GNU linker" manual, here you get + * the following information about the "MEMORY": + * + * "The MEMORY command describes the location and size of + * blocks of memory in the target." + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00400000, LENGTH = 512K + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K +} + + +/* + * And the "SECTION" is used for: + * + * "The SECTIONS command tells the linker how to map input + * sections into output sections, and how to place the output + * sections in memory. + */ +SECTIONS +{ + + /* + * The ".text" section is used for the code, and + * read only (.rodata) data. Even the vectors (.vectors) + * MUST be saved at the start of this section. + */ + .text : + { + _stext = .; /* Provide the name for the start of this section */ + + CREATE_OBJECT_SYMBOLS + KEEP(*(.vectors)) + + *(.text) + *(.text.*) + + . = ALIGN(4); /* Align the start of the exidx part */ + *(.ARM.exidx) + *(.ARM.exidx.*) + + . = ALIGN(4); /* Align the start of the rodata part */ + *(.rodata) + *(.rodata.*) + + . = ALIGN(4); /* Align the end of the section */ + } > FLASH = 0 + _etext = .; /* Provide the name for the end of this section */ + + + /* + * The ".data" section is used for initialized data + * and for functions (.fastrun) which should be copied + * from flash to ram. This functions will later be + * executed from ram instead of flash. + */ + .data : AT (_etext) + { + . = ALIGN(4); /* Align the start of the section */ + _sdata = .; /* Provide the name for the start of this section */ + + *(.data) + *(.data.*) + + . = ALIGN(4); /* Align the start of the fastrun part */ + *(.fastrun) + *(.fastrun.*) + + . = ALIGN(4); /* Align the end of the section */ + } > RAM + _edata = .; /* Provide the name for the end of this section */ + + + /* + * The ".bss" section is used for uninitialized data. + * This section will be cleared by the startup code. + */ + .bss : + { + . = ALIGN(4); /* Align the start of the section */ + _sbss = .; /* Provide the name for the start of this section */ + + *(.bss) + *(.bss.*) + + . = ALIGN(4); /* Align the end of the section */ + } > RAM + _ebss = .; /* Provide the name for the end of this section */ + + . = ALIGN(4); /* Align the end of the section */ + __end = .; + _end = .; + + /* + * The ".stack" section is our stack. + * Here this section starts at the end of the ram segment. + */ + _estack = ORIGIN(RAM) + LENGTH(RAM); + +} + +/*** EOF **/ +