Invert serial, optimization and SFHSS

This commit is contained in:
pascallanger 2016-08-15 11:52:43 +02:00
parent 9e902a5dd4
commit 7438545a16
14 changed files with 611 additions and 177 deletions

View File

@ -155,7 +155,11 @@ void A7105_SetPower()
power=IS_POWER_FLAG_on?A7105_HIGH_POWER:A7105_LOW_POWER;
if(IS_RANGE_FLAG_on)
power=A7105_RANGE_POWER;
A7105_WriteReg(0x28, power);
if(prev_power != power)
{
A7105_WriteReg(0x28, power);
prev_power=power;
}
}
void A7105_Strobe(uint8_t address) {

View File

@ -125,7 +125,11 @@ void CC2500_SetPower()
power=IS_POWER_FLAG_on?CC2500_HIGH_POWER:CC2500_LOW_POWER;
if(IS_RANGE_FLAG_on)
power=CC2500_RANGE_POWER;
CC2500_WriteReg(CC2500_3E_PATABLE, power);
if(prev_power != power)
{
CC2500_WriteReg(CC2500_3E_PATABLE, power);
prev_power=power;
}
}
void CC2500_SetTxRxMode(uint8_t mode)

View File

@ -128,7 +128,11 @@ void CYRF_SetPower(uint8_t val)
power=IS_POWER_FLAG_on?CYRF_HIGH_POWER:CYRF_LOW_POWER;
if(IS_RANGE_FLAG_on)
power=CYRF_RANGE_POWER;
CYRF_WriteRegister(CYRF_03_TX_CFG, val | power);
if(prev_power != power)
{
CYRF_WriteRegister(CYRF_03_TX_CFG, val | power);
prev_power=power;
}
}
/*

View File

@ -416,7 +416,7 @@ uint16_t ReadDsm2()
#define DSM_CH1_CH2_DELAY 4010 // Time between write of channel 1 and channel 2
#define DSM_WRITE_DELAY 1550 // Time after write to verify write complete
#define DSM_READ_DELAY 600 // Time before write to check read state, and switch channels. Was 400 but 500 seems what the 328p needs to read a packet
uint32_t start;
uint16_t start;
switch(cyrf_state)
{
@ -458,7 +458,7 @@ uint16_t ReadDsm2()
case DSM2_CH1_CHECK_A:
case DSM2_CH1_CHECK_B:
start=micros();
while (micros()-start < 500) // Wait max 500µs
while ((uint16_t)micros()-start < 500) // Wait max 500µs
if(CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x02)
break;
set_sop_data_crc();
@ -467,7 +467,7 @@ uint16_t ReadDsm2()
case DSM2_CH2_CHECK_A:
case DSM2_CH2_CHECK_B:
start=micros();
while (micros()-start < 500) // Wait max 500µs
while ((uint16_t)micros()-start < 500) // Wait max 500µs
if(CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x02)
break;
if (cyrf_state == DSM2_CH2_CHECK_A)
@ -501,7 +501,7 @@ uint16_t ReadDsm2()
//Force end read state
CYRF_WriteRegister(CYRF_0F_XACT_CFG, (CYRF_ReadRegister(CYRF_0F_XACT_CFG) | 0x20)); // Force end state
start=micros();
while (micros()-start < 100) // Wait max 100 µs
while ((uint16_t)micros()-start < 100) // Wait max 100 µs
if((CYRF_ReadRegister(CYRF_0F_XACT_CFG) & 0x20) == 0)
break;
cyrf_state = DSM2_CH2_READ_B;

View File

@ -116,24 +116,28 @@ static void __attribute__((unused)) build_beacon_pkt(uint8_t upper)
add_pkt_suffix();
}
#define FORCE_INDIRECT(ptr) __asm__ __volatile__ ("" : "=e" (ptr) : "0" (ptr))
static void __attribute__((unused)) build_bind_pkt()
{
packet[0] = (DEVO_NUM_CHANNELS << 4) | 0x0a;
packet[1] = bind_counter & 0xff;
packet[2] = (bind_counter >> 8);
packet[3] = *hopping_frequency_ptr;
packet[4] = *(hopping_frequency_ptr + 1);
packet[5] = *(hopping_frequency_ptr + 2);
packet[6] = cyrfmfg_id[0];
packet[7] = cyrfmfg_id[1];
packet[8] = cyrfmfg_id[2];
packet[9] = cyrfmfg_id[3];
uint8_t *p = packet ;
FORCE_INDIRECT(p) ;
p[0] = (DEVO_NUM_CHANNELS << 4) | 0x0a;
p[1] = bind_counter & 0xff;
p[2] = (bind_counter >> 8);
p[3] = *hopping_frequency_ptr;
p[4] = *(hopping_frequency_ptr + 1);
p[5] = *(hopping_frequency_ptr + 2);
p[6] = cyrfmfg_id[0];
p[7] = cyrfmfg_id[1];
p[8] = cyrfmfg_id[2];
p[9] = cyrfmfg_id[3];
add_pkt_suffix();
//The fixed-id portion is scrambled in the bind packet
//I assume it is ignored
packet[13] ^= cyrfmfg_id[0];
packet[14] ^= cyrfmfg_id[1];
packet[15] ^= cyrfmfg_id[2];
p[13] ^= cyrfmfg_id[0];
p[14] ^= cyrfmfg_id[1];
p[15] ^= cyrfmfg_id[2];
}
static void __attribute__((unused)) build_data_pkt()
@ -174,31 +178,57 @@ static void __attribute__((unused)) cyrf_set_bound_sop_code()
CYRF_SetPower(0x08);
}
const uint8_t PROGMEM devo_init_vals[][2] = {
{CYRF_06_RX_CFG, 0x4A },
{CYRF_0B_PWR_CTRL, 0x00 },
{CYRF_0D_IO_CFG, 0x04 },
{CYRF_0E_GPIO_CTRL, 0x20 },
{CYRF_10_FRAMING_CFG, 0xA4 },
{CYRF_11_DATA32_THOLD, 0x05 },
{CYRF_12_DATA64_THOLD, 0x0E },
{CYRF_1B_TX_OFFSET_LSB, 0x55 },
{CYRF_1C_TX_OFFSET_MSB, 0x05 },
{CYRF_32_AUTO_CAL_TIME, 0x3C },
{CYRF_35_AUTOCAL_OFFSET, 0x14 },
{CYRF_39_ANALOG_CTRL, 0x01 },
{CYRF_1E_RX_OVERRIDE, 0x10 },
{CYRF_1F_TX_OVERRIDE, 0x00 },
{CYRF_01_TX_LENGTH, 0x10 },
{CYRF_0C_XTAL_CTRL, 0xC0 },
{CYRF_0F_XACT_CFG, 0x10 },
{CYRF_27_CLK_OVERRIDE, 0x02 },
{CYRF_28_CLK_EN, 0x02 },
{CYRF_0F_XACT_CFG, 0x28 }
};
static void __attribute__((unused)) cyrf_init()
{
/* Initialise CYRF chip */
CYRF_WriteRegister(CYRF_1D_MODE_OVERRIDE, 0x39);
CYRF_SetPower(0x08);
CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4A);
CYRF_WriteRegister(CYRF_0B_PWR_CTRL, 0x00);
CYRF_WriteRegister(CYRF_0D_IO_CFG, 0x04);
CYRF_WriteRegister(CYRF_0E_GPIO_CTRL, 0x20);
CYRF_WriteRegister(CYRF_10_FRAMING_CFG, 0xA4);
CYRF_WriteRegister(CYRF_11_DATA32_THOLD, 0x05);
CYRF_WriteRegister(CYRF_12_DATA64_THOLD, 0x0E);
CYRF_WriteRegister(CYRF_1B_TX_OFFSET_LSB, 0x55);
CYRF_WriteRegister(CYRF_1C_TX_OFFSET_MSB, 0x05);
CYRF_WriteRegister(CYRF_32_AUTO_CAL_TIME, 0x3C);
CYRF_WriteRegister(CYRF_35_AUTOCAL_OFFSET, 0x14);
CYRF_WriteRegister(CYRF_39_ANALOG_CTRL, 0x01);
CYRF_WriteRegister(CYRF_1E_RX_OVERRIDE, 0x10);
CYRF_WriteRegister(CYRF_1F_TX_OVERRIDE, 0x00);
CYRF_WriteRegister(CYRF_01_TX_LENGTH, 0x10);
CYRF_WriteRegister(CYRF_0C_XTAL_CTRL, 0xC0);
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x10);
CYRF_WriteRegister(CYRF_27_CLK_OVERRIDE, 0x02);
CYRF_WriteRegister(CYRF_28_CLK_EN, 0x02);
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x28);
for(uint8_t i = 0; i < sizeof(devo_init_vals) / 2; i++)
CYRF_WriteRegister(pgm_read_byte( &devo_init_vals[i][0]), pgm_read_byte( &devo_init_vals[i][1]) );
// CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4A);
// CYRF_WriteRegister(CYRF_0B_PWR_CTRL, 0x00);
// CYRF_WriteRegister(CYRF_0D_IO_CFG, 0x04);
// CYRF_WriteRegister(CYRF_0E_GPIO_CTRL, 0x20);
// CYRF_WriteRegister(CYRF_10_FRAMING_CFG, 0xA4);
// CYRF_WriteRegister(CYRF_11_DATA32_THOLD, 0x05);
// CYRF_WriteRegister(CYRF_12_DATA64_THOLD, 0x0E);
// CYRF_WriteRegister(CYRF_1B_TX_OFFSET_LSB, 0x55);
// CYRF_WriteRegister(CYRF_1C_TX_OFFSET_MSB, 0x05);
// CYRF_WriteRegister(CYRF_32_AUTO_CAL_TIME, 0x3C);
// CYRF_WriteRegister(CYRF_35_AUTOCAL_OFFSET, 0x14);
// CYRF_WriteRegister(CYRF_39_ANALOG_CTRL, 0x01);
// CYRF_WriteRegister(CYRF_1E_RX_OVERRIDE, 0x10);
// CYRF_WriteRegister(CYRF_1F_TX_OVERRIDE, 0x00);
// CYRF_WriteRegister(CYRF_01_TX_LENGTH, 0x10);
// CYRF_WriteRegister(CYRF_0C_XTAL_CTRL, 0xC0);
// CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x10);
// CYRF_WriteRegister(CYRF_27_CLK_OVERRIDE, 0x02);
// CYRF_WriteRegister(CYRF_28_CLK_EN, 0x02);
// CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x28);
}
static void __attribute__((unused)) set_radio_channels()

View File

@ -54,10 +54,11 @@ uint8_t chanrow;
uint8_t chancol;
uint8_t chanoffset;
const uint8_t PROGMEM V912_X17_SEQ[10] = { 0x14, 0x31, 0x40, 0x49, 0x49, // sometime first byte is 0x15 ?
0x49, 0x49, 0x49, 0x49, 0x49, };
static void __attribute__((unused)) flysky_apply_extension_flags()
{
const uint8_t V912_X17_SEQ[10] = { 0x14, 0x31, 0x40, 0x49, 0x49, // sometime first byte is 0x15 ?
0x49, 0x49, 0x49, 0x49, 0x49, };
static uint8_t seq_counter;
switch(sub_protocol)
{
@ -115,7 +116,7 @@ static void __attribute__((unused)) flysky_apply_extension_flags()
packet[14] |= FLAG_V912_TOPBTN;
packet[15] = 0x27; // [15] and [16] apparently hold an analog channel with a value lower than 1000
packet[16] = 0x03; // maybe it's there for a pitch channel for a CP copter ?
packet[17] = V912_X17_SEQ[seq_counter]; // not sure what [17] & [18] are for
packet[17] = pgm_read_byte( &V912_X17_SEQ[seq_counter] ) ; // not sure what [17] & [18] are for
if(seq_counter == 0) // V912 Rx does not even read those bytes... [17-20]
packet[18] = 0x02;
else

View File

@ -89,6 +89,7 @@ static void __attribute__((unused)) frskyX_init()
}
CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x04);
prev_option = option ;
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
CC2500_Strobe(CC2500_SIDLE);
//
@ -124,9 +125,12 @@ static void __attribute__((unused)) initialize_data(uint8_t adr)
const uint16_t PROGMEM CRC_Short[]={
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7 };
static uint16_t __attribute__((unused)) CRCTable(uint8_t val)
static uint16_t CRCTable(uint8_t val)
{
return pgm_read_word(&CRC_Short[val&0x0F]) ^ (0x1081 * (val>>4));
uint16_t word ;
word = pgm_read_word(&CRC_Short[val&0x0F]) ;
val /= 16 ;
return word ^ (0x1081 * val) ;
}
static uint16_t __attribute__((unused)) crc_x(uint8_t *data, uint8_t len)
{
@ -253,6 +257,11 @@ uint16_t ReadFrSkyX()
state++;
break;
case FRSKY_DATA1:
if ( prev_option != option )
{
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack
prev_option = option ;
}
LED_ON;
CC2500_SetTxRxMode(TX_EN);
set_start(channr);

View File

@ -439,6 +439,10 @@ enum {
PKT_TIMEOUT
};
// baudrate defines for serial
#define SPEED_100K 0
#define SPEED_9600 1
//****************************************
//*** MULTI protocol serial definition ***
//****************************************

View File

@ -36,6 +36,8 @@ uint32_t Model_fixed_id=0;
uint32_t fixed_id;
uint8_t cyrfmfg_id[6];//for dsm2 and devo
uint32_t blink=0;
uint8_t prev_option;
uint8_t prev_power=0xFD; // unused power value
//
uint16_t counter;
uint8_t channel;
@ -85,11 +87,19 @@ uint8_t protocol_flags=0,protocol_flags2=0;
volatile uint16_t PPM_data[NUM_CHN];
// Serial variables
#ifdef INVERT_TELEMETRY
// enable bit bash for serial
#define BASH_SERIAL 1
#define INVERT_SERIAL 1
#endif
#define BAUD 100000
#define RXBUFFER_SIZE 25
#define TXBUFFER_SIZE 20
#define TXBUFFER_SIZE 32
volatile uint8_t rx_buff[RXBUFFER_SIZE];
volatile uint8_t rx_ok_buff[RXBUFFER_SIZE];
#ifndef BASH_SERIAL
volatile uint8_t tx_buff[TXBUFFER_SIZE];
#endif
volatile uint8_t idx = 0;
//Serial protocol
@ -112,8 +122,10 @@ uint8_t pkt[MAX_PKT];//telemetry receiving packets
#define HUB_TELEMETRY
#endif
uint8_t pktt[MAX_PKT];//telemetry receiving packets
#ifndef BASH_SERIAL
volatile uint8_t tx_head=0;
volatile uint8_t tx_tail=0;
#endif // BASH_SERIAL
uint8_t v_lipo;
int16_t RSSI_dBm;
//const uint8_t RSSI_offset=72;//69 71.72 values db
@ -283,9 +295,11 @@ void loop()
{
for(uint8_t i=0;i<NUM_CHN;i++)
{ // update servo data without interrupts to prevent bad read in protocols
uint16_t temp_ppm ;
cli(); // disable global int
Servo_data[i]=PPM_data[i];
temp_ppm = PPM_data[i] ;
sei(); // enable global int
Servo_data[i]= temp_ppm ;
}
update_aux_flags();
PPM_FLAG_off; // wait for next frame before update
@ -348,8 +362,10 @@ static void CheckTimer(uint16_t (*cb)(void))
#else
if( (TIFR1 & (1<<OCF1A)) != 0)
{
uint16_t temp ;
temp = TCNT1 ;
cli(); // disable global int
OCR1A=TCNT1; // Callback should already have been called... Use "now" as new sync point.
OCR1A=temp; // Callback should already have been called... Use "now" as new sync point.
sei(); // enable global int
}
else
@ -361,28 +377,34 @@ static void CheckTimer(uint16_t (*cb)(void))
while(next_callback>4000)
{ // start to wait here as much as we can...
next_callback=next_callback-2000;
cli(); // disable global int
#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
OCR1A+=2000*2; // set compare A for callback
uint16_t temp ;
temp = OCR1A + 2000*2 ;
cli(); // disable global int
OCR1A = temp ; // set compare A for callback
TIFR1=(1<<OCF1A); // clear compare A=callback flag
sei(); // enable global int
while((TIFR1 & (1<<OCF1A)) == 0); // wait 2ms...
#endif
}
// at this point we have between 2ms and 4ms in next_callback
cli(); // disable global int
#ifdef XMEGA
cli(); // disable global int
TCC1.CCA +=next_callback*2; // set compare A for callback
TCC1.INTFLAGS = TC1_CCAIF_bm ; // clear compare A=callback flag
diff=TCC1.CCA-TCC1.CNT; // compare timer and comparator
sei(); // enable global int
#else
OCR1A+=next_callback*2; // set compare A for callback
next_callback *= 2 ;
next_callback += OCR1A ;
cli(); // disable global int
OCR1A = next_callback ; // set compare A for callback
TIFR1=(1<<OCF1A); // clear compare A=callback flag
diff=OCR1A-TCNT1; // compare timer and comparator
sei(); // enable global int
@ -657,6 +679,7 @@ static void module_reset()
break;
}
}
prev_power=0xFD; // unused power value
}
int16_t map( int16_t x, int16_t in_min, int16_t in_max, int16_t out_min, int16_t out_max)
@ -721,22 +744,6 @@ uint16_t limit_channel_100(uint8_t ch)
return Servo_data[ch];
}
#if defined(TELEMETRY)
void Serial_write(uint8_t data)
{
cli(); // disable global int
if(++tx_head>=TXBUFFER_SIZE)
tx_head=0;
tx_buff[tx_head]=data;
#ifdef XMEGA
USARTC0.CTRLA = (USARTC0.CTRLA & 0xFC) | 0x01 ;
#else
UCSR0B |= (1<<UDRIE0);//enable UDRE interrupt
#endif
sei(); // enable global int
}
#endif
static void Mprotocol_serial_init()
{
#ifdef XMEGA
@ -766,7 +773,7 @@ static void Mprotocol_serial_init()
#ifdef DEBUG_TX
TX_SET_OUTPUT;
#else
UCSR0B |= (1<<TXEN0);//tx enable
initTXSerial( SPEED_100K ) ;
#endif
#endif
}
@ -774,22 +781,7 @@ static void Mprotocol_serial_init()
#if defined(TELEMETRY)
static void PPM_Telemetry_serial_init()
{
#ifdef XMEGA
USARTC0.BAUDCTRLA = 207 ;
USARTC0.BAUDCTRLB = 0 ;
USARTC0.CTRLB = 0x18 ;
USARTC0.CTRLA = (USARTC0.CTRLA & 0xCF) | 0x10 ;
USARTC0.CTRLC = 0x03 ;
#else
//9600 bauds
UBRR0H = 0x00;
UBRR0L = 0x67;
UCSR0A = 0 ; // Clear X2 bit
//Set frame format to 8 data bits, none, 1 stop bit
UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
UCSR0B = (1<<TXEN0);//tx enable
#endif
initTXSerial( SPEED_9600 ) ;
}
#endif
@ -998,7 +990,7 @@ void init()
#ifdef XMEGA
ISR(PORTD_INT0_vect)
#else
ISR(INT1_vect)
ISR(INT1_vect, ISR_NOBLOCK)
#endif
{ // Interrupt on PPM pin
static int8_t chan=-1;
@ -1021,10 +1013,10 @@ ISR(INT1_vect)
else
if(chan!=-1) // need to wait for start of frame
{ //servo values between 500us and 2420us will end up here
uint16_t a = Cur_TCNT1>>1;
if(a<PPM_MIN) a=PPM_MIN;
else if(a>PPM_MAX) a=PPM_MAX;
PPM_data[chan]=a;
uint16_t temp = Cur_TCNT1>>1;
if(temp<PPM_MIN) temp=PPM_MIN;
else if(temp>PPM_MAX) temp=PPM_MAX;
PPM_data[chan]=temp;
if(chan++>=NUM_CHN)
chan=-1; // don't accept any new channels
}
@ -1041,6 +1033,10 @@ ISR(USART_RX_vect)
#ifdef XMEGA
if((USARTC0.STATUS & 0x1C)==0) // Check frame error, data overrun and parity error
#else
UCSR0B &= ~(1<<RXCIE0) ; //rx interrupt disable
sei() ;
if((UCSR0A&0x1C)==0) // Check frame error, data overrun and parity error
#endif
{ // received byte is ok to process
@ -1080,8 +1076,9 @@ ISR(USART_RX_vect)
#endif
if(!IS_RX_FLAG_on)
{ //Good frame received and main has finished with previous buffer
for(idx=0;idx<RXBUFFER_SIZE;idx++)
rx_ok_buff[idx]=rx_buff[idx]; // Duplicate the buffer
uint8_t i ;
for(i=0;i<RXBUFFER_SIZE;i++)
rx_ok_buff[i]=rx_buff[i]; // Duplicate the buffer
RX_FLAG_on; // flag for main to process servo data
}
idx=0; // start again
@ -1097,42 +1094,21 @@ ISR(USART_RX_vect)
#endif
idx=0; // Error encountered discard full frame...
}
#ifndef XMEGA
cli() ;
UCSR0B |= (1<<RXCIE0) ;//rx enable interrupt
#endif
}
//Serial timer
#ifdef XMEGA
ISR(TCC1_CCB_vect)
#else
ISR(TIMER1_COMPB_vect)
//ISR(TIMER1_COMPB_vect)
ISR(TIMER1_COMPB_vect, ISR_NOBLOCK )
#endif
{ // Timer1 compare B interrupt
idx=0;
}
#if defined(TELEMETRY)
//Serial TX
#ifdef XMEGA
ISR(USARTC0_DRE_vect)
#else
ISR(USART_UDRE_vect)
#endif
{ // Transmit interrupt
if(tx_head!=tx_tail)
{
if(++tx_tail>=TXBUFFER_SIZE)//head
tx_tail=0;
#ifdef XMEGA
USARTC0.DATA = tx_buff[tx_tail] ;
#else
UDR0=tx_buff[tx_tail];
#endif
}
if (tx_tail == tx_head)
#ifdef XMEGA
USARTC0.CTRLA &= ~0x03 ;
#else
UCSR0B &= ~(1<<UDRIE0); // Check if all data is transmitted . if yes disable transmitter UDRE interrupt
#endif
}
#endif

View File

@ -150,7 +150,11 @@ void NRF24L01_SetPower()
if(IS_RANGE_FLAG_on)
power=NRF_POWER_0;
rf_setup = (rf_setup & 0xF9) | (power << 1);
NRF24L01_WriteReg(NRF24L01_06_RF_SETUP, rf_setup);
if(prev_power != power)
{
NRF24L01_WriteReg(NRF24L01_06_RF_SETUP, rf_setup);
prev_power=power;
}
}
void NRF24L01_SetTxRxMode(enum TXRX_State mode)

View File

@ -73,6 +73,22 @@ const PROGMEM uint8_t SFHSS_init_values[] = {
/* 20 */ 0xF8, 0xB6, 0x10, 0xEA, 0x0A, 0x11, 0x11
};
static void __attribute__((unused)) SFHSS_rf_init()
{
CC2500_Reset();
CC2500_Strobe(CC2500_SIDLE);
//CC2500_WriteRegisterMulti(CC2500_00_IOCFG2, init_values, sizeof(init_values));
for (uint8_t i = 0; i < 39; ++i)
CC2500_WriteReg(i, pgm_read_byte_near(&SFHSS_init_values[i]));
prev_option = option+1;
//CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
CC2500_SetTxRxMode(TX_EN);
CC2500_SetPower();
}
static void __attribute__((unused)) SFHSS_tune_chan()
{
CC2500_Strobe(CC2500_SIDLE);
@ -93,25 +109,15 @@ static void __attribute__((unused)) SFHSS_tune_freq() {
// May be we'll need this tuning routine - some receivers are more sensitive to
// frequency impreciseness, and though CC2500 has a procedure to handle it it
// may not be applied in receivers, so we need to compensate for it on TX
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
CC2500_WriteReg(CC2500_0F_FREQ0, SFHSS_FREQ0_VAL + SFHSS_COARSE);
if ( prev_option != option )
{
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
CC2500_WriteReg(CC2500_0F_FREQ0, SFHSS_FREQ0_VAL + SFHSS_COARSE);
prev_option = option ;
}
}
#endif
static void __attribute__((unused)) SFHSS_rf_init()
{
CC2500_Reset();
CC2500_Strobe(CC2500_SIDLE);
for (uint8_t i = 0; i < 39; ++i)
CC2500_WriteReg(i, pgm_read_byte_near(&SFHSS_init_values[i]));
//CC2500_WriteRegisterMulti(CC2500_00_IOCFG2, init_values, sizeof(init_values));
//CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
CC2500_SetTxRxMode(TX_EN);
CC2500_SetPower();
}
static void __attribute__((unused)) SFHSS_calc_next_chan()
{
rf_ch_num += fhss_code + 2;
@ -129,7 +135,6 @@ static uint16_t __attribute__((unused)) SFHSS_convert_channel(uint8_t num)
return (uint16_t) (map(limit_channel_100(num),PPM_MIN_100,PPM_MAX_100,86,906));
}
static void __attribute__((unused)) SFHSS_build_data_packet()
{
#define spacer1 0x02 //0b10

View File

@ -292,7 +292,7 @@ static void __attribute__((unused)) symax_set_channels(uint8_t address)
static void __attribute__((unused)) symax_init2()
{
uint8_t chans_data_x5c[] = {0x1d, 0x2f, 0x26, 0x3d, 0x15, 0x2b, 0x25, 0x24,
static uint8_t chans_data_x5c[] = {0x1d, 0x2f, 0x26, 0x3d, 0x15, 0x2b, 0x25, 0x24,
0x27, 0x2c, 0x1c, 0x3e, 0x39, 0x2d, 0x22};
if (sub_protocol==SYMAX5C)

View File

@ -24,10 +24,24 @@
#define STUFF_MASK 0x20
#define MAX_PKTX 10
uint8_t pktx[MAX_PKTX];
uint8_t pktx1[MAX_PKTX];
uint8_t index;
uint8_t pass = 0;
uint8_t frame[18];
#ifdef BASH_SERIAL
// For bit-bashed serial output
struct t_serial_bash
{
uint8_t head ;
uint8_t tail ;
uint8_t data[64] ;
uint8_t busy ;
uint8_t speed ;
} SerialControl ;
#endif
#if defined DSM_TELEMETRY
void DSM2_frame()
{
@ -131,18 +145,18 @@ void frsky_user_frame()
indexx=pktt[6];
for(i=0;i<indexx;i++)
{
if(pktt[j]==0x5E)
{
if(c++)
{
c=0;
n++;
j++;
}
}
// if(pktt[j]==0x5E)
// {
// if(c++)
// {
// c=0;
// n++;
// j++;
// }
// }
pktx[i]=pktt[j++];
}
indexx = indexx-n;
// indexx = indexx-n;
pass=1;
case 1:
@ -166,7 +180,7 @@ void frsky_user_frame()
case 2:
index = prev_index - index;
prev_index=0;
if(index<(MAX_PKTX-USER_MAX_BYTES)) //10-6=4
if(index<=(MAX_PKTX-USER_MAX_BYTES)) //10-6=4
for(i=0;i<index;i++)
frame[i+3]=pktx[USER_MAX_BYTES+i];
pass=0;
@ -253,7 +267,8 @@ void sportSend(uint8_t *p)
{
uint16_t crc_s = 0;
Serial_write(START_STOP);//+9
for (uint8_t i = 0; i < 9; i++)
Serial_write(p[0]) ;
for (uint8_t i = 1; i < 9; i++)
{
if (i == 8)
p[i] = 0xff - crc_s;
@ -285,7 +300,7 @@ void sportSendFrame()
uint8_t i;
sport_counter = (sport_counter + 1) %36;
if(sport_counter<3)
if(sport_counter<6)
{
frame[0] = 0x98;
frame[1] = 0x10;
@ -297,16 +312,16 @@ void sportSendFrame()
case 0:
frame[2] = 0x05;
frame[3] = 0xf1;
frame[4] = 0x20;//dummy values if swr 20230f00
frame[4] = 0x02 ;//dummy values if swr 20230f00
frame[5] = 0x23;
frame[6] = 0x0F;
break;
case 1: // RSSI
case 2: // RSSI
frame[2] = 0x01;
frame[3] = 0xf1;
frame[4] = rssi;
break;
case 2: //BATT
case 4: //BATT
frame[2] = 0x04;
frame[3] = 0xf1;
frame[4] = RxBt;//a1;
@ -315,7 +330,7 @@ void sportSendFrame()
if(sport)
{
for (i=0;i<FRSKY_SPORT_PACKET_SIZE;i++)
frame[i]=pktx[i];
frame[i]=pktx1[i];
sport=0;
break;
}
@ -340,6 +355,12 @@ void proces_sport_data(uint8_t data)
}
break;
case 1:
if (data == START_STOP) // Happens if missed packet
{//waiting for 0x7e
index = 0;
pass = 1;
break;
}
if(data == BYTESTUFF)//if they are stuffed
pass=2;
else
@ -354,7 +375,19 @@ void proces_sport_data(uint8_t data)
} // end switch
if (index >= FRSKY_SPORT_PACKET_SIZE)
{//8 bytes no crc
sport = 1;//ok to send
if ( sport )
{
// overrun!
}
else
{
uint8_t i ;
for ( i = 0 ; i < FRSKY_SPORT_PACKET_SIZE ; i += 1 )
{
pktx1[i] = pktx[i] ; // Double buffer
}
sport = 1;//ok to send
}
pass = 0;//reset
}
}
@ -362,7 +395,62 @@ void proces_sport_data(uint8_t data)
#endif
void frskyUpdate()
{
{
#if defined SPORT_TELEMETRY
if ((cur_protocol[0]&0x1F)==MODE_FRSKYX)
{ // FrSkyX
if(telemetry_link)
{
if(pktt[4] & 0x80)
rssi=pktt[4] & 0x7F ;
else
RxBt = (pktt[4]<<1) + 1 ;
for (uint8_t i=0; i < pktt[6]; i++)
proces_sport_data(pktt[7+i]);
telemetry_link=0;
}
}
#endif
// check for space in tx buffer
#ifdef BASH_SERIAL
uint8_t h ;
uint8_t t ;
h = SerialControl.head ;
t = SerialControl.tail ;
if ( h >= t )
{
t += 64 - h ;
}
else
{
t -= h ;
}
if ( t < 32 )
{
return ;
}
#else
uint8_t h ;
uint8_t t ;
h = tx_head ;
t = tx_tail ;
if ( h >= t )
{
t += TXBUFFER_SIZE - h ;
}
else
{
t -= h ;
}
if ( t < 16 )
{
return ;
}
#endif
#if defined DSM_TELEMETRY
if(telemetry_link && (cur_protocol[0]&0x1F) == MODE_DSM2 )
{ // DSM2
@ -387,24 +475,318 @@ void frskyUpdate()
#if defined SPORT_TELEMETRY
if ((cur_protocol[0]&0x1F)==MODE_FRSKYX)
{ // FrSkyX
if(telemetry_link)
{
if(pktt[4]>0x36)
rssi=pktt[4]>>1;
else
RxBt=pktt[4];
for (uint8_t i=0; i < pktt[6]; i++)
proces_sport_data(pktt[7+i]);
telemetry_link=0;
}
uint32_t now = micros();
if ((now - last) > SPORT_TIME)
{
sportSendFrame();
last = now;
last += SPORT_TIME ;
}
}
#endif
}
#endif
/**************************/
/**************************/
/** Serial TX routines **/
/**************************/
/**************************/
#ifndef BASH_SERIAL
// Routines for normal serial output
void Serial_write(uint8_t data)
{
cli(); // disable global int
if(++tx_head>=TXBUFFER_SIZE)
tx_head=0;
tx_buff[tx_head]=data;
#ifdef XMEGA
USARTC0.CTRLA = (USARTC0.CTRLA & 0xFC) | 0x01 ;
#else
UCSR0B |= (1<<UDRIE0);//enable UDRE interrupt
#endif
sei(); // enable global int
}
// Speed is 0 for 100K and 1 for 9600
void initTXSerial( uint8_t speed)
{
if(speed==SPEED_9600)
{ // 9600
#ifdef XMEGA
USARTC0.BAUDCTRLA = 207 ;
USARTC0.BAUDCTRLB = 0 ;
USARTC0.CTRLB = 0x18 ;
USARTC0.CTRLA = (USARTC0.CTRLA & 0xCF) | 0x10 ;
USARTC0.CTRLC = 0x03 ;
#else
//9600 bauds
UBRR0H = 0x00;
UBRR0L = 0x67;
UCSR0A = 0 ; // Clear X2 bit
//Set frame format to 8 data bits, none, 1 stop bit
UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
UCSR0B = (1<<TXEN0);//tx enable
#endif
}
else
UCSR0B |= (1<<TXEN0);//tx enable
}
#ifdef XMEGA
ISR(USARTC0_DRE_vect)
#else
ISR(USART_UDRE_vect)
#endif
{ // Transmit interrupt
if(tx_head!=tx_tail)
{
if(++tx_tail>=TXBUFFER_SIZE)//head
tx_tail=0;
#ifdef XMEGA
USARTC0.DATA = tx_buff[tx_tail] ;
#else
UDR0=tx_buff[tx_tail];
#endif
}
if (tx_tail == tx_head)
#ifdef XMEGA
USARTC0.CTRLA &= ~0x03 ;
#else
UCSR0B &= ~(1<<UDRIE0); // Check if all data is transmitted . if yes disable transmitter UDRE interrupt
#endif
}
#else //BASH_SERIAL
// Routines for bit-bashed serial output
// Speed is 0 for 100K and 1 for 9600
void initTXSerial( uint8_t speed)
{
TIMSK0 = 0 ; // Stop all timer 0 interrupts
#ifdef INVERT_SERIAL
PORTD &= ~2 ;
#else
PORTD |= 2 ;
#endif
DDRD |= 2 ; // TxD pin is an output
UCSR0B &= ~(1<<TXEN0) ;
SerialControl.speed = speed ;
if ( speed == SPEED_9600 )
{
OCR0A = 207 ; // 104uS period
TCCR0A = 3 ;
TCCR0B = 0x0A ; // Fast PMM, 2MHz
}
else // 100K
{
TCCR0A = 0 ;
TCCR0B = 2 ; // Clock/8 (0.5uS)
}
}
void Serial_write( uint8_t byte )
{
uint8_t temp ;
uint8_t temp1 ;
uint8_t byteLo ;
#ifdef INVERT_SERIAL
byte = ~byte ;
#endif
byteLo = byte ;
byteLo >>= 7 ; // Top bit
if ( SerialControl.speed == SPEED_100K )
{
#ifdef INVERT_SERIAL
byteLo |= 0x02 ; // Parity bit
#else
byteLo |= 0xFC ; // Stop bits
#endif
// calc parity
temp = byte ;
temp >>= 4 ;
temp = byte ^ temp ;
temp1 = temp ;
temp1 >>= 2 ;
temp = temp ^ temp1 ;
temp1 = temp ;
temp1 <<= 1 ;
temp ^= temp1 ;
temp &= 0x02 ;
#ifdef INVERT_SERIAL
byteLo ^= temp ;
#else
byteLo |= temp ;
#endif
}
else
{
byteLo |= 0xFE ; // Stop bit
}
byte <<= 1 ;
#ifdef INVERT_SERIAL
byte |= 1 ; // Start bit
#endif
uint8_t next = (SerialControl.head + 2) & 0x3f ;
if ( next != SerialControl.tail )
{
SerialControl.data[SerialControl.head] = byte ;
SerialControl.data[SerialControl.head+1] = byteLo ;
SerialControl.head = next ;
}
cli() ;
if ( SerialControl.busy == 0 )
{
sei() ;
// Start the transmission here
#ifdef INVERT_SERIAL
GPIOR2 = 0 ;
#else
GPIOR2 = 0x01 ;
#endif
if ( SerialControl.speed == SPEED_100K )
{
GPIOR1 = 1 ;
OCR0B = TCNT0 + 40 ;
OCR0A = OCR0B + 210 ;
TIFR0 = (1<<OCF0A) | (1<<OCF0B) ;
TIMSK0 |= (1<<OCIE0B) ;
SerialControl.busy = 1 ;
}
else
{
GPIOR1 = 1 ;
TIFR0 = (1<<TOV0) ;
TIMSK0 |= (1<<TOIE0) ;
SerialControl.busy = 1 ;
}
}
else
{
sei() ;
}
}
// Assume timer0 at 0.5uS clock
ISR(TIMER0_COMPA_vect)
{
uint8_t byte ;
byte = GPIOR0 ;
if ( byte & 0x01 )
{
PORTD |= 0x02 ;
}
else
{
PORTD &= ~0x02 ;
}
byte /= 2 ; // Generates shorter code than byte >>= 1
GPIOR0 = byte ;
if ( --GPIOR1 == 0 )
{
TIMSK0 &= ~(1<<OCIE0A) ;
GPIOR1 = 3 ;
}
else
{
OCR0A += 20 ;
}
}
ISR(TIMER0_COMPB_vect)
{
uint8_t byte ;
byte = GPIOR2 ;
if ( byte & 0x01 )
{
PORTD |= 0x02 ;
}
else
{
PORTD &= ~0x02 ;
}
byte /= 2 ; // Generates shorter code than byte >>= 1
GPIOR2 = byte ;
if ( --GPIOR1 == 0 )
{
// prepare next byte and allow for 2 stop bits
struct t_serial_bash *ptr = &SerialControl ;
if ( ptr->head != ptr->tail )
{
GPIOR0 = ptr->data[ptr->tail] ;
GPIOR2 = ptr->data[ptr->tail+1] ;
ptr->tail = ( ptr->tail + 2 ) & 0x3F ;
GPIOR1 = 8 ;
OCR0A = OCR0B + 40 ;
OCR0B = OCR0A + 8 * 20 ;
TIMSK0 |= (1<<OCIE0A) ;
}
else
{
SerialControl.busy = 0 ;
TIMSK0 &= ~(1<<OCIE0B) ;
}
}
else
{
OCR0B += 20 ;
}
}
ISR(TIMER0_OVF_vect)
{
uint8_t byte ;
if ( GPIOR1 > 2 )
{
byte = GPIOR0 ;
}
else
{
byte = GPIOR2 ;
}
if ( byte & 0x01 )
{
PORTD |= 0x02 ;
}
else
{
PORTD &= ~0x02 ;
}
byte /= 2 ; // Generates shorter code than byte >>= 1
if ( GPIOR1 > 2 )
{
GPIOR0 = byte ;
}
else
{
GPIOR2 = byte ;
}
if ( --GPIOR1 == 0 )
{
// prepare next byte
struct t_serial_bash *ptr = &SerialControl ;
if ( ptr->head != ptr->tail )
{
GPIOR0 = ptr->data[ptr->tail] ;
GPIOR2 = ptr->data[ptr->tail+1] ;
ptr->tail = ( ptr->tail + 2 ) & 0x3F ;
GPIOR1 = 10 ;
}
else
{
SerialControl.busy = 0 ;
TIMSK0 &= ~(1<<TOIE0) ;
}
}
}
#endif // BASH_SERIAL
#endif // TELEMETRY

View File

@ -15,6 +15,9 @@
/** Multiprotocol module configuration file ***/
/*******************/
/*** TX SETTINGS ***/
/*******************/
//Uncomment your TX type
#define TX_ER9X_AETR //ER9X AETR (988<->2012µs)
//#define TX_ER9X_TAER //ER9X TAER (988<->2012µs)
@ -22,6 +25,9 @@
//#define TX_SPEKTRUM //Spektrum TAER (1100<->1900µs)
//#define TX_HISKY //HISKY AETR (1100<->1900µs)
/****************************/
/*** PROTOCOLS TO INCLUDE ***/
/****************************/
//Comment if a module is not installed
#define A7105_INSTALLED
#define CYRF6936_INSTALLED
@ -61,9 +67,15 @@
#define FQ777_NRF24L01_INO
#endif
/**************************/
/*** TELEMETRY SETTINGS ***/
/**************************/
//Uncomment to enable telemetry
#define TELEMETRY
//Uncomment to invert the telemetry serial signal, this is usefull for OpenTX on Taranis as an example
//#define INVERT_TELEMETRY 1
//Comment to disable a specific telemetry
#if defined(TELEMETRY)
#if defined DSM2_CYRF6936_INO
@ -77,6 +89,9 @@
#endif
#endif
/********************/
/*** PPM SETTINGS ***/
/********************/
//Update this table to set which protocol and all associated settings are called for the corresponding dial number
const PPM_Parameters PPM_prot[15]= {
// Dial Protocol Sub protocol RX_Num Power Auto Bind Option
@ -180,9 +195,9 @@ Auto Bind AUTOBIND or NO_AUTOBIND
Option value between 0 and 255. 0xD7 or 0x00 for Frsky fine tuning.
*/
//******************
//TX definitions with timing endpoints and channels order
/*******************/
/*** TX SETTINGS ***/
/*******************/
// Turnigy PPM and channels
#if defined(TX_ER9X_AETR)
#define PPM_MAX 2140 // 125%
@ -301,7 +316,3 @@ enum chan_order{
#define PPM_MIN_COMMAND 1250
#define PPM_SWITCH 1550
#define PPM_MAX_COMMAND 1750
//Uncoment the desired serial speed
#define BAUD 100000
//#define BAUD 125000