2017-02-24 11:00:02 +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/>.
*/
// Compatible with Global Drone GW008 protocol.
// There are 3 versions of this small quad, this protocol is for the one with a XNS104 IC in the stock Tx and PAN159CY IC in the quad (SOCs with built-in xn297 compatible RF).
// The xn297 version is compatible with the CX10 protocol (green pcb).
// The LT8910 version is not supported yet.
#if defined(GW008_NRF24L01_INO)
2021-03-17 17:05:42 +01:00
#include "iface_xn297.h"
2017-02-24 11:00:02 +01:00
#define GW008_INITIAL_WAIT 500
#define GW008_PACKET_PERIOD 2400
#define GW008_RF_BIND_CHANNEL 2
#define GW008_PAYLOAD_SIZE 15
enum {
GW008_BIND1 ,
GW008_BIND2 ,
GW008_DATA
};
2021-02-11 18:40:29 +01:00
static void __attribute__ (( unused )) GW008_send_packet ()
2017-02-24 11:00:02 +01:00
{
packet [ 0 ] = rx_tx_addr [ 0 ];
2021-02-11 18:40:29 +01:00
if ( IS_BIND_IN_PROGRESS )
2017-02-24 11:00:02 +01:00
{
packet [ 1 ] = 0x55 ;
packet [ 2 ] = hopping_frequency [ 0 ];
packet [ 3 ] = hopping_frequency [ 1 ];
packet [ 4 ] = hopping_frequency [ 2 ];
packet [ 5 ] = hopping_frequency [ 3 ];
memset ( & packet [ 6 ], 0 , 7 );
packet [ 13 ] = 0xaa ;
}
else
{
2021-03-17 17:05:42 +01:00
XN297_Hopping (( hopping_frequency_no ++ ) / 2 );
hopping_frequency_no %= 8 ;
2019-08-24 22:14:18 +02:00
packet [ 1 ] = 0x01 | GET_FLAG ( CH5_SW , 0x40 ); // flip
2018-01-08 19:37:14 +01:00
packet [ 2 ] = convert_channel_16b_limit ( AILERON , 200 , 0 ); // aileron
packet [ 3 ] = convert_channel_16b_limit ( ELEVATOR , 0 , 200 ); // elevator
packet [ 4 ] = convert_channel_16b_limit ( RUDDER , 200 , 0 ); // rudder
packet [ 5 ] = convert_channel_16b_limit ( THROTTLE , 0 , 200 ); // throttle
2017-02-24 11:00:02 +01:00
packet [ 6 ] = 0xaa ;
packet [ 7 ] = 0x02 ; // max rate
packet [ 8 ] = 0x00 ;
packet [ 9 ] = 0x00 ;
packet [ 10 ] = 0x00 ;
packet [ 11 ] = 0x00 ;
packet [ 12 ] = 0x00 ;
packet [ 13 ] = rx_tx_addr [ 2 ];
}
packet [ 14 ] = rx_tx_addr [ 1 ];
2021-03-17 17:05:42 +01:00
// Send
XN297_SetPower ();
XN297_SetTxRxMode ( TX_EN );
2019-06-05 23:23:27 +02:00
XN297_WriteEnhancedPayload ( packet , GW008_PAYLOAD_SIZE , 0 );
2017-02-24 11:00:02 +01:00
}
2021-02-09 18:23:33 +01:00
static void __attribute__ (( unused )) GW008_RF_init ()
2017-02-24 11:00:02 +01:00
{
2021-03-17 17:05:42 +01:00
XN297_Configure ( XN297_CRCEN , XN297_SCRAMBLED , XN297_1M );
2017-02-24 11:00:02 +01:00
XN297_SetTXAddr (( uint8_t * ) " \xcc\xcc\xcc\xcc\xcc " , 5 );
2021-03-17 17:05:42 +01:00
XN297_SetRXAddr (( uint8_t * ) " \xcc\xcc\xcc\xcc\xcc " , GW008_PAYLOAD_SIZE );
//XN297_HoppingCalib(8);
XN297_RFChannel ( GW008_RF_BIND_CHANNEL );
2017-02-24 11:00:02 +01:00
}
static void __attribute__ (( unused )) GW008_initialize_txid ()
{
uint32_t lfsr = random ( 0xfefefefe ) + (( uint32_t ) random ( 0xfefefefe ) << 16 );
for ( uint8_t i = 0 ; i < 4 ; i ++ )
hopping_frequency [ i ] = 0x10 + (( lfsr >> ( i * 8 )) % 0x37 );
}
uint16_t GW008_callback ()
{
switch ( phase )
{
case GW008_BIND1 :
2021-03-17 17:05:42 +01:00
if ( XN297_IsRX () && // RX fifo data ready
2017-02-24 11:00:02 +01:00
XN297_ReadEnhancedPayload ( packet , GW008_PAYLOAD_SIZE ) == GW008_PAYLOAD_SIZE && // check payload size
packet [ 0 ] == rx_tx_addr [ 0 ] && packet [ 14 ] == rx_tx_addr [ 1 ]) // check tx id
{
2021-03-17 17:05:42 +01:00
XN297_SetTxRxMode ( TXRX_OFF );
XN297_SetTxRxMode ( TX_EN );
2017-02-24 11:00:02 +01:00
rx_tx_addr [ 2 ] = packet [ 13 ];
BIND_DONE ;
phase = GW008_DATA ;
}
else
{
2021-03-17 17:05:42 +01:00
XN297_SetTxRxMode ( TXRX_OFF );
XN297_SetTxRxMode ( TX_EN );
2021-02-11 18:40:29 +01:00
GW008_send_packet ();
2017-02-24 11:00:02 +01:00
phase = GW008_BIND2 ;
2019-08-24 22:14:18 +02:00
return 850 ; // minimum value 750 for STM32
2017-02-24 11:00:02 +01:00
}
break ;
case GW008_BIND2 :
// switch to RX mode
2021-03-17 17:05:42 +01:00
XN297_SetTxRxMode ( TXRX_OFF );
XN297_SetTxRxMode ( RX_EN );
2017-02-24 11:00:02 +01:00
phase = GW008_BIND1 ;
return 5000 ;
case GW008_DATA :
2019-11-11 19:15:39 +01:00
#ifdef MULTI_SYNC
telemetry_set_input_sync ( GW008_PACKET_PERIOD );
#endif
2021-02-11 18:40:29 +01:00
GW008_send_packet ();
2017-02-24 11:00:02 +01:00
break ;
}
return GW008_PACKET_PERIOD ;
}
2021-02-09 18:23:33 +01:00
void GW008_init ()
2017-02-24 11:00:02 +01:00
{
2017-02-24 13:41:32 +01:00
BIND_IN_PROGRESS ; // autobind protocol
2017-02-24 11:00:02 +01:00
GW008_initialize_txid ();
phase = GW008_BIND1 ;
2021-02-09 18:23:33 +01:00
GW008_RF_init ();
2017-02-24 11:00:02 +01:00
hopping_frequency_no = 0 ;
}
#endif