feat: Flysky PL18 Support (#4105)
Co-authored-by: raphaelcoeffic <raphael.coeffic@frafos.com> Co-authored-by: rotorman <risto.koiva@web.de> Co-authored-by: Xy201207 <yaoxu@flysky.com> Co-authored-by: Peter Feerick <peter.feerick@gmail.com>
6
.github/workflows/actions.yml
vendored
|
@ -46,6 +46,8 @@ jobs:
|
|||
- tx16s
|
||||
- nv14
|
||||
- el18
|
||||
- pl18
|
||||
- pl18ev
|
||||
- t12
|
||||
- t16
|
||||
- t18
|
||||
|
@ -90,9 +92,9 @@ jobs:
|
|||
matrix:
|
||||
target:
|
||||
- nv14;el18
|
||||
- pl18;pl18ev
|
||||
- t12
|
||||
- t16
|
||||
- t18
|
||||
- t16;t18
|
||||
- t8;zorro;pocket;mt12;commando8
|
||||
- tlite;tpro;tprov2;lr3pro
|
||||
- t20
|
||||
|
|
1
.github/workflows/nightly.yml
vendored
|
@ -16,6 +16,7 @@ jobs:
|
|||
matrix:
|
||||
target:
|
||||
- nv14;el18
|
||||
- pl18;pl18ev
|
||||
- t12
|
||||
- t16
|
||||
- t18
|
||||
|
|
|
@ -318,6 +318,8 @@ elseif(PCB STREQUAL X10 AND PCBREV STREQUAL T18)
|
|||
set(FLAVOUR t18)
|
||||
elseif(PCB STREQUAL NV14 AND PCBREV STREQUAL EL18)
|
||||
set(FLAVOUR el18)
|
||||
elseif(PCB STREQUAL PL18)
|
||||
set(FLAVOUR pl18)
|
||||
else()
|
||||
string(TOLOWER ${PCB} FLAVOUR)
|
||||
endif()
|
||||
|
|
|
@ -293,6 +293,10 @@
|
|||
<file>images/simulator/NV14/right.png</file>
|
||||
<file>images/simulator/NV14/top.png</file>
|
||||
<file>images/simulator/NV14/bottom.png</file>
|
||||
<file>images/simulator/PL18/left.png</file>
|
||||
<file>images/simulator/PL18/right.png</file>
|
||||
<file>images/simulator/PL18/top.png</file>
|
||||
<file>images/simulator/PL18/bottom.png</file>
|
||||
<file>images/wizard/ailerons.png</file>
|
||||
<file>images/wizard/airbrakes.png</file>
|
||||
<file>images/wizard/elevons.png</file>
|
||||
|
|
|
@ -110,7 +110,9 @@ uint32_t Boards::getFourCC(Type board)
|
|||
case BOARD_FLYSKY_NV14:
|
||||
return 0x3A78746F;
|
||||
case BOARD_FLYSKY_EL18:
|
||||
return 0x3A78746F; // TODO: check this
|
||||
return 0x3A78746F;
|
||||
case BOARD_FLYSKY_PL18:
|
||||
return 0x4878746F;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -159,6 +161,7 @@ int Boards::getEEpromSize(Board::Type board)
|
|||
case BOARD_RADIOMASTER_TX16S:
|
||||
case BOARD_FLYSKY_NV14:
|
||||
case BOARD_FLYSKY_EL18:
|
||||
case BOARD_FLYSKY_PL18:
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
|
@ -206,6 +209,7 @@ int Boards::getFlashSize(Type board)
|
|||
case BOARD_RADIOMASTER_TX16S:
|
||||
case BOARD_FLYSKY_NV14:
|
||||
case BOARD_FLYSKY_EL18:
|
||||
case BOARD_FLYSKY_PL18:
|
||||
return FSIZE_HORUS;
|
||||
case BOARD_UNKNOWN:
|
||||
return FSIZE_MAX;
|
||||
|
@ -419,6 +423,20 @@ SwitchInfo Boards::getSwitchInfo(Board::Type board, int index)
|
|||
if (index < DIM(switches))
|
||||
return switches[index];
|
||||
}
|
||||
else if (IS_FLYSKY_PL18(board)) {
|
||||
const Board::SwitchInfo switches[] = {
|
||||
{SWITCH_2POS, "SA"},
|
||||
{SWITCH_3POS, "SB"},
|
||||
{SWITCH_2POS, "SC"},
|
||||
{SWITCH_3POS, "SD"},
|
||||
{SWITCH_3POS, "SE"},
|
||||
{SWITCH_2POS, "SF"},
|
||||
{SWITCH_3POS, "SG"},
|
||||
{SWITCH_3POS, "SH"}
|
||||
};
|
||||
if (index < DIM(switches))
|
||||
return switches[index];
|
||||
}
|
||||
else if (IS_FAMILY_HORUS_OR_T16(board)) {
|
||||
const Board::SwitchInfo switches[] = {
|
||||
{SWITCH_3POS, "SA"},
|
||||
|
@ -497,6 +515,8 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
|
|||
return 7;
|
||||
else if (IS_HORUS_X12S(board))
|
||||
return 3;
|
||||
else if (IS_FLYSKY_PL18(board))
|
||||
return 3;
|
||||
else
|
||||
return 3;
|
||||
|
||||
|
@ -509,7 +529,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
|
|||
case Sliders:
|
||||
if (IS_HORUS_X12S(board) || IS_TARANIS_X9E(board) || IS_JUMPER_T20(board))
|
||||
return 4;
|
||||
else if (IS_TARANIS_X9D(board) || IS_HORUS_X10(board) || IS_FAMILY_T16(board))
|
||||
else if (IS_TARANIS_X9D(board) || IS_HORUS_X10(board) || IS_FAMILY_T16(board) || IS_FLYSKY_PL18(board))
|
||||
return 2;
|
||||
else
|
||||
return 0;
|
||||
|
@ -531,7 +551,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
|
|||
getCapability(board, Board::MouseAnalogs) + getCapability(board, Board::GyroAnalogs);
|
||||
|
||||
case MultiposPots:
|
||||
if (IS_HORUS_OR_TARANIS(board) && !(IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board)))
|
||||
if (IS_HORUS_OR_TARANIS(board) && !(IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board) || IS_FLYSKY_PL18(board)))
|
||||
return getCapability(board, Board::Pots);
|
||||
else
|
||||
return 0;
|
||||
|
@ -558,6 +578,8 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
|
|||
return 6;
|
||||
else if (board == BOARD_FLYSKY_NV14 || board == BOARD_FLYSKY_EL18)
|
||||
return 8;
|
||||
else if (board == BOARD_FLYSKY_PL18)
|
||||
return 8;
|
||||
else if (board == BOARD_RADIOMASTER_TX12_MK2 || board == BOARD_RADIOMASTER_BOXER || board == BOARD_JUMPER_TPRO)
|
||||
return 6;
|
||||
else if (board == BOARD_RADIOMASTER_POCKET)
|
||||
|
@ -600,7 +622,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
|
|||
return getCapability(board, Board::Switches);
|
||||
|
||||
case SwitchPositions:
|
||||
if (IS_HORUS_OR_TARANIS(board) || IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board))
|
||||
if (IS_HORUS_OR_TARANIS(board) || IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board) || IS_FLYSKY_PL18(board))
|
||||
return getCapability(board, Board::Switches) * 3;
|
||||
else
|
||||
return 9;
|
||||
|
@ -610,7 +632,9 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
|
|||
|
||||
|
||||
case NumTrims:
|
||||
if (IS_FAMILY_HORUS_OR_T16(board) && !(IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board)))
|
||||
if (IS_FLYSKY_PL18(board))
|
||||
return 8;
|
||||
else if (IS_FAMILY_HORUS_OR_T16(board) && !IS_FLYSKY_NV14(board))
|
||||
return 6;
|
||||
else if (IS_IFLIGHT_COMMANDO8(board))
|
||||
return 0;
|
||||
|
@ -626,7 +650,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
|
|||
return IS_STM32(board) ? true : false;
|
||||
|
||||
case HasColorLcd:
|
||||
return IS_FAMILY_HORUS_OR_T16(board);
|
||||
return IS_FAMILY_HORUS_OR_T16(board) || IS_FLYSKY_NV14(board) || IS_FLYSKY_PL18(board);
|
||||
|
||||
case HasSDCard:
|
||||
return IS_STM32(board);
|
||||
|
@ -647,7 +671,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
|
|||
return false;
|
||||
|
||||
case SportMaxBaudRate:
|
||||
if (IS_FAMILY_T16(board) || IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board) || IS_TARANIS_X7_ACCESS(board) ||
|
||||
if (IS_FAMILY_T16(board) || IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board) || IS_FLYSKY_PL18(board) ||IS_TARANIS_X7_ACCESS(board) ||
|
||||
(IS_TARANIS(board) && !IS_TARANIS_XLITE(board) && !IS_TARANIS_X7(board) && !IS_TARANIS_X9LITE(board)))
|
||||
return 400000; // 400K and higher
|
||||
else
|
||||
|
@ -833,6 +857,14 @@ StringTagMappingTable Boards::getAnalogNamesLookupTable(Board::Type board, const
|
|||
{tr("TltY").toStdString(), "TILT_Y", 14},
|
||||
});
|
||||
}
|
||||
} else if (IS_FLYSKY_PL18(board)) {
|
||||
tbl.insert(tbl.end(), {
|
||||
{tr("VRA").toStdString(), "POT1"},
|
||||
{tr("VRB").toStdString(), "POT2"},
|
||||
{tr("VRC").toStdString(), "POT3"},
|
||||
{tr("LS").toStdString(), "LS"},
|
||||
{tr("RS").toStdString(), "RS"},
|
||||
});
|
||||
} else if (IS_HORUS_X10(board) || IS_FAMILY_T16(board)) {
|
||||
if (version < adcVersion) {
|
||||
tbl.insert(tbl.end(), {
|
||||
|
@ -964,6 +996,8 @@ QString Boards::getBoardName(Board::Type board)
|
|||
return "FlySky NV14";
|
||||
case BOARD_FLYSKY_EL18:
|
||||
return "FlySky EL18";
|
||||
case BOARD_FLYSKY_PL18:
|
||||
return "FlySky PL18";
|
||||
case BOARD_BETAFPV_LR3PRO:
|
||||
return "BETAFPV LR3PRO";
|
||||
case BOARD_IFLIGHT_COMMANDO8:
|
||||
|
@ -1198,6 +1232,7 @@ int Boards::getDefaultInternalModules(Board::Type board)
|
|||
case BOARD_JUMPER_TLITE_F4:
|
||||
case BOARD_JUMPER_TPRO:
|
||||
case BOARD_JUMPER_TPROV2:
|
||||
case BOARD_FLYSKY_PL18:
|
||||
return (int)MODULE_TYPE_MULTIMODULE;
|
||||
|
||||
case BOARD_BETAFPV_LR3PRO:
|
||||
|
|
|
@ -69,6 +69,7 @@ namespace Board {
|
|||
BOARD_JUMPER_TLITE,
|
||||
BOARD_JUMPER_TLITE_F4,
|
||||
BOARD_FLYSKY_NV14,
|
||||
BOARD_FLYSKY_PL18,
|
||||
BOARD_RADIOMASTER_ZORRO,
|
||||
BOARD_JUMPER_TPRO,
|
||||
BOARD_BETAFPV_LR3PRO,
|
||||
|
@ -398,6 +399,11 @@ inline bool IS_FLYSKY_EL18(Board::Type board)
|
|||
return (board == Board::BOARD_FLYSKY_EL18);
|
||||
}
|
||||
|
||||
inline bool IS_FLYSKY_PL18(Board::Type board)
|
||||
{
|
||||
return (board == Board::BOARD_FLYSKY_PL18);
|
||||
}
|
||||
|
||||
inline bool IS_TARANIS_XLITE(Board::Type board)
|
||||
{
|
||||
return board == Board::BOARD_TARANIS_XLITE || board == Board::BOARD_TARANIS_XLITES;
|
||||
|
@ -475,7 +481,9 @@ inline bool IS_FAMILY_HORUS(Board::Type board)
|
|||
|
||||
inline bool IS_FAMILY_HORUS_OR_T16(Board::Type board)
|
||||
{
|
||||
return IS_FAMILY_HORUS(board) || IS_FAMILY_T16(board) || IS_FLYSKY_NV14(board)/*generally*/ || IS_FLYSKY_EL18(board)/*generally*/;
|
||||
return IS_FAMILY_HORUS(board) || IS_FAMILY_T16(board) ||
|
||||
IS_FLYSKY_NV14(board)/*generally*/ || IS_FLYSKY_EL18(board)/*generally*/
|
||||
|| IS_FLYSKY_PL18(board);
|
||||
}
|
||||
|
||||
inline bool IS_HORUS_OR_TARANIS(Board::Type board)
|
||||
|
@ -485,7 +493,8 @@ inline bool IS_HORUS_OR_TARANIS(Board::Type board)
|
|||
|
||||
inline bool IS_STM32(Board::Type board)
|
||||
{
|
||||
return IS_TARANIS(board) || IS_FAMILY_HORUS_OR_T16(board) || IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board);
|
||||
return IS_TARANIS(board) || IS_FAMILY_HORUS_OR_T16(board) ||
|
||||
IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board) || IS_FLYSKY_PL18(board);
|
||||
}
|
||||
|
||||
inline bool IS_ARM(Board::Type board)
|
||||
|
|
|
@ -154,6 +154,8 @@ void GeneralSettings::init()
|
|||
strcpy(bluetoothName, "t16");
|
||||
else if (IS_FLYSKY_NV14(board))
|
||||
strcpy(bluetoothName, "nv14");
|
||||
else if (IS_FLYSKY_PL18(board))
|
||||
strcpy(bluetoothName, "pl18");
|
||||
else if (IS_FAMILY_HORUS_OR_T16(board))
|
||||
strcpy(bluetoothName, "horus");
|
||||
else if (IS_TARANIS_X9E(board) || IS_TARANIS_SMALL(board))
|
||||
|
@ -269,7 +271,7 @@ void GeneralSettings::init()
|
|||
|
||||
internalModule = g.profile[g.sessionId()].defaultInternalModule();
|
||||
|
||||
if (IS_FLYSKY_NV14(board))
|
||||
if (IS_FLYSKY_NV14(board) || IS_FLYSKY_PL18(board))
|
||||
stickDeadZone = 2;
|
||||
|
||||
}
|
||||
|
@ -285,7 +287,7 @@ void GeneralSettings::setDefaultControlTypes(Board::Type board)
|
|||
return;
|
||||
|
||||
// TODO: move to Boards, like with switches
|
||||
if (IS_FAMILY_HORUS_OR_T16(board) && !IS_FLYSKY_NV14(board)) {
|
||||
if (IS_FAMILY_HORUS_OR_T16(board) && !IS_FLYSKY_NV14(board) && !IS_FLYSKY_PL18(board)) {
|
||||
potConfig[0] = Board::POT_WITH_DETENT;
|
||||
potConfig[1] = Board::POT_MULTIPOS_SWITCH;
|
||||
potConfig[2] = Board::POT_WITH_DETENT;
|
||||
|
@ -294,6 +296,11 @@ void GeneralSettings::setDefaultControlTypes(Board::Type board)
|
|||
potConfig[0] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[1] = Board::POT_WITHOUT_DETENT;
|
||||
}
|
||||
else if (IS_FLYSKY_PL18(board)) {
|
||||
potConfig[0] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[1] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[2] = Board::POT_WITHOUT_DETENT;
|
||||
}
|
||||
else if (IS_TARANIS_XLITE(board)) {
|
||||
potConfig[0] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[1] = Board::POT_WITHOUT_DETENT;
|
||||
|
|
|
@ -116,7 +116,7 @@ inline int MAX_POTS_STORAGE(Board::Type board, int version)
|
|||
{
|
||||
if (version <= 218 && IS_FAMILY_HORUS_OR_T16(board))
|
||||
return 3;
|
||||
if (version <= 220 && IS_FAMILY_HORUS_OR_T16(board) && !IS_FLYSKY_NV14(board))
|
||||
if (version <= 220 && IS_FAMILY_HORUS_OR_T16(board) && !IS_FLYSKY_NV14(board) && !IS_FLYSKY_PL18(board))
|
||||
return 5;
|
||||
if (IS_FAMILY_T12(board))
|
||||
return 2;
|
||||
|
@ -147,7 +147,7 @@ inline int MAX_XPOTS(Board::Type board, int version)
|
|||
|
||||
inline int MAX_SLIDERS_STORAGE(Board::Type board, int version)
|
||||
{
|
||||
if (version >= 219 && (IS_FAMILY_HORUS_OR_T16(board) && !IS_FLYSKY_NV14(board)))
|
||||
if (version >= 219 && (IS_FAMILY_HORUS_OR_T16(board) && !IS_FLYSKY_NV14(board) && !IS_FLYSKY_PL18(board)))
|
||||
return 4;
|
||||
return Boards::getCapability(board, Board::Sliders);
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ inline int SWITCHES_CONFIG_SIZE(Board::Type board, int version)
|
|||
|
||||
inline int MAX_MOUSE_ANALOG_SOURCES(Board::Type board, int version)
|
||||
{
|
||||
if (IS_FAMILY_HORUS_OR_T16(board) && !IS_FLYSKY_NV14(board))
|
||||
if (IS_FAMILY_HORUS_OR_T16(board) && !IS_FLYSKY_NV14(board) && !IS_FLYSKY_PL18(board))
|
||||
return 2;
|
||||
else
|
||||
return 0;
|
||||
|
@ -211,10 +211,10 @@ inline int MAX_GYRO_ANALOGS(Board::Type board, int version)
|
|||
#define MAX_CURVES(board, version) ((version >= 219 || HAS_LARGE_LCD(board)) ? 32 : 16)
|
||||
#define MAX_GVARS(board, version) 9
|
||||
#define MAX_SCRIPTS(board) (IS_FAMILY_HORUS_OR_T16(board) ? 9 : 7)
|
||||
#define MAX_TELEMETRY_SENSORS(board, version) (version <= 218 ? 32 : ((IS_FAMILY_HORUS_OR_T16(board) || IS_TARANIS_X9(board) || IS_FLYSKY_NV14(board)) ? 60 : 40))
|
||||
#define MAX_TELEMETRY_SENSORS(board, version) (version <= 218 ? 32 : ((IS_FAMILY_HORUS_OR_T16(board) || IS_TARANIS_X9(board) || IS_FLYSKY_NV14(board) || IS_FLYSKY_PL18(board)) ? 60 : 40))
|
||||
#define NUM_PPM_INPUTS(board, version) 16
|
||||
#define ROTENC_COUNT(board, version) ((IS_STM32(board) && version >= 218) ? 0 : 1)
|
||||
#define MAX_AUX_TRIMS(board) ((IS_FAMILY_HORUS_OR_T16(board) && !IS_FLYSKY_NV14(board)) ? 2 : 0)
|
||||
#define MAX_AUX_TRIMS(board) ((IS_FAMILY_HORUS_OR_T16(board) && !IS_FLYSKY_NV14(board) && !IS_FLYSKY_PL18(board)) ? 2 : 0)
|
||||
#define MAX_SOURCE_TYPE_SPECIAL(board, version) SOURCE_TYPE_SPECIAL_COUNT
|
||||
|
||||
inline int switchIndex(int i, Board::Type board, unsigned int version)
|
||||
|
@ -2910,7 +2910,7 @@ void OpenTxModelData::beforeExport()
|
|||
|
||||
// TODO remove when enum not radio specific requires eeprom change and conversion
|
||||
// Note: this must mirror reverse afterImport
|
||||
if (!IS_FLYSKY_NV14(board))
|
||||
if (!IS_FLYSKY_NV14(board) && !IS_FLYSKY_PL18(board))
|
||||
modelData.trainerMode -= 1;
|
||||
|
||||
if (modelData.trainerMode > TRAINER_MODE_SLAVE_JACK) {
|
||||
|
@ -2957,7 +2957,7 @@ void OpenTxModelData::afterImport()
|
|||
|
||||
// TODO remove when enum not radio specific requires eeprom change and conversion
|
||||
// Note: this must mirror reverse beforeExport
|
||||
if (!IS_FLYSKY_NV14(board))
|
||||
if (!IS_FLYSKY_NV14(board) && !IS_FLYSKY_PL18(board))
|
||||
modelData.trainerMode += 1;
|
||||
|
||||
if (modelData.trainerMode > TRAINER_MODE_SLAVE_JACK) {
|
||||
|
@ -3003,7 +3003,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
|
|||
|
||||
internalField.Append(new UnsignedField<16>(this, chkSum));
|
||||
|
||||
if (!IS_FAMILY_HORUS_OR_T16(board) || (IS_FLYSKY_NV14(board))) {
|
||||
if (!IS_FAMILY_HORUS_OR_T16(board) || IS_FLYSKY_NV14(board) || IS_FLYSKY_PL18(board)) {
|
||||
internalField.Append(new UnsignedField<8>(this, generalData.currModelIndex));
|
||||
internalField.Append(new UnsignedField<8>(this, generalData.contrast));
|
||||
}
|
||||
|
@ -3067,11 +3067,11 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
|
|||
internalField.Append(new SignedField<8>(this, generalData.PPM_Multiplier));
|
||||
internalField.Append(new SignedField<8>(this, generalData.hapticLength));
|
||||
|
||||
if (version < 218 || (!IS_TARANIS(board) && !IS_FAMILY_HORUS_OR_T16(board)) || IS_FLYSKY_NV14(board)) {
|
||||
if (version < 218 || (!IS_TARANIS(board) && !IS_FAMILY_HORUS_OR_T16(board)) || IS_FLYSKY_NV14(board) || IS_FLYSKY_PL18(board)) {
|
||||
internalField.Append(new UnsignedField<8>(this, generalData.reNavigation));
|
||||
}
|
||||
|
||||
if ((!IS_TARANIS(board) && !IS_FAMILY_HORUS_OR_T16(board)) || IS_FLYSKY_NV14(board)) {
|
||||
if ((!IS_TARANIS(board) && !IS_FAMILY_HORUS_OR_T16(board)) || IS_FLYSKY_NV14(board) || IS_FLYSKY_PL18(board)) {
|
||||
internalField.Append(new UnsignedField<8>(this, generalData.stickReverse));
|
||||
}
|
||||
|
||||
|
|
|
@ -124,6 +124,8 @@ const char * OpenTxEepromInterface::getName()
|
|||
return "EdgeTX for FlySky NV14";
|
||||
case BOARD_FLYSKY_EL18:
|
||||
return "EdgeTX for FlySky EL18";
|
||||
case BOARD_FLYSKY_PL18:
|
||||
return "EdgeTX for FlySky PL18";
|
||||
case BOARD_BETAFPV_LR3PRO:
|
||||
return "EdgeTx for BETAFPV LR3PRO";
|
||||
case BOARD_IFLIGHT_COMMANDO8:
|
||||
|
@ -664,6 +666,8 @@ int OpenTxFirmware::getCapability(::Capability capability)
|
|||
case LcdWidth:
|
||||
if (IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board))
|
||||
return 320;
|
||||
else if (IS_FLYSKY_PL18(board))
|
||||
return 480;
|
||||
else if (IS_FAMILY_HORUS_OR_T16(board))
|
||||
return 480;
|
||||
else if (IS_TARANIS_SMALL(board))
|
||||
|
@ -675,6 +679,8 @@ int OpenTxFirmware::getCapability(::Capability capability)
|
|||
case LcdHeight:
|
||||
if (IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board))
|
||||
return 480;
|
||||
else if (IS_FLYSKY_PL18(board))
|
||||
return 320;
|
||||
else if (IS_FAMILY_HORUS_OR_T16(board))
|
||||
return 272;
|
||||
else
|
||||
|
@ -777,7 +783,7 @@ int OpenTxFirmware::getCapability(::Capability capability)
|
|||
IS_JUMPER_TPRO(board) || IS_RADIOMASTER_TX12_MK2(board) || IS_RADIOMASTER_BOXER(board) || IS_RADIOMASTER_POCKET(board);
|
||||
case HasBluetooth:
|
||||
return (IS_FAMILY_HORUS_OR_T16(board) || IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board)|| IS_TARANIS_X9E(board) ||
|
||||
IS_TARANIS_X9DP_2019(board) || IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board)) ? true : false;
|
||||
IS_TARANIS_X9DP_2019(board) || IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board) || IS_FLYSKY_PL18(board)) ? true : false;
|
||||
case HasADCJitterFilter:
|
||||
return IS_HORUS_OR_TARANIS(board);
|
||||
case HasTelemetryBaudrate:
|
||||
|
@ -1244,6 +1250,13 @@ void registerOpenTxFirmwares()
|
|||
addOpenTxRfOptions(firmware, FLEX + AFHDS2A + AFHDS3);
|
||||
registerOpenTxFirmware(firmware);
|
||||
|
||||
/* FlySky PL18 board */
|
||||
firmware = new OpenTxFirmware(FIRMWAREID("pl18"), Firmware::tr("FlySky PL18"), BOARD_FLYSKY_PL18);
|
||||
addOpenTxFrskyOptions(firmware);
|
||||
firmware->addOption("bluetooth", Firmware::tr("Support for bluetooth module"));
|
||||
addOpenTxRfOptions(firmware, FLEX + AFHDS3);
|
||||
registerOpenTxFirmware(firmware);
|
||||
|
||||
/* FrSky Horus X10 board */
|
||||
firmware = new OpenTxFirmware(FIRMWAREID("x10"), Firmware::tr("FrSky Horus X10 / X10S"), BOARD_X10);
|
||||
addOpenTxFrskyOptions(firmware);
|
||||
|
|
|
@ -175,7 +175,7 @@ ui(new Ui::GeneralSetup)
|
|||
ui->usbModeCB->hide();
|
||||
}
|
||||
|
||||
if (IS_FLYSKY_EL18(board) || IS_FLYSKY_NV14(board)) {
|
||||
if (IS_FLYSKY_EL18(board) || IS_FLYSKY_NV14(board) || IS_FLYSKY_PL18(board)) {
|
||||
ui->hatsModeCB->setModel(new FilteredItemModel(GeneralSettings::hatsModeItemModel()));
|
||||
ui->hatsModeCB->setField(generalSettings.hatsMode, this);
|
||||
}
|
||||
|
|
BIN
companion/src/images/simulator/PL18/bottom.png
Normal file
After Width: | Height: | Size: 178 B |
BIN
companion/src/images/simulator/PL18/left.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
companion/src/images/simulator/PL18/right.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
companion/src/images/simulator/PL18/top.png
Normal file
After Width: | Height: | Size: 178 B |
|
@ -1696,7 +1696,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
|
|||
|
||||
ui->trimsDisplay->setField(model.trimsDisplay, this);
|
||||
|
||||
if (IS_FLYSKY_EL18(board) || IS_FLYSKY_NV14(board)) {
|
||||
if (IS_FLYSKY_EL18(board) || IS_FLYSKY_NV14(board) || IS_FLYSKY_PL18(board)) {
|
||||
ui->cboHatsMode->setModel(panelFilteredModels->getItemModel(FIM_HATSMODE));
|
||||
ui->cboHatsMode->setField(model.hatsMode, this);
|
||||
}
|
||||
|
|
|
@ -841,7 +841,7 @@ QString ModelPrinter::printSettingsTrim()
|
|||
str << printLabelValue(tr("Display"), printTrimsDisplayMode());
|
||||
str << printLabelValue(tr("Extended"), printBoolean(model.extendedTrims, BOOLEAN_YESNO));
|
||||
Board::Type board = firmware->getBoard();
|
||||
if (IS_FLYSKY_EL18(board) || IS_FLYSKY_NV14(board)) {
|
||||
if (IS_FLYSKY_EL18(board) || IS_FLYSKY_NV14(board) || IS_FLYSKY_PL18(board)) {
|
||||
str << printLabelValue(tr("Hats Mode"), printHatsMode());
|
||||
}
|
||||
return str.join(" ");
|
||||
|
|
|
@ -40,6 +40,7 @@ set(${PROJECT_NAME}_SRCS
|
|||
simulateduiwidgetJumperTPRO.cpp
|
||||
simulateduiwidgetLR3PRO.cpp
|
||||
simulateduiwidgetNV14.cpp
|
||||
simulateduiwidgetPL18.cpp
|
||||
simulateduiwidgetT8.cpp
|
||||
simulateduiwidgetTX12.cpp
|
||||
simulateduiwidgetTX16S.cpp
|
||||
|
|
|
@ -125,6 +125,7 @@ namespace Ui {
|
|||
class SimulatedUIWidgetT8;
|
||||
class SimulatedUIWidgetNV14;
|
||||
class SimulatedUIWidgetEL18;
|
||||
class SimulatedUIWidgetPL18;
|
||||
}
|
||||
|
||||
class SimulatedUIWidget9X: public SimulatedUIWidget
|
||||
|
@ -407,4 +408,16 @@ class SimulatedUIWidgetEL18: public SimulatedUIWidget
|
|||
Ui::SimulatedUIWidgetEL18 * ui;
|
||||
};
|
||||
|
||||
class SimulatedUIWidgetPL18: public SimulatedUIWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SimulatedUIWidgetPL18(SimulatorInterface * simulator, QWidget * parent = nullptr);
|
||||
virtual ~SimulatedUIWidgetPL18();
|
||||
|
||||
private:
|
||||
Ui::SimulatedUIWidgetPL18 * ui;
|
||||
};
|
||||
|
||||
#endif // SIMULATEDUIWIDGET_H
|
||||
|
|
76
companion/src/simulation/simulateduiwidgetPL18.cpp
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
// NOTE: RadioUiAction(NUMBER,...): NUMBER relates to enum EnumKeys in the specific board.h
|
||||
|
||||
#include "simulateduiwidget.h"
|
||||
#include "ui_simulateduiwidgetPL18.h"
|
||||
|
||||
SimulatedUIWidgetPL18::SimulatedUIWidgetPL18(SimulatorInterface *simulator, QWidget * parent):
|
||||
SimulatedUIWidget(simulator, parent),
|
||||
ui(new Ui::SimulatedUIWidgetPL18)
|
||||
{
|
||||
RadioUiAction * act;
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
// add actions in order of appearance on the help menu
|
||||
|
||||
// Note: the PL18 has no physical buttons though at some point the trim joystick is repurposed
|
||||
// allow for colorlcd key events and see what works
|
||||
// the mouse click areas do not map to visual buttons on the background images
|
||||
|
||||
act = new RadioUiAction(3, QList<int>() << Qt::Key_Up, SIMU_STR_HLP_KEY_UP, SIMU_STR_HLP_ACT_MDL);
|
||||
addRadioWidget(ui->rightbuttons->addArea(QRect(10, 1, 80, 35), "PL18/left.png", act));
|
||||
|
||||
m_mouseMidClickAction = new RadioUiAction(2, QList<int>() << Qt::Key_Enter << Qt::Key_Return, SIMU_STR_HLP_KEYS_ACTIVATE, SIMU_STR_HLP_ACT_ROT_DN);
|
||||
addRadioWidget(ui->rightbuttons->addArea(QRect(10, 40, 80, 35), "PL18/left.png", m_mouseMidClickAction));
|
||||
|
||||
act = new RadioUiAction(6, QList<int>() << Qt::Key_Left, SIMU_STR_HLP_KEY_LFT, SIMU_STR_HLP_ACT_SYS);
|
||||
addRadioWidget(ui->leftbuttons->addArea(QRect(10, 80, 80, 35), "PL18/left.png", act));
|
||||
|
||||
act = new RadioUiAction(5, QList<int>() << Qt::Key_Right, SIMU_STR_HLP_KEY_RGT, SIMU_STR_HLP_ACT_TELE);
|
||||
addRadioWidget(ui->leftbuttons->addArea(QRect(10, 120, 80, 35), "PL18/left.png", act));
|
||||
|
||||
act = new RadioUiAction(1, QList<int>() << Qt::Key_PageDown, SIMU_STR_HLP_KEY_PGDN, SIMU_STR_HLP_ACT_PGDN);
|
||||
addRadioWidget(ui->leftbuttons->addArea(QRect(10, 160, 80, 35), "PL18/left.png", act));
|
||||
|
||||
act = new RadioUiAction(0, QList<int>() << Qt::Key_PageUp, SIMU_STR_HLP_KEY_PGUP, SIMU_STR_HLP_ACT_PGUP);
|
||||
addRadioWidget(ui->leftbuttons->addArea(QRect(10, 200, 80, 35), "PL18/left.png", act));
|
||||
|
||||
act = new RadioUiAction(4, QList<int>() << Qt::Key_Down << Qt::Key_Delete << Qt::Key_Escape << Qt::Key_Backspace,
|
||||
SIMU_STR_HLP_KEY_DN % "<br>" % SIMU_STR_HLP_KEYS_EXIT, SIMU_STR_HLP_ACT_RTN);
|
||||
addRadioWidget(ui->leftbuttons->addArea(QRect(10, 240, 80, 35), "PL18/left.png", act));
|
||||
|
||||
m_scrollUpAction = new RadioUiAction(-1, QList<int>() << Qt::Key_Minus, SIMU_STR_HLP_KEY_MIN % "|" % SIMU_STR_HLP_MOUSE_UP, SIMU_STR_HLP_ACT_ROT_LFT);
|
||||
m_scrollDnAction = new RadioUiAction(-1, QList<int>() << Qt::Key_Plus << Qt::Key_Equal, SIMU_STR_HLP_KEY_PLS % "|" % SIMU_STR_HLP_MOUSE_DN, SIMU_STR_HLP_ACT_ROT_RGT);
|
||||
connectScrollActions();
|
||||
|
||||
addRadioWidget(ui->leftbuttons->addArea(QRect(10, 280, 30, 30), "PL18/left.png", m_screenshotAction));
|
||||
|
||||
m_backlightColors << QColor(47, 123, 227);
|
||||
|
||||
setLcd(ui->lcd);
|
||||
}
|
||||
|
||||
SimulatedUIWidgetPL18::~SimulatedUIWidgetPL18()
|
||||
{
|
||||
delete ui;
|
||||
}
|
206
companion/src/simulation/simulateduiwidgetPL18.ui
Normal file
|
@ -0,0 +1,206 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SimulatedUIWidgetPL18</class>
|
||||
<widget class="QWidget" name="SimulatedUIWidgetPL18">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>520</width>
|
||||
<height>500</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>520</width>
|
||||
<height>500</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>520</width>
|
||||
<height>500</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="2" rowspan="3">
|
||||
<widget class="ButtonsWidget" name="rightbuttons" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>500</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>500</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background:url(:/images/simulator/PL18/right.png)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="LcdWidget" name="lcd" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>480</width>
|
||||
<height>320</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>480</width>
|
||||
<height>320</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>5</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" rowspan="3">
|
||||
<widget class="ButtonsWidget" name="leftbuttons" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>500</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>500</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="mouseTracking">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background:url(:/images/simulator/PL18/left.png);</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QWidget" name="top" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>320</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>320</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>5</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background:url(:/images/simulator/PL18/top.png)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QWidget" name="bottom" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>320</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>320</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>5</pointsize>
|
||||
<kerning>false</kerning>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background:url(:/images/simulator/PL18/bottom.png)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LcdWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>lcdwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ButtonsWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>buttonswidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -133,6 +133,9 @@ SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface * simulato
|
|||
case Board::BOARD_FLYSKY_EL18:
|
||||
radioUiWidget = new SimulatedUIWidgetEL18(simulator, this);
|
||||
break;
|
||||
case Board::BOARD_FLYSKY_PL18:
|
||||
radioUiWidget = new SimulatedUIWidgetPL18(simulator, this);
|
||||
break;
|
||||
default:
|
||||
radioUiWidget = new SimulatedUIWidget9X(simulator, this);
|
||||
break;
|
||||
|
|
2
fw.json
|
@ -3,6 +3,8 @@
|
|||
["BETAFPV LiteRadio 3 Pro", "lr3pro-"],
|
||||
["Flysky EL18", "el18-"],
|
||||
["Flysky NV14", "nv14-"],
|
||||
["Flysky PL18", "pl18-"],
|
||||
["Flysky PL18EV", "pl18ev-"],
|
||||
["FrSky Horus X10", "x10-"],
|
||||
["FrSky Horus X10 Access", "x10-access-"],
|
||||
["FrSky Horus X12s", "x12s-"],
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
include(CMakeForceCompiler)
|
||||
include(Bitmaps)
|
||||
|
||||
set(PCB_TYPES X9LITE X9LITES X7 XLITE XLITES X9D X9D+ X9E X10 X12S NV14)
|
||||
set(PCB_TYPES X9LITE X9LITES X7 XLITE XLITES X9D X9D+ X9E X10 X12S NV14 PL18)
|
||||
set(RADIO_LANGUAGES CN CZ DA DE EN ES FI FR HE IT JP PT RU SK SE PL HU NL TW)
|
||||
set(TTS_LANGUAGES CN CZ DA DE EN ES FR HE IT JP PT RU SK SE PL HU NL)
|
||||
|
||||
|
@ -85,6 +85,8 @@ if(PCB STREQUAL X12S OR PCB STREQUAL X10)
|
|||
include(targets/horus/CMakeLists.txt)
|
||||
elseif(PCB STREQUAL NV14)
|
||||
include(targets/nv14/CMakeLists.txt)
|
||||
elseif(PCB STREQUAL PL18)
|
||||
include(targets/pl18/CMakeLists.txt)
|
||||
elseif(PCB STREQUAL X9E OR PCB STREQUAL X9D+ OR PCB STREQUAL X9D OR PCB STREQUAL X7 OR PCB STREQUAL X9LITE OR PCB STREQUAL X9LITES OR PCB STREQUAL XLITE OR PCB STREQUAL XLITES)
|
||||
include(targets/taranis/CMakeLists.txt)
|
||||
else()
|
||||
|
|
|
@ -4,6 +4,8 @@ set(MASK_ARGS ${BITMAP_SIZE_ARGS})
|
|||
|
||||
if(PCB STREQUAL NV14)
|
||||
set(BITMAP_TARGET_PREFIX nv14)
|
||||
elseif(PCB STREQUAL PL18)
|
||||
set(BITMAP_TARGET_PREFIX pl18)
|
||||
elseif(PCB STREQUAL X12S)
|
||||
set(BITMAP_TARGET_PREFIX x12s)
|
||||
else()
|
||||
|
|
|
@ -47,6 +47,9 @@ constexpr uint8_t n_ADC_spi = DIM(_ADC_spi);
|
|||
constexpr uint8_t n_GPIO = DIM(_ADC_GPIOs);
|
||||
constexpr uint8_t n_inputs = DIM(_ADC_inputs);
|
||||
|
||||
static_assert(n_inputs <= MAX_ADC_INPUTS, "Too many ADC inputs");
|
||||
static_assert(n_inputs <= MAX_ANALOG_INPUTS, "Too many analog inputs");
|
||||
|
||||
static bool adc_init()
|
||||
{
|
||||
bool success = stm32_hal_adc_init(_ADC_adc, n_ADC, _ADC_inputs, _ADC_GPIOs, n_GPIO);
|
||||
|
|
|
@ -26,23 +26,27 @@
|
|||
|
||||
#include "stm32_keys.inc"
|
||||
|
||||
void keysInit()
|
||||
#define __weak __attribute__((weak))
|
||||
|
||||
__weak void keysInit()
|
||||
{
|
||||
_init_keys();
|
||||
_init_trims();
|
||||
}
|
||||
|
||||
uint32_t readKeys()
|
||||
__weak uint32_t readKeys()
|
||||
{
|
||||
return _read_keys();
|
||||
}
|
||||
|
||||
uint32_t readTrims()
|
||||
__weak uint32_t readTrims()
|
||||
{
|
||||
uint32_t trims = _read_trims();
|
||||
|
||||
#if defined(PCBXLITE)
|
||||
if (_read_keys() & (1 << KEY_SHIFT))
|
||||
return ((trims & 0x03) << 6) | ((trims & 0x0c) << 2);
|
||||
#endif
|
||||
|
||||
return trims;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "board.h"
|
||||
#include "dataconstants.h"
|
||||
|
||||
#if defined (HARDWARE_INTERNAL_MODULE)
|
||||
#if defined(INTMODULE_USART)
|
||||
|
||||
#define INTMODULE_USART_IRQ_PRIORITY 5
|
||||
|
@ -110,7 +111,8 @@ extern "C" void INTMODULE_TIMER_IRQHandler()
|
|||
|
||||
DEFINE_STM32_SOFTSERIAL_PORT(InternalModule, intmoduleTimer);
|
||||
|
||||
#endif
|
||||
#endif // INTMODULE_USART
|
||||
#endif // HARDWARE_INTERNAL_MODULE
|
||||
|
||||
#include "module_timer_driver.h"
|
||||
|
||||
|
|
|
@ -1040,6 +1040,7 @@ int cliSet(const char **argv)
|
|||
}
|
||||
|
||||
#if defined(ENABLE_SERIAL_PASSTHROUGH)
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
static etx_module_state_t *spInternalModuleState = nullptr;
|
||||
|
||||
static void spInternalModuleTx(uint8_t* buf, uint32_t len)
|
||||
|
@ -1060,6 +1061,7 @@ static const etx_serial_init spIntmoduleSerialInitParams = {
|
|||
.polarity = ETX_Pol_Normal,
|
||||
};
|
||||
|
||||
#endif // HARDWARE_INTERNAL_MODULE
|
||||
// TODO: use proper method instead
|
||||
extern bool cdcConnected;
|
||||
extern uint32_t usbSerialBaudRate(void*);
|
||||
|
@ -1576,7 +1578,7 @@ int cliCrypt(const char ** argv)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(HARDWARE_TOUCH) && !defined(PCBNV14)
|
||||
#if defined(HARDWARE_TOUCH) && !defined(PCBNV14) && !defined(PCBPL18)
|
||||
|
||||
// from tp_gt911.cpp
|
||||
extern uint8_t tp_gt911_cfgVer;
|
||||
|
@ -1648,7 +1650,7 @@ const CliCommand cliCommands[] = {
|
|||
#if defined(ACCESS_DENIED) && defined(DEBUG_CRYPT)
|
||||
{ "crypt", cliCrypt, "<string to be encrypted>" },
|
||||
#endif
|
||||
#if defined(HARDWARE_TOUCH) && !defined(PCBNV14)
|
||||
#if defined(HARDWARE_TOUCH) && !defined(PCBNV14) && !defined(PCBPL18)
|
||||
{ "reset_gt911", cliResetGT911, ""},
|
||||
#endif
|
||||
{ nullptr, nullptr, nullptr } /* sentinel */
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#define LABELS_LENGTH 100 // Maximum length of the label string
|
||||
#define LABEL_LENGTH 16
|
||||
|
||||
#if defined(PCBHORUS) || defined(PCBNV14)
|
||||
#if defined(PCBHORUS) || defined(PCBNV14) || defined(PCBPL18)
|
||||
#define MAX_MODELS 60
|
||||
#define MAX_OUTPUT_CHANNELS 32 // number of real output channels CH1-CH32
|
||||
#define MAX_FLIGHT_MODES 9
|
||||
|
@ -98,7 +98,7 @@ enum CurveType {
|
|||
#define MIN_POINTS_PER_CURVE 3
|
||||
#define MAX_POINTS_PER_CURVE 17
|
||||
|
||||
#if defined(PCBHORUS) || defined(PCBNV14)
|
||||
#if defined(PCBHORUS) || defined(PCBNV14) || defined(PCBPL18)
|
||||
#define LEN_MODEL_NAME 15
|
||||
#define LEN_TIMER_NAME 8
|
||||
#define LEN_FLIGHT_MODE_NAME 10
|
||||
|
@ -408,10 +408,10 @@ enum PotsWarnMode {
|
|||
#define MAX_FLEX_SWITCHES 0
|
||||
#endif
|
||||
|
||||
#if defined(RADIO_T20)
|
||||
#define MAX_TRIMS 8
|
||||
#if NUM_TRIMS > 6
|
||||
#define MAX_TRIMS 8
|
||||
#else
|
||||
#define MAX_TRIMS 6
|
||||
#define MAX_TRIMS 6
|
||||
#endif
|
||||
|
||||
#define MAX_XPOTS_POSITIONS (MAX_POTS * XPOTS_MULTIPOS_COUNT)
|
||||
|
@ -428,6 +428,13 @@ enum SwitchSources {
|
|||
SWSRC_FIRST_TRIM SKIP,
|
||||
SWSRC_LAST_TRIM SKIP = SWSRC_FIRST_TRIM + 2 * MAX_TRIMS - 1,
|
||||
|
||||
#if NUM_TRIMS > 6
|
||||
SWSRC_TrimT7Down,
|
||||
SWSRC_TrimT7Up,
|
||||
SWSRC_TrimT8Down,
|
||||
SWSRC_TrimT8Up,
|
||||
#endif
|
||||
|
||||
SWSRC_FIRST_LOGICAL_SWITCH SKIP,
|
||||
SWSRC_LAST_LOGICAL_SWITCH SKIP = SWSRC_FIRST_LOGICAL_SWITCH + MAX_LOGICAL_SWITCHES - 1,
|
||||
|
||||
|
@ -605,7 +612,7 @@ enum Functions {
|
|||
#if defined(DEBUG)
|
||||
FUNC_MAX SKIP
|
||||
#else
|
||||
FUNC_MAX SKIP = FUNC_TEST - 1
|
||||
FUNC_MAX SKIP = FUNC_TEST
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ static inline void check_struct()
|
|||
CHKSIZE(CurveHeader, 4);
|
||||
CHKSIZE(CustomScreenData, 852);
|
||||
CHKTYPE(TopBarPersistentData, 444);
|
||||
#elif defined(PCBNV14)
|
||||
#elif defined(PCBNV14) || defined(PCBPL18)
|
||||
// TODO
|
||||
#else
|
||||
// Common for all variants
|
||||
|
|
|
@ -602,7 +602,7 @@ PACK(struct CustomScreenData {
|
|||
#define TOPBAR_DATA
|
||||
#endif
|
||||
|
||||
#if defined(PCBHORUS) || defined(PCBTARANIS) || defined(PCBNV14)
|
||||
#if defined(PCBHORUS) || defined(PCBTARANIS) || defined(PCBNV14) || defined(PCBPL18)
|
||||
#define SCRIPT_DATA \
|
||||
NOBACKUP(ScriptData scriptsData[MAX_SCRIPTS]);
|
||||
#else
|
||||
|
|
|
@ -46,8 +46,8 @@ EXTERN_C(extern volatile uint32_t g_tmr10ms);
|
|||
#define debugPrintf(...)
|
||||
#endif
|
||||
|
||||
#define TRACE_TIME_FORMAT "%0.2fs: "
|
||||
#define TRACE_TIME_VALUE ((float)g_tmr10ms / 100.0)
|
||||
#define TRACE_TIME_FORMAT "%dms: "
|
||||
#define TRACE_TIME_VALUE (g_tmr10ms * 10)
|
||||
|
||||
#define TRACE_NOCRLF(...) debugPrintf(__VA_ARGS__)
|
||||
#define TRACE(f_, ...) debugPrintf((TRACE_TIME_FORMAT f_ CRLF), TRACE_TIME_VALUE, ##__VA_ARGS__)
|
||||
|
|
|
@ -93,7 +93,7 @@ void RadioCalibrationPage::buildBody(FormWindow * window)
|
|||
deco->setSlidersVisible(true);
|
||||
deco->setFlightModeVisible(false);
|
||||
|
||||
#if defined(PCBNV14)
|
||||
#if defined(PCBNV14) || defined(PCBPL18)
|
||||
new TextButton(window, {LCD_W - 120, LCD_H - 140, 90, 40}, "Next",
|
||||
[=]() -> uint8_t {
|
||||
nextStep();
|
||||
|
|
|
@ -177,7 +177,7 @@ class AnaCalibratedViewWindow: public AnaViewWindow {
|
|||
}, COLOR_THEME_PRIMARY1);
|
||||
lv_obj_set_grid_cell(lbl->getLvObj(), LV_GRID_ALIGN_STRETCH, 0, 5, LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
|
||||
#if !defined(SIMU) && !defined(PCBNV14)
|
||||
#if !defined(SIMU) && !defined(PCBNV14) && !defined(PCBPL18)
|
||||
line = newLine(grid);
|
||||
auto lbl2 = new StaticText(line, rect_t{}, std::string("Touch GT911 FW ver: ") + std::to_string(touchGT911fwver), COLOR_THEME_PRIMARY1);
|
||||
lv_obj_set_grid_cell(lbl2->getLvObj(), LV_GRID_ALIGN_STRETCH, 0, 5, LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
|
|
|
@ -25,7 +25,11 @@
|
|||
|
||||
#include "hal/rotary_encoder.h"
|
||||
|
||||
#if defined(PCBPL18)
|
||||
static const uint8_t _trimMap[MAX_TRIMS * 2] = {8, 9, 10, 11, 12, 13, 14, 15, 2, 3, 4, 5, 0, 1, 6, 7};
|
||||
#else
|
||||
static const uint8_t _trimMap[MAX_TRIMS * 2] = {6, 7, 4, 5, 2, 3, 0, 1, 8, 9, 10, 11};
|
||||
#endif
|
||||
|
||||
static EnumKeys get_ith_key(uint8_t i)
|
||||
{
|
||||
|
@ -122,8 +126,13 @@ class RadioKeyDiagsWindow : public Window
|
|||
for (uint8_t i = 0; i < keysGetMaxTrims() * 2; i++) {
|
||||
coord_t y = 1 + FH + FH * (i / 2);
|
||||
if (i & 1) {
|
||||
#if defined(PCBPL18)
|
||||
dc->drawText(TRIM_COLUMN, y, "TR", COLOR_THEME_PRIMARY1);
|
||||
dc->drawNumber(TRIM_COLUMN + 20, y, i / 2 + 1, COLOR_THEME_PRIMARY1);
|
||||
#else
|
||||
dc->drawText(TRIM_COLUMN, y, "T", COLOR_THEME_PRIMARY1);
|
||||
dc->drawNumber(TRIM_COLUMN + 10, y, i / 2 + 1, COLOR_THEME_PRIMARY1);
|
||||
#endif
|
||||
}
|
||||
displayTrimState(dc, i & 1 ? TRIM_PLUS_COLUMN : TRIM_MINUS_COLUMN, y, _trimMap[i]);
|
||||
}
|
||||
|
|
|
@ -110,12 +110,14 @@ static void ghostmoduleconfig_cb(lv_event_t* e)
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(HARDWARE_KEYS) && !defined(PCBPL18)
|
||||
void RadioGhostModuleConfig::onCancel()
|
||||
{
|
||||
reusableBuffer.ghostMenu.buttonAction = GHST_BTN_JOYLEFT;
|
||||
reusableBuffer.ghostMenu.menuAction = GHST_MENU_CTRL_NONE;
|
||||
moduleState[EXTERNAL_MODULE].counter = GHST_MENU_CONTROL;
|
||||
}
|
||||
#endif
|
||||
|
||||
RadioGhostModuleConfig::RadioGhostModuleConfig(uint8_t moduleIdx) :
|
||||
Page(ICON_RADIO_TOOLS),
|
||||
|
@ -144,7 +146,7 @@ void RadioGhostModuleConfig::buildBody(FormWindow * window)
|
|||
new GhostModuleConfigWindow(window, {0, 0, LCD_W, LCD_H - MENU_HEADER_HEIGHT - 5});
|
||||
}
|
||||
|
||||
#if defined(HARDWARE_KEYS)
|
||||
#if defined(HARDWARE_KEYS) && !defined(PCBPL18)
|
||||
void RadioGhostModuleConfig::onEvent(event_t event)
|
||||
{
|
||||
switch (event) {
|
||||
|
|
|
@ -28,7 +28,7 @@ class RadioGhostModuleConfig: public Page
|
|||
public:
|
||||
explicit RadioGhostModuleConfig(uint8_t moduleIdx);
|
||||
|
||||
#if defined(HARDWARE_KEYS)
|
||||
#if defined(HARDWARE_KEYS) && !defined(PCBPL18)
|
||||
void onEvent(event_t event) override;
|
||||
void checkEvents() override;
|
||||
void onCancel() override;
|
||||
|
|
|
@ -77,13 +77,14 @@ class VersionDialog : public Dialog
|
|||
memclear(&reusableBuffer.hardwareAndSettings.modules,
|
||||
sizeof(reusableBuffer.hardwareAndSettings.modules));
|
||||
reusableBuffer.hardwareAndSettings.updateTime = get_tmr10ms();
|
||||
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
// Query modules
|
||||
if (isModulePXX2(INTERNAL_MODULE) && modulePortPowered(INTERNAL_MODULE)) {
|
||||
moduleState[INTERNAL_MODULE].readModuleInformation(
|
||||
&reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE],
|
||||
PXX2_HW_INFO_TX_ID, PXX2_MAX_RECEIVERS_PER_MODULE - 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (isModulePXX2(EXTERNAL_MODULE) && modulePortPowered(EXTERNAL_MODULE)) {
|
||||
moduleState[EXTERNAL_MODULE].readModuleInformation(
|
||||
|
@ -165,11 +166,13 @@ class VersionDialog : public Dialog
|
|||
|
||||
void update()
|
||||
{
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
updateModule(INTERNAL_MODULE,
|
||||
int_name,
|
||||
int_module_status_w, int_status,
|
||||
int_rx_name_w, int_rx_name,
|
||||
int_rx_status_w, int_rx_status);
|
||||
#endif
|
||||
updateModule(EXTERNAL_MODULE,
|
||||
ext_name,
|
||||
ext_module_status_w, ext_status,
|
||||
|
@ -309,11 +312,13 @@ class VersionDialog : public Dialog
|
|||
{
|
||||
if (get_tmr10ms() >= reusableBuffer.hardwareAndSettings.updateTime) {
|
||||
// Query modules
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
if (isModulePXX2(INTERNAL_MODULE) && modulePortPowered(INTERNAL_MODULE)) {
|
||||
moduleState[INTERNAL_MODULE].readModuleInformation(
|
||||
&reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE],
|
||||
PXX2_HW_INFO_TX_ID, PXX2_MAX_RECEIVERS_PER_MODULE - 1);
|
||||
}
|
||||
#endif
|
||||
if (isModulePXX2(EXTERNAL_MODULE) && modulePortPowered(EXTERNAL_MODULE)) {
|
||||
moduleState[EXTERNAL_MODULE].readModuleInformation(
|
||||
&reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE],
|
||||
|
@ -332,7 +337,7 @@ RadioVersionPage::RadioVersionPage():
|
|||
{
|
||||
}
|
||||
|
||||
#if defined(PCBNV14)
|
||||
#if defined(PCBNV14) || defined(PCBPL18)
|
||||
extern const char* boardLcdType;
|
||||
#endif
|
||||
|
||||
|
@ -355,7 +360,7 @@ void RadioVersionPage::build(FormWindow * window)
|
|||
version += options[i];
|
||||
}
|
||||
|
||||
#if defined(PCBNV14) && !defined(SIMU)
|
||||
#if (defined(PCBNV14) || defined(PCBPL18)) && !defined(SIMU)
|
||||
version += nl;
|
||||
version += "LCD: ";
|
||||
version += boardLcdType;
|
||||
|
|
|
@ -180,20 +180,21 @@ class SpecialFunctionEditPage : public Page
|
|||
case FUNC_PLAY_TRACK:
|
||||
case FUNC_BACKGND_MUSIC:
|
||||
case FUNC_PLAY_SCRIPT:
|
||||
case FUNC_RGB_LED:
|
||||
new StaticText(line, rect_t{}, STR_VALUE, 0, COLOR_THEME_PRIMARY1);
|
||||
new FileChoice(
|
||||
line, rect_t{},
|
||||
func == FUNC_PLAY_SCRIPT
|
||||
? SCRIPTS_FUNCS_PATH
|
||||
func == FUNC_PLAY_SCRIPT || func == FUNC_RGB_LED
|
||||
? (func == FUNC_PLAY_SCRIPT ? SCRIPTS_FUNCS_PATH : SCRIPTS_RGB_PATH)
|
||||
: std::string(SOUNDS_PATH, SOUNDS_PATH_LNG_OFS) +
|
||||
std::string(currentLanguagePack->id, 2),
|
||||
func == FUNC_PLAY_SCRIPT ? SCRIPTS_EXT : SOUNDS_EXT,
|
||||
(func == FUNC_PLAY_SCRIPT || func == FUNC_RGB_LED) ? SCRIPTS_EXT : SOUNDS_EXT,
|
||||
sizeof(cfn->play.name),
|
||||
[=]() { return std::string(cfn->play.name, ZLEN(cfn->play.name)); },
|
||||
[=](std::string newValue) {
|
||||
strncpy(cfn->play.name, newValue.c_str(), sizeof(cfn->play.name));
|
||||
SET_DIRTY();
|
||||
if (func == FUNC_PLAY_SCRIPT)
|
||||
if (func == FUNC_PLAY_SCRIPT || func == FUNC_RGB_LED)
|
||||
LUA_LOAD_MODEL_SCRIPTS();
|
||||
},
|
||||
true); // strip extension
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include "key_driver.h"
|
||||
|
||||
#include "definitions.h"
|
||||
#include "dataconstants.h"
|
||||
|
||||
#include "hal_keys.inc"
|
||||
|
||||
uint32_t keysGetSupported()
|
||||
|
|
|
@ -50,11 +50,7 @@ enum EnumKeys {
|
|||
|
||||
MAX_KEYS
|
||||
};
|
||||
#if defined(RADIO_T20)
|
||||
#define MAX_TRIMS 8
|
||||
#else
|
||||
#define MAX_TRIMS 6
|
||||
#endif
|
||||
|
||||
// returns a bit field with each key set as (1 << KEY_xxx)
|
||||
uint32_t readKeys();
|
||||
|
||||
|
|
|
@ -30,11 +30,7 @@
|
|||
#include "timers_driver.h"
|
||||
#include "hal/watchdog_driver.h"
|
||||
#include "hal/rotary_encoder.h"
|
||||
|
||||
// required by watchdog macro..
|
||||
#if !defined(SIMU)
|
||||
#include "stm32_cmsis.h"
|
||||
#endif
|
||||
#include "dataconstants.h"
|
||||
|
||||
// long key press minimum duration (x10ms),
|
||||
// must be less than KEY_REPEAT_DELAY
|
||||
|
|
|
@ -169,7 +169,13 @@ enum CurveRefType {
|
|||
#define TRIM_ELE (-2)
|
||||
#define TRIM_THR (-3)
|
||||
#define TRIM_AIL (-4)
|
||||
#if defined(PCBHORUS)
|
||||
#if defined(PCBPL18)
|
||||
#define TRIM_T5 (-5)
|
||||
#define TRIM_T6 (-6)
|
||||
#define TRIM_T7 (-7)
|
||||
#define TRIM_T8 (-8)
|
||||
#define TRIM_LAST TRIM_T8
|
||||
#elif defined(PCBHORUS)
|
||||
#define TRIM_T5 (-5)
|
||||
#define TRIM_T6 (-6)
|
||||
#define TRIM_LAST TRIM_T6
|
||||
|
|
|
@ -203,10 +203,6 @@ extern uint8_t heartbeat;
|
|||
#include "keys.h"
|
||||
#include "pwr.h"
|
||||
|
||||
// #if defined(PCBFRSKY) || defined(PCBNV14)
|
||||
// extern uint8_t potsPos[NUM_XPOTS];
|
||||
// #endif
|
||||
|
||||
bool trimDown(uint8_t idx);
|
||||
|
||||
#if defined(KEYS_GPIO_REG_BIND)
|
||||
|
|
|
@ -83,6 +83,7 @@ typedef uint32_t LcdFlags;
|
|||
typedef uint16_t event_t;
|
||||
|
||||
typedef uint32_t tmr10ms_t;
|
||||
typedef int32_t rotenc_t;
|
||||
typedef int32_t getvalue_t;
|
||||
typedef uint32_t mixsrc_t;
|
||||
typedef int32_t swsrc_t;
|
||||
|
|
|
@ -116,12 +116,9 @@ static void sendFailsafeChannels(uint8_t*& p_buf, uint8_t module)
|
|||
static void setupPulsesMulti(uint8_t*& p_buf, uint8_t module)
|
||||
{
|
||||
static int counter[2] = {0,0}; //TODO
|
||||
static uint8_t invert[2] = {0x00, //internal
|
||||
#if defined(PCBTARANIS) || defined(PCBHORUS) || defined(PCBNV14)
|
||||
static uint8_t invert[2] = {
|
||||
0x00, //internal
|
||||
0x08 //external
|
||||
#else
|
||||
0x00 //external
|
||||
#endif
|
||||
};
|
||||
uint8_t type=MULTI_NORMAL;
|
||||
|
||||
|
|
|
@ -545,7 +545,7 @@ void sdMount()
|
|||
void sdDone()
|
||||
{
|
||||
TRACE("sdDone");
|
||||
|
||||
|
||||
if (sdMounted()) {
|
||||
audioQueue.stopSD();
|
||||
|
||||
|
@ -557,8 +557,10 @@ void sdDone()
|
|||
f_close(&g_bluetoothFile);
|
||||
#endif
|
||||
|
||||
f_mount(nullptr, "", 0); // unmount SD
|
||||
f_mount(nullptr, "", 0); // unmount SD
|
||||
}
|
||||
|
||||
storageDeInit();
|
||||
}
|
||||
|
||||
uint32_t sdMounted()
|
||||
|
|
|
@ -348,7 +348,7 @@ long OpenTxSim::onMouseMove(FXObject*,FXSelector,void*v)
|
|||
void OpenTxSim::updateKeysAndSwitches(bool start)
|
||||
{
|
||||
static int keys[] = {
|
||||
#if defined(PCBNV14)
|
||||
#if defined(PCBFLYSKY)
|
||||
// no keys
|
||||
#elif defined(PCBHORUS)
|
||||
KEY_Page_Up, KEY_PAGEUP,
|
||||
|
|
|
@ -20,6 +20,8 @@ elseif(PCB STREQUAL X10)
|
|||
set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_x10.cpp)
|
||||
elseif(PCB STREQUAL NV14)
|
||||
set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_nv14.cpp)
|
||||
elseif(PCB STREQUAL PL18)
|
||||
set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_pl18.cpp)
|
||||
elseif(PCB STREQUAL X7)
|
||||
if(PCBREV STREQUAL TPRO)
|
||||
set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_tpro.cpp)
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#include "yaml_datastructs_x10.cpp"
|
||||
#elif defined(PCBNV14)
|
||||
#include "yaml_datastructs_nv14.cpp"
|
||||
#elif defined(PCBPL18)
|
||||
#include "yaml_datastructs_pl18.cpp"
|
||||
#elif defined(PCBX7)
|
||||
#if defined(RADIO_TPRO) || defined(RADIO_TPROV2)
|
||||
#include "yaml_datastructs_tpro.cpp"
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
// ========
|
||||
//
|
||||
// If any of these static_assert() fails, you need to check that
|
||||
// the functions bellow are still applicable.
|
||||
// the functions below are still applicable.
|
||||
//
|
||||
// Please note that the sizes used here are those from the v220 format
|
||||
// (see storage/conversions/yaml/datastructs_220.h)
|
||||
|
|
915
radio/src/storage/yaml/yaml_datastructs_pl18.cpp
Normal file
|
@ -0,0 +1,915 @@
|
|||
// generated by generate_yaml.py
|
||||
|
||||
//
|
||||
// Enums first
|
||||
//
|
||||
|
||||
const struct YamlIdStr enum_HatsMode[] = {
|
||||
{ HATSMODE_TRIMS_ONLY, "TRIMS_ONLY" },
|
||||
{ HATSMODE_KEYS_ONLY, "KEYS_ONLY" },
|
||||
{ HATSMODE_SWITCHABLE, "SWITCHABLE" },
|
||||
{ HATSMODE_GLOBAL, "GLOBAL" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_BacklightMode[] = {
|
||||
{ e_backlight_mode_off, "backlight_mode_off" },
|
||||
{ e_backlight_mode_keys, "backlight_mode_keys" },
|
||||
{ e_backlight_mode_sticks, "backlight_mode_sticks" },
|
||||
{ e_backlight_mode_all, "backlight_mode_all" },
|
||||
{ e_backlight_mode_on, "backlight_mode_on" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_AntennaModes[] = {
|
||||
{ ANTENNA_MODE_INTERNAL, "MODE_INTERNAL" },
|
||||
{ ANTENNA_MODE_ASK, "MODE_ASK" },
|
||||
{ ANTENNA_MODE_PER_MODEL, "MODE_PER_MODEL" },
|
||||
{ ANTENNA_MODE_EXTERNAL, "MODE_EXTERNAL" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_ModuleType[] = {
|
||||
{ MODULE_TYPE_NONE, "TYPE_NONE" },
|
||||
{ MODULE_TYPE_PPM, "TYPE_PPM" },
|
||||
{ MODULE_TYPE_XJT_PXX1, "TYPE_XJT_PXX1" },
|
||||
{ MODULE_TYPE_ISRM_PXX2, "TYPE_ISRM_PXX2" },
|
||||
{ MODULE_TYPE_DSM2, "TYPE_DSM2" },
|
||||
{ MODULE_TYPE_CROSSFIRE, "TYPE_CROSSFIRE" },
|
||||
{ MODULE_TYPE_MULTIMODULE, "TYPE_MULTIMODULE" },
|
||||
{ MODULE_TYPE_R9M_PXX1, "TYPE_R9M_PXX1" },
|
||||
{ MODULE_TYPE_R9M_PXX2, "TYPE_R9M_PXX2" },
|
||||
{ MODULE_TYPE_R9M_LITE_PXX1, "TYPE_R9M_LITE_PXX1" },
|
||||
{ MODULE_TYPE_R9M_LITE_PXX2, "TYPE_R9M_LITE_PXX2" },
|
||||
{ MODULE_TYPE_GHOST, "TYPE_GHOST" },
|
||||
{ MODULE_TYPE_R9M_LITE_PRO_PXX2, "TYPE_R9M_LITE_PRO_PXX2" },
|
||||
{ MODULE_TYPE_SBUS, "TYPE_SBUS" },
|
||||
{ MODULE_TYPE_XJT_LITE_PXX2, "TYPE_XJT_LITE_PXX2" },
|
||||
{ MODULE_TYPE_FLYSKY_AFHDS2A, "TYPE_FLYSKY_AFHDS2A" },
|
||||
{ MODULE_TYPE_FLYSKY_AFHDS3, "TYPE_FLYSKY_AFHDS3" },
|
||||
{ MODULE_TYPE_LEMON_DSMP, "TYPE_LEMON_DSMP" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_TrainerMultiplex[] = {
|
||||
{ TRAINER_OFF, "OFF" },
|
||||
{ TRAINER_ADD, "ADD" },
|
||||
{ TRAINER_REPL, "REPL" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_BeeperMode[] = {
|
||||
{ e_mode_quiet, "mode_quiet" },
|
||||
{ e_mode_alarms, "mode_alarms" },
|
||||
{ e_mode_nokeys, "mode_nokeys" },
|
||||
{ e_mode_all, "mode_all" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_BluetoothModes[] = {
|
||||
{ BLUETOOTH_OFF, "OFF" },
|
||||
{ BLUETOOTH_TELEMETRY, "TELEMETRY" },
|
||||
{ BLUETOOTH_TRAINER, "TRAINER" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_Functions[] = {
|
||||
{ FUNC_OVERRIDE_CHANNEL, "OVERRIDE_CHANNEL" },
|
||||
{ FUNC_TRAINER, "TRAINER" },
|
||||
{ FUNC_INSTANT_TRIM, "INSTANT_TRIM" },
|
||||
{ FUNC_RESET, "RESET" },
|
||||
{ FUNC_SET_TIMER, "SET_TIMER" },
|
||||
{ FUNC_ADJUST_GVAR, "ADJUST_GVAR" },
|
||||
{ FUNC_VOLUME, "VOLUME" },
|
||||
{ FUNC_SET_FAILSAFE, "SET_FAILSAFE" },
|
||||
{ FUNC_RANGECHECK, "RANGECHECK" },
|
||||
{ FUNC_BIND, "BIND" },
|
||||
{ FUNC_PLAY_SOUND, "PLAY_SOUND" },
|
||||
{ FUNC_PLAY_TRACK, "PLAY_TRACK" },
|
||||
{ FUNC_PLAY_VALUE, "PLAY_VALUE" },
|
||||
{ FUNC_PLAY_SCRIPT, "PLAY_SCRIPT" },
|
||||
{ FUNC_BACKGND_MUSIC, "BACKGND_MUSIC" },
|
||||
{ FUNC_BACKGND_MUSIC_PAUSE, "BACKGND_MUSIC_PAUSE" },
|
||||
{ FUNC_VARIO, "VARIO" },
|
||||
{ FUNC_HAPTIC, "HAPTIC" },
|
||||
{ FUNC_LOGS, "LOGS" },
|
||||
{ FUNC_BACKLIGHT, "BACKLIGHT" },
|
||||
{ FUNC_SCREENSHOT, "SCREENSHOT" },
|
||||
{ FUNC_RACING_MODE, "RACING_MODE" },
|
||||
{ FUNC_DISABLE_TOUCH, "DISABLE_TOUCH" },
|
||||
{ FUNC_SET_SCREEN, "SET_SCREEN" },
|
||||
{ FUNC_DISABLE_AUDIO_AMP, "DISABLE_AUDIO_AMP" },
|
||||
{ FUNC_RGB_LED, "RGB_LED" },
|
||||
{ FUNC_TEST, "TEST" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_TimerModes[] = {
|
||||
{ TMRMODE_OFF, "OFF" },
|
||||
{ TMRMODE_ON, "ON" },
|
||||
{ TMRMODE_START, "START" },
|
||||
{ TMRMODE_THR, "THR" },
|
||||
{ TMRMODE_THR_REL, "THR_REL" },
|
||||
{ TMRMODE_THR_START, "THR_START" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_MixerMultiplex[] = {
|
||||
{ MLTPX_ADD, "ADD" },
|
||||
{ MLTPX_MUL, "MUL" },
|
||||
{ MLTPX_REPL, "REPL" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_MixSources[] = {
|
||||
{ MIXSRC_NONE, "NONE" },
|
||||
{ MIXSRC_MIN, "MIN" },
|
||||
{ MIXSRC_MAX, "MAX" },
|
||||
{ MIXSRC_TrimRud, "TrimRud" },
|
||||
{ MIXSRC_TrimEle, "TrimEle" },
|
||||
{ MIXSRC_TrimThr, "TrimThr" },
|
||||
{ MIXSRC_TrimAil, "TrimAil" },
|
||||
{ MIXSRC_TrimT5, "TrimT5" },
|
||||
{ MIXSRC_TrimT6, "TrimT6" },
|
||||
{ MIXSRC_TrimT7, "TrimT7" },
|
||||
{ MIXSRC_TrimT8, "TrimT8" },
|
||||
{ MIXSRC_TX_VOLTAGE, "TX_VOLTAGE" },
|
||||
{ MIXSRC_TX_TIME, "TX_TIME" },
|
||||
{ MIXSRC_TX_GPS, "TX_GPS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_LogicalSwitchesFunctions[] = {
|
||||
{ LS_FUNC_NONE, "FUNC_NONE" },
|
||||
{ LS_FUNC_VEQUAL, "FUNC_VEQUAL" },
|
||||
{ LS_FUNC_VALMOSTEQUAL, "FUNC_VALMOSTEQUAL" },
|
||||
{ LS_FUNC_VPOS, "FUNC_VPOS" },
|
||||
{ LS_FUNC_VNEG, "FUNC_VNEG" },
|
||||
{ LS_FUNC_APOS, "FUNC_APOS" },
|
||||
{ LS_FUNC_ANEG, "FUNC_ANEG" },
|
||||
{ LS_FUNC_AND, "FUNC_AND" },
|
||||
{ LS_FUNC_OR, "FUNC_OR" },
|
||||
{ LS_FUNC_XOR, "FUNC_XOR" },
|
||||
{ LS_FUNC_EDGE, "FUNC_EDGE" },
|
||||
{ LS_FUNC_EQUAL, "FUNC_EQUAL" },
|
||||
{ LS_FUNC_GREATER, "FUNC_GREATER" },
|
||||
{ LS_FUNC_LESS, "FUNC_LESS" },
|
||||
{ LS_FUNC_DIFFEGREATER, "FUNC_DIFFEGREATER" },
|
||||
{ LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" },
|
||||
{ LS_FUNC_TIMER, "FUNC_TIMER" },
|
||||
{ LS_FUNC_STICKY, "FUNC_STICKY" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_SwashType[] = {
|
||||
{ SWASH_TYPE_NONE, "TYPE_NONE" },
|
||||
{ SWASH_TYPE_120, "TYPE_120" },
|
||||
{ SWASH_TYPE_120X, "TYPE_120X" },
|
||||
{ SWASH_TYPE_140, "TYPE_140" },
|
||||
{ SWASH_TYPE_90, "TYPE_90" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_SwitchSources[] = {
|
||||
{ SWSRC_NONE, "NONE" },
|
||||
{ SWSRC_TrimT7Down, "TrimT7Down" },
|
||||
{ SWSRC_TrimT7Up, "TrimT7Up" },
|
||||
{ SWSRC_TrimT8Down, "TrimT8Down" },
|
||||
{ SWSRC_TrimT8Up, "TrimT8Up" },
|
||||
{ SWSRC_ON, "ON" },
|
||||
{ SWSRC_ONE, "ONE" },
|
||||
{ SWSRC_TELEMETRY_STREAMING, "TELEMETRY_STREAMING" },
|
||||
{ SWSRC_RADIO_ACTIVITY, "RADIO_ACTIVITY" },
|
||||
{ SWSRC_TRAINER_CONNECTED, "TRAINER_CONNECTED" },
|
||||
{ SWSRC_OFF, "OFF" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_PotsWarnMode[] = {
|
||||
{ POTS_WARN_OFF, "WARN_OFF" },
|
||||
{ POTS_WARN_MANUAL, "WARN_MANUAL" },
|
||||
{ POTS_WARN_AUTO, "WARN_AUTO" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_ModelOverridableEnable[] = {
|
||||
{ OVERRIDE_GLOBAL, "GLOBAL" },
|
||||
{ OVERRIDE_OFF, "OFF" },
|
||||
{ OVERRIDE_ON, "ON" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_FailsafeModes[] = {
|
||||
{ FAILSAFE_NOT_SET, "NOT_SET" },
|
||||
{ FAILSAFE_HOLD, "HOLD" },
|
||||
{ FAILSAFE_CUSTOM, "CUSTOM" },
|
||||
{ FAILSAFE_NOPULSES, "NOPULSES" },
|
||||
{ FAILSAFE_RECEIVER, "RECEIVER" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_TelemetrySensorFormula[] = {
|
||||
{ TELEM_FORMULA_ADD, "FORMULA_ADD" },
|
||||
{ TELEM_FORMULA_AVERAGE, "FORMULA_AVERAGE" },
|
||||
{ TELEM_FORMULA_MIN, "FORMULA_MIN" },
|
||||
{ TELEM_FORMULA_MAX, "FORMULA_MAX" },
|
||||
{ TELEM_FORMULA_MULTIPLY, "FORMULA_MULTIPLY" },
|
||||
{ TELEM_FORMULA_TOTALIZE, "FORMULA_TOTALIZE" },
|
||||
{ TELEM_FORMULA_CELL, "FORMULA_CELL" },
|
||||
{ TELEM_FORMULA_CONSUMPTION, "FORMULA_CONSUMPTION" },
|
||||
{ TELEM_FORMULA_DIST, "FORMULA_DIST" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CUSTOM, "TYPE_CUSTOM" },
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_ZoneOptionValueEnum[] = {
|
||||
{ ZOV_Unsigned, "Unsigned" },
|
||||
{ ZOV_Signed, "Signed" },
|
||||
{ ZOV_Bool, "Bool" },
|
||||
{ ZOV_String, "String" },
|
||||
{ ZOV_Source, "Source" },
|
||||
{ ZOV_Color, "Color" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
//
|
||||
|
||||
static const struct YamlNode struct_CalibData[] = {
|
||||
YAML_IDX_CUST("calib",r_calib,w_calib),
|
||||
YAML_SIGNED( "mid", 16 ),
|
||||
YAML_SIGNED( "spanNeg", 16 ),
|
||||
YAML_SIGNED( "spanPos", 16 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_signed_16[] = {
|
||||
YAML_IDX,
|
||||
YAML_SIGNED( "val", 16 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TrainerMix[] = {
|
||||
YAML_IDX,
|
||||
YAML_UNSIGNED( "srcChn", 6 ),
|
||||
YAML_ENUM("mode", 2, enum_TrainerMultiplex),
|
||||
YAML_SIGNED( "studWeight", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TrainerData[] = {
|
||||
YAML_ARRAY("calib", 16, 4, struct_signed_16, NULL),
|
||||
YAML_ARRAY("mix", 16, 4, struct_TrainerMix, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_1[] = {
|
||||
YAML_STRING("name", 6),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_2[] = {
|
||||
YAML_SIGNED( "val", 16 ),
|
||||
YAML_UNSIGNED( "mode", 8 ),
|
||||
YAML_UNSIGNED( "param", 8 ),
|
||||
YAML_SIGNED( "spare", 16 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_3[] = {
|
||||
YAML_SIGNED( "val1", 32 ),
|
||||
YAML_SIGNED( "val2", 16 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_0_elmts[] = {
|
||||
YAML_STRUCT("play", 48, struct_anonymous_1, NULL),
|
||||
YAML_STRUCT("all", 48, struct_anonymous_2, NULL),
|
||||
YAML_STRUCT("clear", 48, struct_anonymous_3, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_CustomFunctionData[] = {
|
||||
YAML_IDX,
|
||||
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
|
||||
YAML_ENUM("func", 6, enum_Functions),
|
||||
YAML_CUSTOM("def",r_customFn,w_customFn),
|
||||
YAML_PADDING( 48 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_PADDING( 7 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "manuallyEdited", 1 ),
|
||||
YAML_SIGNED( "timezoneMinutes", 3 ),
|
||||
YAML_ENUM("hatsMode", 2, enum_HatsMode),
|
||||
YAML_UNSIGNED( "ppmunit", 2 ),
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_CUSTOM("board",nullptr,w_board),
|
||||
YAML_ARRAY("calib", 48, 20, struct_CalibData, NULL),
|
||||
YAML_PADDING( 16 ),
|
||||
YAML_SIGNED( "currModel", 8 ),
|
||||
YAML_UNSIGNED( "contrast", 8 ),
|
||||
YAML_UNSIGNED( "vBatWarn", 8 ),
|
||||
YAML_SIGNED( "txVoltageCalibration", 8 ),
|
||||
YAML_ENUM("backlightMode", 3, enum_BacklightMode),
|
||||
YAML_ENUM("antennaMode", 2, enum_AntennaModes),
|
||||
YAML_UNSIGNED( "disableRtcWarning", 1 ),
|
||||
YAML_UNSIGNED( "keysBacklight", 1 ),
|
||||
YAML_UNSIGNED( "dontPlayHello", 1 ),
|
||||
YAML_ENUM("internalModule", 8, enum_ModuleType),
|
||||
YAML_STRUCT("trainer", 128, struct_TrainerData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_PADDING( 2 ),
|
||||
YAML_UNSIGNED( "fai", 1 ),
|
||||
YAML_SIGNED_CUST( "beepMode", 2, r_beeperMode, w_beeperMode ),
|
||||
YAML_UNSIGNED( "alarmsFlash", 1 ),
|
||||
YAML_UNSIGNED( "disableMemoryWarning", 1 ),
|
||||
YAML_UNSIGNED( "disableAlarmWarning", 1 ),
|
||||
YAML_UNSIGNED( "stickMode", 2 ),
|
||||
YAML_SIGNED( "timezone", 5 ),
|
||||
YAML_UNSIGNED( "adjustRTC", 1 ),
|
||||
YAML_UNSIGNED( "inactivityTimer", 8 ),
|
||||
YAML_CUSTOM("telemetryBaudrate",r_telemetryBaudrate,nullptr),
|
||||
YAML_UNSIGNED( "internalModuleBaudrate", 3 ),
|
||||
YAML_SIGNED( "splashMode", 3 ),
|
||||
YAML_SIGNED_CUST( "hapticMode", 2, r_beeperMode, w_beeperMode ),
|
||||
YAML_SIGNED( "switchesDelay", 8 ),
|
||||
YAML_UNSIGNED( "lightAutoOff", 8 ),
|
||||
YAML_UNSIGNED( "templateSetup", 8 ),
|
||||
YAML_SIGNED( "PPM_Multiplier", 8 ),
|
||||
YAML_SIGNED_CUST( "hapticLength", 8, r_5pos, w_5pos ),
|
||||
YAML_SIGNED_CUST( "beepLength", 3, r_5pos, w_5pos ),
|
||||
YAML_SIGNED_CUST( "hapticStrength", 3, r_5pos, w_5pos ),
|
||||
YAML_UNSIGNED( "gpsFormat", 1 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_UNSIGNED_CUST( "speakerPitch", 8, r_spPitch, w_spPitch ),
|
||||
YAML_SIGNED_CUST( "speakerVolume", 8, r_vol, w_vol ),
|
||||
YAML_SIGNED_CUST( "vBatMin", 8, r_vbat_min, w_vbat_min ),
|
||||
YAML_SIGNED_CUST( "vBatMax", 8, r_vbat_max, w_vbat_max ),
|
||||
YAML_UNSIGNED( "backlightBright", 8 ),
|
||||
YAML_UNSIGNED( "globalTimer", 32 ),
|
||||
YAML_UNSIGNED( "bluetoothBaudrate", 4 ),
|
||||
YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes),
|
||||
YAML_UNSIGNED( "countryCode", 2 ),
|
||||
YAML_SIGNED( "pwrOnSpeed", 3 ),
|
||||
YAML_SIGNED( "pwrOffSpeed", 3 ),
|
||||
YAML_CUSTOM("jitterFilter",r_jitterFilter,nullptr),
|
||||
YAML_UNSIGNED( "noJitterFilter", 1 ),
|
||||
YAML_UNSIGNED( "imperial", 1 ),
|
||||
YAML_UNSIGNED( "disableRssiPoweroffAlarm", 1 ),
|
||||
YAML_UNSIGNED( "USBMode", 2 ),
|
||||
YAML_UNSIGNED( "jackMode", 2 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_STRING("ttsLanguage", 2),
|
||||
YAML_SIGNED_CUST( "beepVolume", 4, r_5pos, w_5pos ),
|
||||
YAML_SIGNED_CUST( "wavVolume", 4, r_5pos, w_5pos ),
|
||||
YAML_SIGNED_CUST( "varioVolume", 4, r_5pos, w_5pos ),
|
||||
YAML_SIGNED_CUST( "backgroundVolume", 4, r_5pos, w_5pos ),
|
||||
YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ),
|
||||
YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ),
|
||||
YAML_SIGNED( "varioRepeat", 8 ),
|
||||
YAML_ARRAY("customFn", 72, 64, struct_CustomFunctionData, cfn_is_active),
|
||||
YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr),
|
||||
YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr),
|
||||
YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr),
|
||||
YAML_ARRAY("sticksConfig", 0, MAX_STICKS, struct_stickConfig, stick_name_valid),
|
||||
YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr),
|
||||
YAML_ARRAY("potsConfig", 4, 16, struct_potConfig, nullptr),
|
||||
YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr),
|
||||
YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid),
|
||||
YAML_STRING("currModelFilename", 17),
|
||||
YAML_UNSIGNED( "modelQuickSelect", 1 ),
|
||||
YAML_UNSIGNED( "blOffBright", 7 ),
|
||||
YAML_STRING("bluetoothName", 10),
|
||||
YAML_STRING("ownerRegistrationID", 8),
|
||||
YAML_CUSTOM("rotEncDirection",r_rotEncDirection,nullptr),
|
||||
YAML_UNSIGNED( "rotEncMode", 2 ),
|
||||
YAML_SIGNED( "uartSampleMode", 2 ),
|
||||
YAML_PADDING( 3 ),
|
||||
YAML_UNSIGNED( "audioMuteEnable", 1 ),
|
||||
YAML_STRING("selectedTheme", 26),
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_UNSIGNED( "radioGFDisabled", 1 ),
|
||||
YAML_UNSIGNED( "radioTrainerDisabled", 1 ),
|
||||
YAML_UNSIGNED( "modelHeliDisabled", 1 ),
|
||||
YAML_UNSIGNED( "modelFMDisabled", 1 ),
|
||||
YAML_UNSIGNED( "modelCurvesDisabled", 1 ),
|
||||
YAML_UNSIGNED( "modelGVDisabled", 1 ),
|
||||
YAML_UNSIGNED( "modelLSDisabled", 1 ),
|
||||
YAML_UNSIGNED( "modelSFDisabled", 1 ),
|
||||
YAML_UNSIGNED( "modelCustomScriptsDisabled", 1 ),
|
||||
YAML_UNSIGNED( "modelTelemetryDisabled", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_unsigned_8[] = {
|
||||
YAML_IDX,
|
||||
YAML_UNSIGNED( "val", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelHeader[] = {
|
||||
YAML_STRING("name", 15),
|
||||
YAML_ARRAY("modelId", 8, 2, struct_unsigned_8, NULL),
|
||||
YAML_STRING("bitmap", 14),
|
||||
YAML_STRING("labels", 100),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TimerData[] = {
|
||||
YAML_IDX,
|
||||
YAML_UNSIGNED( "start", 22 ),
|
||||
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
|
||||
YAML_SIGNED( "value", 22 ),
|
||||
YAML_ENUM("mode", 3, enum_TimerModes),
|
||||
YAML_UNSIGNED( "countdownBeep", 2 ),
|
||||
YAML_UNSIGNED( "minuteBeep", 1 ),
|
||||
YAML_UNSIGNED( "persistent", 2 ),
|
||||
YAML_SIGNED( "countdownStart", 2 ),
|
||||
YAML_UNSIGNED( "showElapsed", 1 ),
|
||||
YAML_UNSIGNED( "extraHaptic", 1 ),
|
||||
YAML_PADDING( 6 ),
|
||||
YAML_STRING("name", 8),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_CurveRef[] = {
|
||||
YAML_UNSIGNED( "type", 8 ),
|
||||
YAML_SIGNED_CUST( "value", 8, in_read_weight, in_write_weight ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_MixData[] = {
|
||||
YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ),
|
||||
YAML_UNSIGNED( "destCh", 5 ),
|
||||
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
|
||||
YAML_UNSIGNED( "carryTrim", 1 ),
|
||||
YAML_UNSIGNED( "mixWarn", 2 ),
|
||||
YAML_ENUM("mltpx", 2, enum_MixerMultiplex),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_SIGNED_CUST( "offset", 13, in_read_weight, in_write_weight ),
|
||||
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
|
||||
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
|
||||
YAML_STRUCT("curve", 16, struct_CurveRef, NULL),
|
||||
YAML_UNSIGNED( "delayUp", 8 ),
|
||||
YAML_UNSIGNED( "delayDown", 8 ),
|
||||
YAML_UNSIGNED( "speedUp", 8 ),
|
||||
YAML_UNSIGNED( "speedDown", 8 ),
|
||||
YAML_STRING("name", 6),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LimitData[] = {
|
||||
YAML_IDX,
|
||||
YAML_SIGNED_CUST( "min", 11, in_read_weight, in_write_weight ),
|
||||
YAML_SIGNED_CUST( "max", 11, in_read_weight, in_write_weight ),
|
||||
YAML_SIGNED( "ppmCenter", 10 ),
|
||||
YAML_SIGNED_CUST( "offset", 11, in_read_weight, in_write_weight ),
|
||||
YAML_UNSIGNED( "symetrical", 1 ),
|
||||
YAML_UNSIGNED( "revert", 1 ),
|
||||
YAML_PADDING( 3 ),
|
||||
YAML_SIGNED( "curve", 8 ),
|
||||
YAML_STRING("name", 6),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ExpoData[] = {
|
||||
YAML_UNSIGNED( "mode", 2 ),
|
||||
YAML_UNSIGNED( "scale", 14 ),
|
||||
YAML_CUSTOM("carryTrim",r_carryTrim,nullptr),
|
||||
YAML_SIGNED( "trimSource", 6 ),
|
||||
YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ),
|
||||
YAML_UNSIGNED( "chn", 5 ),
|
||||
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
|
||||
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
|
||||
YAML_SIGNED_CUST( "weight", 8, in_read_weight, in_write_weight ),
|
||||
YAML_STRING("name", 6),
|
||||
YAML_SIGNED_CUST( "offset", 8, in_read_weight, in_write_weight ),
|
||||
YAML_STRUCT("curve", 16, struct_CurveRef, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_CurveHeader[] = {
|
||||
YAML_IDX,
|
||||
YAML_UNSIGNED( "type", 1 ),
|
||||
YAML_UNSIGNED( "smooth", 1 ),
|
||||
YAML_SIGNED( "points", 6 ),
|
||||
YAML_STRING("name", 3),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_signed_8[] = {
|
||||
YAML_IDX,
|
||||
YAML_SIGNED( "val", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LogicalSwitchData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions),
|
||||
YAML_CUSTOM("def",r_logicSw,w_logicSw),
|
||||
YAML_PADDING( 10 ),
|
||||
YAML_PADDING( 10 ),
|
||||
YAML_SIGNED_CUST( "andsw", 10, r_swtchSrc, w_swtchSrc ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_PADDING( 16 ),
|
||||
YAML_UNSIGNED( "delay", 8 ),
|
||||
YAML_UNSIGNED( "duration", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_SwashRingData[] = {
|
||||
YAML_ENUM("type", 8, enum_SwashType),
|
||||
YAML_UNSIGNED( "value", 8 ),
|
||||
YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ),
|
||||
YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ),
|
||||
YAML_UNSIGNED_CUST( "elevatorSource", 8, r_mixSrcRaw, w_mixSrcRaw ),
|
||||
YAML_SIGNED( "collectiveWeight", 8 ),
|
||||
YAML_SIGNED( "aileronWeight", 8 ),
|
||||
YAML_SIGNED( "elevatorWeight", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_trim_t[] = {
|
||||
YAML_IDX,
|
||||
YAML_SIGNED( "value", 11 ),
|
||||
YAML_UNSIGNED( "mode", 5 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_FlightModeData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ARRAY("trim", 16, 8, struct_trim_t, NULL),
|
||||
YAML_STRING("name", 10),
|
||||
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
|
||||
YAML_PADDING( 6 ),
|
||||
YAML_UNSIGNED( "fadeIn", 8 ),
|
||||
YAML_UNSIGNED( "fadeOut", 8 ),
|
||||
YAML_ARRAY("gvars", 16, 9, struct_signed_16, gvar_is_active),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_GVarData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("name", 3),
|
||||
YAML_UNSIGNED( "min", 12 ),
|
||||
YAML_UNSIGNED( "max", 12 ),
|
||||
YAML_UNSIGNED( "popup", 1 ),
|
||||
YAML_UNSIGNED( "prec", 1 ),
|
||||
YAML_UNSIGNED( "unit", 2 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_VarioData[] = {
|
||||
YAML_UNSIGNED_CUST( "source", 7, r_tele_sensor, w_tele_sensor ),
|
||||
YAML_UNSIGNED( "centerSilent", 1 ),
|
||||
YAML_SIGNED( "centerMax", 8 ),
|
||||
YAML_SIGNED( "centerMin", 8 ),
|
||||
YAML_SIGNED( "min", 8 ),
|
||||
YAML_SIGNED( "max", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_RssiAlarmData[] = {
|
||||
YAML_CUSTOM("disabled",r_rssiDisabled,nullptr),
|
||||
YAML_CUSTOM("warning",r_rssiWarning,nullptr),
|
||||
YAML_CUSTOM("critical",r_rssiCritical,nullptr),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_RFAlarmData[] = {
|
||||
YAML_SIGNED( "warning", 8 ),
|
||||
YAML_SIGNED( "critical", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PpmModule[] = {
|
||||
YAML_SIGNED( "delay", 6 ),
|
||||
YAML_UNSIGNED( "pulsePol", 1 ),
|
||||
YAML_UNSIGNED( "outputType", 1 ),
|
||||
YAML_SIGNED( "frameLength", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_5[] = {
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_UNSIGNED( "disableTelemetry", 1 ),
|
||||
YAML_UNSIGNED( "disableMapping", 1 ),
|
||||
YAML_UNSIGNED( "autoBindMode", 1 ),
|
||||
YAML_UNSIGNED( "lowPowerMode", 1 ),
|
||||
YAML_UNSIGNED( "receiverTelemetryOff", 1 ),
|
||||
YAML_UNSIGNED( "receiverHigherChannels", 1 ),
|
||||
YAML_PADDING( 2 ),
|
||||
YAML_SIGNED( "optionValue", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_6[] = {
|
||||
YAML_UNSIGNED( "power", 2 ),
|
||||
YAML_PADDING( 2 ),
|
||||
YAML_UNSIGNED( "receiverTelemetryOff", 1 ),
|
||||
YAML_UNSIGNED( "receiverHigherChannels", 1 ),
|
||||
YAML_SIGNED( "antennaMode", 2 ),
|
||||
YAML_PADDING( 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_7[] = {
|
||||
YAML_PADDING( 6 ),
|
||||
YAML_UNSIGNED( "noninverted", 1 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_SIGNED( "refreshRate", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_string_64[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("val", 8),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_8[] = {
|
||||
YAML_UNSIGNED( "receivers", 7 ),
|
||||
YAML_UNSIGNED( "racingMode", 1 ),
|
||||
YAML_ARRAY("receiverName", 64, 3, struct_string_64, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_9[] = {
|
||||
YAML_ARRAY("rx_id", 8, 4, struct_unsigned_8, NULL),
|
||||
YAML_UNSIGNED( "mode", 3 ),
|
||||
YAML_UNSIGNED( "rfPower", 1 ),
|
||||
YAML_UNSIGNED( "reserved", 4 ),
|
||||
YAML_ARRAY("rx_freq", 8, 2, struct_unsigned_8, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_10[] = {
|
||||
YAML_UNSIGNED( "emi", 2 ),
|
||||
YAML_UNSIGNED( "telemetry", 1 ),
|
||||
YAML_UNSIGNED( "phyMode", 3 ),
|
||||
YAML_UNSIGNED( "reserved", 2 ),
|
||||
YAML_UNSIGNED( "rfPower", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_11[] = {
|
||||
YAML_UNSIGNED( "raw12bits", 1 ),
|
||||
YAML_UNSIGNED( "telemetryBaudrate", 3 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_12[] = {
|
||||
YAML_UNSIGNED( "telemetryBaudrate", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_ARRAY("raw", 8, 25, struct_unsigned_8, NULL),
|
||||
YAML_STRUCT("ppm", 16, struct_PpmModule, NULL),
|
||||
YAML_STRUCT("multi", 24, struct_anonymous_5, NULL),
|
||||
YAML_STRUCT("pxx", 16, struct_anonymous_6, NULL),
|
||||
YAML_STRUCT("sbus", 16, struct_anonymous_7, NULL),
|
||||
YAML_STRUCT("pxx2", 200, struct_anonymous_8, NULL),
|
||||
YAML_STRUCT("flysky", 56, struct_anonymous_9, NULL),
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 8, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
YAML_IDX,
|
||||
YAML_UNSIGNED_CUST( "type", 8, r_moduleType, w_moduleType ),
|
||||
YAML_CUSTOM("subType",r_modSubtype,w_modSubtype),
|
||||
YAML_UNSIGNED( "channelsStart", 8 ),
|
||||
YAML_SIGNED_CUST( "channelsCount", 8, r_channelsCount, w_channelsCount ),
|
||||
YAML_ENUM("failsafeMode", 4, enum_FailsafeModes),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TrainerModuleData[] = {
|
||||
YAML_UNSIGNED_CUST( "mode", 8, r_trainerMode, w_trainerMode ),
|
||||
YAML_UNSIGNED( "channelsStart", 8 ),
|
||||
YAML_SIGNED( "channelsCount", 8 ),
|
||||
YAML_SIGNED( "frameLength", 8 ),
|
||||
YAML_SIGNED( "delay", 6 ),
|
||||
YAML_UNSIGNED( "pulsePol", 1 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_ScriptDataInput_elmts[] = {
|
||||
YAML_SIGNED( "value", 16 ),
|
||||
YAML_UNSIGNED_CUST( "source", 16, r_mixSrcRaw, w_mixSrcRaw ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_ScriptDataInput[] = {
|
||||
YAML_IDX,
|
||||
YAML_UNION("u", 16, union_ScriptDataInput_elmts, select_script_input),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ScriptData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("file", 6),
|
||||
YAML_STRING("name", 6),
|
||||
YAML_ARRAY("inputs", 16, 6, union_ScriptDataInput, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_string_32[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("val", 4),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_14_elmts[] = {
|
||||
YAML_UNSIGNED( "id", 16 ),
|
||||
YAML_UNSIGNED( "persistentValue", 16 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_16[] = {
|
||||
YAML_UNSIGNED( "physID", 5 ),
|
||||
YAML_UNSIGNED( "rxIndex", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_15_elmts[] = {
|
||||
YAML_STRUCT("frskyInstance", 8, struct_anonymous_16, NULL),
|
||||
YAML_UNSIGNED( "instance", 8 ),
|
||||
YAML_ENUM("formula", 8, enum_TelemetrySensorFormula),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_18[] = {
|
||||
YAML_UNSIGNED( "ratio", 16 ),
|
||||
YAML_SIGNED( "offset", 16 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_19[] = {
|
||||
YAML_UNSIGNED( "source", 8 ),
|
||||
YAML_UNSIGNED( "index", 8 ),
|
||||
YAML_PADDING( 16 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_20[] = {
|
||||
YAML_ARRAY("sources", 8, 4, struct_signed_8, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_21[] = {
|
||||
YAML_UNSIGNED( "source", 8 ),
|
||||
YAML_PADDING( 24 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_22[] = {
|
||||
YAML_UNSIGNED( "gps", 8 ),
|
||||
YAML_UNSIGNED( "alt", 8 ),
|
||||
YAML_PADDING( 16 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_17_elmts[] = {
|
||||
YAML_STRUCT("custom", 32, struct_anonymous_18, NULL),
|
||||
YAML_STRUCT("cell", 32, struct_anonymous_19, NULL),
|
||||
YAML_STRUCT("calc", 32, struct_anonymous_20, NULL),
|
||||
YAML_STRUCT("consumption", 32, struct_anonymous_21, NULL),
|
||||
YAML_STRUCT("dist", 32, struct_anonymous_22, NULL),
|
||||
YAML_UNSIGNED( "param", 32 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TelemetrySensor[] = {
|
||||
YAML_IDX,
|
||||
YAML_UNION("id1", 16, union_anonymous_14_elmts, select_id1),
|
||||
YAML_UNION("id2", 8, union_anonymous_15_elmts, select_id2),
|
||||
YAML_STRING("label", 4),
|
||||
YAML_UNSIGNED( "subId", 8 ),
|
||||
YAML_ENUM("type", 1, enum_TelemetrySensorType),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_UNSIGNED( "unit", 6 ),
|
||||
YAML_UNSIGNED( "prec", 2 ),
|
||||
YAML_UNSIGNED( "autoOffset", 1 ),
|
||||
YAML_UNSIGNED( "filter", 1 ),
|
||||
YAML_UNSIGNED( "logs", 1 ),
|
||||
YAML_UNSIGNED( "persistent", 1 ),
|
||||
YAML_UNSIGNED( "onlyPositive", 1 ),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_UNION("cfg", 32, union_anonymous_17_elmts, select_sensor_cfg),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_ZoneOptionValue_elmts[] = {
|
||||
YAML_UNSIGNED( "unsignedValue", 32 ),
|
||||
YAML_SIGNED( "signedValue", 32 ),
|
||||
YAML_UNSIGNED( "boolValue", 32 ),
|
||||
YAML_STRING("stringValue", 8),
|
||||
YAML_CUSTOM("source",r_zov_source,w_zov_source),
|
||||
YAML_CUSTOM("color",r_zov_color,w_zov_color),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZoneOptionValueTyped[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("type", 32, enum_ZoneOptionValueEnum),
|
||||
YAML_UNION("value", 64, union_ZoneOptionValue_elmts, select_zov),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_WidgetPersistentData[] = {
|
||||
YAML_ARRAY("options", 96, 5, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ZonePersistentData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("widgetName", 12),
|
||||
YAML_STRUCT("widgetData", 480, struct_WidgetPersistentData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_LayoutPersistentData[] = {
|
||||
YAML_ARRAY("zones", 576, 10, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 96, 10, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_CustomScreenData[] = {
|
||||
YAML_IDX,
|
||||
YAML_STRING("LayoutId", 12),
|
||||
YAML_STRUCT("layoutData", 6720, struct_LayoutPersistentData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_TopBarPersistentData[] = {
|
||||
YAML_ARRAY("zones", 576, 6, struct_ZonePersistentData, NULL),
|
||||
YAML_ARRAY("options", 96, 1, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 1048, struct_ModelHeader, NULL),
|
||||
YAML_ARRAY("timers", 136, 3, struct_TimerData, NULL),
|
||||
YAML_UNSIGNED( "telemetryProtocol", 3 ),
|
||||
YAML_UNSIGNED( "thrTrim", 1 ),
|
||||
YAML_UNSIGNED( "noGlobalFunctions", 1 ),
|
||||
YAML_UNSIGNED( "displayTrims", 2 ),
|
||||
YAML_UNSIGNED( "ignoreSensorIds", 1 ),
|
||||
YAML_SIGNED( "trimInc", 3 ),
|
||||
YAML_UNSIGNED( "disableThrottleWarning", 1 ),
|
||||
YAML_UNSIGNED( "displayChecklist", 1 ),
|
||||
YAML_UNSIGNED( "extendedLimits", 1 ),
|
||||
YAML_UNSIGNED( "extendedTrims", 1 ),
|
||||
YAML_UNSIGNED( "throttleReversed", 1 ),
|
||||
YAML_UNSIGNED( "enableCustomThrottleWarning", 1 ),
|
||||
YAML_UNSIGNED( "disableTelemetryWarning", 1 ),
|
||||
YAML_UNSIGNED( "showInstanceIds", 1 ),
|
||||
YAML_UNSIGNED( "checklistInteractive", 1 ),
|
||||
YAML_ENUM("hatsMode", 2, enum_HatsMode),
|
||||
YAML_PADDING( 2 ),
|
||||
YAML_SIGNED( "customThrottleWarningPosition", 8 ),
|
||||
YAML_UNSIGNED( "beepANACenter", 16 ),
|
||||
YAML_ARRAY("mixData", 160, 64, struct_MixData, NULL),
|
||||
YAML_ARRAY("limitData", 104, 32, struct_LimitData, NULL),
|
||||
YAML_ARRAY("expoData", 136, 64, struct_ExpoData, NULL),
|
||||
YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL),
|
||||
YAML_ARRAY("points", 8, 512, struct_signed_8, NULL),
|
||||
YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL),
|
||||
YAML_ARRAY("customFn", 72, 64, struct_CustomFunctionData, cfn_is_active),
|
||||
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
|
||||
YAML_ARRAY("flightModeData", 384, 9, struct_FlightModeData, fmd_is_active),
|
||||
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
|
||||
YAML_CUSTOM("switchWarningState",r_swtchWarn,w_swtchWarn),
|
||||
YAML_PADDING( 64 ),
|
||||
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
|
||||
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
|
||||
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
|
||||
YAML_STRUCT("rssiAlarms", 0, struct_RssiAlarmData, NULL),
|
||||
YAML_STRUCT("rfAlarms", 16, struct_RFAlarmData, NULL),
|
||||
YAML_UNSIGNED( "thrTrimSw", 3 ),
|
||||
YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode),
|
||||
YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable),
|
||||
YAML_PADDING( 1 ),
|
||||
YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL),
|
||||
YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL),
|
||||
YAML_STRUCT("trainerData", 40, struct_TrainerModuleData, NULL),
|
||||
YAML_ARRAY("scriptsData", 192, 9, struct_ScriptData, NULL),
|
||||
YAML_ARRAY("inputNames", 32, 32, struct_string_32, NULL),
|
||||
YAML_UNSIGNED( "potsWarnEnabled", 16 ),
|
||||
YAML_ARRAY("potsWarnPosition", 8, 16, struct_signed_8, NULL),
|
||||
YAML_ARRAY("telemetrySensors", 112, 60, struct_TelemetrySensor, NULL),
|
||||
YAML_ARRAY("screenData", 6816, 10, struct_CustomScreenData, NULL),
|
||||
YAML_STRUCT("topbarData", 3552, struct_TopBarPersistentData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_ENUM("radioThemesDisabled", 2, enum_ModelOverridableEnable),
|
||||
YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable),
|
||||
YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable),
|
||||
YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable),
|
||||
YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable),
|
||||
YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable),
|
||||
YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable),
|
||||
YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable),
|
||||
YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable),
|
||||
YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable),
|
||||
YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
YAML_STRUCT("header", 1048, struct_ModelHeader, NULL),
|
||||
YAML_ARRAY("timers", 136, 3, struct_TimerData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
|
||||
#define MAX_RADIODATA_MODELDATA_PARTIALMODEL_STR_LEN 29
|
||||
|
||||
static const struct YamlNode __RadioData_root_node = YAML_ROOT( struct_RadioData );
|
||||
|
||||
const YamlNode* get_radiodata_nodes()
|
||||
{
|
||||
return &__RadioData_root_node;
|
||||
}
|
||||
static const struct YamlNode __ModelData_root_node = YAML_ROOT( struct_ModelData );
|
||||
|
||||
const YamlNode* get_modeldata_nodes()
|
||||
{
|
||||
return &__ModelData_root_node;
|
||||
}
|
||||
static const struct YamlNode __PartialModel_root_node = YAML_ROOT( struct_PartialModel );
|
||||
|
||||
const YamlNode* get_partialmodel_nodes()
|
||||
{
|
||||
return &__PartialModel_root_node;
|
||||
}
|
||||
|
|
@ -22,17 +22,19 @@ option(DEBUG_USB_INTERRUPTS "Count individual USB interrupts" OFF)
|
|||
option(DEBUG_TIMERS "Time critical parts of the code" OFF)
|
||||
option(DEBUG_BLUETOOTH "Debug Bluetooth" OFF)
|
||||
|
||||
# option to select the default internal module
|
||||
#set(DEFAULT_INTERNAL_MODULE NONE CACHE STRING "Default internal module")
|
||||
set_property(CACHE DEFAULT_INTERNAL_MODULE PROPERTY STRINGS ${INTERNAL_MODULES})
|
||||
if(INTERNAL_MODULES)
|
||||
# option to select the default internal module
|
||||
#set(DEFAULT_INTERNAL_MODULE NONE CACHE STRING "Default internal module")
|
||||
set_property(CACHE DEFAULT_INTERNAL_MODULE PROPERTY STRINGS ${INTERNAL_MODULES})
|
||||
|
||||
# define variables for internal modules
|
||||
foreach(module ${INTERNAL_MODULES})
|
||||
set(INTERNAL_MODULE_${module} ON CACHE BOOL "Support for ${module} internal module")
|
||||
if (INTERNAL_MODULE_${module})
|
||||
message("-- Adding support for ${module} as internal module")
|
||||
endif()
|
||||
endforeach()
|
||||
# define variables for internal modules
|
||||
foreach(module ${INTERNAL_MODULES})
|
||||
set(INTERNAL_MODULE_${module} ON CACHE BOOL "Support for ${module} internal module")
|
||||
if (INTERNAL_MODULE_${module})
|
||||
message("-- Adding support for ${module} as internal module")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(INTERNAL_MODULE_PXX1)
|
||||
add_definitions(-DHARDWARE_INTERNAL_MODULE)
|
||||
|
|
|
@ -69,8 +69,7 @@ if(DEBUG_SEGGER_RTT)
|
|||
)
|
||||
endif()
|
||||
|
||||
|
||||
if(PCB STREQUAL X10 OR PCB STREQUAL X12S OR PCB STREQUAL NV14)
|
||||
if(PCB STREQUAL X10 OR PCB STREQUAL X12S OR PCB STREQUAL NV14 OR PCB STREQUAL PL18)
|
||||
set(BOOTLOADER_SRC
|
||||
${BOOTLOADER_SRC}
|
||||
../../../../../gui/colorlcd/fonts.cpp
|
||||
|
@ -79,7 +78,6 @@ if(PCB STREQUAL X10 OR PCB STREQUAL X12S OR PCB STREQUAL NV14)
|
|||
../../../../../thirdparty/libopenui/src/bitmapbuffer.cpp
|
||||
../../../../../thirdparty/libopenui/thirdparty/lz4/lz4.c
|
||||
../../../../../targets/common/arm/stm32/dma2d.cpp
|
||||
../../../../../targets/common/arm/stm32/diskio_sdio.cpp
|
||||
../../../../../targets/common/arm/stm32/rtc_driver.cpp
|
||||
../../../../../targets/common/arm/stm32/diskio_spi_flash.cpp
|
||||
../../../../../targets/common/arm/stm32/spi_flash.cpp
|
||||
|
@ -90,12 +88,22 @@ if(PCB STREQUAL X10 OR PCB STREQUAL X12S OR PCB STREQUAL NV14)
|
|||
../../../../../targets/${TARGET_DIR}/haptic_driver.cpp
|
||||
)
|
||||
|
||||
if(NOT PCB STREQUAL PL18)
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC}
|
||||
../../../../../targets/common/arm/stm32/diskio_sdio.cpp
|
||||
)
|
||||
else()
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC}
|
||||
../../../../../targets/pl18/key_driver.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
# Add LVGL sources
|
||||
foreach(LVGL_FILE ${LVGL_SRC_FILES_MINIMAL})
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC} ../../../../../${LVGL_FILE})
|
||||
endforeach()
|
||||
|
||||
if(NOT PCB STREQUAL NV14)
|
||||
if(NOT (PCB STREQUAL NV14 OR PCB STREQUAL PL18))
|
||||
set(BOOTLOADER_SRC
|
||||
${BOOTLOADER_SRC}
|
||||
../../../../../targets/${TARGET_DIR}/led_driver.cpp
|
||||
|
|
|
@ -56,12 +56,17 @@
|
|||
|
||||
#define APP_START_ADDRESS (uint32_t)(FIRMWARE_ADDRESS + BOOTLOADER_SIZE)
|
||||
|
||||
#if defined(EEPROM)
|
||||
#if defined(EEPROM) || defined(SPI_FLASH)
|
||||
#define MAIN_MENU_LEN 3
|
||||
#else
|
||||
#define MAIN_MENU_LEN 2
|
||||
#endif
|
||||
|
||||
#if defined(SPI_FLASH)
|
||||
#include "spi_flash.h"
|
||||
#define SEL_CLEAR_FLASH_STORAGE_MENU_LEN 2
|
||||
#endif
|
||||
|
||||
typedef void (*voidFunction)(void);
|
||||
|
||||
#define jumpTo(addr) do { \
|
||||
|
@ -369,6 +374,10 @@ int bootloaderMain()
|
|||
memoryType = MEM_EEPROM;
|
||||
state = ST_DIR_CHECK;
|
||||
break;
|
||||
#elif defined(SPI_FLASH)
|
||||
case 1:
|
||||
state = ST_CLEAR_FLASH_CHECK;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
if(vpos < bootloaderGetMenuItemCount(MAIN_MENU_LEN-1))
|
||||
|
@ -511,6 +520,35 @@ int bootloaderMain()
|
|||
else if (memoryType == MEM_EEPROM && eepromWritten >= EEPROM_SIZE) {
|
||||
state = ST_FLASH_DONE; // Backstop
|
||||
}
|
||||
#endif
|
||||
#if defined(SPI_FLASH)
|
||||
} else if (state == ST_CLEAR_FLASH_CHECK) {
|
||||
bootloaderDrawScreen(state, vpos);
|
||||
if (event == EVT_KEY_REPT(KEY_DOWN) || event == EVT_KEY_FIRST(KEY_DOWN)) {
|
||||
if (vpos < SEL_CLEAR_FLASH_STORAGE_MENU_LEN - 1) { vpos++; }
|
||||
continue;
|
||||
}
|
||||
if (event == EVT_KEY_REPT(KEY_UP) || event == EVT_KEY_FIRST(KEY_UP)) {
|
||||
if (vpos > 0) { vpos--; }
|
||||
continue;
|
||||
}
|
||||
if (event == EVT_KEY_LONG(KEY_ENTER) && vpos == 0)
|
||||
{
|
||||
state = ST_CLEAR_FLASH;
|
||||
} else if (event == EVT_KEY_BREAK(KEY_EXIT) ||
|
||||
(event == EVT_KEY_BREAK(KEY_ENTER) && vpos == 1) ) {
|
||||
vpos = 0;
|
||||
state = ST_START;
|
||||
continue;
|
||||
}
|
||||
} else if (state == ST_CLEAR_FLASH) {
|
||||
bootloaderDrawScreen(state, 0);
|
||||
lcdRefresh();
|
||||
if(event != EVT_KEY_BREAK(KEY_ENTER))
|
||||
continue;
|
||||
flashSpiEraseAll();
|
||||
vpos = 0;
|
||||
state = ST_START;
|
||||
#endif
|
||||
} else if (state == ST_RADIO_MENU) {
|
||||
if(bootloaderRadioMenu(radioMenuItem, event))
|
||||
|
@ -565,6 +603,6 @@ int bootloaderMain()
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(SIMU) && (defined(PCBHORUS) || defined(PCBNV14))
|
||||
#if !defined(SIMU) && (defined(PCBHORUS) || defined(PCBFLYSKY))
|
||||
void *__dso_handle = nullptr;
|
||||
#endif
|
||||
|
|
|
@ -54,6 +54,10 @@ enum BootloaderState {
|
|||
ST_FLASH_DONE,
|
||||
ST_RESTORE_MENU,
|
||||
ST_USB,
|
||||
#if defined(SPI_FLASH)
|
||||
ST_CLEAR_FLASH_CHECK,
|
||||
ST_CLEAR_FLASH,
|
||||
#endif
|
||||
ST_RADIO_MENU,
|
||||
ST_REBOOT,
|
||||
};
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "drivers/frftl.h"
|
||||
|
||||
static FrFTL _frftl;
|
||||
static bool frftlInitDone = false;
|
||||
|
||||
static bool flashRead(uint32_t addr, uint8_t* buf, uint32_t len)
|
||||
{
|
||||
|
@ -89,6 +90,7 @@ static DSTATUS spi_flash_initialize(BYTE lun)
|
|||
if (!ftlInit(&_frftl, &_frftl_cb, flashSizeMB)) {
|
||||
return STA_NOINIT;
|
||||
}
|
||||
frftlInitDone = true;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
@ -102,7 +104,7 @@ static DSTATUS spi_flash_status (BYTE lun)
|
|||
static DRESULT spi_flash_read(BYTE lun, BYTE * buff, DWORD sector, UINT count)
|
||||
{
|
||||
#if defined(USE_FLASH_FTL)
|
||||
while(count) {
|
||||
while(frftlInitDone && count) {
|
||||
|
||||
if(!ftlRead(&_frftl, sector, (uint8_t*)buff)) {
|
||||
return RES_ERROR;
|
||||
|
@ -122,7 +124,7 @@ static DRESULT spi_flash_read(BYTE lun, BYTE * buff, DWORD sector, UINT count)
|
|||
static DRESULT spi_flash_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
|
||||
{
|
||||
#if defined(USE_FLASH_FTL)
|
||||
if (!ftlWrite(&_frftl, sector, count, (uint8_t*)buff)) {
|
||||
if (frftlInitDone && !ftlWrite(&_frftl, sector, count, (uint8_t*)buff)) {
|
||||
return RES_ERROR;
|
||||
}
|
||||
#else
|
||||
|
@ -166,7 +168,7 @@ static DRESULT spi_flash_ioctl(BYTE lun, BYTE ctrl, void *buff)
|
|||
|
||||
case CTRL_SYNC:
|
||||
#if defined(USE_FLASH_FTL)
|
||||
if (!ftlSync(&_frftl)) {
|
||||
if (frftlInitDone && !ftlSync(&_frftl)) {
|
||||
res = RES_ERROR;
|
||||
}
|
||||
#else
|
||||
|
@ -176,7 +178,7 @@ static DRESULT spi_flash_ioctl(BYTE lun, BYTE ctrl, void *buff)
|
|||
|
||||
case CTRL_TRIM:
|
||||
#if defined(USE_FLASH_FTL)
|
||||
if (!ftlTrim(&_frftl, *(DWORD*)buff, 1 + *((DWORD*)buff + 1) - *(DWORD*)buff)) {
|
||||
if (frftlInitDone && !ftlTrim(&_frftl, *(DWORD*)buff, 1 + *((DWORD*)buff + 1) - *(DWORD*)buff)) {
|
||||
res = RES_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -38,9 +38,11 @@ void pwrInit()
|
|||
#endif
|
||||
|
||||
// Internal module power
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
INTERNAL_MODULE_OFF();
|
||||
GPIO_InitStructure.GPIO_Pin = INTMODULE_PWR_GPIO_PIN;
|
||||
GPIO_Init(INTMODULE_PWR_GPIO, &GPIO_InitStructure);
|
||||
#endif
|
||||
|
||||
// External module power
|
||||
EXTERNAL_MODULE_PWR_OFF();
|
||||
|
|
|
@ -223,10 +223,19 @@ static bool flash_read_sfdp(SpiFlashDescriptor* desc)
|
|||
return true;
|
||||
}
|
||||
|
||||
void flashSpiSync()
|
||||
{
|
||||
uint8_t status;
|
||||
do {
|
||||
flash_do_cmd(FLASH_CMD_STATUS, 0, &status, 1);
|
||||
} while (status & 0x01);
|
||||
}
|
||||
|
||||
bool flashSpiInit(void)
|
||||
{
|
||||
stm32_spi_init(&_flash_spi);
|
||||
delay_ms(1);
|
||||
flashSpiSync();
|
||||
|
||||
if (!flash_read_id(&_flashDescriptor)) {
|
||||
return false;
|
||||
|
@ -239,14 +248,6 @@ bool flashSpiInit(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
void flashSpiSync()
|
||||
{
|
||||
uint8_t status;
|
||||
do {
|
||||
flash_do_cmd(FLASH_CMD_STATUS, 0, &status, 1);
|
||||
} while (status & 0x01);
|
||||
}
|
||||
|
||||
uint32_t flashSpiGetSize()
|
||||
{
|
||||
return (1UL << _flashDescriptor.log2Size);
|
||||
|
|
|
@ -26,9 +26,10 @@
|
|||
|
||||
#include "opentx.h"
|
||||
|
||||
#define ADC_COMMON ((ADC_Common_TypeDef *) ADC_BASE)
|
||||
#define MAX_ADC_INPUTS 32
|
||||
#define OVERSAMPLING 4
|
||||
#define ADC_COMMON ((ADC_Common_TypeDef *)ADC_BASE)
|
||||
#define OVERSAMPLING 4
|
||||
|
||||
#define SAMPLING_TIMEOUT_US 500
|
||||
|
||||
// Please note that we use the same prio for DMA TC and ADC IRQs
|
||||
// to avoid issues with preemption between these 2
|
||||
|
@ -43,7 +44,7 @@ static volatile uint32_t _adc_inhibit_mask;
|
|||
static uint16_t _adc_dma_buffer[MAX_ADC_INPUTS] __DMA;
|
||||
|
||||
// ADCs started
|
||||
static uint8_t _adc_started_mask;
|
||||
static volatile uint8_t _adc_started_mask;
|
||||
static volatile uint8_t _adc_completed;
|
||||
|
||||
static const stm32_adc_t* _adc_ADCs;
|
||||
|
@ -532,8 +533,14 @@ void stm32_hal_adc_wait_completion(const stm32_adc_t* ADCs, uint8_t n_ADC,
|
|||
(void)inputs;
|
||||
(void)n_inputs;
|
||||
|
||||
auto timeout = timersGetUsTick();
|
||||
while(!_adc_completed) {
|
||||
// busy wait
|
||||
if ((uint32_t)(timersGetUsTick() - timeout) >= SAMPLING_TIMEOUT_US) {
|
||||
TRACE("ADC timeout");
|
||||
_adc_started_mask = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -572,8 +579,7 @@ static void _adc_chain_conversions(const stm32_adc_t* adc)
|
|||
void stm32_hal_adc_dma_isr(const stm32_adc_t* adc)
|
||||
{
|
||||
// Disable IRQ
|
||||
auto dma_stream = _dma_get_stream(adc->DMAx, adc->DMA_Stream);
|
||||
CLEAR_BIT(dma_stream->CR, DMA_SxCR_TCIE | DMA_SxCR_TEIE | DMA_SxCR_DMEIE);
|
||||
adc_dma_clear_flags(adc->DMAx, adc->DMA_Stream);
|
||||
|
||||
uint16_t* dma_buffer = _adc_dma_buffer + adc->offset;
|
||||
copy_adc_values(dma_buffer, adc, _adc_inputs);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "stm32_hal_ll.h"
|
||||
#include "hal/adc_driver.h"
|
||||
|
||||
#define MAX_ADC_INPUTS 32
|
||||
|
||||
struct stm32_adc_input_t {
|
||||
GPIO_TypeDef* GPIOx;
|
||||
|
|
|
@ -49,7 +49,8 @@ void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev)
|
|||
|
||||
GPIO_PinAFConfig(USB_GPIO, USB_GPIO_PinSource_DM, USB_GPIO_AF);
|
||||
GPIO_PinAFConfig(USB_GPIO, USB_GPIO_PinSource_DP, USB_GPIO_AF);
|
||||
|
||||
|
||||
#if defined(USB_GPIO_PIN_VBUS)
|
||||
/* Configure VBUS Pin */
|
||||
GPIO_InitStructure.GPIO_Pin = USB_GPIO_PIN_VBUS;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
|
@ -57,6 +58,7 @@ void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev)
|
|||
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
|
||||
GPIO_Init(USB_GPIO, &GPIO_InitStructure);
|
||||
#endif
|
||||
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
|
||||
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_OTG_FS, ENABLE) ;
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include "stm32f2xx.h"
|
||||
#endif
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
/* USB Core and PHY interface configuration.
|
||||
Tip: To avoid modifying these defines each time you need to change the USB
|
||||
configuration, you can declare the needed define in your toolchain
|
||||
|
@ -97,7 +99,9 @@
|
|||
#endif
|
||||
|
||||
/****************** USB OTG MISC CONFIGURATION ********************************/
|
||||
#if defined(USB_GPIO_PIN_VBUS)
|
||||
#define VBUS_SENSING_ENABLED
|
||||
#endif
|
||||
|
||||
/****************** USB OTG MODE CONFIGURATION ********************************/
|
||||
//#define USE_HOST_MODE
|
||||
|
|
|
@ -57,6 +57,7 @@ void setSelectedUsbMode(int mode)
|
|||
selectedUsbMode = usbMode(mode);
|
||||
}
|
||||
|
||||
#if defined(USB_GPIO_PIN_VBUS)
|
||||
int usbPlugged()
|
||||
{
|
||||
static uint8_t debouncedState = 0;
|
||||
|
@ -71,6 +72,7 @@ int usbPlugged()
|
|||
|
||||
return debouncedState;
|
||||
}
|
||||
#endif
|
||||
|
||||
USB_OTG_CORE_HANDLE USB_OTG_dev;
|
||||
|
||||
|
|
|
@ -158,7 +158,6 @@ add_definitions(-DPCBHORUS -DSTM32F429_439xx -DSTM32F429xx -DSDRAM -DCCMRAM -DCO
|
|||
add_definitions(-DEEPROM_VARIANT=0 -DAUDIO -DVOICE -DRTCLOCK)
|
||||
add_definitions(-DGPS_USART_BAUDRATE=${INTERNAL_GPS_BAUDRATE})
|
||||
add_definitions(-DPWR_BUTTON_${PWR_BUTTON})
|
||||
add_definitions(-DHARDWARE_TRAINER_JACK)
|
||||
add_definitions(-DSTM32_SUPPORT_32BIT_TIMERS)
|
||||
|
||||
set(SDRAM ON)
|
||||
|
|
|
@ -19,7 +19,6 @@ set(BITMAPS_DIR 480x272)
|
|||
set(HARDWARE_EXTERNAL_MODULE YES)
|
||||
|
||||
set(TARGET_DIR nv14)
|
||||
add_definitions(-DHARDWARE_TRAINER_JACK)
|
||||
|
||||
set(RTC_BACKUP_RAM YES)
|
||||
set(PPM_LIMITS_SYMETRICAL YES)
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#include "flysky_gimbal_driver.h"
|
||||
#include "timers_driver.h"
|
||||
|
||||
#include "lcd_driver.h"
|
||||
#include "lcd_driver.h"
|
||||
#include "battery_driver.h"
|
||||
#include "touch_driver.h"
|
||||
|
@ -73,7 +72,8 @@ void delay_self(int count)
|
|||
for (; count > 0; count--);
|
||||
}
|
||||
}
|
||||
#define RCC_AHB1PeriphMinimum (PWR_RCC_AHB1Periph |\
|
||||
|
||||
#define RCC_AHB1PeriphMinimum (PWR_RCC_AHB1Periph | \
|
||||
LCD_RCC_AHB1Periph |\
|
||||
BACKLIGHT_RCC_AHB1Periph |\
|
||||
SDRAM_RCC_AHB1Periph \
|
||||
|
|
|
@ -115,25 +115,17 @@ extern HardwareOptions hardwareOptions;
|
|||
#endif // defined(SIMU)
|
||||
|
||||
#define EXTERNAL_MODULE_PWR_OFF EXTERNAL_MODULE_OFF
|
||||
#define IS_UART_MODULE(port) (port == INTERNAL_MODULE)
|
||||
#define IS_PXX2_INTERNAL_ENABLED() (false)
|
||||
|
||||
#if !defined(NUM_FUNCTIONS_SWITCHES)
|
||||
#define NUM_FUNCTIONS_SWITCHES 0
|
||||
#endif
|
||||
|
||||
#define NUM_TRIMS_KEYS (NUM_TRIMS * 2)
|
||||
|
||||
#define DEFAULT_STICK_DEADZONE 2
|
||||
|
||||
// 2 pots without detent
|
||||
#define DEFAULT_POTS_CONFIG \
|
||||
(POT_WITHOUT_DETENT << 0) + \
|
||||
(POT_WITHOUT_DETENT << 2)
|
||||
#define DEFAULT_STICK_DEADZONE 2
|
||||
|
||||
#define BATTERY_WARN 36 // 3.6V
|
||||
#define BATTERY_MIN 35 // 3.5V
|
||||
#define BATTERY_MAX 42 // 4.2V
|
||||
#define BATTERY_DIVIDER 2942
|
||||
|
||||
#if defined(__cplusplus) && !defined(SIMU)
|
||||
extern "C" {
|
||||
|
@ -275,6 +267,4 @@ bool touchPanelEventOccured();
|
|||
struct TouchState touchPanelRead();
|
||||
struct TouchState getInternalTouchState();
|
||||
|
||||
#define BATTERY_DIVIDER 2942
|
||||
|
||||
#endif // _BOARD_H_
|
||||
|
|
167
radio/src/targets/pl18/CMakeLists.txt
Normal file
|
@ -0,0 +1,167 @@
|
|||
option(UNEXPECTED_SHUTDOWN "Enable the Unexpected Shutdown screen" ON)
|
||||
option(PXX1 "PXX1 protocol support" ON)
|
||||
option(PXX2 "PXX2 protocol support" OFF)
|
||||
option(AFHDS3 "AFHDS3 TX Module" ON)
|
||||
option(MULTIMODULE "DIY Multiprotocol TX Module (https://github.com/pascallanger/DIY-Multiprotocol-TX-Module)" ON)
|
||||
option(GHOST "Ghost TX Module" ON)
|
||||
option(MODULE_SIZE_STD "Standard size TX Module" ON)
|
||||
option(LUA_MIXER "Enable LUA mixer/model scripts support" ON)
|
||||
|
||||
set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)")
|
||||
set(CPU_TYPE STM32F4)
|
||||
set(HSE_VALUE 12000000)
|
||||
set(SDCARD YES)
|
||||
set(STORAGE_MODELSLIST YES)
|
||||
set(HAPTIC YES)
|
||||
set(GUI_DIR colorlcd)
|
||||
set(BITMAPS_DIR 480x272)
|
||||
set(TARGET_DIR pl18)
|
||||
set(LINKER_SCRIPT targets/pl18/stm32f4_flash.ld)
|
||||
set(RTC_BACKUP_RAM YES)
|
||||
set(PPM_LIMITS_SYMETRICAL YES)
|
||||
set(USB_SERIAL ON CACHE BOOL "Enable USB serial (CDC)")
|
||||
set(HARDWARE_EXTERNAL_MODULE YES)
|
||||
set(WIRELESS_CHARGER YES)
|
||||
|
||||
#option(STICKS_DEAD_ZONE "Enable sticks dead zone" YES)
|
||||
#option(AFHDS2 "Support for AFHDS2" OFF)
|
||||
|
||||
# for size report script
|
||||
set(CPU_TYPE_FULL STM32F429xI)
|
||||
set(TARGET_LINKER_DIR stm32f429_sdram)
|
||||
set(TARGET_LINKER_PARAMS "-Wl,--defsym=__SDRAM_START__=0xC0000000")
|
||||
set(SIZE_TARGET_MEM_DEFINE "MEM_SIZE_SDRAM1=8192")
|
||||
|
||||
#set(RF_BAUD_RATE 921600 230400 115200 57600 38400 19200 9600 4800 2400 1200)
|
||||
#set(PCB_RF_BAUD 921600 CACHE STRING "INTERNAL_MODULE_BAUDRATE: ${RF_BAUD_RATE}")
|
||||
#set_property(CACHE PCB_RF_BAUD PROPERTY STRINGS ${RF_BAUD_RATE})
|
||||
|
||||
add_definitions(-DPCBPL18 -DPCBFLYSKY)
|
||||
add_definitions(-DBATTERY_CHARGE)
|
||||
add_definitions(-DSOFTWARE_VOLUME)
|
||||
add_definitions(-DSPI_FLASH)
|
||||
add_definitions(-DSTM32_SUPPORT_32BIT_TIMERS)
|
||||
|
||||
if(PCBREV STREQUAL PL18EV)
|
||||
set(FLAVOUR pl18ev)
|
||||
add_definitions(-DRADIO_PL18EV)
|
||||
else()
|
||||
set(FLAVOUR pl18)
|
||||
add_definitions(-DRADIO_PL18)
|
||||
|
||||
# Defines internal modules for PL18 via UART7
|
||||
set(INTERNAL_MODULES MULTI CACHE STRING "Internal modules")
|
||||
set(DEFAULT_INTERNAL_MODULE MULTIMODULE CACHE STRING "Default internal module")
|
||||
endif()
|
||||
|
||||
set(BITMAPS_TARGET pl18_bitmaps)
|
||||
set(FONTS_TARGET x12_fonts)
|
||||
set(LCD_DRIVER lcd_driver.cpp)
|
||||
set(TOUCH_DRIVER touch_driver.cpp)
|
||||
set(HARDWARE_TOUCH YES)
|
||||
set(RADIO_DEPENDENCIES ${RADIO_DEPENDENCIES} ${BITMAPS_TARGET})
|
||||
set(FIRMWARE_DEPENDENCIES datacopy)
|
||||
|
||||
set(HARDWARE_TOUCH ON)
|
||||
set(SOFTWARE_KEYBOARD ON)
|
||||
set(FLYSKY_GIMBAL ON)
|
||||
|
||||
add_definitions(
|
||||
-DSTM32F429_439xx -DSTM32F429xx
|
||||
-DSDRAM -DCCMRAM -DCOLORLCD -DLIBOPENUI
|
||||
-DHARDWARE_TOUCH -DHARDWARE_KEYS
|
||||
-DSOFTWARE_KEYBOARD -DUSE_HATS_AS_KEYS)
|
||||
|
||||
set(SDRAM ON)
|
||||
|
||||
add_definitions(-DEEPROM_VARIANT=0 -DAUDIO -DVOICE -DRTCLOCK)
|
||||
add_definitions(-DGPS_USART_BAUDRATE=${INTERNAL_GPS_BAUDRATE})
|
||||
add_definitions(-DPWR_BUTTON_${PWR_BUTTON})
|
||||
add_definitions(-DCROSSFIRE_NATIVE)
|
||||
add_definitions(-DHARDWARE_EXTERNAL_MODULE)
|
||||
|
||||
if(WIRELESS_CHARGER)
|
||||
add_definitions(-DWIRELESS_CHARGER)
|
||||
endif()
|
||||
|
||||
if(STICKS_DEAD_ZONE)
|
||||
add_definitions(-DSTICK_DEAD_ZONE)
|
||||
endif()
|
||||
|
||||
if(NOT UNEXPECTED_SHUTDOWN)
|
||||
add_definitions(-DNO_UNEXPECTED_SHUTDOWN)
|
||||
endif()
|
||||
|
||||
set(AFHDS3 ON)
|
||||
|
||||
# VCP CLI
|
||||
set(ENABLE_SERIAL_PASSTHROUGH ON CACHE BOOL "Enable serial passthrough")
|
||||
set(CLI ON CACHE BOOL "Enable CLI")
|
||||
|
||||
include_directories(${RADIO_SRC_DIR}/fonts/colorlcd gui/${GUI_DIR} gui/${GUI_DIR}/layouts)
|
||||
|
||||
file(GLOB THEMES_SRC RELATIVE ${RADIO_SRC_DIR}/gui/colorlcd ${RADIO_SRC_DIR}/gui/colorlcd/themes/*.cpp)
|
||||
file(GLOB LAYOUTS_SRC RELATIVE ${RADIO_SRC_DIR}/gui/colorlcd ${RADIO_SRC_DIR}/gui/colorlcd/layouts/*.cpp)
|
||||
file(GLOB WIDGETS_SRC RELATIVE ${RADIO_SRC_DIR}/gui/colorlcd ${RADIO_SRC_DIR}/gui/colorlcd/widgets/*.cpp)
|
||||
|
||||
set(SRC
|
||||
${SRC}
|
||||
io/frsky_firmware_update.cpp
|
||||
)
|
||||
|
||||
set(GVAR_SCREEN model_gvars.cpp)
|
||||
|
||||
if(BOOTLOADER)
|
||||
set(FIRMWARE_TARGET_SRC
|
||||
${FIRMWARE_TARGET_SRC}
|
||||
../common/arm/loadboot.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
set(SRC
|
||||
${SRC}
|
||||
io/frsky_firmware_update.cpp
|
||||
io/multi_firmware_update.cpp
|
||||
)
|
||||
|
||||
if (MULTIMODULE)
|
||||
add_definitions(-DMULTI_PROTOLIST)
|
||||
set(SRC ${SRC}
|
||||
io/multi_protolist.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
set(FIRMWARE_TARGET_SRC
|
||||
${FIRMWARE_TARGET_SRC}
|
||||
${LCD_DRIVER}
|
||||
${TOUCH_DRIVER}
|
||||
board.cpp
|
||||
key_driver.cpp
|
||||
battery_driver.cpp
|
||||
backlight_driver.cpp
|
||||
led_driver.cpp
|
||||
sdram_driver.c
|
||||
)
|
||||
|
||||
set(FIRMWARE_SRC
|
||||
${FIRMWARE_SRC}
|
||||
targets/common/arm/stm32/audio_dac_driver.cpp
|
||||
targets/common/arm/stm32/dma2d.cpp
|
||||
targets/common/arm/stm32/spi_flash.cpp
|
||||
targets/common/arm/stm32/diskio_spi_flash.cpp
|
||||
targets/common/arm/stm32/stm32_ws2812.cpp
|
||||
boards/generic_stm32/rgb_leds.cpp
|
||||
drivers/frftl.cpp
|
||||
)
|
||||
|
||||
# Make malloc() thread-safe
|
||||
add_definitions(-DTHREADSAFE_MALLOC)
|
||||
|
||||
set(STM32LIB_SRC
|
||||
STM32F4xx_StdPeriph_Driver/src/stm32f4xx_sdio.c
|
||||
STM32F4xx_StdPeriph_Driver/src/stm32f4xx_fmc.c
|
||||
STM32F4xx_StdPeriph_Driver/src/stm32f4xx_ltdc.c
|
||||
STM32F4xx_StdPeriph_Driver/src/stm32f4xx_tim.c
|
||||
STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dma2d.c
|
||||
)
|
||||
|
95
radio/src/targets/pl18/backlight_driver.cpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "opentx_types.h"
|
||||
#include "board.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "lcd_driver.h"
|
||||
|
||||
void backlightLowInit( void )
|
||||
{
|
||||
RCC_AHB1PeriphClockCmd(BACKLIGHT_RCC_AHB1Periph, ENABLE);
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = BACKLIGHT_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
|
||||
GPIO_Init(BACKLIGHT_GPIO, &GPIO_InitStructure);
|
||||
GPIO_WriteBit( BACKLIGHT_GPIO, BACKLIGHT_GPIO_PIN, Bit_RESET );
|
||||
}
|
||||
|
||||
void backlightInit()
|
||||
{
|
||||
// PIN init
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = BACKLIGHT_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(BACKLIGHT_GPIO, &GPIO_InitStructure);
|
||||
GPIO_PinAFConfig(BACKLIGHT_GPIO, BACKLIGHT_GPIO_PinSource, BACKLIGHT_GPIO_AF);
|
||||
|
||||
// TODO review this when the timer will be chosen
|
||||
BACKLIGHT_TIMER->ARR = 100;
|
||||
BACKLIGHT_TIMER->PSC = BACKLIGHT_TIMER_FREQ / 1000000 - 1; // 10kHz (same as FrOS)
|
||||
BACKLIGHT_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1PE; // PWM mode 1
|
||||
BACKLIGHT_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1NE;
|
||||
BACKLIGHT_TIMER->CCR1 = 100; // 100% on init
|
||||
BACKLIGHT_TIMER->EGR = TIM_EGR_UG;
|
||||
BACKLIGHT_TIMER->CR1 |= TIM_CR1_CEN; // Counter enable
|
||||
BACKLIGHT_TIMER->BDTR |= TIM_BDTR_MOE;
|
||||
}
|
||||
|
||||
uint8_t lastDutyCycle = 0;
|
||||
|
||||
void backlightEnable(uint8_t dutyCycle)
|
||||
{
|
||||
BACKLIGHT_TIMER->CCR1 = dutyCycle;
|
||||
if(!dutyCycle) {
|
||||
//experimental to turn off LCD when no backlight
|
||||
if(lcdOffFunction) lcdOffFunction();
|
||||
}
|
||||
else if(!lastDutyCycle) {
|
||||
if(lcdOnFunction) lcdOnFunction();
|
||||
else lcdInit();
|
||||
}
|
||||
lastDutyCycle = dutyCycle;
|
||||
}
|
||||
|
||||
void lcdOff() {
|
||||
backlightEnable(0);
|
||||
}
|
||||
|
||||
void lcdOn(){
|
||||
if(lcdOnFunction) lcdOnFunction();
|
||||
else lcdInit();
|
||||
backlightEnable(BACKLIGHT_LEVEL_MAX);
|
||||
}
|
||||
|
||||
bool boardBacklightOn;
|
||||
|
||||
bool isBacklightEnabled()
|
||||
{
|
||||
return boardBacklightOn;
|
||||
}
|
436
radio/src/targets/pl18/battery_driver.cpp
Normal file
|
@ -0,0 +1,436 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
#include "battery_driver.h"
|
||||
|
||||
#define __BATTERY_DRIVER_C__
|
||||
|
||||
#define BATTERY_W 140
|
||||
#define BATTERY_H 200
|
||||
#define BATTERY_TOP ((LCD_H - BATTERY_H)/2)
|
||||
#define BATTERY_CONNECTOR_W 32
|
||||
#define BATTERY_CONNECTOR_H 10
|
||||
#define BATTERY_BORDER 4
|
||||
#define BATTERY_W_INNER (BATTERY_W - 2*BATTERY_BORDER)
|
||||
#define BATTERY_H_INNER (BATTERY_H - 2*BATTERY_BORDER)
|
||||
#define BATTERY_TOP_INNER (BATTERY_TOP + BATTERY_BORDER)
|
||||
|
||||
#define UCHARGER_SAMPLING_CNT 10
|
||||
#define UCHARGER_CHARGING_SAMPLING_CNT 10
|
||||
#define WCHARGER_SAMPLING_CNT 30
|
||||
#define WCHARGER_CHARGING_SAMPLING_CNT 10
|
||||
#define WCHARGER_LOW_CURRENT_DELAY_CNT 6000
|
||||
#define WCHARGER_HIGH_CURRENT_DELAY_CNT 24000
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool hasCharger : 1;
|
||||
bool isChargeEnd : 1;
|
||||
bool isChargerDetectionReady : 1;
|
||||
bool isChargingDetectionReady : 1;
|
||||
bool isHighCurrent : 1;
|
||||
uint8_t chargerSamplingCount;
|
||||
uint8_t chargingSamplingCount;
|
||||
uint8_t chargeEndSamplingCount;
|
||||
} STRUCT_BATTERY_CHARGER;
|
||||
|
||||
STRUCT_BATTERY_CHARGER uCharger; // USB charger
|
||||
#if defined(WIRELESS_CHARGER)
|
||||
STRUCT_BATTERY_CHARGER wCharger; // Wireless charger
|
||||
uint16_t wirelessLowCurrentDelay = 0;
|
||||
uint16_t wirelessHighCurrentDelay = 0;
|
||||
#endif
|
||||
|
||||
void chargerDetection(STRUCT_BATTERY_CHARGER* charger, uint8_t chargerPinActive, uint8_t samplingCountThreshold)
|
||||
{
|
||||
if ((charger->hasCharger && chargerPinActive) || (!charger->hasCharger && !chargerPinActive))
|
||||
{
|
||||
charger->chargerSamplingCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
charger->chargerSamplingCount++;
|
||||
if (charger->chargerSamplingCount >= samplingCountThreshold)
|
||||
{
|
||||
charger->chargerSamplingCount = 0;
|
||||
charger->hasCharger = !charger->hasCharger;
|
||||
charger->isChargerDetectionReady = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void resetChargeEndDetection(STRUCT_BATTERY_CHARGER* charger)
|
||||
{
|
||||
charger->isChargeEnd = false;
|
||||
charger->isChargingDetectionReady = false;
|
||||
charger->chargingSamplingCount = 0;
|
||||
charger->isHighCurrent = false;
|
||||
}
|
||||
|
||||
void chargeEndDetection(STRUCT_BATTERY_CHARGER* charger, uint8_t chargeEndPinActive, uint8_t samplingCountThreshold)
|
||||
{
|
||||
if (charger->isChargeEnd)
|
||||
{
|
||||
if (chargeEndPinActive)
|
||||
{
|
||||
charger->chargingSamplingCount = 0;
|
||||
if (charger->isChargingDetectionReady)
|
||||
{
|
||||
charger->chargeEndSamplingCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
charger->chargeEndSamplingCount++;
|
||||
if (charger->chargeEndSamplingCount >= samplingCountThreshold)
|
||||
{
|
||||
charger->chargeEndSamplingCount = 0;
|
||||
charger->isChargingDetectionReady = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
charger->chargeEndSamplingCount = 0;
|
||||
charger->chargingSamplingCount++;
|
||||
if (charger->chargingSamplingCount >= samplingCountThreshold)
|
||||
{
|
||||
charger->chargingSamplingCount = 0;
|
||||
charger->isChargeEnd = false;
|
||||
charger->isChargingDetectionReady = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!chargeEndPinActive)
|
||||
{
|
||||
charger->chargeEndSamplingCount = 0;
|
||||
if (charger->isChargingDetectionReady)
|
||||
{
|
||||
charger->chargingSamplingCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
charger->chargingSamplingCount++;
|
||||
if (charger->chargingSamplingCount >= samplingCountThreshold)
|
||||
{
|
||||
charger->chargingSamplingCount = 0;
|
||||
charger->isChargingDetectionReady = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
charger->chargingSamplingCount = 0;
|
||||
charger->chargeEndSamplingCount++;
|
||||
if (charger->chargeEndSamplingCount >= samplingCountThreshold)
|
||||
{
|
||||
charger->chargeEndSamplingCount = 0;
|
||||
charger->isChargeEnd = true;
|
||||
charger->isChargingDetectionReady = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t get_battery_charge_state()
|
||||
{
|
||||
uint16_t state = CHARGE_UNKNOWN;
|
||||
|
||||
chargerDetection(&uCharger, IS_UCHARGER_ACTIVE(), UCHARGER_SAMPLING_CNT);
|
||||
if (uCharger.isChargerDetectionReady)
|
||||
{
|
||||
if (uCharger.hasCharger) // USB charger can be detected properly no matter it is enabled or not
|
||||
{
|
||||
ENABLE_UCHARGER();
|
||||
chargeEndDetection(&uCharger, IS_UCHARGER_CHARGE_END_ACTIVE(), UCHARGER_CHARGING_SAMPLING_CNT);
|
||||
if (uCharger.isChargingDetectionReady)
|
||||
{
|
||||
if (uCharger.isChargeEnd)
|
||||
{
|
||||
state = CHARGE_FINISHED;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = CHARGE_STARTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resetChargeEndDetection(&uCharger);
|
||||
|
||||
// Disable USB charger if it is not present, so that wireless charger can be detected properly
|
||||
DISABLE_UCHARGER();
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(WIRELESS_CHARGER)
|
||||
chargerDetection(&wCharger, IS_WCHARGER_ACTIVE(), WCHARGER_SAMPLING_CNT);
|
||||
if (wCharger.isChargerDetectionReady)
|
||||
{
|
||||
if (wCharger.hasCharger) // Wireless charger can only be detected when USB charger is disabled
|
||||
{
|
||||
chargeEndDetection(&wCharger, IS_WCHARGER_CHARGE_END_ACTIVE(), WCHARGER_CHARGING_SAMPLING_CNT);
|
||||
if (wCharger.isChargingDetectionReady)
|
||||
{
|
||||
if (wCharger.isChargeEnd)
|
||||
{
|
||||
state = CHARGE_FINISHED;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = CHARGE_STARTED;
|
||||
}
|
||||
}
|
||||
|
||||
// Charge current control
|
||||
wirelessLowCurrentDelay = 0;
|
||||
if (wirelessHighCurrentDelay >= WCHARGER_HIGH_CURRENT_DELAY_CNT)
|
||||
{
|
||||
wCharger.isHighCurrent = true;
|
||||
WCHARGER_CURRENT_HIGH();
|
||||
}
|
||||
else
|
||||
{
|
||||
wirelessHighCurrentDelay++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resetChargeEndDetection(&wCharger);
|
||||
|
||||
// Charge current control
|
||||
wirelessHighCurrentDelay = 0;
|
||||
if (wirelessLowCurrentDelay >= WCHARGER_LOW_CURRENT_DELAY_CNT)
|
||||
{
|
||||
wCharger.isHighCurrent = false;
|
||||
WCHARGER_CURRENT_LOW();
|
||||
}
|
||||
else
|
||||
{
|
||||
wirelessLowCurrentDelay++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
bool isChargerActive()
|
||||
{
|
||||
#if defined(WIRELESS_CHARGER)
|
||||
while (!(uCharger.isChargerDetectionReady && wCharger.isChargerDetectionReady))
|
||||
{
|
||||
get_battery_charge_state();
|
||||
delay_ms(10);
|
||||
}
|
||||
return uCharger.hasCharger || wCharger.hasCharger;
|
||||
#else
|
||||
while (!uCharger.isChargerDetectionReady)
|
||||
{
|
||||
get_battery_charge_state();
|
||||
delay_ms(10);
|
||||
}
|
||||
return uCharger.hasCharger;
|
||||
#endif
|
||||
}
|
||||
|
||||
void battery_charge_init()
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
// Input pins
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
|
||||
// USB charger status pins
|
||||
GPIO_InitStructure.GPIO_Pin = UCHARGER_GPIO_PIN;
|
||||
GPIO_Init(UCHARGER_GPIO, &GPIO_InitStructure);
|
||||
GPIO_InitStructure.GPIO_Pin = UCHARGER_CHARGE_END_GPIO_PIN;
|
||||
GPIO_Init(UCHARGER_CHARGE_END_GPIO, &GPIO_InitStructure);
|
||||
|
||||
#if defined(WIRELESS_CHARGER)
|
||||
// Wireless charger status pins
|
||||
GPIO_InitStructure.GPIO_Pin = WCHARGER_GPIO_PIN;
|
||||
GPIO_Init(WCHARGER_GPIO, &GPIO_InitStructure);
|
||||
GPIO_InitStructure.GPIO_Pin = WCHARGER_CHARGE_END_GPIO_PIN;
|
||||
GPIO_Init(WCHARGER_CHARGE_END_GPIO, &GPIO_InitStructure);
|
||||
#endif
|
||||
|
||||
// Output pins
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
|
||||
// USB charger control pins
|
||||
GPIO_InitStructure.GPIO_Pin = UCHARGER_EN_GPIO_PIN;
|
||||
GPIO_Init(UCHARGER_EN_GPIO, &GPIO_InitStructure);
|
||||
|
||||
// USB charger state init
|
||||
ENABLE_UCHARGER();
|
||||
uCharger.hasCharger = !IS_UCHARGER_ACTIVE(); // Init for sampling count works
|
||||
uCharger.isChargerDetectionReady = false;
|
||||
resetChargeEndDetection(&uCharger);
|
||||
|
||||
#if defined(WIRELESS_CHARGER)
|
||||
// Wireless charger control pins
|
||||
GPIO_InitStructure.GPIO_Pin = WCHARGER_EN_GPIO_PIN;
|
||||
GPIO_Init(WCHARGER_EN_GPIO, &GPIO_InitStructure);
|
||||
GPIO_InitStructure.GPIO_Pin = WCHARGER_I_CONTROL_GPIO_PIN;
|
||||
GPIO_Init(WCHARGER_I_CONTROL_GPIO, &GPIO_InitStructure);
|
||||
|
||||
// Wireless charger state init
|
||||
ENABLE_WCHARGER();
|
||||
WCHARGER_CURRENT_LOW();
|
||||
wCharger.hasCharger = !IS_WCHARGER_ACTIVE(); // Init for sampling count works
|
||||
wCharger.isChargerDetectionReady = false;
|
||||
resetChargeEndDetection(&wCharger);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void drawChargingInfo(uint16_t chargeState) {
|
||||
static int progress = 0;
|
||||
const char* text = chargeState == CHARGE_STARTED ? STR_BATTERYCHARGING : STR_BATTERYFULL;
|
||||
int h = 0;
|
||||
LcdFlags color = 0;
|
||||
if (CHARGE_STARTED == chargeState)
|
||||
{
|
||||
if (progress >= 100)
|
||||
{
|
||||
progress = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
progress += 25;
|
||||
}
|
||||
text = STR_BATTERYCHARGING;
|
||||
h = ((BATTERY_H_INNER * progress) / 100);
|
||||
color = COLOR_THEME_EDIT;
|
||||
}
|
||||
else if (CHARGE_FINISHED == chargeState)
|
||||
{
|
||||
text = STR_BATTERYFULL;
|
||||
h = BATTERY_H_INNER;
|
||||
color = COLOR_THEME_EDIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
text = STR_BATTERYNONE;
|
||||
h = BATTERY_H_INNER;
|
||||
color = COLOR_THEME_PRIMARY1;
|
||||
}
|
||||
|
||||
BACKLIGHT_ENABLE();
|
||||
lcd->drawSizedText(LCD_W / 2, LCD_H - 50, text, strlen(text), CENTERED | COLOR_THEME_PRIMARY2);
|
||||
|
||||
lcd->drawFilledRect((LCD_W - BATTERY_W) / 2, BATTERY_TOP, BATTERY_W, BATTERY_H, SOLID, COLOR_THEME_PRIMARY2);
|
||||
lcd->drawFilledRect((LCD_W - BATTERY_W_INNER) / 2, BATTERY_TOP_INNER, BATTERY_W_INNER, BATTERY_H_INNER, SOLID, COLOR_THEME_PRIMARY1);
|
||||
|
||||
lcd->drawFilledRect((LCD_W - BATTERY_W_INNER) / 2, BATTERY_TOP_INNER + BATTERY_H_INNER - h, BATTERY_W_INNER, h, SOLID, color);
|
||||
lcd->drawFilledRect((LCD_W - BATTERY_CONNECTOR_W) / 2, BATTERY_TOP - BATTERY_CONNECTOR_H, BATTERY_CONNECTOR_W, BATTERY_CONNECTOR_H, SOLID, COLOR_THEME_PRIMARY2);
|
||||
}
|
||||
#define CHARGE_INFO_DURATION 500
|
||||
|
||||
//this method should be called by timer interrupt or by GPIO interrupt
|
||||
void handle_battery_charge(uint32_t last_press_time)
|
||||
{
|
||||
#if !defined(SIMU)
|
||||
static uint32_t updateTime = 0;
|
||||
static uint16_t lastState = CHARGE_UNKNOWN;
|
||||
static uint32_t info_until = 0;
|
||||
static bool lcdInited = false;
|
||||
|
||||
uint32_t now = get_tmr10ms();
|
||||
uint16_t chargeState = get_battery_charge_state();
|
||||
if (chargeState != CHARGE_UNKNOWN) {
|
||||
|
||||
if (lastState != chargeState) {
|
||||
//avoid positive check when none and unknown
|
||||
if (lastState + chargeState > 1) {
|
||||
//charge state changed - last state known
|
||||
info_until = now + (CHARGE_INFO_DURATION);
|
||||
}
|
||||
}
|
||||
//power buttons pressed
|
||||
else if (now - last_press_time < POWER_ON_DELAY) {
|
||||
info_until = now + CHARGE_INFO_DURATION;
|
||||
}
|
||||
lastState = chargeState;
|
||||
}
|
||||
|
||||
|
||||
if(now > info_until) {
|
||||
info_until = 0;
|
||||
lcd->clear();
|
||||
BACKLIGHT_DISABLE();
|
||||
if(lcdInited) {
|
||||
lcdOff();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (updateTime == 0 || ((get_tmr10ms() - updateTime) >= 50))
|
||||
{
|
||||
if (!lcdInited) {
|
||||
backlightInit();
|
||||
lcdInit();
|
||||
lcdInitDisplayDriver();
|
||||
lcdInited = true;
|
||||
}
|
||||
else {
|
||||
lcdOn();
|
||||
}
|
||||
updateTime = get_tmr10ms();
|
||||
lcdInitDirectDrawing();
|
||||
lcd->clear();
|
||||
drawChargingInfo(chargeState);
|
||||
|
||||
// DEBUG INFO
|
||||
#if 0
|
||||
char buffer[1024];
|
||||
|
||||
sprintf(buffer, "%d,%d,%d,%d", uCharger.isChargerDetectionReady, uCharger.hasCharger, IS_UCHARGER_ACTIVE(), uCharger.chargerSamplingCount);
|
||||
lcd->drawSizedText(100, 10, buffer, strlen(buffer), CENTERED | COLOR_THEME_PRIMARY2);
|
||||
|
||||
sprintf(buffer, "%d,%d,%d,%d,%d,", uCharger.isChargingDetectionReady, uCharger.isChargeEnd, IS_UCHARGER_CHARGE_END_ACTIVE(), uCharger.chargingSamplingCount, uCharger.chargeEndSamplingCount);
|
||||
lcd->drawSizedText(100, 40, buffer, strlen(buffer), CENTERED | COLOR_THEME_PRIMARY2);
|
||||
|
||||
sprintf(buffer, "%d,%d,%d,%d,%d", wCharger.isChargerDetectionReady, wCharger.hasCharger, IS_WCHARGER_ACTIVE(), wCharger.chargerSamplingCount, wCharger.isHighCurrent);
|
||||
lcd->drawSizedText(100, 70, buffer, strlen(buffer), CENTERED | COLOR_THEME_PRIMARY2);
|
||||
|
||||
sprintf(buffer, "%d,%d,%d,%d,%d,", wCharger.isChargingDetectionReady, wCharger.isChargeEnd, IS_WCHARGER_CHARGE_END_ACTIVE(), wCharger.chargingSamplingCount, wCharger.chargeEndSamplingCount);
|
||||
lcd->drawSizedText(100, 100, buffer, strlen(buffer), CENTERED | COLOR_THEME_PRIMARY2);
|
||||
|
||||
sprintf(buffer, "%d", isChargerActive());
|
||||
lcd->drawSizedText(100, 130, buffer, strlen(buffer), CENTERED | COLOR_THEME_PRIMARY2);
|
||||
#endif
|
||||
|
||||
lcdRefresh();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
60
radio/src/targets/pl18/battery_driver.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
/***************************************************************************************************
|
||||
|
||||
***************************************************************************************************/
|
||||
#ifndef __BATTERY_DRIVER_H__
|
||||
#define __BATTERY_DRIVER_H__
|
||||
/***************************************************************************************************
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
#include "board.h"
|
||||
#include "hal.h"
|
||||
|
||||
enum ChargeState
|
||||
{
|
||||
CHARGE_UNKNOWN,
|
||||
CHARGE_NONE,
|
||||
CHARGE_STARTED,
|
||||
CHARGE_FINISHED
|
||||
};
|
||||
|
||||
#define IS_UCHARGER_ACTIVE() GPIO_ReadInputDataBit(UCHARGER_GPIO, UCHARGER_GPIO_PIN)
|
||||
#define IS_UCHARGER_CHARGE_END_ACTIVE() GPIO_ReadInputDataBit(UCHARGER_CHARGE_END_GPIO, UCHARGER_CHARGE_END_GPIO_PIN)
|
||||
#define ENABLE_UCHARGER() GPIO_SetBits(UCHARGER_EN_GPIO, UCHARGER_EN_GPIO_PIN)
|
||||
#define DISABLE_UCHARGER() GPIO_ResetBits(UCHARGER_EN_GPIO, UCHARGER_EN_GPIO_PIN)
|
||||
|
||||
#define IS_WCHARGER_ACTIVE() GPIO_ReadInputDataBit(WCHARGER_GPIO, WCHARGER_GPIO_PIN)
|
||||
#define IS_WCHARGER_CHARGE_END_ACTIVE() GPIO_ReadInputDataBit(WCHARGER_CHARGE_END_GPIO, WCHARGER_CHARGE_END_GPIO_PIN)
|
||||
#define ENABLE_WCHARGER() GPIO_SetBits(WCHARGER_EN_GPIO, WCHARGER_EN_GPIO_PIN)
|
||||
#define DISABLE_WCHARGER() GPIO_ResetBits(WCHARGER_EN_GPIO, WCHARGER_EN_GPIO_PIN)
|
||||
#define WCHARGER_CURRENT_LOW() GPIO_ResetBits(WCHARGER_I_CONTROL_GPIO, WCHARGER_I_CONTROL_GPIO_PIN)
|
||||
#define WCHARGER_CURRENT_HIGH() GPIO_SetBits(WCHARGER_I_CONTROL_GPIO, WCHARGER_I_CONTROL_GPIO_PIN)
|
||||
|
||||
extern void battery_charge_init();
|
||||
extern void handle_battery_charge(uint32_t last_press_time);
|
||||
extern uint16_t get_battery_charge_state();
|
||||
extern uint16_t getBatteryVoltage(); // returns current battery voltage in 10mV steps
|
||||
extern bool isChargerActive();
|
||||
|
||||
#endif
|
261
radio/src/targets/pl18/board.cpp
Normal file
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "stm32_adc.h"
|
||||
|
||||
#include "stm32_ws2812.h"
|
||||
#include "boards/generic_stm32/rgb_leds.h"
|
||||
|
||||
#include "board.h"
|
||||
#include "boards/generic_stm32/module_ports.h"
|
||||
|
||||
#include "hal/adc_driver.h"
|
||||
#include "hal/trainer_driver.h"
|
||||
#include "hal/switch_driver.h"
|
||||
#include "hal/abnormal_reboot.h"
|
||||
#include "hal/watchdog_driver.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "sdcard.h"
|
||||
#include "touch.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "flysky_gimbal_driver.h"
|
||||
#include "timers_driver.h"
|
||||
|
||||
#include "battery_driver.h"
|
||||
#include "touch_driver.h"
|
||||
|
||||
#include "bitmapbuffer.h"
|
||||
#include "colors.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(__cplusplus) && !defined(SIMU)
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "usb_dcd_int.h"
|
||||
#include "usb_bsp.h"
|
||||
#if defined(__cplusplus) && !defined(SIMU)
|
||||
}
|
||||
#endif
|
||||
|
||||
// common ADC driver
|
||||
extern const etx_hal_adc_driver_t _adc_driver;
|
||||
|
||||
#if defined(SEMIHOSTING)
|
||||
extern "C" void initialise_monitor_handles();
|
||||
#endif
|
||||
|
||||
#if defined(SPI_FLASH)
|
||||
extern "C" void flushFTL();
|
||||
#endif
|
||||
|
||||
void delay_self(int count)
|
||||
{
|
||||
for (int i = 50000; i > 0; i--)
|
||||
{
|
||||
for (; count > 0; count--);
|
||||
}
|
||||
}
|
||||
#define RCC_AHB1PeriphMinimum (PWR_RCC_AHB1Periph |\
|
||||
LCD_RCC_AHB1Periph |\
|
||||
BACKLIGHT_RCC_AHB1Periph |\
|
||||
SDRAM_RCC_AHB1Periph \
|
||||
)
|
||||
#define RCC_AHB1PeriphOther (AUDIO_RCC_AHB1Periph |\
|
||||
TELEMETRY_RCC_AHB1Periph |\
|
||||
TRAINER_RCC_AHB1Periph |\
|
||||
HAPTIC_RCC_AHB1Periph |\
|
||||
EXTMODULE_RCC_AHB1Periph \
|
||||
)
|
||||
#define RCC_AHB3PeriphMinimum (SDRAM_RCC_AHB3Periph)
|
||||
#define RCC_APB1PeriphMinimum (BACKLIGHT_RCC_APB1Periph)
|
||||
#define RCC_APB1PeriphOther (TELEMETRY_RCC_APB1Periph |\
|
||||
AUDIO_RCC_APB1Periph \
|
||||
)
|
||||
#define RCC_APB2PeriphMinimum (LCD_RCC_APB2Periph)
|
||||
#define RCC_APB2PeriphOther (HAPTIC_RCC_APB2Periph)
|
||||
|
||||
void boardInit()
|
||||
{
|
||||
#if defined(SEMIHOSTING)
|
||||
initialise_monitor_handles();
|
||||
#endif
|
||||
|
||||
#if !defined(SIMU)
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1PeriphMinimum | RCC_AHB1PeriphOther, ENABLE);
|
||||
RCC_AHB3PeriphClockCmd(RCC_AHB3PeriphMinimum, ENABLE);
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1PeriphMinimum | RCC_APB1PeriphOther, ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2PeriphMinimum | RCC_APB2PeriphOther, ENABLE);
|
||||
|
||||
// enable interrupts
|
||||
__enable_irq();
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG)
|
||||
serialSetMode(SP_AUX1, UART_MODE_DEBUG); // indicate AUX1 is used
|
||||
serialInit(SP_AUX1, UART_MODE_DEBUG); // early AUX1 init
|
||||
#endif
|
||||
|
||||
TRACE("\nPL18 board started :)");
|
||||
delay_ms(10);
|
||||
TRACE("RCC->CSR = %08x", RCC->CSR);
|
||||
|
||||
pwrInit();
|
||||
boardInitModulePorts();
|
||||
|
||||
init_trainer();
|
||||
battery_charge_init();
|
||||
flysky_gimbal_init();
|
||||
timersInit();
|
||||
touchPanelInit();
|
||||
usbInit();
|
||||
|
||||
extern const stm32_pulse_timer_t _led_timer;
|
||||
|
||||
ws2812_init(&_led_timer, LED_STRIP_LENGTH);
|
||||
for (uint8_t i = 0; i < LED_STRIP_LENGTH; i++) {
|
||||
ws2812_set_color(i, 0, 0, 0);
|
||||
}
|
||||
ws2812_update(&_led_timer);
|
||||
|
||||
uint32_t press_start = 0;
|
||||
uint32_t press_end = 0;
|
||||
|
||||
if (UNEXPECTED_SHUTDOWN()) {
|
||||
pwrOn();
|
||||
} else if (isChargerActive()) {
|
||||
while (true) {
|
||||
pwrOn();
|
||||
uint32_t now = get_tmr10ms();
|
||||
if (pwrPressed()) {
|
||||
press_end = now;
|
||||
if (press_start == 0) press_start = now;
|
||||
if ((now - press_start) > POWER_ON_DELAY) {
|
||||
break;
|
||||
}
|
||||
} else if (!isChargerActive()) {
|
||||
boardOff();
|
||||
} else {
|
||||
uint32_t press_end_touch = press_end;
|
||||
if (touchPanelEventOccured()) {
|
||||
touchPanelRead();
|
||||
press_end_touch = get_tmr10ms();
|
||||
}
|
||||
press_start = 0;
|
||||
handle_battery_charge(press_end_touch);
|
||||
delay_ms(10);
|
||||
press_end = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
keysInit();
|
||||
switchInit();
|
||||
audioInit();
|
||||
adcInit(&_adc_driver);
|
||||
hapticInit();
|
||||
|
||||
|
||||
#if defined(RTCLOCK)
|
||||
rtcInit(); // RTC must be initialized before rambackupRestore() is called
|
||||
#endif
|
||||
|
||||
lcdSetInitalFrameBuffer(lcdFront->getData());
|
||||
|
||||
#if defined(DEBUG)
|
||||
DBGMCU_APB1PeriphConfig(
|
||||
DBGMCU_IWDG_STOP | DBGMCU_TIM1_STOP | DBGMCU_TIM2_STOP |
|
||||
DBGMCU_TIM3_STOP | DBGMCU_TIM4_STOP | DBGMCU_TIM5_STOP |
|
||||
DBGMCU_TIM6_STOP | DBGMCU_TIM7_STOP | DBGMCU_TIM8_STOP |
|
||||
DBGMCU_TIM9_STOP | DBGMCU_TIM10_STOP | DBGMCU_TIM11_STOP |
|
||||
DBGMCU_TIM12_STOP | DBGMCU_TIM13_STOP | DBGMCU_TIM14_STOP,
|
||||
ENABLE);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern void rtcDisableBackupReg();
|
||||
|
||||
void boardOff()
|
||||
{
|
||||
lcdOff();
|
||||
|
||||
while (pwrPressed()) {
|
||||
WDG_RESET();
|
||||
}
|
||||
|
||||
SysTick->CTRL = 0; // turn off systick
|
||||
|
||||
// Shutdown the Haptic
|
||||
hapticDone();
|
||||
|
||||
rtcDisableBackupReg();
|
||||
|
||||
#if !defined(BOOT)
|
||||
if (isChargerActive())
|
||||
{
|
||||
delay_ms(100); // Add a delay to wait for lcdOff
|
||||
// RTC->BKP0R = SOFTRESET_REQUEST;
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// RTC->BKP0R = SHUTDOWN_REQUEST;
|
||||
pwrOff();
|
||||
}
|
||||
|
||||
// We reach here only in forced power situations, such as hw-debugging with external power
|
||||
// Enter STM32 stop mode / deep-sleep
|
||||
// Code snippet from ST Nucleo PWR_EnterStopMode example
|
||||
#define PDMode 0x00000000U
|
||||
#if defined(PWR_CR_MRUDS) && defined(PWR_CR_LPUDS) && defined(PWR_CR_FPDS)
|
||||
MODIFY_REG(PWR->CR, (PWR_CR_PDDS | PWR_CR_LPDS | PWR_CR_FPDS | PWR_CR_LPUDS | PWR_CR_MRUDS), PDMode);
|
||||
#elif defined(PWR_CR_MRLVDS) && defined(PWR_CR_LPLVDS) && defined(PWR_CR_FPDS)
|
||||
MODIFY_REG(PWR->CR, (PWR_CR_PDDS | PWR_CR_LPDS | PWR_CR_FPDS | PWR_CR_LPLVDS | PWR_CR_MRLVDS), PDMode);
|
||||
#else
|
||||
MODIFY_REG(PWR->CR, (PWR_CR_PDDS| PWR_CR_LPDS), PDMode);
|
||||
#endif /* PWR_CR_MRUDS && PWR_CR_LPUDS && PWR_CR_FPDS */
|
||||
|
||||
/* Set SLEEPDEEP bit of Cortex System Control Register */
|
||||
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
|
||||
|
||||
// To avoid HardFault at return address, end in an endless loop
|
||||
while (1) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int usbPlugged()
|
||||
{
|
||||
static uint8_t debouncedState = 0;
|
||||
static uint8_t lastState = 0;
|
||||
|
||||
uint8_t state = GPIO_ReadInputDataBit(UCHARGER_GPIO, UCHARGER_GPIO_PIN);
|
||||
|
||||
if (state == lastState)
|
||||
debouncedState = state;
|
||||
else
|
||||
lastState = state;
|
||||
|
||||
return debouncedState;
|
||||
}
|
250
radio/src/targets/pl18/board.h
Normal file
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _BOARD_H_
|
||||
#define _BOARD_H_
|
||||
|
||||
#include "definitions.h"
|
||||
#include "opentx_constants.h"
|
||||
|
||||
#include "board_common.h"
|
||||
#include "hal.h"
|
||||
#include "hal/serial_port.h"
|
||||
#include "hal/watchdog_driver.h"
|
||||
|
||||
#define FLASHSIZE 0x200000
|
||||
#define BOOTLOADER_SIZE 0x20000
|
||||
#define FIRMWARE_ADDRESS 0x08000000
|
||||
|
||||
#define MB *1024*1024
|
||||
#define LUA_MEM_EXTRA_MAX (2 MB) // max allowed memory usage for Lua bitmaps (in bytes)
|
||||
#define LUA_MEM_MAX (6 MB) // max allowed memory usage for complete Lua (in bytes), 0 means unlimited
|
||||
|
||||
extern uint16_t sessionTimer;
|
||||
|
||||
#define SLAVE_MODE() (g_model.trainerData.mode == TRAINER_MODE_SLAVE)
|
||||
|
||||
// Board driver
|
||||
void boardInit();
|
||||
void boardOff();
|
||||
|
||||
// CPU Unique ID
|
||||
#define LEN_CPU_UID (3*8+2)
|
||||
void getCPUUniqueID(char * s);
|
||||
|
||||
// Flash Write driver
|
||||
#define FLASH_PAGESIZE 256
|
||||
void unlockFlash();
|
||||
void lockFlash();
|
||||
void flashWrite(uint32_t * address, const uint32_t * buffer);
|
||||
uint32_t isFirmwareStart(const uint8_t * buffer);
|
||||
uint32_t isBootloaderStart(const uint8_t * buffer);
|
||||
|
||||
// SDRAM driver
|
||||
void SDRAM_Init();
|
||||
|
||||
// Pulses driver
|
||||
#if !defined(SIMU)
|
||||
|
||||
#define INTERNAL_MODULE_ON() GPIO_SetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN)
|
||||
#define INTERNAL_MODULE_OFF() GPIO_ResetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN)
|
||||
#define EXTERNAL_MODULE_ON() GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN)
|
||||
#define EXTERNAL_MODULE_OFF() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN)
|
||||
#define EXTERNAL_MODULE_PWR_OFF EXTERNAL_MODULE_OFF
|
||||
#define BLUETOOTH_MODULE_ON() GPIO_ResetBits(BT_EN_GPIO, BT_EN_GPIO_PIN)
|
||||
#define BLUETOOTH_MODULE_OFF() GPIO_SetBits(BT_EN_GPIO, BT_EN_GPIO_PIN)
|
||||
#define IS_INTERNAL_MODULE_ON() (false)
|
||||
#define IS_EXTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) == Bit_SET)
|
||||
|
||||
#else
|
||||
|
||||
#define INTERNAL_MODULE_OFF()
|
||||
#define INTERNAL_MODULE_ON()
|
||||
#define EXTERNAL_MODULE_ON()
|
||||
#define EXTERNAL_MODULE_OFF()
|
||||
#define BLUETOOTH_MODULE_ON()
|
||||
#define BLUETOOTH_MODULE_OFF()
|
||||
#define IS_INTERNAL_MODULE_ON() (false)
|
||||
#define IS_EXTERNAL_MODULE_ON() (false)
|
||||
|
||||
#endif // defined(SIMU)
|
||||
|
||||
#if !defined(NUM_FUNCTIONS_SWITCHES)
|
||||
#define NUM_FUNCTIONS_SWITCHES 0
|
||||
#endif
|
||||
|
||||
#define NUM_TRIMS 8
|
||||
#define DEFAULT_STICK_DEADZONE 2
|
||||
|
||||
#define BATTERY_WARN 37 // 3.7V
|
||||
#define BATTERY_MIN 35 // 3.4V
|
||||
#define BATTERY_MAX 43 // 4.3V
|
||||
#define BATTERY_DIVIDER 962
|
||||
|
||||
#if defined(__cplusplus) && !defined(SIMU)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Power driver
|
||||
#define SOFT_PWR_CTRL
|
||||
#define POWER_ON_DELAY 10 // 1s
|
||||
void pwrInit();
|
||||
void extModuleInit();
|
||||
uint32_t pwrCheck();
|
||||
uint32_t lowPowerCheck();
|
||||
|
||||
void pwrOn();
|
||||
void pwrSoftReboot();
|
||||
void pwrOff();
|
||||
void pwrResetHandler();
|
||||
bool pwrPressed();
|
||||
bool pwrOffPressed();
|
||||
#if defined(PWR_EXTRA_SWITCH_GPIO)
|
||||
bool pwrForcePressed();
|
||||
#else
|
||||
#define pwrForcePressed() false
|
||||
#endif
|
||||
uint32_t pwrPressedDuration();;
|
||||
|
||||
const etx_serial_port_t* auxSerialGetPort(int port_nr);
|
||||
#define AUX_SERIAL_POWER_ON()
|
||||
#define AUX_SERIAL_POWER_OFF()
|
||||
|
||||
// LED driver
|
||||
void ledInit();
|
||||
void ledOff();
|
||||
void ledRed();
|
||||
void ledBlue();
|
||||
void ledGreen();
|
||||
|
||||
// LCD driver
|
||||
void lcdSetInitalFrameBuffer(void* fbAddress);
|
||||
void lcdInit();
|
||||
void lcdCopy(void * dest, void * src);
|
||||
|
||||
void lcdOff();
|
||||
void lcdOn();
|
||||
|
||||
#define lcdRefreshWait(...)
|
||||
|
||||
// Backlight driver
|
||||
#define BACKLIGHT_LEVEL_MAX 100
|
||||
#define BACKLIGHT_FORCED_ON BACKLIGHT_LEVEL_MAX + 1
|
||||
#define BACKLIGHT_LEVEL_MIN 1
|
||||
|
||||
extern bool boardBacklightOn;
|
||||
void backlightLowInit( void );
|
||||
void backlightInit();
|
||||
void backlightEnable(uint8_t dutyCycle);
|
||||
void backlightFullOn();
|
||||
bool isBacklightEnabled();
|
||||
|
||||
#define BACKLIGHT_ENABLE() \
|
||||
{ \
|
||||
boardBacklightOn = true; \
|
||||
backlightEnable(BACKLIGHT_LEVEL_MAX - currentBacklightBright); \
|
||||
}
|
||||
|
||||
#define BACKLIGHT_DISABLE() \
|
||||
{ \
|
||||
boardBacklightOn = false; \
|
||||
backlightEnable(((g_eeGeneral.blOffBright == BACKLIGHT_LEVEL_MIN) && \
|
||||
(g_eeGeneral.backlightMode != e_backlight_mode_off)) \
|
||||
? 0 \
|
||||
: g_eeGeneral.blOffBright); \
|
||||
}
|
||||
|
||||
#if !defined(SIMU)
|
||||
void usbJoystickUpdate();
|
||||
#endif
|
||||
#if defined(RADIO_PL18EV)
|
||||
#define USB_NAME "FlySky PL18EV"
|
||||
#define USB_MANUFACTURER 'F', 'l', 'y', 'S', 'k', 'y', ' ', ' ' /* 8 bytes */
|
||||
#define USB_PRODUCT 'P', 'L', '1', '8', 'E', 'V', ' ', ' ' /* 8 Bytes */
|
||||
#else
|
||||
#define USB_NAME "FlySky PL18"
|
||||
#define USB_MANUFACTURER 'F', 'l', 'y', 'S', 'k', 'y', ' ', ' ' /* 8 bytes */
|
||||
#define USB_PRODUCT 'P', 'L', '1', '8', ' ', ' ', ' ', ' ' /* 8 Bytes */
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus) && !defined(SIMU)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Audio driver
|
||||
void audioInit();
|
||||
void audioConsumeCurrentBuffer();
|
||||
void audioSpiWriteBuffer(const uint8_t * buffer, uint32_t size);
|
||||
void audioSpiSetSpeed(uint8_t speed);
|
||||
uint8_t audioHardReset();
|
||||
uint8_t audioSoftReset();
|
||||
void audioSendRiffHeader();
|
||||
void audioOn();
|
||||
void audioOff();
|
||||
bool isAudioReady();
|
||||
bool audioChipReset();
|
||||
|
||||
#define SPI_SPEED_2 0
|
||||
#define SPI_SPEED_4 1
|
||||
#define SPI_SPEED_8 2
|
||||
#define SPI_SPEED_16 3
|
||||
#define SPI_SPEED_32 4
|
||||
#define SPI_SPEED_64 5
|
||||
#define SPI_SPEED_128 6
|
||||
#define SPI_SPEED_256 7
|
||||
|
||||
#define audioDisableIrq() // interrupts must stay enabled on Horus
|
||||
#define audioEnableIrq() // interrupts must stay enabled on Horus
|
||||
#if defined(PCBNV14)
|
||||
#define setSampleRate(freq)
|
||||
#else
|
||||
void setSampleRate(uint32_t frequency);
|
||||
#endif
|
||||
void setScaledVolume(uint8_t volume);
|
||||
void setVolume(uint8_t volume);
|
||||
int32_t getVolume();
|
||||
#define VOLUME_LEVEL_MAX 23
|
||||
#define VOLUME_LEVEL_DEF 12
|
||||
|
||||
// Telemetry driver
|
||||
#define INTMODULE_FIFO_SIZE 512
|
||||
#define TELEMETRY_FIFO_SIZE 512
|
||||
|
||||
// Haptic driver
|
||||
void hapticInit();
|
||||
void hapticDone();
|
||||
void hapticOff();
|
||||
void hapticOn(uint32_t pwmPercent);
|
||||
|
||||
// Second serial port driver
|
||||
//#define AUX_SERIAL
|
||||
#define DEBUG_BAUDRATE 115200
|
||||
#define LUA_DEFAULT_BAUDRATE 115200
|
||||
|
||||
extern uint8_t currentTrainerMode;
|
||||
void checkTrainerSettings();
|
||||
|
||||
// Touch panel driver
|
||||
bool touchPanelEventOccured();
|
||||
struct TouchState touchPanelRead();
|
||||
struct TouchState getInternalTouchState();
|
||||
|
||||
#endif // _BOARD_H_
|
261
radio/src/targets/pl18/bootloader/boot_menu.cpp
Normal file
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
#include "fw_version.h"
|
||||
#include "lcd.h"
|
||||
|
||||
#include "translations.h"
|
||||
|
||||
#include "../../common/arm/stm32/bootloader/boot.h"
|
||||
#include "../../common/arm/stm32/bootloader/bin_files.h"
|
||||
|
||||
#include <lvgl/lvgl.h>
|
||||
|
||||
#define SELECTED_COLOR (INVERS | COLOR_THEME_SECONDARY1)
|
||||
#define DEFAULT_PADDING 28
|
||||
#define DOUBLE_PADDING 56
|
||||
#define MESSAGE_TOP (LCD_H - (2*DOUBLE_PADDING))
|
||||
|
||||
const uint8_t __bmp_plug_usb[] {
|
||||
#include "bmp_plug_usb.lbm"
|
||||
};
|
||||
LZ4Bitmap BMP_PLUG_USB(BMP_ARGB4444, __bmp_plug_usb);
|
||||
|
||||
const uint8_t __bmp_usb_plugged[] {
|
||||
#include "bmp_usb_plugged.lbm"
|
||||
};
|
||||
LZ4Bitmap BMP_USB_PLUGGED(BMP_ARGB4444, __bmp_usb_plugged);
|
||||
|
||||
#define BL_GREEN COLOR2FLAGS(RGB(73, 219, 62))
|
||||
#define BL_RED COLOR2FLAGS(RGB(229, 32, 30))
|
||||
#define BL_BACKGROUND COLOR2FLAGS(BLACK)
|
||||
#define BL_FOREGROUND COLOR2FLAGS(WHITE)
|
||||
#define BL_SELECTED COLOR2FLAGS(RGB(11, 65, 244)) // deep blue
|
||||
|
||||
extern BitmapBuffer * lcd;
|
||||
|
||||
void bootloaderInitScreen()
|
||||
{
|
||||
lcdInitDisplayDriver();
|
||||
backlightInit();
|
||||
backlightEnable(100);
|
||||
setHatsAsKeys(true);
|
||||
}
|
||||
|
||||
static void bootloaderDrawTitle(const char* text)
|
||||
{
|
||||
lcd->drawText(LCD_W/2, DEFAULT_PADDING, text, CENTERED | BL_FOREGROUND);
|
||||
lcd->drawSolidFilledRect(DEFAULT_PADDING, DOUBLE_PADDING, LCD_W - DOUBLE_PADDING, 2, BL_FOREGROUND);
|
||||
}
|
||||
|
||||
static void bootloaderDrawFooter()
|
||||
{
|
||||
lcd->drawSolidFilledRect(DEFAULT_PADDING, LCD_H - (DEFAULT_PADDING + 10), LCD_W - DOUBLE_PADDING, 2, BL_FOREGROUND);
|
||||
}
|
||||
|
||||
static void bootloaderDrawBackground()
|
||||
{
|
||||
lcd->clear(BL_BACKGROUND);
|
||||
}
|
||||
|
||||
void bootloaderDrawScreen(BootloaderState st, int opt, const char* str)
|
||||
{
|
||||
lcdInitDirectDrawing();
|
||||
bootloaderDrawBackground();
|
||||
|
||||
int center = LCD_W/2;
|
||||
if (st == ST_START) {
|
||||
|
||||
bootloaderDrawTitle(BOOTLOADER_TITLE);
|
||||
|
||||
lcd->drawText(102, 75, LV_SYMBOL_CHARGE, BL_FOREGROUND);
|
||||
coord_t pos = lcd->drawText(124, 75, TR_BL_WRITE_FW, BL_FOREGROUND);
|
||||
pos += 8;
|
||||
|
||||
#if defined(SPI_FLASH)
|
||||
lcd->drawText(102, 110, LV_SYMBOL_SD_CARD, BL_FOREGROUND);
|
||||
pos = lcd->drawText(124, 110, TR_BL_ERASE_FLASH, BL_FOREGROUND);
|
||||
pos += 8;
|
||||
|
||||
lcd->drawText(100, 145, LV_SYMBOL_NEW_LINE, BL_FOREGROUND);
|
||||
lcd->drawText(124, 145, TR_BL_EXIT, BL_FOREGROUND);
|
||||
#else
|
||||
lcd->drawText(100, 110, LV_SYMBOL_NEW_LINE, BL_FOREGROUND);
|
||||
lcd->drawText(124, 110, TR_BL_EXIT, BL_FOREGROUND);
|
||||
#endif
|
||||
|
||||
pos -= 92;
|
||||
lcd->drawSolidRect(92, 72 + (opt * 35), pos, 26, 2, BL_SELECTED);
|
||||
|
||||
lcd->drawBitmap(60, 214, (const BitmapBuffer*)&BMP_PLUG_USB);
|
||||
lcd->drawText(195, 223, TR_BL_USB_PLUGIN, BL_FOREGROUND);
|
||||
lcd->drawText(195, 248, TR_BL_USB_MASS_STORE, BL_FOREGROUND);
|
||||
|
||||
bootloaderDrawFooter();
|
||||
lcd->drawText(center, LCD_H - DEFAULT_PADDING, getFirmwareVersion(), CENTERED | BL_FOREGROUND);
|
||||
}
|
||||
#if defined(SPI_FLASH)
|
||||
else if (st == ST_CLEAR_FLASH_CHECK) {
|
||||
|
||||
bootloaderDrawTitle(TR_BL_ERASE_INT_FLASH);
|
||||
|
||||
lcd->drawText(102, 75, LV_SYMBOL_SD_CARD, BL_FOREGROUND);
|
||||
coord_t pos = lcd->drawText(124, 75, TR_BL_ERASE_FLASH, BL_FOREGROUND);
|
||||
pos += 8;
|
||||
|
||||
lcd->drawText(100, 110, LV_SYMBOL_NEW_LINE, BL_FOREGROUND);
|
||||
lcd->drawText(124, 110, TR_BL_EXIT, BL_FOREGROUND);
|
||||
|
||||
pos -= 92;
|
||||
lcd->drawSolidRect(92, 72 + (opt * 35), pos, 26, 2, BL_SELECTED);
|
||||
|
||||
bootloaderDrawFooter();
|
||||
lcd->drawText(DEFAULT_PADDING, LCD_H - DEFAULT_PADDING,
|
||||
LV_SYMBOL_SD_CARD TR_BL_ERASE_KEY, BL_FOREGROUND);
|
||||
lcd->drawText(305, LCD_H - DEFAULT_PADDING,
|
||||
LV_SYMBOL_NEW_LINE TR_BL_EXIT_KEY, BL_FOREGROUND);
|
||||
}
|
||||
else if (st == ST_CLEAR_FLASH) {
|
||||
bootloaderDrawTitle(TR_BL_ERASE_INT_FLASH);
|
||||
|
||||
lcd->drawText(center, 75, TR_BL_ERASE_FLASH_MSG, CENTERED | BL_FOREGROUND);
|
||||
bootloaderDrawFooter();
|
||||
}
|
||||
#endif
|
||||
|
||||
else if (st == ST_USB) {
|
||||
lcd->drawBitmap(center - 26, 98, (const BitmapBuffer*)&BMP_USB_PLUGGED);
|
||||
lcd->drawText(center, 168, TR_BL_USB_CONNECTED, CENTERED | BL_FOREGROUND);
|
||||
} else if (st == ST_FILE_LIST || st == ST_DIR_CHECK ||
|
||||
st == ST_FLASH_CHECK || st == ST_FLASHING ||
|
||||
st == ST_FLASH_DONE) {
|
||||
|
||||
bootloaderDrawTitle(LV_SYMBOL_SD_CARD " /FIRMWARE");
|
||||
|
||||
if (st == ST_FLASHING || st == ST_FLASH_DONE) {
|
||||
LcdFlags color = BL_RED; // red
|
||||
|
||||
if (st == ST_FLASH_DONE) {
|
||||
color = BL_GREEN /* green */;
|
||||
opt = 100; // Completed > 100%
|
||||
}
|
||||
|
||||
lcd->drawRect(DEFAULT_PADDING, 120, LCD_W - DOUBLE_PADDING, 31, 2,
|
||||
SOLID, BL_SELECTED);
|
||||
lcd->drawSolidFilledRect(DEFAULT_PADDING + 4, 124,
|
||||
((LCD_W - DOUBLE_PADDING - 8) * opt) / 100, 23,
|
||||
color);
|
||||
} else if (st == ST_DIR_CHECK) {
|
||||
if (opt == FR_NO_PATH) {
|
||||
lcd->drawText(20, MESSAGE_TOP,
|
||||
LV_SYMBOL_CLOSE TR_BL_DIR_MISSING, BL_FOREGROUND);
|
||||
} else {
|
||||
lcd->drawText(20, MESSAGE_TOP, LV_SYMBOL_CLOSE TR_BL_DIR_EMPTY,
|
||||
BL_FOREGROUND);
|
||||
}
|
||||
} else if (st == ST_FLASH_CHECK) {
|
||||
bootloaderDrawFilename(str, 0, true);
|
||||
|
||||
if (opt == FC_ERROR) {
|
||||
lcd->drawText(20, MESSAGE_TOP,
|
||||
LV_SYMBOL_CLOSE " " TR_BL_INVALID_FIRMWARE,
|
||||
BL_FOREGROUND);
|
||||
} else if (opt == FC_OK) {
|
||||
VersionTag tag;
|
||||
memset(&tag, 0, sizeof(tag));
|
||||
extractFirmwareVersion(&tag);
|
||||
|
||||
lcd->drawText(LCD_W / 4 + DEFAULT_PADDING,
|
||||
MESSAGE_TOP - DEFAULT_PADDING,
|
||||
TR_BL_FORK, RIGHT | BL_FOREGROUND);
|
||||
lcd->drawSizedText(LCD_W / 4 + 6 + DEFAULT_PADDING,
|
||||
MESSAGE_TOP - DEFAULT_PADDING, tag.fork, 6,
|
||||
BL_FOREGROUND);
|
||||
|
||||
lcd->drawText(LCD_W / 4 + DEFAULT_PADDING, MESSAGE_TOP,
|
||||
TR_BL_VERSION, RIGHT | BL_FOREGROUND);
|
||||
lcd->drawText(LCD_W / 4 + 6 + DEFAULT_PADDING, MESSAGE_TOP,
|
||||
tag.version, BL_FOREGROUND);
|
||||
|
||||
lcd->drawText(LCD_W / 4 + DEFAULT_PADDING,
|
||||
MESSAGE_TOP + DEFAULT_PADDING,
|
||||
TR_BL_RADIO, RIGHT | BL_FOREGROUND);
|
||||
lcd->drawText(LCD_W / 4 + 6 + DEFAULT_PADDING,
|
||||
MESSAGE_TOP + DEFAULT_PADDING, tag.flavour,
|
||||
BL_FOREGROUND);
|
||||
|
||||
lcd->drawText(DOUBLE_PADDING, MESSAGE_TOP, LV_SYMBOL_OK, BL_GREEN);
|
||||
}
|
||||
}
|
||||
|
||||
bootloaderDrawFooter();
|
||||
|
||||
if (st != ST_DIR_CHECK && (st != ST_FLASH_CHECK || opt == FC_OK)) {
|
||||
|
||||
if (st == ST_FILE_LIST) {
|
||||
lcd->drawText(DEFAULT_PADDING, LCD_H - DEFAULT_PADDING,
|
||||
LV_SYMBOL_CHARGE TR_BL_SELECT_KEY, BL_FOREGROUND);
|
||||
} else if (st == ST_FLASH_CHECK && opt == FC_OK) {
|
||||
lcd->drawText(DEFAULT_PADDING, LCD_H - DEFAULT_PADDING,
|
||||
LV_SYMBOL_CHARGE TR_BL_FLASH_KEY, BL_FOREGROUND);
|
||||
} else if (st == ST_FLASHING) {
|
||||
lcd->drawText(DEFAULT_PADDING, LCD_H - DEFAULT_PADDING,
|
||||
LV_SYMBOL_CHARGE TR_BL_WRITING_FW, BL_FOREGROUND);
|
||||
} else if (st == ST_FLASH_DONE) {
|
||||
lcd->drawText(DEFAULT_PADDING, LCD_H - DEFAULT_PADDING,
|
||||
LV_SYMBOL_CHARGE TR_BL_WRITING_COMPL, BL_FOREGROUND);
|
||||
}
|
||||
}
|
||||
|
||||
if (st != ST_FLASHING) {
|
||||
lcd->drawText(305, LCD_H - DEFAULT_PADDING,
|
||||
LV_SYMBOL_NEW_LINE TR_BL_EXIT_KEY, BL_FOREGROUND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bootloaderDrawFilename(const char* str, uint8_t line, bool selected)
|
||||
{
|
||||
lcd->drawText(DEFAULT_PADDING, 75 + (line * 25), LV_SYMBOL_FILE, BL_FOREGROUND);
|
||||
lcd->drawText(DEFAULT_PADDING + 30, 75 + (line * 25), str, BL_FOREGROUND);
|
||||
|
||||
if (selected) {
|
||||
lcd->drawSolidRect(DEFAULT_PADDING + 25, 72 + (line * 25),
|
||||
LCD_W - (DEFAULT_PADDING + 25) - 28, 26, 2, BL_SELECTED);
|
||||
}
|
||||
}
|
||||
uint32_t bootloaderGetMenuItemCount(int baseCount)
|
||||
{
|
||||
return baseCount;
|
||||
}
|
||||
|
||||
bool bootloaderRadioMenu(uint32_t menuItem, event_t event)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void blExit(void)
|
||||
{
|
||||
lcdClear();
|
||||
lcdRefresh();
|
||||
lcdRefreshWait();
|
||||
}
|
49
radio/src/targets/pl18/extmodule_helper.cpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
void EXTERNAL_MODULE_ON()
|
||||
{
|
||||
GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN);
|
||||
}
|
||||
|
||||
void EXTERNAL_MODULE_OFF()
|
||||
{
|
||||
GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN);
|
||||
}
|
||||
|
||||
void extModuleInit()
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_TX_INVERT_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(EXTMODULE_TX_INVERT_GPIO, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_RX_INVERT_GPIO_PIN;
|
||||
GPIO_Init(EXTMODULE_RX_INVERT_GPIO, &GPIO_InitStructure);
|
||||
|
||||
EXTMODULE_TX_INVERTED();
|
||||
EXTMODULE_RX_INVERTED();
|
||||
}
|
719
radio/src/targets/pl18/hal.h
Normal file
|
@ -0,0 +1,719 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _HAL_H_
|
||||
#define _HAL_H_
|
||||
|
||||
#define CPU_FREQ 168000000
|
||||
|
||||
// HSI is at 168Mhz (over-drive is not enabled!)
|
||||
#define PERI1_FREQUENCY 42000000
|
||||
#define PERI2_FREQUENCY 84000000
|
||||
#define TIMER_MULT_APB1 2
|
||||
#define TIMER_MULT_APB2 2
|
||||
|
||||
/* Timers Allocation:
|
||||
* TIM1 = Haptic
|
||||
* TIM4 = Trainer
|
||||
* TIM6 = Audio
|
||||
* TIM7 = 2 MHz counter
|
||||
*
|
||||
*
|
||||
* TIM14 = 5 ms counter
|
||||
*/
|
||||
|
||||
/* DMA Allocation:
|
||||
DMA/Stream/Channel
|
||||
1/5/7 DAC/Audio
|
||||
2/4/0 ADC1
|
||||
2/0/2 ADC3
|
||||
2/3/4 SDIO
|
||||
*/
|
||||
|
||||
// Keys
|
||||
// PL18/PL18EV only has virtual keys via trim buttons
|
||||
// #define KEYS_GPIO_PIN_PGUP /* for activating PGUP in keys diagnose screen */
|
||||
|
||||
// Trims
|
||||
#define TRIMS_GPIO_REG_LHL
|
||||
#define TRIMS_GPIO_PIN_LHL
|
||||
|
||||
#define TRIMS_GPIO_REG_LHR
|
||||
#define TRIMS_GPIO_PIN_LHR
|
||||
|
||||
#define TRIMS_GPIO_REG_LVD
|
||||
#define TRIMS_GPIO_PIN_LVD
|
||||
|
||||
#define TRIMS_GPIO_REG_LVU
|
||||
#define TRIMS_GPIO_PIN_LVU
|
||||
|
||||
#define TRIMS_GPIO_REG_RHL
|
||||
#define TRIMS_GPIO_PIN_RHL
|
||||
|
||||
#define TRIMS_GPIO_REG_RHR
|
||||
#define TRIMS_GPIO_PIN_RHR
|
||||
|
||||
#define TRIMS_GPIO_REG_RVD
|
||||
#define TRIMS_GPIO_PIN_RVD
|
||||
|
||||
#define TRIMS_GPIO_REG_RVU
|
||||
#define TRIMS_GPIO_PIN_RVU
|
||||
|
||||
#define TRIMS_GPIO_REG_LSD
|
||||
#define TRIMS_GPIO_PIN_LSD
|
||||
|
||||
#define TRIMS_GPIO_REG_LSU
|
||||
#define TRIMS_GPIO_PIN_LSU
|
||||
|
||||
#define TRIMS_GPIO_REG_RSD
|
||||
#define TRIMS_GPIO_PIN_RSD
|
||||
|
||||
#define TRIMS_GPIO_REG_RSU
|
||||
#define TRIMS_GPIO_PIN_RSU
|
||||
|
||||
#define TRIMS_GPIO_REG_T7L
|
||||
#define TRIMS_GPIO_PIN_T7L
|
||||
|
||||
#define TRIMS_GPIO_REG_T7R
|
||||
#define TRIMS_GPIO_PIN_T7R
|
||||
|
||||
#define TRIMS_GPIO_REG_T8D
|
||||
#define TRIMS_GPIO_PIN_T8D
|
||||
|
||||
#define TRIMS_GPIO_REG_T8U
|
||||
#define TRIMS_GPIO_PIN_T8U
|
||||
|
||||
#define TRIMS_GPIO_REG_TR1U GPIOH->IDR
|
||||
#define TRIMS_GPIO_PIN_TR1U LL_GPIO_PIN_8 // PH.08
|
||||
#define TRIMS_GPIO_REG_TR1D GPIOH->IDR
|
||||
#define TRIMS_GPIO_PIN_TR1D LL_GPIO_PIN_9 // PH.09
|
||||
#define TRIMS_GPIO_REG_TR2U GPIOH->IDR
|
||||
#define TRIMS_GPIO_PIN_TR2U LL_GPIO_PIN_10 // PH.10
|
||||
#define TRIMS_GPIO_REG_TR2D GPIOH->IDR
|
||||
#define TRIMS_GPIO_PIN_TR2D LL_GPIO_PIN_11 // PH.11
|
||||
|
||||
// active 4x4 column/row based key-matrix to support up to 16 buttons with only 8 GPIOs
|
||||
#define TRIMS_GPIO_OUT1 GPIOG
|
||||
#define TRIMS_GPIO_OUT1_PIN LL_GPIO_PIN_2 // PG.02
|
||||
#define TRIMS_GPIO_OUT2 GPIOG
|
||||
#define TRIMS_GPIO_OUT2_PIN LL_GPIO_PIN_10 // PG.10
|
||||
#define TRIMS_GPIO_OUT3 GPIOG
|
||||
#define TRIMS_GPIO_OUT3_PIN LL_GPIO_PIN_11 // PG.11
|
||||
// OUT4 routed on MCU PCB, but not attached to any physical buttons, free to use for extensions
|
||||
#define TRIMS_GPIO_OUT4 GPIOH
|
||||
#define TRIMS_GPIO_OUT4_PIN LL_GPIO_PIN_7 // PH.07
|
||||
|
||||
#define TRIMS_GPIO_REG_IN1 GPIOB->IDR
|
||||
#define TRIMS_GPIO_PIN_IN1 LL_GPIO_PIN_15 // PB.15
|
||||
#define TRIMS_GPIO_REG_IN2 GPIOC->IDR
|
||||
#define TRIMS_GPIO_PIN_IN2 LL_GPIO_PIN_13 // PC.13
|
||||
#define TRIMS_GPIO_REG_IN3 GPIOD->IDR
|
||||
#define TRIMS_GPIO_PIN_IN3 LL_GPIO_PIN_7 // PD.07
|
||||
#define TRIMS_GPIO_REG_IN4 GPIOJ->IDR
|
||||
#define TRIMS_GPIO_PIN_IN4 LL_GPIO_PIN_12 // PJ.12
|
||||
|
||||
// Index of all trims
|
||||
|
||||
#define KEYS_GPIOB_PINS (LL_GPIO_PIN_15)
|
||||
|
||||
// PC8 allocated to SDIO D0, is not required to sample SWA !
|
||||
#define KEYS_GPIOC_PINS (LL_GPIO_PIN_13)
|
||||
|
||||
#define KEYS_GPIOD_PINS (LL_GPIO_PIN_7)
|
||||
|
||||
#define KEYS_GPIOH_PINS \
|
||||
(LL_GPIO_PIN_8 | LL_GPIO_PIN_9 | LL_GPIO_PIN_10 | LL_GPIO_PIN_11)
|
||||
|
||||
#define KEYS_GPIOJ_PINS (LL_GPIO_PIN_12)
|
||||
|
||||
#define KEYS_OUT_GPIOG_PINS (LL_GPIO_PIN_2 | LL_GPIO_PIN_10 | LL_GPIO_PIN_11)
|
||||
|
||||
#define KEYS_OUT_GPIOH_PINS (LL_GPIO_PIN_7)
|
||||
|
||||
|
||||
// Monitor pin
|
||||
// #define MONITOR_RCC_AHB1Periph (RCC_AHB1Periph_GPIOJ)
|
||||
// #define VBUS_MONITOR_GPIO (GPIOJ)
|
||||
// #define VBUS_MONITOR_PIN (LL_GPIO_PIN_14)
|
||||
|
||||
// Switches:
|
||||
// Switches A and C on PL18/PL18EV are 2-position switches,
|
||||
// so there is no NEED to configure two pins for Switches A and C.
|
||||
//
|
||||
// Especially, as on current dev. state, using PC8 for SDIO D0.
|
||||
// (happy coincidence ;)
|
||||
//
|
||||
// #define SWITCHES_GPIO_REG_A_H GPIOC
|
||||
// #define SWITCHES_GPIO_PIN_A_H LL_GPIO_PIN_8 // PC.08
|
||||
// #define SWITCHES_GPIO_REG_A_L GPIOC
|
||||
// #define SWITCHES_GPIO_PIN_A_L LL_GPIO_PIN_9 // PC.09
|
||||
|
||||
#define SWITCHES_GPIO_REG_A GPIOC
|
||||
#define SWITCHES_GPIO_PIN_A LL_GPIO_PIN_9 // PC.09
|
||||
|
||||
// High rail of Switch C is not required and thus PC10 is free to use for
|
||||
// customizations.
|
||||
//
|
||||
// #define SWITCHES_GPIO_REG_C_H GPIOC
|
||||
// #define SWITCHES_GPIO_PIN_C_H LL_GPIO_PIN_10 // PC.10
|
||||
// #define SWITCHES_GPIO_REG_C_L GPIOC
|
||||
// #define SWITCHES_GPIO_PIN_C_L LL_GPIO_PIN_11 // PC.11
|
||||
|
||||
#define SWITCHES_GPIO_REG_C GPIOC
|
||||
#define SWITCHES_GPIO_PIN_C LL_GPIO_PIN_11 // PC.11
|
||||
|
||||
// ADC
|
||||
|
||||
#define ADC_GPIO_PIN_STICK_LH
|
||||
#define ADC_GPIO_PIN_STICK_LV
|
||||
#define ADC_GPIO_PIN_STICK_RV
|
||||
#define ADC_GPIO_PIN_STICK_RH
|
||||
|
||||
#define ADC_GPIO_PIN_POT1 LL_GPIO_PIN_6 // PA.06 VRA
|
||||
#define ADC_GPIO_PIN_POT2 LL_GPIO_PIN_4 // PC.04 VRB
|
||||
#define ADC_GPIO_PIN_POT3 LL_GPIO_PIN_8 // PF.08 VRC
|
||||
#define ADC_GPIO_PIN_SLIDER1 LL_GPIO_PIN_9 // PF.09 VRD/LS
|
||||
#define ADC_GPIO_PIN_SLIDER2 LL_GPIO_PIN_7 // PA.07 VRE/RS
|
||||
|
||||
#if defined(RADIO_PL18EV)
|
||||
#define ADC_GPIO_PIN_EXT1 LL_GPIO_PIN_5 // PA.05
|
||||
#define ADC_GPIO_PIN_EXT2 LL_GPIO_PIN_2 // PA.02
|
||||
#define ADC_GPIO_PIN_EXT3 LL_GPIO_PIN_6 // PF.06
|
||||
#define ADC_GPIO_PIN_EXT4 LL_GPIO_PIN_3 // PA.03
|
||||
#endif
|
||||
|
||||
#define ADC_GPIO_PIN_SWB LL_GPIO_PIN_1 // PC.01
|
||||
#define ADC_GPIO_PIN_SWD LL_GPIO_PIN_0 // PC.00
|
||||
#define ADC_GPIO_PIN_SWE LL_GPIO_PIN_2 // PC.02
|
||||
#define ADC_GPIO_PIN_SWF LL_GPIO_PIN_0 // PB.00
|
||||
#define ADC_GPIO_PIN_SWG LL_GPIO_PIN_1 // PB.01
|
||||
#define ADC_GPIO_PIN_SWH LL_GPIO_PIN_10 // PF.10
|
||||
|
||||
#define ADC_GPIO_PIN_BATT LL_GPIO_PIN_5 // PC.05
|
||||
|
||||
#define ADC_GPIOA_PINS (ADC_GPIO_PIN_POT1 | ADC_GPIO_PIN_SLIDER2 | \
|
||||
ADC_GPIO_PIN_EXT1 | ADC_GPIO_PIN_EXT2 | ADC_GPIO_PIN_EXT4)
|
||||
#define ADC_GPIOB_PINS (ADC_GPIO_PIN_SWF | ADC_GPIO_PIN_SWG)
|
||||
#define ADC_GPIOC_PINS (ADC_GPIO_PIN_POT2 | ADC_GPIO_PIN_BATT | \
|
||||
ADC_GPIO_PIN_SWB | ADC_GPIO_PIN_SWD | ADC_GPIO_PIN_SWE)
|
||||
#define ADC_GPIOF_PINS (ADC_GPIO_PIN_POT3 | ADC_GPIO_PIN_SLIDER1 | \
|
||||
ADC_GPIO_PIN_EXT3 | ADC_GPIO_PIN_SWH)
|
||||
|
||||
#define ADC_CHANNEL_STICK_LH
|
||||
#define ADC_CHANNEL_STICK_LV
|
||||
#define ADC_CHANNEL_STICK_RV
|
||||
#define ADC_CHANNEL_STICK_RH
|
||||
|
||||
// Each ADC cannot map more than 8 channels, otherwise it will cause problems
|
||||
|
||||
#define ADC_CHANNEL_POT1 LL_ADC_CHANNEL_6 // ADC12_IN6 -> ADC1_IN6
|
||||
#define ADC_CHANNEL_POT2 LL_ADC_CHANNEL_14 // ADC12_IN14 -> ADC1_IN14
|
||||
#define ADC_CHANNEL_POT3 LL_ADC_CHANNEL_6 // ADC3_IN6 -> ADC3_IN6
|
||||
#define ADC_CHANNEL_SLIDER1 LL_ADC_CHANNEL_7 // ADC3_IN7 -> ADC3_IN7
|
||||
#define ADC_CHANNEL_SLIDER2 LL_ADC_CHANNEL_7 // ADC12_IN7 -> ADC1_IN7
|
||||
|
||||
#if defined(RADIO_PL18EV)
|
||||
// Left, right stick end pot on PL18EV
|
||||
#define ADC_CHANNEL_EXT1 LL_ADC_CHANNEL_5 // ADC12_IN5 -> ADC1_IN5
|
||||
#define ADC_CHANNEL_EXT2 LL_ADC_CHANNEL_2 // ADC123_IN2 -> ADC1_IN2
|
||||
|
||||
// Left, right stick end buttons on PL18EV
|
||||
#define ADC_CHANNEL_EXT3 LL_ADC_CHANNEL_4 // ADC3_IN4 -> ADC3_IN4
|
||||
#define ADC_CHANNEL_EXT4 LL_ADC_CHANNEL_3 // ADC123_IN3 -> ADC3_IN3
|
||||
#endif
|
||||
|
||||
// Analog switches
|
||||
#define ADC_CHANNEL_SWB LL_ADC_CHANNEL_11 // ADC123_IN11 -> ADC3_IN11
|
||||
#define ADC_CHANNEL_SWD LL_ADC_CHANNEL_10 // ADC123_IN10 -> ADC3_IN10
|
||||
#define ADC_CHANNEL_SWE LL_ADC_CHANNEL_12 // ADC123_IN12 -> ADC3_IN12
|
||||
#define ADC_CHANNEL_SWF LL_ADC_CHANNEL_8 // ADC12_IN8 -> ADC1_IN8
|
||||
#define ADC_CHANNEL_SWG LL_ADC_CHANNEL_9 // ADC12_IN9 -> ADC1_IN9
|
||||
#define ADC_CHANNEL_SWH LL_ADC_CHANNEL_8 // ADC3_IN8 -> ADC3_IN8
|
||||
|
||||
#define ADC_CHANNEL_BATT LL_ADC_CHANNEL_15 // ADC12_IN15 -> ADC1_IN15
|
||||
|
||||
#if !defined(RADIO_PL18EV)
|
||||
// Disabled for PL18EV because 2 ADC 16 channels are fully mapped already
|
||||
#define ADC_CHANNEL_RTC_BAT LL_ADC_CHANNEL_VBAT // ADC1_IN18
|
||||
#endif
|
||||
|
||||
#define ADC_MAIN ADC1
|
||||
#define ADC_EXT ADC3
|
||||
|
||||
#define ADC_EXT_CHANNELS \
|
||||
{ ADC_CHANNEL_POT3, ADC_CHANNEL_SLIDER1, ADC_CHANNEL_EXT3, ADC_CHANNEL_EXT4, \
|
||||
ADC_CHANNEL_SWB, ADC_CHANNEL_SWD, ADC_CHANNEL_SWE, ADC_CHANNEL_SWH \
|
||||
}
|
||||
|
||||
#define ADC_SAMPTIME LL_ADC_SAMPLINGTIME_28CYCLES
|
||||
#define ADC_DMA DMA2
|
||||
#define ADC_DMA_CHANNEL LL_DMA_CHANNEL_0
|
||||
#define ADC_DMA_STREAM LL_DMA_STREAM_4
|
||||
#define ADC_DMA_STREAM_IRQ DMA2_Stream4_IRQn
|
||||
#define ADC_DMA_STREAM_IRQHandler DMA2_Stream4_IRQHandler
|
||||
|
||||
#define ADC_EXT_DMA DMA2
|
||||
#define ADC_EXT_DMA_CHANNEL LL_DMA_CHANNEL_2
|
||||
#define ADC_EXT_DMA_STREAM LL_DMA_STREAM_0
|
||||
#define ADC_EXT_DMA_STREAM_IRQ DMA2_Stream0_IRQn
|
||||
#define ADC_EXT_DMA_STREAM_IRQHandler DMA2_Stream0_IRQHandler
|
||||
#define ADC_EXT_SAMPTIME LL_ADC_SAMPLINGTIME_28CYCLES
|
||||
|
||||
#define ADC_VREF_PREC2 660
|
||||
|
||||
#if defined(RADIO_PL18EV)
|
||||
#define ADC_DIRECTION { \
|
||||
0,0,0,0, /* gimbals */ \
|
||||
0,0,0, /* pots */ \
|
||||
-1,-1, /* sliders */ \
|
||||
0,0,0,0, /* ext1-4 */ \
|
||||
0, /* vbat */ \
|
||||
-1, /* SWB */ \
|
||||
-1, /* SWD */ \
|
||||
0, /* SWE */ \
|
||||
0, /* SWF */ \
|
||||
0, /* SWG */ \
|
||||
0 /* SWH */ \
|
||||
}
|
||||
#else
|
||||
#define ADC_DIRECTION { \
|
||||
0,0,0,0, /* gimbals */ \
|
||||
0,0,0, /* pots */ \
|
||||
-1,-1, /* sliders */ \
|
||||
0, /* vbat */ \
|
||||
0, /* rtc_bat */ \
|
||||
-1, /* SWB */ \
|
||||
-1, /* SWD */ \
|
||||
0, /* SWE */ \
|
||||
0, /* SWF */ \
|
||||
0, /* SWG */ \
|
||||
0 /* SWH */ \
|
||||
}
|
||||
#endif
|
||||
|
||||
// Power
|
||||
#define PWR_RCC_AHB1Periph RCC_AHB1Periph_GPIOI
|
||||
#define PWR_ON_GPIO GPIOI
|
||||
#define PWR_SWITCH_GPIO GPIOI
|
||||
#define PWR_SWITCH_GPIO_PIN GPIO_Pin_11 // PI.11
|
||||
#define PWR_ON_GPIO_PIN GPIO_Pin_14 // PI.14
|
||||
|
||||
// Chargers (USB and wireless)
|
||||
#define CHARGER_RCC_AHB1Periph ( RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOG | RCC_AHB1Periph_GPIOH | RCC_AHB1Periph_GPIOI )
|
||||
|
||||
#define UCHARGER_GPIO GPIOB
|
||||
#define UCHARGER_GPIO_PIN GPIO_Pin_14 // PB.14 input
|
||||
|
||||
#define UCHARGER_CHARGE_END_GPIO GPIOB
|
||||
#define UCHARGER_CHARGE_END_GPIO_PIN GPIO_Pin_13 // PB.13 input
|
||||
|
||||
#define UCHARGER_EN_GPIO GPIOG
|
||||
#define UCHARGER_EN_GPIO_PIN GPIO_Pin_3 // PG.03 output
|
||||
|
||||
#if defined (WIRELESS_CHARGER)
|
||||
|
||||
#define WCHARGER_GPIO GPIOI
|
||||
#define WCHARGER_GPIO_PIN GPIO_Pin_9 // PI.09 input
|
||||
|
||||
#define WCHARGER_CHARGE_END_GPIO GPIOI
|
||||
#define WCHARGER_CHARGE_END_GPIO_PIN GPIO_Pin_10 // PI.10 input
|
||||
|
||||
#define WCHARGER_EN_GPIO GPIOH
|
||||
#define WCHARGER_EN_GPIO_PIN GPIO_Pin_4 // PH.04 output
|
||||
|
||||
#define WCHARGER_I_CONTROL_GPIO GPIOH
|
||||
#define WCHARGER_I_CONTROL_GPIO_PIN GPIO_Pin_13 // PH.13 output
|
||||
|
||||
#endif
|
||||
|
||||
// TODO! Check IOLL1 to PI.01 connectivity!
|
||||
|
||||
// S.Port update connector
|
||||
#define SPORT_MAX_BAUDRATE 400000
|
||||
#define SPORT_UPDATE_RCC_AHB1Periph 0
|
||||
#define HAS_SPORT_UPDATE_CONNECTOR() (false)
|
||||
|
||||
// Serial Port (DEBUG)
|
||||
// We will temporarily used the PPM and the HEARTBEAT PINS
|
||||
#define AUX_SERIAL_RCC_AHB1Periph (RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOE)
|
||||
#define AUX_SERIAL_RCC_APB1Periph 0
|
||||
#define AUX_SERIAL_RCC_APB2Periph RCC_APB2Periph_USART6
|
||||
#define AUX_SERIAL_GPIO GPIOC
|
||||
#define AUX_SERIAL_GPIO_PIN_TX GPIO_Pin_6 // PC.06
|
||||
#define AUX_SERIAL_GPIO_PIN_RX GPIO_Pin_7 // PC.07
|
||||
#define AUX_SERIAL_GPIO_PinSource_TX GPIO_PinSource6
|
||||
#define AUX_SERIAL_GPIO_PinSource_RX GPIO_PinSource7
|
||||
#define AUX_SERIAL_GPIO_AF GPIO_AF_USART6
|
||||
#define AUX_SERIAL_USART USART6
|
||||
#define AUX_SERIAL_USART_IRQHandler USART6_IRQHandler
|
||||
#define AUX_SERIAL_USART_IRQn USART6_IRQn
|
||||
#define AUX_SERIAL_TX_INVERT_GPIO GPIOE
|
||||
#define AUX_SERIAL_TX_INVERT_GPIO_PIN GPIO_Pin_3 // PE.03
|
||||
#define AUX_SERIAL_RX_INVERT_GPIO GPIOI
|
||||
#define AUX_SERIAL_RX_INVERT_GPIO_PIN GPIO_Pin_15 // PI.15
|
||||
|
||||
//used in BOOTLOADER
|
||||
#define SERIAL_RCC_AHB1Periph 0
|
||||
#define SERIAL_RCC_APB1Periph 0
|
||||
#define AUX2_SERIAL_RCC_AHB1Periph 0
|
||||
#define AUX2_SERIAL_RCC_APB1Periph 0
|
||||
#define AUX2_SERIAL_RCC_APB2Periph 0
|
||||
#define KEYS_BACKLIGHT_RCC_AHB1Periph 0
|
||||
|
||||
// Telemetry
|
||||
#define TELEMETRY_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOJ | RCC_AHB1Periph_DMA1)
|
||||
#define TELEMETRY_RCC_APB1Periph RCC_APB1Periph_USART2
|
||||
#define TELEMETRY_REV_GPIO GPIOJ
|
||||
#define TELEMETRY_RX_REV_GPIO_PIN GPIO_Pin_8 // PJ.08
|
||||
#define TELEMETRY_TX_REV_GPIO_PIN GPIO_Pin_7 // PJ.07
|
||||
#define TELEMETRY_DIR_GPIO GPIOJ
|
||||
#define TELEMETRY_DIR_GPIO_PIN GPIO_Pin_13 // PJ.13
|
||||
#define TELEMETRY_SET_INPUT 1
|
||||
#define TELEMETRY_GPIO GPIOD
|
||||
#define TELEMETRY_TX_GPIO_PIN GPIO_Pin_5 // PD.05
|
||||
#define TELEMETRY_RX_GPIO_PIN GPIO_Pin_6 // PD.06
|
||||
#define TELEMETRY_GPIO_PinSource_TX GPIO_PinSource5
|
||||
#define TELEMETRY_GPIO_PinSource_RX GPIO_PinSource6
|
||||
#define TELEMETRY_GPIO_AF GPIO_AF_USART2
|
||||
#define TELEMETRY_USART USART2
|
||||
#define TELEMETRY_DMA DMA1
|
||||
#define TELEMETRY_DMA_Stream_TX LL_DMA_STREAM_6
|
||||
#define TELEMETRY_DMA_Channel_TX DMA_Channel_4
|
||||
#define TELEMETRY_DMA_TX_Stream_IRQ DMA1_Stream6_IRQn
|
||||
#define TELEMETRY_DMA_TX_IRQHandler DMA1_Stream6_IRQHandler
|
||||
#define TELEMETRY_DMA_TX_FLAG_TC DMA_IT_TCIF6
|
||||
// #define TELEMETRY_DMA_Stream_RX LL_DMA_STREAM_5
|
||||
// #define TELEMETRY_DMA_Channel_RX LL_DMA_CHANNEL_4
|
||||
#define TELEMETRY_USART_IRQHandler USART2_IRQHandler
|
||||
#define TELEMETRY_USART_IRQn USART2_IRQn
|
||||
|
||||
#define TELEMETRY_DIR_OUTPUT() TELEMETRY_DIR_GPIO->BSRRH = TELEMETRY_DIR_GPIO_PIN
|
||||
#define TELEMETRY_DIR_INPUT() TELEMETRY_DIR_GPIO->BSRRL = TELEMETRY_DIR_GPIO_PIN
|
||||
#define TELEMETRY_TX_POL_NORM() TELEMETRY_REV_GPIO->BSRRH = TELEMETRY_TX_REV_GPIO_PIN
|
||||
#define TELEMETRY_TX_POL_INV() TELEMETRY_REV_GPIO->BSRRL = TELEMETRY_TX_REV_GPIO_PIN
|
||||
#define TELEMETRY_RX_POL_NORM() TELEMETRY_REV_GPIO->BSRRH = TELEMETRY_RX_REV_GPIO_PIN
|
||||
#define TELEMETRY_RX_POL_INV() TELEMETRY_REV_GPIO->BSRRL = TELEMETRY_RX_REV_GPIO_PIN
|
||||
|
||||
// Software IRQ (Prio 5 -> FreeRTOS compatible)
|
||||
#define TELEMETRY_RX_FRAME_EXTI_LINE LL_EXTI_LINE_4
|
||||
#define USE_EXTI4_IRQ
|
||||
#define EXTI4_IRQ_Priority 5
|
||||
|
||||
// USB
|
||||
#define USB_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOA
|
||||
#define USB_GPIO GPIOA
|
||||
// #define USB_GPIO_PIN_VBUS GPIO_Pin_9 // PA.09
|
||||
#define USB_GPIO_PIN_ID GPIO_Pin_10 // PA.10
|
||||
#define USB_GPIO_PIN_DM GPIO_Pin_11 // PA.11
|
||||
#define USB_GPIO_PIN_DP GPIO_Pin_12 // PA.12
|
||||
#define USB_GPIO_PinSource_DM GPIO_PinSource11
|
||||
#define USB_GPIO_PinSource_DP GPIO_PinSource12
|
||||
#define USB_GPIO_AF GPIO_AF_OTG1_FS
|
||||
|
||||
// LCD
|
||||
#define LCD_RCC_AHB1Periph (RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOG | RCC_AHB1Periph_GPIOI | RCC_AHB1Periph_GPIOJ | RCC_AHB1Periph_GPIOK | RCC_AHB1Periph_DMA2D)
|
||||
#define LCD_RCC_APB1Periph 0
|
||||
#define LCD_RCC_APB2Periph RCC_APB2Periph_LTDC
|
||||
#define LCD_NRST_GPIO GPIOG
|
||||
#define LCD_NRST_GPIO_PIN LL_GPIO_PIN_9 // PG.09
|
||||
#define LCD_SPI_GPIO GPIOE
|
||||
#define LCD_SPI_CS_GPIO_PIN LL_GPIO_PIN_4 // PE.04
|
||||
#define LCD_SPI_SCK_GPIO_PIN LL_GPIO_PIN_2 // PE.02
|
||||
#define LCD_SPI_MISO_GPIO_PIN LL_GPIO_PIN_5 // PE.05
|
||||
#define LCD_SPI_MOSI_GPIO_PIN LL_GPIO_PIN_6 // PE.06
|
||||
#define LTDC_IRQ_PRIO 4
|
||||
#define DMA_SCREEN_IRQ_PRIO 6
|
||||
|
||||
// Backlight
|
||||
// TODO TIM3, TIM8, TIM14, review the channel in backlight_driver.cpp according to the chosen timer
|
||||
#define BACKLIGHT_RCC_AHB1Periph RCC_AHB1Periph_GPIOA
|
||||
#define BACKLIGHT_RCC_APB1Periph RCC_APB1Periph_TIM2
|
||||
#define BACKLIGHT_RCC_APB2Periph 0
|
||||
#define BACKLIGHT_GPIO GPIOA
|
||||
#define BACKLIGHT_GPIO_PIN GPIO_Pin_15
|
||||
#define BACKLIGHT_GPIO_PinSource GPIO_PinSource15
|
||||
#define BACKLIGHT_TIMER TIM2
|
||||
#define BACKLIGHT_GPIO_AF GPIO_AF_TIM2
|
||||
#define BACKLIGHT_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
|
||||
|
||||
//used in BOOTLOADER
|
||||
#define SERIAL_RCC_AHB1Periph 0
|
||||
#define SERIAL_RCC_APB1Periph 0
|
||||
#define ROTARY_ENCODER_RCC_APB1Periph 0
|
||||
|
||||
// SPI NOR Flash
|
||||
#define FLASH_SPI SPI6
|
||||
#define FLASH_SPI_CS_GPIO GPIOG
|
||||
#define FLASH_SPI_CS_GPIO_PIN LL_GPIO_PIN_6 // PG.06
|
||||
#define FLASH_SPI_GPIO GPIOG
|
||||
#define FLASH_SPI_SCK_GPIO_PIN LL_GPIO_PIN_13 // PG.13
|
||||
#define FLASH_SPI_MISO_GPIO_PIN LL_GPIO_PIN_12 // PG.12
|
||||
#define FLASH_SPI_MOSI_GPIO_PIN LL_GPIO_PIN_14 // PG.14
|
||||
// #define FLASH_SPI_DMA DMA2
|
||||
// #define FLASH_SPI_DMA_CHANNEL LL_DMA_CHANNEL_1
|
||||
// #define FLASH_SPI_DMA_TX_STREAM LL_DMA_STREAM_5
|
||||
// #define FLASH_SPI_DMA_TX_IRQn DMA2_Stream5_IRQn
|
||||
// #define FLASH_SPI_DMA_TX_IRQHandler DMA2_Stream5_IRQHandler
|
||||
// #define FLASH_SPI_DMA_RX_STREAM LL_DMA_STREAM_6
|
||||
// #define FLASH_SPI_DMA_RX_IRQn DMA2_Stream6_IRQn
|
||||
// #define FLASH_SPI_DMA_RX_IRQHandler DMA2_Stream6_IRQHandler
|
||||
#define STORAGE_USE_SPI_FLASH
|
||||
|
||||
// SDRAM
|
||||
#define SDRAM_RCC_AHB1Periph (RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOG | RCC_AHB1Periph_GPIOH)
|
||||
#define SDRAM_RCC_AHB3Periph RCC_AHB3Periph_FMC
|
||||
|
||||
// Audio
|
||||
#define AUDIO_RCC_APB1Periph (RCC_APB1Periph_TIM6 | RCC_APB1Periph_DAC)
|
||||
#define AUDIO_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_DMA1)
|
||||
#define AUDIO_OUTPUT_GPIO GPIOA
|
||||
#define AUDIO_OUTPUT_GPIO_PIN GPIO_Pin_4 // PA.04
|
||||
#define AUDIO_GPIO_PinSource GPIO_PinSource4
|
||||
#define AUDIO_DMA_Stream DMA1_Stream5
|
||||
#define AUDIO_DMA_Stream_IRQn DMA1_Stream5_IRQn
|
||||
#define AUDIO_TIM_IRQn TIM6_DAC_IRQn
|
||||
#define AUDIO_TIM_IRQHandler TIM6_DAC_IRQHandler
|
||||
#define AUDIO_DMA_Stream_IRQHandler DMA1_Stream5_IRQHandler
|
||||
#define AUDIO_TIMER TIM6
|
||||
#define AUDIO_DMA DMA1
|
||||
|
||||
// I2C Bus
|
||||
#define I2C_B1 I2C1
|
||||
#define I2C_B1_GPIO GPIOB
|
||||
#define I2C_B1_SDA_GPIO_PIN LL_GPIO_PIN_7 // PB.07
|
||||
#define I2C_B1_SCL_GPIO_PIN LL_GPIO_PIN_8 // PB.08
|
||||
#define I2C_B1_GPIO_AF LL_GPIO_AF_4
|
||||
|
||||
// Touch
|
||||
#define TOUCH_I2C_BUS I2C_Bus_1
|
||||
#define TOUCH_I2C_CLK_RATE 400000
|
||||
#define TOUCH_INT_GPIO GPIOB
|
||||
#define TOUCH_INT_GPIO_PIN LL_GPIO_PIN_9 // PB.09
|
||||
#define TOUCH_RST_GPIO GPIOB
|
||||
#define TOUCH_RST_GPIO_PIN LL_GPIO_PIN_12 // PB.12
|
||||
#define TOUCH_INT_EXTI_Line LL_EXTI_LINE_9
|
||||
#define TOUCH_INT_EXTI_Port LL_SYSCFG_EXTI_PORTB
|
||||
#define TOUCH_INT_EXTI_SysCfgLine LL_SYSCFG_EXTI_LINE9
|
||||
|
||||
// TOUCH_INT_EXTI IRQ
|
||||
#if !defined(USE_EXTI9_5_IRQ)
|
||||
#define USE_EXTI9_5_IRQ
|
||||
#define EXTI9_5_IRQ_Priority 9
|
||||
#endif
|
||||
|
||||
// Haptic: TIM1_CH1
|
||||
#define HAPTIC_PWM
|
||||
#define HAPTIC_RCC_AHB1Periph RCC_AHB1Periph_GPIOA
|
||||
#define HAPTIC_RCC_APB2Periph RCC_APB2ENR_TIM1EN
|
||||
#define HAPTIC_GPIO GPIOA
|
||||
#define HAPTIC_GPIO_PIN GPIO_Pin_8
|
||||
#define HAPTIC_GPIO_TIMER TIM1
|
||||
#define HAPTIC_GPIO_AF GPIO_AF_TIM1
|
||||
#define HAPTIC_GPIO_PinSource GPIO_PinSource8
|
||||
#define HAPTIC_TIMER_OUTPUT_ENABLE TIM_CCER_CC1E | TIM_CCER_CC1NE;
|
||||
#define HAPTIC_TIMER_MODE TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1PE
|
||||
#define HAPTIC_TIMER_COMPARE_VALUE HAPTIC_GPIO_TIMER->CCR1
|
||||
|
||||
// Flysky Hall Stick
|
||||
#define FLYSKY_HALL_SERIAL_USART UART4
|
||||
#define FLYSKY_HALL_SERIAL_GPIO GPIOA
|
||||
#define FLYSKY_HALL_DMA_Channel LL_DMA_CHANNEL_4
|
||||
#define FLYSKY_HALL_SERIAL_TX_GPIO_PIN LL_GPIO_PIN_0 // PA.00
|
||||
#define FLYSKY_HALL_SERIAL_RX_GPIO_PIN LL_GPIO_PIN_1 // PA.01
|
||||
#define FLYSKY_HALL_SERIAL_GPIO_AF LL_GPIO_AF_8
|
||||
|
||||
#define FLYSKY_HALL_RCC_AHB1Periph RCC_AHB1Periph_DMA1
|
||||
#define FLYSKY_HALL_RCC_APB1Periph RCC_APB1Periph_UART4
|
||||
|
||||
#define FLYSKY_HALL_SERIAL_USART_IRQHandler UART4_IRQHandler
|
||||
#define FLYSKY_HALL_SERIAL_USART_IRQn UART4_IRQn
|
||||
#define FLYSKY_HALL_SERIAL_DMA DMA1
|
||||
#define FLYSKY_HALL_DMA_Stream_RX LL_DMA_STREAM_2
|
||||
#define FLYSKY_HALL_DMA_Stream_TX LL_DMA_STREAM_4
|
||||
|
||||
// LED Strip
|
||||
#define LED_STRIP_LENGTH 4
|
||||
#define LED_STRIP_GPIO GPIOH
|
||||
#define LED_STRIP_GPIO_PIN_DATA LL_GPIO_PIN_12 // PH.12 / TIM5_CH3
|
||||
#define LED_STRIP_GPIO_PIN_AF LL_GPIO_AF_2 // TIM3/4/5
|
||||
#define LED_STRIP_TIMER TIM5
|
||||
#define LED_STRIP_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
|
||||
#define LED_STRIP_TIMER_CHANNEL LL_TIM_CHANNEL_CH3
|
||||
#define LED_STRIP_TIMER_DMA DMA1
|
||||
#define LED_STRIP_TIMER_DMA_CHANNEL LL_DMA_CHANNEL_6
|
||||
#define LED_STRIP_TIMER_DMA_STREAM LL_DMA_STREAM_0
|
||||
#define LED_STRIP_TIMER_DMA_IRQn DMA1_Stream0_IRQn
|
||||
#define LED_STRIP_TIMER_DMA_IRQHandler DMA1_Stream0_IRQHandler
|
||||
#define LED_STRIP_REFRESH_PERIOD 50 //ms
|
||||
|
||||
#define STATUS_LEDS
|
||||
|
||||
|
||||
// Internal Module
|
||||
#if defined(RADIO_PL18)
|
||||
#define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOI | RCC_AHB1Periph_DMA1)
|
||||
#define INTMODULE_PWR_GPIO GPIOI
|
||||
#define INTMODULE_PWR_GPIO_PIN GPIO_Pin_0 // PI.00
|
||||
#define INTMODULE_GPIO GPIOF
|
||||
#define INTMODULE_TX_GPIO_PIN LL_GPIO_PIN_7 // PF.07
|
||||
#define INTMODULE_RX_GPIO_PIN LL_GPIO_PIN_6 // PF.06
|
||||
#define INTMODULE_USART UART7
|
||||
#define INTMODULE_GPIO_AF LL_GPIO_AF_8
|
||||
#define INTMODULE_USART_IRQn UART7_IRQn
|
||||
#define INTMODULE_USART_IRQHandler UART7_IRQHandler
|
||||
#define INTMODULE_DMA DMA1
|
||||
#define INTMODULE_DMA_STREAM LL_DMA_STREAM_1
|
||||
#define INTMODULE_DMA_STREAM_IRQ DMA1_Stream1_IRQn
|
||||
#define INTMODULE_DMA_FLAG_TC DMA_FLAG_TCIF1
|
||||
#define INTMODULE_DMA_CHANNEL LL_DMA_CHANNEL_5
|
||||
#define INTMODULE_RX_DMA DMA1
|
||||
#define INTMODULE_RX_DMA_STREAM LL_DMA_STREAM_3
|
||||
#define INTMODULE_RX_DMA_CHANNEL LL_DMA_CHANNEL_5
|
||||
// #define INTMODULE_RX_DMA_Stream_IRQn DMA1_Stream3_IRQn
|
||||
// #define INTMODULE_RX_DMA_Stream_IRQHandler DMA1_Stream_IRQHandler
|
||||
|
||||
#define INTMODULE_TIMER TIM3
|
||||
#define INTMODULE_TIMER_IRQn TIM3_IRQn
|
||||
#define INTMODULE_TIMER_IRQHandler TIM3_IRQHandler
|
||||
#define INTMODULE_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
|
||||
#endif
|
||||
|
||||
// External Module
|
||||
#define EXTMODULE
|
||||
#define EXTMODULE_PULSES
|
||||
#define EXTMODULE_PWR_GPIO GPIOD
|
||||
#define EXTMODULE_PWR_GPIO_PIN GPIO_Pin_11 // PD.11
|
||||
#define EXTMODULE_RCC_AHB1Periph \
|
||||
(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOC | \
|
||||
RCC_AHB1Periph_GPIOI | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_DMA2)
|
||||
#define EXTMODULE_TX_GPIO GPIOC
|
||||
#define EXTMODULE_TX_GPIO_PIN LL_GPIO_PIN_6 // PC.06
|
||||
#define EXTMODULE_TX_GPIO_AF LL_GPIO_AF_3 // TIM8_CH1
|
||||
#define EXTMODULE_TX_GPIO_AF_USART GPIO_AF_USART6
|
||||
#define EXTMODULE_RX_GPIO GPIOC
|
||||
#define EXTMODULE_RX_GPIO_PIN LL_GPIO_PIN_7 // PC.07
|
||||
#define EXTMODULE_RX_GPIO_AF_USART GPIO_AF_USART6
|
||||
#define EXTMODULE_TIMER TIM8
|
||||
#define EXTMODULE_TIMER_Channel LL_TIM_CHANNEL_CH1
|
||||
#define EXTMODULE_TIMER_IRQn TIM8_UP_TIM13_IRQn
|
||||
#define EXTMODULE_TIMER_IRQHandler TIM8_UP_TIM13_IRQHandler
|
||||
#define EXTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2)
|
||||
#define EXTMODULE_TIMER_TX_GPIO_AF LL_GPIO_AF_3
|
||||
//USART
|
||||
#define EXTMODULE_USART USART6
|
||||
#define EXTMODULE_USART_GPIO GPIOC
|
||||
#define EXTMODULE_USART_GPIO_AF GPIO_AF_USART6
|
||||
#define EXTMODULE_USART_GPIO_AF_LL LL_GPIO_AF_8
|
||||
#define EXTMODULE_USART_TX_DMA DMA2
|
||||
#define EXTMODULE_USART_TX_DMA_CHANNEL LL_DMA_CHANNEL_5
|
||||
#define EXTMODULE_USART_TX_DMA_STREAM DMA2_Stream7
|
||||
#define EXTMODULE_USART_TX_DMA_STREAM_LL LL_DMA_STREAM_7
|
||||
|
||||
#define EXTMODULE_USART_RX_DMA_CHANNEL LL_DMA_CHANNEL_5
|
||||
#define EXTMODULE_USART_RX_DMA_STREAM DMA2_Stream2
|
||||
#define EXTMODULE_USART_RX_DMA_STREAM_LL LL_DMA_STREAM_2
|
||||
|
||||
#define EXTMODULE_USART_IRQHandler USART6_IRQHandler
|
||||
#define EXTMODULE_USART_IRQn USART6_IRQn
|
||||
|
||||
//TIMER
|
||||
#define EXTMODULE_TIMER_DMA_CHANNEL LL_DMA_CHANNEL_7
|
||||
#define EXTMODULE_TIMER_DMA_STREAM DMA2_Stream1
|
||||
#define EXTMODULE_TIMER_DMA DMA2
|
||||
#define EXTMODULE_TIMER_DMA_STREAM_LL LL_DMA_STREAM_1
|
||||
#define EXTMODULE_TIMER_DMA_STREAM_IRQn DMA2_Stream1_IRQn
|
||||
#define EXTMODULE_TIMER_DMA_IRQHandler DMA2_Stream1_IRQHandler
|
||||
|
||||
#define EXTMODULE_TX_INVERT_GPIO GPIOE
|
||||
#define EXTMODULE_TX_INVERT_GPIO_PIN GPIO_Pin_3 // PE.03
|
||||
#define EXTMODULE_RX_INVERT_GPIO GPIOI
|
||||
#define EXTMODULE_RX_INVERT_GPIO_PIN GPIO_Pin_15 // PI.15
|
||||
|
||||
#define EXTMODULE_TX_NORMAL() EXTMODULE_TX_INVERT_GPIO->BSRRH = EXTMODULE_TX_INVERT_GPIO_PIN
|
||||
#define EXTMODULE_TX_INVERTED() EXTMODULE_TX_INVERT_GPIO->BSRRL = EXTMODULE_TX_INVERT_GPIO_PIN
|
||||
#define EXTMODULE_RX_NORMAL() EXTMODULE_RX_INVERT_GPIO->BSRRH = EXTMODULE_RX_INVERT_GPIO_PIN
|
||||
#define EXTMODULE_RX_INVERTED() EXTMODULE_RX_INVERT_GPIO->BSRRL = EXTMODULE_RX_INVERT_GPIO_PIN
|
||||
|
||||
// Trainer Port
|
||||
#define TRAINER_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD)
|
||||
#define TRAINER_GPIO GPIOD
|
||||
|
||||
#define TRAINER_IN_GPIO_PIN LL_GPIO_PIN_12 // PD.12
|
||||
#define TRAINER_IN_TIMER_Channel LL_TIM_CHANNEL_CH1
|
||||
|
||||
#define TRAINER_OUT_GPIO_PIN LL_GPIO_PIN_13 // PD.13
|
||||
#define TRAINER_OUT_TIMER_Channel LL_TIM_CHANNEL_CH2
|
||||
|
||||
#define TRAINER_TIMER TIM4
|
||||
#define TRAINER_TIMER_IRQn TIM4_IRQn
|
||||
#define TRAINER_TIMER_IRQHandler TIM4_IRQHandler
|
||||
#define TRAINER_GPIO_AF LL_GPIO_AF_2
|
||||
#define TRAINER_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
|
||||
|
||||
//ROTARY emulation for trims as buttons
|
||||
#define ROTARY_ENCODER_NAVIGATION
|
||||
|
||||
//BLUETOOTH
|
||||
#define BLUETOOTH_ON_RCC_AHB1Periph RCC_AHB1Periph_GPIOI
|
||||
#define BT_EN_GPIO GPIOI
|
||||
#define BT_EN_GPIO_PIN GPIO_Pin_8 // PI.8
|
||||
|
||||
#define BT_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOI | RCC_AHB1Periph_GPIOH)
|
||||
#define BT_RCC_APB1Periph (RCC_APB1Periph_USART3)
|
||||
#define BT_RCC_APB2Periph 0
|
||||
|
||||
#define BT_USART USART3
|
||||
#define BT_GPIO_AF GPIO_AF_USART3
|
||||
#define BT_USART_IRQn USART3_IRQn
|
||||
#define BT_GPIO_TXRX GPIOB
|
||||
#define BT_TX_GPIO_PIN GPIO_Pin_10 // PB.10
|
||||
#define BT_RX_GPIO_PIN GPIO_Pin_11 // PB.11
|
||||
#define BT_TX_GPIO_PinSource GPIO_PinSource10
|
||||
#define BT_RX_GPIO_PinSource GPIO_PinSource11
|
||||
#define BT_USART_IRQHandler USART3_IRQHandler
|
||||
|
||||
#define BT_CONNECTED_GPIO GPIOJ
|
||||
#define BT_CONNECTED_GPIO_PIN GPIO_Pin_1 // PJ.01
|
||||
|
||||
#define BT_CMD_MODE_GPIO GPIOH
|
||||
#define BT_CMD_MODE_GPIO_PIN GPIO_Pin_6 // PH.6
|
||||
|
||||
// Millisecond timer
|
||||
#define MS_TIMER TIM14
|
||||
#define MS_TIMER_IRQn TIM8_TRG_COM_TIM14_IRQn
|
||||
#define MS_TIMER_IRQHandler TIM8_TRG_COM_TIM14_IRQHandler
|
||||
|
||||
// Mixer scheduler timer
|
||||
#define MIXER_SCHEDULER_TIMER TIM12
|
||||
#define MIXER_SCHEDULER_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
|
||||
#define MIXER_SCHEDULER_TIMER_IRQn TIM8_BRK_TIM12_IRQn
|
||||
#define MIXER_SCHEDULER_TIMER_IRQHandler TIM8_BRK_TIM12_IRQHandler
|
||||
|
||||
#define LCD_W 480
|
||||
#define LCD_H 320
|
||||
|
||||
#define LCD_PHYS_W 320
|
||||
#define LCD_PHYS_H 480
|
||||
|
||||
#define LCD_DEPTH 16
|
||||
#define LCD_CONTRAST_DEFAULT 20
|
||||
|
||||
#endif // _HAL_H_
|
63
radio/src/targets/pl18/haptic_driver.cpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
void hapticOff(void)
|
||||
{
|
||||
HAPTIC_TIMER_COMPARE_VALUE = 0;
|
||||
}
|
||||
|
||||
void hapticOn(uint32_t pwmPercent)
|
||||
{
|
||||
if (pwmPercent > 100) {
|
||||
pwmPercent = 100;
|
||||
}
|
||||
HAPTIC_TIMER_COMPARE_VALUE = pwmPercent;
|
||||
}
|
||||
|
||||
void hapticInit(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = HAPTIC_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(HAPTIC_GPIO, &GPIO_InitStructure);
|
||||
|
||||
GPIO_PinAFConfig(HAPTIC_GPIO, HAPTIC_GPIO_PinSource, HAPTIC_GPIO_AF);
|
||||
|
||||
HAPTIC_GPIO_TIMER->ARR = 100;
|
||||
HAPTIC_GPIO_TIMER->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 10000 - 1;
|
||||
HAPTIC_GPIO_TIMER->CCMR1 = HAPTIC_TIMER_MODE; // PWM
|
||||
HAPTIC_GPIO_TIMER->CCER = HAPTIC_TIMER_OUTPUT_ENABLE;
|
||||
HAPTIC_GPIO_TIMER->CCR1 = 0;
|
||||
HAPTIC_GPIO_TIMER->EGR = TIM_EGR_UG;
|
||||
HAPTIC_GPIO_TIMER->CR1 = TIM_CR1_CEN; // counter enable
|
||||
HAPTIC_GPIO_TIMER->BDTR |= TIM_BDTR_MOE;
|
||||
}
|
||||
|
||||
void hapticDone(void)
|
||||
{
|
||||
hapticOff();
|
||||
RCC_AHB1PeriphClockCmd(HAPTIC_RCC_AHB1Periph, DISABLE);
|
||||
}
|
220
radio/src/targets/pl18/key_driver.cpp
Normal file
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "hal/key_driver.h"
|
||||
|
||||
#include "stm32_hal_ll.h"
|
||||
#include "stm32_gpio_driver.h"
|
||||
|
||||
#include "hal.h"
|
||||
#include "delays_driver.h"
|
||||
#include "keys.h"
|
||||
|
||||
/* The output bit-order has to be:
|
||||
0 LHL TR7L (Left equals down)
|
||||
1 LHR TR7R
|
||||
2 LVD TR5D
|
||||
3 LVU TR5U
|
||||
4 RVD TR6D
|
||||
5 RVU TR6U
|
||||
6 RHL TR8L
|
||||
7 RHR TR8R
|
||||
8 LSD TR1D
|
||||
9 LSU TR1U
|
||||
10 RSD TR2D
|
||||
11 RSU TR2U
|
||||
12 EX1D TR3D
|
||||
13 EX1U TR3U
|
||||
14 EX2D TR4D
|
||||
15 EX2U TR4U
|
||||
*/
|
||||
|
||||
enum PhysicalTrims
|
||||
{
|
||||
TR7L = 0,
|
||||
TR7R,
|
||||
TR5D = 2,
|
||||
TR5U,
|
||||
TR6D = 4,
|
||||
TR6U,
|
||||
TR8L = 6,
|
||||
TR8R,
|
||||
TR1D = 8,
|
||||
TR1U,
|
||||
TR2D = 10,
|
||||
TR2U,
|
||||
TR3D = 12,
|
||||
TR3U,
|
||||
TR4D = 14,
|
||||
TR4U,
|
||||
};
|
||||
|
||||
void keysInit()
|
||||
{
|
||||
stm32_gpio_enable_clock(GPIOB);
|
||||
stm32_gpio_enable_clock(GPIOC);
|
||||
stm32_gpio_enable_clock(GPIOD);
|
||||
stm32_gpio_enable_clock(GPIOF);
|
||||
stm32_gpio_enable_clock(GPIOH);
|
||||
stm32_gpio_enable_clock(GPIOJ);
|
||||
|
||||
LL_GPIO_InitTypeDef pinInit;
|
||||
LL_GPIO_StructInit(&pinInit);
|
||||
pinInit.Mode = LL_GPIO_MODE_INPUT;
|
||||
pinInit.Pull = LL_GPIO_PULL_DOWN;
|
||||
|
||||
pinInit.Pin = KEYS_GPIOB_PINS;
|
||||
LL_GPIO_Init(GPIOB, &pinInit);
|
||||
|
||||
pinInit.Pin = KEYS_GPIOC_PINS;
|
||||
LL_GPIO_Init(GPIOC, &pinInit);
|
||||
|
||||
pinInit.Pin = KEYS_GPIOD_PINS;
|
||||
LL_GPIO_Init(GPIOD, &pinInit);
|
||||
|
||||
pinInit.Pin = KEYS_GPIOH_PINS;
|
||||
LL_GPIO_Init(GPIOH, &pinInit);
|
||||
|
||||
pinInit.Pin = KEYS_GPIOJ_PINS;
|
||||
LL_GPIO_Init(GPIOJ, &pinInit);
|
||||
|
||||
// Matrix outputs
|
||||
pinInit.Mode = LL_GPIO_MODE_OUTPUT;
|
||||
pinInit.Pull = LL_GPIO_PULL_NO;
|
||||
|
||||
pinInit.Pin = KEYS_OUT_GPIOG_PINS;
|
||||
LL_GPIO_Init(GPIOG, &pinInit);
|
||||
|
||||
pinInit.Pin = KEYS_OUT_GPIOH_PINS;
|
||||
LL_GPIO_Init(GPIOH, &pinInit);
|
||||
}
|
||||
|
||||
static uint32_t _readKeyMatrix()
|
||||
{
|
||||
// This function avoids concurrent matrix agitation
|
||||
|
||||
uint32_t result = 0;
|
||||
/* Bit 0 - TR3 down
|
||||
* Bit 1 - TR3 up
|
||||
* Bit 2 - TR4 down
|
||||
* Bit 3 - TR4 up
|
||||
* Bit 4 - TR5 down
|
||||
* Bit 5 - TR5 up
|
||||
* Bit 6 - TR6 down
|
||||
* Bit 7 - TR6 up
|
||||
* Bit 8 - TR7 left
|
||||
* Bit 9 - TR7 right
|
||||
* Bit 10 - TR8 left
|
||||
* Bit 11 - TR8 right
|
||||
*/
|
||||
|
||||
volatile static struct
|
||||
{
|
||||
uint32_t oldResult = 0;
|
||||
uint8_t ui8ReadInProgress = 0;
|
||||
} syncelem;
|
||||
|
||||
if (syncelem.ui8ReadInProgress != 0) return syncelem.oldResult;
|
||||
|
||||
// ui8ReadInProgress was 0, increment it
|
||||
syncelem.ui8ReadInProgress++;
|
||||
// Double check before continuing, as non-atomic, non-blocking so far
|
||||
// If ui8ReadInProgress is above 1, then there was concurrent task calling it, exit
|
||||
if (syncelem.ui8ReadInProgress > 1) return syncelem.oldResult;
|
||||
|
||||
// If we land here, we have exclusive access to Matrix
|
||||
LL_GPIO_ResetOutputPin(TRIMS_GPIO_OUT1, TRIMS_GPIO_OUT1_PIN);
|
||||
LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT2, TRIMS_GPIO_OUT2_PIN);
|
||||
LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT3, TRIMS_GPIO_OUT3_PIN);
|
||||
LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT4, TRIMS_GPIO_OUT4_PIN);
|
||||
delay_us(10);
|
||||
if (~TRIMS_GPIO_REG_IN1 & TRIMS_GPIO_PIN_IN1)
|
||||
result |= 1 << TR7L;
|
||||
if (~TRIMS_GPIO_REG_IN2 & TRIMS_GPIO_PIN_IN2)
|
||||
result |= 1 << TR7R;
|
||||
if (~TRIMS_GPIO_REG_IN3 & TRIMS_GPIO_PIN_IN3)
|
||||
result |= 1 << TR5D;
|
||||
if (~TRIMS_GPIO_REG_IN4 & TRIMS_GPIO_PIN_IN4)
|
||||
result |= 1 << TR5U;
|
||||
|
||||
LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT1, TRIMS_GPIO_OUT1_PIN);
|
||||
LL_GPIO_ResetOutputPin(TRIMS_GPIO_OUT2, TRIMS_GPIO_OUT2_PIN);
|
||||
delay_us(10);
|
||||
if (~TRIMS_GPIO_REG_IN1 & TRIMS_GPIO_PIN_IN1)
|
||||
result |= 1 << TR3D;
|
||||
if (~TRIMS_GPIO_REG_IN2 & TRIMS_GPIO_PIN_IN2)
|
||||
result |= 1 << TR3U;
|
||||
if (~TRIMS_GPIO_REG_IN3 & TRIMS_GPIO_PIN_IN3)
|
||||
result |= 1 << TR4U;
|
||||
if (~TRIMS_GPIO_REG_IN4 & TRIMS_GPIO_PIN_IN4)
|
||||
result |= 1 << TR4D;
|
||||
|
||||
LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT2, TRIMS_GPIO_OUT2_PIN);
|
||||
LL_GPIO_ResetOutputPin(TRIMS_GPIO_OUT3, TRIMS_GPIO_OUT3_PIN);
|
||||
delay_us(10);
|
||||
if (~TRIMS_GPIO_REG_IN1 & TRIMS_GPIO_PIN_IN1)
|
||||
result |= 1 << TR6U;
|
||||
if (~TRIMS_GPIO_REG_IN2 & TRIMS_GPIO_PIN_IN2)
|
||||
result |= 1 << TR6D;
|
||||
if (~TRIMS_GPIO_REG_IN3 & TRIMS_GPIO_PIN_IN3)
|
||||
result |= 1 << TR8L;
|
||||
if (~TRIMS_GPIO_REG_IN4 & TRIMS_GPIO_PIN_IN4)
|
||||
result |= 1 << TR8R;
|
||||
|
||||
LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT3, TRIMS_GPIO_OUT3_PIN);
|
||||
|
||||
syncelem.oldResult = result;
|
||||
syncelem.ui8ReadInProgress = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t readKeys()
|
||||
{
|
||||
uint32_t result = 0;
|
||||
|
||||
if (getHatsAsKeys()) {
|
||||
uint32_t mkeys = _readKeyMatrix();
|
||||
if (mkeys & (1 << TR4D)) result |= 1 << KEY_ENTER;
|
||||
if (mkeys & (1 << TR4U)) result |= 1 << KEY_EXIT;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t readTrims()
|
||||
{
|
||||
uint32_t result = 0;
|
||||
|
||||
result |= _readKeyMatrix();
|
||||
|
||||
if (~TRIMS_GPIO_REG_TR1U & TRIMS_GPIO_PIN_TR1U)
|
||||
result |= 1 << (TR1U);
|
||||
if (~TRIMS_GPIO_REG_TR1D & TRIMS_GPIO_PIN_TR1D)
|
||||
result |= 1 << (TR1D);
|
||||
|
||||
if (~TRIMS_GPIO_REG_TR2U & TRIMS_GPIO_PIN_TR2U)
|
||||
result |= 1 << (TR2U);
|
||||
if (~TRIMS_GPIO_REG_TR2D & TRIMS_GPIO_PIN_TR2D)
|
||||
result |= 1 << (TR2D);
|
||||
|
||||
return result;
|
||||
}
|
2876
radio/src/targets/pl18/lcd_driver.cpp
Normal file
92
radio/src/targets/pl18/lcd_driver.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __LCD_DRIVER_H__
|
||||
#define __LCD_DRIVER_H__
|
||||
|
||||
#define HBP ( 24 ) // TODO use names from FlySky
|
||||
#define VBP ( 10 )
|
||||
|
||||
#define HSW ( 4 )
|
||||
#define VSH ( 2 )
|
||||
|
||||
#define HFP ( 140 - HBP )
|
||||
#define VFP ( 22 - VBP )
|
||||
|
||||
#define LCD_ST7796S_ID ( 0x7796 )
|
||||
#define LCD_ILI9481_ID ( 0x9481 )
|
||||
#define LCD_ILI9486_ID ( 0x9486 )
|
||||
#define LCD_ILI9488_ID ( 0x9488 )
|
||||
#define LCD_HX8357D_ID ( 0x99 )
|
||||
|
||||
#define LCD_DELAY() LCD_Delay()
|
||||
|
||||
typedef void (*lcdSpiInitFucPtr)(void);
|
||||
typedef unsigned int LcdReadIDFucPtr( void );
|
||||
|
||||
extern lcdSpiInitFucPtr lcdInitFunction;
|
||||
extern lcdSpiInitFucPtr lcdOffFunction;
|
||||
extern lcdSpiInitFucPtr lcdOnFunction;
|
||||
|
||||
#define SET_IO_INPUT( PORT, PIN ) LL_GPIO_SetPinMode( PORT, PIN, LL_GPIO_MODE_INPUT )
|
||||
#define SET_IO_OUTPUT( PORT, PIN ) LL_GPIO_SetPinMode( PORT, PIN, LL_GPIO_MODE_OUTPUT )
|
||||
|
||||
#define LCD_NRST_HIGH() LL_GPIO_SetOutputPin(LCD_NRST_GPIO, LCD_NRST_GPIO_PIN)
|
||||
#define LCD_NRST_LOW() LL_GPIO_ResetOutputPin(LCD_NRST_GPIO, LCD_NRST_GPIO_PIN)
|
||||
|
||||
#define LCD_CS_HIGH() LL_GPIO_SetOutputPin(LCD_SPI_GPIO, LCD_SPI_CS_GPIO_PIN)
|
||||
#define LCD_CS_LOW() LL_GPIO_ResetOutputPin(LCD_SPI_GPIO, LCD_SPI_CS_GPIO_PIN)
|
||||
|
||||
#define LCD_SCK_HIGH() LL_GPIO_SetOutputPin(LCD_SPI_GPIO, LCD_SPI_SCK_GPIO_PIN)
|
||||
#define LCD_SCK_LOW() LL_GPIO_ResetOutputPin(LCD_SPI_GPIO, LCD_SPI_SCK_GPIO_PIN)
|
||||
|
||||
#define LCD_MOSI_HIGH() LL_GPIO_SetOutputPin(LCD_SPI_GPIO, LCD_SPI_MOSI_GPIO_PIN)
|
||||
#define LCD_MOSI_LOW() LL_GPIO_ResetOutputPin(LCD_SPI_GPIO, LCD_SPI_MOSI_GPIO_PIN)
|
||||
|
||||
#define LCD_MOSI_AS_INPUT() SET_IO_INPUT( LCD_SPI_GPIO, LCD_SPI_MOSI_GPIO_PIN )
|
||||
#define LCD_MOSI_AS_OUTPUT() SET_IO_OUTPUT( LCD_SPI_GPIO, LCD_SPI_MOSI_GPIO_PIN )
|
||||
|
||||
#define LCD_READ_DATA_PIN() LL_GPIO_IsInputPinSet(LCD_SPI_GPIO, LCD_SPI_MOSI_GPIO_PIN)
|
||||
|
||||
|
||||
#if 1
|
||||
#define HORIZONTAL_SYNC_WIDTH ( 4 )
|
||||
#define HORIZONTAL_BACK_PORCH ( 24 )
|
||||
#define HORIZONTAL_FRONT_PORCH ( 140 - HORIZONTAL_BACK_PORCH )
|
||||
#define VERTICAL_SYNC_HEIGHT ( 2 )
|
||||
#define VERTICAL_BACK_PORCH ( 10 )
|
||||
#define VERTICAL_FRONT_PORCH ( 22 - VERTICAL_BACK_PORCH )
|
||||
#else
|
||||
#define HORIZONTAL_SYNC_WIDTH ( 4 )
|
||||
#define HORIZONTAL_BACK_PORCH ( 20 )
|
||||
#define HORIZONTAL_FRONT_PORCH ( 60 - HORIZONTAL_BACK_PORCH )
|
||||
#define VERTICAL_SYNC_HEIGHT ( 2 )
|
||||
#define VERTICAL_BACK_PORCH ( 6 )
|
||||
#define VERTICAL_FRONT_PORCH ( 14 - VERTICAL_BACK_PORCH )
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
60
radio/src/targets/pl18/led_driver.cpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
#include "boards/generic_stm32/rgb_leds.h"
|
||||
|
||||
void ledInit()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void ledOff()
|
||||
{
|
||||
for (uint8_t i = 0; i < LED_STRIP_LENGTH; i++) {
|
||||
rgbSetLedColor(i, 0, 0, 0);
|
||||
}
|
||||
rgbLedColorApply();
|
||||
}
|
||||
|
||||
void ledRed()
|
||||
{
|
||||
for (uint8_t i = 0; i < LED_STRIP_LENGTH; i++) {
|
||||
rgbSetLedColor(i, 50, 0, 0);
|
||||
}
|
||||
rgbLedColorApply();
|
||||
}
|
||||
|
||||
void ledGreen()
|
||||
{
|
||||
for (uint8_t i = 0; i < LED_STRIP_LENGTH; i++) {
|
||||
rgbSetLedColor(i, 0, 50, 0);
|
||||
}
|
||||
rgbLedColorApply();
|
||||
}
|
||||
|
||||
void ledBlue()
|
||||
{
|
||||
for (uint8_t i = 0; i < LED_STRIP_LENGTH; i++) {
|
||||
rgbSetLedColor(i, 0, 0, 50);
|
||||
}
|
||||
rgbLedColorApply();
|
||||
}
|
29
radio/src/targets/pl18/libopenui_config.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
constexpr coord_t INPUT_EDIT_CURVE_WIDTH = 132;
|
||||
constexpr coord_t INPUT_EDIT_CURVE_HEIGHT = INPUT_EDIT_CURVE_WIDTH;
|
||||
constexpr coord_t MENUS_MAX_HEIGHT = (MENUS_LINE_HEIGHT * 8) + 8;
|
||||
|
||||
// Disable rotary encoder, as the PL18 does not have one
|
||||
#define ROTARY_ENCODER_SPEED() 0
|
257
radio/src/targets/pl18/sdram_driver.c
Normal file
|
@ -0,0 +1,257 @@
|
|||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
#include "stm32f4xx_fmc.h"
|
||||
|
||||
#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000)
|
||||
#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001)
|
||||
#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002)
|
||||
#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004)
|
||||
#define SDRAM_MODEREG_BURST_FULL_PAGE ((uint16_t)0x0007)
|
||||
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000)
|
||||
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008)
|
||||
#define SDRAM_MODEREG_CAS_LATENCY_1 ((uint16_t)0x0010)
|
||||
#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020)
|
||||
#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030)
|
||||
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000)
|
||||
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
|
||||
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200)
|
||||
|
||||
void SDRAM_GPIOConfig(void)
|
||||
{
|
||||
/*
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
PC3 <-> FMC_SDCKE0 | PD0 <-> FMC_D2 | PE0 <-> FMC_NBL0 | PF0 <-> FMC_A0 | PG0 <-> FMC_A10 | PH3 <-> FMC_SDNE0 | PI0 <-> FMC_D24
|
||||
| PD1 <-> FMC_D3 | PE1 <-> FMC_NBL1 | PF1 <-> FMC_A1 | PG1 <-> FMC_A11 | PH5 <-> FMC_SDNWE | PI1 <-> FMC_D25
|
||||
| PD8 <-> FMC_D13 | PE7 <-> FMC_D4 | PF2 <-> FMC_A2 | PG4 <-> FMC_BA0 | PH8 <-> FMC_D16 | PI2 <-> FMC_D26
|
||||
| PD9 <-> FMC_D14 | PE8 <-> FMC_D5 | PF3 <-> FMC_A3 | PG5 <-> FMC_BA1 | PH9 <-> FMC_D17 | PI3 <-> FMC_D27
|
||||
| PD10 <-> FMC_D15 | PE9 <-> FMC_D6 | PF4 <-> FMC_A4 | PG8 <-> FMC_SDCLK | PH10 <-> FMC_D18 | PI4 <-> FMC_NBL2
|
||||
| PD14 <-> FMC_D0 | PE10 <-> FMC_D7 | PF5 <-> FMC_A5 | PG15 <-> FMC_NCAS | PH11 <-> FMC_D19 | PI5 <-> FMC_NBL3
|
||||
| PD15 <-> FMC_D1 | PE11 <-> FMC_D8 | PF11 <-> FMC_NRAS | | PH12 <-> FMC_D20 | PI6 <-> FMC_D28
|
||||
| | PE12 <-> FMC_D9 | PF12 <-> FMC_A6 | | PH13 <-> FMC_D21 | PI7 <-> FMC_D29
|
||||
| | PE13 <-> FMC_D10 | PF13 <-> FMC_A7 | | PH14 <-> FMC_D22 | PI9 <-> FMC_D30
|
||||
| | PE14 <-> FMC_D11 | PF14 <-> FMC_A8 | | PH15 <-> FMC_D23 | PI10 <-> FMC_D31
|
||||
| | PE15 <-> FMC_D12 | PF15 <-> FMC_A9 | | |
|
||||
*/
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
|
||||
/* GPIOC configuration */
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource3 , GPIO_AF_FMC);
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 ;
|
||||
GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||||
|
||||
/* GPIOD configuration */
|
||||
GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FMC);
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15;
|
||||
GPIO_Init(GPIOD, &GPIO_InitStructure);
|
||||
|
||||
/* GPIOE configuration */
|
||||
GPIO_PinAFConfig(GPIOE, GPIO_PinSource0, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOE, GPIO_PinSource1, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOE, GPIO_PinSource7, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOE, GPIO_PinSource8, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOE, GPIO_PinSource10, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOE, GPIO_PinSource12, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOE, GPIO_PinSource14, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOE, GPIO_PinSource15, GPIO_AF_FMC);
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
|
||||
GPIO_Init(GPIOE, &GPIO_InitStructure);
|
||||
|
||||
/* GPIOF configuration */
|
||||
GPIO_PinAFConfig(GPIOF, GPIO_PinSource0, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOF, GPIO_PinSource1, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOF, GPIO_PinSource2, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOF, GPIO_PinSource3, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOF, GPIO_PinSource4, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOF, GPIO_PinSource5, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOF, GPIO_PinSource11, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOF, GPIO_PinSource12, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOF, GPIO_PinSource13, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOF, GPIO_PinSource14, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOF, GPIO_PinSource15, GPIO_AF_FMC);
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
|
||||
GPIO_Init(GPIOF, &GPIO_InitStructure);
|
||||
|
||||
/* GPIOG configuration */
|
||||
GPIO_PinAFConfig(GPIOG, GPIO_PinSource0 , GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOG, GPIO_PinSource1 , GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOG, GPIO_PinSource4 , GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOG, GPIO_PinSource5 , GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOG, GPIO_PinSource8 , GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOG, GPIO_PinSource15 , GPIO_AF_FMC);
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_15;
|
||||
GPIO_Init(GPIOG, &GPIO_InitStructure);
|
||||
|
||||
/* GPIOH configuration */
|
||||
GPIO_PinAFConfig(GPIOH, GPIO_PinSource3, GPIO_AF_FMC);
|
||||
GPIO_PinAFConfig(GPIOH, GPIO_PinSource5, GPIO_AF_FMC);
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_5;
|
||||
GPIO_Init(GPIOH, &GPIO_InitStructure);
|
||||
}
|
||||
|
||||
void SDRAM_InitSequence(void)
|
||||
{
|
||||
FMC_SDRAMCommandTypeDef FMC_SDRAMCommandStructure;
|
||||
uint32_t tmpr = 0;
|
||||
|
||||
/* Step 3 --------------------------------------------------------------------*/
|
||||
/* Configure a clock configuration enable command */
|
||||
FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_CLK_Enabled;
|
||||
FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank1;
|
||||
FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1;
|
||||
FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0;
|
||||
/* Wait until the SDRAM controller is ready */
|
||||
while(FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) {
|
||||
}
|
||||
/* Send the command */
|
||||
FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
|
||||
|
||||
/* Step 4 --------------------------------------------------------------------*/
|
||||
/* Insert 100 ms delay */
|
||||
delay_ms(100);
|
||||
|
||||
/* Step 5 --------------------------------------------------------------------*/
|
||||
/* Configure a PALL (precharge all) command */
|
||||
FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_PALL;
|
||||
FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank1;
|
||||
FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1;
|
||||
FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0;
|
||||
/* Wait until the SDRAM controller is ready */
|
||||
while(FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) {
|
||||
}
|
||||
/* Send the command */
|
||||
FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
|
||||
|
||||
/* Step 6 --------------------------------------------------------------------*/
|
||||
/* Configure a Auto-Refresh command */
|
||||
FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_AutoRefresh;
|
||||
FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank1;
|
||||
FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 4;
|
||||
FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0;
|
||||
/* Wait until the SDRAM controller is ready */
|
||||
while(FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) {
|
||||
}
|
||||
/* Send the first command */
|
||||
FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
|
||||
|
||||
/* Wait until the SDRAM controller is ready */
|
||||
while(FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) {
|
||||
}
|
||||
/* Send the second command */
|
||||
FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
|
||||
|
||||
/* Step 7 --------------------------------------------------------------------*/
|
||||
/* Program the external memory mode register */
|
||||
tmpr = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2 |
|
||||
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
|
||||
SDRAM_MODEREG_CAS_LATENCY_3 |
|
||||
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
|
||||
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
|
||||
|
||||
/* Configure a load Mode register command*/
|
||||
FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_LoadMode;
|
||||
FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank1;
|
||||
FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1;
|
||||
FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = tmpr;
|
||||
/* Wait until the SDRAM controller is ready */
|
||||
while(FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) {
|
||||
}
|
||||
/* Send the command */
|
||||
FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
|
||||
|
||||
/* Step 8 --------------------------------------------------------------------*/
|
||||
/* Set the refresh rate counter */
|
||||
/* (15.62 us x Freq) - 20 */
|
||||
/* Set the device refresh counter */
|
||||
FMC_SetRefreshCount(683);//904
|
||||
/* Wait until the SDRAM controller is ready */
|
||||
while(FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SDRAM_Init(void)
|
||||
{
|
||||
//delay funcion needed
|
||||
delaysInit();
|
||||
// Clocks must be enabled here, because the sdramInit is called before main
|
||||
RCC_AHB1PeriphClockCmd(SDRAM_RCC_AHB1Periph, ENABLE);
|
||||
RCC_AHB3PeriphClockCmd(SDRAM_RCC_AHB3Periph, ENABLE);
|
||||
|
||||
/* GPIO configuration for FMC SDRAM bank */
|
||||
SDRAM_GPIOConfig();
|
||||
|
||||
/* FMC Configuration ---------------------------------------------------------*/
|
||||
FMC_SDRAMInitTypeDef FMC_SDRAMInitStructure;
|
||||
FMC_SDRAMTimingInitTypeDef FMC_SDRAMTimingInitStructure;
|
||||
|
||||
/* FMC SDRAM Bank configuration */
|
||||
/* Timing configuration for 90 Mhz of SD clock frequency (168Mhz/2) */
|
||||
/* TMRD: 2 Clock cycles */
|
||||
FMC_SDRAMTimingInitStructure.FMC_LoadToActiveDelay = 2;
|
||||
/* TXSR: min=70ns (7x11.11ns) */
|
||||
FMC_SDRAMTimingInitStructure.FMC_ExitSelfRefreshDelay = 7;
|
||||
/* TRAS: min=42ns (4x11.11ns) max=120k (ns) */
|
||||
FMC_SDRAMTimingInitStructure.FMC_SelfRefreshTime = 4;
|
||||
/* TRC: min=70 (7x11.11ns) */
|
||||
FMC_SDRAMTimingInitStructure.FMC_RowCycleDelay = 7;
|
||||
/* TWR: min=1+ 7ns (1+1x11.11ns) */
|
||||
FMC_SDRAMTimingInitStructure.FMC_WriteRecoveryTime = 2;
|
||||
/* TRP: 20ns => 2x11.11ns */
|
||||
FMC_SDRAMTimingInitStructure.FMC_RPDelay = 2;
|
||||
/* TRCD: 20ns => 2x11.11ns */
|
||||
FMC_SDRAMTimingInitStructure.FMC_RCDDelay = 2;
|
||||
|
||||
/* FMC SDRAM control configuration */
|
||||
FMC_SDRAMInitStructure.FMC_Bank = FMC_Bank1_SDRAM;
|
||||
/* Row addressing: [7:0] */
|
||||
FMC_SDRAMInitStructure.FMC_ColumnBitsNumber = FMC_ColumnBits_Number_8b;
|
||||
/* Column addressing: [11:0] */
|
||||
FMC_SDRAMInitStructure.FMC_RowBitsNumber = FMC_RowBits_Number_12b;
|
||||
FMC_SDRAMInitStructure.FMC_SDMemoryDataWidth = FMC_SDMemory_Width_16b;
|
||||
FMC_SDRAMInitStructure.FMC_InternalBankNumber = FMC_InternalBank_Number_4;
|
||||
FMC_SDRAMInitStructure.FMC_CASLatency = FMC_CAS_Latency_3;
|
||||
FMC_SDRAMInitStructure.FMC_WriteProtection = FMC_Write_Protection_Disable;
|
||||
FMC_SDRAMInitStructure.FMC_SDClockPeriod = FMC_SDClock_Period_2;
|
||||
FMC_SDRAMInitStructure.FMC_ReadBurst = FMC_Read_Burst_Enable;
|
||||
FMC_SDRAMInitStructure.FMC_ReadPipeDelay = FMC_ReadPipe_Delay_1;
|
||||
FMC_SDRAMInitStructure.FMC_SDRAMTimingStruct = &FMC_SDRAMTimingInitStructure;
|
||||
|
||||
/* FMC SDRAM bank initialization */
|
||||
FMC_SDRAMInit(&FMC_SDRAMInitStructure);
|
||||
|
||||
/* FMC SDRAM device initialization sequence */
|
||||
SDRAM_InitSequence();
|
||||
}
|
470
radio/src/targets/pl18/touch_driver.cpp
Normal file
|
@ -0,0 +1,470 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "stm32_hal_ll.h"
|
||||
#include "stm32_hal.h"
|
||||
#include "stm32_i2c_driver.h"
|
||||
#include "stm32_gpio_driver.h"
|
||||
#include "stm32_exti_driver.h"
|
||||
|
||||
#include "hal.h"
|
||||
#include "timers_driver.h"
|
||||
#include "delays_driver.h"
|
||||
#include "touch_driver.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#define TAP_TIME 25
|
||||
#define I2C_TIMEOUT_MAX 5 // 5 ms
|
||||
|
||||
// FT6236 definitions
|
||||
#define TOUCH_FT6236_I2C_ADDRESS (0x70>>1)
|
||||
#define TOUCH_FT6236_REG_TH_GROUP 0x80
|
||||
#define TOUCH_FT6236_REG_PERIODACTIVE 0x88
|
||||
#define TOUCH_FT6236_REG_LIB_VER_H 0xa1
|
||||
#define TOUCH_FT6236_REG_LIB_VER_L 0xa2
|
||||
#define TOUCH_FT6236_REG_CIPHER 0xa3
|
||||
#define TOUCH_FT6236_REG_FIRMID 0xa6
|
||||
#define TOUCH_FT6236_REG_FOCALTECH_ID 0xa8
|
||||
#define TOUCH_FT6236_REG_RELEASE_CODE_ID 0xaf
|
||||
#define TOUCH_FT6206_REG_TD_STAT 0x02
|
||||
#define TOUCH_FT6206_REG_P1_XH 0x03
|
||||
#define TOUCH_FT6206_EVT_SHIFT 6
|
||||
#define TOUCH_FT6206_EVT_MASK (3 << TOUCH_FT6206_EVT_SHIFT)
|
||||
#define TOUCH_FT6206_EVT_CONTACT 0x02
|
||||
#define TOUCH_FT6206_MASK_TD_STAT 0x0f
|
||||
|
||||
// CST340 definitions
|
||||
#define TOUCH_CST340_I2C_ADDRESS 0x1a
|
||||
#define TOUCH_CST340_REG_FINGER1 0x00
|
||||
#define TOUCH_CST340_EVT_CONTACT 0x06
|
||||
|
||||
// CHSC5448 definitions
|
||||
#define TOUCH_CHSC5448_I2C_ADDRESS 0x2e
|
||||
#define TOUCH_CHSC5448_REG_ADDR 0x2c000020
|
||||
#define TOUCH_CHSC5448_EVT_CONTACT 0x08
|
||||
#define TOUCH_CHSC5448_MAX_POINTS 5
|
||||
|
||||
typedef enum {TC_NONE, TC_FT6236, TC_CST340, TC_CHSC5448} TouchController;
|
||||
|
||||
#if defined(DEBUG)
|
||||
const char TOUCH_CONTROLLER_STR[][10] = {"", "FT6236", "CST340", "CHSC5448"};
|
||||
#endif
|
||||
|
||||
TouchController touchController = TC_NONE;
|
||||
|
||||
struct TouchControllerDescriptor
|
||||
{
|
||||
bool (*hasTouchEvent)();
|
||||
bool (*touchRead)(uint16_t * X, uint16_t * Y);
|
||||
void (*printDebugInfo)();
|
||||
bool needTranspose;
|
||||
};
|
||||
|
||||
union rpt_point_t
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned char x_l8;
|
||||
unsigned char y_l8;
|
||||
unsigned char z;
|
||||
unsigned char x_h4:4;
|
||||
unsigned char y_h4:4;
|
||||
unsigned char id:4;
|
||||
unsigned char event:4;
|
||||
}rp;
|
||||
unsigned char data[5];
|
||||
};
|
||||
|
||||
extern uint8_t TouchControllerType;
|
||||
|
||||
static const TouchControllerDescriptor *tcd = nullptr;
|
||||
static TouchState internalTouchState = {};
|
||||
volatile static bool touchEventOccured;
|
||||
static tmr10ms_t downTime = 0;
|
||||
static tmr10ms_t tapTime = 0;
|
||||
static short tapCount = 0;
|
||||
|
||||
static void _touch_exti_isr(void)
|
||||
{
|
||||
touchEventOccured = true;
|
||||
}
|
||||
|
||||
static void _touch_exti_stop(void)
|
||||
{
|
||||
stm32_exti_disable(TOUCH_INT_EXTI_Line);
|
||||
}
|
||||
|
||||
static void _touch_exti_config(void)
|
||||
{
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
LL_SYSCFG_SetEXTISource(TOUCH_INT_EXTI_Port, TOUCH_INT_EXTI_SysCfgLine);
|
||||
|
||||
stm32_exti_enable(TOUCH_INT_EXTI_Line, LL_EXTI_TRIGGER_FALLING, _touch_exti_isr);
|
||||
}
|
||||
|
||||
static void _touch_gpio_config(void)
|
||||
{
|
||||
LL_GPIO_InitTypeDef gpioInit;
|
||||
LL_GPIO_StructInit(&gpioInit);
|
||||
|
||||
stm32_gpio_enable_clock(TOUCH_RST_GPIO);
|
||||
stm32_gpio_enable_clock(TOUCH_INT_GPIO);
|
||||
|
||||
gpioInit.Mode = LL_GPIO_MODE_OUTPUT;
|
||||
gpioInit.Speed = LL_GPIO_SPEED_FREQ_LOW;
|
||||
gpioInit.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
|
||||
gpioInit.Pull = LL_GPIO_PULL_NO;
|
||||
|
||||
gpioInit.Pin = TOUCH_RST_GPIO_PIN;
|
||||
LL_GPIO_Init(TOUCH_RST_GPIO, &gpioInit);
|
||||
LL_GPIO_SetOutputPin(TOUCH_RST_GPIO, TOUCH_RST_GPIO_PIN);
|
||||
|
||||
gpioInit.Pin = TOUCH_INT_GPIO_PIN;
|
||||
gpioInit.Mode = LL_GPIO_MODE_INPUT;
|
||||
gpioInit.Pull = LL_GPIO_PULL_UP;
|
||||
gpioInit.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
|
||||
LL_GPIO_Init(TOUCH_INT_GPIO, &gpioInit);
|
||||
LL_GPIO_SetOutputPin(TOUCH_INT_GPIO, TOUCH_INT_GPIO_PIN);
|
||||
}
|
||||
|
||||
static void _touch_reset()
|
||||
{
|
||||
LL_GPIO_ResetOutputPin(TOUCH_RST_GPIO, TOUCH_RST_GPIO_PIN);
|
||||
delay_ms(10);
|
||||
LL_GPIO_SetOutputPin(TOUCH_RST_GPIO, TOUCH_RST_GPIO_PIN);
|
||||
delay_ms(300);
|
||||
}
|
||||
|
||||
static void _i2c_init(void)
|
||||
{
|
||||
TRACE("Touch I2C Init");
|
||||
|
||||
if (stm32_i2c_init(TOUCH_I2C_BUS, TOUCH_I2C_CLK_RATE) < 0) {
|
||||
TRACE("Touch I2C Init ERROR: stm32_i2c_init failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void _i2c_reInit(void)
|
||||
{
|
||||
stm32_i2c_deinit(TOUCH_I2C_BUS);
|
||||
_i2c_init();
|
||||
}
|
||||
|
||||
static int _i2c_read(uint8_t addr, uint32_t reg, uint8_t regSize, uint8_t* data, uint16_t len, uint32_t timeout)
|
||||
{
|
||||
if (regSize > 2) {
|
||||
if(stm32_i2c_master_tx(TOUCH_I2C_BUS, addr, (uint8_t*) ®, regSize, 3) < 0)
|
||||
return false;
|
||||
delay_us(5);
|
||||
if(stm32_i2c_master_rx(TOUCH_I2C_BUS, addr, data, len, I2C_TIMEOUT_MAX) < 0)
|
||||
return false;
|
||||
return true;
|
||||
} else {
|
||||
return stm32_i2c_read(TOUCH_I2C_BUS, addr, reg, regSize, data, len, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t _i2c_readRetry(uint8_t addr, uint32_t reg, uint8_t regSize)
|
||||
{
|
||||
uint8_t result;
|
||||
uint8_t tryCount = 3;
|
||||
while (_i2c_read(addr, reg, regSize, &result, 1, I2C_TIMEOUT_MAX) < 0) {
|
||||
if (--tryCount == 0) break;
|
||||
_i2c_reInit();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint16_t _i2c_readMultipleRetry(uint8_t addr, uint32_t reg, uint8_t regSize, uint8_t * buffer, uint16_t length)
|
||||
{
|
||||
uint8_t tryCount = 3;
|
||||
while (_i2c_read(addr, reg, regSize, buffer, length, I2C_TIMEOUT_MAX) < 0) {
|
||||
if (--tryCount == 0) break;
|
||||
_i2c_reInit();
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
static bool ft6236TouchRead(uint16_t * X, uint16_t * Y)
|
||||
{
|
||||
// Read register FT6206_TD_STAT_REG to check number of touches detection
|
||||
uint8_t nbTouch = _i2c_readRetry(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6206_REG_TD_STAT, 1);
|
||||
nbTouch &= TOUCH_FT6206_MASK_TD_STAT;
|
||||
bool hasTouch = nbTouch > 0;
|
||||
|
||||
if (hasTouch) {
|
||||
uint8_t dataxy[4];
|
||||
// Read X and Y positions and event
|
||||
_i2c_readMultipleRetry(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6206_REG_P1_XH, 1, dataxy, sizeof(dataxy));
|
||||
|
||||
// Send back ready X position to caller
|
||||
*X = ((dataxy[0] & 0x0f) << 8) | dataxy[1];
|
||||
// Send back ready Y position to caller
|
||||
*Y = ((dataxy[2] & 0x0f) << 8) | dataxy[3];
|
||||
|
||||
uint8_t event = (dataxy[0] & TOUCH_FT6206_EVT_MASK) >> TOUCH_FT6206_EVT_SHIFT;
|
||||
return event == TOUCH_FT6206_EVT_CONTACT;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ft6236HasTouchEvent()
|
||||
{
|
||||
return touchEventOccured;
|
||||
}
|
||||
|
||||
static void ft6236PrintDebugInfo()
|
||||
{
|
||||
#if defined(DEBUG)
|
||||
TRACE("ft6x36: thrhld = %d", _i2c_readRetry(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_TH_GROUP, 1) * 4);
|
||||
TRACE("ft6x36: rep rate=", _i2c_readRetry(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_PERIODACTIVE, 1) * 10);
|
||||
TRACE("ft6x36: fw lib 0x%02X %02X", _i2c_readRetry(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_LIB_VER_H, 1),
|
||||
_i2c_readRetry(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_LIB_VER_L, 1));
|
||||
TRACE("ft6x36: fw v 0x%02X", _i2c_readRetry(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_FIRMID, 1));
|
||||
TRACE("ft6x36: CHIP ID 0x%02X", _i2c_readRetry(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_CIPHER, 1));
|
||||
TRACE("ft6x36: CTPM ID 0x%02X", _i2c_readRetry(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_FOCALTECH_ID, 1));
|
||||
TRACE("ft6x36: rel code 0x%02X", _i2c_readRetry(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_RELEASE_CODE_ID, 1));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static bool cst340TouchRead(uint16_t * X, uint16_t * Y)
|
||||
{
|
||||
uint8_t data[4];
|
||||
|
||||
// Read X and Y positions
|
||||
_i2c_readMultipleRetry(TOUCH_CST340_I2C_ADDRESS, TOUCH_CST340_REG_FINGER1, 1, data, sizeof(data));
|
||||
|
||||
// Send back X position to caller
|
||||
if (X) *X = ((data[1]<<4) + ((data[3]>>4)&0x0f));
|
||||
// Send back Y position to caller
|
||||
if (Y) *Y = ((data[2]<<4) + ((data[3])&0x0f));
|
||||
|
||||
return data[0] == TOUCH_CST340_EVT_CONTACT;
|
||||
}
|
||||
|
||||
static bool cst340HasTouchEvent()
|
||||
{
|
||||
static bool lastHasTouch = false;
|
||||
bool ret = touchEventOccured;
|
||||
if (ret) {
|
||||
uint8_t hasTouch = cst340TouchRead(nullptr, nullptr);
|
||||
if (!hasTouch && !lastHasTouch) {
|
||||
TRACE("Interrupt occurs without touch event!!");
|
||||
touchEventOccured = false;
|
||||
ret = false;
|
||||
}
|
||||
lastHasTouch = hasTouch;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cst340PrintDebugInfo()
|
||||
{
|
||||
// TODO, when necessary
|
||||
}
|
||||
|
||||
static bool chsc5448TouchRead(uint16_t * X, uint16_t * Y)
|
||||
{
|
||||
static uint8_t readbuffer[84];
|
||||
const uint8_t reportSize = ((TOUCH_CHSC5448_MAX_POINTS * 5 + 2) + 3) & 0xfc;
|
||||
|
||||
int ptCnt = 0;
|
||||
union rpt_point_t* ppt;
|
||||
|
||||
_i2c_readMultipleRetry(TOUCH_CHSC5448_I2C_ADDRESS, TOUCH_CHSC5448_REG_ADDR, 4, readbuffer, reportSize);
|
||||
ptCnt = readbuffer[1] & 0x0f;
|
||||
ppt = (union rpt_point_t*)&readbuffer[2];
|
||||
*X = ((ppt->rp.x_h4 & 0x0f) << 8) | ppt->rp.x_l8;
|
||||
*Y = ((ppt->rp.y_h4 & 0x0f) << 8) | ppt->rp.y_l8;
|
||||
uint8_t event = ppt->rp.event;
|
||||
|
||||
return ptCnt > 0 && event == TOUCH_CHSC5448_EVT_CONTACT;
|
||||
}
|
||||
|
||||
static bool chsc5448HasTouchEvent()
|
||||
{
|
||||
return touchEventOccured;
|
||||
}
|
||||
|
||||
static void chsc5448PrintDebugInfo()
|
||||
{
|
||||
// TODO, when necessary
|
||||
}
|
||||
|
||||
static const TouchControllerDescriptor FT6236 =
|
||||
{
|
||||
.hasTouchEvent = ft6236HasTouchEvent,
|
||||
.touchRead = ft6236TouchRead,
|
||||
.printDebugInfo = ft6236PrintDebugInfo,
|
||||
.needTranspose = true,
|
||||
};
|
||||
|
||||
static const TouchControllerDescriptor CST340 =
|
||||
{
|
||||
.hasTouchEvent = cst340HasTouchEvent,
|
||||
.touchRead = cst340TouchRead,
|
||||
.printDebugInfo = cst340PrintDebugInfo,
|
||||
.needTranspose = true,
|
||||
};
|
||||
|
||||
static const TouchControllerDescriptor CHSC5448 =
|
||||
{
|
||||
.hasTouchEvent = chsc5448HasTouchEvent,
|
||||
.touchRead = chsc5448TouchRead,
|
||||
.printDebugInfo = chsc5448PrintDebugInfo,
|
||||
.needTranspose = false,
|
||||
};
|
||||
|
||||
void _detect_touch_controller()
|
||||
{
|
||||
if (stm32_i2c_is_dev_ready(TOUCH_I2C_BUS, TOUCH_CST340_I2C_ADDRESS, 3, I2C_TIMEOUT_MAX) == 0) {
|
||||
touchController = TC_CST340;
|
||||
tcd = &CST340;
|
||||
TouchControllerType = 0;
|
||||
} else if (stm32_i2c_is_dev_ready(TOUCH_I2C_BUS, TOUCH_CHSC5448_I2C_ADDRESS, 3, I2C_TIMEOUT_MAX) == 0) {
|
||||
touchController = TC_CHSC5448;
|
||||
tcd = &CHSC5448;
|
||||
TouchControllerType = 0;
|
||||
} else {
|
||||
touchController = TC_FT6236;
|
||||
tcd = &FT6236;
|
||||
TouchControllerType = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void touchPanelDeInit()
|
||||
{
|
||||
_touch_exti_stop();
|
||||
}
|
||||
|
||||
bool touchPanelInit()
|
||||
{
|
||||
_touch_gpio_config();
|
||||
_i2c_init();
|
||||
_touch_reset();
|
||||
_detect_touch_controller();
|
||||
_touch_exti_config();
|
||||
|
||||
tcd->printDebugInfo();
|
||||
|
||||
return touchController != TC_NONE;
|
||||
}
|
||||
|
||||
bool touchPanelEventOccured()
|
||||
{
|
||||
return tcd->hasTouchEvent();
|
||||
}
|
||||
|
||||
struct TouchState touchPanelRead()
|
||||
{
|
||||
if (!touchEventOccured) return internalTouchState;
|
||||
|
||||
touchEventOccured = false;
|
||||
|
||||
tmr10ms_t now = get_tmr10ms();
|
||||
internalTouchState.tapCount = 0;
|
||||
unsigned short touchX;
|
||||
unsigned short touchY;
|
||||
bool hasTouchContact = tcd->touchRead(&touchX, &touchY);
|
||||
|
||||
if (tcd->needTranspose) {
|
||||
// Touch sensor is rotated by 90 deg
|
||||
unsigned short tmp = touchY;
|
||||
touchY = 319 - touchX;
|
||||
touchX = tmp;
|
||||
}
|
||||
|
||||
if (hasTouchContact) {
|
||||
int dx = touchX - internalTouchState.x;
|
||||
int dy = touchY - internalTouchState.y;
|
||||
internalTouchState.x = touchX;
|
||||
internalTouchState.y = touchY;
|
||||
|
||||
if (internalTouchState.event == TE_NONE || internalTouchState.event == TE_UP || internalTouchState.event == TE_SLIDE_END) {
|
||||
internalTouchState.startX = internalTouchState.x;
|
||||
internalTouchState.startY = internalTouchState.y;
|
||||
internalTouchState.event = TE_DOWN;
|
||||
}
|
||||
else if (internalTouchState.event == TE_DOWN) {
|
||||
if (dx >= SLIDE_RANGE || dx <= -SLIDE_RANGE || dy >= SLIDE_RANGE || dy <= -SLIDE_RANGE) {
|
||||
internalTouchState.event = TE_SLIDE;
|
||||
internalTouchState.deltaX = (short) dx;
|
||||
internalTouchState.deltaY = (short) dy;
|
||||
}
|
||||
else {
|
||||
internalTouchState.event = TE_DOWN;
|
||||
internalTouchState.deltaX = 0;
|
||||
internalTouchState.deltaY = 0;
|
||||
}
|
||||
}
|
||||
else if (internalTouchState.event == TE_SLIDE) {
|
||||
internalTouchState.event = TE_SLIDE; //no change
|
||||
internalTouchState.deltaX = (short) dx;
|
||||
internalTouchState.deltaY = (short) dy;
|
||||
}
|
||||
|
||||
if (internalTouchState.event == TE_DOWN && downTime == 0) {
|
||||
downTime = now;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (internalTouchState.event == TE_DOWN) {
|
||||
internalTouchState.event = TE_UP;
|
||||
if (now - downTime <= TAP_TIME) {
|
||||
if (now - tapTime > TAP_TIME) {
|
||||
tapCount = 1;
|
||||
} else {
|
||||
tapCount++;
|
||||
}
|
||||
internalTouchState.tapCount = tapCount;
|
||||
tapTime = now;
|
||||
} else {
|
||||
internalTouchState.tapCount = 0; // not a tap
|
||||
}
|
||||
downTime = 0;
|
||||
} else {
|
||||
tapCount = 0;
|
||||
internalTouchState.tapCount = 0;
|
||||
internalTouchState.event = TE_SLIDE_END;
|
||||
}
|
||||
}
|
||||
|
||||
TouchState ret = internalTouchState;
|
||||
internalTouchState.deltaX = 0;
|
||||
internalTouchState.deltaY = 0;
|
||||
if (internalTouchState.event == TE_UP || internalTouchState.event == TE_SLIDE_END)
|
||||
internalTouchState.event = TE_NONE;
|
||||
|
||||
#if defined(DEBUG)
|
||||
TRACE("%s: event=%d,X=%d,Y=%d", TOUCH_CONTROLLER_STR[touchController], ret.event, ret.x, ret.y);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct TouchState getInternalTouchState()
|
||||
{
|
||||
return internalTouchState;
|
||||
}
|
31
radio/src/targets/pl18/touch_driver.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "touch.h"
|
||||
|
||||
extern void touchPanelDeInit();
|
||||
extern bool touchPanelInit();
|
||||
|
||||
struct TouchState touchPanelRead();
|
||||
bool touchPanelEventOccured();
|
||||
struct TouchState getInternalTouchState();
|
560
radio/src/targets/pl18/tp_cst340.cpp
Normal file
|
@ -0,0 +1,560 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "stm32_hal_ll.h"
|
||||
#include "stm32_hal.h"
|
||||
#include "stm32_i2c_driver.h"
|
||||
#include "stm32_gpio_driver.h"
|
||||
#include "stm32_exti_driver.h"
|
||||
|
||||
#include "hal.h"
|
||||
#include "timers_driver.h"
|
||||
#include "delays_driver.h"
|
||||
#include "tp_cst340.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#define TOUCH_FT6236_I2C_ADDRESS (0x70>>1)
|
||||
#define TOUCH_CST340_I2C_ADDRESS 0x1A
|
||||
|
||||
|
||||
extern uint8_t TouchControllerType;
|
||||
|
||||
volatile static bool touchEventOccured;
|
||||
enum TouchControllers {TC_NONE, TC_FT6236, TC_CST340};
|
||||
TouchControllers touchController = TC_NONE;
|
||||
|
||||
static tc_handle_TypeDef tc_handle = {0, 0};
|
||||
|
||||
tmr10ms_t downTime = 0;
|
||||
tmr10ms_t tapTime = 0;
|
||||
short tapCount = 0;
|
||||
#define TAP_TIME 25
|
||||
|
||||
struct TouchControllerDescriptor
|
||||
{
|
||||
void (*read)(uint16_t * X, uint16_t * Y, uint32_t * event);
|
||||
uint8_t (*detectTouch)();
|
||||
void (*printDebugInfo)();
|
||||
uint32_t contactEvent;
|
||||
};
|
||||
|
||||
static const TouchControllerDescriptor *tc = nullptr;
|
||||
|
||||
static TouchState internalTouchState = {};
|
||||
|
||||
static void _cst340_exti_isr(void)
|
||||
{
|
||||
touchEventOccured = true;
|
||||
}
|
||||
|
||||
static void TOUCH_AF_ExtiStop(void)
|
||||
{
|
||||
stm32_exti_disable(TOUCH_INT_EXTI_Line);
|
||||
}
|
||||
|
||||
static void TOUCH_AF_ExtiConfig(void)
|
||||
{
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
LL_SYSCFG_SetEXTISource(TOUCH_INT_EXTI_Port, TOUCH_INT_EXTI_SysCfgLine);
|
||||
|
||||
stm32_exti_enable(TOUCH_INT_EXTI_Line,
|
||||
LL_EXTI_TRIGGER_FALLING,
|
||||
_cst340_exti_isr);
|
||||
}
|
||||
|
||||
static void TOUCH_AF_GPIOConfig(void)
|
||||
{
|
||||
LL_GPIO_InitTypeDef gpioInit;
|
||||
LL_GPIO_StructInit(&gpioInit);
|
||||
|
||||
stm32_gpio_enable_clock(TOUCH_RST_GPIO);
|
||||
stm32_gpio_enable_clock(TOUCH_INT_GPIO);
|
||||
|
||||
gpioInit.Mode = LL_GPIO_MODE_OUTPUT;
|
||||
gpioInit.Speed = LL_GPIO_SPEED_FREQ_LOW;
|
||||
gpioInit.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
|
||||
gpioInit.Pull = LL_GPIO_PULL_NO;
|
||||
|
||||
gpioInit.Pin = TOUCH_RST_GPIO_PIN;
|
||||
LL_GPIO_Init(TOUCH_RST_GPIO, &gpioInit);
|
||||
LL_GPIO_SetOutputPin(TOUCH_RST_GPIO, TOUCH_RST_GPIO_PIN);
|
||||
|
||||
gpioInit.Pin = TOUCH_INT_GPIO_PIN;
|
||||
gpioInit.Mode = LL_GPIO_MODE_INPUT;
|
||||
gpioInit.Pull = LL_GPIO_PULL_UP;
|
||||
gpioInit.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
|
||||
LL_GPIO_Init(TOUCH_INT_GPIO, &gpioInit);
|
||||
LL_GPIO_SetOutputPin(TOUCH_INT_GPIO, TOUCH_INT_GPIO_PIN);
|
||||
}
|
||||
|
||||
void I2C_Init_Radio(void)
|
||||
{
|
||||
TRACE("CST340 I2C Init");
|
||||
|
||||
if (stm32_i2c_init(TOUCH_I2C_BUS, TOUCH_I2C_CLK_RATE) < 0) {
|
||||
TRACE("CST340 ERROR: stm32_i2c_init failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// void Touch_DeInit()
|
||||
// {
|
||||
// I2C_DeInit(I2C_B1);
|
||||
// __HAL_RCC_I2C1_FORCE_RESET();
|
||||
// delay_ms(150);
|
||||
// __HAL_RCC_I2C1_RELEASE_RESET();
|
||||
// }
|
||||
|
||||
#define I2C_TIMEOUT_MAX 5 // 5 ms
|
||||
|
||||
bool touch_i2c_read(uint8_t addr, uint8_t reg, uint8_t * data, uint8_t len)
|
||||
{
|
||||
// if(touchController == TC_CST836U)
|
||||
// {
|
||||
// if(stm32_i2c_master_tx(TOUCH_I2C_BUS, addr, ®, 1, 3) < 0)
|
||||
// return false;
|
||||
// delay_us(5);
|
||||
// if(stm32_i2c_master_rx(TOUCH_I2C_BUS, addr, data, len, I2C_TIMEOUT_MAX) < 0)
|
||||
// return false;
|
||||
// } else {
|
||||
if (stm32_i2c_read(TOUCH_I2C_BUS, addr, reg, 1, data, len, I2C_TIMEOUT_MAX) < 0)
|
||||
return false;
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static bool touch_i2c_write(uint8_t addr, uint8_t reg, uint8_t * data, uint8_t len)
|
||||
{
|
||||
if (stm32_i2c_write(TOUCH_I2C_BUS, addr, reg, 1, data, len, I2C_TIMEOUT_MAX) < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void TS_IO_Write(uint8_t addr, uint8_t reg, uint8_t data)
|
||||
{
|
||||
uint8_t tryCount = 3;
|
||||
while (!touch_i2c_write(addr, reg, &data, 1)) {
|
||||
if (--tryCount == 0) break;
|
||||
I2C_Init();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint8_t TS_IO_Read(uint8_t addr, uint8_t reg)
|
||||
{
|
||||
uint8_t result;
|
||||
uint8_t tryCount = 3;
|
||||
while (!touch_i2c_read(addr, reg, &result, 1)) {
|
||||
if (--tryCount == 0) break;
|
||||
I2C_Init_Radio();
|
||||
// I2C_Init();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint16_t TS_IO_ReadMultiple(uint8_t addr, uint8_t reg, uint8_t * buffer, uint16_t length)
|
||||
{
|
||||
uint8_t tryCount = 3;
|
||||
while (!touch_i2c_read(addr, reg, buffer, length)) {
|
||||
if (--tryCount == 0) break;
|
||||
I2C_Init_Radio();
|
||||
// I2C_Init();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void touch_ft6236_debug_info(void)
|
||||
{
|
||||
#if defined(DEBUG)
|
||||
TRACE("ft6x36: thrhld = %d", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_TH_GROUP) * 4);
|
||||
TRACE("ft6x36: rep rate=", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_PERIODACTIVE) * 10);
|
||||
TRACE("ft6x36: fw lib 0x%02X %02X", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_LIB_VER_H), TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_LIB_VER_L));
|
||||
TRACE("ft6x36: fw v 0x%02X", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_FIRMID));
|
||||
TRACE("ft6x36: CHIP ID 0x%02X", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_CIPHER));
|
||||
TRACE("ft6x36: CTPM ID 0x%02X", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_FOCALTECH_ID));
|
||||
TRACE("ft6x36: rel code 0x%02X", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_RELEASE_CODE_ID));
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return if there is touches detected or not.
|
||||
* Try to detect new touches and forget the old ones (reset internal global
|
||||
* variables).
|
||||
* @param DeviceAddr: Device address on communication Bus.
|
||||
* @retval : Number of active touches detected (can be 0, 1 or 2).
|
||||
*/
|
||||
static uint8_t ft6x06_TS_DetectTouch()
|
||||
{
|
||||
volatile uint8_t nbTouch = 0;
|
||||
|
||||
/* Read register FT6206_TD_STAT_REG to check number of touches detection */
|
||||
nbTouch = TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, FT6206_TD_STAT_REG);
|
||||
nbTouch &= FT6206_TD_STAT_MASK;
|
||||
if (nbTouch > FT6206_MAX_DETECTABLE_TOUCH) {
|
||||
/* If invalid number of touch detected, set it to zero */
|
||||
nbTouch = 0;
|
||||
}
|
||||
/* Update ft6x06 driver internal global : current number of active touches */
|
||||
tc_handle.currActiveTouchNb = nbTouch;
|
||||
|
||||
/* Reset current active touch index on which to work on */
|
||||
tc_handle.currActiveTouchIdx = 0;
|
||||
return (nbTouch);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* @brief Get the touch detailed informations on touch number 'touchIdx' (0..1)
|
||||
* This touch detailed information contains :
|
||||
* - weight that was applied to this touch
|
||||
* - sub-area of the touch in the touch panel
|
||||
* - event of linked to the touch (press down, lift up, ...)
|
||||
* @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6x06).
|
||||
* @param touchIdx : Passed index of the touch (0..1) on which we want to get the
|
||||
* detailed information.
|
||||
* @param pWeight : Pointer to to get the weight information of 'touchIdx'.
|
||||
* @param pArea : Pointer to to get the sub-area information of 'touchIdx'.
|
||||
* @param pEvent : Pointer to to get the event information of 'touchIdx'.
|
||||
|
||||
* @retval None.
|
||||
*/
|
||||
static void ft6x06_TS_GetTouchInfo(uint16_t DeviceAddr,
|
||||
uint32_t touchIdx,
|
||||
uint32_t * pWeight,
|
||||
uint32_t * pArea,
|
||||
uint32_t * pEvent)
|
||||
{
|
||||
uint8_t regAddress = 0;
|
||||
uint8_t dataxy[3];
|
||||
|
||||
if (touchIdx < ft6x06_handle.currActiveTouchNb) {
|
||||
switch (touchIdx) {
|
||||
case 0 :
|
||||
regAddress = FT6206_P1_WEIGHT_REG;
|
||||
break;
|
||||
|
||||
case 1 :
|
||||
regAddress = FT6206_P2_WEIGHT_REG;
|
||||
break;
|
||||
|
||||
default :
|
||||
break;
|
||||
|
||||
} /* end switch(touchIdx) */
|
||||
|
||||
/* Read weight, area and Event Id of touch index */
|
||||
TS_IO_ReadMultiple(DeviceAddr, regAddress, dataxy, sizeof(dataxy));
|
||||
|
||||
/* Return weight of touch index */
|
||||
*pWeight = (dataxy[0] & FT6206_TOUCH_WEIGHT_MASK) >> FT6206_TOUCH_WEIGHT_SHIFT;
|
||||
/* Return area of touch index */
|
||||
*pArea = (dataxy[1] & FT6206_TOUCH_AREA_MASK) >> FT6206_TOUCH_AREA_SHIFT;
|
||||
/* Return Event Id of touch index */
|
||||
*pEvent = (dataxy[2] & FT6206_TOUCH_EVT_FLAG_MASK) >> FT6206_TOUCH_EVT_FLAG_SHIFT;
|
||||
|
||||
} /* of if(touchIdx < ft6x06_handle.currActiveTouchNb) */
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Get the touch screen X and Y positions values
|
||||
* Manage multi touch thanks to touch Index global
|
||||
* variable 'tc_handle.currActiveTouchIdx'.
|
||||
* @param DeviceAddr: Device address on communication Bus.
|
||||
* @param X: Pointer to X position value
|
||||
* @param Y: Pointer to Y position value
|
||||
* @retval None.
|
||||
*/
|
||||
static void ft6x06_TS_GetXY(uint16_t * X, uint16_t * Y, uint32_t * event)
|
||||
{
|
||||
uint8_t regAddress = 0;
|
||||
uint8_t dataxy[4];
|
||||
|
||||
if (tc_handle.currActiveTouchIdx < tc_handle.currActiveTouchNb) {
|
||||
switch (tc_handle.currActiveTouchIdx) {
|
||||
case 0 :
|
||||
regAddress = FT6206_P1_XH_REG;
|
||||
break;
|
||||
case 1 :
|
||||
regAddress = FT6206_P2_XH_REG;
|
||||
break;
|
||||
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
/* Read X and Y positions */
|
||||
TS_IO_ReadMultiple(TOUCH_FT6236_I2C_ADDRESS, regAddress, dataxy, sizeof(dataxy));
|
||||
/* Send back ready X position to caller */
|
||||
*X = ((dataxy[0] & FT6206_MSB_MASK) << 8) | (dataxy[1] & FT6206_LSB_MASK);
|
||||
/* Send back ready Y position to caller */
|
||||
*Y = ((dataxy[2] & FT6206_MSB_MASK) << 8) | (dataxy[3] & FT6206_LSB_MASK);
|
||||
|
||||
*event = (dataxy[0] & FT6206_TOUCH_EVT_FLAG_MASK) >> FT6206_TOUCH_EVT_FLAG_SHIFT;
|
||||
/*
|
||||
uint32_t weight;
|
||||
uint32_t area;
|
||||
ft6x06_TS_GetTouchInfo(DeviceAddr, ft6x06_handle.currActiveTouchIdx, &weight, &area, event);
|
||||
*/
|
||||
tc_handle.currActiveTouchIdx++;
|
||||
}
|
||||
}
|
||||
|
||||
static void touch_cst340_debug_info(void)
|
||||
{
|
||||
#if 0 // Disabled because cannot compile, will fix when necessary
|
||||
#if defined(DEBUG)
|
||||
uint8_t tmp[4];
|
||||
if (!TS_IO_Write(CST340_MODE_DEBUG_INFO, tmp, 0))
|
||||
TRACE("CST340 chip NOT FOUND");
|
||||
|
||||
// Check the value, expected ChipID
|
||||
uint32_t chipId = tmp[0] << 8) + tmp[1];
|
||||
|
||||
if (!I2C_CST340_ReadRegister(CST340_FWVER_REG, tmp, 4))
|
||||
TRACE("Error reading CST340 firmware version!");
|
||||
uint32_t fwVersion = tmp[0] << 24 | tmp[1]<<16 | tmp[2]<<8 | tmp[0];
|
||||
|
||||
// Enter normal mode
|
||||
if (!I2C_CST340_WriteRegister(CST340_MODE_NORMAL, tmp, 0))
|
||||
TRACE("ERROR chaning CST340 mode back to normal!");
|
||||
|
||||
TRACE("cst340: fw ver 0x%08X", fwVersion);
|
||||
TRACE("cst836u: chip id 0x%04X", chipId);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the touch screen X and Y positions values
|
||||
* @param DeviceAddr: Device address on communication Bus.
|
||||
* @param X: Pointer to X position value
|
||||
* @param Y: Pointer to Y position value
|
||||
* @retval None.
|
||||
*/
|
||||
static void cst340_TS_GetXY(uint16_t * X, uint16_t * Y, uint32_t * event)
|
||||
{
|
||||
uint8_t dataxy[4];
|
||||
|
||||
/* Read X and Y positions */
|
||||
TS_IO_ReadMultiple(TOUCH_CST340_I2C_ADDRESS, CST340_FINGER1_REG, dataxy, sizeof(dataxy));
|
||||
/* Send back ready X position to caller */
|
||||
*X = ((dataxy[1]<<4) + ((dataxy[3]>>4)&0x0f));
|
||||
*Y = ((dataxy[2]<<4) + ((dataxy[3])&0x0f));
|
||||
/* Send back ready Y position to caller */
|
||||
|
||||
*event = dataxy[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return if there is touches detected or not.
|
||||
* Try to detect new touches and forget the old ones (reset internal global
|
||||
* variables).
|
||||
* @param DeviceAddr: Device address on communication Bus.
|
||||
* @retval : Number of active touches detected
|
||||
*/
|
||||
static uint8_t cst340_TS_DetectTouch()
|
||||
{
|
||||
uint8_t nbTouch;
|
||||
uint8_t reg = TS_IO_Read(TOUCH_CST340_I2C_ADDRESS, CST340_FINGER1_REG);
|
||||
if( reg == 0x06 )
|
||||
nbTouch = 1;
|
||||
else
|
||||
nbTouch = 0;
|
||||
|
||||
tc_handle.currActiveTouchNb = nbTouch;
|
||||
|
||||
tc_handle.currActiveTouchIdx = 0;
|
||||
return (nbTouch);
|
||||
}
|
||||
|
||||
void TouchReset()
|
||||
{
|
||||
LL_GPIO_ResetOutputPin(TOUCH_RST_GPIO, TOUCH_RST_GPIO_PIN);
|
||||
delay_ms(10);
|
||||
LL_GPIO_SetOutputPin(TOUCH_RST_GPIO, TOUCH_RST_GPIO_PIN);
|
||||
delay_ms(300);
|
||||
}
|
||||
|
||||
static const TouchControllerDescriptor FT6236 =
|
||||
{
|
||||
.read = ft6x06_TS_GetXY,
|
||||
.detectTouch = ft6x06_TS_DetectTouch,
|
||||
.printDebugInfo = touch_ft6236_debug_info,
|
||||
.contactEvent = FT6206_TOUCH_EVT_FLAG_CONTACT
|
||||
};
|
||||
static const TouchControllerDescriptor CST340 =
|
||||
{
|
||||
.read = cst340_TS_GetXY,
|
||||
.detectTouch = cst340_TS_DetectTouch,
|
||||
.printDebugInfo = touch_cst340_debug_info,
|
||||
.contactEvent = CST340_TOUCH_EVT_FLAG_CONTACT
|
||||
};
|
||||
|
||||
void detectTouchController()
|
||||
{
|
||||
if( stm32_i2c_is_dev_ready(TOUCH_I2C_BUS, TOUCH_CST340_I2C_ADDRESS, 3, 5) == 0)
|
||||
{
|
||||
TouchControllerType = 0;
|
||||
touchController = TC_CST340;
|
||||
tc = &CST340;
|
||||
} else {
|
||||
TouchControllerType = 1;
|
||||
touchController = TC_FT6236;
|
||||
tc = &FT6236;
|
||||
}
|
||||
}
|
||||
|
||||
void TouchInit()
|
||||
{
|
||||
TOUCH_AF_GPIOConfig(); // SET RST=OUT INT=IN INT=HIGH
|
||||
I2C_Init_Radio();
|
||||
TouchReset();
|
||||
detectTouchController();
|
||||
TOUCH_AF_ExtiConfig();
|
||||
|
||||
tc->printDebugInfo();
|
||||
}
|
||||
|
||||
void handleTouch()
|
||||
{
|
||||
unsigned short touchX;
|
||||
unsigned short touchY;
|
||||
uint32_t tEvent = 0;
|
||||
tc->read(&touchX, &touchY, &tEvent);
|
||||
|
||||
#if defined(DEBUG)
|
||||
TRACE("handleTouch: touchX=%d, touchY=%d, tEvent=%d", touchX, touchY, tEvent);
|
||||
#endif
|
||||
// touch sensor is rotated by 90 deg
|
||||
unsigned short tmp = touchY;
|
||||
touchY = 319 - touchX;
|
||||
touchX = tmp;
|
||||
|
||||
if (tEvent == tc->contactEvent) {
|
||||
int dx = touchX - internalTouchState.x;
|
||||
int dy = touchY - internalTouchState.y;
|
||||
|
||||
internalTouchState.x = touchX;
|
||||
internalTouchState.y = touchY;
|
||||
|
||||
if (internalTouchState.event == TE_NONE || internalTouchState.event == TE_UP || internalTouchState.event == TE_SLIDE_END) {
|
||||
internalTouchState.startX = internalTouchState.x;
|
||||
internalTouchState.startY = internalTouchState.y;
|
||||
internalTouchState.event = TE_DOWN;
|
||||
}
|
||||
else if (internalTouchState.event == TE_DOWN) {
|
||||
if (dx >= SLIDE_RANGE || dx <= -SLIDE_RANGE || dy >= SLIDE_RANGE || dy <= -SLIDE_RANGE) {
|
||||
internalTouchState.event = TE_SLIDE;
|
||||
internalTouchState.deltaX = (short) dx;
|
||||
internalTouchState.deltaY = (short) dy;
|
||||
}
|
||||
else {
|
||||
internalTouchState.event = TE_DOWN;
|
||||
internalTouchState.deltaX = 0;
|
||||
internalTouchState.deltaY = 0;
|
||||
}
|
||||
}
|
||||
else if (internalTouchState.event == TE_SLIDE) {
|
||||
internalTouchState.event = TE_SLIDE; //no change
|
||||
internalTouchState.deltaX = (short) dx;
|
||||
internalTouchState.deltaY = (short) dy;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static bool lastHasTouch = false;
|
||||
bool touchPanelEventOccured()
|
||||
{
|
||||
bool result = touchEventOccured;
|
||||
uint8_t hasTouch = false;
|
||||
if (touchEventOccured) {
|
||||
hasTouch = tc->detectTouch();
|
||||
if (!hasTouch && !lastHasTouch) {
|
||||
touchEventOccured = false;
|
||||
result = false;
|
||||
}
|
||||
lastHasTouch = hasTouch;
|
||||
}
|
||||
|
||||
#if defined(DEBUG)
|
||||
TRACE("TouchEvent: %d, %d, %d, %d", touchEventOccured, lastHasTouch, hasTouch, result);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
TouchState touchPanelRead()
|
||||
{
|
||||
if (!touchEventOccured) return internalTouchState;
|
||||
|
||||
touchEventOccured = false;
|
||||
|
||||
tmr10ms_t now = get_tmr10ms();
|
||||
internalTouchState.tapCount = 0;
|
||||
|
||||
if (tc->detectTouch()) {
|
||||
handleTouch();
|
||||
if (internalTouchState.event == TE_DOWN && downTime == 0) {
|
||||
downTime = now;
|
||||
}
|
||||
} else {
|
||||
if (internalTouchState.event == TE_DOWN) {
|
||||
internalTouchState.event = TE_UP;
|
||||
if (now - downTime <= TAP_TIME) {
|
||||
if (now - tapTime > TAP_TIME) {
|
||||
tapCount = 1;
|
||||
} else {
|
||||
tapCount++;
|
||||
}
|
||||
internalTouchState.tapCount = tapCount;
|
||||
tapTime = now;
|
||||
} else {
|
||||
internalTouchState.tapCount = 0; // not a tap
|
||||
}
|
||||
downTime = 0;
|
||||
} else {
|
||||
tapCount = 0;
|
||||
internalTouchState.tapCount = 0;
|
||||
internalTouchState.event = TE_SLIDE_END;
|
||||
}
|
||||
}
|
||||
TouchState ret = internalTouchState;
|
||||
internalTouchState.deltaX = 0;
|
||||
internalTouchState.deltaY = 0;
|
||||
if(internalTouchState.event == TE_UP || internalTouchState.event == TE_SLIDE_END)
|
||||
internalTouchState.event = TE_NONE;
|
||||
|
||||
#if defined(DEBUG)
|
||||
TRACE("%s: Event = %d", touchController == TC_CST340 ? "CST340" : "FT6236", ret.event);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
TouchState getInternalTouchState()
|
||||
{
|
||||
return internalTouchState;
|
||||
}
|
289
radio/src/targets/pl18/tp_cst340.h
Normal file
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "touch.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* field holding the current number of simultaneous active touches */
|
||||
uint8_t currActiveTouchNb;
|
||||
|
||||
/* field holding the touch index currently managed */
|
||||
uint8_t currActiveTouchIdx;
|
||||
|
||||
} tc_handle_TypeDef;
|
||||
|
||||
|
||||
#define TOUCH_FT6236_MAX_TOUCH_POINTS 2
|
||||
|
||||
#define TOUCH_FT6236_REG_TH_GROUP 0x80
|
||||
#define TOUCH_FT6236_REG_PERIODACTIVE 0x88
|
||||
#define TOUCH_FT6236_REG_LIB_VER_H 0xa1
|
||||
#define TOUCH_FT6236_REG_LIB_VER_L 0xa2
|
||||
#define TOUCH_FT6236_REG_CIPHER 0xa3
|
||||
#define TOUCH_FT6236_REG_FIRMID 0xa6
|
||||
#define TOUCH_FT6236_REG_FOCALTECH_ID 0xa8
|
||||
#define TOUCH_FT6236_REG_RELEASE_CODE_ID 0xaf
|
||||
|
||||
#define TOUCH_FT6236_EVENT_PRESS_DOWN 0
|
||||
#define TOUCH_FT6236_EVENT_LIFT_UP 1
|
||||
#define TOUCH_FT6236_EVENT_CONTACT 2
|
||||
#define TOUCH_FT6236_EVENT_NO_EVENT 3
|
||||
|
||||
#define TOUCH_FT6236_GESTURE_MOVE_FLAG 0x10
|
||||
#define TOUCH_FT6236_GESTURE_MOVE_UP 0x10
|
||||
#define TOUCH_FT6236_GESTURE_MOVE_RIGHT 0x14
|
||||
#define TOUCH_FT6236_GESTURE_MOVE_DOWN 0x18
|
||||
#define TOUCH_FT6236_GESTURE_MOVE_LEFT 0x1C
|
||||
#define TOUCH_FT6236_GESTURE_ZOOM_IN 0x48
|
||||
#define TOUCH_FT6236_GESTURE_ZOOM_OUT 0x49
|
||||
#define TOUCH_FT6236_GESTURE_NONE 0x00
|
||||
|
||||
#define TOUCH_GESTURE_UP ((TOUCH_FT6236_GESTURE_MOVE_UP & 0x0F)+1)
|
||||
#define TOUCH_GESTURE_DOWN ((TOUCH_FT6236_GESTURE_MOVE_DOWN & 0x0F)+1)
|
||||
#define TOUCH_GESTURE_LEFT ((TOUCH_FT6236_GESTURE_MOVE_LEFT & 0x0F)+1)
|
||||
#define TOUCH_GESTURE_RIGHT ((TOUCH_FT6236_GESTURE_MOVE_RIGHT & 0x0F)+1)
|
||||
#define TOUCH_GESTURE_MOUSE_DOWN (0x80+TOUCH_FT6236_EVENT_PRESS_DOWN)
|
||||
#define TOUCH_GESTURE_MOUSE_UP (0x80+TOUCH_FT6236_EVENT_LIFT_UP)
|
||||
#define TOUCH_GESTURE_MOUSE_MOVE (0x80+TOUCH_FT6236_EVENT_CONTACT)
|
||||
#define TOUCH_GESTURE_MOUSE_NONE (0x80+TOUCH_FT6236_EVENT_NO_EVENT)
|
||||
|
||||
|
||||
|
||||
/* Maximum border values of the touchscreen pad */
|
||||
#define FT_6206_MAX_WIDTH ((uint16_t)800) /* Touchscreen pad max width */
|
||||
#define FT_6206_MAX_HEIGHT ((uint16_t)480) /* Touchscreen pad max height */
|
||||
|
||||
/* Possible values of driver functions return status */
|
||||
#define FT6206_STATUS_OK 0
|
||||
#define FT6206_STATUS_NOT_OK 1
|
||||
|
||||
/* Max detectable simultaneous touches */
|
||||
#define FT6206_MAX_DETECTABLE_TOUCH 2
|
||||
|
||||
/**
|
||||
* @brief : Definitions for FT6206 I2C register addresses on 8 bit
|
||||
**/
|
||||
|
||||
/* Current mode register of the FT6206 (R/W) */
|
||||
#define FT6206_DEV_MODE_REG 0x00
|
||||
|
||||
/* Possible values of FT6206_DEV_MODE_REG */
|
||||
#define FT6206_DEV_MODE_WORKING 0x00
|
||||
#define FT6206_DEV_MODE_FACTORY 0x04
|
||||
|
||||
#define FT6206_DEV_MODE_MASK 0x7
|
||||
#define FT6206_DEV_MODE_SHIFT 4
|
||||
|
||||
/* Gesture ID register */
|
||||
#define FT6206_GEST_ID_REG 0x01
|
||||
|
||||
/* Possible values of FT6206_GEST_ID_REG */
|
||||
#define FT6206_GEST_ID_NO_GESTURE 0x00
|
||||
#define FT6206_GEST_ID_MOVE_UP 0x10
|
||||
#define FT6206_GEST_ID_MOVE_RIGHT 0x14
|
||||
#define FT6206_GEST_ID_MOVE_DOWN 0x18
|
||||
#define FT6206_GEST_ID_MOVE_LEFT 0x1C
|
||||
#define FT6206_GEST_ID_ZOOM_IN 0x48
|
||||
#define FT6206_GEST_ID_ZOOM_OUT 0x49
|
||||
|
||||
/* Touch Data Status register : gives number of active touch points (0..2) */
|
||||
#define FT6206_TD_STAT_REG 0x02
|
||||
|
||||
/* Values related to FT6206_TD_STAT_REG */
|
||||
#define FT6206_TD_STAT_MASK 0x0F
|
||||
#define FT6206_TD_STAT_SHIFT 0x00
|
||||
|
||||
/* Values Pn_XH and Pn_YH related */
|
||||
#define FT6206_TOUCH_EVT_FLAG_PRESS_DOWN 0x00
|
||||
#define FT6206_TOUCH_EVT_FLAG_LIFT_UP 0x01
|
||||
#define FT6206_TOUCH_EVT_FLAG_CONTACT 0x02
|
||||
#define FT6206_TOUCH_EVT_FLAG_NO_EVENT 0x03
|
||||
|
||||
#define FT6206_TOUCH_EVT_FLAG_SHIFT 6
|
||||
#define FT6206_TOUCH_EVT_FLAG_MASK (3 << FT6206_TOUCH_EVT_FLAG_SHIFT)
|
||||
|
||||
#define FT6206_MSB_MASK 0x0F
|
||||
#define FT6206_MSB_SHIFT 0
|
||||
|
||||
/* Values Pn_XL and Pn_YL related */
|
||||
#define FT6206_LSB_MASK 0xFF
|
||||
#define FT6206_LSB_SHIFT 0
|
||||
|
||||
#define FT6206_P1_XH_REG 0x03
|
||||
#define FT6206_P1_XL_REG 0x04
|
||||
#define FT6206_P1_YH_REG 0x05
|
||||
#define FT6206_P1_YL_REG 0x06
|
||||
|
||||
/* Touch Pressure register value (R) */
|
||||
#define FT6206_P1_WEIGHT_REG 0x07
|
||||
|
||||
/* Values Pn_WEIGHT related */
|
||||
#define FT6206_TOUCH_WEIGHT_MASK 0xFF
|
||||
#define FT6206_TOUCH_WEIGHT_SHIFT 0
|
||||
|
||||
/* Touch area register */
|
||||
#define FT6206_P1_MISC_REG 0x08
|
||||
|
||||
/* Values related to FT6206_Pn_MISC_REG */
|
||||
#define FT6206_TOUCH_AREA_MASK (0x04 << 4)
|
||||
#define FT6206_TOUCH_AREA_SHIFT 0x04
|
||||
|
||||
#define FT6206_P2_XH_REG 0x09
|
||||
#define FT6206_P2_XL_REG 0x0A
|
||||
#define FT6206_P2_YH_REG 0x0B
|
||||
#define FT6206_P2_YL_REG 0x0C
|
||||
#define FT6206_P2_WEIGHT_REG 0x0D
|
||||
#define FT6206_P2_MISC_REG 0x0E
|
||||
|
||||
/* Threshold for touch detection */
|
||||
#define FT6206_TH_GROUP_REG 0x80
|
||||
|
||||
/* Values FT6206_TH_GROUP_REG : threshold related */
|
||||
#define FT6206_THRESHOLD_MASK 0xFF
|
||||
#define FT6206_THRESHOLD_SHIFT 0
|
||||
|
||||
/* Filter function coefficients */
|
||||
#define FT6206_TH_DIFF_REG 0x85
|
||||
|
||||
/* Control register */
|
||||
#define FT6206_CTRL_REG 0x86
|
||||
|
||||
/* Values related to FT6206_CTRL_REG */
|
||||
|
||||
/* Will keep the Active mode when there is no touching */
|
||||
#define FT6206_CTRL_KEEP_ACTIVE_MODE 0x00
|
||||
|
||||
/* Switching from Active mode to Monitor mode automatically when there is no touching */
|
||||
#define FT6206_CTRL_KEEP_AUTO_SWITCH_MONITOR_MODE 0x01
|
||||
|
||||
/* The time period of switching from Active mode to Monitor mode when there is no touching */
|
||||
#define FT6206_TIMEENTERMONITOR_REG 0x87
|
||||
|
||||
/* Report rate in Active mode */
|
||||
#define FT6206_PERIODACTIVE_REG 0x88
|
||||
|
||||
/* Report rate in Monitor mode */
|
||||
#define FT6206_PERIODMONITOR_REG 0x89
|
||||
|
||||
/* The value of the minimum allowed angle while Rotating gesture mode */
|
||||
#define FT6206_RADIAN_VALUE_REG 0x91
|
||||
|
||||
/* Maximum offset while Moving Left and Moving Right gesture */
|
||||
#define FT6206_OFFSET_LEFT_RIGHT_REG 0x92
|
||||
|
||||
/* Maximum offset while Moving Up and Moving Down gesture */
|
||||
#define FT6206_OFFSET_UP_DOWN_REG 0x93
|
||||
|
||||
/* Minimum distance while Moving Left and Moving Right gesture */
|
||||
#define FT6206_DISTANCE_LEFT_RIGHT_REG 0x94
|
||||
|
||||
/* Minimum distance while Moving Up and Moving Down gesture */
|
||||
#define FT6206_DISTANCE_UP_DOWN_REG 0x95
|
||||
|
||||
/* Maximum distance while Zoom In and Zoom Out gesture */
|
||||
#define FT6206_DISTANCE_ZOOM_REG 0x96
|
||||
|
||||
/* High 8-bit of LIB Version info */
|
||||
#define FT6206_LIB_VER_H_REG 0xA1
|
||||
|
||||
/* Low 8-bit of LIB Version info */
|
||||
#define FT6206_LIB_VER_L_REG 0xA2
|
||||
|
||||
/* Chip Selecting */
|
||||
#define FT6206_CIPHER_REG 0xA3
|
||||
|
||||
/* Interrupt mode register (used when in interrupt mode) */
|
||||
#define FT6206_GMODE_REG 0xA4
|
||||
|
||||
#define FT6206_G_MODE_INTERRUPT_MASK 0x03
|
||||
#define FT6206_G_MODE_INTERRUPT_SHIFT 0x00
|
||||
|
||||
/* Possible values of FT6206_GMODE_REG */
|
||||
#define FT6206_G_MODE_INTERRUPT_POLLING 0x00
|
||||
#define FT6206_G_MODE_INTERRUPT_TRIGGER 0x01
|
||||
|
||||
/* Current power mode the FT6206 system is in (R) */
|
||||
#define FT6206_PWR_MODE_REG 0xA5
|
||||
|
||||
/* FT6206 firmware version */
|
||||
#define FT6206_FIRMID_REG 0xA6
|
||||
|
||||
/* FT6206 Chip identification register */
|
||||
#define FT6206_CHIP_ID_REG 0xA8
|
||||
|
||||
/* Possible values of FT6206_CHIP_ID_REG */
|
||||
#define FT6206_ID_VALUE 0x11
|
||||
|
||||
/* Release code version */
|
||||
#define FT6206_RELEASE_CODE_ID_REG 0xAF
|
||||
|
||||
/* Current operating mode the FT6206 system is in (R) */
|
||||
#define FT6206_STATE_REG 0xBC
|
||||
|
||||
|
||||
|
||||
#define HAS_TOUCH_PANEL() touchCST340Flag == true
|
||||
|
||||
#define CST340_MODE_DEBUG_INFO 0xD101 // To read out chip ID and firmware version
|
||||
#define CST340_MODE_NORMAL 0xD109 // Normal mode
|
||||
#define CST340_FINGER1_REG 0xD000 // Touch info register
|
||||
#define CST340_CHIPTYPE_REG 0xD204 // uint16_t chip IC type & uint16_t project ID register
|
||||
#define CST340_FWVER_REG 0xD208 // Firmware version register(uint8_t major, uint8_t minor, uint16_t build)
|
||||
#define CST340_TOUCH_EVT_FLAG_CONTACT 6
|
||||
|
||||
#define CST340_CHIP_ID 0x011C // Expected answer to CST340_CHIPTYPE_REG query for the ChipID field
|
||||
|
||||
#define TOUCH_POINTS_MAX 5 // Max touch points
|
||||
|
||||
#define TOUCH_ACK 0
|
||||
#define TOUCH_NACK 1
|
||||
|
||||
#define CST340_I2C_ADDR 0x1A
|
||||
|
||||
extern bool touchCST340Flag;
|
||||
extern uint32_t touchI2Chiccups;
|
||||
extern uint16_t touchICfwver;
|
||||
void TouchInit();
|
||||
|
||||
struct TouchState touchPanelRead();
|
||||
bool touchPanelEventOccured();
|
||||
|
||||
PACK(typedef struct {
|
||||
uint8_t track;
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
uint16_t size;
|
||||
uint8_t reserved;
|
||||
}) TouchPoint;
|
||||
|
||||
PACK(struct TouchData {
|
||||
union
|
||||
{
|
||||
TouchPoint points[TOUCH_POINTS_MAX];
|
||||
uint8_t data[TOUCH_POINTS_MAX * sizeof(TouchPoint)];
|
||||
};
|
||||
});
|
||||
|
||||
#define TPRST_LOW() do { TOUCH_RST_GPIO->BSRRH = TOUCH_RST_GPIO_PIN; } while(0)
|
||||
#define TPRST_HIGH() do { TOUCH_RST_GPIO->BSRRL = TOUCH_RST_GPIO_PIN; } while(0)
|
|
@ -712,6 +712,8 @@ class OpenTxSimulatorFactory: public SimulatorFactory
|
|||
return Board::BOARD_TARANIS_X9LITE;
|
||||
#elif defined(PCBNV14)
|
||||
return Board::BOARD_FLYSKY_NV14;
|
||||
#elif defined(PCBPL18)
|
||||
return Board::BOARD_FLYSKY_PL18;
|
||||
#else
|
||||
return Board::BOARD_TARANIS_X9D;
|
||||
#endif
|
||||
|
|
|
@ -535,7 +535,7 @@ void boardOff()
|
|||
|
||||
void hapticOff() {}
|
||||
|
||||
#if defined(PCBFRSKY) || defined(PCBFLYSKY)
|
||||
#if defined(PCBFRSKY) || defined(PCBNV14)
|
||||
HardwareOptions hardwareOptions;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -616,6 +616,7 @@ FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs)
|
|||
#include "hal/storage.h"
|
||||
|
||||
void storageInit() {}
|
||||
void storageDeInit() {}
|
||||
void storagePreMountHook() {}
|
||||
bool storageIsPresent() { return true; }
|
||||
|
||||
|
|
|
@ -480,10 +480,6 @@ else()
|
|||
message( FATAL_ERROR "Unknown CPU_TYPE_FULL" )
|
||||
endif()
|
||||
|
||||
if(NOT PCB STREQUAL PCBXLITE)
|
||||
add_definitions(-DHARDWARE_TRAINER_JACK)
|
||||
endif()
|
||||
|
||||
if(ENABLE_SERIAL_PASSTHROUGH)
|
||||
set(CLI ON "Enable CLI")
|
||||
endif()
|
||||
|
|
|
@ -479,4 +479,12 @@ void setTopBatteryValue(uint32_t volts);
|
|||
#define VOLTAGE_DROP 20
|
||||
#endif
|
||||
|
||||
#if defined(RADIO_T20)
|
||||
#define NUM_TRIMS 8
|
||||
#else
|
||||
#define NUM_TRIMS 4
|
||||
#endif
|
||||
|
||||
#define NUM_TRIMS_KEYS (NUM_TRIMS * 2)
|
||||
|
||||
#endif // _BOARD_H_
|
||||
|
|
|
@ -30,8 +30,15 @@
|
|||
#else
|
||||
#define MENUS_STACK_SIZE 2000
|
||||
#endif
|
||||
|
||||
#if !defined(DEBUG)
|
||||
#define MIXER_STACK_SIZE 400
|
||||
#define AUDIO_STACK_SIZE 400
|
||||
#else
|
||||
#define MIXER_STACK_SIZE 512
|
||||
#define AUDIO_STACK_SIZE 512
|
||||
#endif
|
||||
|
||||
#define CLI_STACK_SIZE 1024 // only consumed with CLI build option
|
||||
|
||||
#if defined(FREE_RTOS)
|
||||
|
|
BIN
radio/src/tests/images/color/bitmap_480x320.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
radio/src/tests/images/color/clipping_480x320.png
Normal file
After Width: | Height: | Size: 5 KiB |
BIN
radio/src/tests/images/color/lines_480x320.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
radio/src/tests/images/color/masks_480x320.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
radio/src/tests/images/color/primitives_EN_480x320.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
radio/src/tests/images/color/transparency_EN_480x320.png
Normal file
After Width: | Height: | Size: 9.8 KiB |