Code cleaning (XMEGA)

This commit is contained in:
pascallanger 2016-09-01 17:41:24 +02:00
parent ee27535b82
commit 043a8336e5
3 changed files with 398 additions and 461 deletions

View File

@ -146,6 +146,27 @@ struct PPM_Parameters
uint8_t option; uint8_t option;
}; };
//*******************
//*** Timer ***
//*******************
#ifdef XMEGA
#define TIFR1 TCC1.INTFLAGS
#define OCF1A_bm TC1_CCAIF_bm
#define OCR1A TCC1.CCA
#define TCNT1 TCC1.CNT
#define USARTC0.DATA UDR0
#define OCF1B_bm TC1_CCBIF_bm
#define OCR1B TCC1.CCB
#define TCC1.INTCTRLB TIMSK1
#define SET_TIMSK1_OCIE1B TIMSK1 = (TIMSK1 & 0xF3) | 0x04
#define CLR_TIMSK1_OCIE1B TIMSK1 &= 0xF3
#else
#define OCF1A_bm _BV(OCF1A)
#define OCF1B_bm _BV(OCF1B)
#define SET_TIMSK1_OCIE1B TIMSK1 |= _BV(OCIE1B)
#define CLR_TIMSK1_OCIE1B TIMSK1 &=~_BV(OCIE1B)
#endif
//******************* //*******************
//*** Pinouts *** //*** Pinouts ***
//******************* //*******************

View File

@ -29,6 +29,10 @@
#include "_Config.h" #include "_Config.h"
#include "TX_Def.h" #include "TX_Def.h"
#ifdef XMEGA
#undef ENABLE_PPM // Disable PPM for orange module
#endif
//Global constants/variables //Global constants/variables
uint32_t MProtocol_id;//tx id, uint32_t MProtocol_id;//tx id,
uint32_t MProtocol_id_master; uint32_t MProtocol_id_master;
@ -72,7 +76,7 @@ uint8_t len;
uint8_t RX_num; uint8_t RX_num;
#if defined(FRSKYX_CC2500_INO) || defined(SFHSS_CC2500_INO) #if defined(FRSKYX_CC2500_INO) || defined(SFHSS_CC2500_INO)
uint8_t calData[48]; uint8_t calData[48];
#endif #endif
//Channel mapping for protocols //Channel mapping for protocols
@ -100,7 +104,7 @@ volatile uint16_t PPM_data[NUM_CHN];
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];
#ifndef BASH_SERIAL #ifndef BASH_SERIAL
volatile uint8_t tx_buff[TXBUFFER_SIZE]; volatile uint8_t tx_buff[TXBUFFER_SIZE];
#endif #endif
volatile uint8_t discard_frame = 0; volatile uint8_t discard_frame = 0;
@ -134,27 +138,44 @@ void_function_t remote_callback = 0;
// Init // Init
void setup() void setup()
{ {
#ifdef XMEGA #ifdef XMEGA
PORTD.OUTSET = 0x17 ; // General pinout
PORTD.DIRSET = 0xB2 ; PORTD.OUTSET = 0x17 ;
PORTD.DIRCLR = 0x4D ; PORTD.DIRSET = 0xB2 ;
PORTD.PIN0CTRL = 0x18 ; PORTD.DIRCLR = 0x4D ;
PORTD.PIN2CTRL = 0x18 ; PORTD.PIN0CTRL = 0x18 ;
PORTE.DIRSET = 0x01 ; PORTD.PIN2CTRL = 0x18 ;
PORTE.DIRCLR = 0x02 ; PORTE.DIRSET = 0x01 ;
PORTE.OUTSET = 0x01 ; PORTE.DIRCLR = 0x02 ;
PORTE.OUTSET = 0x01 ;
for ( uint8_t count = 0 ; count < 20 ; count += 1 ) for ( uint8_t count = 0 ; count < 20 ; count += 1 )
asm("nop") ; asm("nop") ;
PORTE.OUTCLR = 0x01 ; PORTE.OUTCLR = 0x01 ;
#else
// General pinout // Timer1 config
DDRD = _BV(A7105_CS_pin)|_BV(SDI_pin)|_BV(SCLK_pin)|_BV( CC25_CSN_pin);//pin output // TCC1 16-bit timer, clocked at 0.5uS
DDRC = _BV(CTRL1_pin)|_BV(CTRL2_pin)|_BV(CYRF_RST_pin); //pin output EVSYS.CH3MUX = 0x80 + 0x04 ; // Prescaler of 16
DDRB = _BV(NRF_CSN_pin)|_BV(CYRF_CSN_pin); //pin output TCC1.CTRLB = 0; TCC1.CTRLC = 0; TCC1.CTRLD = 0; TCC1.CTRLE = 0;
PORTB = _BV(2)|_BV(3)|_BV(4)|_BV(BIND_pin); //pullup on dial (D10=PB2,D11=PB3,D12=PB4) and bind button TCC1.INTCTRLA = 0; TIMSK1 = 0;
PORTC = _BV(0); //pullup on dial (A0=PC0) TCC1.PER = 0xFFFF ;
#endif TCNT1 = 0 ;
TCC1.CTRLA = 0x0B ; // Event3 (prescale of 16)
#else
// General pinout
DDRD = _BV(A7105_CS_pin)|_BV(SDI_pin)|_BV(SCLK_pin)|_BV( CC25_CSN_pin);//pin output
DDRC = _BV(CTRL1_pin)|_BV(CTRL2_pin)|_BV(CYRF_RST_pin); //pin output
DDRB = _BV(NRF_CSN_pin)|_BV(CYRF_CSN_pin); //pin output
PORTB = _BV(2)|_BV(3)|_BV(4)|_BV(BIND_pin); //pullup on dial (D10=PB2,D11=PB3,D12=PB4) and bind button
PORTC = _BV(0); //pullup on dial (A0=PC0)
#ifdef DEBUG_TX
TX_SET_OUTPUT;
#endif
// Timer1 config
TCCR1A = 0;
TCCR1B = (1 << CS11); //prescaler8, set timer1 to increment every 0.5us(16Mhz) and start timer
#endif
// Set Chip selects // Set Chip selects
A7105_CS_on; A7105_CS_on;
@ -165,32 +186,13 @@ void setup()
SDI_on; SDI_on;
SCK_off; SCK_off;
//#ifdef XMEGA
// // SPI enable, master, prescale of 16
// SPID.CTRL = SPI_ENABLE_bm | SPI_MASTER_bm | SPI_PRESCALER0_bm ;
//#endif
// Timer1 config
#ifdef XMEGA
// TCC1 16-bit timer, clocked at 0.5uS
EVSYS.CH3MUX = 0x80 + 0x04 ; // Prescaler of 16
TCC1.CTRLB = 0; TCC1.CTRLC = 0; TCC1.CTRLD = 0; TCC1.CTRLE = 0;
TCC1.INTCTRLA = 0; TCC1.INTCTRLB = 0;
TCC1.PER = 0xFFFF ;
TCC1.CNT = 0 ;
TCC1.CTRLA = 0x0B ; // Event3 (prescale of 16)
#else
TCCR1A = 0;
TCCR1B = (1 << CS11); //prescaler8, set timer1 to increment every 0.5us(16Mhz) and start timer
#endif
// Set servos positions // Set servos positions
for(uint8_t i=0;i<NUM_CHN;i++) for(uint8_t i=0;i<NUM_CHN;i++)
Servo_data[i]=1500; Servo_data[i]=1500;
Servo_data[THROTTLE]=servo_min_100; Servo_data[THROTTLE]=servo_min_100;
#ifdef ENABLE_PPM #ifdef ENABLE_PPM
memcpy((void *)PPM_data,Servo_data, sizeof(Servo_data)); memcpy((void *)PPM_data,Servo_data, sizeof(Servo_data));
#endif #endif
//Wait for every component to start //Wait for every component to start
delayMilliseconds(100); delayMilliseconds(100);
@ -201,11 +203,11 @@ void setup()
// Read status of mode select binary switch // Read status of mode select binary switch
// after this mode_select will be one of {0000, 0001, ..., 1111} // after this mode_select will be one of {0000, 0001, ..., 1111}
#ifdef XMEGA #ifndef ENABLE_PPM
mode_select = MODE_SERIAL ; // only serial mode mode_select = MODE_SERIAL ; // force serial mode
#else #else
mode_select=0x0F - ( ( (PINB>>2)&0x07 ) | ( (PINC<<3)&0x08) );//encoder dip switches 1,2,4,8=>B2,B3,B4,C0 mode_select=0x0F - ( ( (PINB>>2)&0x07 ) | ( (PINC<<3)&0x08) );//encoder dip switches 1,2,4,8=>B2,B3,B4,C0
#endif #endif
// Update LED // Update LED
LED_OFF; LED_OFF;
@ -235,27 +237,25 @@ void setup()
protocol_init(); protocol_init();
#ifndef XMEGA
//Configure PPM interrupt //Configure PPM interrupt
EICRA |=_BV(ISC11); // The rising edge of INT1 pin D3 generates an interrupt request EICRA |=_BV(ISC11); // The rising edge of INT1 pin D3 generates an interrupt request
EIMSK |= _BV(INT1); // INT1 interrupt enable EIMSK |= _BV(INT1); // INT1 interrupt enable
#endif
#if defined(TELEMETRY) #if defined(TELEMETRY)
PPM_Telemetry_serial_init(); // Configure serial for telemetry PPM_Telemetry_serial_init(); // Configure serial for telemetry
#endif #endif
} }
else else
#endif //ENABLE_PPM #endif //ENABLE_PPM
{ // Serial { // Serial
#ifdef ENABLE_SERIAL #ifdef ENABLE_SERIAL
cur_protocol[0]=0; cur_protocol[0]=0;
cur_protocol[1]=0; cur_protocol[1]=0;
prev_protocol=0; prev_protocol=0;
servo_max_100=SERIAL_MAX_100; servo_min_100=SERIAL_MIN_100; servo_max_100=SERIAL_MAX_100; servo_min_100=SERIAL_MIN_100;
servo_max_125=SERIAL_MAX_125; servo_min_125=SERIAL_MIN_125; servo_max_125=SERIAL_MAX_125; servo_min_125=SERIAL_MIN_125;
Mprotocol_serial_init(); // Configure serial and enable RX interrupt Mprotocol_serial_init(); // Configure serial and enable RX interrupt
#endif //ENABLE_SERIAL #endif //ENABLE_SERIAL
} }
} }
@ -275,25 +275,14 @@ void loop()
} }
while(remote_callback==0); while(remote_callback==0);
} }
#ifdef XMEGA if( (TIFR1 & OCF1A_bm) != 0)
if( (TCC1.INTFLAGS & TC1_CCAIF_bm) != 0) {
{ cli(); // Disable global int due to RW of 16 bits registers
cli(); // Disable global int due to RW of 16 bits registers OCR1A=TCNT1; // Callback should already have been called... Use "now" as new sync point.
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
else while((TIFR1 & OCF1A_bm) == 0); // Wait before callback
while((TCC1.INTFLAGS & TC1_CCAIF_bm) == 0); // wait before callback
#else
if( (TIFR1 & _BV(OCF1A)) != 0)
{
cli(); // Disable global int due to RW of 16 bits registers
OCR1A=TCNT1; // Callback should already have been called... Use "now" as new sync point.
sei(); // Enable global int
}
else
while((TIFR1 & _BV(OCF1A)) == 0); // Wait before callback
#endif
do do
{ {
TX_ON; TX_ON;
@ -306,41 +295,22 @@ void loop()
while(next_callback>4000) while(next_callback>4000)
{ // start to wait here as much as we can... { // start to wait here as much as we can...
next_callback-=2000; // We will wait below for 2ms next_callback-=2000; // We will wait below for 2ms
#ifdef XMEGA cli(); // Disable global int due to RW of 16 bits registers
cli(); // Disable global int due to RW of 16 bits registers OCR1A += 2000*2 ; // set compare A for callback
TCC1.CCA +=2000*2; // set compare A for callback TIFR1=OCF1A_bm; // clear compare A=callback flag
TCC1.INTFLAGS = TC1_CCAIF_bm ; // clear compare A=callback flag sei(); // enable global int
sei(); // enable global int Update_All();
Update_All(); if(IS_CHANGE_PROTOCOL_FLAG_on)
if(IS_CHANGE_PROTOCOL_FLAG_on) break; // Protocol has been changed
break; // Protocol has been changed while((TIFR1 & OCF1A_bm) == 0); // wait 2ms...
while((TCC1.INTFLAGS & TC1_CCAIF_bm) == 0); // wait 2ms...
#else
cli(); // Disable global int due to RW of 16 bits registers
OCR1A += 2000*2 ; // set compare A for callback
TIFR1=_BV(OCF1A); // clear compare A=callback flag
sei(); // enable global int
Update_All();
if(IS_CHANGE_PROTOCOL_FLAG_on)
break; // Protocol has been changed
while((TIFR1 & _BV(OCF1A)) == 0); // wait 2ms...
#endif
} }
// at this point we have a maximum of 4ms in next_callback // at this point we have a maximum of 4ms in next_callback
next_callback *= 2 ; next_callback *= 2 ;
#ifdef XMEGA cli(); // Disable global int due to RW of 16 bits registers
cli(); // Disable global int due to RW of 16 bits registers OCR1A+= next_callback ; // set compare A for callback
TCC1.CCA +=next_callback; // set compare A for callback TIFR1=OCF1A_bm; // clear compare A=callback flag
TCC1.INTFLAGS = TC1_CCAIF_bm ; // clear compare A=callback flag diff=OCR1A-TCNT1; // compare timer and comparator
diff=TCC1.CCA-TCC1.CNT; // compare timer and comparator sei(); // enable global int
sei(); // enable global int
#else
cli(); // Disable global int due to RW of 16 bits registers
OCR1A+= next_callback ; // set compare A for callback
TIFR1=_BV(OCF1A); // clear compare A=callback flag
diff=OCR1A-TCNT1; // compare timer and comparator
sei(); // enable global int
#endif
} }
while(diff&0x8000); // Callback did not took more than requested time for next callback while(diff&0x8000); // Callback did not took more than requested time for next callback
// so we can launch Update_All before next callback // so we can launch Update_All before next callback
@ -349,49 +319,42 @@ void loop()
void Update_All() void Update_All()
{ {
TX_ON; #ifdef ENABLE_SERIAL
NOP(); if(mode_select==MODE_SERIAL && IS_RX_FLAG_on) // Serial mode and something has been received
TX_OFF; {
update_serial_data(); // Update protocol and data
#ifdef ENABLE_SERIAL update_aux_flags();
if(mode_select==MODE_SERIAL && IS_RX_FLAG_on) // Serial mode and something has been received if(IS_CHANGE_PROTOCOL_FLAG_on)
{ { // Protocol needs to be changed
update_serial_data(); // Update protocol and data LED_OFF; //led off during protocol init
update_aux_flags(); modules_reset(); //reset all modules
if(IS_CHANGE_PROTOCOL_FLAG_on) protocol_init(); //init new protocol
{ // 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
#endif //ENABLE_SERIAL #ifdef ENABLE_PPM
#ifdef ENABLE_PPM if(mode_select!=MODE_SERIAL && IS_PPM_FLAG_on) // PPM mode and a full frame has been received
if(mode_select!=MODE_SERIAL && IS_PPM_FLAG_on) // PPM mode and a full frame has been received {
{ for(uint8_t i=0;i<NUM_CHN;i++)
for(uint8_t i=0;i<NUM_CHN;i++) { // update servo data without interrupts to prevent bad read in protocols
{ // update servo data without interrupts to prevent bad read in protocols uint16_t temp_ppm ;
uint16_t temp_ppm ; cli(); // disable global int
cli(); // disable global int temp_ppm = PPM_data[i] ;
temp_ppm = PPM_data[i] ; sei(); // enable global int
sei(); // enable global int if(temp_ppm<PPM_MIN_125) temp_ppm=PPM_MIN_125;
if(temp_ppm<PPM_MIN_125) temp_ppm=PPM_MIN_125; else if(temp_ppm>PPM_MAX_125) temp_ppm=PPM_MAX_125;
else if(temp_ppm>PPM_MAX_125) temp_ppm=PPM_MAX_125; Servo_data[i]= temp_ppm ;
Servo_data[i]= temp_ppm ; }
update_aux_flags();
PPM_FLAG_off; // wait for next frame before update
} }
update_aux_flags(); #endif //ENABLE_PPM
PPM_FLAG_off; // wait for next frame before update
}
#endif //ENABLE_PPM
update_led_status(); update_led_status();
#if defined(TELEMETRY) #if defined(TELEMETRY)
uint8_t protocol=cur_protocol[0]&0x1F; uint8_t protocol=cur_protocol[0]&0x1F;
if( (protocol==MODE_FRSKY) || (protocol==MODE_HUBSAN) || (protocol==MODE_FRSKYX) || (protocol==MODE_DSM) ) if( (protocol==MODE_FRSKY) || (protocol==MODE_HUBSAN) || (protocol==MODE_FRSKYX) || (protocol==MODE_DSM) )
TelemetryUpdate(); TelemetryUpdate();
#endif #endif
TX_ON;
NOP();
TX_OFF;
} }
// Update Servo_AUX flags based on servo AUX positions // Update Servo_AUX flags based on servo AUX positions
@ -429,27 +392,29 @@ static void update_led_status(void)
inline void tx_pause() inline void tx_pause()
{ {
#ifdef TELEMETRY #ifdef TELEMETRY
#ifdef XMEGA #ifdef XMEGA
USARTC0.CTRLA &= ~0x03 ; // Pause telemetry by disabling transmitter interrupt USARTC0.CTRLA &= ~0x03 ; // Pause telemetry by disabling transmitter interrupt
#else #else
#ifndef BASH_SERIAL #ifndef BASH_SERIAL
UCSR0B &= ~_BV(UDRIE0); // Pause telemetry by disabling transmitter interrupt UCSR0B &= ~_BV(UDRIE0); // Pause telemetry by disabling transmitter interrupt
#endif
#endif #endif
#endif #endif
#endif
} }
inline void tx_resume() inline void tx_resume()
{ {
#ifdef TELEMETRY #ifdef TELEMETRY
if(!IS_TX_PAUSE_on) if(!IS_TX_PAUSE_on)
#ifdef XMEGA #ifdef XMEGA
USARTC0.CTRLA = (USARTC0.CTRLA & 0xFC) | 0x01 ; // Resume telemetry by enabling transmitter interrupt USARTC0.CTRLA = (USARTC0.CTRLA & 0xFC) | 0x01 ; // Resume telemetry by enabling transmitter interrupt
#else #else
UCSR0B |= _BV(UDRIE0); // Resume telemetry by enabling transmitter interrupt #ifndef BASH_SERIAL
#endif UCSR0B |= _BV(UDRIE0); // Resume telemetry by enabling transmitter interrupt
#endif #endif
#endif
#endif
} }
// Protocol start // Protocol start
@ -482,186 +447,186 @@ static void protocol_init()
switch(cur_protocol[0]&0x1F) // Init the requested protocol switch(cur_protocol[0]&0x1F) // Init the requested protocol
{ {
#if defined(FLYSKY_A7105_INO) #if defined(FLYSKY_A7105_INO)
case MODE_FLYSKY: case MODE_FLYSKY:
CTRL1_off; //antenna RF1 CTRL1_off; //antenna RF1
next_callback = initFlySky(); next_callback = initFlySky();
remote_callback = ReadFlySky; remote_callback = ReadFlySky;
break; break;
#endif #endif
#if defined(HUBSAN_A7105_INO) #if defined(HUBSAN_A7105_INO)
case MODE_HUBSAN: case MODE_HUBSAN:
CTRL1_off; //antenna RF1 CTRL1_off; //antenna RF1
if(IS_BIND_BUTTON_FLAG_on) random_id(10,true); // Generate new ID if bind button is pressed. if(IS_BIND_BUTTON_FLAG_on) random_id(10,true); // Generate new ID if bind button is pressed.
next_callback = initHubsan(); next_callback = initHubsan();
remote_callback = ReadHubsan; remote_callback = ReadHubsan;
break; break;
#endif #endif
#if defined(FRSKY_CC2500_INO) #if defined(FRSKY_CC2500_INO)
case MODE_FRSKY: case MODE_FRSKY:
CTRL1_off; //antenna RF2 CTRL1_off; //antenna RF2
CTRL2_on; CTRL2_on;
next_callback = initFrSky_2way(); next_callback = initFrSky_2way();
remote_callback = ReadFrSky_2way; remote_callback = ReadFrSky_2way;
break; break;
#endif #endif
#if defined(FRSKY1_CC2500_INO) #if defined(FRSKY1_CC2500_INO)
case MODE_FRSKY1: case MODE_FRSKY1:
CTRL1_off; //antenna RF2 CTRL1_off; //antenna RF2
CTRL2_on; CTRL2_on;
next_callback = initFRSKY1(); next_callback = initFRSKY1();
remote_callback = ReadFRSKY1; remote_callback = ReadFRSKY1;
break; break;
#endif #endif
#if defined(FRSKYX_CC2500_INO) #if defined(FRSKYX_CC2500_INO)
case MODE_FRSKYX: case MODE_FRSKYX:
CTRL1_off; //antenna RF2 CTRL1_off; //antenna RF2
CTRL2_on; CTRL2_on;
next_callback = initFrSkyX(); next_callback = initFrSkyX();
remote_callback = ReadFrSkyX; remote_callback = ReadFrSkyX;
break; break;
#endif #endif
#if defined(SFHSS_CC2500_INO) #if defined(SFHSS_CC2500_INO)
case MODE_SFHSS: case MODE_SFHSS:
CTRL1_off; //antenna RF2 CTRL1_off; //antenna RF2
CTRL2_on; CTRL2_on;
next_callback = initSFHSS(); next_callback = initSFHSS();
remote_callback = ReadSFHSS; remote_callback = ReadSFHSS;
break; break;
#endif #endif
#if defined(DSM_CYRF6936_INO) #if defined(DSM_CYRF6936_INO)
case MODE_DSM: case MODE_DSM:
CTRL2_on; //antenna RF4 CTRL2_on; //antenna RF4
next_callback = initDsm(); next_callback = initDsm();
//Servo_data[2]=1500;//before binding //Servo_data[2]=1500;//before binding
remote_callback = ReadDsm; remote_callback = ReadDsm;
break; break;
#endif #endif
#if defined(DEVO_CYRF6936_INO) #if defined(DEVO_CYRF6936_INO)
case MODE_DEVO: case MODE_DEVO:
#ifdef ENABLE_PPM #ifdef ENABLE_PPM
if(mode_select) //PPM mode if(mode_select) //PPM mode
{ {
if(IS_BIND_BUTTON_FLAG_on) if(IS_BIND_BUTTON_FLAG_on)
{ {
eeprom_write_byte((uint8_t*)(30+mode_select),0x00); // reset to autobind mode for the current model eeprom_write_byte((uint8_t*)(30+mode_select),0x00); // reset to autobind mode for the current model
option=0; option=0;
} }
else else
{ {
option=eeprom_read_byte((uint8_t*)(30+mode_select)); // load previous mode: autobind or fixed id option=eeprom_read_byte((uint8_t*)(30+mode_select)); // load previous mode: autobind or fixed id
if(option!=1) option=0; // if not fixed id mode then it should be autobind if(option!=1) option=0; // if not fixed id mode then it should be autobind
} }
} }
#endif //ENABLE_PPM #endif //ENABLE_PPM
CTRL2_on; //antenna RF4 CTRL2_on; //antenna RF4
next_callback = DevoInit(); next_callback = DevoInit();
remote_callback = devo_callback; remote_callback = devo_callback;
break; break;
#endif #endif
#if defined(J6PRO_CYRF6936_INO) #if defined(J6PRO_CYRF6936_INO)
case MODE_J6PRO: case MODE_J6PRO:
CTRL2_on; //antenna RF4 CTRL2_on; //antenna RF4
next_callback = initJ6Pro(); next_callback = initJ6Pro();
remote_callback = ReadJ6Pro; remote_callback = ReadJ6Pro;
break; break;
#endif #endif
#if defined(HISKY_NRF24L01_INO) #if defined(HISKY_NRF24L01_INO)
case MODE_HISKY: case MODE_HISKY:
next_callback=initHiSky(); next_callback=initHiSky();
remote_callback = hisky_cb; remote_callback = hisky_cb;
break; break;
#endif #endif
#if defined(V2X2_NRF24L01_INO) #if defined(V2X2_NRF24L01_INO)
case MODE_V2X2: case MODE_V2X2:
next_callback = initV2x2(); next_callback = initV2x2();
remote_callback = ReadV2x2; remote_callback = ReadV2x2;
break; break;
#endif #endif
#if defined(YD717_NRF24L01_INO) #if defined(YD717_NRF24L01_INO)
case MODE_YD717: case MODE_YD717:
next_callback=initYD717(); next_callback=initYD717();
remote_callback = yd717_callback; remote_callback = yd717_callback;
break; break;
#endif #endif
#if defined(KN_NRF24L01_INO) #if defined(KN_NRF24L01_INO)
case MODE_KN: case MODE_KN:
next_callback = initKN(); next_callback = initKN();
remote_callback = kn_callback; remote_callback = kn_callback;
break; break;
#endif #endif
#if defined(SYMAX_NRF24L01_INO) #if defined(SYMAX_NRF24L01_INO)
case MODE_SYMAX: case MODE_SYMAX:
next_callback = initSymax(); next_callback = initSymax();
remote_callback = symax_callback; remote_callback = symax_callback;
break; break;
#endif #endif
#if defined(SLT_NRF24L01_INO) #if defined(SLT_NRF24L01_INO)
case MODE_SLT: case MODE_SLT:
next_callback=initSLT(); next_callback=initSLT();
remote_callback = SLT_callback; remote_callback = SLT_callback;
break; break;
#endif #endif
#if defined(CX10_NRF24L01_INO) #if defined(CX10_NRF24L01_INO)
case MODE_CX10: case MODE_CX10:
next_callback=initCX10(); next_callback=initCX10();
remote_callback = CX10_callback; remote_callback = CX10_callback;
break; break;
#endif #endif
#if defined(CG023_NRF24L01_INO) #if defined(CG023_NRF24L01_INO)
case MODE_CG023: case MODE_CG023:
next_callback=initCG023(); next_callback=initCG023();
remote_callback = CG023_callback; remote_callback = CG023_callback;
break; break;
#endif #endif
#if defined(BAYANG_NRF24L01_INO) #if defined(BAYANG_NRF24L01_INO)
case MODE_BAYANG: case MODE_BAYANG:
next_callback=initBAYANG(); next_callback=initBAYANG();
remote_callback = BAYANG_callback; remote_callback = BAYANG_callback;
break; break;
#endif #endif
#if defined(ESKY_NRF24L01_INO) #if defined(ESKY_NRF24L01_INO)
case MODE_ESKY: case MODE_ESKY:
next_callback=initESKY(); next_callback=initESKY();
remote_callback = ESKY_callback; remote_callback = ESKY_callback;
break; break;
#endif #endif
#if defined(MT99XX_NRF24L01_INO) #if defined(MT99XX_NRF24L01_INO)
case MODE_MT99XX: case MODE_MT99XX:
next_callback=initMT99XX(); next_callback=initMT99XX();
remote_callback = MT99XX_callback; remote_callback = MT99XX_callback;
break; break;
#endif #endif
#if defined(MJXQ_NRF24L01_INO) #if defined(MJXQ_NRF24L01_INO)
case MODE_MJXQ: case MODE_MJXQ:
next_callback=initMJXQ(); next_callback=initMJXQ();
remote_callback = MJXQ_callback; remote_callback = MJXQ_callback;
break; break;
#endif #endif
#if defined(SHENQI_NRF24L01_INO) #if defined(SHENQI_NRF24L01_INO)
case MODE_SHENQI: case MODE_SHENQI:
next_callback=initSHENQI(); next_callback=initSHENQI();
remote_callback = SHENQI_callback; remote_callback = SHENQI_callback;
break; break;
#endif #endif
#if defined(FY326_NRF24L01_INO) #if defined(FY326_NRF24L01_INO)
case MODE_FY326: case MODE_FY326:
next_callback=initFY326(); next_callback=initFY326();
remote_callback = FY326_callback; remote_callback = FY326_callback;
break; break;
#endif #endif
#if defined(FQ777_NRF24L01_INO) #if defined(FQ777_NRF24L01_INO)
case MODE_FQ777: case MODE_FQ777:
next_callback=initFQ777(); next_callback=initFQ777();
remote_callback = FQ777_callback; remote_callback = FQ777_callback;
break; break;
#endif #endif
#if defined(ASSAN_NRF24L01_INO) #if defined(ASSAN_NRF24L01_INO)
case MODE_ASSAN: case MODE_ASSAN:
next_callback=initASSAN(); next_callback=initASSAN();
remote_callback = ASSAN_callback; remote_callback = ASSAN_callback;
break; break;
#endif #endif
} }
if(next_callback>32000) if(next_callback>32000)
@ -671,15 +636,9 @@ static void protocol_init()
next_callback-=temp<<10; // between 2-3ms left at this stage next_callback-=temp<<10; // between 2-3ms left at this stage
} }
cli(); // disable global int cli(); // disable global int
#ifdef XMEGA OCR1A = TCNT1 + next_callback*2;// set compare A for callback
TCC1.CCA = TCC1.CNT + next_callback*2; // set compare A for callback
sei(); // enable global int sei(); // enable global int
TCC1.INTFLAGS = TC1_CCAIF_bm ; // clear compare A flag TIFR1 = OCF1A_bm ; // clear compare A flag
#else
OCR1A=TCNT1+next_callback*2; // set compare A for callback
sei(); // enable global int
TIFR1=_BV(OCF1A); // clear compare A flag
#endif
BIND_BUTTON_FLAG_off; // do not bind/reset id anymore even if protocol change BIND_BUTTON_FLAG_off; // do not bind/reset id anymore even if protocol change
} }
@ -834,40 +793,37 @@ uint16_t limit_channel_100(uint8_t ch)
void Mprotocol_serial_init() void Mprotocol_serial_init()
{ {
#ifdef XMEGA #ifdef XMEGA
PORTC.OUTSET = 0x08 ;
PORTC.OUTSET = 0x08 ; PORTC.DIRSET = 0x08 ;
PORTC.DIRSET = 0x08 ;
USARTC0.BAUDCTRLA = 19 ; USARTC0.BAUDCTRLA = 19 ;
USARTC0.BAUDCTRLB = 0 ; USARTC0.BAUDCTRLB = 0 ;
USARTC0.CTRLB = 0x18 ; USARTC0.CTRLB = 0x18 ;
USARTC0.CTRLA = (USARTC0.CTRLA & 0xCF) | 0x10 ; USARTC0.CTRLA = (USARTC0.CTRLA & 0xCF) | 0x10 ;
USARTC0.CTRLC = 0x2B ; USARTC0.CTRLC = 0x2B ;
USARTC0.DATA ; UDR0 ;
#ifdef INVERT_TELEMETRY #ifdef INVERT_TELEMETRY
PORTC.PIN3CTRL |= 0x40 ; PORTC.PIN3CTRL |= 0x40 ;
#endif #endif
#else #else
#include <util/setbaud.h> #include <util/setbaud.h>
UBRR0H = UBRRH_VALUE; UBRR0H = UBRRH_VALUE;
UBRR0L = UBRRL_VALUE; UBRR0L = UBRRL_VALUE;
UCSR0A = 0 ; // Clear X2 bit UCSR0A = 0 ; // Clear X2 bit
//Set frame format to 8 data bits, even parity, 2 stop bits //Set frame format to 8 data bits, even parity, 2 stop bits
UCSR0C = _BV(UPM01)|_BV(USBS0)|_BV(UCSZ01)|_BV(UCSZ00); UCSR0C = _BV(UPM01)|_BV(USBS0)|_BV(UCSZ01)|_BV(UCSZ00);
while ( UCSR0A & (1 << RXC0) )//flush receive buffer while ( UCSR0A & (1 << RXC0) )//flush receive buffer
UDR0; UDR0;
//enable reception and RC complete interrupt //enable reception and RC complete interrupt
UCSR0B = _BV(RXEN0)|_BV(RXCIE0);//rx enable and interrupt UCSR0B = _BV(RXEN0)|_BV(RXCIE0);//rx enable and interrupt
#ifdef DEBUG_TX #ifndef DEBUG_TX
TX_SET_OUTPUT; #if defined(TELEMETRY)
#else initTXSerial( SPEED_100K ) ;
#if defined(TELEMETRY) #endif //TELEMETRY
initTXSerial( SPEED_100K ) ; #endif //DEBUG_TX
#endif //TELEMETRY #endif //XMEGA
#endif //DEBUG_TX
#endif //XMEGA
} }
#if defined(TELEMETRY) #if defined(TELEMETRY)
@ -1076,11 +1032,7 @@ ISR(INT1_vect, ISR_NOBLOCK)
static uint16_t Prev_TCNT1=0; static uint16_t Prev_TCNT1=0;
uint16_t Cur_TCNT1; uint16_t Cur_TCNT1;
#ifdef XMEGA Cur_TCNT1 = TCNT1 - Prev_TCNT1 ; // Capture current Timer1 value
Cur_TCNT1 = TCC1.CNT - Prev_TCNT1 ; // Capture current Timer1 value
#else
Cur_TCNT1=TCNT1-Prev_TCNT1; // Capture current Timer1 value
#endif
if(Cur_TCNT1<1000) if(Cur_TCNT1<1000)
chan=-1; // bad frame chan=-1; // bad frame
else else
@ -1110,44 +1062,30 @@ ISR(USART_RX_vect)
{ // RX interrupt { // RX interrupt
static uint8_t idx=0; static uint8_t idx=0;
#ifdef XMEGA #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 #else
UCSR0B &= ~_BV(RXCIE0) ; // RX interrupt disable UCSR0B &= ~_BV(RXCIE0) ; // RX interrupt disable
sei() ; sei() ;
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(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; idx=0;discard_frame=0;
#ifdef XMEGA if(UDR0==0x55) // If 1st byte is 0x55 it looks ok
if(USARTC0.DATA==0x55) // If 1st byte is 0x55 it looks ok
#else
if(UDR0==0x55) // If 1st byte is 0x55 it looks ok
#endif
{ {
TX_RX_PAUSE_on; TX_RX_PAUSE_on;
tx_pause(); tx_pause();
#ifdef XMEGA OCR1B = TCNT1+(6500L) ; // Full message should be received within timer of 3250us
TCC1.CCB = TCC1.CNT+(6500L) ; // Full message should be received within timer of 3250us TIFR1 = OCF1B_bm ; // clear OCR1B match flag
TCC1.INTFLAGS = TC1_CCBIF_bm ; // clear OCR1B match flag SET_TIMSK1_OCIE1B ; // enable interrupt on compare B match
TCC1.INTCTRLB = (TCC1.INTCTRLB & 0xF3) | 0x04 ; // enable interrupt on compare B match
#else
OCR1B=TCNT1+6500L; // Full message should be received within timer of 3250us
TIFR1=_BV(OCF1B); // clear OCR1B match flag
TIMSK1 |=_BV(OCIE1B); // enable interrupt on compare B match
#endif
idx++; idx++;
} }
} }
else else
{ {
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...
#ifdef XMEGA rx_buff[(idx++)-1]=UDR0; // Store received byte
rx_buff[(idx++)-1]=USARTC0.DATA; // Store received byte
#else
rx_buff[(idx++)-1]=UDR0; // Store received byte
#endif
if(idx>RXBUFFER_SIZE) if(idx>RXBUFFER_SIZE)
{ // A full frame has been received { // A full frame has been received
if(!IS_RX_DONOTUPDTAE_on) if(!IS_RX_DONOTUPDTAE_on)
@ -1156,27 +1094,19 @@ ISR(USART_RX_vect)
RX_FLAG_on; // flag for main to process servo data RX_FLAG_on; // flag for main to process servo data
} }
else else
RX_MISSED_BUFF_on; // notify that rx_buff is good RX_MISSED_BUFF_on; // notify that rx_buff is good
discard_frame=1; // start again discard_frame=1; // start again
} }
} }
} }
else else
{ {
#ifdef XMEGA idx=UDR0; // Dummy read
idx = USARTC0.DATA; // Dummy read discard_frame=1; // Error encountered discard full frame...
#else
idx=UDR0; // Dummy read
#endif
discard_frame=1; // Error encountered discard full frame...
} }
if(discard_frame==1) if(discard_frame==1)
{ {
#ifdef XMEGA CLR_TIMSK1_OCIE1B; // Disable interrupt on compare B match
TCC1.INTCTRLB &=0xF3; // Disable interrupt on compare B match
#else
TIMSK1 &=~_BV(OCIE1B); // Disable interrupt on compare B match
#endif
TX_RX_PAUSE_off; TX_RX_PAUSE_off;
tx_resume(); tx_resume();
} }
@ -1190,16 +1120,11 @@ ISR(USART_RX_vect)
#ifdef XMEGA #ifdef XMEGA
ISR(TCC1_CCB_vect) ISR(TCC1_CCB_vect)
#else #else
//ISR(TIMER1_COMPB_vect)
ISR(TIMER1_COMPB_vect, ISR_NOBLOCK ) ISR(TIMER1_COMPB_vect, ISR_NOBLOCK )
#endif #endif
{ // Timer1 compare B interrupt { // Timer1 compare B interrupt
discard_frame=1; discard_frame=1;
#ifdef XMEGA CLR_TIMSK1_OCIE1B; // Disable interrupt on compare B match
TCC1.INTCTRLB &=0xF3; // Disable interrupt on compare B match
#else
TIMSK1 &=~_BV(OCIE1B); // Disable interrupt on compare B match
#endif
tx_resume(); tx_resume();
} }
#endif //ENABLE_SERIAL #endif //ENABLE_SERIAL

View File

@ -1,7 +1,7 @@
//************************************* //**************************
// FrSky Telemetry serial code * // Telemetry serial code *
// By Midelic on RCGroups * // By Midelic on RCGroups *
//************************************* //**************************
#if defined TELEMETRY #if defined TELEMETRY
@ -30,15 +30,14 @@ uint8_t frame[18];
#ifdef BASH_SERIAL #ifdef BASH_SERIAL
// For bit-bashed serial output // For bit-bashed serial output
struct t_serial_bash
struct t_serial_bash {
{ uint8_t head ;
uint8_t head ; uint8_t tail ;
uint8_t tail ; uint8_t data[64] ;
uint8_t data[64] ; uint8_t busy ;
uint8_t busy ; uint8_t speed ;
uint8_t speed ; } SerialControl ;
} SerialControl ;
#endif #endif
#if defined DSM_TELEMETRY #if defined DSM_TELEMETRY
@ -540,18 +539,10 @@ ISR(USART_UDRE_vect)
{ {
if(++tx_tail>=TXBUFFER_SIZE)//head if(++tx_tail>=TXBUFFER_SIZE)//head
tx_tail=0; tx_tail=0;
#ifdef XMEGA
USARTC0.DATA = tx_buff[tx_tail] ;
#else
UDR0=tx_buff[tx_tail]; UDR0=tx_buff[tx_tail];
#endif
} }
if (tx_tail == tx_head) if (tx_tail == tx_head)
#ifdef XMEGA tx_pause(); // Check if all data is transmitted . if yes disable transmitter UDRE interrupt
USARTC0.CTRLA &= ~0x03 ;
#else
UCSR0B &= ~(1<<UDRIE0); // Check if all data is transmitted . if yes disable transmitter UDRE interrupt
#endif
} }
#else //BASH_SERIAL #else //BASH_SERIAL
@ -561,11 +552,11 @@ ISR(USART_UDRE_vect)
void initTXSerial( uint8_t speed) void initTXSerial( uint8_t speed)
{ {
TIMSK0 = 0 ; // Stop all timer 0 interrupts TIMSK0 = 0 ; // Stop all timer 0 interrupts
#ifdef INVERT_SERIAL #ifdef INVERT_SERIAL
PORTD &= ~2 ; PORTD &= ~2 ;
#else #else
PORTD |= 2 ; PORTD |= 2 ;
#endif #endif
DDRD |= 2 ; // TxD pin is an output DDRD |= 2 ; // TxD pin is an output
UCSR0B &= ~(1<<TXEN0) ; UCSR0B &= ~(1<<TXEN0) ;