Merge pull request #5 from kilrah/bsongis/x-lites-pxx2-update

Bsongis/x lites pxx2 update
This commit is contained in:
Bertrand Songis
2019-03-05 17:05:00 +01:00
committed by GitHub
19 changed files with 329 additions and 163 deletions
+9 -4
View File
@@ -37,7 +37,6 @@
#if defined(PCBHORUS)
#define MAX_MODELS 60
#define MAX_RECEIVERS_PER_MODULE 5
#define MAX_OUTPUT_CHANNELS 32 // number of real output channels CH1-CH32
#define MAX_FLIGHT_MODES 9
#define MAX_MIXERS 64
@@ -51,7 +50,6 @@
#define MAX_CUSTOM_SCREENS 5
#elif defined(PCBTARANIS)
#define MAX_MODELS 60
#define MAX_RECEIVERS_PER_MODULE 2
#define MAX_OUTPUT_CHANNELS 32 // number of real output channels CH1-CH32
#define MAX_FLIGHT_MODES 9
#define MAX_MIXERS 64
@@ -64,7 +62,6 @@
#define MAX_TELEMETRY_SENSORS 32
#elif defined(PCBSKY9X)
#define MAX_MODELS 60
#define MAX_RECEIVERS_PER_MODULE 2
#define MAX_OUTPUT_CHANNELS 32 // number of real output channels CH1-CH32
#define MAX_FLIGHT_MODES 9
#define MAX_MIXERS 64
@@ -127,6 +124,14 @@ enum CurveType {
#define MAX_CURVE_POINTS 512
#endif
#if defined(PCBHORUS)
#define NUM_RECEIVERS 10
#define MAX_RECEIVERS_PER_MODULE 5
#else
#define NUM_RECEIVERS 4
#define MAX_RECEIVERS_PER_MODULE 4
#endif
#if defined(PCBTARANIS) || defined(PCBSKY9X) || defined(PCBHORUS)
#define NUM_MODULES 2
#else
@@ -788,7 +793,7 @@ enum BluetoothModes {
// PXX2 constants
#define PXX2_LEN_REGISTRATION_ID 8
#define PXX2_LEN_RX_NAME 8
#define PXX2_LEN_RX_NAME 8
#define PXX2_MAX_RECEIVERS_PER_MODULE 5
#endif // _DATACONSTANTS_H_
+26 -7
View File
@@ -25,6 +25,7 @@
#include "board.h"
#include "dataconstants.h"
#include "definitions.h"
#include "bitfield.h"
#if defined(PCBTARANIS)
#define N_TARANIS_FIELD(x)
@@ -415,10 +416,13 @@ PACK(struct TrainerModuleData {
*/
PACK(struct ReceiverData {
uint8_t enabled:1;
// 5 bits per receiver output (24) as it can be assigned to one of the 24 channels
uint64_t channelMapping0; // 12 first channels (4 bits spare)
uint64_t channelMapping1:60; // 12 last channels
uint8_t used:1;
uint8_t telemetry:1;
uint8_t spare:6;
uint64_t channelMapping; // each receiver output (16) can be assigned to one of the 16 channels
uint8_t spare:2;
char name[PXX2_LEN_RX_NAME];
});
/*
@@ -478,8 +482,24 @@ PACK(struct ModuleData {
NOBACKUP(struct {
uint8_t power:2; // 0=10 mW, 1=100 mW, 2=500 mW, 3=1W
uint8_t external_antenna:1; // false = internal antenna, true = external antenna
#if defined(PCBHORUS)
uint8_t spare:5;
ReceiverData receivers[MAX_RECEIVERS_PER_MODULE];
uint32_t receivers; // max 5 receivers per module and 10 receivers in total (4bits per receiver with 0 = unused)
#else
uint8_t spare:1;
uint16_t receivers:12; // max 4 receivers per module and 4 receivers in total (3bits per receiver with 0 = unused)
#endif
NOBACKUP(inline uint8_t getReceiverSlot(uint8_t receiver) {
return (receivers >> (3 * receiver)) & 0b111;
})
NOBACKUP(inline void setReceiverSlot(uint8_t receiver, uint8_t slot) {
receivers = BF_SET<uint16_t>(receivers, slot, 3 * receiver, 3);
})
NOBACKUP(inline void clearReceiverSlot(uint8_t receiver) {
setReceiverSlot(receiver, 0);
})
} pxx2);
};
@@ -490,12 +510,10 @@ PACK(struct ModuleData {
return ((uint8_t) (rfProtocol & 0x0f)) + (multi.rfProtocolExtra << 4);
})
NOBACKUP(inline void setMultiProtocol(uint8_t proto)
{
NOBACKUP(inline void setMultiProtocol(uint8_t proto) {
rfProtocol = (uint8_t) (proto & 0x0f);
multi.rfProtocolExtra = (proto & 0x30) >> 4;
})
});
/*
@@ -610,6 +628,7 @@ PACK(struct ModelData {
NOBACKUP(uint8_t spare:6);
NOBACKUP(uint8_t potsWarnMode:2);
ModuleData moduleData[NUM_MODULES];
ReceiverData receiverData[NUM_RECEIVERS];
int16_t failsafeChannels[MAX_OUTPUT_CHANNELS];
TrainerModuleData trainerData;
-2
View File
@@ -199,8 +199,6 @@ void title(const char * s);
#define SIMPLE_SUBMENU_NOTITLE(lines_count) \
check_submenu_simple(event, (lines_count)-1);
#endif
#define SIMPLE_MENU(title, tab, menu, lines_count) \
+111 -52
View File
@@ -91,6 +91,14 @@ enum MenuModelSetupItems {
ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_2_PINMAP,
ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_2_TELEM,
ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_2_BIND_SHARE,
ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_3_LABEL,
ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_3_PINMAP,
ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_3_TELEM,
ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_3_BIND_SHARE,
ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_4_LABEL,
ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_4_PINMAP,
ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_4_TELEM,
ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_4_BIND_SHARE,
#endif
ITEM_MODEL_EXTERNAL_MODULE_LABEL,
ITEM_MODEL_EXTERNAL_MODULE_MODE,
@@ -123,6 +131,14 @@ enum MenuModelSetupItems {
ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_2_PINMAP,
ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_2_TELEM,
ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_2_BIND_SHARE,
ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_3_LABEL,
ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_3_PINMAP,
ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_3_TELEM,
ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_3_BIND_SHARE,
ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_4_LABEL,
ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_4_PINMAP,
ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_4_TELEM,
ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_4_BIND_SHARE,
#if defined(PCBSKY9X) && !defined(REVA)
ITEM_MODEL_EXTRA_MODULE_LABEL,
ITEM_MODEL_EXTRA_MODULE_CHANNELS,
@@ -159,11 +175,11 @@ enum MenuModelSetupItems {
#define IF_PXX2_MODULE(module, xxx) (isModulePXX2(module) ? (uint8_t)(xxx) : HIDDEN_ROW)
#define IF_NOT_PXX2_MODULE(module, xxx) (isModulePXX2(module) ? HIDDEN_ROW : (uint8_t)(xxx))
#define IF_PXX2_RECEIVER_DISPLAYED(module, idx, xxx) ((isModulePXX2(module) && g_model.moduleData[module].pxx2.receivers[idx].enabled) ? (uint8_t)(xxx) : HIDDEN_ROW)
#define IF_PXX2_RECEIVER_DISPLAYED(module, idx, xxx) ((isModulePXX2(module) && g_model.moduleData[module].pxx2.getReceiverSlot(idx)) ? (uint8_t)(xxx) : HIDDEN_ROW)
#if defined(PCBTARANIS)
#define CURRENT_MODULE_EDITED(k) (k >= ITEM_MODEL_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE)
#define CURRENT_RECEIVER_EDITED(k) (k >= (k >= ITEM_MODEL_EXTERNAL_MODULE_LABEL ? ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_2_LABEL : ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_2_LABEL) ? 1 : 0)
#define CURRENT_RECEIVER_EDITED(k) ((k - (k >= ITEM_MODEL_EXTERNAL_MODULE_LABEL ? ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_1_LABEL : ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_1_LABEL)) / 4)
#elif defined(PCBSKY9X) && !defined(REVA)
#define CURRENT_MODULE_EDITED(k) (k >= ITEM_MODEL_EXTRA_MODULE_LABEL ? EXTRA_MODULE : EXTERNAL_MODULE)
#else
@@ -248,7 +264,7 @@ enum MenuModelSetupItems {
void onPXX2BindMenu(const char * result)
{
reusableBuffer.moduleSetup.pxx2.bindSelectedReceiverIndex = (result - reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversNames[0]) / sizeof(reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversNames[0]);
reusableBuffer.moduleSetup.pxx2.bindSelectedReceiverIndex = (result - reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversNames[0]) / PXX2_LEN_RX_NAME;
reusableBuffer.moduleSetup.pxx2.bindStep = BIND_RX_NAME_SELECTED;
}
@@ -361,6 +377,16 @@ inline bool isDefaultModelRegistrationID()
return memcmp(g_model.modelRegistrationID, g_eeGeneral.ownerRegistrationID, PXX2_LEN_REGISTRATION_ID) == 0;
}
uint8_t findEmptyReceiverSlot()
{
for (uint8_t slot=0; slot<NUM_RECEIVERS; slot++) {
if (!g_model.receiverData[slot].used) {
return slot + 1;
}
}
return 0;
}
void menuModelSetup(event_t event)
{
#if defined(EXTERNAL_ANTENNA)
@@ -415,6 +441,14 @@ void menuModelSetup(event_t event)
IF_PXX2_RECEIVER_DISPLAYED(INTERNAL_MODULE, 1, 0), // Receiver2 Pinmap
IF_PXX2_RECEIVER_DISPLAYED(INTERNAL_MODULE, 1, 0), // Receiver2 Telemetry
IF_PXX2_RECEIVER_DISPLAYED(INTERNAL_MODULE, 1, 1), // Receiver2 Bind/Share
IF_PXX2_RECEIVER_DISPLAYED(INTERNAL_MODULE, 1, 0), // Receiver3 Name + Add/Del buttons
IF_PXX2_RECEIVER_DISPLAYED(INTERNAL_MODULE, 2, 0), // Receiver3 Pinmap
IF_PXX2_RECEIVER_DISPLAYED(INTERNAL_MODULE, 2, 0), // Receiver3 Telemetry
IF_PXX2_RECEIVER_DISPLAYED(INTERNAL_MODULE, 2, 1), // Receiver3 Bind/Share
IF_PXX2_RECEIVER_DISPLAYED(INTERNAL_MODULE, 2, 0), // Receiver4 Name + Add/Del buttons
IF_PXX2_RECEIVER_DISPLAYED(INTERNAL_MODULE, 3, 0), // Receiver4 Pinmap
IF_PXX2_RECEIVER_DISPLAYED(INTERNAL_MODULE, 3, 0), // Receiver4 Telemetry
IF_PXX2_RECEIVER_DISPLAYED(INTERNAL_MODULE, 3, 1), // Receiver4 Bind/Share
LABEL(ExternalModule),
EXTERNAL_MODULE_MODE_ROWS,
@@ -438,6 +472,14 @@ void menuModelSetup(event_t event)
IF_PXX2_RECEIVER_DISPLAYED(EXTERNAL_MODULE, 1, 0), // Receiver2 Range
IF_PXX2_RECEIVER_DISPLAYED(EXTERNAL_MODULE, 1, 0), // Receiver2 Telemetry
IF_PXX2_RECEIVER_DISPLAYED(EXTERNAL_MODULE, 1, 1), // Receiver2 Bind/Share
IF_PXX2_RECEIVER_DISPLAYED(EXTERNAL_MODULE, 1, 0), // Receiver3 Name + Add/Del buttons
IF_PXX2_RECEIVER_DISPLAYED(EXTERNAL_MODULE, 2, 0), // Receiver3 Pinmap
IF_PXX2_RECEIVER_DISPLAYED(EXTERNAL_MODULE, 2, 0), // Receiver3 Telemetry
IF_PXX2_RECEIVER_DISPLAYED(EXTERNAL_MODULE, 2, 1), // Receiver3 Bind/Share
IF_PXX2_RECEIVER_DISPLAYED(EXTERNAL_MODULE, 2, 0), // Receiver4 Name + Add/Del buttons
IF_PXX2_RECEIVER_DISPLAYED(EXTERNAL_MODULE, 3, 0), // Receiver4 Pinmap
IF_PXX2_RECEIVER_DISPLAYED(EXTERNAL_MODULE, 3, 0), // Receiver4 Telemetry
IF_PXX2_RECEIVER_DISPLAYED(EXTERNAL_MODULE, 3, 1), // Receiver4 Bind/Share
TRAINER_ROWS
});
@@ -1193,22 +1235,26 @@ void menuModelSetup(event_t event)
case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_1_LABEL:
case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_2_LABEL:
case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_3_LABEL:
case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_4_LABEL:
case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_1_LABEL:
case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_2_LABEL:
case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_3_LABEL:
case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_4_LABEL:
{
uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(k);
uint8_t moduleIdx = CURRENT_MODULE_EDITED(k);
uint8_t receiverSlot = g_model.moduleData[moduleIdx].pxx2.getReceiverSlot(receiverIdx);
lcdDrawTextAlignedLeft(y, STR_RECEIVER);
lcdDrawNumber(lcdLastRightPos + 1, y, receiverIdx + 1);
// lcdDrawSizedText(MODEL_SETUP_2ND_COLUMN, y, g_model.moduleData[moduleIdx].pxx2.receivers[receiverIdx].rxName, PXX2_LEN_RX_NAME, ZCHAR);
if (g_model.moduleData[moduleIdx].pxx2.receivers[receiverIdx].enabled) {
if (receiverSlot) {
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_DEL_BUTTON, attr);
if (attr && s_editMode > 0) {
if (receiverIdx == 0) {
memcpy(&g_model.moduleData[moduleIdx].pxx2.receivers[0], &g_model.moduleData[moduleIdx].pxx2.receivers[1], sizeof(ReceiverData));
}
memclear(&g_model.moduleData[moduleIdx].pxx2.receivers[1], sizeof(ReceiverData)); // we always remove the second receiver data
g_model.moduleData[moduleIdx].pxx2.receivers = (g_model.moduleData[moduleIdx].pxx2.receivers & BF_MASK<uint16_t>(0, receiverIdx * 3)) | ((g_model.moduleData[moduleIdx].pxx2.receivers & BF_MASK<uint16_t>((receiverIdx + 1) * 3, (MAX_RECEIVERS_PER_MODULE - 1 - receiverIdx) * 3)) >> 3);
memclear(&g_model.receiverData[receiverSlot], sizeof(ReceiverData));
s_editMode = 0;
killEvents(event);
storageDirty(EE_MODEL);
@@ -1217,18 +1263,18 @@ void menuModelSetup(event_t event)
else {
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_RXADD_BUTTON, attr);
if (attr && s_editMode > 0) {
if (g_model.moduleData[moduleIdx].pxx2.receivers[0].enabled) {
g_model.moduleData[moduleIdx].pxx2.receivers[1].enabled = 0x01;
memcpy(&g_model.moduleData[moduleIdx].pxx2.receivers[1].channelMapping, DEFAULT_CHANNEL_MAPPING, sizeof(uint64_t));
}
else {
g_model.moduleData[moduleIdx].pxx2.receivers[0].enabled = 0x01;
memcpy(&g_model.moduleData[moduleIdx].pxx2.receivers[0].channelMapping, DEFAULT_CHANNEL_MAPPING, sizeof(uint64_t));
}
menuVerticalPosition += 3;
s_editMode = 0;
killEvents(event);
storageDirty(EE_MODEL);
uint8_t slot = findEmptyReceiverSlot();
if (slot > 0) {
g_model.moduleData[moduleIdx].pxx2.receivers |= (slot << (receiverIdx * 3));
--slot;
g_model.receiverData[slot].used = 1;
#warning "USE 32bits copy"
g_model.receiverData[slot].channelMapping0 = (0 << 0) + (1 << 5) + (2 << 10) + (3 << 15) + (4 << 20) + (5 << 25) + ((uint64_t)6 << 30) + ((uint64_t)7 << 35) + ((uint64_t)8 << 40) + ((uint64_t)9 << 45) + ((uint64_t)10 << 50) + ((uint64_t)11 << 55);
g_model.receiverData[slot].channelMapping1 = (12 << 0) + (13 << 5) + (14 << 10) + (15 << 15) + (16 << 20) + (17 << 25) + ((uint64_t)18 << 30) + ((uint64_t)19 << 35) + ((uint64_t)20 << 40) + ((uint64_t)21 << 45) + ((uint64_t)22 << 50) + ((uint64_t)23 << 55);
storageDirty(EE_MODEL);
}
}
}
}
@@ -1236,17 +1282,19 @@ void menuModelSetup(event_t event)
case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_1_PINMAP:
case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_2_PINMAP:
case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_3_PINMAP:
case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_4_PINMAP:
case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_1_PINMAP:
case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_2_PINMAP:
case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_3_PINMAP:
case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_4_PINMAP:
{
uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(k);
uint8_t moduleIdx = CURRENT_MODULE_EDITED(k);
lcdDrawTextAlignedLeft(y, INDENT INDENT "Pinmap");
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_SET, attr);
if (event == EVT_KEY_BREAK(KEY_ENTER) && attr) {
g_receiverIdx = receiverIdx;
g_moduleIdx = moduleIdx;
uint8_t moduleIdx = CURRENT_MODULE_EDITED(k);
uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(k);
g_receiverIdx = g_model.moduleData[moduleIdx].pxx2.getReceiverSlot(receiverIdx) - 1;
pushMenu(menuModelPinmap);
}
}
@@ -1254,24 +1302,39 @@ void menuModelSetup(event_t event)
case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_1_TELEM:
case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_2_TELEM:
case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_3_TELEM:
case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_4_TELEM:
case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_1_TELEM:
case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_2_TELEM:
case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_3_TELEM:
case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_4_TELEM:
{
uint8_t moduleIdx = CURRENT_MODULE_EDITED(k);
uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(k);
g_model.moduleData[INTERNAL_MODULE].pxx2.receivers[receiverIdx].telemetry = editCheckBox(g_model.moduleData[INTERNAL_MODULE].pxx2.receivers[receiverIdx].telemetry, MODEL_SETUP_2ND_COLUMN, y, INDENT INDENT "Telemetry", attr, event);
uint8_t receiverSlot = g_model.moduleData[moduleIdx].pxx2.getReceiverSlot(receiverIdx) - 1;
g_model.receiverData[receiverSlot].telemetry = editCheckBox(g_model.receiverData[receiverSlot].telemetry, MODEL_SETUP_2ND_COLUMN, y, INDENT INDENT "Telemetry", attr, event);
break;
}
break;
case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_1_BIND_SHARE:
case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_2_BIND_SHARE:
case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_3_BIND_SHARE:
case ITEM_MODEL_INTERNAL_MODULE_PXX2_RECEIVER_4_BIND_SHARE:
case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_1_BIND_SHARE:
case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_2_BIND_SHARE:
case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_3_BIND_SHARE:
case ITEM_MODEL_EXTERNAL_MODULE_PXX2_RECEIVER_4_BIND_SHARE:
{
uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(k);
uint8_t moduleIdx = CURRENT_MODULE_EDITED(k);
uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(k);
uint8_t receiverSlot = g_model.moduleData[moduleIdx].pxx2.getReceiverSlot(receiverIdx) - 1;
lcdDrawTextAlignedLeft(y, INDENT INDENT "---");
// TODO later once first telemetry frame received => the RX name
if (zexist(g_model.receiverData[receiverSlot].name, PXX2_LEN_RX_NAME)) {
lcdDrawSizedText(INDENT_WIDTH * 2, y, g_model.receiverData[receiverSlot].name, PXX2_LEN_RX_NAME);
}
else {
lcdDrawTextAlignedLeft(y, INDENT INDENT "---");
}
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_MODULE_BIND, menuHorizontalPosition==0 ? attr : 0);
lcdDrawText(lcdLastRightPos + FW/2, y, BUTTON("Share"), menuHorizontalPosition==1 ? attr : 0);
@@ -1281,6 +1344,7 @@ void menuModelSetup(event_t event)
if (event == EVT_KEY_BREAK(KEY_ENTER)) {
reusableBuffer.moduleSetup.pxx2.bindStep = BIND_START;
reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversCount = 0;
reusableBuffer.moduleSetup.pxx2.bindReceiverSlot = receiverSlot;
moduleSettings[moduleIdx].mode ^= MODULE_MODE_BIND;
}
if (moduleSettings[moduleIdx].mode == MODULE_MODE_BIND) {
@@ -1800,7 +1864,7 @@ void menuModelFailsafe(event_t event)
const int32_t channelValue = channelOutputs[ch+channelStart];
int32_t failsafeValue = g_model.failsafeChannels[ch];
//Channel
// Channel
putsChn(x+1, y, ch+1, SMLSIZE);
// Value
@@ -1838,7 +1902,7 @@ void menuModelFailsafe(event_t event)
}
// Gauge
#if !defined(PCBX7) && !defined(PCBX3) // X7 LCD doesn't like too many horizontal lines
#if !defined(PCBX7) // X7 LCD doesn't like too many horizontal lines
lcdDrawRect(x+LCD_W-3-wbar, y, wbar+1, 6);
#endif
const uint8_t lenChannel = limit<uint8_t>(1, (abs(channelValue) * wbar/2 + lim/2) / lim, wbar/2);
@@ -1869,43 +1933,38 @@ void menuModelPinmap(event_t event)
SIMPLE_SUBMENU_NOTITLE(sentModuleChannels(g_moduleIdx));
lcdDrawTextAlignedLeft(0, STR_PINMAPSET);
// for (uint8_t pos=0; pos<PXX2_LEN_RX_NAME; pos++) {
// lcdDrawHexChar(50 + pos*FW*2, 0, g_model.moduleData[INTERNAL_MODULE].pxx2.receivers[g_receiverIdx].rxName[pos], 0);
// }
// TODO write receiver name here
lcdInvertLine(0);
const coord_t x = 1;
coord_t y = FH + 1;
uint8_t pin = (menuVerticalPosition >= 8 ? 8 : 0);
for (uint8_t line = 0; line < 8; line++) {
const int32_t channelValue = channelOutputs[getPinOuput(g_receiverIdx, g_moduleIdx, pin)];
for (uint8_t i = 0; i < NUM_BODY_LINES; i++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
uint8_t pin = menuVerticalOffset + i;
const int32_t channelValue = channelOutputs[getPinOuput(g_receiverIdx, pin)];
// Pin
lcdDrawText(0, y, "Pin", SMLSIZE);
lcdDrawNumber(lcdLastRightPos + 1, y, pin+1, SMLSIZE);
lcdDrawText(0, y, "Pin");
lcdDrawNumber(lcdLastRightPos + 1, y, pin+1);
// Channel
LcdFlags flags = SMLSIZE;
LcdFlags flags = 0;
if (menuVerticalPosition == pin) {
flags |= INVERS;
if (s_editMode > 0) {
uint8_t channel = getPinOuput(g_receiverIdx, g_moduleIdx, pin);
uint8_t channel = getPinOuput(g_receiverIdx, pin);
flags |= BLINK;
CHECK_INCDEC_MODELVAR(event, channel, 0, sentModuleChannels(g_moduleIdx));
setPinOuput(g_receiverIdx, g_moduleIdx, pin, channel);
setPinOuput(g_receiverIdx, pin, channel);
}
}
putsChn(8*FW, y, getPinOuput(g_receiverIdx, g_moduleIdx, pin)+1, flags);
putsChn(7*FW, y, getPinOuput(g_receiverIdx, pin)+1, flags);
// Bargraph
#if !defined(PCBX7) // X7 LCD doesn't like too many horizontal lines
lcdDrawRect(LCD_W-3-wbar, y + 1, wbar+1, 4);
#endif
const uint8_t lenChannel = limit<uint8_t>(1, (abs(channelValue) * wbar/2 + lim/2) / lim, wbar/2);
const coord_t xChannel = (channelValue>0) ? x+LCD_W-3-wbar/2 : x+LCD_W-2-wbar/2-lenChannel;
lcdDrawHorizontalLine(xChannel, y+1, lenChannel, DOTTED, 0);
lcdDrawHorizontalLine(xChannel, y+2, lenChannel, DOTTED, 0);
y += FH-1;
if (++pin > sentModuleChannels(g_moduleIdx))
break;
const coord_t xChannel = (channelValue>0) ? LCD_W-3-wbar/2 : LCD_W-2-wbar/2-lenChannel;
lcdDrawHorizontalLine(xChannel, y+2, lenChannel, SOLID, 0);
lcdDrawHorizontalLine(xChannel, y+3, lenChannel, SOLID, 0);
}
}
+12 -8
View File
@@ -136,7 +136,7 @@ const uint8_t * DeviceFirmwareUpdate::readFrame(uint32_t timeout)
}
}
bool DeviceFirmwareUpdate::waitState(State state, uint32_t timeout)
bool DeviceFirmwareUpdate::waitState(State newState, uint32_t timeout)
{
#if defined(SIMU)
UNUSED(state);
@@ -150,8 +150,8 @@ bool DeviceFirmwareUpdate::waitState(State state, uint32_t timeout)
return false;
}
processFrame(&frame[1]);
return state == state;
processFrame(frame);
return state == newState;
#endif
}
@@ -258,11 +258,11 @@ const char * DeviceFirmwareUpdate::uploadFile(const char *filename)
count >>= 2;
for (UINT i=0; i<count; i++) {
for (uint32_t i=0; i<count; i++) {
if (!waitState(SPORT_DATA_REQ, 2000)) {
return "Module refused data";
}
startFrame(PRIM_DATA_WORD) ;
startFrame(PRIM_DATA_WORD);
uint32_t offset = (address & 1023) >> 2; // 32 bit word offset into buffer
*((uint32_t *)(frame + 2)) = buffer[offset];
frame[6] = address & 0x000000FF;
@@ -303,9 +303,9 @@ void DeviceFirmwareUpdate::flashFile(const char * filename)
EXTERNAL_MODULE_OFF();
SPORT_UPDATE_POWER_OFF();
/* wait 2s off */
watchdogSuspend(2000);
RTOS_WAIT_MS(2000);
/* wait 1s off */
watchdogSuspend(1000);
RTOS_WAIT_MS(1000);
startup();
@@ -328,6 +328,10 @@ void DeviceFirmwareUpdate::flashFile(const char * filename)
waitState(SPORT_IDLE, 500); // Clear the fifo
/* wait 1s off */
watchdogSuspend(1000);
RTOS_WAIT_MS(1000);
if (intPwr)
INTERNAL_MODULE_ON();
if (extPwr)
-7
View File
@@ -98,13 +98,6 @@ bool isJackPlugged()
#endif
#if defined(PCBXLITES)
enum JackState
{
SPEAKER_ACTIVE,
HEADPHONE_ACTIVE,
TRAINER_ACTIVE,
};
uint8_t jackState = SPEAKER_ACTIVE;
const char STR_JACK_HEADPHONE[] = "Headphone";
+1
View File
@@ -1132,6 +1132,7 @@ union ReusableBuffer
char registrationID[PXX2_LEN_REGISTRATION_ID];
char bindCandidateReceiversNames[PXX2_MAX_RECEIVERS_PER_MODULE][PXX2_LEN_RX_NAME];
uint8_t bindCandidateReceiversCount;
uint8_t bindReceiverSlot;
union {
uint8_t bindSelectedReceiverIndex;
uint8_t shareReceiverIndex;
+16 -4
View File
@@ -206,14 +206,26 @@ static const int8_t maxChannelsXJT[] = { 0, 8, 0, 4 }; // relative to 8!
constexpr int8_t MAX_TRAINER_CHANNELS_M8 = MAX_TRAINER_CHANNELS - 8;
constexpr int8_t MAX_EXTRA_MODULE_CHANNELS_M8 = 8; // only 16ch PPM
inline uint8_t getPinOuput(uint8_t receiverIdx, uint8_t moduleIdx, uint8_t pin)
inline uint8_t getPinOuput(uint8_t receiverIdx, uint8_t pin)
{
return ((g_model.moduleData[moduleIdx].pxx2.receivers[receiverIdx].channelMapping >> (pin + ((pin & 0x01) ? -1 : 1 )) * 4) & 0x0F);
if (pin < 12) {
return ((g_model.receiverData[receiverIdx].channelMapping0 >> (pin * 5)) & 0x1F);
}
else {
pin -= 12;
return ((g_model.receiverData[receiverIdx].channelMapping1 >> (pin * 5)) & 0x1F);
}
}
inline void setPinOuput(uint8_t receiverIdx, uint8_t moduleIdx, uint8_t pin, uint8_t chan)
inline void setPinOuput(uint8_t receiverIdx, uint8_t pin, uint8_t chan)
{
g_model.moduleData[moduleIdx].pxx2.receivers[receiverIdx].channelMapping = BF_SET<uint64_t>(g_model.moduleData[moduleIdx].pxx2.receivers[receiverIdx].channelMapping, chan, (pin + ((pin & 0x01) ? -1 : 1 )) * 4, 4);
if (pin < 12) {
g_model.receiverData[receiverIdx].channelMapping0 = BF_SET<uint64_t>(g_model.receiverData[receiverIdx].channelMapping0, chan, pin * 5, 5);
}
else {
pin -= 12;
g_model.receiverData[receiverIdx].channelMapping1 = BF_SET<uint64_t>(g_model.receiverData[receiverIdx].channelMapping1, chan, pin * 5, 5);
}
}
inline int8_t maxModuleChannels_M8(uint8_t idx)
+1
View File
@@ -53,6 +53,7 @@ void setupPulsesPPM(PpmPulsesData<T> * ppmPulsesData, uint8_t channelsStart, int
rest = limit<int32_t>(9000, rest, 65535); /* avoids that CCR2 is bigger than ARR which would cause reboot */
#if defined(STM32)
*ppmPulsesData->ptr++ = rest;
*ppmPulsesData->ptr = 0; // it's needed in case PPM is sent without DMA (we stop when we reach this 0)
#else
*ptr = rest;
*(ptr + 1) = 0;
+1 -1
View File
@@ -28,7 +28,7 @@
#define PXX_SEND_RANGECHECK (1 << 5)
#if defined(PXX_FREQUENCY_HIGH)
#define EXTMODULE_USART_PXX_BAUDRATE 420000
#define EXTMODULE_USART_PXX_BAUDRATE 450000
#define INTMODULE_USART_PXX_BAUDRATE 450000
#define PXX_PERIOD 4/*ms*/
#else
+18 -28
View File
@@ -104,7 +104,7 @@ void Pxx2Pulses::setupChannelsFrame(uint8_t module)
}
}
bool Pxx2Pulses::setupRegisterFrame(uint8_t module)
void Pxx2Pulses::setupRegisterFrame(uint8_t module)
{
addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_REGISTER);
@@ -120,46 +120,42 @@ bool Pxx2Pulses::setupRegisterFrame(uint8_t module)
else {
Pxx2Transport::addByte(0);
}
return true; // TODO not always
}
bool Pxx2Pulses::setupBindFrame(uint8_t module)
void Pxx2Pulses::setupBindFrame(uint8_t module)
{
addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_BIND);
if (reusableBuffer.moduleSetup.pxx2.bindStep == BIND_WAIT) {
if (get_tmr10ms() > reusableBuffer.moduleSetup.pxx2.bindWaitTimeout) {
moduleSettings[module].mode = MODULE_MODE_NORMAL;
reusableBuffer.moduleSetup.pxx2.bindStep = BIND_OK;
POPUP_INFORMATION(STR_BIND_OK);
}
else {
return false;
}
return;
}
else if (reusableBuffer.moduleSetup.pxx2.bindStep == BIND_RX_NAME_SELECTED) {
addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_BIND);
if (reusableBuffer.moduleSetup.pxx2.bindStep == BIND_RX_NAME_SELECTED) {
Pxx2Transport::addByte(0x01);
for (uint8_t i=0; i<PXX2_LEN_RX_NAME; i++) {
Pxx2Transport::addByte(reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversNames[reusableBuffer.moduleSetup.pxx2.bindSelectedReceiverIndex][i]);
}
Pxx2Transport::addByte(g_model.header.modelId[INTERNAL_MODULE]);
Pxx2Transport::addByte(reusableBuffer.moduleSetup.pxx2.bindReceiverSlot); // RX_UID is the slot index (which is unique and never moved)
Pxx2Transport::addByte(g_model.header.modelId[module]);
}
else {
Pxx2Transport::addByte(0x00);
for (uint8_t i=0; i<PXX2_LEN_REGISTRATION_ID; i++) {
Pxx2Transport::addByte(zchar2char(reusableBuffer.moduleSetup.pxx2.registrationID[i]));
Pxx2Transport::addByte(zchar2char(g_model.modelRegistrationID[i]));
}
}
return true; // TODO not always
}
bool Pxx2Pulses::setupSpectrumAnalyser(uint8_t module)
void Pxx2Pulses::setupSpectrumAnalyser(uint8_t module)
{
if (moduleSettings[module].counter > 1000) {
moduleSettings[module].counter = 1002;
return false;
return;
}
moduleSettings[module].counter = 1002;
@@ -175,11 +171,9 @@ bool Pxx2Pulses::setupSpectrumAnalyser(uint8_t module)
reusableBuffer.spectrum.step = 100000; // 100KHz
Pxx2Transport::addWord(reusableBuffer.spectrum.step);
return true;
}
bool Pxx2Pulses::setupShareMode(uint8_t module)
void Pxx2Pulses::setupShareMode(uint8_t module)
{
addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_RX_SETUP);
@@ -192,24 +186,22 @@ bool Pxx2Pulses::setupShareMode(uint8_t module)
}
moduleSettings[module].mode = MODULE_MODE_NORMAL;
return true;
}
bool Pxx2Pulses::setupFrame(uint8_t module)
void Pxx2Pulses::setupFrame(uint8_t module)
{
initFrame();
bool result = true;
uint8_t mode = moduleSettings[module].mode;
if (mode == MODULE_MODE_REGISTER)
result = setupRegisterFrame(module);
setupRegisterFrame(module);
else if (mode == MODULE_MODE_BIND)
result = setupBindFrame(module);
setupBindFrame(module);
else if (mode == MODULE_MODE_SPECTRUM_ANALYSER)
result = setupSpectrumAnalyser(module);
setupSpectrumAnalyser(module);
else if (mode == MODULE_MODE_SHARE)
result = setupShareMode(module);
setupShareMode(module);
else
setupChannelsFrame(module);
@@ -218,8 +210,6 @@ bool Pxx2Pulses::setupFrame(uint8_t module)
}
endFrame();
return result;
}
template class PxxPulses<Pxx2Transport>;
+16 -9
View File
@@ -100,18 +100,18 @@ class Pxx2Transport: public DataBuffer<uint8_t, 64>, public Pxx2CrcMixin {
class Pxx2Pulses: public PxxPulses<Pxx2Transport> {
public:
bool setupFrame(uint8_t module);
void setupFrame(uint8_t module);
protected:
bool setupRegisterFrame(uint8_t module);
void setupRegisterFrame(uint8_t module);
bool setupBindFrame(uint8_t module);
void setupBindFrame(uint8_t module);
bool setupShareMode(uint8_t module);
void setupShareMode(uint8_t module);
void setupChannelsFrame(uint8_t module);
bool setupSpectrumAnalyser(uint8_t module);
void setupSpectrumAnalyser(uint8_t module);
void addHead()
{
@@ -157,11 +157,18 @@ class Pxx2Pulses: public PxxPulses<Pxx2Transport> {
void endFrame()
{
// update the frame LEN = frame length minus the 2 first bytes
data[1] = getSize() - 2;
uint8_t size = getSize() - 2;
// now add the CRC
addCrc();
if (size > 0) {
// update the frame LEN = frame length minus the 2 first bytes
data[1] = getSize() - 2;
// now add the CRC
addCrc();
}
else {
Pxx2Transport::initBuffer();
}
}
};
@@ -92,6 +92,9 @@ extern "C" void INTMODULE_USART_IRQHandler(void)
void intmoduleSendBuffer(const uint8_t * data, uint8_t size)
{
if (size == 0)
return;
DMA_InitTypeDef DMA_InitStructure;
DMA_DeInit(INTMODULE_DMA_STREAM);
DMA_InitStructure.DMA_Channel = INTMODULE_DMA_CHANNEL;
+1 -1
View File
@@ -170,7 +170,7 @@ else()
)
endif()
if(NOT PCB STREQUAL XLITE AND NOT PCB STREQUAL XLITES)
if(NOT PCB STREQUAL XLITE)
set(TARGET_SRC
${TARGET_SRC}
trainer_driver.cpp
+10 -1
View File
@@ -200,8 +200,17 @@ void extmoduleSendNextFrame();
#define SLAVE_MODE() (g_model.trainerData.mode == TRAINER_MODE_SLAVE)
#if defined(PCBX9E)
#define TRAINER_CONNECTED() (true)
#elif defined(PCBX7)
#elif defined(PCBX7) || defined(PCBX3)
#define TRAINER_CONNECTED() (GPIO_ReadInputDataBit(TRAINER_DETECT_GPIO, TRAINER_DETECT_GPIO_PIN) == Bit_SET)
#elif defined(PCBXLITES)
enum JackState
{
SPEAKER_ACTIVE,
HEADPHONE_ACTIVE,
TRAINER_ACTIVE,
};
extern uint8_t jackState;
#define TRAINER_CONNECTED() (jackState == TRAINER_ACTIVE)
#elif defined(PCBXLITE)
#define TRAINER_CONNECTED() false // there is no Trainer jack on Taranis X-Lite
#else
+37 -16
View File
@@ -816,33 +816,42 @@
#endif
// Trainer Port
#if defined(PCBXLITE)
#define TRAINER_RCC_AHB1Periph 0
#define TRAINER_RCC_APB1Periph 0
#elif defined(PCBX3)
#define TRAINER_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD)
#if defined(PCBXLITES) || defined(PCBX3)
// on these 2 radios the trainer port already uses DMA1_Stream6, we won't use the DMA
#define TRAINER_RCC_AHB1Periph RCC_AHB1Periph_GPIOD
#define TRAINER_RCC_APB1Periph RCC_APB1Periph_TIM4
#define TRAINER_GPIO GPIOD
#define TRAINER_IN_GPIO_PIN GPIO_Pin_13 // PD.13
#define TRAINER_IN_GPIO_PinSource GPIO_PinSource13
#define TRAINER_OUT_GPIO_PIN GPIO_Pin_12 // PD.12
#define TRAINER_OUT_GPIO_PinSource GPIO_PinSource12
#if defined(PCBX3)
#define TRAINER_DETECT_GPIO GPIOD
#define TRAINER_DETECT_GPIO_PIN GPIO_Pin_11 // PD.11
#endif
#define TRAINER_TIMER TIM4
#define TRAINER_TIMER_IRQn TIM4_IRQn
#define TRAINER_GPIO_AF GPIO_AF_TIM4
#define TRAINER_DMA DMA1
#define TRAINER_DMA_CHANNEL DMA_Channel_5
#define TRAINER_DMA_STREAM DMA1_Stream2
#define TRAINER_DMA_IRQn DMA1_Stream2_IRQn
#define TRAINER_DMA_IRQHandler DMA1_Stream2_IRQHandler
#define TRAINER_DMA_FLAG_TC DMA_IT_TCIF2
#define TRAINER_GPIO_AF GPIO_AF_TIM4 // TIM4_CH1 (Out) + TIM4_CH2 (In)
#define TRAINER_TIMER_IRQn TIM4_IRQn
#define TRAINER_TIMER_IRQHandler TIM4_IRQHandler
#define TRAINER_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
#define TRAINER_OUT_CCMR1 TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1PE;
#define TRAINER_IN_CCMR1 TIM_CCMR1_IC2F_0 | TIM_CCMR1_IC2F_1 | TIM_CCMR1_CC2S_0;
#define TRAINER_OUT_COUNTER_REGISTER TRAINER_TIMER->CCR1
#define TRAINER_IN_COUNTER_REGISTER TRAINER_TIMER->CCR2
#define TRAINER_SETUP_REGISTER TRAINER_TIMER->CCR3
#define TRAINER_OUT_INTERRUPT_FLAG TIM_SR_CC3IF
#define TRAINER_OUT_INTERRUPT_ENABLE TIM_DIER_CC3IE
#define TRAINER_IN_INTERRUPT_ENABLE TIM_DIER_CC2IE
#define TRAINER_IN_INTERRUPT_FLAG TIM_SR_CC2IF
#define TRAINER_OUT_CCER TIM_CCER_CC1E
#define TRAINER_CCER_POLARYTY TIM_CCER_CC1P
#define TRAINER_IN_CCER TIM_CCER_CC2E
#elif defined(PCBXLITE)
#define TRAINER_RCC_AHB1Periph 0
#define TRAINER_RCC_APB1Periph 0
#else
#define TRAINER_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC)
#define TRAINER_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_DMA1)
#define TRAINER_RCC_APB1Periph RCC_APB1Periph_TIM3
#define TRAINER_GPIO GPIOC
#define TRAINER_IN_GPIO_PIN GPIO_Pin_8 // PC.08
@@ -863,6 +872,18 @@
#define TRAINER_TIMER_IRQn TIM3_IRQn
#define TRAINER_TIMER_IRQHandler TIM3_IRQHandler
#define TRAINER_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
#define TRAINER_OUT_CCMR2 TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4PE;
#define TRAINER_IN_CCMR2 TIM_CCMR2_IC3F_0 | TIM_CCMR2_IC3F_1 | TIM_CCMR2_CC3S_0;
#define TRAINER_OUT_COUNTER_REGISTER TRAINER_TIMER->CCR4
#define TRAINER_IN_COUNTER_REGISTER TRAINER_TIMER->CCR3
#define TRAINER_SETUP_REGISTER TRAINER_TIMER->CCR1
#define TRAINER_OUT_INTERRUPT_FLAG TIM_SR_CC1IF
#define TRAINER_OUT_INTERRUPT_ENABLE TIM_DIER_CC1IE
#define TRAINER_IN_INTERRUPT_ENABLE TIM_DIER_CC3IE
#define TRAINER_IN_INTERRUPT_FLAG TIM_SR_CC3IF
#define TRAINER_OUT_CCER TIM_CCER_CC4E
#define TRAINER_IN_CCER TIM_CCER_CC3E
#define TRAINER_CCER_POLARYTY TIM_CCER_CC4P
#endif
// Serial Port
@@ -1181,7 +1202,7 @@
#define SD_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1)
#define SD_RCC_APB1Periph RCC_APB1Periph_SPI2
#define SD_GPIO_PRESENT_GPIO GPIOD
#if defined(PCBXLITE)
#if defined(PCBXLITE) || defined(PCBX3)
#define SD_GPIO_PRESENT_GPIO_PIN GPIO_Pin_10 // PD.10
#else
#define SD_GPIO_PRESENT_GPIO_PIN GPIO_Pin_9 // PD.09
@@ -1226,8 +1247,8 @@
#define JACK_DETECT_GPIO_PIN GPIO_Pin_13 // PC.13
#define AUDIO_SPEAKER_ENABLE_GPIO GPIOD
#define AUDIO_SPEAKER_ENABLE_GPIO_PIN GPIO_Pin_14 // PD.14
#define HEADPHONE_TRAINER_SWITCH_GPIO GPIOD
#define HEADPHONE_TRAINER_SWITCH_GPIO_PIN GPIO_Pin_13 // PD.13
#define HEADPHONE_TRAINER_SWITCH_GPIO GPIOD
#define HEADPHONE_TRAINER_SWITCH_GPIO_PIN GPIO_Pin_9 // PD.09
#else
#define AUDIO_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_DMA1)
#endif
+62 -18
View File
@@ -20,7 +20,9 @@
#include "opentx.h"
#if defined(HEARTBEAT_USART)
DMAFifo<32> heartbeatFifo __DMA (HEARTBEAT_DMA_Stream);
#endif
void trainerSendNextFrame();
@@ -39,7 +41,11 @@ void init_trainer_ppm()
TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN;
TRAINER_TIMER->PSC = TRAINER_TIMER_FREQ / 2000000 - 1; // 0.5uS
TRAINER_TIMER->ARR = 45000;
TRAINER_TIMER->CCMR2 = TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4PE; // PWM mode 1
#if defined(TRAINER_OUT_CCMR1)
TRAINER_TIMER->CCMR1 = TRAINER_OUT_CCMR1;
#elif defined(TRAINER_OUT_CCMR2)
TRAINER_TIMER->CCMR2 = TRAINER_OUT_CCMR2;
#endif
TRAINER_TIMER->BDTR = TIM_BDTR_MOE;
TRAINER_TIMER->EGR = 1;
TRAINER_TIMER->DIER |= TIM_DIER_UDE;
@@ -48,18 +54,23 @@ void init_trainer_ppm()
setupPulsesPPMTrainer();
trainerSendNextFrame();
#if defined(TRAINER_DMA_STREAM)
NVIC_EnableIRQ(TRAINER_DMA_IRQn);
NVIC_SetPriority(TRAINER_DMA_IRQn, 7);
#endif
NVIC_EnableIRQ(TRAINER_TIMER_IRQn);
NVIC_SetPriority(TRAINER_TIMER_IRQn, 7);
}
void stop_trainer_ppm()
{
#if defined(TRAINER_DMA_STREAM)
NVIC_DisableIRQ(TRAINER_DMA_IRQn);
NVIC_DisableIRQ(TRAINER_TIMER_IRQn);
TRAINER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
#endif
NVIC_DisableIRQ(TRAINER_TIMER_IRQn);
TRAINER_TIMER->DIER = 0;
TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop counter
}
@@ -79,10 +90,14 @@ void init_trainer_capture()
TRAINER_TIMER->ARR = 0xFFFF;
TRAINER_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 2000000 - 1; // 0.5uS
TRAINER_TIMER->CR2 = 0;
TRAINER_TIMER->CCMR2 = TIM_CCMR2_IC3F_0 | TIM_CCMR2_IC3F_1 | TIM_CCMR2_CC3S_0;
TRAINER_TIMER->CCER = TIM_CCER_CC3E;
#if defined(TRAINER_IN_CCMR1)
TRAINER_TIMER->CCMR1 = TRAINER_IN_CCMR1;
#elif defined(TRAINER_IN_CCMR2)
TRAINER_TIMER->CCMR2 = TRAINER_IN_CCMR2;
#endif
TRAINER_TIMER->CCER = TRAINER_IN_CCER;
TRAINER_TIMER->SR &= ~TIM_SR_CC3IF & ~TIM_SR_CC2IF & ~TIM_SR_UIF; // Clear flags
TRAINER_TIMER->DIER |= TIM_DIER_CC3IE;
TRAINER_TIMER->DIER |= TRAINER_IN_INTERRUPT_ENABLE;
TRAINER_TIMER->CR1 = TIM_CR1_CEN;
NVIC_EnableIRQ(TRAINER_TIMER_IRQn);
@@ -98,18 +113,26 @@ void stop_trainer_capture()
void trainerSendNextFrame()
{
TRAINER_TIMER->CCR4 = GET_TRAINER_PPM_DELAY() * 2;
TRAINER_TIMER->CCER = TIM_CCER_CC4E | (GET_TRAINER_PPM_POLARITY() ? 0 : TIM_CCER_CC4P);
TRAINER_TIMER->CCR1 = *(trainerPulsesData.ppm.ptr - 1) - 4000; // 2mS in advance
TRAINER_OUT_COUNTER_REGISTER = GET_TRAINER_PPM_DELAY() * 2;
TRAINER_TIMER->CCER = TRAINER_OUT_CCER | (GET_TRAINER_PPM_POLARITY() ? 0 : TRAINER_CCER_POLARYTY);
TRAINER_SETUP_REGISTER = *(trainerPulsesData.ppm.ptr - 1) - 4000; // 2mS in advance
#if defined(TRAINER_DMA_STREAM)
TRAINER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
TRAINER_DMA_STREAM->CR |= TRAINER_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1;
TRAINER_DMA_STREAM->PAR = CONVERT_PTR_UINT(&TRAINER_TIMER->ARR);
TRAINER_DMA_STREAM->M0AR = CONVERT_PTR_UINT(trainerPulsesData.ppm.pulses);
TRAINER_DMA_STREAM->NDTR = trainerPulsesData.ppm.ptr - trainerPulsesData.ppm.pulses;
TRAINER_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA
#else
trainerPulsesData.ppm.ptr = trainerPulsesData.ppm.pulses;
TRAINER_TIMER->DIER |= TIM_DIER_UDE;
TRAINER_TIMER->SR &= ~TIM_SR_UIF; // Clear this flag
TRAINER_TIMER->DIER |= TIM_DIER_UIE; // Enable this interrupt
#endif
}
#if defined(TRAINER_DMA_STREAM)
extern "C" void TRAINER_DMA_IRQHandler()
{
if (!DMA_GetITStatus(TRAINER_DMA_STREAM, TRAINER_DMA_FLAG_TC))
@@ -117,9 +140,10 @@ extern "C" void TRAINER_DMA_IRQHandler()
DMA_ClearITPendingBit(TRAINER_DMA_STREAM, TRAINER_DMA_FLAG_TC);
TRAINER_TIMER->SR &= ~TIM_SR_CC1IF; // Clear flag
TRAINER_TIMER->DIER |= TIM_DIER_CC1IE; // Enable this interrupt
TRAINER_TIMER->SR &= ~TRAINER_OUT_INTERRUPT_FLAG; // Clear flag
TRAINER_TIMER->DIER |= TRAINER_OUT_INTERRUPT_ENABLE; // Enable this interrupt
}
#endif
extern "C" void TRAINER_TIMER_IRQHandler()
{
@@ -129,14 +153,15 @@ extern "C" void TRAINER_TIMER_IRQHandler()
bool doCapture = false;
// What mode? in or out?
if ((TRAINER_TIMER->DIER & TIM_DIER_CC3IE) && (TRAINER_TIMER->SR & TIM_SR_CC3IF)) {
if ((TRAINER_TIMER->DIER & TRAINER_IN_INTERRUPT_ENABLE) && (TRAINER_TIMER->SR & TRAINER_IN_INTERRUPT_FLAG)) {
// capture mode on trainer jack
capture = TRAINER_TIMER->CCR3;
capture = TRAINER_IN_COUNTER_REGISTER;
if (TRAINER_CONNECTED() && currentTrainerMode == TRAINER_MODE_MASTER_TRAINER_JACK) {
doCapture = true;
}
}
#if defined(TRAINER_MODULE_HEARTBEAT)
if ((TRAINER_TIMER->DIER & TIM_DIER_CC2IE) && (TRAINER_TIMER->SR & TIM_SR_CC2IF)) {
// capture mode on heartbeat pin (external module)
capture = TRAINER_TIMER->CCR2;
@@ -144,22 +169,36 @@ extern "C" void TRAINER_TIMER_IRQHandler()
doCapture = true;
}
}
#endif
if (doCapture) {
captureTrainerPulses(capture);
}
// PPM out compare interrupt
if ((TRAINER_TIMER->DIER & TIM_DIER_CC1IE) && (TRAINER_TIMER->SR & TIM_SR_CC1IF)) {
if ((TRAINER_TIMER->DIER & TRAINER_OUT_INTERRUPT_ENABLE) && (TRAINER_TIMER->SR & TRAINER_OUT_INTERRUPT_FLAG)) {
// compare interrupt
TRAINER_TIMER->DIER &= ~TIM_DIER_CC1IE; // stop this interrupt
TRAINER_TIMER->SR &= ~TIM_SR_CC1IF; // Clear flag
TRAINER_TIMER->DIER &= ~TRAINER_OUT_INTERRUPT_ENABLE; // stop this interrupt
TRAINER_TIMER->SR &= ~TRAINER_OUT_INTERRUPT_FLAG; // Clear flag
setupPulsesPPMTrainer();
trainerSendNextFrame();
}
#if !defined(TRAINER_DMA_STREAM)
// PPM out update interrupt
if ((TRAINER_TIMER->DIER & TIM_DIER_UIE) && (TRAINER_TIMER->SR & TIM_SR_UIF)) {
TRAINER_TIMER->SR &= ~TIM_SR_UIF; // Clear flag
TRAINER_TIMER->ARR = *trainerPulsesData.ppm.ptr++;
if (*trainerPulsesData.ppm.ptr == 0) {
TRAINER_TIMER->SR &= ~TRAINER_OUT_INTERRUPT_FLAG; // Clear this flag
TRAINER_TIMER->DIER |= TRAINER_OUT_INTERRUPT_ENABLE; // Enable this interrupt
}
}
#endif
}
void init_cppm_on_heartbeat_capture(void)
#if defined(TRAINER_MODULE_HEARTBEAT)
void init_cppm_on_heartbeat_capture()
{
EXTERNAL_MODULE_ON();
@@ -196,7 +235,9 @@ void stop_cppm_on_heartbeat_capture()
EXTERNAL_MODULE_OFF();
}
}
#endif
#if defined(HEARTBEAT_USART)
void init_sbus_on_heartbeat_capture()
{
EXTERNAL_MODULE_ON();
@@ -258,13 +299,16 @@ void stop_sbus_on_heartbeat_capture()
EXTERNAL_MODULE_OFF();
}
}
#endif
int sbusGetByte(uint8_t * byte)
{
switch (currentTrainerMode) {
#if defined(HEARTBEAT_USART)
case TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE:
return heartbeatFifo.pop(*byte);
#if !defined(PCBX7) && !defined(PCBX9E) && !defined(PCBX3)
#endif
#if !defined(PCBX7) && !defined(PCBX9E) && !defined(PCBX3) && !defined(PCBXLITE)
case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT:
return serial2RxFifo.pop(*byte);
#endif
+4 -4
View File
@@ -102,19 +102,19 @@ void processBindFrame(uint8_t module, uint8_t * frame)
if (frame[3] == 0x00) {
bool found = false;
for (uint8_t i=0; i<reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversCount; i++) {
if (memcmp(reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversNames[i], &frame[4], PXX2_LEN_RX_NAME) == 0) {
if (memcmp(&reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversNames[i], &frame[4], PXX2_LEN_RX_NAME) == 0) {
found = true;
break;
}
}
if (!found && reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversCount < PXX2_MAX_RECEIVERS_PER_MODULE) {
memcpy(reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversNames[reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversCount], &frame[4], PXX2_LEN_RX_NAME);
memcpy(&reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversNames[reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversCount], &frame[4], PXX2_LEN_RX_NAME);
++reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversCount;
reusableBuffer.moduleSetup.pxx2.bindStep = BIND_RX_NAME_RECEIVED;
}
}
else if (frame[3] == 0x01) {
if (memcmp(reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversNames[reusableBuffer.moduleSetup.pxx2.bindSelectedReceiverIndex], &frame[4], PXX2_LEN_RX_NAME) == 0) {
if (memcmp(&reusableBuffer.moduleSetup.pxx2.bindCandidateReceiversNames[reusableBuffer.moduleSetup.pxx2.bindSelectedReceiverIndex], &frame[4], PXX2_LEN_RX_NAME) == 0) {
reusableBuffer.moduleSetup.pxx2.bindStep = BIND_WAIT;
reusableBuffer.moduleSetup.pxx2.bindWaitTimeout = get_tmr10ms() + 30;
}
@@ -123,7 +123,7 @@ void processBindFrame(uint8_t module, uint8_t * frame)
void processTelemetryFrame(uint8_t module, uint8_t * frame)
{
sportProcessTelemetryPacketWithoutCrc(&frame[2]);
sportProcessTelemetryPacketWithoutCrc(&frame[3]);
}
void processSpectrumFrame(uint8_t module, uint8_t * frame)
+1 -1
View File
@@ -155,7 +155,7 @@ void logTelemetryWriteByte(uint8_t data);
#define LOG_TELEMETRY_WRITE_BYTE(data)
#endif
#define TELEMETRY_OUTPUT_FIFO_SIZE 16
#define TELEMETRY_OUTPUT_FIFO_SIZE 20
extern uint8_t outputTelemetryBuffer[TELEMETRY_OUTPUT_FIFO_SIZE] __DMA;
extern uint8_t outputTelemetryBufferSize;
extern uint8_t outputTelemetryBufferTrigger;