Fixes a problem where setting failsafe values was only possible once after bind and only set values for the first 12 channels. This fix allows setting failsafe values without having to rebind and sets failsafe values correctly for all possible 16 channels. (#695)

Notes for OpenTX/EdgeTX:
This fix doesn't exhibit servo jitter if failsafe mode was left on Custom, however it is still recommended to set failsafe mode back to Receiver after setting failsafe values.
It is still necessary to wait at least 8 seconds switching back from failsafe mode Custom to failsafe mode Receiver as OpenTX/EdgeTX will trigger the data transfer in Custom mode only every 7 seconds.

Bench tested with HoTT receivers GR-16, GR-24pro, GR-32
Flight tested with HoTT receiver GR-24
This commit is contained in:
Michael 2022-06-13 14:28:21 +02:00 committed by GitHub
parent 175cfa5e93
commit 0616cab386
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -169,66 +169,77 @@ static void __attribute__((unused)) HOTT_TXID_init()
} }
} }
static void __attribute__((unused)) HOTT_prep_data_packet() static void __attribute__((unused)) HOTT_prep_data_packet() {
{ static uint8_t upper = 0; // toggles between sending channels 1..8,9..12 and 1..8,13..16
static uint8_t upper=0;
packet[2] = hopping_frequency_no; // send next frequency to be used
packet[3] = upper; // indicate upper or lower channels (only supporting 16 channels)
packet[2] = hopping_frequency_no;
packet[3] = upper; // used for failsafe and upper channels (only supporting 16 channels)
#ifdef FAILSAFE_ENABLE #ifdef FAILSAFE_ENABLE
static uint8_t failsafe_count=0; static uint8_t failsafe_count = 0; // failsafe packet state machine (need to send two packets)
if(IS_FAILSAFE_VALUES_on && IS_BIND_DONE)
{ if(IS_FAILSAFE_VALUES_on && IS_BIND_DONE) { // if TX wants to send failsafe data and RX is connected
failsafe_count++; failsafe_count++; // prepare to send next packet
if(failsafe_count>=3)
{ if(failsafe_count >= 3) { // done sending two failsafe channel data packets
FAILSAFE_VALUES_off; FAILSAFE_VALUES_off;
failsafe_count=0; failsafe_count = 0;
} }
} }
else else
failsafe_count=0; failsafe_count = 0;
#endif #endif
// Channels value are PPM*2, -100%=1100µs, +100%=1900µs, order TAER // Channels value are PPM*2, -100%=1100µs, +100%=1900µs, order TAER
//
// Note: failsafe packets are differnt to normal operation packets
// normal operation toggles between sending channels 1..8,9..12 and 1..8,13..16 using bit0 as high/low indicator in packet[3]
// while failsafe packets send channels 1..12, 13..24 (and probably 25..32) using bit0 in packet[3] as packet type indicator
// packet[3] = 0x40 -> failsafe packet with data for channels 1..12
// packet[3] = 0x41 -> failsafe packet with data for channels 13..24
//
uint16_t val; uint16_t val;
for(uint8_t i=4;i<28;i+=2) for(uint8_t i = 0 ; i < 12*2 ; i += 2) { // working 12 channels (using 2 bytes per channel)
{ uint8_t chIndex = i >> 1 ; // normal operation channel number
uint8_t ch=(i-4)>>1; uint8_t fschIndex = chIndex; // linear channel number for failsafe
if(upper && ch >= 8)
ch+=4; // when upper swap CH9..CH12 by CH13..16 if(upper && chIndex >= 8) chIndex += 4; // for normal operation toggle between channels 1..8,9..12 and 1..8,13..16
val=Channel_data[ch]; val = Channel_data[chIndex]; // get normal operation channel data
val=(((val<<2)+val)>>2)+860*2; // value range 860<->2140 *2 <-> -125%<->+125% val = (((val << 2) + val) >> 2)+ 860*2; // convert channel data 0..2047 to 1720..4278 <-> -125%<->+125%
// val = (val*5/4+860*2)
#ifdef FAILSAFE_ENABLE #ifdef FAILSAFE_ENABLE
if(failsafe_count==1) if(failsafe_count == 1 || failsafe_count == 2) {// failsafe data needs to be sent to RX
{ // first failsafe packet uint16_t fs = 0x8000; // default failsafe mode is hold
packet[3] |= 0x40;
uint16_t fs=Failsafe_data[ch]; if(failsafe_count == 1) { // send fail safe packet containing channels 1..12
if( fs == FAILSAFE_CHANNEL_HOLD || fs == FAILSAFE_CHANNEL_NOPULSES) packet[3] = 0x40; // indicate packet has failsafe values for channels 1..12
val|=0x8000; // channel hold flag fs = Failsafe_data[fschIndex]; // get failsafe channel data
else } else { // send fail safe packet containing channels 13..24
{ packet[3] = 0x41; // indicate packet has failsafe values for channels 13..24
val=(((fs<<2)+fs)>>2)+860*2; // value range 860<->2140 *2 <-> -125%<->+125% if(fschIndex < 4) // we only work 16 channels so send channels 13..16, rest default
val|=0x4000; // channel specific position flag fs = Failsafe_data[fschIndex+12]; // get failsafe channel data 13..16
}
if( fs == FAILSAFE_CHANNEL_HOLD || // treat HOLD and NOPULSES as channel hold
fs == FAILSAFE_CHANNEL_NOPULSES)
val = 0x8000; // set channel failsafe mode hold flag
else {
val = (((fs << 2) + fs) >> 2) +860*2; // convert channel data 0..2047 to 1720..4278 <-> -125%<->+125%
val |= 0x4000; // set channel failsafe mode position flag
} }
} }
else if(failsafe_count==2)
{ // second failsafe packet=timing?
packet[3] |= 0x50;
if(i==4)
val=2;
else
val=0;
}
#endif #endif
packet[i] = val;
packet[i+1] = val>>8; packet[i + 4] = val; // first channel data at packet[4] and packet[5]
packet[i + 4+1] = val >> 8;
} }
upper ^= 0x01; // toggle between CH9..CH12 and CH13..16
upper ^= 0x01; // toggle to upper and lower channels
packet[28] = 0x80; // no sensor
packet[29] = 0x02; // 0x02 when bind starts then when RX replies cycle in sequence 0x1A/22/2A/0A/12, 0x02 during normal packets, 0x01->text config menu, 0x0A->no more RX telemetry packet[28] = 0x80; // no sensor
packet[29] = 0x02; // 0x02 when bind starts then when RX replies cycle in sequence 0x1A/22/2A/0A/12, 0x02 during normal packets, 0x01->text config menu, 0x0A->no more RX telemetry
#ifdef HOTT_FW_TELEMETRY #ifdef HOTT_FW_TELEMETRY
if(IS_BIND_DONE) if(IS_BIND_DONE)
{ {