diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index da8861284..6c54d6064 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -416,13 +416,9 @@ 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 dirty:1; - uint8_t spare:1; + uint8_t dirty:6; char name[PXX2_LEN_RX_NAME]; }); diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index fe6bd8146..87d6ef0d1 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -20,7 +20,9 @@ #include -uint8_t g_moduleIdx, g_receiverIdx; +#warning "TODO remove it" +uint8_t g_moduleIdx; + void menuModelFailsafe(event_t event); void menuModelPinmap(event_t event); @@ -1267,9 +1269,6 @@ void menuModelSetup(event_t event) 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); } } @@ -1291,7 +1290,11 @@ void menuModelSetup(event_t event) if (event == EVT_KEY_BREAK(KEY_ENTER) && attr) { uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(k); - g_receiverIdx = g_model.moduleData[moduleIdx].pxx2.getReceiverSlot(receiverIdx) - 1; + uint8_t receiverSlot = g_model.moduleData[g_moduleIdx].pxx2.getReceiverSlot(receiverIdx) - 1; + memclear(&reusableBuffer.receiverSetup, sizeof(reusableBuffer.receiverSetup)); + reusableBuffer.receiverSetup.moduleIdx = moduleIdx; + reusableBuffer.receiverSetup.receiverId = receiverSlot; + moduleSettings[moduleIdx].mode = MODULE_MODE_RECEIVER_SETTINGS; pushMenu(menuModelPinmap); } } @@ -1932,35 +1935,45 @@ void menuModelPinmap(event_t event) // TODO write receiver name here lcdInvertLine(0); - 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)]; + if (reusableBuffer.receiverSetup.state > 0) { + for (uint8_t i = 0; i < NUM_BODY_LINES; i++) { + coord_t y = MENU_HEADER_HEIGHT + 1 + i * FH; + uint8_t pin = menuVerticalOffset + i; + uint8_t channel = reusableBuffer.receiverSetup.channelMapping[pin]; + int32_t channelValue = channelOutputs[channel]; - // Pin - lcdDrawText(0, y, "Pin"); - lcdDrawNumber(lcdLastRightPos + 1, y, pin+1); + // Pin + lcdDrawText(0, y, "Pin"); + lcdDrawNumber(lcdLastRightPos + 1, y, pin + 1); - // Channel - LcdFlags flags = 0; - if (menuVerticalPosition == pin) { - flags |= INVERS; - if (s_editMode > 0) { - uint8_t channel = getPinOuput(g_receiverIdx, pin); - flags |= BLINK; - CHECK_INCDEC_MODELVAR(event, channel, 0, sentModuleChannels(g_moduleIdx)); - setPinOuput(g_receiverIdx, pin, channel); + // Channel + LcdFlags flags = 0; + if (menuVerticalPosition == pin) { + flags |= INVERS; + if (s_editMode > 0) { + flags |= BLINK; + #warning "Not a MODELVAR" + CHECK_INCDEC_MODELVAR(event, channel, 0, sentModuleChannels(g_moduleIdx)); + if (checkIncDec_Ret) { + reusableBuffer.receiverSetup.channelMapping[pin] = channel; + reusableBuffer.receiverSetup.state = 0x40; + moduleSettings[reusableBuffer.receiverSetup.moduleIdx].mode = MODULE_MODE_RECEIVER_SETTINGS; + } + } } - } - putsChn(7*FW, y, getPinOuput(g_receiverIdx, pin)+1, flags); + putsChn(7 * FW, y, channel + 1, flags); - // Bargraph + // Bargraph #if !defined(PCBX7) // X7 LCD doesn't like too many horizontal lines - lcdDrawRect(LCD_W-3-wbar, y + 1, wbar+1, 4); + 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) ? 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); + const uint8_t lenChannel = limit(1, (abs(channelValue) * wbar / 2 + lim / 2) / lim, wbar / 2); + 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); + } + } + else { + lcdDrawText(4*FW, 4*FH, "Waiting for RX..."); } } diff --git a/radio/src/opentx.h b/radio/src/opentx.h index 2ad4ec6e6..85e541277 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -1141,6 +1141,13 @@ union ReusableBuffer }; } moduleSetup; + struct { + uint8_t state; // 0x00 = READ 0x40 = WRITE + uint8_t moduleIdx; + uint8_t receiverId; + uint8_t channelMapping[24]; + } receiverSetup; + // 103 bytes struct { int16_t midVals[NUM_STICKS+NUM_POTS+NUM_SLIDERS+NUM_MOUSE_ANALOGS]; diff --git a/radio/src/pulses/modules.h b/radio/src/pulses/modules.h index 3c4543206..bf805e9ba 100644 --- a/radio/src/pulses/modules.h +++ b/radio/src/pulses/modules.h @@ -206,30 +206,6 @@ 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 pin) -{ - 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 pin, uint8_t chan) -{ - 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); - } - g_model.receiverData[receiverIdx].dirty = 1; - storageDirty(EE_MODEL); -} - inline int8_t maxModuleChannels_M8(uint8_t idx) { if (isExtraModule(idx)) diff --git a/radio/src/pulses/pulses.h b/radio/src/pulses/pulses.h index 352f0edaf..086b00e42 100644 --- a/radio/src/pulses/pulses.h +++ b/radio/src/pulses/pulses.h @@ -74,6 +74,7 @@ enum ModuleSettingsMode MODULE_MODE_NORMAL, MODULE_MODE_SPECTRUM_ANALYSER, MODULE_MODE_GET_HARDWARE_INFO, + MODULE_MODE_RECEIVER_SETTINGS, MODULE_MODE_BEEP_FIRST, MODULE_MODE_REGISTER = MODULE_MODE_BEEP_FIRST, MODULE_MODE_BIND, diff --git a/radio/src/pulses/pxx2.cpp b/radio/src/pulses/pxx2.cpp index 9bb7ba104..ecd9264bc 100644 --- a/radio/src/pulses/pxx2.cpp +++ b/radio/src/pulses/pxx2.cpp @@ -140,9 +140,15 @@ void Pxx2Pulses::setupRegisterFrame(uint8_t module) } } -void Pxx2Pulses::setupSetRxParamsFrame(uint8_t module, uint8_t receiverSlot) +void Pxx2Pulses::setupReceiverSettingsFrame(uint8_t module) { - + addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_RX_SETTINGS); + Pxx2Transport::addByte(reusableBuffer.receiverSetup.state + reusableBuffer.receiverSetup.receiverId); + Pxx2Transport::addByte(0x0); + for (int i=0; i<24; i++) { + Pxx2Transport::addByte(reusableBuffer.receiverSetup.channelMapping[i]); + } + // TODO moduleSettings[module].mode = MODULE_MODE_NORMAL; } void Pxx2Pulses::setupBindFrame(uint8_t module) @@ -151,7 +157,6 @@ void Pxx2Pulses::setupBindFrame(uint8_t module) if (get_tmr10ms() > reusableBuffer.moduleSetup.pxx2.bindWaitTimeout) { moduleSettings[module].mode = MODULE_MODE_NORMAL; reusableBuffer.moduleSetup.pxx2.bindStep = BIND_OK; - setupSetRxParamsFrame(module, reusableBuffer.moduleSetup.pxx2.bindReceiverSlot); POPUP_INFORMATION(STR_BIND_OK); } return; @@ -199,7 +204,7 @@ void Pxx2Pulses::setupSpectrumAnalyser(uint8_t module) void Pxx2Pulses::setupShareMode(uint8_t module) { - addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_RX_SETUP); + addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_RX_SETTINGS); Pxx2Transport::addByte(0xC0); @@ -220,6 +225,8 @@ void Pxx2Pulses::setupFrame(uint8_t module) if (mode == MODULE_MODE_GET_HARDWARE_INFO) setupHardwareInfoFrame(module); + else if (mode == MODULE_MODE_RECEIVER_SETTINGS) + setupReceiverSettingsFrame(module); else if (mode == MODULE_MODE_REGISTER) setupRegisterFrame(module); else if (mode == MODULE_MODE_BIND) diff --git a/radio/src/pulses/pxx2.h b/radio/src/pulses/pxx2.h index 8fefeeca0..2b4a04464 100644 --- a/radio/src/pulses/pxx2.h +++ b/radio/src/pulses/pxx2.h @@ -29,7 +29,8 @@ #define PXX2_TYPE_ID_REGISTER 0x01 #define PXX2_TYPE_ID_BIND 0x02 #define PXX2_TYPE_ID_CHANNELS 0x03 - #define PXX2_TYPE_ID_RX_SETUP 0x05 + #define PXX2_TYPE_ID_TX_SETTINGS 0x04 + #define PXX2_TYPE_ID_RX_SETTINGS 0x05 #define PXX2_TYPE_ID_HW_INFO 0x06 #define PXX2_TYPE_ID_TELEMETRY 0xFE @@ -112,7 +113,7 @@ class Pxx2Pulses: public PxxPulses { void setupShareMode(uint8_t module); - void setupSetRxParamsFrame(uint8_t module, uint8_t receiverSlot); + void setupReceiverSettingsFrame(uint8_t module); void setupChannelsFrame(uint8_t module); diff --git a/radio/src/telemetry/telemetry.cpp b/radio/src/telemetry/telemetry.cpp index 55ae9a9b5..879e560db 100644 --- a/radio/src/telemetry/telemetry.cpp +++ b/radio/src/telemetry/telemetry.cpp @@ -88,6 +88,21 @@ void processGetHardwareInfoFrame(uint8_t module, uint8_t * frame) } } +void processReceiverSettingsFrame(uint8_t module, uint8_t * frame) +{ + #warning "TODO This will be needed to ensure we are in the right menu" + // if (moduleSettings[module].mode != MODULE_MODE_GET_HARDWARE_INFO) { + // return; + // } + + for (uint8_t pin=0; pin<24; pin++) { + reusableBuffer.receiverSetup.channelMapping[pin] = frame[5 + pin]; + } + + reusableBuffer.receiverSetup.state = 0xFF; + moduleSettings[module].mode = MODULE_MODE_NORMAL; +} + void processRegisterFrame(uint8_t module, uint8_t * frame) { if (moduleSettings[module].mode != MODULE_MODE_REGISTER) { @@ -173,6 +188,10 @@ void processRadioFrame(uint8_t module, uint8_t * frame) processGetHardwareInfoFrame(module, frame); break; + case PXX2_TYPE_ID_RX_SETTINGS: + processReceiverSettingsFrame(module, frame); + break; + case PXX2_TYPE_ID_REGISTER: processRegisterFrame(module, frame); break;