diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index 2aaf97a6d..44a115986 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -416,13 +416,13 @@ PACK(struct TrainerModuleData { */ PACK(struct ReceiverData { + // 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:2; - // 5 bits per receiver output (24) as it can be assigned to one of the 24 channels - uint64_t channelMapping0:60; - uint64_t channelMapping1:64; - char name[8]; + char name[PXX2_LEN_RX_NAME]; }); /* diff --git a/radio/src/gui/128x64/gui.h b/radio/src/gui/128x64/gui.h index cd794dd0e..648e56f14 100644 --- a/radio/src/gui/128x64/gui.h +++ b/radio/src/gui/128x64/gui.h @@ -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) \ diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index a5beddc11..59fb2ed4d 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -1267,8 +1267,12 @@ void menuModelSetup(event_t event) killEvents(event); uint8_t slot = findEmptyReceiverSlot(); if (slot > 0) { - g_model.moduleData[moduleIdx].pxx2.receivers |= slot << (receiverIdx * 3); - g_model.receiverData[receiverSlot - 1].used = 1; + 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); } } @@ -1278,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); } } @@ -1296,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); @@ -1880,7 +1901,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(1, (abs(channelValue) * wbar/2 + lim/2) / lim, wbar/2); @@ -1911,43 +1932,38 @@ void menuModelPinmap(event_t event) SIMPLE_SUBMENU_NOTITLE(sentModuleChannels(g_moduleIdx)); lcdDrawTextAlignedLeft(0, STR_PINMAPSET); - // for (uint8_t pos=0; pos= 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(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); } } diff --git a/radio/src/pulses/modules.h b/radio/src/pulses/modules.h index 8b07460b6..5f8f78afc 100644 --- a/radio/src/pulses/modules.h +++ b/radio/src/pulses/modules.h @@ -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) { - // TODO 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) { - // TODO g_model.moduleData[moduleIdx].pxx2.receivers[receiverIdx].channelMapping = BF_SET(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(g_model.receiverData[receiverIdx].channelMapping0, chan, pin * 5, 5); + } + else { + pin -= 12; + g_model.receiverData[receiverIdx].channelMapping1 = BF_SET(g_model.receiverData[receiverIdx].channelMapping1, chan, pin * 5, 5); + } } inline int8_t maxModuleChannels_M8(uint8_t idx)