2016-07-27 22:24:48 +02: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/>.
*/
#if defined(J6PRO_CYRF6936_INO)
#include "iface_cyrf6936.h"
enum PktState {
J6PRO_BIND ,
J6PRO_BIND_01 ,
J6PRO_BIND_03_START ,
J6PRO_BIND_03_CHECK ,
J6PRO_BIND_05_1 ,
J6PRO_BIND_05_2 ,
J6PRO_BIND_05_3 ,
J6PRO_BIND_05_4 ,
J6PRO_BIND_05_5 ,
J6PRO_BIND_05_6 ,
J6PRO_CHANSEL ,
J6PRO_CHAN_1 ,
J6PRO_CHAN_2 ,
J6PRO_CHAN_3 ,
J6PRO_CHAN_4 ,
};
2023-11-22 07:57:30 +01:00
const uint8_t j6pro_data_code [] = { 0x02 , 0xf9 , 0x93 , 0x97 , 0x02 , 0xfa , 0x5c , 0xe3 , 0x01 , 0x2b , 0xf1 , 0xdb , 0x01 , 0x32 , 0xbe , 0x6f }; // unneeded since this is the default table after a reset
2016-07-27 22:24:48 +02:00
static void __attribute__ (( unused )) j6pro_build_bind_packet ()
{
packet [ 0 ] = 0x01 ; //Packet type
packet [ 1 ] = 0x01 ; //FIXME: What is this? Model number maybe?
packet [ 2 ] = 0x56 ; //FIXME: What is this?
packet [ 3 ] = cyrfmfg_id [ 0 ];
packet [ 4 ] = cyrfmfg_id [ 1 ];
packet [ 5 ] = cyrfmfg_id [ 2 ];
packet [ 6 ] = cyrfmfg_id [ 3 ];
packet [ 7 ] = cyrfmfg_id [ 4 ];
packet [ 8 ] = cyrfmfg_id [ 5 ];
}
static void __attribute__ (( unused )) j6pro_build_data_packet ()
{
uint8_t i ;
uint32_t upperbits = 0 ;
2016-11-06 15:47:40 +01:00
uint16_t value ;
2016-07-27 22:24:48 +02:00
packet [ 0 ] = 0xaa ; //FIXME what is this?
2016-07-28 15:01:24 +02:00
for ( i = 0 ; i < 12 ; i ++ )
2016-11-06 15:47:40 +01:00
{
2021-01-09 18:39:31 +01:00
value = convert_channel_10b ( CH_AETR [ i ], false );
2016-07-27 22:24:48 +02:00
packet [ i + 1 ] = value & 0xff ;
upperbits |= ( value >> 8 ) << ( i * 2 );
}
packet [ 13 ] = upperbits & 0xff ;
packet [ 14 ] = ( upperbits >> 8 ) & 0xff ;
packet [ 15 ] = ( upperbits >> 16 ) & 0xff ;
}
static void __attribute__ (( unused )) j6pro_cyrf_init ()
{
/* Initialise CYRF chip */
CYRF_WriteRegister ( CYRF_28_CLK_EN , 0x02 );
CYRF_WriteRegister ( CYRF_32_AUTO_CAL_TIME , 0x3c );
CYRF_WriteRegister ( CYRF_35_AUTOCAL_OFFSET , 0x14 );
CYRF_WriteRegister ( CYRF_1C_TX_OFFSET_MSB , 0x05 );
CYRF_WriteRegister ( CYRF_1B_TX_OFFSET_LSB , 0x55 );
2016-11-06 15:47:40 +01:00
//CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24);
//CYRF_SetPower(0x05);
CYRF_WriteRegister ( CYRF_06_RX_CFG , 0x4a );
2016-07-27 22:24:48 +02:00
CYRF_SetPower ( 0x28 );
CYRF_WriteRegister ( CYRF_12_DATA64_THOLD , 0x0e );
CYRF_WriteRegister ( CYRF_10_FRAMING_CFG , 0xee );
CYRF_WriteRegister ( CYRF_1F_TX_OVERRIDE , 0x00 );
CYRF_WriteRegister ( CYRF_1E_RX_OVERRIDE , 0x00 );
2023-11-22 07:57:30 +01:00
//Same as default reset but issues if not configured...
2023-12-01 10:58:56 +01:00
CYRF_ConfigDataCode ( j6pro_data_code );
2016-11-06 15:47:40 +01:00
CYRF_WritePreamble ( 0x333302 );
2016-07-27 22:24:48 +02:00
CYRF_GetMfgData ( cyrfmfg_id );
//Model match
cyrfmfg_id [ 3 ] += RX_num ;
}
static void __attribute__ (( unused )) cyrf_bindinit ()
{
2016-11-06 15:47:40 +01:00
/* Use when binding */
CYRF_SetPower ( 0x28 ); //Deviation using max power, replaced by bind power...
//CYRF_ConfigRFChannel(0x52);
2024-05-04 11:34:59 +02:00
CYRF_PROGMEM_ConfigSOPCode ( DEVO_j6pro_sopcodes [ 19 ]);
2016-11-06 15:47:40 +01:00
CYRF_ConfigCRCSeed ( 0x0000 );
//CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a);
//CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80);
//CYRF_ConfigRFChannel(0x52);
//CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24);
//CYRF_WriteRegister(CYRF_02_TX_CTRL, 0x40);
j6pro_build_bind_packet ();
2016-07-27 22:24:48 +02:00
}
static void __attribute__ (( unused )) cyrf_datainit ()
{
2016-11-06 15:47:40 +01:00
/* Use when already bound */
uint8_t sop_idx = ( 0xff & ( cyrfmfg_id [ 0 ] + cyrfmfg_id [ 1 ] + cyrfmfg_id [ 2 ] + cyrfmfg_id [ 3 ] - cyrfmfg_id [ 5 ])) % 19 ;
2021-01-16 16:50:45 +01:00
crc = ( 0xff & ( cyrfmfg_id [ 1 ] - cyrfmfg_id [ 4 ] + cyrfmfg_id [ 5 ])) |
(( 0xff & ( cyrfmfg_id [ 2 ] + cyrfmfg_id [ 3 ] - cyrfmfg_id [ 4 ] + cyrfmfg_id [ 5 ])) << 8 );
2016-11-06 15:47:40 +01:00
//CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24);
CYRF_PROGMEM_ConfigSOPCode ( DEVO_j6pro_sopcodes [ sop_idx ]);
CYRF_ConfigCRCSeed ( crc );
2016-07-27 22:24:48 +02:00
}
static void __attribute__ (( unused )) j6pro_set_radio_channels ()
{
//FIXME: Query free channels
//lowest channel is 0x08, upper channel is 0x4d?
2024-03-25 15:11:31 +01:00
CYRF_FindBestChannels ( hopping_frequency , 3 , 5 , 8 , 77 , FIND_CHANNEL_ANY );
2016-07-28 15:01:24 +02:00
hopping_frequency [ 3 ] = hopping_frequency [ 0 ];
2016-07-27 22:24:48 +02:00
}
2021-02-09 18:23:33 +01:00
uint16_t J6PRO_callback ()
2016-07-27 22:24:48 +02:00
{
2018-08-21 14:58:44 +02:00
uint16_t start ;
2016-07-27 22:24:48 +02:00
2016-07-28 15:01:24 +02:00
switch ( phase )
2016-11-06 15:47:40 +01:00
{
2016-07-27 22:24:48 +02:00
case J6PRO_BIND :
cyrf_bindinit ();
phase = J6PRO_BIND_01 ;
//no break because we want to send the 1st bind packet now
case J6PRO_BIND_01 :
CYRF_ConfigRFChannel ( 0x52 );
CYRF_SetTxRxMode ( TX_EN );
2016-11-06 15:47:40 +01:00
//CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24);
2016-07-27 22:24:48 +02:00
CYRF_WriteDataPacketLen ( packet , 0x09 );
phase = J6PRO_BIND_03_START ;
return 3000 ; //3msec
case J6PRO_BIND_03_START :
2018-08-21 14:58:44 +02:00
start = ( uint16_t ) micros ();
while (( uint16_t )(( uint16_t ) micros () - ( uint16_t ) start ) < 500 ) // Wait max 500µs
if (( CYRF_ReadRegister ( CYRF_02_TX_CTRL ) & 0x80 ) == 0x00 )
break ; // Packet transmission complete
CYRF_ConfigRFChannel ( 0x53 );
2016-07-27 22:24:48 +02:00
CYRF_SetTxRxMode ( RX_EN );
2016-11-06 15:47:40 +01:00
//CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a);
CYRF_WriteRegister ( CYRF_05_RX_CTRL , 0x80 );
2016-07-27 22:24:48 +02:00
phase = J6PRO_BIND_03_CHECK ;
return 30000 ; //30msec
case J6PRO_BIND_03_CHECK :
{
uint8_t rx = CYRF_ReadRegister ( CYRF_07_RX_IRQ_STATUS );
if (( rx & 0x1a ) == 0x1a ) {
rx = CYRF_ReadRegister ( CYRF_0A_RX_LENGTH );
if ( rx == 0x0f ) {
rx = CYRF_ReadRegister ( CYRF_09_RX_COUNT );
if ( rx == 0x0f ) {
//Expected and actual length are both 15
CYRF_ReadDataPacketLen ( packet , rx );
if ( packet [ 0 ] == 0x03 &&
packet [ 3 ] == cyrfmfg_id [ 0 ] &&
packet [ 4 ] == cyrfmfg_id [ 1 ] &&
packet [ 5 ] == cyrfmfg_id [ 2 ] &&
packet [ 6 ] == cyrfmfg_id [ 3 ] &&
packet [ 7 ] == cyrfmfg_id [ 4 ] &&
packet [ 8 ] == cyrfmfg_id [ 5 ])
{
//Send back Ack
packet [ 0 ] = 0x05 ;
CYRF_ConfigRFChannel ( 0x54 );
CYRF_SetTxRxMode ( TX_EN );
phase = J6PRO_BIND_05_1 ;
return 2000 ; //2msec
}
}
}
}
phase = J6PRO_BIND_01 ;
return 500 ;
}
case J6PRO_BIND_05_1 :
case J6PRO_BIND_05_2 :
case J6PRO_BIND_05_3 :
case J6PRO_BIND_05_4 :
case J6PRO_BIND_05_5 :
case J6PRO_BIND_05_6 :
2016-11-06 15:47:40 +01:00
//CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24);
2016-07-27 22:24:48 +02:00
CYRF_WriteDataPacketLen ( packet , 0x0f );
phase = phase + 1 ;
return 4600 ; //4.6msec
case J6PRO_CHANSEL :
BIND_DONE ;
j6pro_set_radio_channels ();
cyrf_datainit ();
phase = J6PRO_CHAN_1 ;
case J6PRO_CHAN_1 :
2019-11-11 19:15:39 +01:00
#ifdef MULTI_SYNC
telemetry_set_input_sync ( 24550 );
#endif
2019-10-10 23:12:09 +02:00
//Keep transmit power updated
2016-11-06 15:47:40 +01:00
CYRF_SetPower ( 0x28 );
2016-07-27 22:24:48 +02:00
j6pro_build_data_packet ();
//return 3400;
case J6PRO_CHAN_2 :
//return 3500;
case J6PRO_CHAN_3 :
//return 3750
case J6PRO_CHAN_4 :
2016-07-28 15:01:24 +02:00
CYRF_ConfigRFChannel ( hopping_frequency [ phase - J6PRO_CHAN_1 ]);
2016-07-27 22:24:48 +02:00
CYRF_SetTxRxMode ( TX_EN );
CYRF_WriteDataPacket ( packet );
if ( phase == J6PRO_CHAN_4 ) {
phase = J6PRO_CHAN_1 ;
return 13900 ;
}
phase = phase + 1 ;
return 3550 ;
}
return 0 ;
}
2021-02-09 18:23:33 +01:00
void J6PRO_init ()
2016-07-27 22:24:48 +02:00
{
j6pro_cyrf_init ();
2018-01-03 13:04:58 +01:00
if ( IS_BIND_IN_PROGRESS )
2016-07-27 22:24:48 +02:00
phase = J6PRO_BIND ;
2016-11-06 15:47:40 +01:00
else
2016-07-27 22:24:48 +02:00
phase = J6PRO_CHANSEL ;
}
#endif