2020-01-21 17:42:33 +02:00
# if defined(FRSKYR9_SX1276_INO)
2020-01-23 22:25:00 +02:00
# include "iface_sx1276.h"
2020-01-21 17:42:33 +02:00
2020-01-23 22:25:00 +02:00
# define FREQ_MAP_SIZE 29
2020-01-21 17:42:33 +02:00
2020-01-23 22:25:00 +02:00
// TODO the channel spacing is equal, consider calculating the new channel instead of using lookup tables (first_chan + index * step)
2020-01-21 17:42:33 +02:00
2020-01-24 12:12:07 +01:00
static uint32_t FrSkyR9_freq_map_915 [ FREQ_MAP_SIZE ] =
2020-01-21 17:42:33 +02:00
{
914472960 ,
914972672 ,
915472384 ,
915972096 ,
916471808 ,
916971520 ,
917471232 ,
917970944 ,
918470656 ,
918970368 ,
919470080 ,
919969792 ,
920469504 ,
920969216 ,
921468928 ,
921968640 ,
922468352 ,
922968064 ,
923467776 ,
923967488 ,
924467200 ,
924966912 ,
925466624 ,
925966336 ,
926466048 ,
926965760 ,
927465472 ,
2020-01-24 12:12:07 +01:00
// last two determined by FrSkyR9_step
2020-01-21 17:42:33 +02:00
0 ,
0
} ;
2020-01-24 12:12:07 +01:00
static uint32_t FrSkyR9_freq_map_868 [ FREQ_MAP_SIZE ] =
2020-01-23 22:25:00 +02:00
{
859504640 ,
860004352 ,
860504064 ,
861003776 ,
861503488 ,
862003200 ,
862502912 ,
863002624 ,
863502336 ,
864002048 ,
864501760 ,
865001472 ,
865501184 ,
866000896 ,
866500608 ,
867000320 ,
867500032 ,
867999744 ,
868499456 ,
868999168 ,
869498880 ,
869998592 ,
870498304 ,
870998016 ,
871497728 ,
871997440 ,
872497152 ,
2020-01-21 17:42:33 +02:00
2020-01-24 12:12:07 +01:00
// last two determined by FrSkyR9_step
2020-01-23 22:25:00 +02:00
0 ,
0
} ;
2020-01-24 12:12:07 +01:00
static uint8_t FrSkyR9_step = 1 ;
static uint32_t * FrSkyR9_freq_map = FrSkyR9_freq_map_915 ;
2020-01-21 17:42:33 +02:00
uint16_t initFrSkyR9 ( )
{
set_rx_tx_addr ( MProtocol_id_master ) ;
2020-01-24 14:59:26 +01:00
if ( sub_protocol & 0x01 )
2020-01-24 12:12:07 +01:00
FrSkyR9_freq_map = FrSkyR9_freq_map_868 ;
2020-01-24 14:59:26 +01:00
else
FrSkyR9_freq_map = FrSkyR9_freq_map_915 ;
2020-01-23 22:25:00 +02:00
2020-01-24 12:12:07 +01:00
FrSkyR9_step = 1 + ( random ( 0xfefefefe ) % 24 ) ;
FrSkyR9_freq_map [ 27 ] = FrSkyR9_freq_map [ FrSkyR9_step ] ;
FrSkyR9_freq_map [ 28 ] = FrSkyR9_freq_map [ FrSkyR9_step + 1 ] ;
2020-01-21 17:42:33 +02:00
2020-01-23 22:25:00 +02:00
SX1276_SetMode ( true , false , SX1276_OPMODE_SLEEP ) ;
SX1276_SetMode ( true , false , SX1276_OPMODE_STDBY ) ;
2020-01-21 17:42:33 +02:00
2020-01-23 22:25:00 +02:00
// uint8_t buffer[2];
// buffer[0] = 0x00;
// buffer[1] = 0x00;
// SX1276_WriteRegisterMulti(SX1276_40_DIOMAPPING1, buffer, 2);
2020-01-21 17:42:33 +02:00
2020-01-23 22:25:00 +02:00
SX1276_SetDetectOptimize ( true , SX1276_DETECT_OPTIMIZE_SF6 ) ;
SX1276_ConfigModem1 ( SX1276_MODEM_CONFIG1_BW_500KHZ , SX1276_MODEM_CONFIG1_CODING_RATE_4_5 , true ) ;
SX1276_ConfigModem2 ( 6 , false , false ) ;
SX1276_ConfigModem3 ( false , false ) ;
SX1276_SetPreambleLength ( 9 ) ;
SX1276_SetDetectionThreshold ( SX1276_MODEM_DETECTION_THRESHOLD_SF6 ) ;
SX1276_SetLna ( 1 , true ) ;
SX1276_SetHopPeriod ( 0 ) ; // 0 = disabled, we hope frequencies manually
SX1276_SetPaDac ( true ) ;
2020-01-21 17:42:33 +02:00
2020-01-24 12:12:07 +01:00
hopping_frequency_no = 0 ;
2020-01-21 17:42:33 +02:00
// TODO this can probably be shorter
return 20000 ; // start calling FrSkyR9_callback in 20 milliseconds
}
uint16_t FrSkyR9_callback ( )
{
2020-01-23 22:25:00 +02:00
SX1276_SetMode ( true , false , SX1276_OPMODE_STDBY ) ;
2020-01-21 17:42:33 +02:00
2020-01-23 22:25:00 +02:00
//SX1276_WriteReg(SX1276_11_IRQFLAGSMASK, 0xbf); // use only RxDone interrupt
2020-01-21 17:42:33 +02:00
2020-01-23 22:25:00 +02:00
// uint8_t buffer[2];
// buffer[0] = 0x00;
// buffer[1] = 0x00;
// SX1276_WriteRegisterMulti(SX1276_40_DIOMAPPING1, buffer, 2); // RxDone interrupt mapped to DIO0 (the rest are not used because of the REG_IRQ_FLAGS_MASK)
2020-01-21 17:42:33 +02:00
// SX1276_WriteReg(REG_PAYLOAD_LENGTH, 13);
// SX1276_WriteReg(REG_FIFO_ADDR_PTR, 0x00);
2020-01-23 22:25:00 +02:00
// SX1276_WriteReg(SX1276_01_OPMODE, 0x85); // RXCONTINUOUS
2020-01-21 17:42:33 +02:00
// delay(10); // 10 ms
2020-01-23 22:25:00 +02:00
// SX1276_WriteReg(SX1276_01_OPMODE, 0x81); // STDBY
2020-01-21 17:42:33 +02:00
2020-01-23 22:25:00 +02:00
//SX1276_WriteReg(SX1276_09_PACONFIG, 0xF0);
2020-01-21 17:42:33 +02:00
2020-01-23 22:25:00 +02:00
// max power: 15dBm (10.8 + 0.6 * MaxPower [dBm])
// output_power: 2 dBm (17-(15-OutputPower) (if pa_boost_pin == true))
SX1276_SetPaConfig ( true , 7 , 0 ) ;
2020-01-24 12:12:07 +01:00
SX1276_SetFrequency ( FrSkyR9_freq_map [ hopping_frequency_no ] ) ; // set current center frequency
2020-01-21 17:42:33 +02:00
delayMicroseconds ( 500 ) ;
2020-01-24 12:12:07 +01:00
packet [ 0 ] = 0x3C ; // ????
packet [ 1 ] = rx_tx_addr [ 3 ] ; // unique radio id
packet [ 2 ] = rx_tx_addr [ 2 ] ; // unique radio id
packet [ 3 ] = hopping_frequency_no ; // current channel index
packet [ 4 ] = FrSkyR9_step ; // step size and last 2 channels start index
packet [ 5 ] = RX_num ; // receiver number from OpenTX
2020-01-21 17:42:33 +02:00
// binding mode: 0x00 regular / 0x41 bind?
if ( IS_BIND_IN_PROGRESS )
2020-01-24 12:12:07 +01:00
packet [ 6 ] = 0x41 ;
2020-01-21 17:42:33 +02:00
else
2020-01-24 12:12:07 +01:00
packet [ 6 ] = 0x00 ;
2020-01-21 17:42:33 +02:00
// TODO
2020-01-24 12:12:07 +01:00
packet [ 7 ] = 0x00 ; // fail safe related (looks like the same sequence of numbers as FrskyX protocol)
2020-01-21 17:42:33 +02:00
// two channel are spread over 3 bytes.
// each channel is 11 bit + 1 bit (msb) that states whether
// it's part of the upper channels (9-16) or lower (1-8) (0 - lower 1 - upper)
2020-01-24 14:59:26 +01:00
# define CH_POS 8
static uint8_t chan_start = 0 ;
uint8_t chan_index = chan_start ;
2020-01-21 17:42:33 +02:00
2020-01-24 22:09:37 +02:00
for ( int i = 0 ; i < 12 ; i + = 3 )
2020-01-21 17:42:33 +02:00
{
// map channel values (0-2047) to (64-1984)
2020-01-23 22:29:57 +02:00
uint16_t ch1 = FrSkyX_scaleForPXX ( chan_index ) ;
uint16_t ch2 = FrSkyX_scaleForPXX ( chan_index + 1 ) ;
2020-01-21 17:42:33 +02:00
2020-01-24 14:59:26 +01:00
packet [ CH_POS + i ] = ch1 ;
packet [ CH_POS + i + 1 ] = ( ch1 > > 8 ) | ( ch2 < < 4 ) ;
packet [ CH_POS + i + 2 ] = ( ch2 > > 4 ) ;
2020-01-21 17:42:33 +02:00
2020-01-24 12:12:07 +01:00
chan_index + = 2 ;
2020-01-21 17:42:33 +02:00
}
2020-01-24 14:59:26 +01:00
if ( ( sub_protocol & 0x02 ) = = 0 )
chan_start ^ = 0x08 ; // Alternate between lower and upper when 16 channels is used
2020-01-24 12:12:07 +01:00
packet [ 20 ] = 0x08 ; // ????
packet [ 21 ] = 0x00 ; // ????
packet [ 22 ] = 0x00 ; // ????
packet [ 23 ] = 0x00 ; // ????
2020-01-21 17:42:33 +02:00
2020-01-24 12:12:07 +01:00
uint16_t crc = FrSkyX_crc ( packet , 24 ) ;
2020-01-21 17:42:33 +02:00
2020-01-24 12:12:07 +01:00
packet [ 24 ] = crc ; // low byte
packet [ 25 ] = crc > > 8 ; // high byte
2020-01-21 17:42:33 +02:00
2020-01-24 12:12:07 +01:00
SX1276_WritePayloadToFifo ( packet , 26 ) ;
2020-01-21 17:42:33 +02:00
2020-01-24 12:12:07 +01:00
hopping_frequency_no = ( hopping_frequency_no + FrSkyR9_step ) % FREQ_MAP_SIZE ;
2020-01-21 17:42:33 +02:00
2020-01-23 22:25:00 +02:00
SX1276_SetMode ( true , false , SX1276_OPMODE_TX ) ;
2020-01-21 17:42:33 +02:00
// need to clear RegIrqFlags?
return 19400 ;
}
# endif