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 **/
+