mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-12-13 19:13:14 +00:00
New protocol: E129
This commit is contained in:
@@ -15,115 +15,40 @@
|
||||
|
||||
#if defined(E010R5_CYRF6936_INO)
|
||||
|
||||
#include "iface_cyrf6936.h"
|
||||
#include "iface_rf2500.h"
|
||||
|
||||
#define E010R5_FORCE_ID
|
||||
|
||||
#define E010R5_BIND_CH 0x2D //45
|
||||
#define E010R5_PAYLOAD_SIZE 14
|
||||
|
||||
|
||||
static void __attribute__((unused)) E010R5_build_data_packet()
|
||||
{
|
||||
uint8_t buf[16];
|
||||
|
||||
//Build the packet
|
||||
buf[ 0] = 0x0D; // Packet length
|
||||
buf[ 1] = convert_channel_8b(THROTTLE);
|
||||
buf[ 2] = convert_channel_s8b(RUDDER);
|
||||
buf[ 3] = convert_channel_s8b(ELEVATOR);
|
||||
buf[ 4] = convert_channel_s8b(AILERON);
|
||||
buf[ 5] = 0x20; // Trim Rudder
|
||||
buf[ 6] = 0x20; // Trim Elevator
|
||||
buf[ 7] = 0x20; // Trim Aileron
|
||||
buf[ 8] = 0x01 // Flags: high=0x01, low=0x00
|
||||
packet[ 0] = 0x0D; // Packet length
|
||||
packet[ 1] = convert_channel_8b(THROTTLE);
|
||||
packet[ 2] = convert_channel_s8b(RUDDER);
|
||||
packet[ 3] = convert_channel_s8b(ELEVATOR);
|
||||
packet[ 4] = convert_channel_s8b(AILERON);
|
||||
packet[ 5] = 0x20; // Trim Rudder
|
||||
packet[ 6] = 0x20; // Trim Elevator
|
||||
packet[ 7] = 0x20; // Trim Aileron
|
||||
packet[ 8] = 0x01 // Flags: high=0x01, low=0x00
|
||||
| GET_FLAG(CH5_SW, 0x04) // flip=0x04
|
||||
| GET_FLAG(CH6_SW, 0x08) // led=0x08
|
||||
| GET_FLAG(CH8_SW, 0x10) // headless=0x10
|
||||
| GET_FLAG(CH9_SW, 0x20); // one key return=0x20
|
||||
buf[ 9] = IS_BIND_IN_PROGRESS ? 0x80 : 0x00 // Flags: bind=0x80
|
||||
packet[ 9] = IS_BIND_IN_PROGRESS ? 0x80 : 0x00 // Flags: bind=0x80
|
||||
| GET_FLAG(CH7_SW, 0x20) // calib=0x20
|
||||
| GET_FLAG(CH10_SW, 0x01); // strange effect=0x01=long press on right button
|
||||
buf[10] = rx_tx_addr[0];
|
||||
buf[11] = rx_tx_addr[1];
|
||||
buf[12] = rx_tx_addr[2];
|
||||
buf[13] = 0x9D; // Check
|
||||
packet[10] = rx_tx_addr[0];
|
||||
packet[11] = rx_tx_addr[1];
|
||||
packet[12] = rx_tx_addr[2];
|
||||
packet[13] = 0x9D; // Check
|
||||
for(uint8_t i=0;i<13;i++)
|
||||
buf[13] += buf[i];
|
||||
packet[13] += packet[i];
|
||||
|
||||
//Add CRC
|
||||
crc=0x00;
|
||||
for(uint8_t i=0;i<14;i++)
|
||||
crc16_update(bit_reverse(buf[i]),8);
|
||||
buf[14] = bit_reverse(crc>>8);
|
||||
buf[15] = bit_reverse(crc);
|
||||
|
||||
#if 0
|
||||
debug("B:");
|
||||
for(uint8_t i=0; i<16; i++)
|
||||
debug(" %02X",buf[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
|
||||
//Build the payload
|
||||
memcpy(packet,"\x0E\x54\x96\xEE\xC3\xC3",6); // 4 bytes of address followed by 5 FEC encoded
|
||||
memset(&packet[6],0x00,70-6);
|
||||
|
||||
//FEC encode
|
||||
for(uint8_t i=0; i<16; i++)
|
||||
{
|
||||
for(uint8_t j=0;j<8;j++)
|
||||
{
|
||||
uint8_t offset=6 + (i<<2) + (j>>1);
|
||||
packet[offset] <<= 4;
|
||||
if( (buf[i]>>j) & 0x01 )
|
||||
packet[offset] |= 0x0C;
|
||||
else
|
||||
packet[offset] |= 0x03;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
debug("E:");
|
||||
for(uint8_t i=0; i<70; i++)
|
||||
debug(" %02X",packet[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
|
||||
//CYRF wants LSB first
|
||||
for(uint8_t i=0;i<71;i++)
|
||||
packet[i]=bit_reverse(packet[i]);
|
||||
}
|
||||
|
||||
const uint8_t PROGMEM E010R5_init_vals[][2] = {
|
||||
{CYRF_02_TX_CTRL, 0x00}, // transmit err & complete interrupts disabled
|
||||
{CYRF_05_RX_CTRL, 0x00}, // receive err & complete interrupts disabled
|
||||
{CYRF_28_CLK_EN, 0x02}, // Force Receive Clock Enable, MUST be set
|
||||
{CYRF_32_AUTO_CAL_TIME, 0x3c}, // must be set to 3C
|
||||
{CYRF_35_AUTOCAL_OFFSET, 0x14}, // must be set to 14
|
||||
{CYRF_06_RX_CFG, 0x48}, // LNA manual control, Rx Fast Turn Mode Enable
|
||||
{CYRF_1B_TX_OFFSET_LSB, 0x00}, // Tx frequency offset LSB
|
||||
{CYRF_1C_TX_OFFSET_MSB, 0x00}, // Tx frequency offset MSB
|
||||
{CYRF_0F_XACT_CFG, 0x24}, // Force End State, transaction end state = idle
|
||||
{CYRF_03_TX_CFG, 0x00}, // GFSK mode
|
||||
{CYRF_12_DATA64_THOLD, 0x0a}, // 64 Chip Data PN Code Correlator Threshold = 10
|
||||
{CYRF_0F_XACT_CFG, 0x04}, // Transaction End State = idle
|
||||
{CYRF_39_ANALOG_CTRL, 0x01}, // synth setting time for all channels is the same as for slow channels
|
||||
{CYRF_0F_XACT_CFG, 0x24}, //Force IDLE
|
||||
{CYRF_29_RX_ABORT, 0x00}, //Clear RX abort
|
||||
{CYRF_12_DATA64_THOLD, 0x0a}, //set pn correlation threshold
|
||||
{CYRF_10_FRAMING_CFG, 0x4a}, //set sop len and threshold
|
||||
{CYRF_29_RX_ABORT, 0x0f}, //Clear RX abort?
|
||||
{CYRF_03_TX_CFG, 0x00}, // GFSK mode
|
||||
{CYRF_10_FRAMING_CFG, 0x4a}, // 0b11000000 //set sop len and threshold
|
||||
{CYRF_1F_TX_OVERRIDE, 0x04}, //disable tx CRC
|
||||
{CYRF_1E_RX_OVERRIDE, 0x14}, //disable rx crc
|
||||
{CYRF_14_EOP_CTRL, 0x00}, //set EOP sync == 0
|
||||
{CYRF_01_TX_LENGTH, 70 }, // payload length
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) E010R5_cyrf_init()
|
||||
{
|
||||
for(uint8_t i = 0; i < sizeof(E010R5_init_vals) / 2; i++)
|
||||
CYRF_WriteRegister(pgm_read_byte_near(&E010R5_init_vals[i][0]), pgm_read_byte_near(&E010R5_init_vals[i][1]));
|
||||
CYRF_WritePreamble(0xAAAA02);
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
RF2500_BuildPayload(packet);
|
||||
}
|
||||
|
||||
uint16_t ReadE010R5()
|
||||
@@ -136,20 +61,8 @@ uint16_t ReadE010R5()
|
||||
BIND_DONE;
|
||||
}
|
||||
|
||||
//Send packet of 71 bytes...
|
||||
uint8_t *buffer=packet;
|
||||
CYRF_WriteRegister(CYRF_02_TX_CTRL, 0x40);
|
||||
CYRF_WriteRegisterMulti(CYRF_20_TX_BUFFER, buffer, 16);
|
||||
CYRF_WriteRegister(CYRF_02_TX_CTRL, 0x80);
|
||||
buffer+=16;
|
||||
for(uint8_t i=0;i<6;i++)
|
||||
{
|
||||
while((CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS)&0x10) == 0);
|
||||
CYRF_WriteRegisterMulti(CYRF_20_TX_BUFFER, buffer, 8);
|
||||
buffer+=8;
|
||||
}
|
||||
while((CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS)&0x10) == 0);
|
||||
CYRF_WriteRegisterMulti(CYRF_20_TX_BUFFER, buffer, 6);
|
||||
//Send packet
|
||||
RF2500_SendPayload();
|
||||
|
||||
//Timing and hopping
|
||||
packet_count++;
|
||||
@@ -167,9 +80,8 @@ uint16_t ReadE010R5()
|
||||
rf_ch_num = 0x30 + (hopping_frequency_no<<3);
|
||||
else
|
||||
rf_ch_num = hopping_frequency[hopping_frequency_no];
|
||||
CYRF_ConfigRFChannel(rf_ch_num);
|
||||
debugln("%d",hopping_frequency[hopping_frequency_no]);
|
||||
CYRF_SetPower(0x00);
|
||||
RF2500_RFChannel(rf_ch_num);
|
||||
RF2500_SetPower();
|
||||
packet_count = 0;
|
||||
case 3:
|
||||
E010R5_build_data_packet();
|
||||
@@ -180,11 +92,13 @@ uint16_t ReadE010R5()
|
||||
|
||||
uint16_t initE010R5()
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
BIND_IN_PROGRESS; // Autobind protocol
|
||||
bind_counter = 2600;
|
||||
|
||||
E010R5_cyrf_init();
|
||||
|
||||
//RF2500 emu init
|
||||
RF2500_Init(E010R5_PAYLOAD_SIZE, false); // 14 bytes, not scrambled
|
||||
RF2500_SetTXAddr((uint8_t*)"\x0E\x54\x96\xEE"); // Same address for bind and normal packets
|
||||
|
||||
#ifdef E010R5_FORCE_ID
|
||||
hopping_frequency[0]=0x30; //48
|
||||
hopping_frequency[1]=0x45; //69
|
||||
@@ -196,7 +110,7 @@ uint16_t initE010R5()
|
||||
#endif
|
||||
|
||||
E010R5_build_data_packet();
|
||||
CYRF_ConfigRFChannel(hopping_frequency[0]);
|
||||
RF2500_RFChannel(hopping_frequency[0]);
|
||||
hopping_frequency_no=0;
|
||||
packet_count=0;
|
||||
|
||||
|
||||
152
Multiprotocol/E129_cyrf6936.ino
Normal file
152
Multiprotocol/E129_cyrf6936.ino
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
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
|
||||
|
||||
#define E129_BIND_CH 0x2D //45
|
||||
#define E129_PAYLOAD_SIZE 16
|
||||
|
||||
static void __attribute__((unused)) E129_build_data_packet()
|
||||
{
|
||||
//Build the packet
|
||||
memset(packet,0,E129_PAYLOAD_SIZE);
|
||||
packet[ 0] = 0x0F; // Packet length
|
||||
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
|
||||
{
|
||||
packet[ 1] = 0xA6;
|
||||
packet[ 2] = 0xF7; // High rate 0xF7, low rate 0xF4
|
||||
//packet[ 3] = 0x00; // Mode: short press=0x20->0x00->0x20->..., long press=0x10->0x30->0x10->...
|
||||
packet[ 4] = GET_FLAG(CH5_SW, 0x20) // Take off/Land 0x20
|
||||
| GET_FLAG(CH6_SW, 0x04); // Emergency stop 0x04
|
||||
|
||||
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;
|
||||
packet[ 7] = trim | (val >>8); // Trim (0x00..0x1F..0x3E) << 2 | channel >> 8
|
||||
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)
|
||||
}
|
||||
packet[14] = 0x00; // Check
|
||||
for(uint8_t i=0;i<14;i++)
|
||||
packet[14] += packet[i];
|
||||
|
||||
RF2500_BuildPayload(packet);
|
||||
}
|
||||
|
||||
uint16_t ReadE129()
|
||||
{
|
||||
//Set RF channel
|
||||
if(phase==0)
|
||||
RF2500_RFChannel(IS_BIND_IN_PROGRESS ? E129_BIND_CH : hopping_frequency[hopping_frequency_no]);
|
||||
|
||||
//Send packet
|
||||
RF2500_SendPayload();
|
||||
|
||||
//Send twice on same channel
|
||||
if(phase==0)
|
||||
{
|
||||
phase++;
|
||||
return 1260;
|
||||
}
|
||||
|
||||
//Bind
|
||||
if(bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
if(bind_counter==0)
|
||||
{
|
||||
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;
|
||||
return 5200-1260;
|
||||
}
|
||||
|
||||
uint16_t initE129()
|
||||
{
|
||||
BIND_IN_PROGRESS; // Autobind protocol
|
||||
bind_counter = 384; // ~2sec
|
||||
|
||||
//RF2500 emu init
|
||||
RF2500_Init(E129_PAYLOAD_SIZE, true); // 16 bytes, Scrambled
|
||||
|
||||
//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
|
||||
|
||||
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;
|
||||
return 1260;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -79,4 +79,5 @@
|
||||
79,WFLY,RF20x
|
||||
80,E016H,E016Hv2
|
||||
81,E010r5
|
||||
82,LOLI
|
||||
82,LOLI
|
||||
83,E129
|
||||
@@ -97,6 +97,7 @@ const char STR_NANORF[] ="NanoRF";
|
||||
const char STR_E016HV2[] ="E016Hv2";
|
||||
const char STR_E010R5[] ="E010r5";
|
||||
const char STR_LOLI[] ="LOLI";
|
||||
const char STR_E129[] ="E129";
|
||||
|
||||
const char STR_SUBTYPE_FLYSKY[] = "\x04""Std\0""V9x9""V6x6""V912""CX20";
|
||||
const char STR_SUBTYPE_HUBSAN[] = "\x04""H107""H301""H501";
|
||||
@@ -224,6 +225,9 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
#if defined(E01X_NRF24L01_INO)
|
||||
{PROTO_E01X, STR_E01X, 3, STR_SUBTYPE_E01X, OPTION_OPTION },
|
||||
#endif
|
||||
#if defined(E129_CYRF6936_INO)
|
||||
{PROTO_E129, STR_E129, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(ESKY_NRF24L01_INO)
|
||||
{PROTO_ESKY, STR_ESKY, 2, STR_SUBTYPE_ESKY, OPTION_NONE },
|
||||
#endif
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 3
|
||||
#define VERSION_REVISION 2
|
||||
#define VERSION_PATCH_LEVEL 2
|
||||
#define VERSION_PATCH_LEVEL 3
|
||||
|
||||
//******************
|
||||
// Protocols
|
||||
@@ -108,6 +108,7 @@ enum PROTOCOLS
|
||||
PROTO_E016HV2 = 80, // =>CC2500 & NRF24L01
|
||||
PROTO_E010R5 = 81, // =>CYRF6936
|
||||
PROTO_LOLI = 82, // =>NRF24L01
|
||||
PROTO_E129 = 83, // =>CYRF6936
|
||||
|
||||
PROTO_NANORF = 126, // =>NRF24L01
|
||||
PROTO_TEST = 127, // =>CC2500
|
||||
@@ -767,8 +768,9 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
0x54 sub_protocol values are 32..63 Stream contains channels
|
||||
0x57 sub_protocol values are 0..31 Stream contains failsafe
|
||||
0x56 sub_protocol values are 32..63 Stream contains failsafe
|
||||
Note: V2 adds the 2 top bits to extend the number of protocols to 256 in Stream[26]
|
||||
Stream[1] = sub_protocol|BindBit|RangeCheckBit|AutoBindBit;
|
||||
sub_protocol is 0..31 (bits 0..4), value should be added with 32 if Stream[0] = 0x54 | 0x56
|
||||
sub_protocol is 0..31 (bits 0..4)
|
||||
Reserved 0
|
||||
Flysky 1
|
||||
Hubsan 2
|
||||
@@ -851,6 +853,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
E016HV2 80
|
||||
E010R5 81
|
||||
LOLI 82
|
||||
E129 83
|
||||
BindBit=> 0x80 1=Bind/0=No
|
||||
AutoBindBit=> 0x40 1=Yes /0=No
|
||||
RangeCheck=> 0x20 1=Yes /0=No
|
||||
|
||||
@@ -75,7 +75,7 @@ uint32_t blink=0,last_signal=0;
|
||||
//
|
||||
uint16_t counter;
|
||||
uint8_t channel;
|
||||
#if defined(ESKY150V2_CC2500_INO) || defined(E010R5_CYRF6936_INO)
|
||||
#if defined(ESKY150V2_CC2500_INO)
|
||||
uint8_t packet[150];
|
||||
#else
|
||||
uint8_t packet[50];
|
||||
@@ -1376,6 +1376,13 @@ static void protocol_init()
|
||||
remote_callback = ReadE010R5;
|
||||
break;
|
||||
#endif
|
||||
#if defined(E129_CYRF6936_INO)
|
||||
case PROTO_E129:
|
||||
PE2_on; //antenna RF4
|
||||
next_callback = initE129();
|
||||
remote_callback = ReadE129;
|
||||
break;
|
||||
#endif
|
||||
#if defined(DEVO_CYRF6936_INO)
|
||||
case PROTO_DEVO:
|
||||
#ifdef ENABLE_PPM
|
||||
|
||||
169
Multiprotocol/RF2500_EMU.ino
Normal file
169
Multiprotocol/RF2500_EMU.ino
Normal file
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
#ifdef CYRF6936_INSTALLED
|
||||
#include "iface_rf2500.h"
|
||||
|
||||
const uint8_t PROGMEM RF2500_init_vals[][2] = {
|
||||
{CYRF_02_TX_CTRL, 0x00}, // transmit err & complete interrupts disabled
|
||||
{CYRF_05_RX_CTRL, 0x00}, // receive err & complete interrupts disabled
|
||||
{CYRF_28_CLK_EN, 0x02}, // Force Receive Clock Enable, MUST be set
|
||||
{CYRF_32_AUTO_CAL_TIME, 0x3c}, // must be set to 3C
|
||||
{CYRF_35_AUTOCAL_OFFSET, 0x14}, // must be set to 14
|
||||
{CYRF_06_RX_CFG, 0x48}, // LNA manual control, Rx Fast Turn Mode Enable
|
||||
{CYRF_1B_TX_OFFSET_LSB, 0x00}, // Tx frequency offset LSB
|
||||
{CYRF_1C_TX_OFFSET_MSB, 0x00}, // Tx frequency offset MSB
|
||||
{CYRF_0F_XACT_CFG, 0x24}, // Force End State, transaction end state = idle
|
||||
{CYRF_03_TX_CFG, 0x00}, // GFSK mode
|
||||
{CYRF_12_DATA64_THOLD, 0x0a}, // 64 Chip Data PN Code Correlator Threshold = 10
|
||||
{CYRF_0F_XACT_CFG, 0x04}, // Transaction End State = idle
|
||||
{CYRF_39_ANALOG_CTRL, 0x01}, // synth setting time for all channels is the same as for slow channels
|
||||
{CYRF_0F_XACT_CFG, 0x24}, //Force IDLE
|
||||
{CYRF_29_RX_ABORT, 0x00}, //Clear RX abort
|
||||
{CYRF_12_DATA64_THOLD, 0x0a}, //set pn correlation threshold
|
||||
{CYRF_10_FRAMING_CFG, 0x4a}, //set sop len and threshold
|
||||
{CYRF_29_RX_ABORT, 0x0f}, //Clear RX abort?
|
||||
{CYRF_03_TX_CFG, 0x00}, // GFSK mode
|
||||
{CYRF_10_FRAMING_CFG, 0x4a}, // 0b11000000 //set sop len and threshold
|
||||
{CYRF_1F_TX_OVERRIDE, 0x04}, //disable tx CRC
|
||||
{CYRF_1E_RX_OVERRIDE, 0x14}, //disable rx crc
|
||||
{CYRF_14_EOP_CTRL, 0x00}, //set EOP sync == 0
|
||||
};
|
||||
|
||||
uint8_t RF2500_payload_length, RF2500_tx_addr[4], RF2500_buf[80];
|
||||
bool RF2500_scramble_enabled;
|
||||
|
||||
#define RF2500_ADDR_LENGTH 4
|
||||
|
||||
static void __attribute__((unused)) RF2500_Init(uint8_t payload_length, bool scramble)
|
||||
{
|
||||
for(uint8_t i = 0; i < sizeof(RF2500_init_vals) / 2; i++)
|
||||
CYRF_WriteRegister(pgm_read_byte_near(&RF2500_init_vals[i][0]), pgm_read_byte_near(&RF2500_init_vals[i][1]));
|
||||
|
||||
RF2500_payload_length=payload_length;
|
||||
|
||||
CYRF_WriteRegister(CYRF_01_TX_LENGTH, RF2500_ADDR_LENGTH + 2 + (payload_length+2)*4 ); // full payload length with CRC + address + 5 + FEC
|
||||
RF2500_scramble_enabled=scramble;
|
||||
|
||||
CYRF_WritePreamble(0xAAAA02);
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
RF2500_SetPower();
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) RF2500_SetTXAddr(const uint8_t* addr)
|
||||
{
|
||||
memcpy(RF2500_tx_addr, addr, RF2500_ADDR_LENGTH);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) RF2500_BuildPayload(uint8_t* buffer)
|
||||
{
|
||||
const uint8_t RF2500_scramble[] = { 0xD0, 0x9E, 0x53, 0x33, 0xD8, 0xBA, 0x98, 0x08, 0x24, 0xCB, 0x3B, 0xFC, 0x71, 0xA3, 0xF4, 0x55 };
|
||||
const uint16_t RF2500_crc_xorout_scramble = 0xAEE4;
|
||||
|
||||
//Scramble the incoming buffer
|
||||
if(RF2500_scramble_enabled)
|
||||
for(uint8_t i=0; i<RF2500_payload_length; i++)
|
||||
buffer[i] ^= RF2500_scramble[i];
|
||||
|
||||
//Add CRC to the buffer
|
||||
crc=0x0000;
|
||||
for(uint8_t i=0;i<RF2500_payload_length;i++)
|
||||
crc16_update(bit_reverse(buffer[i]),8);
|
||||
buffer[RF2500_payload_length ] = bit_reverse(crc>>8);
|
||||
buffer[RF2500_payload_length+1] = bit_reverse(crc);
|
||||
|
||||
if(RF2500_scramble_enabled)
|
||||
{
|
||||
buffer[RF2500_payload_length ] ^= RF2500_crc_xorout_scramble>>8;
|
||||
buffer[RF2500_payload_length+1] ^= RF2500_crc_xorout_scramble;
|
||||
}
|
||||
|
||||
#if 0
|
||||
debug("B:");
|
||||
for(uint8_t i=0; i<RF2500_payload_length+2; i++)
|
||||
debug(" %02X",buffer[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
|
||||
memcpy(RF2500_buf,RF2500_tx_addr,RF2500_ADDR_LENGTH); // Address
|
||||
|
||||
uint8_t pos = RF2500_ADDR_LENGTH;
|
||||
|
||||
RF2500_buf[pos++]=0xC3;RF2500_buf[pos++]=0xC3; // 5 FEC encoded
|
||||
memset(&RF2500_buf[pos],0x00,(RF2500_payload_length+2)*4); // + CRC) * 4 FEC bytes per byte
|
||||
|
||||
//FEC encode
|
||||
for(uint8_t i=0; i<RF2500_payload_length+2; i++) // Include CRC
|
||||
{
|
||||
for(uint8_t j=0;j<8;j++)
|
||||
{
|
||||
uint8_t offset=pos + (i<<2) + (j>>1);
|
||||
RF2500_buf[offset] <<= 4;
|
||||
if( (buffer[i]>>j) & 0x01 )
|
||||
RF2500_buf[offset] |= 0x0C;
|
||||
else
|
||||
RF2500_buf[offset] |= 0x03;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
debug("E:");
|
||||
for(uint8_t i=0; i<RF2500_ADDR_LENGTH+2+(RF2500_payload_length+2)*4; i++)
|
||||
debug(" %02X",RF2500_buf[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
|
||||
//CYRF wants LSB first
|
||||
for(uint8_t i=0; i<RF2500_ADDR_LENGTH+2+(RF2500_payload_length+2)*4; i++)
|
||||
RF2500_buf[i]=bit_reverse(RF2500_buf[i]);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) RF2500_SendPayload()
|
||||
{
|
||||
uint8_t *buffer=RF2500_buf;
|
||||
uint8_t len=4 + 2 + (RF2500_payload_length+2)*4; // Full payload length with CRC + address + 5 + FEC
|
||||
|
||||
uint8_t send=len>16 ? 16 : len;
|
||||
CYRF_WriteRegister(CYRF_02_TX_CTRL, 0x40);
|
||||
CYRF_WriteRegisterMulti(CYRF_20_TX_BUFFER, buffer, send); // Fill the buffer with 16 bytes max
|
||||
CYRF_WriteRegister(CYRF_02_TX_CTRL, 0x80); // Start send
|
||||
buffer += send;
|
||||
len -= send;
|
||||
|
||||
while(len>8)
|
||||
{
|
||||
while((CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS)&0x10) == 0); // Wait that half of the buffer is empty
|
||||
CYRF_WriteRegisterMulti(CYRF_20_TX_BUFFER, buffer, 8); // Add 8 bytes to the buffer
|
||||
buffer+=8;
|
||||
len-=8;
|
||||
}
|
||||
|
||||
if(len)
|
||||
{
|
||||
while((CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS)&0x10) == 0); // Wait that half of the buffer is empty
|
||||
CYRF_WriteRegisterMulti(CYRF_20_TX_BUFFER, buffer, len); // Add the remaining bytes to the buffer
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) RF2500_RFChannel(uint8_t channel)
|
||||
{
|
||||
CYRF_ConfigRFChannel(channel);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) RF2500_SetPower()
|
||||
{
|
||||
CYRF_SetPower(0x00);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -242,6 +242,7 @@
|
||||
#undef DSM_CYRF6936_INO
|
||||
#undef DSM_RX_CYRF6936_INO
|
||||
#undef E010R5_CYRF6936_INO
|
||||
#undef E129_CYRF6936_INO
|
||||
#undef J6PRO_CYRF6936_INO
|
||||
#undef MLINK_CYRF6936_INO
|
||||
#undef TRAXXAS_CYRF6936_INO
|
||||
|
||||
@@ -628,10 +628,10 @@ static uint16_t XN297Dump_callback()
|
||||
if(phase==0)
|
||||
{
|
||||
address_length=4;
|
||||
memcpy(rx_tx_addr, (uint8_t *)"\xEE\x96\x54\x0E", address_length);
|
||||
memcpy(rx_tx_addr, (uint8_t *)"\x5A\x20\x12\xAC", address_length); //"\xA3\x05\x22\xC1"
|
||||
bitrate=XN297DUMP_1M;
|
||||
packet_length=32;
|
||||
hopping_frequency_no=48; //bind ?, normal 48
|
||||
hopping_frequency_no=60; //bind ?, normal 60
|
||||
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
@@ -678,16 +678,16 @@ static uint16_t XN297Dump_callback()
|
||||
if(NRF24L01_ReadReg(NRF24L01_09_CD))
|
||||
{
|
||||
NRF24L01_ReadPayload(packet, packet_length);
|
||||
#define XN_DEB 0 //6 //0
|
||||
#define XN_LON 32 //4 //32
|
||||
bool ok=true;
|
||||
uint8_t buffer[40];
|
||||
memcpy(buffer,packet,packet_length);
|
||||
if(memcmp(&packet_in[XN_DEB],&packet[XN_DEB],XN_LON))
|
||||
if(memcmp(&packet_in[0],&packet[0],packet_length))
|
||||
{
|
||||
//realign bits
|
||||
for(uint8_t i=0; i<packet_length; i++)
|
||||
buffer[i]=buffer[i+2];
|
||||
//for(uint8_t i=0; i<packet_length; i++)
|
||||
// buffer[i]=(buffer[i]<<4)+(buffer[i+1]>>4);
|
||||
|
||||
//check for validity and decode
|
||||
memset(packet_in,0,packet_length);
|
||||
@@ -720,7 +720,7 @@ static uint16_t XN297Dump_callback()
|
||||
if(packet[12]==((crc>>8)&0xFF) && packet[13]==(crc&0xFF))
|
||||
if(memcmp(&packet_in[1],&packet[1],packet_length-1))
|
||||
{
|
||||
/*debug("P:");
|
||||
debug("P:");
|
||||
for(uint8_t i=0;i<packet_length;i++)
|
||||
debug(" %02X",packet[i]);
|
||||
debug(" CRC: %04X",crc);
|
||||
|
||||
@@ -182,6 +182,7 @@
|
||||
#define DSM_CYRF6936_INO
|
||||
#define DSM_RX_CYRF6936_INO
|
||||
#define E010R5_CYRF6936_INO
|
||||
#define E129_CYRF6936_INO
|
||||
#define J6PRO_CYRF6936_INO
|
||||
#define TRAXXAS_CYRF6936_INO
|
||||
#define WFLY_CYRF6936_INO
|
||||
@@ -583,6 +584,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
E012
|
||||
E015
|
||||
E016H
|
||||
PROTO_E129
|
||||
NONE
|
||||
PROTO_ESKY
|
||||
ESKY_STD
|
||||
ESKY_ET4
|
||||
|
||||
14
Multiprotocol/iface_rf2500.h
Normal file
14
Multiprotocol/iface_rf2500.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef _IFACE_RF2500_H_
|
||||
#define _IFACE_RF2500_H_
|
||||
|
||||
#include "iface_cyrf6936.h"
|
||||
|
||||
//RF2500
|
||||
static void __attribute__((unused)) RF2500_Init(uint8_t, bool);
|
||||
static void __attribute__((unused)) RF2500_SetTXAddr(const uint8_t*);
|
||||
static void __attribute__((unused)) RF2500_BuildPayload(uint8_t*);
|
||||
static void __attribute__((unused)) RF2500_SendPayload();
|
||||
static void __attribute__((unused)) RF2500_RFChannel(uint8_t);
|
||||
static void __attribute__((unused)) RF2500_SetPower();
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user