184 lines
5.3 KiB
Arduino
Raw Normal View History

/*
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 JJRC345
#if defined(JJRC345_NRF24L01_INO)
#include "iface_nrf24l01.h"
2020-05-22 21:03:01 +02:00
//#define JJRC345_FORCE_ID
#define JJRC345_PACKET_PERIOD 7450 // Timeout for callback in uSec
#define JJRC345_INITIAL_WAIT 500
#define JJRC345_PACKET_SIZE 16
#define JJRC345_RF_BIND_CHANNEL 5
2020-10-30 12:01:40 +01:00
#define SKYTMBLR_RF_BIND_CHANNEL 40
#define JJRC345_BIND_COUNT 500
#define JJRC345_NUM_CHANNELS 4
enum JJRC345_FLAGS {
// flags going to packet[8]
JJRC345_FLAG_HEADLESS = 0x40,
2020-05-21 17:49:04 +02:00
JJRC345_FLAG_RTH = 0x80,
2020-10-30 12:01:40 +01:00
// flags going to packet[9]
SKYTMBLR_FLAG_UNK1 = 0x40,
SKYTMBLR_FLAG_UNK2 = 0x80,
// flags going to packet[10]
SKYTMBLR_FLAG_LED = 0x40,
SKYTMBLR_FLAG_UNK3 = 0x80,
};
static uint8_t __attribute__((unused)) JJRC345_convert_channel(uint8_t num)
{
uint8_t val=convert_channel_8b(num);
2020-05-22 21:03:01 +02:00
// 7E..60..41..01, 80 center, 81..C1..E0..FE
2020-05-21 11:56:08 +02:00
if(val<0x80)
{
val=0x80-val; // 80..01
2020-05-22 21:03:01 +02:00
if(val>0x7E)
val=0x7E; // 7E..01
2020-05-21 11:56:08 +02:00
}
2020-05-22 21:03:01 +02:00
else if(val>0xFE)
val=0xFE; // 81..FE
return val;
}
static void __attribute__((unused)) JJRC345_send_packet()
{
packet[0] = 0x00;
packet[2] = 0x00;
if (IS_BIND_IN_PROGRESS)
{ //00 05 00 0A 46 4A 41 47 00 00 40 46 A5 4A F1 18
2020-10-30 12:01:40 +01:00
packet[1] = (sub_protocol == JJRC345 ? JJRC345_RF_BIND_CHANNEL:SKYTMBLR_RF_BIND_CHANNEL);
packet[4] = hopping_frequency[0];
packet[5] = hopping_frequency[1];
packet[6] = hopping_frequency[2];
packet[7] = hopping_frequency[3];
packet[12] = 0xa5;
}
else
{ //00 41 00 0A 00 80 80 80 00 00 40 46 00 49 F1 18
XN297_Hopping(hopping_frequency_no);
2020-05-21 17:24:11 +02:00
hopping_frequency_no++;
hopping_frequency_no %= JJRC345_NUM_CHANNELS;
packet[1] = hopping_frequency[hopping_frequency_no]; // next packet will be sent on this channel
packet[4] = convert_channel_8b(THROTTLE); // throttle: 00..FF
packet[5] = JJRC345_convert_channel(RUDDER); // rudder: 70..60..41..01, 80 center, 81..C1..E0..F0
packet[6] = JJRC345_convert_channel(ELEVATOR); // elevator: 70..60..41..01, 80 center, 81..C1..E0..F0
packet[7] = JJRC345_convert_channel(AILERON); // aileron: 70..60..41..01, 80 center, 81..C1..E0..F0
2020-05-21 17:24:11 +02:00
if(CH5_SW) //Flip
{
if(packet[6]>0xF0)
2020-05-21 17:24:11 +02:00
packet[6]=0xFF;
else if(packet[6]<0x80 && packet[6]>0x70)
2020-05-21 17:24:11 +02:00
packet[6]=0x7F;
if(packet[7]>0xF0)
2020-05-21 17:24:11 +02:00
packet[7]=0xFF;
else if(packet[7]<0x80 && packet[7]>0x70)
2020-05-21 17:24:11 +02:00
packet[7]=0x7F;
}
packet[12] = 0x02; // Rate: 00-01-02
}
2020-05-22 21:03:01 +02:00
packet[3] = 0x00; // Checksum upper bits
2020-05-21 17:49:04 +02:00
packet[8] = 0x00 // Rudder trim, 00 when not used, 01..1F when trimmed left, 20..3F
2020-10-30 12:01:40 +01:00
| GET_FLAG(CH6_SW ,JJRC345_FLAG_HEADLESS) // 0x40 HeadLess
| GET_FLAG(CH7_SW ,JJRC345_FLAG_RTH); // 0x80 RTH
packet[9] = 0x00 // Elevator trim, 00 when not used, 20..25 when trimmed up, 0..1F when trimmed down
| GET_FLAG(CH9_SW ,SKYTMBLR_FLAG_UNK1) // 0x40 Unknown
| GET_FLAG(CH10_SW,SKYTMBLR_FLAG_UNK2); // 0x80 Unknown
packet[10] = 0x00 // Aileron trim, 00 when not used, 00..1F when trimmed left, 21..3F when trimmed right
| GET_FLAG(!CH8_SW,SKYTMBLR_FLAG_LED) // 0x40 LED
| GET_FLAG(CH11_SW,SKYTMBLR_FLAG_UNK3); // 0x80 Unknown
packet[11] = hopping_frequency[0]; // First hopping frequency
// Checksum
2020-05-22 21:03:01 +02:00
uint16_t sum=2;
for (uint8_t i = 0; i < 13; i++)
2020-05-22 21:03:01 +02:00
sum += packet[i];
packet[13]=sum;
packet[3]=((sum>>8)<<2)+2;
2020-05-21 17:24:11 +02:00
// TX ID
packet[14] = rx_tx_addr[2];
packet[15] = rx_tx_addr[3];
// Send
XN297_SetPower();
XN297_SetTxRxMode(TX_EN);
XN297_WritePayload(packet, JJRC345_PACKET_SIZE);
}
2021-02-09 18:23:33 +01:00
static void __attribute__((unused)) JJRC345_RF_init()
{
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
XN297_SetTXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5);
//XN297_HoppingCalib(JJRC345_NUM_CHANNELS);
XN297_RFChannel(sub_protocol == JJRC345 ? JJRC345_RF_BIND_CHANNEL:SKYTMBLR_RF_BIND_CHANNEL); // Bind channel
}
uint16_t JJRC345_callback()
{
#ifdef MULTI_SYNC
telemetry_set_input_sync(JJRC345_PACKET_PERIOD);
#endif
2021-02-12 11:21:42 +01:00
if(bind_counter)
{
2021-02-12 11:21:42 +01:00
bind_counter--;
if (bind_counter==0)
BIND_DONE;
}
JJRC345_send_packet();
return JJRC345_PACKET_PERIOD;
}
static void __attribute__((unused)) JJRC345_initialize_txid()
{
2020-05-26 22:26:30 +02:00
calc_fh_channels(JJRC345_NUM_CHANNELS);
#ifdef JJRC345_FORCE_ID
//TX 1
rx_tx_addr[2]=0x1B;
rx_tx_addr[3]=0x12;
hopping_frequency[0] = 0x3f;
hopping_frequency[1] = 0x49;
hopping_frequency[2] = 0x47;
hopping_frequency[3] = 0x47;
//TX 2
rx_tx_addr[2]=0xF1;
rx_tx_addr[3]=0x18;
hopping_frequency[0] = 0x46;
hopping_frequency[1] = 0x4A;
hopping_frequency[2] = 0x41;
hopping_frequency[3] = 0x47;
#endif
}
2021-02-09 18:23:33 +01:00
void JJRC345_init(void)
{
BIND_IN_PROGRESS; // autobind protocol
bind_counter = JJRC345_BIND_COUNT;
JJRC345_initialize_txid();
2021-02-09 18:23:33 +01:00
JJRC345_RF_init();
}
#endif