diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index 4e30d40..bf25279 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -310,6 +310,14 @@ struct PPM_Parameters #define BAD_PROTO_on protocol_flags2 |= _BV(0) #define IS_BAD_PROTO_on ( ( protocol_flags2 & _BV(0) ) !=0 ) +#define RX_DONOTUPDTAE_off protocol_flags2 &= ~_BV(1) +#define RX_DONOTUPDTAE_on protocol_flags2 |= _BV(1) +#define IS_RX_DONOTUPDTAE_on ( ( protocol_flags2 & _BV(1) ) !=0 ) + +#define RX_MISSED_BUFF_off protocol_flags2 &= ~_BV(2) +#define RX_MISSED_BUFF_on protocol_flags2 |= _BV(2) +#define IS_RX_MISSED_BUFF_on ( ( protocol_flags2 & _BV(2) ) !=0 ) + #define BLINK_BIND_TIME 100 #define BLINK_SERIAL_TIME 500 #define BLINK_BAD_PROTO_TIME_LOW 1000 diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino index e62befa..bcae55c 100644 --- a/Multiprotocol/Multiprotocol.ino +++ b/Multiprotocol/Multiprotocol.ino @@ -102,7 +102,7 @@ volatile uint8_t rx_ok_buff[RXBUFFER_SIZE]; #ifndef BASH_SERIAL volatile uint8_t tx_buff[TXBUFFER_SIZE]; #endif -volatile uint8_t idx = 0; +volatile uint8_t discard_frame = 0; //Serial protocol uint8_t sub_protocol; @@ -368,54 +368,53 @@ static void CheckTimer(uint16_t (*cb)(void)) #ifdef XMEGA if( (TCC1.INTFLAGS & TC1_CCAIF_bm) != 0) { - cli(); // disable global int + cli(); // Disable global int due to RW of 16 bits registers TCC1.CCA = TCC1.CNT ; // Callback should already have been called... Use "now" as new sync point. - sei(); // enable global int + sei(); // Enable global int } else while((TCC1.INTFLAGS & TC1_CCAIF_bm) == 0); // wait before callback #else if( (TIFR1 & (1<4000) - { // start to wait here as much as we can... - next_callback=next_callback-2000; + { // start to wait here as much as we can... + next_callback-=2000; // We will wait below for 2ms #ifdef XMEGA - cli(); // disable global int + cli(); // Disable global int due to RW of 16 bits registers TCC1.CCA +=2000*2; // set compare A for callback TCC1.INTFLAGS = TC1_CCAIF_bm ; // clear compare A=callback flag sei(); // enable global int while((TCC1.INTFLAGS & TC1_CCAIF_bm) == 0); // wait 2ms... #else - cli(); // disable global int + cli(); // Disable global int due to RW of 16 bits registers OCR1A = OCR1A + 2000*2 ; // set compare A for callback TIFR1=(1<>4)& 0x07; //subprotocol no (0-7) bits 4-6 - RX_num=rx_ok_buff[1]& 0x0F; - MProtocol_id=MProtocol_id_master+RX_num; //personalized RX bind + rx num // rx_num bits 0---3 - } - else - if( ((rx_ok_buff[0]&0x80)!=0) && ((cur_protocol[0]&0x80)==0) ) // Bind flag has been set - CHANGE_PROTOCOL_FLAG_on; //restart protocol with bind - cur_protocol[0] = rx_ok_buff[0]; //store current protocol - - // decode channel values - volatile uint8_t *p=rx_ok_buff+2; - uint8_t dec=-3; - for(uint8_t i=0;i=8) - { - dec-=8; - p++; - } - p++; - Servo_data[i]=((((*((uint32_t *)p))>>dec)&0x7FF)*5)/8+860; //value range 860<->2140 -125%<->+125% - } RX_FLAG_off; //data has been processed + do + { + cli(); + 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 + sei(); + RX_MISSED_BUFF_off; + RX_DONOTUPDTAE_on; + if(rx_ok_buff[0]&0x20) //check range + RANGE_FLAG_on; + else + RANGE_FLAG_off; + if(rx_ok_buff[0]&0xC0) //check autobind(0x40) & bind(0x80) together + AUTOBIND_FLAG_on; + else + AUTOBIND_FLAG_off; + if(rx_ok_buff[1]&0x80) //if rx_ok_buff[1] ==1,power is low ,0-power high + POWER_FLAG_off; //power low + else + POWER_FLAG_on; //power high + + option=rx_ok_buff[2]; + + if( ((rx_ok_buff[0]&0x5F) != (cur_protocol[0]&0x5F)) || ( (rx_ok_buff[1]&0x7F) != cur_protocol[1] ) ) + { // New model has been selected + prev_protocol=cur_protocol[0]&0x1F; //store previous protocol so we can reset the module + cur_protocol[1] = rx_ok_buff[1]&0x7F; //store current protocol + CHANGE_PROTOCOL_FLAG_on; //change protocol + sub_protocol=(rx_ok_buff[1]>>4)& 0x07; //subprotocol no (0-7) bits 4-6 + RX_num=rx_ok_buff[1]& 0x0F; + MProtocol_id=MProtocol_id_master+RX_num;//personalized RX bind + rx num // rx_num bits 0---3 + } + else + if( ((rx_ok_buff[0]&0x80)!=0) && ((cur_protocol[0]&0x80)==0) ) // Bind flag has been set + CHANGE_PROTOCOL_FLAG_on; //restart protocol with bind + cur_protocol[0] = rx_ok_buff[0]; //store current protocol + + // decode channel values + volatile uint8_t *p=rx_ok_buff+2; + uint8_t dec=-3; + for(uint8_t i=0;i=8) + { + dec-=8; + p++; + } + p++; + Servo_data[i]=((((*((uint32_t *)p))>>dec)&0x7FF)*5)/8+860; //value range 860<->2140 -125%<->+125% + } + RX_DONOTUPDTAE_off; + } + while(IS_RX_MISSED_BUFF_on); // We've just processed an old frame... } void module_reset() @@ -1037,18 +1047,20 @@ ISR(USARTC0_RXC_vect) ISR(USART_RX_vect) #endif { // RX interrupt + static uint8_t idx=0; #ifdef XMEGA - 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 #else - UCSR0B &= ~(1<