2015-12-30 01:41:12 +01:00
/*
This project is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
Multiprotocol is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with Multiprotocol . If not , see < http : //www.gnu.org/licenses/>.
*/
2016-09-03 11:49:25 +02:00
# if defined(FRSKYD_CC2500_INO)
2015-12-30 01:41:12 +01:00
# include "iface_cc2500.h"
2016-01-27 17:57:33 +01:00
static void __attribute__ ( ( unused ) ) frsky2way_init ( uint8_t bind )
2015-12-30 01:41:12 +01:00
{
2017-01-30 16:10:32 +01:00
FRSKY_init_cc2500 ( FRSKYD_cc2500_conf ) ;
2015-12-30 01:41:12 +01:00
2020-03-21 15:17:46 +01:00
CC2500_WriteReg ( CC2500_1B_AGCCTRL2 , bind ? 0x43 : 0x03 ) ;
2016-04-06 12:57:42 +02:00
CC2500_WriteReg ( CC2500_09_ADDR , bind ? 0x03 : rx_tx_addr [ 3 ] ) ;
CC2500_WriteReg ( CC2500_07_PKTCTRL1 , 0x05 ) ;
CC2500_Strobe ( CC2500_SIDLE ) ; // Go to idle...
2015-12-30 01:41:12 +01:00
//
2016-04-06 12:57:42 +02:00
CC2500_WriteReg ( CC2500_0A_CHANNR , 0x00 ) ;
CC2500_WriteReg ( CC2500_23_FSCAL3 , 0x89 ) ;
CC2500_Strobe ( CC2500_SFRX ) ;
2015-12-30 01:41:12 +01:00
//#######END INIT########
}
2016-01-27 17:57:33 +01:00
static void __attribute__ ( ( unused ) ) frsky2way_build_bind_packet ( )
2015-12-30 01:41:12 +01:00
{
//11 03 01 d7 2d 00 00 1e 3c 5b 78 00 00 00 00 00 00 01
//11 03 01 19 3e 00 02 8e 2f bb 5c 00 00 00 00 00 00 01
packet [ 0 ] = 0x11 ;
packet [ 1 ] = 0x03 ;
packet [ 2 ] = 0x01 ;
packet [ 3 ] = rx_tx_addr [ 3 ] ;
packet [ 4 ] = rx_tx_addr [ 2 ] ;
uint16_t idx = ( ( state - FRSKY_BIND ) % 10 ) * 5 ;
packet [ 5 ] = idx ;
2016-12-21 18:05:55 +01:00
packet [ 6 ] = hopping_frequency [ idx + + ] ;
packet [ 7 ] = hopping_frequency [ idx + + ] ;
packet [ 8 ] = hopping_frequency [ idx + + ] ;
packet [ 9 ] = hopping_frequency [ idx + + ] ;
packet [ 10 ] = hopping_frequency [ idx + + ] ;
2015-12-30 01:41:12 +01:00
packet [ 11 ] = 0x00 ;
packet [ 12 ] = 0x00 ;
packet [ 13 ] = 0x00 ;
packet [ 14 ] = 0x00 ;
packet [ 15 ] = 0x00 ;
packet [ 16 ] = 0x00 ;
packet [ 17 ] = 0x01 ;
}
2016-01-27 17:57:33 +01:00
static void __attribute__ ( ( unused ) ) frsky2way_data_frame ( )
2015-12-30 01:41:12 +01:00
{ //pachet[4] is telemetry user frame counter(hub)
//11 d7 2d 22 00 01 c9 c9 ca ca 88 88 ca ca c9 ca 88 88
//11 57 12 00 00 01 f2 f2 f2 f2 06 06 ca ca ca ca 18 18
packet [ 0 ] = 0x11 ; //Length
packet [ 1 ] = rx_tx_addr [ 3 ] ;
packet [ 2 ] = rx_tx_addr [ 2 ] ;
packet [ 3 ] = counter ; //
2016-02-05 17:27:51 +01:00
# if defined TELEMETRY
packet [ 4 ] = telemetry_counter ;
# else
packet [ 4 ] = 0x00 ;
# endif
2016-01-26 13:46:22 +01:00
2015-12-30 01:41:12 +01:00
packet [ 5 ] = 0x01 ;
//
packet [ 10 ] = 0 ;
packet [ 11 ] = 0 ;
packet [ 16 ] = 0 ;
packet [ 17 ] = 0 ;
for ( uint8_t i = 0 ; i < 8 ; i + + )
{
uint16_t value ;
value = convert_channel_frsky ( i ) ;
if ( i < 4 )
{
packet [ 6 + i ] = value & 0xff ;
packet [ 10 + ( i > > 1 ) ] | = ( ( value > > 8 ) & 0x0f ) < < ( 4 * ( i & 0x01 ) ) ;
}
else
{
packet [ 8 + i ] = value & 0xff ;
packet [ 16 + ( ( i - 4 ) > > 1 ) ] | = ( ( value > > 8 ) & 0x0f ) < < ( 4 * ( ( i - 4 ) & 0x01 ) ) ;
}
}
}
2016-01-27 17:57:33 +01:00
uint16_t initFrSky_2way ( )
{
2020-03-21 15:17:46 +01:00
//FrskyD init hop
2020-04-10 19:32:50 +02:00
if ( eeprom_read_byte ( ( EE_ADDR ) FRSKY_RX_EEPROM_OFFSET + 4 ) = = 127 & & eeprom_read_byte ( ( EE_ADDR ) FRSKY_RX_EEPROM_OFFSET ) = = 2 ) // bound in FRSKY-RX CloneTX -> use clone mode
Frsky_init_clone ( ) ;
else
for ( uint8_t i = 0 ; i < 50 ; i + + )
{
uint8_t freq = ( i * 0x1e ) % 0xeb ;
if ( i = = 3 | | i = = 23 | | i = = 47 )
freq + + ;
if ( i > 47 )
freq = 0 ;
hopping_frequency [ i ] = freq ;
}
2020-03-21 15:17:46 +01:00
2017-01-30 21:09:20 +01:00
packet_count = 0 ;
2018-01-03 13:04:58 +01:00
if ( IS_BIND_IN_PROGRESS )
2016-08-31 15:43:45 +02:00
{
2016-01-27 17:57:33 +01:00
frsky2way_init ( 1 ) ;
2016-08-31 15:43:45 +02:00
state = FRSKY_BIND ;
2016-01-27 17:57:33 +01:00
}
else
{
2017-02-06 10:32:09 +01:00
state = FRSKY_BIND_DONE ;
2016-01-27 17:57:33 +01:00
}
return 10000 ;
}
uint16_t ReadFrSky_2way ( )
{
if ( state < FRSKY_BIND_DONE )
{
frsky2way_build_bind_packet ( ) ;
2016-04-06 12:57:42 +02:00
CC2500_Strobe ( CC2500_SIDLE ) ;
CC2500_WriteReg ( CC2500_0A_CHANNR , 0x00 ) ;
CC2500_WriteReg ( CC2500_23_FSCAL3 , 0x89 ) ;
CC2500_Strobe ( CC2500_SFRX ) ; //0x3A
CC2500_WriteData ( packet , packet [ 0 ] + 1 ) ;
2018-01-03 13:04:58 +01:00
if ( IS_BIND_DONE )
2017-02-06 18:46:34 +01:00
state = FRSKY_BIND_DONE ;
else
state + + ;
2016-01-27 17:57:33 +01:00
return 9000 ;
}
if ( state = = FRSKY_BIND_DONE )
{
state = FRSKY_DATA2 ;
frsky2way_init ( 0 ) ;
counter = 0 ;
BIND_DONE ;
}
else
if ( state = = FRSKY_DATA5 )
{
2016-04-06 12:57:42 +02:00
CC2500_Strobe ( CC2500_SRX ) ; //0x34 RX enable
2016-01-27 17:57:33 +01:00
state = FRSKY_DATA1 ;
return 9200 ;
}
counter = ( counter + 1 ) % 188 ;
if ( state = = FRSKY_DATA4 )
{ //telemetry receive
CC2500_SetTxRxMode ( RX_EN ) ;
2016-04-06 12:57:42 +02:00
CC2500_Strobe ( CC2500_SIDLE ) ;
2016-12-21 18:05:55 +01:00
CC2500_WriteReg ( CC2500_0A_CHANNR , hopping_frequency [ counter % 47 ] ) ;
2016-04-06 12:57:42 +02:00
CC2500_WriteReg ( CC2500_23_FSCAL3 , 0x89 ) ;
2016-01-27 17:57:33 +01:00
state + + ;
return 1300 ;
}
else
{
if ( state = = FRSKY_DATA1 )
{
2019-11-11 19:15:39 +01:00
# ifdef MULTI_SYNC
telemetry_set_input_sync ( 9000 ) ;
# endif
2016-04-06 12:57:42 +02:00
len = CC2500_ReadReg ( CC2500_3B_RXBYTES | CC2500_READ_BURST ) & 0x7F ;
2017-01-30 21:09:20 +01:00
if ( len & & len < = ( 0x11 + 3 ) ) // 20bytes
{
2019-09-30 17:35:12 +02:00
CC2500_ReadData ( packet_in , len ) ; //received telemetry packets
2016-01-27 17:57:33 +01:00
# if defined(TELEMETRY)
2019-09-30 17:35:12 +02:00
if ( packet_in [ len - 1 ] & 0x80 )
2017-01-30 21:09:20 +01:00
{ //with valid crc
2017-01-31 08:46:50 +01:00
packet_count = 0 ;
2019-09-30 17:35:12 +02:00
frsky_check_telemetry ( packet_in , len ) ; //check if valid telemetry packets and buffer them.
2017-01-30 21:09:20 +01:00
}
# endif
}
else
{
packet_count + + ;
// restart sequence on missed packet - might need count or timeout instead of one missed
if ( packet_count > 100 )
{ //~1sec
packet_count = 0 ;
# if defined TELEMETRY
telemetry_link = 0 ; //no link frames
2019-09-30 17:35:12 +02:00
packet_in [ 6 ] = 0 ; //no user frames.
2017-01-30 21:09:20 +01:00
# endif
}
}
2016-01-27 17:57:33 +01:00
CC2500_SetTxRxMode ( TX_EN ) ;
CC2500_SetPower ( ) ; // Set tx_power
}
2016-04-06 12:57:42 +02:00
CC2500_Strobe ( CC2500_SIDLE ) ;
2016-12-21 18:05:55 +01:00
CC2500_WriteReg ( CC2500_0A_CHANNR , hopping_frequency [ counter % 47 ] ) ;
2016-08-31 10:22:36 +02:00
if ( prev_option ! = option )
{
CC2500_WriteReg ( CC2500_0C_FSCTRL0 , option ) ; // Frequency offset hack
prev_option = option ;
}
2016-04-06 12:57:42 +02:00
CC2500_WriteReg ( CC2500_23_FSCAL3 , 0x89 ) ;
CC2500_Strobe ( CC2500_SFRX ) ;
2016-01-27 17:57:33 +01:00
frsky2way_data_frame ( ) ;
2016-04-06 12:57:42 +02:00
CC2500_WriteData ( packet , packet [ 0 ] + 1 ) ;
2016-01-27 17:57:33 +01:00
state + + ;
}
return state = = FRSKY_DATA4 ? 7500 : 9000 ;
}
2015-12-30 01:41:12 +01:00
# endif