|
4 | 4 |
|
5 | 5 | #include "OTA.h" |
6 | 6 |
|
7 | | -#ifdef HYBRID_SWITCHES_8 |
| 7 | +#if defined HYBRID_SWITCHES_8 or defined UNIT_TEST |
8 | 8 |
|
9 | 9 | /** |
10 | | - * Hybrid switches packet |
11 | | - * Replaces Generate4ChannelData_11bit |
| 10 | + * Hybrid switches packet encoding for sending over the air |
| 11 | + * |
12 | 12 | * Analog channels are reduced to 10 bits to allow for switch encoding |
13 | 13 | * Switch[0] is sent on every packet. |
14 | 14 | * A 3 bit switch index and 2 bit value is used to send the remaining switches |
@@ -48,4 +48,136 @@ void ICACHE_RAM_ATTR GenerateChannelDataHybridSwitch8(SX127xDriver *Radio, CRSF |
48 | 48 | // update the sent value |
49 | 49 | crsf->setSentSwitch(i, value); |
50 | 50 | } |
51 | | -#endif |
| 51 | + |
| 52 | +/** |
| 53 | + * Hybrid switches decoding of over the air data |
| 54 | + * |
| 55 | + * Hybrid switches uses 10 bits for each analog channel, |
| 56 | + * 2 bits for the low latency switch[0] |
| 57 | + * 3 bits for the round-robin switch index and 2 bits for the value |
| 58 | + * |
| 59 | + * Input: Radio->RXdataBuffer |
| 60 | + * Output: crsf->PackedRCdataOut |
| 61 | + */ |
| 62 | +void ICACHE_RAM_ATTR UnpackChannelDataHybridSwitches8(SX127xDriver *Radio, CRSF *crsf) |
| 63 | +{ |
| 64 | + // The analog channels |
| 65 | + crsf->PackedRCdataOut.ch0 = (Radio->RXdataBuffer[1] << 3) + ((Radio->RXdataBuffer[5] & 0b11000000) >> 5); |
| 66 | + crsf->PackedRCdataOut.ch1 = (Radio->RXdataBuffer[2] << 3) + ((Radio->RXdataBuffer[5] & 0b00110000) >> 3); |
| 67 | + crsf->PackedRCdataOut.ch2 = (Radio->RXdataBuffer[3] << 3) + ((Radio->RXdataBuffer[5] & 0b00001100) >> 1); |
| 68 | + crsf->PackedRCdataOut.ch3 = (Radio->RXdataBuffer[4] << 3) + ((Radio->RXdataBuffer[5] & 0b00000011) << 1); |
| 69 | + |
| 70 | + // The low latency switch |
| 71 | + crsf->PackedRCdataOut.ch4 = SWITCH2b_to_CRSF((Radio->RXdataBuffer[6] & 0b01100000) >> 5); |
| 72 | + |
| 73 | + // The round-robin switch |
| 74 | + uint8_t switchIndex = (Radio->RXdataBuffer[6] & 0b11100) >> 2; |
| 75 | + uint16_t switchValue = SWITCH2b_to_CRSF(Radio->RXdataBuffer[6] & 0b11); |
| 76 | + |
| 77 | + switch (switchIndex) { |
| 78 | + case 0: // we should never get index 0 here since that is the low latency switch |
| 79 | + Serial.println("BAD switchIndex 0"); |
| 80 | + break; |
| 81 | + case 1: |
| 82 | + crsf->PackedRCdataOut.ch5 = switchValue; |
| 83 | + break; |
| 84 | + case 2: |
| 85 | + crsf->PackedRCdataOut.ch6 = switchValue; |
| 86 | + break; |
| 87 | + case 3: |
| 88 | + crsf->PackedRCdataOut.ch7 = switchValue; |
| 89 | + break; |
| 90 | + case 4: |
| 91 | + crsf->PackedRCdataOut.ch8 = switchValue; |
| 92 | + break; |
| 93 | + case 5: |
| 94 | + crsf->PackedRCdataOut.ch9 = switchValue; |
| 95 | + break; |
| 96 | + case 6: |
| 97 | + crsf->PackedRCdataOut.ch10 = switchValue; |
| 98 | + break; |
| 99 | + case 7: |
| 100 | + crsf->PackedRCdataOut.ch11 = switchValue; |
| 101 | + break; |
| 102 | + } |
| 103 | +} |
| 104 | + |
| 105 | +#endif // HYBRID_SWITCHES_8 |
| 106 | + |
| 107 | +#if defined SEQ_SWITCHES or defined UNIT_TEST |
| 108 | + |
| 109 | +/** |
| 110 | + * Sequential switches packet encoding |
| 111 | + * |
| 112 | + * Channel 3 is reduced to 10 bits to allow a 3 bit switch index and 2 bit value |
| 113 | + * We cycle through 8 switches on successive packets. If any switches have changed |
| 114 | + * we take the lowest indexed one and send that, hence lower indexed switches have |
| 115 | + * higher priority in the event that several are changed at once. |
| 116 | + */ |
| 117 | +void ICACHE_RAM_ATTR GenerateChannelDataSeqSwitch(SX127xDriver *Radio, CRSF *crsf, uint8_t addr) |
| 118 | +{ |
| 119 | + uint8_t PacketHeaderAddr; |
| 120 | + PacketHeaderAddr = (addr << 2) + RC_DATA_PACKET; |
| 121 | + Radio->TXdataBuffer[0] = PacketHeaderAddr; |
| 122 | + Radio->TXdataBuffer[1] = ((crsf->ChannelDataIn[0]) >> 3); |
| 123 | + Radio->TXdataBuffer[2] = ((crsf->ChannelDataIn[1]) >> 3); |
| 124 | + Radio->TXdataBuffer[3] = ((crsf->ChannelDataIn[2]) >> 3); |
| 125 | + Radio->TXdataBuffer[4] = ((crsf->ChannelDataIn[3]) >> 3); |
| 126 | + Radio->TXdataBuffer[5] = ((crsf->ChannelDataIn[0] & 0b00000111) << 5) + ((crsf->ChannelDataIn[1] & 0b111) << 2) + ((crsf->ChannelDataIn[2] & 0b110) >> 1); |
| 127 | + Radio->TXdataBuffer[6] = ((crsf->ChannelDataIn[2] & 0b001) << 7) + ((crsf->ChannelDataIn[3] & 0b110) << 4); |
| 128 | + |
| 129 | + // find the next switch to send |
| 130 | + uint8_t i = crsf->getNextSwitchIndex() & 0b111; // mask for paranoia |
| 131 | + uint8_t value = crsf->currentSwitches[i] & 0b11; // mask for paranoia |
| 132 | + |
| 133 | + // put the bits into buf[6] |
| 134 | + Radio->TXdataBuffer[6] += (i << 2) + value; |
| 135 | + |
| 136 | + // update the sent value |
| 137 | + crsf->setSentSwitch(i, value); |
| 138 | +} |
| 139 | + |
| 140 | + |
| 141 | +/** |
| 142 | + * Sequential switches decoding of over the air packet |
| 143 | + * |
| 144 | + * Seq switches uses 10 bits for ch3, 3 bits for the switch index and 2 bits for the switch value |
| 145 | + */ |
| 146 | +void ICACHE_RAM_ATTR UnpackChannelDataSeqSwitches(SX127xDriver *Radio, CRSF *crsf) |
| 147 | +{ |
| 148 | + crsf->PackedRCdataOut.ch0 = (Radio->RXdataBuffer[1] << 3) + ((Radio->RXdataBuffer[5] & 0b11100000) >> 5); |
| 149 | + crsf->PackedRCdataOut.ch1 = (Radio->RXdataBuffer[2] << 3) + ((Radio->RXdataBuffer[5] & 0b00011100) >> 2); |
| 150 | + crsf->PackedRCdataOut.ch2 = (Radio->RXdataBuffer[3] << 3) + ((Radio->RXdataBuffer[5] & 0b00000011) << 1) + (Radio->RXdataBuffer[6] & 0b10000000 >> 7); |
| 151 | + crsf->PackedRCdataOut.ch3 = (Radio->RXdataBuffer[4] << 3) + ((Radio->RXdataBuffer[6] & 0b01100000) >> 4); |
| 152 | + |
| 153 | + uint8_t switchIndex = (Radio->RXdataBuffer[6] & 0b11100) >> 2; |
| 154 | + uint16_t switchValue = SWITCH2b_to_CRSF(Radio->RXdataBuffer[6] & 0b11); |
| 155 | + |
| 156 | + switch (switchIndex) { |
| 157 | + case 0: |
| 158 | + crsf->PackedRCdataOut.ch4 = switchValue; |
| 159 | + break; |
| 160 | + case 1: |
| 161 | + crsf->PackedRCdataOut.ch5 = switchValue; |
| 162 | + break; |
| 163 | + case 2: |
| 164 | + crsf->PackedRCdataOut.ch6 = switchValue; |
| 165 | + break; |
| 166 | + case 3: |
| 167 | + crsf->PackedRCdataOut.ch7 = switchValue; |
| 168 | + break; |
| 169 | + case 4: |
| 170 | + crsf->PackedRCdataOut.ch8 = switchValue; |
| 171 | + break; |
| 172 | + case 5: |
| 173 | + crsf->PackedRCdataOut.ch9 = switchValue; |
| 174 | + break; |
| 175 | + case 6: |
| 176 | + crsf->PackedRCdataOut.ch10 = switchValue; |
| 177 | + break; |
| 178 | + case 7: |
| 179 | + crsf->PackedRCdataOut.ch11 = switchValue; |
| 180 | + break; |
| 181 | + } |
| 182 | +} |
| 183 | +#endif // SEQ_SWITCHES |
0 commit comments