Enhanced serial protocol

Protocol 0..255
RX_Num 0..63
Disable channel mapping -> not implemented yet
Disable telemetry
Data 0-9 bytes
This commit is contained in:
pascallanger 2019-10-07 19:06:00 +02:00
parent e3a5b2825d
commit ff96146b04
8 changed files with 221 additions and 204 deletions

View File

@ -264,11 +264,15 @@ uint16_t ReadAFHDS2A()
A7105_ReadData(AFHDS2A_RXPACKET_SIZE); A7105_ReadData(AFHDS2A_RXPACKET_SIZE);
if(packet[0] == 0xbc && packet[9] == 0x01) if(packet[0] == 0xbc && packet[9] == 0x01)
{ {
uint8_t temp=AFHDS2A_EEPROM_OFFSET+RX_num*4; uint8_t addr;
if(RX_num<16)
addr=AFHDS2A_EEPROM_OFFSET+RX_num*4;
else
addr=AFHDS2A_EEPROM_OFFSET2+(RX_num-16)*4;
for(uint8_t i=0; i<4; i++) for(uint8_t i=0; i<4; i++)
{ {
rx_id[i] = packet[5+i]; rx_id[i] = packet[5+i];
eeprom_write_byte((EE_ADDR)(temp+i),rx_id[i]); eeprom_write_byte((EE_ADDR)(addr+i),rx_id[i]);
} }
phase = AFHDS2A_BIND4; phase = AFHDS2A_BIND4;
packet_count++; packet_count++;
@ -390,9 +394,13 @@ uint16_t initAFHDS2A()
{ {
phase = AFHDS2A_DATA_INIT; phase = AFHDS2A_DATA_INIT;
//Read RX ID from EEPROM based on RX_num, RX_num must be uniq for each RX //Read RX ID from EEPROM based on RX_num, RX_num must be uniq for each RX
uint8_t temp=AFHDS2A_EEPROM_OFFSET+RX_num*4; uint8_t addr;
if(RX_num<16)
addr=AFHDS2A_EEPROM_OFFSET+RX_num*4;
else
addr=AFHDS2A_EEPROM_OFFSET2+(RX_num-16)*4;
for(uint8_t i=0;i<4;i++) for(uint8_t i=0;i<4;i++)
rx_id[i]=eeprom_read_byte((EE_ADDR)(temp+i)); rx_id[i]=eeprom_read_byte((EE_ADDR)(addr+i));
} }
hopping_frequency_no = 0; hopping_frequency_no = 0;
#if defined(AFHDS2A_FW_TELEMETRY) || defined(AFHDS2A_HUB_TELEMETRY) #if defined(AFHDS2A_FW_TELEMETRY) || defined(AFHDS2A_HUB_TELEMETRY)

View File

@ -181,7 +181,7 @@ static void __attribute__((unused)) BUGSMINI_make_address()
uint8_t start, length, index; uint8_t start, length, index;
//read rxid //read rxid
uint8_t base_adr=BUGSMINI_EEPROM_OFFSET+RX_num*2; uint8_t base_adr=BUGSMINI_EEPROM_OFFSET+(RX_num&0x0F)*2;
uint8_t rxid_high = eeprom_read_byte((EE_ADDR)(base_adr+0)); uint8_t rxid_high = eeprom_read_byte((EE_ADDR)(base_adr+0));
uint8_t rxid_low = eeprom_read_byte((EE_ADDR)(base_adr+1)); uint8_t rxid_low = eeprom_read_byte((EE_ADDR)(base_adr+1));
@ -272,7 +272,7 @@ uint16_t BUGSMINI_callback()
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
{ // RX fifo data ready { // RX fifo data ready
XN297_ReadPayload(packet, BUGSMINI_RX_PAYLOAD_SIZE); XN297_ReadPayload(packet, BUGSMINI_RX_PAYLOAD_SIZE);
base_adr=BUGSMINI_EEPROM_OFFSET+RX_num*2; base_adr=BUGSMINI_EEPROM_OFFSET+(RX_num&0x0F)*2;
eeprom_write_byte((EE_ADDR)(base_adr+0),packet[1]); // Save rxid in EEPROM eeprom_write_byte((EE_ADDR)(base_adr+0),packet[1]); // Save rxid in EEPROM
eeprom_write_byte((EE_ADDR)(base_adr+1),packet[2]); // Save rxid in EEPROM eeprom_write_byte((EE_ADDR)(base_adr+1),packet[2]); // Save rxid in EEPROM
NRF24L01_SetTxRxMode(TXRX_OFF); NRF24L01_SetTxRxMode(TXRX_OFF);

View File

@ -284,7 +284,7 @@ static void __attribute__((unused))BUGS_set_radio_data()
{ {
offset=BUGS_NUM_RFCHAN; offset=BUGS_NUM_RFCHAN;
// Read radio_id from EEPROM // Read radio_id from EEPROM
uint8_t base_adr=BUGS_EEPROM_OFFSET+RX_num*2; uint8_t base_adr=BUGS_EEPROM_OFFSET+(RX_num&0x0F)*2;
uint16_t rxid=0; uint16_t rxid=0;
for(uint8_t i=0; i<2; i++) for(uint8_t i=0; i<2; i++)
rxid|=eeprom_read_byte((EE_ADDR)(base_adr+i))<<(i*8); rxid|=eeprom_read_byte((EE_ADDR)(base_adr+i))<<(i*8);
@ -374,7 +374,7 @@ uint16_t ReadBUGS(void)
BIND_DONE; BIND_DONE;
// set radio_id // set radio_id
rxid = (packet[1] << 8) + packet[2]; rxid = (packet[1] << 8) + packet[2];
base_adr=BUGS_EEPROM_OFFSET+RX_num*2; base_adr=BUGS_EEPROM_OFFSET+(RX_num&0x0F)*2;
for(uint8_t i=0; i<2; i++) for(uint8_t i=0; i<2; i++)
eeprom_write_byte((EE_ADDR)(base_adr+i),rxid>>(i*8)); // Save rxid in EEPROM eeprom_write_byte((EE_ADDR)(base_adr+i),rxid>>(i*8)); // Save rxid in EEPROM
BUGS_set_radio_data(); BUGS_set_radio_data();
@ -437,7 +437,7 @@ uint16_t ReadBUGS(void)
uint16_t initBUGS(void) uint16_t initBUGS(void)
{ {
uint16_t rxid=0; uint16_t rxid=0;
uint8_t base_adr=BUGS_EEPROM_OFFSET+RX_num*2; uint8_t base_adr=BUGS_EEPROM_OFFSET+(RX_num&0x0F)*2;
for(uint8_t i=0; i<2; i++) for(uint8_t i=0; i<2; i++)
rxid|=eeprom_read_byte((EE_ADDR)(base_adr+i))<<(i*8); rxid|=eeprom_read_byte((EE_ADDR)(base_adr+i))<<(i*8);
if(rxid==0xffff) if(rxid==0xffff)

View File

@ -237,13 +237,16 @@ static void __attribute__((unused)) FrSkyX_build_packet()
else else
used -= SportHead ; used -= SportHead ;
if ( used < (MAX_SPORT_BUFFER>>1) ) if ( used < (MAX_SPORT_BUFFER>>1) )
{
DATA_BUFFER_LOW_off; DATA_BUFFER_LOW_off;
debugln("Ok buf:%d",used);
}
} }
FrSkyX_TX_Seq = ( FrSkyX_TX_Seq + 1 ) & 0x03 ; // Next iteration send next packet FrSkyX_TX_Seq = ( FrSkyX_TX_Seq + 1 ) & 0x03 ; // Next iteration send next packet
} }
else else
{//Not in sequence somehow, transmit what the receiver wants but why not asking for retransmit... {//Not in sequence somehow, transmit what the receiver wants but why not asking for retransmit...
debugln("RX_Seq:%d,TX:%d",FrSkyX_TX_IN_Seq,FrSkyX_TX_Seq); //debugln("RX_Seq:%d,TX:%d",FrSkyX_TX_IN_Seq,FrSkyX_TX_Seq);
packet[21] |= FrSkyX_TX_IN_Seq; packet[21] |= FrSkyX_TX_IN_Seq;
packet[22] = FrSkyX_TX_Frames[FrSkyX_TX_IN_Seq].count; packet[22] = FrSkyX_TX_Frames[FrSkyX_TX_IN_Seq].count;
for (uint8_t i=23;i<23+FrSkyX_TX_Frames[FrSkyX_TX_IN_Seq].count;i++) for (uint8_t i=23;i<23+FrSkyX_TX_Frames[FrSkyX_TX_IN_Seq].count;i++)

View File

@ -19,7 +19,7 @@
#define VERSION_MAJOR 1 #define VERSION_MAJOR 1
#define VERSION_MINOR 3 #define VERSION_MINOR 3
#define VERSION_REVISION 0 #define VERSION_REVISION 0
#define VERSION_PATCH_LEVEL 6 #define VERSION_PATCH_LEVEL 8
//****************** //******************
// Protocols // Protocols
@ -304,17 +304,16 @@ enum FRSKYX_RX
struct PPM_Parameters struct PPM_Parameters
{ {
uint8_t protocol : 7; uint8_t protocol;
uint8_t sub_proto : 3; uint8_t sub_proto : 3;
uint8_t rx_num : 4; uint8_t rx_num : 4;
uint8_t power : 1; uint8_t power : 1;
uint8_t autobind : 1; uint8_t autobind : 1;
uint8_t option; uint8_t option;
uint32_t chan_order; uint32_t chan_order;
}; };
// Telemetry // Telemetry
enum MultiPacketTypes enum MultiPacketTypes
{ {
MULTI_TELEMETRY_STATUS = 1, MULTI_TELEMETRY_STATUS = 1,
@ -390,6 +389,7 @@ enum MultiPacketTypes
#define TX_RX_PAUSE_on protocol_flags2 |= _BV(4) #define TX_RX_PAUSE_on protocol_flags2 |= _BV(4)
#define IS_TX_RX_PAUSE_on ( ( protocol_flags2 & _BV(4) ) !=0 ) #define IS_TX_RX_PAUSE_on ( ( protocol_flags2 & _BV(4) ) !=0 )
#define IS_TX_PAUSE_on ( ( protocol_flags2 & (_BV(4)|_BV(3)) ) !=0 ) #define IS_TX_PAUSE_on ( ( protocol_flags2 & (_BV(4)|_BV(3)) ) !=0 )
#define IS_TX_PAUSE_off ( ( protocol_flags2 & (_BV(4)|_BV(3)) ) ==0 )
//Signal OK //Signal OK
#define INPUT_SIGNAL_off protocol_flags2 &= ~_BV(5) #define INPUT_SIGNAL_off protocol_flags2 &= ~_BV(5)
#define INPUT_SIGNAL_on protocol_flags2 |= _BV(5) #define INPUT_SIGNAL_on protocol_flags2 |= _BV(5)
@ -414,6 +414,15 @@ enum MultiPacketTypes
#define SEND_MULTI_STATUS_on protocol_flags3 |= _BV(1) #define SEND_MULTI_STATUS_on protocol_flags3 |= _BV(1)
#define IS_SEND_MULTI_STATUS_on ( ( protocol_flags3 & _BV(1) ) !=0 ) #define IS_SEND_MULTI_STATUS_on ( ( protocol_flags3 & _BV(1) ) !=0 )
#define IS_SEND_MULTI_STATUS_off ( ( protocol_flags3 & _BV(1) ) ==0 ) #define IS_SEND_MULTI_STATUS_off ( ( protocol_flags3 & _BV(1) ) ==0 )
#define DISABLE_CH_MAP_off protocol_flags3 &= ~_BV(2)
#define DISABLE_CH_MAP_on protocol_flags3 |= _BV(2)
#define IS_DISABLE_CH_MAP_on ( ( protocol_flags3 & _BV(2) ) !=0 )
#define IS_DISABLE_CH_MAP_off ( ( protocol_flags3 & _BV(2) ) ==0 )
#define DISABLE_TELEM_off protocol_flags3 &= ~_BV(3)
#define DISABLE_TELEM_on protocol_flags3 |= _BV(3)
#define IS_DISABLE_TELEM_on ( ( protocol_flags3 & _BV(3) ) !=0 )
#define IS_DISABLE_TELEM_off ( ( protocol_flags3 & _BV(3) ) ==0 )
// Failsafe // Failsafe
#define FAILSAFE_CHANNEL_HOLD 2047 #define FAILSAFE_CHANNEL_HOLD 2047
@ -587,85 +596,81 @@ enum {
#define BUGSMINI_EEPROM_OFFSET 146 // RX ID, 2 bytes per model id, end is 146+32=178 #define BUGSMINI_EEPROM_OFFSET 146 // RX ID, 2 bytes per model id, end is 146+32=178
#define FRSKYX_RX_EEPROM_OFFSET 178 // (3) TX ID + (1) freq_tune + (47) channels, 51 bytes, end is 178+51=229 #define FRSKYX_RX_EEPROM_OFFSET 178 // (3) TX ID + (1) freq_tune + (47) channels, 51 bytes, end is 178+51=229
#define AFHDS2A_RX_EEPROM_OFFSET 229 // (4) TX ID + (16) channels, 20 bytes, end is 229+20=249 #define AFHDS2A_RX_EEPROM_OFFSET 229 // (4) TX ID + (16) channels, 20 bytes, end is 229+20=249
//#define CONFIG_EEPROM_OFFSET 210 // Current configuration of the multimodule #define AFHDS2A_EEPROM_OFFSET2 249 // RX ID, 4 bytes per model id, end is 249+192=441
//#define CONFIG_EEPROM_OFFSET 441 // Current configuration of the multimodule
//**************************************** //****************************************
//*** MULTI protocol serial definition *** //*** MULTI protocol serial definition ***
//**************************************** //****************************************
/* /*
************************** ***************************
16 channels serial protocol 16 channels serial protocol
************************** ***************************
Serial: 100000 Baud 8e2 _ xxxx xxxx p -- Serial: 100000 Baud 8e2 _ xxxx xxxx p --
Total of 26 bytes Total of 26 bytes for protocol V1, variable length for protocol V2
Stream[0] = 0x55 sub_protocol values are 0..31 Stream contains channels Stream[0] = header
Stream[0] = 0x54 sub_protocol values are 32..63 Stream contains channels 0x55 sub_protocol values are 0..31 Stream contains channels
Stream[0] = 0x51 sub_protocol values are 64..95 Stream contains channels 0x54 sub_protocol values are 32..63 Stream contains channels
Stream[0] = 0x50 sub_protocol values are 96..127 Stream contains channels 0x57 sub_protocol values are 0..31 Stream contains failsafe
Stream[0] = 0x57 sub_protocol values are 0..31 Stream contains failsafe 0x56 sub_protocol values are 32..63 Stream contains failsafe
Stream[0] = 0x56 sub_protocol values are 32..63 Stream contains failsafe
Stream[0] = 0x53 sub_protocol values are 64..95 Stream contains failsafe
Stream[0] = 0x52 sub_protocol values are 96..127 Stream contains failsafe
Stream[0] |= 0x20 any of the above + 8 additional data bytes at the end of the stream available for the current sub_protocol
header
Stream[1] = sub_protocol|BindBit|RangeCheckBit|AutoBindBit; Stream[1] = sub_protocol|BindBit|RangeCheckBit|AutoBindBit;
sub_protocol is 0..31 (bits 0..4), value should be added with 32 if Stream[0] = 0x54 | 0x56 sub_protocol is 0..31 (bits 0..4), value should be added with 32 if Stream[0] = 0x54 | 0x56
=> Reserved 0 Reserved 0
Flysky 1 Flysky 1
Hubsan 2 Hubsan 2
FrskyD 3 FrskyD 3
Hisky 4 Hisky 4
V2x2 5 V2x2 5
DSM 6 DSM 6
Devo 7 Devo 7
YD717 8 YD717 8
KN 9 KN 9
SymaX 10 SymaX 10
SLT 11 SLT 11
CX10 12 CX10 12
CG023 13 CG023 13
Bayang 14 Bayang 14
FrskyX 15 FrskyX 15
ESky 16 ESky 16
MT99XX 17 MT99XX 17
MJXQ 18 MJXQ 18
SHENQI 19 SHENQI 19
FY326 20 FY326 20
SFHSS 21 SFHSS 21
J6PRO 22 J6PRO 22
FQ777 23 FQ777 23
ASSAN 24 ASSAN 24
FrskyV 25 FrskyV 25
HONTAI 26 HONTAI 26
OpenLRS 27 OpenLRS 27
AFHDS2A 28 AFHDS2A 28
Q2X2 29 Q2X2 29
WK2x01 30 WK2x01 30
Q303 31 Q303 31
GW008 32 GW008 32
DM002 33 DM002 33
CABELL 34 CABELL 34
ESKY150 35 ESKY150 35
H8_3D 36 H8_3D 36
CORONA 37 CORONA 37
CFlie 38 CFlie 38
Hitec 39 Hitec 39
WFLY 40 WFLY 40
BUGS 41 BUGS 41
BUGSMINI 42 BUGSMINI 42
TRAXXAS 43 TRAXXAS 43
NCC1701 44 NCC1701 44
E01X 45 E01X 45
V911S 46 V911S 46
GD00X 47 GD00X 47
V761 48 V761 48
KF606 49 KF606 49
REDPINE 50 REDPINE 50
POTENSIC 51 POTENSIC 51
ZSX 52 ZSX 52
FLYZONE 53 FLYZONE 53
SCANNER 54 SCANNER 54
FRSKYX_RX 55 FRSKYX_RX 55
BindBit=> 0x80 1=Bind/0=No BindBit=> 0x80 1=Bind/0=No
AutoBindBit=> 0x40 1=Yes /0=No AutoBindBit=> 0x40 1=Yes /0=No
RangeCheck=> 0x20 1=Yes /0=No RangeCheck=> 0x20 1=Yes /0=No
@ -824,6 +829,12 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
Values are concatenated to fit in 22 bytes like in SBUS protocol. Values are concatenated to fit in 22 bytes like in SBUS protocol.
Failsafe values have exactly the same range/values than normal channels except the extremes where Failsafe values have exactly the same range/values than normal channels except the extremes where
0=no pulse, 2047=hold. If failsafe is not set or RX then failsafe packets should not be sent. 0=no pulse, 2047=hold. If failsafe is not set or RX then failsafe packets should not be sent.
Stream[26] = sub_protocol bits 6 & 7|RxNum bits 4 & 5|Disable_CH_Mapping 3|Disable_Telemetry 2|future use 1|future use 0;
sub_protocol is 0..255 (bits 0..5 + bits 6..7)
RxNum value is 0..63 (bits 0..3 + bits 4..5)
Disable_CH_Mapping => 0x08 0=enable, 1=disable
Disable_Telemetry => 0x04 0=enable, 1=disable
Stream[27.. 36] = between 0 and 9 bytes for additional protocol data
*/ */
/* /*
Multimodule Status Multimodule Status

View File

@ -162,10 +162,12 @@ uint8_t RX_num;
//Serial RX variables //Serial RX variables
#define BAUD 100000 #define BAUD 100000
#define RXBUFFER_SIZE 34 #define RXBUFFER_SIZE 36 // 26+1+9
volatile uint8_t rx_buff[RXBUFFER_SIZE]; volatile uint8_t rx_buff[RXBUFFER_SIZE];
volatile uint8_t rx_ok_buff[RXBUFFER_SIZE]; volatile uint8_t rx_ok_buff[RXBUFFER_SIZE];
volatile uint8_t discard_frame = 0; volatile uint8_t discard_frame = 0;
volatile uint8_t rx_idx=0, rx_len=0;
// Telemetry // Telemetry
#define TELEMETRY_BUFFER_SIZE 30 #define TELEMETRY_BUFFER_SIZE 30
@ -664,7 +666,8 @@ uint8_t Update_All()
#if ( !( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) ) ) #if ( !( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) ) )
if( (protocol == PROTO_FRSKYX_RX) || (protocol == PROTO_SCANNER) || (protocol==PROTO_FRSKYD) || (protocol==PROTO_BAYANG) || (protocol==PROTO_NCC1701) || (protocol==PROTO_BUGS) || (protocol==PROTO_BUGSMINI) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_FRSKYX) || (protocol==PROTO_DSM) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC)) if( (protocol == PROTO_FRSKYX_RX) || (protocol == PROTO_SCANNER) || (protocol==PROTO_FRSKYD) || (protocol==PROTO_BAYANG) || (protocol==PROTO_NCC1701) || (protocol==PROTO_BUGS) || (protocol==PROTO_BUGSMINI) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_FRSKYX) || (protocol==PROTO_DSM) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC))
#endif #endif
TelemetryUpdate(); if(IS_DISABLE_TELEM_off)
TelemetryUpdate();
#endif #endif
#ifdef ENABLE_BIND_CH #ifdef ENABLE_BIND_CH
if(IS_AUTOBIND_FLAG_on && IS_BIND_CH_PREV_off && Channel_data[BIND_CH-1]>CHANNEL_MAX_COMMAND && Channel_data[THROTTLE]<(CHANNEL_MIN_100+50)) if(IS_AUTOBIND_FLAG_on && IS_BIND_CH_PREV_off && Channel_data[BIND_CH-1]>CHANNEL_MAX_COMMAND && Channel_data[THROTTLE]<(CHANNEL_MIN_100+50))
@ -891,7 +894,7 @@ inline void tx_resume()
{ {
#ifdef TELEMETRY #ifdef TELEMETRY
// Resume telemetry by enabling transmitter interrupt // Resume telemetry by enabling transmitter interrupt
if(!IS_TX_PAUSE_on) if(IS_TX_PAUSE_off)
{ {
#ifdef ORANGE_TX #ifdef ORANGE_TX
cli() ; cli() ;
@ -945,6 +948,7 @@ static void protocol_init()
#endif #endif
TX_RX_PAUSE_off; TX_RX_PAUSE_off;
TX_MAIN_PAUSE_off; TX_MAIN_PAUSE_off;
tx_resume();
#endif #endif
//Set global ID and rx_tx_addr //Set global ID and rx_tx_addr
@ -1408,6 +1412,11 @@ void update_serial_data()
memcpy((void*)(rx_ok_buff+4),(void*)(rx_ok_buff+4+11),11); // reassign channels 9-16 to 1-8 memcpy((void*)(rx_ok_buff+4),(void*)(rx_ok_buff+4+11),11); // reassign channels 9-16 to 1-8
} }
#endif #endif
#ifdef BONI // Extremely dangerous, do not enable this!!! This is really for a special case...
if(CH14_SW)
rx_ok_buff[2]=(rx_ok_buff[2]&0xF0)|((rx_ok_buff[2]+1)&0x0F);
#endif
if(rx_ok_buff[1]&0x20) //check range if(rx_ok_buff[1]&0x20) //check range
RANGE_FLAG_on; RANGE_FLAG_on;
else else
@ -1466,23 +1475,21 @@ void update_serial_data()
failsafe=true; failsafe=true;
rx_ok_buff[0]&=0xFD; //remove the failsafe flag rx_ok_buff[0]&=0xFD; //remove the failsafe flag
FAILSAFE_VALUES_on; //failsafe data has been received FAILSAFE_VALUES_on; //failsafe data has been received
debugln("Failsafe received");
} }
#endif #endif
#ifdef SERIAL_DATA_ENABLE DISABLE_CH_MAP_off;
bool data=false; DISABLE_TELEM_off;
if(rx_ok_buff[0]&0x20) if(rx_len>26) // Additional protocol numbers and RX_Num available -> store them in rx_ok_buff[0]
{ // Packet has additional data {
data=true; rx_ok_buff[0]=(rx_ok_buff[26]&0xF0) | (rx_ok_buff[0]&0x0F);
rx_ok_buff[0]&=0xDF; //remove the data flag if(rx_ok_buff[26]&0x08)
} DISABLE_CH_MAP_on;
#endif if(rx_ok_buff[26]&0x04)
DISABLE_TELEM_on;
#ifdef BONI }
if(CH14_SW)
rx_ok_buff[2]=(rx_ok_buff[2]&0xF0)|((rx_ok_buff[2]+1)&0x0F); // Extremely dangerous, do not enable this!!! This is really for a special case...
#endif
if( (rx_ok_buff[0] != cur_protocol[0]) || ((rx_ok_buff[1]&0x5F) != (cur_protocol[1]&0x5F)) || ( (rx_ok_buff[2]&0x7F) != (cur_protocol[2]&0x7F) ) ) if( (rx_ok_buff[0] != cur_protocol[0]) || ((rx_ok_buff[1]&0x5F) != (cur_protocol[1]&0x5F)) || ( (rx_ok_buff[2]&0x7F) != (cur_protocol[2]&0x7F) ) )
{ // New model has been selected { // New model has been selected
CHANGE_PROTOCOL_FLAG_on; //change protocol CHANGE_PROTOCOL_FLAG_on; //change protocol
@ -1494,10 +1501,12 @@ void update_serial_data()
protocol=rx_ok_buff[1]&0x1F; //protocol no (0-31) protocol=rx_ok_buff[1]&0x1F; //protocol no (0-31)
if(!(rx_ok_buff[0]&1)) if(!(rx_ok_buff[0]&1))
protocol+=32; //protocol no (0-63) protocol+=32; //protocol no (0-63)
if(!(rx_ok_buff[0]&4)) if(rx_len>26)
protocol+=64; //protocol no (0-127) protocol|=rx_ok_buff[26]&0xC0; //protocol no (0-255)
sub_protocol=(rx_ok_buff[2]>>4)& 0x07; //subprotocol no (0-7) bits 4-6 sub_protocol=(rx_ok_buff[2]>>4)& 0x07; //subprotocol no (0-7) bits 4-6
RX_num=rx_ok_buff[2]& 0x0F; // rx_num bits 0-3 RX_num=rx_ok_buff[2]& 0x0F; //rx_num no (0-15)
if(rx_len>26)
RX_num|=rx_ok_buff[26]&0x30; //rx_num no (0-63)
} }
else else
if( ((rx_ok_buff[1]&0x80)!=0) && ((cur_protocol[1]&0x80)==0) ) // Bind flag has been set if( ((rx_ok_buff[1]&0x80)!=0) && ((cur_protocol[1]&0x80)==0) ) // Bind flag has been set
@ -1521,7 +1530,7 @@ void update_serial_data()
for(uint8_t i=0;i<3;i++) for(uint8_t i=0;i<3;i++)
cur_protocol[i] = rx_ok_buff[i]; cur_protocol[i] = rx_ok_buff[i];
// decode channel/failsafe values // decode channel/failsafe values
volatile uint8_t *p=rx_ok_buff+3; volatile uint8_t *p=rx_ok_buff+3;
uint8_t dec=-3; uint8_t dec=-3;
for(uint8_t i=0;i<NUM_CHN;i++) for(uint8_t i=0;i<NUM_CHN;i++)
@ -1542,48 +1551,45 @@ void update_serial_data()
Channel_data[i]=temp; //value range 0..2047, 0=-125%, 2047=+125% Channel_data[i]=temp; //value range 0..2047, 0=-125%, 2047=+125%
} }
#ifdef SERIAL_DATA_ENABLE if(rx_len>27)
if(data) { // Data available for the current protocol
{ // Data available for the current protocol #ifdef SPORT_SEND
#ifdef SPORT_SEND if(protocol==PROTO_FRSKYX && rx_len==35)
if(protocol==PROTO_FRSKYX) {//Protocol waiting for 8 bytes
#define BYTE_STUFF 0x7D
#define STUFF_MASK 0x20
//debug("SPort_in: ");
SportData[SportTail]=0x7E;
SportTail = (SportTail+1) & (MAX_SPORT_BUFFER-1);
SportData[SportTail]=rx_ok_buff[27]&0x1F;
SportTail = (SportTail+1) & (MAX_SPORT_BUFFER-1);
for(uint8_t i=28;i<28+7;i++)
{ {
#define BYTE_STUFF 0x7D if(rx_ok_buff[i]==BYTE_STUFF)
#define STUFF_MASK 0x20 {//stuff
//TODO detect overrun of the buffer before writing... SportData[SportTail]=BYTE_STUFF;
//debug("SPort_in: ");
SportData[SportTail]=0x7E;
SportTail = (SportTail+1) & (MAX_SPORT_BUFFER-1);
SportData[SportTail]=rx_ok_buff[26]&0x1F;
SportTail = (SportTail+1) & (MAX_SPORT_BUFFER-1);
for(uint8_t i=27;i<27+7;i++)
{
if(rx_ok_buff[i]==BYTE_STUFF)
{//stuff
SportData[SportTail]=BYTE_STUFF;
SportTail = (SportTail+1) & (MAX_SPORT_BUFFER-1);
SportData[SportTail]=rx_ok_buff[i]^STUFF_MASK;
}
else
SportData[SportTail]=rx_ok_buff[i];
//debug("%02X ",SportData[SportTail]);
SportTail = (SportTail+1) & (MAX_SPORT_BUFFER-1); SportTail = (SportTail+1) & (MAX_SPORT_BUFFER-1);
SportData[SportTail]=rx_ok_buff[i]^STUFF_MASK;
} }
uint8_t used = SportTail;
if ( SportHead > SportTail )
used += MAX_SPORT_BUFFER - SportHead ;
else else
used -= SportHead ; SportData[SportTail]=rx_ok_buff[i];
if ( used >= MAX_SPORT_BUFFER-(MAX_SPORT_BUFFER>>2) ) //debug("%02X ",SportData[SportTail]);
{ SportTail = (SportTail+1) & (MAX_SPORT_BUFFER-1);
DATA_BUFFER_LOW_on;
SEND_MULTI_STATUS_on; //Send Multi Status ASAP to inform the TX
debugln("Low buf=%d,h=%d,t=%d",used,SportHead,SportTail);
}
} }
#endif uint8_t used = SportTail;
} if ( SportHead > SportTail )
#endif // SERIAL_DATA_ENABLE used += MAX_SPORT_BUFFER - SportHead ;
else
used -= SportHead ;
if ( used >= MAX_SPORT_BUFFER-(MAX_SPORT_BUFFER>>2) )
{
DATA_BUFFER_LOW_on;
SEND_MULTI_STATUS_on; //Send Multi Status ASAP to inform the TX
debugln("Low buf=%d,h=%d,t=%d",used,SportHead,SportTail);
}
}
#endif //SPORT_SEND
}
RX_DONOTUPDATE_off; RX_DONOTUPDATE_off;
#ifdef ORANGE_TX #ifdef ORANGE_TX
@ -1592,7 +1598,9 @@ void update_serial_data()
UCSR0B &= ~_BV(RXCIE0); // RX interrupt disable UCSR0B &= ~_BV(RXCIE0); // RX interrupt disable
#endif #endif
if(IS_RX_MISSED_BUFF_on) // If the buffer is still valid if(IS_RX_MISSED_BUFF_on) // If the buffer is still valid
{ memcpy((void*)rx_ok_buff,(const void*)rx_buff,RXBUFFER_SIZE);// Duplicate the buffer {
rx_len=rx_idx;
memcpy((void*)rx_ok_buff,(const void*)rx_buff,rx_len);// Duplicate the buffer
RX_FLAG_on; // data to be processed next time... RX_FLAG_on; // data to be processed next time...
RX_MISSED_BUFF_off; RX_MISSED_BUFF_off;
} }
@ -1601,10 +1609,6 @@ void update_serial_data()
#else #else
UCSR0B |= _BV(RXCIE0) ; // RX interrupt enable UCSR0B |= _BV(RXCIE0) ; // RX interrupt enable
#endif #endif
#ifdef FAILSAFE_ENABLE
if(failsafe)
debugln("RX_FS:%d,%d,%d,%d",Failsafe_data[0],Failsafe_data[1],Failsafe_data[2],Failsafe_data[3]);
#endif
} }
void modules_reset() void modules_reset()
@ -1940,7 +1944,6 @@ static uint32_t random_id(uint16_t address, uint8_t create_new)
ISR(USART_RX_vect) ISR(USART_RX_vect)
#endif #endif
{ // RX interrupt { // RX interrupt
static uint8_t idx=0,len=26;
#ifdef ORANGE_TX #ifdef ORANGE_TX
if((USARTC0.STATUS & 0x1C)==0) // Check frame error, data overrun and parity error if((USARTC0.STATUS & 0x1C)==0) // Check frame error, data overrun and parity error
#elif defined STM32_BOARD #elif defined STM32_BOARD
@ -1951,69 +1954,53 @@ static uint32_t random_id(uint16_t address, uint8_t create_new)
if((UCSR0A&0x1C)==0) // Check frame error, data overrun and parity error if((UCSR0A&0x1C)==0) // Check frame error, data overrun and parity error
#endif #endif
{ // received byte is ok to process { // received byte is ok to process
if(idx==0||discard_frame==1) if(rx_idx==0||discard_frame==1)
{ // Let's try to sync at this point { // Let's try to sync at this point
idx=0;discard_frame=0;
RX_MISSED_BUFF_off; // If rx_buff was good it's not anymore... RX_MISSED_BUFF_off; // If rx_buff was good it's not anymore...
rx_idx=0;discard_frame=0;
rx_buff[0]=UDR0; rx_buff[0]=UDR0;
#ifdef SERIAL_DATA_ENABLE #ifdef FAILSAFE_ENABLE
#ifdef FAILSAFE_ENABLE if((rx_buff[0]&0xFC)==0x54) // If 1st byte is 0x54, 0x55, 0x56 or 0x57 it looks ok
if((rx_buff[0]&0xD8)==0x50) // If 1st byte is 0x74, 0x75, 0x76, 0x77, 0x54, 0x55, 0x56 or 0x57 it looks ok
#else
if((rx_buff[0]&0xDA)==0x50) // If 1st byte is 0x74, 0x75, 0x54 or 0x55 it looks ok
#endif
#else #else
#ifdef FAILSAFE_ENABLE if((rx_buff[0]&0xFE)==0x54) // If 1st byte is 0x54 or 0x55 it looks ok
if((rx_buff[0]&0xF8)==0x50) // If 1st byte is 0x58, 0x54, 0x55, 0x56 or 0x57 it looks ok
#else
if((rx_buff[0]&0xFA)==0x50) // If 1st byte is 0x54 or 0x55 it looks ok
#endif
#endif #endif
{ {
#ifdef SERIAL_DATA_ENABLE
if(rx_buff[0]&0x20)
len=34;
else
#endif
len=26;
TX_RX_PAUSE_on; TX_RX_PAUSE_on;
tx_pause(); tx_pause();
#if defined STM32_BOARD #if defined STM32_BOARD
TIMER2_BASE->CCR2=TIMER2_BASE->CNT + 300; // Next byte should show up within 15??s=1.5 byte TIMER2_BASE->CCR2=TIMER2_BASE->CNT + 300; // Next byte should show up within 15us=1.5 byte
TIMER2_BASE->SR = 0x1E5F & ~TIMER_SR_CC2IF; // Clear Timer2/Comp2 interrupt flag TIMER2_BASE->SR = 0x1E5F & ~TIMER_SR_CC2IF; // Clear Timer2/Comp2 interrupt flag
TIMER2_BASE->DIER |= TIMER_DIER_CC2IE; // Enable Timer2/Comp2 interrupt TIMER2_BASE->DIER |= TIMER_DIER_CC2IE; // Enable Timer2/Comp2 interrupt
#else #else
OCR1B = TCNT1 + 300; // Next byte should show up within 15??s=1.5 byte OCR1B = TCNT1 + 300; // Next byte should show up within 15us=1.5 byte
TIFR1 = OCF1B_bm ; // clear OCR1B match flag TIFR1 = OCF1B_bm ; // clear OCR1B match flag
SET_TIMSK1_OCIE1B ; // enable interrupt on compare B match SET_TIMSK1_OCIE1B ; // enable interrupt on compare B match
#endif #endif
idx++; rx_idx++;
} }
} }
else else
{ {
rx_buff[idx++]=UDR0; // Store received byte if(rx_idx>=RXBUFFER_SIZE)
#if defined STM32_BOARD {
TIMER2_BASE->CCR2=TIMER2_BASE->CNT + 300; // Next byte should show up within 15??s=1.5 byte discard_frame=1; // Too many bytes being received...
#else debugln("RX frame too long");
OCR1B = TCNT1 + 300; // Next byte should show up within 15??s=1.5 byte }
#endif else
if(idx>=len) {
{ // A full frame has been received rx_buff[rx_idx++]=UDR0; // Store received byte
if(!IS_RX_DONOTUPDATE_on) #if defined STM32_BOARD
{ //Good frame received and main is not working on the buffer TIMER2_BASE->CCR2=TIMER2_BASE->CNT + 300; // Next byte should show up within 15us=1.5 byte
memcpy((void*)rx_ok_buff,(const void*)rx_buff,len);// Duplicate the buffer #else
RX_FLAG_on; // Flag for main to process servo data OCR1B = TCNT1 + 300; // Next byte should show up within 15us=1.5 byte
} #endif
else
RX_MISSED_BUFF_on; // Notify that rx_buff is good
discard_frame=1; // Start again
} }
} }
} }
else else
{ {
idx=UDR0; // Dummy read rx_idx=UDR0; // Dummy read
rx_idx=0;
discard_frame=1; // Error encountered discard full frame... discard_frame=1; // Error encountered discard full frame...
debugln("Bad frame RX"); debugln("Bad frame RX");
} }
@ -2042,13 +2029,26 @@ static uint32_t random_id(uint16_t address, uint8_t create_new)
ISR(TIMER1_COMPB_vect, ISR_NOBLOCK ) ISR(TIMER1_COMPB_vect, ISR_NOBLOCK )
#endif #endif
{ // Timer1 compare B interrupt { // Timer1 compare B interrupt
if(rx_idx>=26)
{ // A full frame has been received
if(!IS_RX_DONOTUPDATE_on)
{ //Good frame received and main is not working on the buffer
rx_len=rx_idx;
memcpy((void*)rx_ok_buff,(const void*)rx_buff,rx_idx); // Duplicate the buffer
RX_FLAG_on; // Flag for main to process servo data
}
else
RX_MISSED_BUFF_on; // Notify that rx_buff is good
}
else
debugln("RX frame too short");
discard_frame=1; discard_frame=1;
#ifdef STM32_BOARD #ifdef STM32_BOARD
TIMER2_BASE->DIER &= ~TIMER_DIER_CC2IE; // Disable Timer2/Comp2 interrupt TIMER2_BASE->DIER &= ~TIMER_DIER_CC2IE; // Disable Timer2/Comp2 interrupt
debugln("Bad frame timer");
#else #else
CLR_TIMSK1_OCIE1B; // Disable interrupt on compare B match CLR_TIMSK1_OCIE1B; // Disable interrupt on compare B match
#endif #endif
TX_RX_PAUSE_off;
tx_resume(); tx_resume();
} }
#endif //ENABLE_SERIAL #endif //ENABLE_SERIAL

View File

@ -720,19 +720,18 @@ void TelemetryUpdate()
t -= h ; t -= h ;
if ( t < 32 ) if ( t < 32 )
{ {
debugln("TEL_BUF_FULL");
return ; return ;
} }
#endif #endif
#if ( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) ) #if defined(MULTI_TELEMETRY) || defined(MULTI_STATUS)
uint32_t now = millis();
if (IS_SEND_MULTI_STATUS_on || ((now - lastMulti) > MULTI_TIME))
{ {
uint32_t now = millis(); multi_send_status();
if (IS_SEND_MULTI_STATUS_on || (now - lastMulti) > MULTI_TIME) SEND_MULTI_STATUS_off;
{ lastMulti = now;
multi_send_status(); return;
SEND_MULTI_STATUS_off;
lastMulti = now;
return;
}
} }
#endif #endif

View File

@ -315,10 +315,6 @@
#endif #endif
#endif #endif
#ifdef SPORT_SEND
#define SERIAL_DATA_ENABLE
#endif
//Make sure TX is defined correctly //Make sure TX is defined correctly
#ifndef AILERON #ifndef AILERON
#error You must select a correct channel order. #error You must select a correct channel order.