added Mike Blandord modifications

- used bootloader to flash multi-module with TX
-updated  FrslyX protocol telemetry sequence
This commit is contained in:
midelic 2017-07-28 23:39:51 +03:00
parent 021577d638
commit 2753f6c4e5
5 changed files with 245 additions and 28 deletions

View File

@ -21,8 +21,11 @@
#include "iface_cc2500.h"
uint8_t chanskip;
uint8_t seq_last_sent;
uint8_t seq_last_rcvd;
//uint8_t seq_last_sent;
//uint8_t seq_last_rcvd;
uint8_t FrX_send_seq ;
uint8_t FrX_receive_seq ;
static void __attribute__((unused)) set_start(uint8_t ch )
{
@ -151,13 +154,7 @@ static void __attribute__((unused)) frskyX_data_frame()
packet[9+i+2]=chan_1>>4;
}
packet[21] = seq_last_sent << 4 | seq_last_rcvd;//8 at start
if (seq_last_sent < 0x08 && seq_last_rcvd < 8)
seq_last_sent = (seq_last_sent + 1) % 4;
else if (seq_last_rcvd == 0x00)
seq_last_sent = 1;
else
seq_last_rcvd = 8;
packet[21] = (FrX_receive_seq << 4) | FrX_send_seq ;//8 at start
if(sub_protocol & 1 )// in X8 mode send only 8ch every 9ms
lpass = 0 ;
@ -210,7 +207,7 @@ uint16_t ReadFrSkyX()
CC2500_Strobe(CC2500_SIDLE);
CC2500_WriteData(packet, packet[0]+1);
//
frskyX_data_frame();
// frskyX_data_frame();
state++;
return 5500;
case FRSKY_DATA2:
@ -221,7 +218,7 @@ uint16_t ReadFrSkyX()
case FRSKY_DATA3:
CC2500_Strobe(CC2500_SRX);
state++;
return 3000;
return 2800;
case FRSKY_DATA4:
len = CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
if (len && (len<=(0x0E + 3))) //Telemetry frame is 17
@ -240,8 +237,10 @@ uint16_t ReadFrSkyX()
// restart sequence on missed packet - might need count or timeout instead of one missed
if(packet_count>100)
{//~1sec
seq_last_sent = 0;
seq_last_rcvd = 8;
// seq_last_sent = 0;
// seq_last_rcvd = 8;
FrX_send_seq = 0x08 ;
FrX_receive_seq = 0 ;
packet_count=0;
#if defined TELEMETRY
telemetry_lost=1;
@ -249,8 +248,13 @@ uint16_t ReadFrSkyX()
}
CC2500_Strobe(CC2500_SFRX); //flush the RXFIFO
}
frskyX_data_frame();
if ( FrX_send_seq != 0x08 )
{
FrX_send_seq = ( FrX_send_seq + 1 ) & 0x03 ;
}
state = FRSKY_DATA1;
return 300;
return 500;
}
return 1;
}
@ -279,8 +283,10 @@ uint16_t initFrSkyX()
state = FRSKY_DATA1;
initialize_data(0);
}
seq_last_sent = 0;
seq_last_rcvd = 8;
// seq_last_sent = 0;
// seq_last_rcvd = 8;
uint8_t FrX_send_seq = 0x08 ;
uint8_t FrX_receive_seq = 0 ;
return 10000;
}
#endif

View File

@ -393,7 +393,7 @@ enum CC2500_POWER
CC2500_POWER_16 = 0xFE, // 0dbm
CC2500_POWER_17 = 0xFF // +1dbm
};
#define CC2500_HIGH_POWER CC2500_POWER_16
#define CC2500_HIGH_POWER CC2500_POWER_17
#define CC2500_LOW_POWER CC2500_POWER_13
#define CC2500_RANGE_POWER CC2500_POWER_1
#define CC2500_BIND_POWER CC2500_POWER_1

View File

@ -106,6 +106,19 @@ uint8_t RX_num;
uint8_t calData[48];
#endif
#ifdef CHECK_FOR_BOOTLOADER
uint8_t BootTimer ;
uint8_t BootState ;
uint8_t NotBootChecking ;
uint8_t BootCount ;
#define BOOT_WAIT_30_IDLE 0
#define BOOT_WAIT_30_DATA 1
#define BOOT_WAIT_20 2
#define BOOT_READY 3
#endif
//Channel mapping for protocols
const uint8_t CH_AETR[]={AILERON, ELEVATOR, THROTTLE, RUDDER, AUX1, AUX2, AUX3, AUX4, AUX5, AUX6, AUX7, AUX8, AUX9, AUX10};
const uint8_t CH_TAER[]={THROTTLE, AILERON, ELEVATOR, RUDDER, AUX1, AUX2, AUX3, AUX4, AUX5, AUX6, AUX7, AUX8};
@ -392,12 +405,91 @@ void setup()
protocol=0;
servo_max_100=SERIAL_MAX_100; servo_min_100=SERIAL_MIN_100;
servo_max_125=SERIAL_MAX_125; servo_min_125=SERIAL_MIN_125;
#ifdef CHECK_FOR_BOOTLOADER
Mprotocol_serial_init(1); // Configure serial and enable RX interrupt
#else
Mprotocol_serial_init(); // Configure serial and enable RX interrupt
#endif
#endif //ENABLE_SERIAL
}
servo_mid=servo_min_100+servo_max_100; //In fact 2* mid_value
}
#ifdef CHECK_FOR_BOOTLOADER
void pollBoot()
{
uint8_t rxchar ;
uint8_t lState = BootState ;
uint8_t millisTime = millis() ; // Call this once only
#ifdef ORANGE_TX
if ( USARTC0.STATUS & USART_RXCIF_bm )
#else
if ( UCSR0A & ( 1 << RXC0 ) )
#endif
{
rxchar = UDR0 ;
BootCount += 1 ;
if ( ( lState == BOOT_WAIT_30_IDLE ) || ( lState == BOOT_WAIT_30_DATA ) )
{
if ( lState == BOOT_WAIT_30_IDLE ) // Waiting for 0x30
{
BootTimer = millisTime ; // Start timeout
}
if ( rxchar == 0x30 )
{
lState = BOOT_WAIT_20 ;
}
else
{
lState = BOOT_WAIT_30_DATA ;
}
}
else if ( lState == BOOT_WAIT_20 ) // Waiting for 0x20
{
if ( rxchar == 0x20 )
{
lState = BOOT_READY ;
}
}
}
else // No byte received
{
if ( lState != BOOT_WAIT_30_IDLE ) // Something received
{
uint8_t time = millisTime - BootTimer ;
if ( time > 5 )
{
if ( BootCount > 2 )
{ // Run normally
NotBootChecking = 0xFF ;
Mprotocol_serial_init( 0 ) ;
}
else if ( lState == BOOT_READY )
{
cli(); // Disable global int due to RW of 16 bits registers
void (*p)() ;
#ifndef ORANGE_TX
p = (void (*)())0x3F00 ; // Word address (0x7E00 byte)
#else
p = (void (*)())0x4000 ; // Word address (0x8000 byte)
#endif
(*p)() ;
// go to boot
}
else
{
lState = BOOT_WAIT_30_IDLE ;
BootCount = 0 ;
}
}
}
}
BootState = lState ;
}
#endif
// Main
// Protocol scheduler
void loop()
@ -485,6 +577,13 @@ void loop()
uint8_t Update_All()
{
#ifdef ENABLE_SERIAL
#ifdef CHECK_FOR_BOOTLOADER
if ( (mode_select==MODE_SERIAL) && (NotBootChecking == 0) )
{
pollBoot() ;
}
else
#endif
if(mode_select==MODE_SERIAL && IS_RX_FLAG_on) // Serial mode and something has been received
{
update_serial_data(); // Update protocol and data
@ -1093,7 +1192,11 @@ void modules_reset()
prev_power=0xFD; // unused power value
}
#ifdef CHECK_FOR_BOOTLOADER
void Mprotocol_serial_init( uint8_t boot )
#else
void Mprotocol_serial_init()
#endif
{
#ifdef ORANGE_TX
PORTC.OUTSET = 0x08 ;
@ -1103,12 +1206,23 @@ void Mprotocol_serial_init()
USARTC0.BAUDCTRLB = 0 ;
USARTC0.CTRLB = 0x18 ;
USARTC0.CTRLA = (USARTC0.CTRLA & 0xCF) | 0x10 ;
USARTC0.CTRLA = (USARTC0.CTRLA & 0xCC) | 0x11 ;
USARTC0.CTRLC = 0x2B ;
UDR0 ;
#ifdef INVERT_SERIAL
PORTC.PIN3CTRL |= 0x40 ;
#endif
#ifdef CHECK_FOR_BOOTLOADER
if ( boot )
{
USARTC0.BAUDCTRLB = 0 ;
USARTC0.BAUDCTRLA = 33 ; // 57600
USARTC0.CTRLA = (USARTC0.CTRLA & 0xC0) ;
USARTC0.CTRLC = 0x03 ; // 8 bit, no parity, 1 stop
USARTC0.CTRLB = 0x18 ; // Enable Tx and Rx
PORTC.PIN3CTRL &= ~0x40 ;
}
#endif // CHECK_FOR_BOOTLOADER
#elif defined STM32_BOARD
usart2_begin(100000,SERIAL_8E2);
usart3_begin(100000,SERIAL_8E2);
@ -1132,6 +1246,16 @@ void Mprotocol_serial_init()
initTXSerial( SPEED_100K ) ;
#endif //TELEMETRY
#endif //DEBUG_TX
#ifdef CHECK_FOR_BOOTLOADER
if ( boot )
{
UBRR0H = 0 ;
UBRR0L = 33 ; // 57600
UCSR0C &= ~_BV(UPM01) ; // No parity
UCSR0B &= ~_BV(RXCIE0);// No rx interrupt
UCSR0A |= _BV(U2X0); //Double speed mode USART0
}
#endif // CHECK_FOR_BOOTLOADER
#endif //ORANGE_TX
}

View File

@ -31,6 +31,18 @@ uint8_t RetrySequence ;
uint8_t sport_counter=0;
uint8_t RxBt = 0;
uint8_t sport = 0;
struct t_fx_rx_packet
{
uint8_t validSequence ;
uint8_t count ;
uint8_t payload[6] ;
} ;
// Store for out of sequence packet
struct t_fx_rx_packet FrskyxRxTelemetry ;
#endif
#if defined HUB_TELEMETRY
#define USER_MAX_BYTES 6
@ -205,19 +217,73 @@ void frsky_check_telemetry(uint8_t *pkt,uint8_t len)
telemetry_lost=0;
if (protocol==MODE_FRSKYX)
{
if ((pktt[5] >> 4 & 0x0f) == 0x08)
{
seq_last_sent = 8;
seq_last_rcvd = 0;
pass=0;
}
else
uint16_t lcrc = crc_x(&pkt[3], len-7) ;
if ( ( (lcrc >> 8) == pkt[len-4]) && ( (lcrc & 0x00FF ) == pkt[len-3]) )
{
if ((pktt[5] >> 4 & 0x03) == (seq_last_rcvd + 1) % 4)
seq_last_rcvd = (seq_last_rcvd + 1) % 4;
// Check if in sequence
if ( (pkt[5] & 0x0F) == 0x08 )
{
FrX_receive_seq = 0x08 ;
}
else if ( (pkt[5] & 0x03) == (FrX_receive_seq & 0x03 ) )
{
// OK to process
FrX_receive_seq = ( FrX_receive_seq + 1 ) & 0x03 ;
if ( FrskyxRxTelemetry.validSequence & 0x80 )
{
FrX_receive_seq = ( FrskyxRxTelemetry.validSequence + 1 ) & 3 ;
}
}
else
pass=0;//reset if sequence wrong
{
// Save and request correct packet
struct t_fx_rx_packet *p ;
uint8_t count ;
// pkt[4] RSSI
// pkt[5] sequence control
// pkt[6] payload count
// pkt[7-12] payload
pktt[6] = 0 ; // Don't process
p = &FrskyxRxTelemetry ;
count = pkt[6] ;
if ( count <= 6 )
{
p->count = count ;
for ( uint8_t i = 0 ; i < count ; i += 1 )
{
p->payload[i] = pkt[i+7] ;
}
p->validSequence = 0x80 | ( pkt[5] & 0x03 ) ;
}
FrX_receive_seq = ( FrX_receive_seq & 0x03 ) | 0x04 ; // Request re-transmission
}
if (((pktt[5] >> 4) & 0x0f) == 0x08)
{
FrX_send_seq = 0 ;
// FrX_receive_seq = 0x08 ;
}
}
// packet[21] = (FrX_receive_seq << 4) | FrX_send_seq ;//8 at start
// if ( FrX_send_seq != 0x08 )
// {
// FrX_send_seq = ( FrX_send_seq + 1 ) & 0x03 ;
// }
// if ((pktt[5] >> 4 & 0x0f) == 0x08)
// {
// seq_last_sent = 8;
// seq_last_rcvd = 0;
// pass=0;
// }
// else
// {
// if ((pktt[5] >> 4 & 0x03) == (seq_last_rcvd + 1) % 4)
// seq_last_rcvd = (seq_last_rcvd + 1) % 4;
// else
// pass=0;//reset if sequence wrong
// }
}
#endif
}
@ -573,8 +639,20 @@ void TelemetryUpdate()
else
RxBt = (pktt[4]<<1) + 1 ;
if(pktt[6] && pktt[6]<=6)
{
for (uint8_t i=0; i < pktt[6]; i++)
proces_sport_data(pktt[7+i]);
if ( FrskyxRxTelemetry.validSequence & 0x80 )
{
// Process out of sequence packet
for (uint8_t i=0; i < FrskyxRxTelemetry.count ; i++)
{
proces_sport_data( FrskyxRxTelemetry.payload[i] ) ;
}
// FrX_receive_seq = ( FrskyxRxTelemetry.validSequence + 1 ) & 3 ;
FrskyxRxTelemetry.validSequence = 0 ;
}
}
telemetry_link=0;
}
uint32_t now = micros();

View File

@ -49,6 +49,15 @@
//The goal is to prevent binding other people's model when powering up the TX, changing model or scanning through protocols.
#define WAIT_FOR_BIND
/*************************/
/*** BOOTLOADER USE ***/
/*************************/
#define CHECK_FOR_BOOTLOADER
//Allow flashing multimodule directly with TX(erky9x or opentx modified firmwares)
//1. Start ersky9x in bootloader mode and copy the multi.hex file into the firmware directory on the SD card.
//2. Disconnect the USB, then press EXIT LONG while holding the horizontal trims APART to enter "maintenance mode".
//3. Select "Update Multi", then HEX mode, then select the file and start the flash.
//4. When finished, EXIT back to reboot in normal mode.
/****************/
/*** RF CHIPS ***/