New Redpine protocol

Protocol Redpine: 50
Sub protocol: Fast=0, Slow=1
Option=freq tunning
This commit is contained in:
Pascal Langer 2019-06-17 17:16:39 +02:00
parent 9d50171034
commit d940a7e49a
6 changed files with 287 additions and 4 deletions

View File

@ -47,4 +47,5 @@
47,GD00X,GD_V1,GD_V2
48,V761
49,KF606
50,REDPINE,FAST,SLOW
63,XN_DUMP,250K,1M,2M

View File

@ -19,7 +19,7 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 2
#define VERSION_REVISION 1
#define VERSION_PATCH_LEVEL 61
#define VERSION_PATCH_LEVEL 62
//******************
// Protocols
@ -76,6 +76,7 @@ enum PROTOCOLS
PROTO_GD00X = 47, // =>NRF24L01
PROTO_V761 = 48, // =>NRF24L01
PROTO_KF606 = 49, // =>NRF24L01
PROTO_REDPINE = 50, // =>CC2500
PROTO_XN297DUMP = 63, // =>NRF24L01
};
@ -270,6 +271,11 @@ enum BUGSMINI
BUGSMINI= 0,
BUGS3H = 1,
};
enum REDPINE
{
RED_FAST= 0,
RED_SLOW= 1,
};
#define NONE 0
#define P_HIGH 1
#define P_LOW 0
@ -613,6 +619,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
GD00X 47
V761 48
KF606 49
REDPINE 50
BindBit=> 0x80 1=Bind/0=No
AutoBindBit=> 0x40 1=Yes /0=No
RangeCheck=> 0x20 1=Yes /0=No
@ -749,6 +756,9 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
sub_protocol==GD00X
GD_V1 0
GD_V2 1
sub_protocol==REDPINE
RED_FAST 0
RED_SLOW 1
Power value => 0x80 0=High/1=Low
Stream[3] = option_protocol;

View File

@ -113,7 +113,7 @@ uint8_t len;
uint8_t armed, arm_flags, arm_channel_previous;
#ifdef CC2500_INSTALLED
uint8_t calData[48];
uint8_t calData[50];
#endif
#ifdef CHECK_FOR_BOOTLOADER
@ -442,6 +442,11 @@ void setup()
option = FORCE_CORONA_TUNING; // Use config-defined tuning value for CORONA
else
#endif
#if defined(FORCE_REDPINE_TUNING) && defined(REDPINE_CC2500_INO)
if (protocol==PROTO_REDPINE)
option = FORCE_REDPINE_TUNING; // Use config-defined tuning value for REDPINE
else
#endif
#if defined(FORCE_HITEC_TUNING) && defined(HITEC_CC2500_INO)
if (protocol==PROTO_HITEC)
option = FORCE_HITEC_TUNING; // Use config-defined tuning value for HITEC
@ -969,6 +974,14 @@ static void protocol_init()
remote_callback = ReadCORONA;
break;
#endif
#if defined(REDPINE_CC2500_INO)
case PROTO_REDPINE:
PE1_off; //antenna RF2
PE2_on;
next_callback = initREDPINE();
remote_callback = ReadREDPINE;
break;
#endif
#if defined(HITEC_CC2500_INO)
case PROTO_HITEC:
PE1_off; //antenna RF2
@ -1321,6 +1334,11 @@ void update_serial_data()
option=FORCE_CORONA_TUNING; // Use config-defined tuning value for CORONA
else
#endif
#if defined(FORCE_REDPINE_TUNING) && defined(REDPINE_CC2500_INO)
if (protocol==PROTO_REDPINE)
option=FORCE_REDPINE_TUNING; // Use config-defined tuning value for REDPINE
else
#endif
#if defined(FORCE_HITEC_TUNING) && defined(HITEC_CC2500_INO)
if (protocol==PROTO_HITEC)
option=FORCE_HITEC_TUNING; // Use config-defined tuning value for HITEC

View File

@ -0,0 +1,242 @@
/*
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(REDPINE_CC2500_INO)
#include "iface_cc2500.h"
#define REDPINE_LOOPTIME_FAST 9 //9ms
#define REDPINE_LOOPTIME_SLOW 22 //22ms
#define REDPINE_BIND 1000
#define REDPINE_PACKET_SIZE 11
#define REDPINE_FEC false // from cc2500 datasheet: The convolutional coder is a rate 1/2 code with a constraint length of m=4
#define REDPINE_NUM_HOPS 50
static void REDPINE_set_channel(uint8_t ch)
{
CC2500_Strobe(CC2500_SIDLE);
CC2500_WriteReg(CC2500_25_FSCAL1, calData[ch]);
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[ch]);
}
static void REDPINE_build_bind_packet()
{
memset(&packet[0], 0, REDPINE_PACKET_SIZE);
packet[0] = REDPINE_PACKET_SIZE - 1;
packet[1] = 0x03;
packet[2] = 0x01;
packet[3] = rx_tx_addr[2];
packet[4] = rx_tx_addr[3]; // Use RX_Num
uint16_t idx = ((REDPINE_BIND - bind_counter) % 10) * 5;
packet[5] = idx;
packet[6] = hopping_frequency[idx++];
packet[7] = hopping_frequency[idx++];
packet[8] = hopping_frequency[idx++];
packet[9] = hopping_frequency[idx++];
packet[10] = hopping_frequency[idx++];
// packet[11] = 0x02;
// packet[12] = RXNUM;
}
static uint16_t Redpine_Scale(uint8_t chan)
{
uint16_t chan_val=Channel_data[chan]; // -125%..+125% <=> 0..2047
if (chan_val > 2046) chan_val = 2046;
else if (chan_val < 10) chan_val = 10;
return chan_val;
}
static void REDPINE_data_frame() {
uint16_t chan[4];
memset(&packet[0], 0, REDPINE_PACKET_SIZE);
packet[0] = REDPINE_PACKET_SIZE - 1;
packet[1] = rx_tx_addr[2];
packet[2] = rx_tx_addr[3]; // Use RX_Num
chan[0] = Redpine_Scale(0);
chan[1] = Redpine_Scale(1);
chan[2] = Redpine_Scale(2);
chan[3] = Redpine_Scale(3);
packet[3] = chan[0];
packet[4] = (((chan[0] >> 8) & 0x07) | (chan[1] << 4)) | GET_FLAG(CH5_SW, 0x08);
packet[5] = ((chan[1] >> 4) & 0x7F) | GET_FLAG(CH6_SW, 0x80);
packet[6] = chan[2];
packet[7] = (((chan[2] >> 8) & 0x07) | (chan[3] << 4)) | GET_FLAG(CH7_SW, 0x08);
packet[8] = ((chan[3] >> 4) & 0x7F) | GET_FLAG(CH8_SW, 0x80);
packet[9] = GET_FLAG(CH9_SW, 0x01)
| GET_FLAG(CH10_SW, 0x02)
| GET_FLAG(CH11_SW, 0x04)
| GET_FLAG(CH12_SW, 0x08)
| GET_FLAG(CH13_SW, 0x10)
| GET_FLAG(CH14_SW, 0x20)
| GET_FLAG(CH15_SW, 0x40)
| GET_FLAG(CH16_SW, 0x80);
if (sub_protocol==0)
packet[10] = REDPINE_LOOPTIME_FAST;
else
packet[10] = REDPINE_LOOPTIME_SLOW;
}
static uint16_t ReadREDPINE()
{
if ( prev_option != option )
{ // Frequency adjust
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
prev_option = option ;
}
if(IS_BIND_IN_PROGRESS)
{
if(bind_counter== REDPINE_BIND)
REDPINE_init(0);
if(state == REDPINE_BIND/2)
REDPINE_init(1);
REDPINE_set_channel(49);
CC2500_SetPower();
CC2500_Strobe(CC2500_SFRX);
REDPINE_build_bind_packet();
CC2500_Strobe(CC2500_SIDLE);
CC2500_WriteData(packet, REDPINE_PACKET_SIZE);
if(--bind_counter==0)
{
BIND_DONE;
REDPINE_init(sub_protocol);
}
return 9000;
}
else
{
CC2500_SetTxRxMode(TX_EN);
REDPINE_set_channel(hopping_frequency_no);
CC2500_SetPower();
CC2500_Strobe(CC2500_SFRX);
REDPINE_data_frame();
CC2500_Strobe(CC2500_SIDLE);
hopping_frequency_no = (hopping_frequency_no + 1) % 49;
CC2500_WriteData(packet, REDPINE_PACKET_SIZE);
if (sub_protocol==0)
return REDPINE_LOOPTIME_FAST*100;
else
return REDPINE_LOOPTIME_SLOW*100;
}
return 1;
}
// register, fast 250k, slow
static const uint8_t REDPINE_init_data[][3] = {
{CC2500_00_IOCFG2, 0x06, 0x06},
{CC2500_02_IOCFG0, 0x06, 0x06},
{CC2500_03_FIFOTHR, 0x07, 0x07},
{CC2500_07_PKTCTRL1, 0x04, 0x04},
{CC2500_08_PKTCTRL0, 0x05, 0x05},
{CC2500_09_ADDR, 0x00, 0x00},
{CC2500_0B_FSCTRL1, 0x0A, 0x0A},
{CC2500_0C_FSCTRL0, 0x00, 0x00},
{CC2500_0D_FREQ2, 0x5D, 0x5c},
{CC2500_0E_FREQ1, 0x93, 0x76},
{CC2500_0F_FREQ0, 0xB1, 0x27},
{CC2500_10_MDMCFG4, 0x2D, 0x7B},
{CC2500_11_MDMCFG3, 0x3B, 0x61},
{CC2500_12_MDMCFG2, 0x73, 0x13},
#ifdef REDPINE_FEC
{CC2500_13_MDMCFG1, 0xA3, 0xA3},
#else
{CC2500_13_MDMCFG1, 0x23, 0x23},
#endif
{CC2500_14_MDMCFG0, 0x56, 0x7a}, // Chan space
{CC2500_15_DEVIATN, 0x00, 0x51},
{CC2500_17_MCSM1, 0x0c, 0x0c},
{CC2500_18_MCSM0, 0x08, 0x08}, //??? 0x18, 0x18},
{CC2500_19_FOCCFG, 0x1D, 0x16},
{CC2500_1A_BSCFG, 0x1C, 0x6c},
{CC2500_1B_AGCCTRL2, 0xC7, 0x43},
{CC2500_1C_AGCCTRL1, 0x00, 0x40},
{CC2500_1D_AGCCTRL0, 0xB0, 0x91},
{CC2500_21_FREND1, 0xB6, 0x56},
{CC2500_22_FREND0, 0x10, 0x10},
{CC2500_23_FSCAL3, 0xEA, 0xA9},
{CC2500_24_FSCAL2, 0x0A, 0x0A},
{CC2500_25_FSCAL1, 0x00, 0x00},
{CC2500_26_FSCAL0, 0x11, 0x11},
{CC2500_29_FSTEST, 0x59, 0x59},
{CC2500_2C_TEST2, 0x88, 0x88},
{CC2500_2D_TEST1, 0x31, 0x31},
{CC2500_2E_TEST0, 0x0B, 0x0B},
{CC2500_3E_PATABLE, 0xff, 0xff}
};
static void REDPINE_init(uint8_t format)
{
CC2500_Reset();
CC2500_WriteReg(CC2500_06_PKTLEN, REDPINE_PACKET_SIZE);
for (uint8_t i=0; i < ((sizeof REDPINE_init_data) / (sizeof REDPINE_init_data[0])); i++)
CC2500_WriteReg(REDPINE_init_data[i][0], REDPINE_init_data[i][format+1]);
prev_option = option;
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
CC2500_Strobe(CC2500_SIDLE);
// calibrate hop channels
for (uint8_t c = 0; c < REDPINE_NUM_HOPS; c++)
{
CC2500_Strobe(CC2500_SIDLE);
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[c]);
CC2500_Strobe(CC2500_SCAL);
delayMicroseconds(900);
calData[c] = CC2500_ReadReg(CC2500_25_FSCAL1);
}
}
static uint16_t initREDPINE()
{
hopping_frequency_no = 0;
// Used from kn_nrf24l01.c : kn_calculate_freqency_hopping_channels
uint32_t idx = 0;
uint32_t rnd = MProtocol_id;
#define REDPINE_MAX_RF_CHANNEL 255
hopping_frequency[idx++] = 1;
while (idx < REDPINE_NUM_HOPS-1)
{
uint32_t i;
rnd = rnd * 0x0019660D + 0x3C6EF35F; // Randomization
// Drop least-significant byte for better randomization. Start from 1
uint8_t next_ch = (rnd >> 8) % REDPINE_MAX_RF_CHANNEL + 1;
// Check that it's not duplicate nor adjacent nor channel 0 or 1
for (i = 0; i < idx; i++)
{
uint8_t ch = hopping_frequency[i];
if ((ch <= next_ch + 1) && (ch >= next_ch - 1) && (ch > 1))
break;
}
if (i != idx)
continue;
hopping_frequency[idx++] = next_ch;
}
hopping_frequency[49] = 0; // Last channel is the bind channel at hop 0
bind_counter=REDPINE_BIND;
REDPINE_init(sub_protocol);
CC2500_SetTxRxMode(TX_EN); // enable PA
return 10000;
}
#endif

View File

@ -87,6 +87,11 @@
#error "The CORONA forced frequency tuning value is outside of the range -127..127."
#endif
#endif
#ifdef FORCE_REDPINE_TUNING
#if ( FORCE_REDPINE_TUNING < -127 ) || ( FORCE_REDPINE_TUNING > 127 )
#error "The REDPINE forced frequency tuning value is outside of the range -127..127."
#endif
#endif
#ifdef FORCE_HITEC_TUNING
#if ( FORCE_HITEC_TUNING < -127 ) || ( FORCE_HITEC_TUNING > 127 )
#error "The HITEC forced frequency tuning value is outside of the range -127..127."
@ -154,6 +159,7 @@
#undef FRSKYX_CC2500_INO
#undef SFHSS_CC2500_INO
#undef CORONA_CC2500_INO
#undef REDPINE_CC2500_INO
#undef HITEC_CC2500_INO
#undef XN297L_CC2500_EMU
#endif

View File

@ -87,8 +87,8 @@
//#define ORANGE_TX_BLUE
/** CC2500 Fine Frequency Tuning **/
//For optimal performance the CC2500 RF module used by the FrSkyD, FrSkyV, FrSkyX, SFHSS, CORONA and Hitec protocols needs to be tuned for each protocol.
//Initial tuning should be done via the radio menu with a genuine FrSky/Futaba/CORONA/Hitec receiver.
//For optimal performance the CC2500 RF module used by the FrSkyD, FrSkyV, FrSkyX, SFHSS, CORONA, Redpine and Hitec protocols needs to be tuned for each protocol.
//Initial tuning should be done via the radio menu with a genuine FrSky/Futaba/CORONA/Hitec/Redpine receiver.
//Once a good tuning value is found it can be set here and will override the radio's 'option' setting for all existing and new models which use that protocol.
//For more information: https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/tree/master/docs/Frequency_Tuning.md
//Uncomment the lines below (remove the "//") and set an appropriate value (replace the "0") to enable. Valid range is -127 to +127.
@ -98,6 +98,7 @@
//#define FORCE_SFHSS_TUNING 0
//#define FORCE_CORONA_TUNING 0
//#define FORCE_HITEC_TUNING 0
//#define FORCE_REDPINE_TUNING 0
/** A7105 Fine Frequency Tuning **/
//This is required in rare cases where some A7105 modules and/or RXs have an inaccurate crystal oscillator.
@ -164,6 +165,7 @@
#define J6PRO_CYRF6936_INO
#define WFLY_CYRF6936_INO
#define WK2x01_CYRF6936_INO
//#define TRAXXAS_CYRF6936_INO
//The protocols below need a CC2500 to be installed
@ -173,6 +175,7 @@
#define FRSKYX_CC2500_INO
#define HITEC_CC2500_INO
#define SFHSS_CC2500_INO
#define REDPINE_CC2500_INO
//The protocols below need a NRF24L01 to be installed
#define ASSAN_NRF24L01_INO
@ -598,6 +601,9 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
CX35
CX10D
CX10WD
PROTO_REDPINE
RED_FAST
RED_SLOW
PROTO_SFHSS
NONE
PROTO_SHENQI