diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino
index 56498fb..918d07d 100644
--- a/Multiprotocol/Multiprotocol.ino
+++ b/Multiprotocol/Multiprotocol.ino
@@ -21,7 +21,7 @@
along with Multiprotocol. If not, see .
*/
#define STM32_board
-#undef __cplusplus
+//#undef __cplusplus
#if defined STM32_board
#include "Multiprotocol_STM32.h"
#include
@@ -462,1084 +462,1097 @@ void loop()
}
- void Update_All()
- {
+void Update_All()
+{
#ifndef STM32_board
- TX_ON;
- NOP();
- TX_OFF;
+ TX_ON;
+ NOP();
+ TX_OFF;
#endif
#ifdef ENABLE_SERIAL
- if(mode_select==MODE_SERIAL && IS_RX_FLAG_on) // Serial mode and something has been received
- {
- update_serial_data(); // Update protocol and data
- update_aux_flags();
- if(IS_CHANGE_PROTOCOL_FLAG_on)
- { // Protocol needs to be changed
- LED_OFF; //led off during protocol init
- modules_reset(); //reset all modules
- protocol_init(); //init new protocol
- }
+ if(mode_select==MODE_SERIAL && IS_RX_FLAG_on) // Serial mode and something has been received
+ {
+ update_serial_data(); // Update protocol and data
+ update_aux_flags();
+ if(IS_CHANGE_PROTOCOL_FLAG_on)
+ { // Protocol needs to be changed
+ LED_OFF; //led off during protocol init
+ modules_reset(); //reset all modules
+ protocol_init(); //init new protocol
}
+ }
#endif //ENABLE_SERIAL
#ifdef ENABLE_PPM
- if(mode_select!=MODE_SERIAL && IS_PPM_FLAG_on) // PPM mode and a full frame has been received
- {
- for(uint8_t i=0;iPPM_MAX_125) temp_ppm=PPM_MAX_125;
- Servo_data[i]= temp_ppm ;
- }
- update_aux_flags();
- PPM_FLAG_off; // wait for next frame before update
+ if(mode_select!=MODE_SERIAL && IS_PPM_FLAG_on) // PPM mode and a full frame has been received
+ {
+ for(uint8_t i=0;iPPM_MAX_125) temp_ppm=PPM_MAX_125;
+ Servo_data[i]= temp_ppm ;
}
+ update_aux_flags();
+ PPM_FLAG_off; // wait for next frame before update
+ }
#endif //ENABLE_PPM
- update_led_status();
- #if defined(TELEMETRY)
- uint8_t protocol=cur_protocol[0]&0x1F;
- if( (protocol==MODE_FRSKY) || (protocol==MODE_HUBSAN) || (protocol==MODE_FRSKYX) || (protocol==MODE_DSM2) )
- TelemetryUpdate();
- #endif
+ update_led_status();
+ #if defined(TELEMETRY)
+ uint8_t protocol=cur_protocol[0]&0x1F;
+ if( (protocol==MODE_FRSKY) || (protocol==MODE_HUBSAN) || (protocol==MODE_FRSKYX) || (protocol==MODE_DSM2) )
+ TelemetryUpdate();
+ #endif
#ifndef STM32_board
- TX_ON;
- NOP();
- TX_OFF;
+ TX_ON;
+ NOP();
+ TX_OFF;
#endif
- }
+}
- // Update Servo_AUX flags based on servo AUX positions
- static void update_aux_flags(void)
+// Update Servo_AUX flags based on servo AUX positions
+static void update_aux_flags(void)
+{
+ Servo_AUX=0;
+ for(uint8_t i=0;i<8;i++)
+ if(Servo_data[AUX1+i]>PPM_SWITCH)
+ Servo_AUX|=1<PPM_SWITCH)
- Servo_AUX|=1< led on
- else
- blink+=BLINK_BIND_TIME; //blink fastly during binding
- LED_TOGGLE;
+ blink+=BLINK_BAD_PROTO_TIME_HIGH;
}
+ else
+ if(IS_BIND_DONE_on)
+ LED_OFF; //bind completed -> led on
+ else
+ blink+=BLINK_BIND_TIME; //blink fastly during binding
+ LED_TOGGLE;
}
+}
- inline void tx_pause()
- {
+inline void tx_pause()
+{
#ifdef TELEMETRY
- #ifdef XMEGA
- USARTC0.CTRLA &= ~0x03 ; // Pause telemetry by disabling transmitter interrupt
- #else
- #ifndef BASH_SERIAL
- #ifdef STM32_board
- USART3_BASE->CR1 &= ~ USART_CR1_TXEIE;//disable TX intrerupt
- #else
- UCSR0B &= ~_BV(UDRIE0); // Pause telemetry by disabling transmitter interrupt
- #endif
- #endif
- #endif
+ #ifdef XMEGA
+ USARTC0.CTRLA &= ~0x03 ; // Pause telemetry by disabling transmitter interrupt
+ #else
+ #ifndef BASH_SERIAL
+ #ifdef STM32_board
+ USART3_BASE->CR1 &= ~ USART_CR1_TXEIE;//disable TX intrerupt
+ #else
+ UCSR0B &= ~_BV(UDRIE0); // Pause telemetry by disabling transmitter interrupt
+ #endif
+ #endif
+ #endif
#endif
- }
+}
- inline void tx_resume()
- {
+inline void tx_resume()
+{
#ifdef TELEMETRY
- if(!IS_TX_PAUSE_on)
- #ifdef XMEGA
- USARTC0.CTRLA = (USARTC0.CTRLA & 0xFC) | 0x01 ; // Resume telemetry by enabling transmitter interrupt
- #else
- #ifdef STM32_board
- USART3_BASE->CR1 |= USART_CR1_TXEIE;// TX intrrupt enabled
- #else
- UCSR0B |= _BV(UDRIE0); // Resume telemetry by enabling transmitter interrupt
- #endif
- #endif
+ if(!IS_TX_PAUSE_on)
+ #ifdef XMEGA
+ USARTC0.CTRLA = (USARTC0.CTRLA & 0xFC) | 0x01 ; // Resume telemetry by enabling transmitter interrupt
+ #else
+ #ifdef STM32_board
+ USART3_BASE->CR1 |= USART_CR1_TXEIE;// TX intrrupt enabled
+ #else
+ UCSR0B |= _BV(UDRIE0); // Resume telemetry by enabling transmitter interrupt
+ #endif
+ #endif
#endif
- }
+}
#ifdef STM32_board
- void start_timer2(){
- // Pause the timer while we're configuring it
- timer.pause();
- TIMER2_BASE->PSC = 35;//36-1;for 72 MHZ /0.5sec/(35+1)
- TIMER2_BASE->ARR = 0xFFFF; //count till max
- timer.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE);
- timer.setMode(TIMER_CH2, TIMER_OUTPUT_COMPARE);
- // Refresh the timer's count, prescale, and overflow
- timer.refresh();
- timer.resume();
- }
+void start_timer2(){
+ // Pause the timer while we're configuring it
+ timer.pause();
+ TIMER2_BASE->PSC = 35;//36-1;for 72 MHZ /0.5sec/(35+1)
+ TIMER2_BASE->ARR = 0xFFFF; //count till max
+ timer.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE);
+ timer.setMode(TIMER_CH2, TIMER_OUTPUT_COMPARE);
+ // Refresh the timer's count, prescale, and overflow
+ timer.refresh();
+ timer.resume();
+}
#endif
- // Protocol scheduler
- static void CheckTimer(uint16_t (*cb)(void))
- {
- uint16_t next_callback,diff;
- #ifdef XMEGA
- if( (TCC1.INTFLAGS & TC1_CCAIF_bm) != 0)
- {
- cli(); // disable global int
- TCC1.CCA = TCC1.CNT ; // Callback should already have been called... Use "now" as new sync point.
- sei(); // enable global int
+// Protocol scheduler
+static void CheckTimer(uint16_t (*cb)(void))
+{
+ uint16_t next_callback,diff;
+ #ifdef XMEGA
+ if( (TCC1.INTFLAGS & TC1_CCAIF_bm) != 0)
+ {
+ cli(); // disable global int
+ TCC1.CCA = TCC1.CNT ; // Callback should already have been called... Use "now" as new sync point.
+ sei(); // enable global int
+ }
+ else
+ while((TCC1.INTFLAGS & TC1_CCAIF_bm) == 0); // wait before callback
+ #else
+ #if defined STM32_board
+ if((TIMER2_BASE->SR & TIMER_SR_CC1IF)!=0){
+ cli();
+ OCR1A = TIMER2_BASE->CNT;
+ TIMER2_BASE->CCR1=OCR1A;
+ sei();
+ }
+ else
+ while((TIMER2_BASE->SR & TIMER_SR_CC1IF )==0);//walit till compare match
+ #else
+ if( (TIFR1 & (1<4000)
+ { // start to wait here as much as we can...
+ next_callback=next_callback-2000;
+
+ #ifdef XMEGA
+ cli(); // disable global int
+ 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
+
+ #if defined STM32_board
+ cli();
+ OCR1A+=2000*2;// clear compare A=callback flag
+ TIMER2_BASE->CCR1=OCR1A;
+ TCNT1 = TIMER2_BASE->CNT;
+ TIMER2_BASE->SR &= ~TIMER_SR_CC1IF; //clear compare Flag
+ sei();
+ while((TIMER2_BASE->SR &TIMER_SR_CC1IF)==0);//2ms wait
+ #else
+ cli();
+ OCR1A+=2000*2; // clear compare A=callback flag
+ TIFR1=(1<SR & TIMER_SR_CC1IF)!=0){
- cli();
- OCR1A = TIMER2_BASE->CNT;
- TIMER2_BASE->CCR1=OCR1A;
- sei();
- }
- else
- while((TIMER2_BASE->SR & TIMER_SR_CC1IF )==0);//walit till compare match
+ OCR1A+=next_callback;
+ cli();
+ TIMER2_BASE->CCR1 = OCR1A;
+ TCNT1 = TIMER2_BASE->CNT;
+ TIMER2_BASE->SR &= ~TIMER_SR_CC1IF;//clear compare Flag write zero
+ diff=OCR1A-TCNT1; // compare timer and comparator
+ sei();
#else
- if( (TIFR1 & (1<4000)
- { // start to wait here as much as we can...
- next_callback=next_callback-2000;
-
- #ifdef XMEGA
- cli(); // disable global int
- 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...
+ if(IS_BIND_BUTTON_FLAG_on)
+ {
+ #ifdef STM32_board
+ EEPROM.write((200+mode_select),0x00); // reset to autobind mode for the current model
#else
-
- #if defined STM32_board
- cli();
- OCR1A+=2000*2;// clear compare A=callback flag
- TIMER2_BASE->CCR1=OCR1A;
- TCNT1 = TIMER2_BASE->CNT;
- TIMER2_BASE->SR &= ~TIMER_SR_CC1IF; //clear compare Flag
- sei();
- while((TIMER2_BASE->SR &TIMER_SR_CC1IF)==0);//2ms wait
- #else
- cli();
- OCR1A+=2000*2; // clear compare A=callback flag
- TIFR1=(1<CCR1 = OCR1A;
- TCNT1 = TIMER2_BASE->CNT;
- TIMER2_BASE->SR &= ~TIMER_SR_CC1IF;//clear compare Flag write zero
- diff=OCR1A-TCNT1; // compare timer and comparator
- sei();
- #else
- cli();
- OCR1A+=next_callback; // set compare A for callback
- TIFR1=(1<32000)
+ { // next_callback should not be more than 32767 so we will wait here...
+ uint16_t temp=(next_callback>>10)-2;
+ delay(temp);
+ next_callback-=temp<<10; // between 2-3ms left at this stage
}
- // Protocol start
- static void protocol_init()
- {
- uint16_t next_callback=0; // Default is immediate call back
- remote_callback = 0;
-
- set_rx_tx_addr(MProtocol_id);
- // reset telemetry
- #ifdef TELEMETRY
- #ifndef STM32_board
- tx_pause();
- #endif
- pass=0;
- telemetry_link=0;
- tx_tail=0;
- tx_head=0;
- #endif
-
- blink=millis();
- if(IS_BIND_BUTTON_FLAG_on)
- AUTOBIND_FLAG_on;
- if(IS_AUTOBIND_FLAG_on)
- BIND_IN_PROGRESS; // Indicates bind in progress for blinking bind led
- else
- BIND_DONE;
-
- CTRL1_on; //NRF24L01 antenna RF3 by default
- CTRL2_off; //NRF24L01 antenna RF3 by default
-
- switch(cur_protocol[0]&0x1F) // Init the requested protocol
- {
- #if defined(FLYSKY_A7105_INO)
- case MODE_FLYSKY:
- CTRL1_off; //antenna RF1
- next_callback = initFlySky();
- remote_callback = ReadFlySky;
- break;
- #endif
- #if defined(HUBSAN_A7105_INO)
- case MODE_HUBSAN:
- CTRL1_off; //antenna RF1
- if(IS_BIND_BUTTON_FLAG_on) random_id(10,true); // Generate new ID if bind button is pressed.
- next_callback = initHubsan();
- remote_callback = ReadHubsan;
- break;
- #endif
- #if defined(FRSKY_CC2500_INO)
- case MODE_FRSKY:
- CTRL1_off; //antenna RF2
- CTRL2_on;
- next_callback = initFrSky_2way();
- remote_callback = ReadFrSky_2way;
- break;
- #endif
- #if defined(FRSKYX_CC2500_INO)
- case MODE_FRSKYX:
- CTRL1_off; //antenna RF2
- CTRL2_on;
- next_callback = initFrSkyX();
- remote_callback = ReadFrSkyX;
- break;
- #endif
- #if defined(SFHSS_CC2500_INO)
- case MODE_SFHSS:
- CTRL1_off; //antenna RF2
- CTRL2_on;
- next_callback = initSFHSS();
- remote_callback = ReadSFHSS;
- break;
- #endif
- #if defined(DSM2_CYRF6936_INO)
- case MODE_DSM2:
- CTRL2_on; //antenna RF4
- next_callback = initDsm2();
- //Servo_data[2]=1500;//before binding
- remote_callback = ReadDsm2;
- break;
- #endif
- #if defined(DEVO_CYRF6936_INO)
- case MODE_DEVO:
- #ifdef ENABLE_PPM
- if(mode_select) //PPM mode
- {
- if(IS_BIND_BUTTON_FLAG_on)
- {
- #ifdef STM32_board
- EEPROM.write((200+mode_select),0x00); // reset to autobind mode for the current model
- #else
- eeprom_write_byte((uint8_t*)(30+mode_select),0x00); // reset to autobind mode for the current model
- #endif
- option=0;
- }
- else
- {
- #ifdef STM32_board
- option=EEPROM.read((200+mode_select)); // load previous mode: autobind or fixed id
- #else
- option=eeprom_read_byte((uint8_t*)(30+mode_select)); // load previous mode: autobind or fixed id
- #endif
- if(option!=1) option=0; // if not fixed id mode then it should be autobind // if not fixed id mode then it should be autobind
- }
- }
- #endif //ENABLE_PPM
- CTRL2_on; //antenna RF4
- next_callback = DevoInit();
- remote_callback = devo_callback;
- break;
- #endif
- #if defined(J6PRO_CYRF6936_INO)
- case MODE_J6PRO:
- CTRL2_on; //antenna RF4
- next_callback = initJ6Pro();
- remote_callback = ReadJ6Pro;
- break;
- #endif
- #if defined(HISKY_NRF24L01_INO)
- case MODE_HISKY:
- next_callback=initHiSky();
- remote_callback = hisky_cb;
- break;
- #endif
- #if defined(V2X2_NRF24L01_INO)
- case MODE_V2X2:
- next_callback = initV2x2();
- remote_callback = ReadV2x2;
- break;
- #endif
- #if defined(YD717_NRF24L01_INO)
- case MODE_YD717:
- next_callback=initYD717();
- remote_callback = yd717_callback;
- break;
- #endif
- #if defined(KN_NRF24L01_INO)
- case MODE_KN:
- next_callback = initKN();
- remote_callback = kn_callback;
- break;
- #endif
- #if defined(SYMAX_NRF24L01_INO)
- case MODE_SYMAX:
- next_callback = initSymax();
- remote_callback = symax_callback;
- break;
- #endif
- #if defined(SLT_NRF24L01_INO)
- case MODE_SLT:
- next_callback=initSLT();
- remote_callback = SLT_callback;
- break;
- #endif
- #if defined(CX10_NRF24L01_INO)
- case MODE_CX10:
- next_callback=initCX10();
- remote_callback = CX10_callback;
- break;
- #endif
- #if defined(CG023_NRF24L01_INO)
- case MODE_CG023:
- next_callback=initCG023();
- remote_callback = CG023_callback;
- break;
- #endif
- #if defined(BAYANG_NRF24L01_INO)
- case MODE_BAYANG:
- next_callback=initBAYANG();
- remote_callback = BAYANG_callback;
- break;
- #endif
- #if defined(ESKY_NRF24L01_INO)
- case MODE_ESKY:
- next_callback=initESKY();
- remote_callback = ESKY_callback;
- break;
- #endif
- #if defined(MT99XX_NRF24L01_INO)
- case MODE_MT99XX:
- next_callback=initMT99XX();
- remote_callback = MT99XX_callback;
- break;
- #endif
- #if defined(MJXQ_NRF24L01_INO)
- case MODE_MJXQ:
- next_callback=initMJXQ();
- remote_callback = MJXQ_callback;
- break;
- #endif
- #if defined(SHENQI_NRF24L01_INO)
- case MODE_SHENQI:
- next_callback=initSHENQI();
- remote_callback = SHENQI_callback;
- break;
- #endif
- #if defined(FY326_NRF24L01_INO)
- case MODE_FY326:
- next_callback=initFY326();
- remote_callback = FY326_callback;
- break;
- #endif
- #if defined(FQ777_NRF24L01_INO)
- case MODE_FQ777:
- next_callback=initFQ777();
- remote_callback = FQ777_callback;
- break;
- #endif
- #if defined(ASSAN_NRF24L01_INO)
- case MODE_ASSAN:
- next_callback=initASSAN();
- remote_callback = ASSAN_callback;
- break;
- #endif
-
- }
-
- if(next_callback>32000)
- { // next_callback should not be more than 32767 so we will wait here...
- uint16_t temp=(next_callback>>10)-2;
- delay(temp);
- next_callback-=temp<<10; // between 2-3ms left at this stage
- }
+ #ifdef XMEGA
+ cli(); // disable global int
+ TCC1.CCA = TCC1.CNT + next_callback*2; // set compare A for callback
+ sei(); // enable global int
+ TCC1.INTFLAGS = TC1_CCAIF_bm ; // clear compare A flag
+ #else
+ #if defined STM32_board
+ cli(); // disable global int
+ TCNT1 = TIMER2_BASE->CNT;
+ OCR1A=TCNT1+next_callback*2;
+ TIMER2_BASE->CCR1 = OCR1A;
+ sei();
+ TIMER2_BASE->SR &= ~TIMER_SR_CC1IF;//clear compare Flag write zero
+ #else
+ cli(); // disable global int
+ OCR1A=TCNT1+next_callback*2; // set compare A for callback
+ sei(); // enable global int
+ TIFR1=(1<CNT;
- OCR1A=TCNT1+next_callback*2;
- TIMER2_BASE->CCR1 = OCR1A;
- sei();
- TIMER2_BASE->SR &= ~TIMER_SR_CC1IF;//clear compare Flag write zero
- #else
- cli(); // disable global int
- OCR1A=TCNT1+next_callback*2; // set compare A for callback
- sei(); // enable global int
- 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
}
-
- static void update_serial_data()
+ 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
+ else
+ 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>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
- else
- 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+=3;
- if(dec>=8)
- {
- dec-=8;
- p++;
- }
+ dec-=8;
p++;
- Servo_data[i]=((((*((uint32_t *)p))>>dec)&0x7FF)*5)/8+860; //value range 860<->2140 -125%<->+125%
}
- RX_DONOTUPDTAE_off;
+ p++;
+ Servo_data[i]=((((*((uint32_t *)p))>>dec)&0x7FF)*5)/8+860; //value range 860<->2140 -125%<->+125%
+ }
+ RX_DONOTUPDTAE_off;
#ifdef XMEGA
- cli();
- #else
- #ifdef STM32_board
- //here code fro RX intrurpt disable
- USART3_BASE->CR1 &= ~ USART_CR1_RXNEIE;//disable
- #else
- UCSR0B &= ~(1<CR1 |= USART_CR1_RXNEIE ;//disable
- #else
- UCSR0B |= (1<CR1 &= ~ USART_CR1_RXNEIE;//disable
+ #else
+ UCSR0B &= ~(1<CR1 |= USART_CR1_RXNEIE ;//disable
+ #else
+ UCSR0B |= (1<>8);
- }
+// Channel value is converted for HK310
+void convert_channel_HK310(uint8_t num, uint8_t *low, uint8_t *high)
+{
+ uint16_t temp=0xFFFF-(4*Servo_data[num])/3;
+ *low=(uint8_t)(temp&0xFF);
+ *high=(uint8_t)(temp>>8);
+}
- // Channel value is limited to PPM_100
- uint16_t limit_channel_100(uint8_t ch)
- {
- if(Servo_data[ch]>servo_max_100)
- return servo_max_100;
- else
- if (Servo_data[ch]servo_max_100)
+ return servo_max_100;
+ else
+ if (Servo_data[ch]CR1 |= USART_CR1_PCE_BIT;
- USART3_BASE->CR1 &= ~ USART_CR1_RE;//disable
- USART2_BASE->CR1 &= ~ USART_CR1_TE;//disable transmit
- #else
- #include
- UBRR0H = UBRRH_VALUE;
- UBRR0L = UBRRL_VALUE;
- UCSR0A = 0 ; // Clear X2 bit
- //Set frame format to 8 data bits, even parity, 2 stop bits
- UCSR0C = (1<CR1 |= USART_CR1_PCE_BIT;
+ USART3_BASE->CR1 &= ~ USART_CR1_RE;//disable
+ USART2_BASE->CR1 &= ~ USART_CR1_TE;//disable transmit
+ #else
+ #include
+ UBRR0H = UBRRH_VALUE;
+ UBRR0L = UBRRL_VALUE;
+ UCSR0A = 0 ; // Clear X2 bit
+ //Set frame format to 8 data bits, even parity, 2 stop bits
+ UCSR0C = (1<> 24) & 0xFF;
- rx_tx_addr[1] = (id >> 16) & 0xFF;
- rx_tx_addr[2] = (id >> 8) & 0xFF;
- rx_tx_addr[3] = (id >> 0) & 0xFF;
- rx_tx_addr[4] = 0xC1; // for YD717: always uses first data port
- }
+// Convert 32b id to rx_tx_addr
+static void set_rx_tx_addr(uint32_t id)
+{ // Used by almost all protocols
+ rx_tx_addr[0] = (id >> 24) & 0xFF;
+ rx_tx_addr[1] = (id >> 16) & 0xFF;
+ rx_tx_addr[2] = (id >> 8) & 0xFF;
+ rx_tx_addr[3] = (id >> 0) & 0xFF;
+ rx_tx_addr[4] = 0xC1; // for YD717: always uses first data port
+}
#if defined STM32_board
- static uint32_t random_id(uint16_t adress, uint8_t create_new)
- {
- uint32_t id;
- uint8_t txid[4];
- pinMode(PB0, INPUT_ANALOG); // set up pin for analog input
- pinMode(PB1, INPUT_ANALOG); // set up pin for analog input
-
- if ((EEPROM.read(adress+100)==0xf0) && !create_new)
- { // TXID exists in EEPROM
- for(uint8_t i=0;i<4;i++)
- txid[i]=EEPROM.read(adress+110);
- id=(txid[0] | ((uint32_t)txid[1]<<8) | ((uint32_t)txid[2]<<16) | ((uint32_t)txid[3]<<24));
- }
- else
- { // if not generate a random ID
- randomSeed((uint32_t)analogRead(PB0)<<10|analogRead(PB1));//seed
- //
- id = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16);
- txid[0]= (id &0xFF);
- txid[1] = ((id >> 8) & 0xFF);
- txid[2] = ((id >> 16) & 0xFF);
- txid[3] = ((id >> 24) & 0xFF);
- for(uint8_t i=0;i<4;i++)
- EEPROM.write((adress+110),txid[i]);
- EEPROM.write(adress+100,0xF0);
- }
- return id;
+static uint32_t random_id(uint16_t adress, uint8_t create_new)
+{
+ uint32_t id;
+ uint8_t txid[4];
+ pinMode(PB0, INPUT_ANALOG); // set up pin for analog input
+ pinMode(PB1, INPUT_ANALOG); // set up pin for analog input
+
+ if ((EEPROM.read(adress+100)==0xf0) && !create_new)
+ { // TXID exists in EEPROM
+ for(uint8_t i=0;i<4;i++)
+ txid[i]=EEPROM.read(adress+110);
+ id=(txid[0] | ((uint32_t)txid[1]<<8) | ((uint32_t)txid[2]<<16) | ((uint32_t)txid[3]<<24));
}
+ else
+ { // if not generate a random ID
+ randomSeed((uint32_t)analogRead(PB0)<<10|analogRead(PB1));//seed
+ //
+ id = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16);
+ txid[0]= (id &0xFF);
+ txid[1] = ((id >> 8) & 0xFF);
+ txid[2] = ((id >> 16) & 0xFF);
+ txid[3] = ((id >> 24) & 0xFF);
+ for(uint8_t i=0;i<4;i++)
+ EEPROM.write((adress+110),txid[i]);
+ EEPROM.write(adress+100,0xF0);
+ }
+ return id;
+}
#else
- static uint32_t random_id(uint16_t adress, uint8_t create_new)
- {
- uint32_t id;
- uint8_t txid[4];
-
- if (eeprom_read_byte((uint8_t*)(adress+10))==0xf0 && !create_new)
- { // TXID exists in EEPROM
- eeprom_read_block((void*)txid,(const void*)adress,4);
- id=(txid[0] | ((uint32_t)txid[1]<<8) | ((uint32_t)txid[2]<<16) | ((uint32_t)txid[3]<<24));
- }
- else
- { // if not generate a random ID
- randomSeed((uint32_t)analogRead(A6)<<10|analogRead(A7));//seed
- //
- id = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16);
- txid[0]= (id &0xFF);
- txid[1] = ((id >> 8) & 0xFF);
- txid[2] = ((id >> 16) & 0xFF);
- txid[3] = ((id >> 24) & 0xFF);
- eeprom_write_block((const void*)txid,(void*)adress,4);
- eeprom_write_byte((uint8_t*)(adress+10),0xf0);//write bind flag in eeprom.
- }
- return id;
+static uint32_t random_id(uint16_t adress, uint8_t create_new)
+{
+ uint32_t id;
+ uint8_t txid[4];
+
+ if (eeprom_read_byte((uint8_t*)(adress+10))==0xf0 && !create_new)
+ { // TXID exists in EEPROM
+ eeprom_read_block((void*)txid,(const void*)adress,4);
+ id=(txid[0] | ((uint32_t)txid[1]<<8) | ((uint32_t)txid[2]<<16) | ((uint32_t)txid[3]<<24));
}
+ else
+ { // if not generate a random ID
+ randomSeed((uint32_t)analogRead(A6)<<10|analogRead(A7));//seed
+ //
+ id = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16);
+ txid[0]= (id &0xFF);
+ txid[1] = ((id >> 8) & 0xFF);
+ txid[2] = ((id >> 16) & 0xFF);
+ txid[3] = ((id >> 24) & 0xFF);
+ eeprom_write_block((const void*)txid,(void*)adress,4);
+ eeprom_write_byte((uint8_t*)(adress+10),0xf0);//write bind flag in eeprom.
+ }
+ return id;
+}
#endif
#ifndef XMEGA
#ifndef STM32_board
- /************************************/
- /** Arduino replacement routines **/
- /************************************/
- // replacement millis() and micros()
- // These work polled, no interrupts
- // micros() MUST be called at least once every 32 milliseconds
- uint16_t MillisPrecount ;
- uint16_t lastTimerValue ;
- uint32_t TotalMicros ;
- uint32_t TotalMillis ;
- uint8_t Correction ;
+/************************************/
+/** Arduino replacement routines **/
+/************************************/
+// replacement millis() and micros()
+// These work polled, no interrupts
+// micros() MUST be called at least once every 32 milliseconds
+uint16_t MillisPrecount ;
+uint16_t lastTimerValue ;
+uint32_t TotalMicros ;
+uint32_t TotalMillis ;
+uint8_t Correction ;
- uint32_t micros()
+uint32_t micros()
+{
+ uint16_t elapsed ;
+ uint8_t millisToAdd ;
+ uint8_t oldSREG = SREG ;
+ cli() ;
+ uint16_t time = TCNT1 ; // Read timer 1
+ SREG = oldSREG ;
+
+ elapsed = time - lastTimerValue ;
+ elapsed += Correction ;
+ Correction = elapsed & 0x01 ;
+ elapsed >>= 1 ;
+
+ uint32_t ltime = TotalMicros ;
+ ltime += elapsed ;
+ cli() ;
+ TotalMicros = ltime ; // Done this way for RPM to work correctly
+ lastTimerValue = time ;
+ SREG = oldSREG ; // Still valid from above
+
+ elapsed += MillisPrecount;
+ millisToAdd = 0 ;
+
+ if ( elapsed > 15999 )
{
- uint16_t elapsed ;
- uint8_t millisToAdd ;
- uint8_t oldSREG = SREG ;
- cli() ;
- uint16_t time = TCNT1 ; // Read timer 1
- SREG = oldSREG ;
-
- elapsed = time - lastTimerValue ;
- elapsed += Correction ;
- Correction = elapsed & 0x01 ;
- elapsed >>= 1 ;
-
- uint32_t ltime = TotalMicros ;
- ltime += elapsed ;
- cli() ;
- TotalMicros = ltime ; // Done this way for RPM to work correctly
- lastTimerValue = time ;
- SREG = oldSREG ; // Still valid from above
-
- elapsed += MillisPrecount;
- millisToAdd = 0 ;
-
- if ( elapsed > 15999 )
- {
- millisToAdd = 16 ;
- elapsed -= 16000 ;
- }
- if ( elapsed > 7999 )
- {
- millisToAdd += 8 ;
- elapsed -= 8000 ;
- }
- if ( elapsed > 3999 )
- {
- millisToAdd += 4 ;
- elapsed -= 4000 ;
- }
- if ( elapsed > 1999 )
- {
- millisToAdd += 2 ;
- elapsed -= 2000 ;
- }
- if ( elapsed > 999 )
- {
- millisToAdd += 1 ;
- elapsed -= 1000 ;
- }
- TotalMillis += millisToAdd ;
- MillisPrecount = elapsed ;
- return TotalMicros ;
+ millisToAdd = 16 ;
+ elapsed -= 16000 ;
}
-
- uint32_t millis()
+ if ( elapsed > 7999 )
{
- micros() ;
- return TotalMillis ;
+ millisToAdd += 8 ;
+ elapsed -= 8000 ;
}
-
- void delayMilliseconds(unsigned long ms)
+ if ( elapsed > 3999 )
{
- uint16_t start = (uint16_t)micros();
- uint16_t lms = ms ;
+ millisToAdd += 4 ;
+ elapsed -= 4000 ;
+ }
+ if ( elapsed > 1999 )
+ {
+ millisToAdd += 2 ;
+ elapsed -= 2000 ;
+ }
+ if ( elapsed > 999 )
+ {
+ millisToAdd += 1 ;
+ elapsed -= 1000 ;
+ }
+ TotalMillis += millisToAdd ;
+ MillisPrecount = elapsed ;
+ return TotalMicros ;
+}
- while (lms > 0) {
- if (((uint16_t)micros() - start) >= 1000) {
- lms--;
- start += 1000;
- }
+uint32_t millis()
+{
+ micros() ;
+ return TotalMillis ;
+}
+
+void delayMilliseconds(unsigned long ms)
+{
+ uint16_t start = (uint16_t)micros();
+ uint16_t lms = ms ;
+
+ while (lms > 0) {
+ if (((uint16_t)micros() - start) >= 1000) {
+ lms--;
+ start += 1000;
}
}
+}
- /* Important notes:
+/* Important notes:
- Max value is 16000µs
- delay is not accurate due to interrupts happening */
- void delayMicroseconds(unsigned int us)
- {
- if (--us == 0)
- return;
- us <<= 2; // * 4
- us -= 2; // - 2
- __asm__ __volatile__ (
- "1: sbiw %0,1" "\n\t" // 2 cycles
- "brne 1b" : "=w" (us) : "0" (us) // 2 cycles
- );
- }
+void delayMicroseconds(unsigned int us)
+{
+ if (--us == 0)
+ return;
+ us <<= 2; // * 4
+ us -= 2; // - 2
+ __asm__ __volatile__ (
+ "1: sbiw %0,1" "\n\t" // 2 cycles
+ "brne 1b" : "=w" (us) : "0" (us) // 2 cycles
+ );
+}
- void init()
- {
- // this needs to be called before setup() or some functions won't work there
- sei();
- }
+void init()
+{
+ // this needs to be called before setup() or some functions won't work there
+ sei();
+}
#endif
#endif
- /**************************/
- /**************************/
- /** Interrupt routines **/
- /**************************/
- /**************************/
+/**************************/
+/**************************/
+/** Interrupt routines **/
+/**************************/
+/**************************/
- //PPM
+//PPM
#ifdef ENABLE_PPM
#ifdef XMEGA
- ISR(PORTD_INT0_vect)
+ISR(PORTD_INT0_vect)
#else
#ifdef STM32_board
- void PPM_decode()
+void PPM_decode()
#else
- ISR(INT1_vect)
+ISR(INT1_vect)
#endif
#endif
- { // Interrupt on PPM pin
- static int8_t chan=-1;
- static uint16_t Prev_TCNT1=0;
- uint16_t Cur_TCNT1;
-
- #ifdef XMEGA
- Cur_TCNT1 = TCC1.CNT - Prev_TCNT1 ; // Capture current Timer1 value
- #else
- #if defined STM32_board
- uint16_t time=TIMER2_BASE->CNT;
- Cur_TCNT1=time-Prev_TCNT1; // Capture current Timer1 value
- #else
- Cur_TCNT1=TCNT1-Prev_TCNT1; // Capture current Timer1 value
- #endif
- #endif
- if(Cur_TCNT1<1000)
- chan=-1; // bad frame
- else
- if(Cur_TCNT1>4840)
- {
- chan=0; // start of frame
- PPM_FLAG_on; // full frame present (even at startup since PPM_data has been initialized)
- }
- else
- if(chan!=-1) // need to wait for start of frame
- { //servo values between 500us and 2420us will end up here
- PPM_data[chan]= Cur_TCNT1>>1;;
- if(chan++>=NUM_CHN)
- chan=-1; // don't accept any new channels
- }
- Prev_TCNT1+=Cur_TCNT1;
+{ // Interrupt on PPM pin
+ static int8_t chan=-1;
+ static uint16_t Prev_TCNT1=0;
+ uint16_t Cur_TCNT1;
+
+ #ifdef XMEGA
+ Cur_TCNT1 = TCC1.CNT - Prev_TCNT1 ; // Capture current Timer1 value
+ #else
+ #if defined STM32_board
+ uint16_t time=TIMER2_BASE->CNT;
+ Cur_TCNT1=time-Prev_TCNT1; // Capture current Timer1 value
+ #else
+ Cur_TCNT1=TCNT1-Prev_TCNT1; // Capture current Timer1 value
+ #endif
+ #endif
+ if(Cur_TCNT1<1000)
+ chan=-1; // bad frame
+ else
+ if(Cur_TCNT1>4840)
+ {
+ chan=0; // start of frame
+ PPM_FLAG_on; // full frame present (even at startup since PPM_data has been initialized)
}
+ else
+ if(chan!=-1) // need to wait for start of frame
+ { //servo values between 500us and 2420us will end up here
+ PPM_data[chan]= Cur_TCNT1>>1;;
+ if(chan++>=NUM_CHN)
+ chan=-1; // don't accept any new channels
+ }
+ Prev_TCNT1+=Cur_TCNT1;
+}
#endif //ENABLE_PPM
#ifdef ENABLE_SERIAL
- //Serial RX
+//Serial RX
#ifdef XMEGA
- ISR(USARTC0_RXC_vect)
+ISR(USARTC0_RXC_vect)
#else
#if defined STM32_board
-
#ifdef __cplusplus
- extern "C" {
- #endif
- void __irq_usart2()
+extern "C" {
+ #endif
+ void __irq_usart2()
+ #else
+ ISR(USART_RX_vect)
+ #endif
+ #endif
+
+ { // RX interrupt
+ static uint8_t idx=0;
+ #ifdef XMEGA
+ if((USARTC0.STATUS & 0x1C)==0) // Check frame error, data overrun and parity error
#else
- ISR(USART_RX_vect)
+ #ifndef STM32_board
+ UCSR0B &= ~_BV(RXCIE0) ; // RX interrupt disable
#endif
- #endif
-
- { // RX interrupt
- static uint8_t idx=0;
- #ifdef XMEGA
- if((USARTC0.STATUS & 0x1C)==0) // Check frame error, data overrun and parity error
- #else
- sei();
- #if defined STM32_board
- if(USART2_BASE->SR & USART_SR_RXNE) {
- if((USART2_BASE->SR &0x0F)==0)
- #else
- if((UCSR0A&0x1C)==0) // Check frame error, data overrun and parity error
- #endif
- #endif
- { // received byte is ok to process
- if(idx==0||discard_frame==1)
- { // Let's try to sync at this point
- idx=0;discard_frame=0;
- #ifdef XMEGA
- if(USARTC0.DATA==0x55) // If 1st byte is 0x55 it looks ok
-
- #else
- #if defined STM32_board
- if(USART2_BASE->DR==0x55)
- #else
- if(UDR0==0x55) // If 1st byte is 0x55 it looks ok
- #endif
- #endif
- {
- #ifdef XMEGA
- TCC1.CCB = TCC1.CNT+(6500L) ; // Full message should be received within timer of 3250us
- TCC1.INTFLAGS = TC1_CCBIF_bm ; // clear OCR1B match flag
- TCC1.INTCTRLB = (TCC1.INTCTRLB & 0xF3) | 0x04 ; // enable interrupt on compare B match
-
- #else
- #if defined STM32_board
- uint16_t OCR1B = TIMER2_BASE->CNT;
- OCR1B +=6500L;
- timer.setCompare(TIMER_CH2,OCR1B);
- timer.attachCompare2Interrupt(ISR_COMPB);
- #else
- OCR1B=TCNT1+6500L; // Full message should be received within timer of 3250us
- TIFR1=(1<SR & USART_SR_RXNE) {
+ if((USART2_BASE->SR &0x0F)==0)
+ #else
+ if((UCSR0A&0x1C)==0) // Check frame error, data overrun and parity error
+ #endif
+ #endif
+ { // received byte is ok to process
+ if(idx==0||discard_frame==1)
+ { // Let's try to sync at this point
+ idx=0;discard_frame=0;
+ #ifdef XMEGA
+ if(USARTC0.DATA==0x55) // If 1st byte is 0x55 it looks ok
+
+ #else
+ #if defined STM32_board
+ if(USART2_BASE->DR==0x55)
+ #else
+ if(UDR0==0x55) // If 1st byte is 0x55 it looks ok
+ #endif
+ #endif
{
- RX_MISSED_BUFF_off; // if rx_buff was good it's not anymore...
-
#ifdef XMEGA
- rx_buff[(idx++)-1]=USARTC0.DATA; // Store received byte
+ TCC1.CCB = TCC1.CNT+(6500L) ; // Full message should be received within timer of 3250us
+ TCC1.INTFLAGS = TC1_CCBIF_bm ; // clear OCR1B match flag
+ TCC1.INTCTRLB = (TCC1.INTCTRLB & 0xF3) | 0x04 ; // enable interrupt on compare B match
+
#else
#if defined STM32_board
-
- rx_buff[(idx++)-1]=USART2_BASE->DR&0xff; // Store received byte
+ uint16_t OCR1B = TIMER2_BASE->CNT;
+ OCR1B +=6500L;
+ timer.setCompare(TIMER_CH2,OCR1B);
+ timer.attachCompare2Interrupt(ISR_COMPB);
#else
-
- rx_buff[(idx++)-1]=UDR0; // Store received byte
- #endif
+ OCR1B=TCNT1+6500L; // Full message should be received within timer of 3250us
+ TIFR1=(1<RXBUFFER_SIZE)
- { // A full frame has been received
-
- if(!IS_RX_DONOTUPDTAE_on)
- { //Good frame received and main has finished with previous buffer
- memcpy((void*)rx_ok_buff,(const void*)rx_buff,RXBUFFER_SIZE);// Duplicate the buffer
- RX_FLAG_on; // flag for main to process servo data
- }
- else
- RX_MISSED_BUFF_on; // notify that rx_buff is good
- idx=0; // start again
- }
+ idx++;
}
}
else
{
+ RX_MISSED_BUFF_off; // if rx_buff was good it's not anymore...
+
#ifdef XMEGA
- idx = USARTC0.DATA ; // Dummy read
- #else
- #if defined STM32_board
- idx=USART2_BASE->DR&0xff;
- #else
- idx=UDR0; // Dummy read
- #endif
- #endif
- discard_frame=1; // Error encountered discard full frame...
- }
-
- if(discard_frame==1)
- {
- #ifdef XMEGA
- TCC1.INTCTRLB &=0xF3; // disable interrupt on compare B match
+ rx_buff[(idx++)-1]=USARTC0.DATA; // Store received byte
#else
#if defined STM32_board
- detachInterrupt(2);//disable interrupt on ch2
- #else
- TIMSK1 &=~(1<DR&0xff; // Store received byte
+ #else
+ rx_buff[(idx++)-1]=UDR0; // Store received byte
+ #endif
#endif
-
- }
- #if defined STM32_board //If activated telemetry it doesn't work activated
+ if(idx>RXBUFFER_SIZE)
+ { // A full frame has been received
+
+ if(!IS_RX_DONOTUPDTAE_on)
+ { //Good frame received and main has finished with previous buffer
+ memcpy((void*)rx_ok_buff,(const void*)rx_buff,RXBUFFER_SIZE);// Duplicate the buffer
+ RX_FLAG_on; // flag for main to process servo data
+ }
+ else
+ RX_MISSED_BUFF_on; // notify that rx_buff is good
+ discard_frame=1; // start again
+ }
+ }
}
- #endif
- }
- #if defined STM32_board
- #ifdef __cplusplus
- }
+ else
+ {
+ #ifdef XMEGA
+ idx = USARTC0.DATA ; // Dummy read
+ #else
+ #if defined STM32_board
+ idx=USART2_BASE->DR&0xff;
+ #else
+ idx=UDR0; // Dummy read
+ #endif
+ #endif
+ discard_frame=1; // Error encountered discard full frame...
+ }
+
+ if(discard_frame==1)
+ {
+ #ifdef XMEGA
+ TCC1.INTCTRLB &=0xF3; // disable interrupt on compare B match
+ #else
+ #if defined STM32_board
+ detachInterrupt(2);//disable interrupt on ch2
+ #else
+ TIMSK1 &=~(1<