2021-01-16 15:45:19 +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/>.
*/
#if defined(E129_CYRF6936_INO)
#include "iface_rf2500.h"
//#define E129_FORCE_ID
2022-06-27 16:59:48 +02:00
//#define C186_FORCE_ID
2021-01-16 15:45:19 +01:00
#define E129_BIND_CH 0x2D //45
#define E129_PAYLOAD_SIZE 16
2022-06-27 16:59:48 +02:00
#define C186_PAYLOAD_SIZE 19
2021-01-16 15:45:19 +01:00
static void __attribute__ (( unused )) E129_build_data_packet ()
{
//Build the packet
2022-06-27 16:59:48 +02:00
memset ( packet , 0 , packet_length );
packet [ 0 ] = packet_length - 1 ; // Packet length
2021-01-16 15:45:19 +01:00
if ( IS_BIND_IN_PROGRESS )
{
packet [ 1 ] = 0xA4 ;
packet [ 2 ] = bit_reverse ( rx_tx_addr [ 2 ]);
packet [ 3 ] = bit_reverse ( rx_tx_addr [ 3 ]);
packet [ 4 ] = bit_reverse ( rx_tx_addr [ 0 ]);
packet [ 5 ] = bit_reverse ( rx_tx_addr [ 1 ]);
for ( uint8_t i = 0 ; i < 4 ; i ++ )
packet [ 6 + i ] = hopping_frequency [ i ] - 2 ;
}
else
{
2024-07-11 16:20:32 +02:00
packet [ 1 ] = 0xA6 ; // Set to A5 every few packets??
2022-06-27 16:59:48 +02:00
//Flags
2026-07-14 18:44:41 +02:00
packet [ 2 ] = 0xF7 ; // E129 High rate 0xF7, low 0xF4
if ( sub_protocol == E129_C186 )
2022-06-27 16:59:48 +02:00
{
packet [ 2 ] = 0xFA ; // High rate 0xFA, medium 0xF7, low 0xF4
packet [ 13 ] = bit_reverse ( rx_tx_addr [ 2 ]);
packet [ 14 ] = bit_reverse ( rx_tx_addr [ 3 ]);
packet [ 15 ] = bit_reverse ( rx_tx_addr [ 0 ]);
packet [ 16 ] = bit_reverse ( rx_tx_addr [ 1 ]);
}
2024-07-11 16:20:32 +02:00
packet [ 3 ] = GET_FLAG ( CH10_SW , 0x40 ) // C159: loop flight 0x40
| GET_FLAG ( CH11_SW , 0x08 ); // C129V2: flip
//Other flags seen in packet[3]
// Flag 0x04 is set on some helis (C159/C190)
// E129 Mode: short press=0x20->0x00->0x20->..., long press=0x10->0x30->0x10->... => C186 throttle trim is doing the same:up=short press and down=long press
2023-10-23 11:24:37 +02:00
packet [ 4 ] = GET_FLAG ( CH5_SW , 0x20 ) // Take off/Land 0x20
2024-07-11 16:20:32 +02:00
| GET_FLAG ( CH6_SW , 0x04 ) // Emergency stop 0x04
| GET_FLAG ( CH12_SW , 0x80 ); // C190: debug mode->remote THR trim down sets 0x80
//Other flags seen in packet[4]
// C190 remote LANDING sets 0x10
// C190 remote THR trim down sets 0x80
2022-06-27 16:59:48 +02:00
//Channels and trims
2021-01-16 15:45:19 +01:00
uint16_t val = convert_channel_10b ( AILERON , false );
uint8_t trim = convert_channel_8b ( CH7 ) & 0xFC ;
packet [ 5 ] = trim | ( val >> 8 ); // Trim (0x00..0x1F..0x3E) << 2 | channel >> 8
packet [ 6 ] = val ; // channel (0x000...0x200...0x3FF)
val = convert_channel_10b ( ELEVATOR , false );
trim = convert_channel_8b ( CH8 ) & 0xFC ;
2021-02-21 16:05:25 +01:00
packet [ 7 ] = trim | ( val >> 8 ); // Trim (0x00..0x1F..0x3E) << 2 | channel >> 8
2021-01-16 15:45:19 +01:00
packet [ 8 ] = val ; // channel (0x000...0x200...0x3FF)
if ( packet_count > 200 )
val = convert_channel_10b ( THROTTLE , false );
else
{ //Allow bind to complete with throttle not centered
packet_count ++ ;
val = 0x200 ;
}
packet [ 9 ] = ( 0x1F << 2 ) | ( val >> 8 ); // Trim (0x00..0x1F..0x3E) << 2 | channel >> 8
packet [ 10 ] = val ; // channel (0x000...0x200...0x3FF)
val = convert_channel_10b ( RUDDER , false );
trim = convert_channel_8b ( CH9 ) & 0xFC ;
packet [ 11 ] = trim | ( val >> 8 ); // Trim (0x00..0x1F..0x3E) << 2 | channel >> 8
packet [ 12 ] = val ; // channel (0x000...0x200...0x3FF)
}
2022-06-27 16:59:48 +02:00
//Check
2023-10-23 11:24:37 +02:00
for ( uint8_t i = 0 ; i < packet_length - 2 ; i ++ )
2022-06-27 16:59:48 +02:00
packet [ packet_length - 2 ] += packet [ i ];
2023-10-23 11:24:37 +02:00
if ( sub_protocol == E129_C186 )
packet [ packet_length - 2 ] -= 0x80 ;
2021-01-16 15:45:19 +01:00
RF2500_BuildPayload ( packet );
}
2021-02-09 18:23:33 +01:00
uint16_t E129_callback ()
2021-01-16 15:45:19 +01:00
{
//Set RF channel
if ( phase == 0 )
RF2500_RFChannel ( IS_BIND_IN_PROGRESS ? E129_BIND_CH : hopping_frequency [ hopping_frequency_no ]);
//Send packet
RF2500_SendPayload ();
2022-06-27 16:59:48 +02:00
//E129 sends twice on same channel, not the C186 but there is a bug somewhere if I don't send the packets back to back
2021-01-16 15:45:19 +01:00
if ( phase == 0 )
{
phase ++ ;
return 1260 ;
}
//Bind
if ( bind_counter )
2021-02-12 11:21:42 +01:00
if ( -- bind_counter == 0 )
2021-01-16 15:45:19 +01:00
{
BIND_DONE ;
RF2500_SetTXAddr ( rx_tx_addr ); // 4 bytes of address
}
//Build packet
E129_build_data_packet ();
//Set power
RF2500_SetPower ();
//Hopp
hopping_frequency_no ++ ;
hopping_frequency_no &= 3 ;
phase = 0 ;
2022-06-27 16:59:48 +02:00
if ( sub_protocol == E129_E129 )
return 5200 - 1260 ;
return 5500 - 1260 ; //E129_C186
2021-01-16 15:45:19 +01:00
}
2021-02-09 18:23:33 +01:00
void E129_init ()
2021-01-16 15:45:19 +01:00
{
BIND_IN_PROGRESS ; // Autobind protocol
bind_counter = 384 ; // ~2sec
2022-06-27 16:59:48 +02:00
//RF2500 emu init
packet_length = sub_protocol == E129_E129 ? E129_PAYLOAD_SIZE : C186_PAYLOAD_SIZE ;
RF2500_Init ( packet_length , true ); // 16/19 bytes, Scrambled
2021-01-16 15:45:19 +01:00
//Freq hopping
calc_fh_channels ( 4 );
for ( uint8_t i = 0 ; i < 4 ; i ++ )
if ( hopping_frequency [ i ] == E129_BIND_CH )
hopping_frequency [ i ] ++ ;
#ifdef E129_FORCE_ID
rx_tx_addr [ 0 ] = 0xC1 ;
rx_tx_addr [ 1 ] = 0x22 ;
rx_tx_addr [ 2 ] = 0x05 ;
rx_tx_addr [ 3 ] = 0xA3 ;
hopping_frequency [ 0 ] = 0x3C ; //60
hopping_frequency [ 1 ] = 0x49 ; //73
hopping_frequency [ 2 ] = 0x4B ; //75
hopping_frequency [ 3 ] = 0x41 ; //65
#endif
2022-06-27 16:59:48 +02:00
#ifdef C186_FORCE_ID
rx_tx_addr [ 0 ] = 0x91 ;
rx_tx_addr [ 1 ] = 0x02 ;
rx_tx_addr [ 2 ] = 0x5D ;
rx_tx_addr [ 3 ] = 0x33 ;
hopping_frequency [ 0 ] = 0x44 + 2 ;
hopping_frequency [ 1 ] = 0x41 + 2 ;
hopping_frequency [ 2 ] = 0x43 + 2 ;
hopping_frequency [ 3 ] = 0x49 + 2 ;
#endif
2021-01-16 15:45:19 +01:00
RF2500_SetTXAddr (( uint8_t * ) " \xE2\x32\xE0\xC8 " ); // 4 bytes of bind address
E129_build_data_packet ();
hopping_frequency_no = 0 ;
packet_count = 0 ;
phase = 0 ;
}
#endif