Fix (?) protocol issues

This commit is contained in:
pascallanger 2019-10-31 23:33:10 +01:00
parent d29461607b
commit 9b499ab7d1
6 changed files with 105 additions and 105 deletions

View File

@ -48,7 +48,6 @@ enum {
FRSKY_DATA3,
FRSKY_DATA4,
FRSKY_DATA5,
FRSKY_DATA6
};
void Frsky_init_hop(void)

View File

@ -277,6 +277,9 @@ static void __attribute__((unused)) FrSkyX_build_packet()
uint16_t ReadFrSkyX()
{
static bool transmit=true;
#ifdef DEBUG_SERIAL
static uint16_t fr_time=0;
#endif
switch(state)
{
@ -298,8 +301,8 @@ uint16_t ReadFrSkyX()
hopping_frequency_no=0;
BIND_DONE;
state++; //FRSKY_DATA1
break;
case FRSKY_DATA6:
break;
case FRSKY_DATA5:
telemetry_set_input_sync(9000);
len = CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
if (len && (len<=(0x0E + 3))) //Telemetry frame is 17
@ -309,7 +312,7 @@ uint16_t ReadFrSkyX()
#if defined TELEMETRY
frsky_check_telemetry(packet_in,len); //Check and parse telemetry packets
#endif
}
}
else
{
packet_count++;
@ -344,36 +347,43 @@ uint16_t ReadFrSkyX()
transmit=true;
#ifdef FRSKYX_LBT
CC2500_Strobe(CC2500_SIDLE);
state++;
return 100; //Wait for the freq to stabilize
case FRSKY_DATA2:
delayMicroseconds(90); //Wait for the freq to stabilize
CC2500_Strobe(CC2500_SRX); //Acquire RSSI
state++;
return 400;
case FRSKY_DATA3:
return 500;
case FRSKY_DATA2:
uint8_t rssi;
rssi = CC2500_ReadReg(CC2500_34_RSSI | CC2500_READ_BURST); // 0.5 db/count, RSSI value read from the RSSI status register is a 2's complement number
if ((sub_protocol & 2) && rssi < 128) //LBT and RSSI between -73 to -8.5 dBm (-36dBm=72)
if ((sub_protocol & 2) && rssi > 72 && rssi < 128) //LBT and RSSI between -36 and -8.5 dBm
{
transmit=false;
debugln("Busy %d %d",hopping_frequency_no,rssi);
}
#endif
CC2500_Strobe(CC2500_SIDLE);
CC2500_Strobe(CC2500_SFRX);
CC2500_SetTxRxMode(TX_EN);
CC2500_SetPower();
CC2500_Strobe(CC2500_SFRX);
hopping_frequency_no = (hopping_frequency_no+FrSkyX_chanskip)%47;
CC2500_Strobe(CC2500_SIDLE);
if(transmit)
{
#ifdef DEBUG_SERIAL
uint16_t fr_cur=millis();
fr_time=fr_cur-fr_time;
if(fr_time!=9)
debugln("Bad timing: %d",fr_time);
fr_time=fr_cur;
#endif
CC2500_WriteData(packet, packet[0]+1);
state=FRSKY_DATA4;
}
state=FRSKY_DATA3;
return 5200;
case FRSKY_DATA4:
case FRSKY_DATA3:
CC2500_SetTxRxMode(RX_EN);
CC2500_Strobe(CC2500_SIDLE);
state++;
return 200;
case FRSKY_DATA5:
case FRSKY_DATA4:
CC2500_Strobe(CC2500_SRX);
state++;
return 3100;

View File

@ -19,7 +19,7 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_REVISION 0
#define VERSION_PATCH_LEVEL 26
#define VERSION_PATCH_LEVEL 27
//******************
// Protocols

View File

@ -165,7 +165,7 @@ uint8_t RX_num;
#define RXBUFFER_SIZE 36 // 26+1+9
volatile uint8_t rx_buff[RXBUFFER_SIZE];
volatile uint8_t rx_ok_buff[RXBUFFER_SIZE];
volatile uint8_t discard_frame = 0;
volatile bool discard_frame = false;
volatile uint8_t rx_idx=0, rx_len=0;
@ -555,88 +555,76 @@ void setup()
// Protocol scheduler
void loop()
{
uint16_t next_callback,diff=0xFFFF;
uint16_t next_callback, diff;
uint8_t count=0;
while(1)
{
if(remote_callback==0 || IS_WAIT_BIND_on || diff>2*200)
{
do
while(remote_callback==0 || IS_WAIT_BIND_on || IS_INPUT_SIGNAL_off)
if(!Update_All())
{
Update_All();
}
while(remote_callback==0 || IS_WAIT_BIND_on);
}
#ifndef STM32_BOARD
if( (TIFR1 & OCF1A_bm) != 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 & OCF1A_bm) == 0); // Wait before callback
#else
if((TIMER2_BASE->SR & TIMER_SR_CC1IF)!=0)
{
debugln("Callback miss");
cli();
OCR1A = TCNT1;
sei();
}
else
while((TIMER2_BASE->SR & TIMER_SR_CC1IF )==0); // Wait before callback
#endif
do
{
TX_MAIN_PAUSE_on;
tx_pause();
if(IS_INPUT_SIGNAL_on && remote_callback!=0)
next_callback=remote_callback();
else
next_callback=2000; // No PPM/serial signal check again in 2ms...
TX_MAIN_PAUSE_off;
tx_resume();
while(next_callback>1000)
{ // start to wait here as much as we can...
next_callback-=500; // We will wait below for 0.5ms
cli(); // Disable global int due to RW of 16 bits registers
OCR1A += 500*2 ; // set compare A for callback
#ifndef STM32_BOARD
TIFR1=OCF1A_bm; // clear compare A=callback flag
#else
TIMER2_BASE->SR = 0x1E5F & ~TIMER_SR_CC1IF; // Clear Timer2/Comp1 interrupt flag
#endif
sei(); // enable global int
if(Update_All()) // Protocol changed?
{
next_callback=0; // Launch new protocol ASAP
break;
}
#ifndef STM32_BOARD
while((TIFR1 & OCF1A_bm) == 0); // wait 0.5ms...
#else
while((TIMER2_BASE->SR & TIMER_SR_CC1IF)==0);//wait 0.5ms...
#endif
OCR1A=TCNT1; // Callback should already have been called... Use "now" as new sync point.
sei(); // Enable global int
}
// at this point we have a maximum of 1ms in next_callback
next_callback *= 2 ;
TX_MAIN_PAUSE_on;
tx_pause();
next_callback=remote_callback()<<1;
TX_MAIN_PAUSE_off;
tx_resume();
cli(); // Disable global int due to RW of 16 bits registers
OCR1A+=next_callback; // Calc when next_callback should happen
#ifndef STM32_BOARD
TIFR1=OCF1A_bm; // Clear compare A=callback flag
#else
TIMER2_BASE->SR = 0x1E5F & ~TIMER_SR_CC1IF; // Clear Timer2/Comp1 interrupt flag
#endif
diff=OCR1A-TCNT1; // Calc the time difference
sei(); // Enable global int
if((diff&0x8000) && !(next_callback&0x8000))
{ // Negative result=callback should already have been called...
cli(); // Disable global int due to RW of 16 bits registers
OCR1A+= next_callback ; // set compare A for callback
#ifndef STM32_BOARD
TIFR1=OCF1A_bm; // clear compare A=callback flag
#else
TIMER2_BASE->SR = 0x1E5F & ~TIMER_SR_CC1IF; // Clear Timer2/Comp1 interrupt flag
#endif
diff=OCR1A-TCNT1; // compare timer and comparator
sei(); // enable global int
OCR1A=TCNT1; // Use "now" as new sync point.
sei(); // Enable global int
debugln("Short CB:%d",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
else
{
if(IS_RX_FLAG_on || IS_PPM_FLAG_on)
{ // Serial or PPM is waiting...
if(++count>10)
{ //The protocol does not leave engough time for an update so forcing it
count=0;
debugln("Force update");
Update_All();
}
}
#ifndef STM32_BOARD
while((TIFR1 & OCF1A_bm) == 0)
#else
while((TIMER2_BASE->SR & TIMER_SR_CC1IF )==0)
#endif
{
if(diff>900*2)
{ //If at least 1ms is available update values
count=0;
Update_All();
#if defined(STM32_BOARD) && defined(DEBUG_SERIAL)
if(TIMER2_BASE->SR & TIMER_SR_CC1IF )
debugln("Long update");
#endif
if(remote_callback==0)
break;
cli(); // Disable global int due to RW of 16 bits registers
diff=OCR1A-TCNT1; // Calc the time difference
sei(); // Enable global int
}
}
}
}
}
uint8_t Update_All()
bool Update_All()
{
#ifdef ENABLE_SERIAL
#ifdef CHECK_FOR_BOOTLOADER
@ -718,9 +706,9 @@ uint8_t Update_All()
if(IS_CHANGE_PROTOCOL_FLAG_on)
{ // Protocol needs to be changed or relaunched for bind
protocol_init(); //init new protocol
return 1;
return true;
}
return 0;
return false;
}
#if defined(FAILSAFE_ENABLE) && defined(ENABLE_PPM)
@ -778,7 +766,10 @@ static void update_led_status(void)
{
if(IS_INPUT_SIGNAL_on)
if(millis()-last_signal>70)
{
INPUT_SIGNAL_off; //no valid signal (PPM or Serial) received for 70ms
debugln("No input signal");
}
if(blink<millis())
{
if(IS_INPUT_SIGNAL_off)
@ -1716,7 +1707,7 @@ void update_serial_data()
{
rx_len=rx_idx;
memcpy((void*)rx_ok_buff,(const void*)rx_buff,rx_len);// Duplicate the buffer
RX_FLAG_on; // data to be processed next time...
RX_FLAG_on; // Data to be processed next time...
}
RX_MISSED_BUFF_off;
}
@ -2076,10 +2067,10 @@ static uint32_t random_id(uint16_t address, uint8_t create_new)
if((UCSR0A&0x1C)==0) // Check frame error, data overrun and parity error
#endif
{ // received byte is ok to process
if(rx_idx==0||discard_frame==1)
if(rx_idx==0||discard_frame==true)
{ // Let's try to sync at this point
RX_MISSED_BUFF_off; // If rx_buff was good it's not anymore...
rx_idx=0;discard_frame=0;
rx_idx=0;discard_frame=false;
rx_buff[0]=UDR0;
#ifdef FAILSAFE_ENABLE
if((rx_buff[0]&0xFC)==0x54) // If 1st byte is 0x54, 0x55, 0x56 or 0x57 it looks ok
@ -2107,7 +2098,7 @@ static uint32_t random_id(uint16_t address, uint8_t create_new)
{
if(rx_idx>=RXBUFFER_SIZE)
{
discard_frame=1; // Too many bytes being received...
discard_frame=true; // Too many bytes being received...
debugln("RX frame too long");
}
else
@ -2127,10 +2118,10 @@ static uint32_t random_id(uint16_t address, uint8_t create_new)
{
rx_idx=UDR0; // Dummy read
rx_idx=0;
discard_frame=1; // Error encountered discard full frame...
discard_frame=true; // Error encountered discard full frame...
debugln("Bad frame RX");
}
if(discard_frame==1)
if(discard_frame==true)
{
#ifdef STM32_BOARD
TIMER2_BASE->DIER &= ~TIMER_DIER_CC2IE; // Disable Timer2/Comp2 interrupt
@ -2157,7 +2148,6 @@ static uint32_t random_id(uint16_t address, uint8_t create_new)
{ // Timer1 compare B interrupt
if(rx_idx>=26 && rx_idx<RXBUFFER_SIZE)
{
debugln("%d",rx_idx);
#ifdef MULTI_SYNC
last_serial_input=TCNT1;
#endif
@ -2166,16 +2156,17 @@ static uint32_t random_id(uint16_t address, uint8_t create_new)
{ //Good frame received and main is not working on the buffer
rx_len=rx_idx;
memcpy((void*)rx_ok_buff,(const void*)rx_buff,rx_idx); // Duplicate the buffer
RX_FLAG_on; // Flag for main to process servo data
RX_FLAG_on; // Flag for main to process data
}
else
RX_MISSED_BUFF_on; // Notify that rx_buff is good
}
else
debugln("RX frame too short");
discard_frame=1;
discard_frame=true;
#ifdef STM32_BOARD
TIMER2_BASE->DIER &= ~TIMER_DIER_CC2IE; // Disable Timer2/Comp2 interrupt
TIMER2_BASE->SR = 0x1E5F & ~TIMER_SR_CC2IF; // Clear Timer2/Comp2 interrupt flag
#else
CLR_TIMSK1_OCIE1B; // Disable interrupt on compare B match
TX_RX_PAUSE_off;

View File

@ -99,7 +99,7 @@ inline void telemetry_set_input_sync(uint16_t refreshRate)
inputDelay=TIMER2_BASE->CNT;
#else
cli(); // Disable global int due to RW of 16 bits registers
inputDelay = TCNT1; // Next byte should show up within 15us=1.5 byte
inputDelay = TCNT1;
sei(); // Enable global int
#endif
inputDelay = (inputDelay - last_serial_input)>>1;
@ -824,7 +824,7 @@ void TelemetryUpdate()
t -= h ;
if ( t < 32 )
{
debugln("TEL_BUF_FULL");
// debugln("TEL_BUF_FULL");
return ;
}
#endif
@ -1055,7 +1055,7 @@ void TelemetryUpdate()
}
if (tx_tail == tx_head)
{
tx_pause(); // Check if all data is transmitted . if yes disable transmitter UDRE interrupt
tx_pause(); // Check if all data is transmitted. If yes disable transmitter UDRE interrupt.
}
#ifdef STM32_BOARD
}

View File

@ -225,6 +225,7 @@
//FrSkyX specific setting
//-----------------------
//EU LBT setting: if commented the TX will not check if a channel is busy before transmitting.
//!!!Work in progress!!! it's currently known to cause telemerty issues. Enable only if you know what you are doing.
//#define FRSKYX_LBT
//DSM specific settings
@ -281,9 +282,8 @@
#define MULTI_TELEMETRY
//Send to OpenTX the current protocol and subprotocol names. Comment to disable.
#define MULTI_NAMES
//Sync OpenTX frames with the current protocol timing. This feature is only available on the STM32 module. Uncomment to enable.
//!!!Work in progress!!! it's currently known to cause issues. Enable only if you know what you are doing.
//#define MULTI_SYNC
//Sync OpenTX frames with the current protocol timing. This feature is only available on the STM32 module. Comment to disable.
#define MULTI_SYNC
//Comment a line to disable a specific protocol telemetry
#define DSM_TELEMETRY // Forward received telemetry packet directly to TX to be decoded by er9x, erskyTX and OpenTX