mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-07-12 17:57:53 +00:00
update to last multi modification
This commit is contained in:
parent
2ab47c08c8
commit
ee10ba29a4
@ -74,17 +74,17 @@ uint16_t ASSAN_callback()
|
|||||||
NRF24L01_SetTxRxMode(RX_EN);
|
NRF24L01_SetTxRxMode(RX_EN);
|
||||||
phase++;
|
phase++;
|
||||||
case ASSAN_BIND1:
|
case ASSAN_BIND1:
|
||||||
//Wait for RX to send the frames
|
//Wait for receiver to send the frames
|
||||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR))
|
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||||
{ //Something has been received
|
{ //Something has been received
|
||||||
NRF24L01_ReadPayload(packet, ASSAN_PACKET_SIZE);
|
NRF24L01_ReadPayload(packet, ASSAN_PACKET_SIZE);
|
||||||
if(packet[19]==0x13)
|
if(packet[19]==0x13)
|
||||||
{ //Last packet received
|
{ //Last frame received
|
||||||
phase++;
|
phase++;
|
||||||
//Switch to TX
|
//Switch to TX
|
||||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
//Prepare packet
|
//Prepare bind packet
|
||||||
memset(packet,0x05,ASSAN_PACKET_SIZE-5);
|
memset(packet,0x05,ASSAN_PACKET_SIZE-5);
|
||||||
packet[15]=0x99;
|
packet[15]=0x99;
|
||||||
for(uint8_t i=0;i<4;i++)
|
for(uint8_t i=0;i<4;i++)
|
||||||
@ -134,7 +134,7 @@ uint16_t ASSAN_callback()
|
|||||||
|
|
||||||
static void __attribute__((unused)) ASSAN_initialize_txid()
|
static void __attribute__((unused)) ASSAN_initialize_txid()
|
||||||
{
|
{
|
||||||
/* //Renaud TXID with Freq=36 and alternate freq 67 or 68 or 69 or 70 or 71 or 73 or 74 or 75 or 78 and may be more...
|
/* //Renaud TXID with Freq=36 and alternate Freq 67 or 68 or 69 or 70 or 71 or 73 or 74 or 75 or 78 and may be more...
|
||||||
packet[23]=0x22;
|
packet[23]=0x22;
|
||||||
packet[22]=0x37;
|
packet[22]=0x37;
|
||||||
packet[21]=0xFA;
|
packet[21]=0xFA;
|
||||||
@ -153,19 +153,15 @@ static void __attribute__((unused)) ASSAN_initialize_txid()
|
|||||||
freq=((freq%25)+2)<<1;
|
freq=((freq%25)+2)<<1;
|
||||||
if(freq&0x02) freq|=0x01;
|
if(freq&0x02) freq|=0x01;
|
||||||
hopping_frequency[0]=freq;
|
hopping_frequency[0]=freq;
|
||||||
// Alternate frequency
|
// Alternate frequency has some random
|
||||||
hopping_frequency[1]=freq*2-6;
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
#if defined STM32_board
|
#if defined STM32_board
|
||||||
randomSeed((uint32_t)analogRead(PB0) << 10 | analogRead(PB1));
|
randomSeed((uint32_t)analogRead(PB0) << 10 | analogRead(PB1));
|
||||||
#else
|
#endif
|
||||||
randomSeed((uint32_t)analogRead(A6) << 10 | analogRead(A7));
|
|
||||||
#endif
|
|
||||||
freq2=random(0xfefefefe)%9;
|
freq2=random(0xfefefefe)%9;
|
||||||
freq2+=freq*2-5;
|
freq2+=freq*2-5;
|
||||||
}
|
}
|
||||||
|
|
||||||
while( (freq2>118) || (freq2<freq+1) || (freq2==2*freq) );
|
while( (freq2>118) || (freq2<freq+1) || (freq2==2*freq) );
|
||||||
hopping_frequency[1]=freq2; // Add some random to the second channel
|
hopping_frequency[1]=freq2; // Add some random to the second channel
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
|||||||
|
|
||||||
// Power on, TX mode, 2byte CRC
|
// Power on, TX mode, 2byte CRC
|
||||||
// Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing
|
// Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing
|
||||||
XN297_Configure(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP));
|
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||||
|
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? BAYANG_RF_BIND_CHANNEL:hopping_frequency[hopping_frequency_no++]);
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? BAYANG_RF_BIND_CHANNEL:hopping_frequency[hopping_frequency_no++]);
|
||||||
hopping_frequency_no%=BAYANG_RF_NUM_CHANNELS;
|
hopping_frequency_no%=BAYANG_RF_NUM_CHANNELS;
|
||||||
|
@ -84,11 +84,11 @@ void CC2500_Strobe(uint8_t address)
|
|||||||
{
|
{
|
||||||
// Toggle chip select signal
|
// Toggle chip select signal
|
||||||
CC25_CSN_on;
|
CC25_CSN_on;
|
||||||
_delay_us(30);
|
delayMicroseconds(30);
|
||||||
CC25_CSN_off;
|
CC25_CSN_off;
|
||||||
_delay_us(30);
|
delayMicroseconds(30);
|
||||||
CC25_CSN_on;
|
CC25_CSN_on;
|
||||||
_delay_us(45);
|
delayMicroseconds(45);
|
||||||
CC2500_Strobe(CC2500_SRES);
|
CC2500_Strobe(CC2500_SRES);
|
||||||
_delay_ms(100);
|
_delay_ms(100);
|
||||||
}
|
}
|
||||||
@ -96,7 +96,7 @@ void CC2500_Strobe(uint8_t address)
|
|||||||
uint8_t CC2500_Reset()
|
uint8_t CC2500_Reset()
|
||||||
{
|
{
|
||||||
CC2500_Strobe(CC2500_SRES);
|
CC2500_Strobe(CC2500_SRES);
|
||||||
_delay_us(1000);
|
delayMilliseconds(1);
|
||||||
CC2500_SetTxRxMode(TXRX_OFF);
|
CC2500_SetTxRxMode(TXRX_OFF);
|
||||||
return CC2500_ReadReg(CC2500_0E_FREQ1) == 0xC4;//check if reset
|
return CC2500_ReadReg(CC2500_0E_FREQ1) == 0xC4;//check if reset
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ static void __attribute__((unused)) CG023_send_packet(uint8_t bind)
|
|||||||
|
|
||||||
// Power on, TX mode, 2byte CRC
|
// Power on, TX mode, 2byte CRC
|
||||||
// Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing
|
// Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing
|
||||||
XN297_Configure(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP));
|
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||||
if (bind)
|
if (bind)
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, sub_protocol==H8_3D?hopping_frequency[0]:CG023_RF_BIND_CHANNEL);
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, sub_protocol==H8_3D?hopping_frequency[0]:CG023_RF_BIND_CHANNEL);
|
||||||
else
|
else
|
||||||
|
@ -148,7 +148,7 @@ static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind)
|
|||||||
|
|
||||||
// Power on, TX mode, 2byte CRC
|
// Power on, TX mode, 2byte CRC
|
||||||
// Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing
|
// Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing
|
||||||
XN297_Configure(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP));
|
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||||
if (bind)
|
if (bind)
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, CX10_RF_BIND_CHANNEL);
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, CX10_RF_BIND_CHANNEL);
|
||||||
else
|
else
|
||||||
@ -197,7 +197,7 @@ uint16_t CX10_callback()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CX10_BIND2:
|
case CX10_BIND2:
|
||||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR))
|
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||||
{ // RX fifo data ready
|
{ // RX fifo data ready
|
||||||
XN297_ReadPayload(packet, packet_length);
|
XN297_ReadPayload(packet, packet_length);
|
||||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||||
@ -215,12 +215,12 @@ uint16_t CX10_callback()
|
|||||||
NRF24L01_FlushTx();
|
NRF24L01_FlushTx();
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
CX10_Write_Packet(1);
|
CX10_Write_Packet(1);
|
||||||
_delay_us(400);
|
delayMicroseconds(400);
|
||||||
// switch to RX mode
|
// switch to RX mode
|
||||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||||
NRF24L01_FlushRx();
|
NRF24L01_FlushRx();
|
||||||
NRF24L01_SetTxRxMode(RX_EN);
|
NRF24L01_SetTxRxMode(RX_EN);
|
||||||
XN297_Configure(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP) | BV(NRF24L01_00_PRIM_RX));
|
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CX10_DATA:
|
case CX10_DATA:
|
||||||
|
@ -14,11 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "iface_cyrf6936.h"
|
#include "iface_cyrf6936.h"
|
||||||
|
|
||||||
#ifdef XMEGA
|
|
||||||
#define XNOP() NOP()
|
|
||||||
#else
|
|
||||||
#define XNOP()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void CYRF_WriteRegister(uint8_t address, uint8_t data)
|
void CYRF_WriteRegister(uint8_t address, uint8_t data)
|
||||||
@ -64,17 +60,19 @@ uint8_t CYRF_ReadRegister(uint8_t address)
|
|||||||
|
|
||||||
uint8_t CYRF_Reset()
|
uint8_t CYRF_Reset()
|
||||||
{
|
{
|
||||||
//CYRF_WriteRegister(CYRF_1D_MODE_OVERRIDE, 0x01);//software reset
|
#ifdef CYRF_RST_HI
|
||||||
// _delay_us(200);//
|
CYRF_RST_HI; //Hardware reset
|
||||||
CYRF_RST_HI;
|
delayMicroseconds(100);
|
||||||
_delay_us(100);
|
|
||||||
CYRF_RST_LO;
|
CYRF_RST_LO;
|
||||||
_delay_us(100);
|
delayMicroseconds(100);
|
||||||
|
#endif
|
||||||
|
CYRF_WriteRegister(CYRF_1D_MODE_OVERRIDE, 0x01); //Software reset
|
||||||
|
delayMicroseconds(200);
|
||||||
CYRF_WriteRegister(CYRF_0C_XTAL_CTRL, 0xC0); //Enable XOUT as GPIO
|
CYRF_WriteRegister(CYRF_0C_XTAL_CTRL, 0xC0); //Enable XOUT as GPIO
|
||||||
CYRF_WriteRegister(CYRF_0D_IO_CFG, 0x04); //Enable PACTL as GPIO
|
CYRF_WriteRegister(CYRF_0D_IO_CFG, 0x04); //Enable PACTL as GPIO
|
||||||
CYRF_SetTxRxMode(TXRX_OFF);
|
CYRF_SetTxRxMode(TXRX_OFF);
|
||||||
//Verify the CYRD chip is responding
|
//Verify the CYRF chip is responding
|
||||||
return (CYRF_ReadRegister(CYRF_10_FRAMING_CFG) == 0xa5);//return if reset
|
return (CYRF_ReadRegister(CYRF_10_FRAMING_CFG) == 0xa5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -106,9 +104,15 @@ void CYRF_SetTxRxMode(uint8_t mode)
|
|||||||
//Set the post tx/rx state
|
//Set the post tx/rx state
|
||||||
CYRF_WriteRegister(CYRF_0F_XACT_CFG, mode == TX_EN ? 0x28 : 0x2C); // 4=IDLE, 8=TX, C=RX
|
CYRF_WriteRegister(CYRF_0F_XACT_CFG, mode == TX_EN ? 0x28 : 0x2C); // 4=IDLE, 8=TX, C=RX
|
||||||
if(mode == TX_EN)
|
if(mode == TX_EN)
|
||||||
|
#ifdef DSM_BLUE
|
||||||
|
CYRF_WriteRegister(CYRF_0E_GPIO_CTRL,0x20); // XOUT=1, PACTL=0
|
||||||
|
else
|
||||||
|
CYRF_WriteRegister(CYRF_0E_GPIO_CTRL,0x80); // XOUT=0, PACTL=1
|
||||||
|
#else
|
||||||
CYRF_WriteRegister(CYRF_0E_GPIO_CTRL,0x80); // XOUT=1, PACTL=0
|
CYRF_WriteRegister(CYRF_0E_GPIO_CTRL,0x80); // XOUT=1, PACTL=0
|
||||||
else
|
else
|
||||||
CYRF_WriteRegister(CYRF_0E_GPIO_CTRL,0x20); // XOUT=0, PACTL=1
|
CYRF_WriteRegister(CYRF_0E_GPIO_CTRL,0x20); // XOUT=0, PACTL=1
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -134,6 +138,7 @@ void CYRF_SetPower(uint8_t val)
|
|||||||
power=IS_POWER_FLAG_on?CYRF_HIGH_POWER:CYRF_LOW_POWER;
|
power=IS_POWER_FLAG_on?CYRF_HIGH_POWER:CYRF_LOW_POWER;
|
||||||
if(IS_RANGE_FLAG_on)
|
if(IS_RANGE_FLAG_on)
|
||||||
power=CYRF_RANGE_POWER;
|
power=CYRF_RANGE_POWER;
|
||||||
|
power|=val;
|
||||||
if(prev_power != power)
|
if(prev_power != power)
|
||||||
{
|
{
|
||||||
CYRF_WriteRegister(CYRF_03_TX_CFG, power);
|
CYRF_WriteRegister(CYRF_03_TX_CFG, power);
|
||||||
@ -236,13 +241,13 @@ void CYRF_FindBestChannels(uint8_t *channels, uint8_t len, uint8_t minspace, uin
|
|||||||
CYRF_ConfigCRCSeed(0x0000);
|
CYRF_ConfigCRCSeed(0x0000);
|
||||||
CYRF_SetTxRxMode(RX_EN);
|
CYRF_SetTxRxMode(RX_EN);
|
||||||
//Wait for pre-amp to switch from send to receive
|
//Wait for pre-amp to switch from send to receive
|
||||||
_delay_us(1000);
|
delayMilliseconds(1);
|
||||||
for(i = 0; i < NUM_FREQ; i++)
|
for(i = 0; i < NUM_FREQ; i++)
|
||||||
{
|
{
|
||||||
CYRF_ConfigRFChannel(i);
|
CYRF_ConfigRFChannel(i);
|
||||||
CYRF_ReadRegister(CYRF_13_RSSI);
|
CYRF_ReadRegister(CYRF_13_RSSI);
|
||||||
CYRF_StartReceive();
|
CYRF_StartReceive();
|
||||||
_delay_us(10);
|
delayMicroseconds(10);
|
||||||
rssi[i] = CYRF_ReadRegister(CYRF_13_RSSI);
|
rssi[i] = CYRF_ReadRegister(CYRF_13_RSSI);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,3 +266,37 @@ void CYRF_FindBestChannels(uint8_t *channels, uint8_t len, uint8_t minspace, uin
|
|||||||
}
|
}
|
||||||
CYRF_SetTxRxMode(TX_EN);
|
CYRF_SetTxRxMode(TX_EN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(DEVO_CYRF6936_INO) || defined(J6PRO_CYRF6936_INO)
|
||||||
|
const uint8_t PROGMEM DEVO_j6pro_sopcodes[][8] = {
|
||||||
|
/* Note these are in order transmitted (LSB 1st) */
|
||||||
|
{0x3C, 0x37, 0xCC, 0x91, 0xE2, 0xF8, 0xCC, 0x91},
|
||||||
|
{0x9B, 0xC5, 0xA1, 0x0F, 0xAD, 0x39, 0xA2, 0x0F},
|
||||||
|
{0xEF, 0x64, 0xB0, 0x2A, 0xD2, 0x8F, 0xB1, 0x2A},
|
||||||
|
{0x66, 0xCD, 0x7C, 0x50, 0xDD, 0x26, 0x7C, 0x50},
|
||||||
|
{0x5C, 0xE1, 0xF6, 0x44, 0xAD, 0x16, 0xF6, 0x44},
|
||||||
|
{0x5A, 0xCC, 0xAE, 0x46, 0xB6, 0x31, 0xAE, 0x46},
|
||||||
|
{0xA1, 0x78, 0xDC, 0x3C, 0x9E, 0x82, 0xDC, 0x3C},
|
||||||
|
{0xB9, 0x8E, 0x19, 0x74, 0x6F, 0x65, 0x18, 0x74},
|
||||||
|
{0xDF, 0xB1, 0xC0, 0x49, 0x62, 0xDF, 0xC1, 0x49},
|
||||||
|
{0x97, 0xE5, 0x14, 0x72, 0x7F, 0x1A, 0x14, 0x72},
|
||||||
|
#if defined(J6PRO_CYRF6936_INO)
|
||||||
|
{0x82, 0xC7, 0x90, 0x36, 0x21, 0x03, 0xFF, 0x17},
|
||||||
|
{0xE2, 0xF8, 0xCC, 0x91, 0x3C, 0x37, 0xCC, 0x91}, //Note: the '03' was '9E' in the Cypress recommended table
|
||||||
|
{0xAD, 0x39, 0xA2, 0x0F, 0x9B, 0xC5, 0xA1, 0x0F}, //The following are the same as the 1st 8 above,
|
||||||
|
{0xD2, 0x8F, 0xB1, 0x2A, 0xEF, 0x64, 0xB0, 0x2A}, //but with the upper and lower word swapped
|
||||||
|
{0xDD, 0x26, 0x7C, 0x50, 0x66, 0xCD, 0x7C, 0x50},
|
||||||
|
{0xAD, 0x16, 0xF6, 0x44, 0x5C, 0xE1, 0xF6, 0x44},
|
||||||
|
{0xB6, 0x31, 0xAE, 0x46, 0x5A, 0xCC, 0xAE, 0x46},
|
||||||
|
{0x9E, 0x82, 0xDC, 0x3C, 0xA1, 0x78, 0xDC, 0x3C},
|
||||||
|
{0x6F, 0x65, 0x18, 0x74, 0xB9, 0x8E, 0x19, 0x74},
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
static void __attribute__((unused)) CYRF_PROGMEM_ConfigSOPCode(const uint8_t *data)
|
||||||
|
{
|
||||||
|
uint8_t code[8];
|
||||||
|
for(uint8_t i=0;i<8;i++)
|
||||||
|
code[i]=pgm_read_byte_near(&data[i]);
|
||||||
|
CYRF_ConfigSOPCode(code);
|
||||||
|
}
|
||||||
|
620
Multiprotocol/DSM_cyrf6936.ino
Normal file
620
Multiprotocol/DSM_cyrf6936.ino
Normal file
@ -0,0 +1,620 @@
|
|||||||
|
/*
|
||||||
|
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(DSM_CYRF6936_INO)
|
||||||
|
|
||||||
|
#include "iface_cyrf6936.h"
|
||||||
|
|
||||||
|
#define DSM_BIND_CHANNEL 0x0d //13 This can be any odd channel
|
||||||
|
|
||||||
|
//During binding we will send BIND_COUNT/2 packets
|
||||||
|
//One packet each 10msec
|
||||||
|
#define DSM_BIND_COUNT 300
|
||||||
|
|
||||||
|
enum {
|
||||||
|
DSM_BIND_WRITE=0,
|
||||||
|
DSM_BIND_CHECK,
|
||||||
|
DSM_BIND_READ,
|
||||||
|
DSM_CHANSEL,
|
||||||
|
DSM_CH1_WRITE_A,
|
||||||
|
DSM_CH1_CHECK_A,
|
||||||
|
DSM_CH2_WRITE_A,
|
||||||
|
DSM_CH2_CHECK_A,
|
||||||
|
DSM_CH2_READ_A,
|
||||||
|
DSM_CH1_WRITE_B,
|
||||||
|
DSM_CH1_CHECK_B,
|
||||||
|
DSM_CH2_WRITE_B,
|
||||||
|
DSM_CH2_CHECK_B,
|
||||||
|
DSM_CH2_READ_B,
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
uint8_t sop_col;
|
||||||
|
uint8_t DSM_orx=0;
|
||||||
|
uint8_t DSM_num_ch=0;
|
||||||
|
uint8_t ch_map[14];
|
||||||
|
const uint8_t PROGMEM ch_map_progmem[][12] = {
|
||||||
|
{0, 1, 2, 3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, //Guess
|
||||||
|
{0, 1, 2, 3, 4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, //Guess
|
||||||
|
{1, 5, 2, 3, 0, 4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, //HP6DSM
|
||||||
|
{1, 5, 2, 4, 3, 6, 0, 0xff, 0xff, 0xff, 0xff, 0xff}, //DX6i
|
||||||
|
{1, 5, 2, 3, 6, 0xff, 0xff, 4, 0, 7, 0xff, 0xff}, //DX8
|
||||||
|
{3, 2, 1, 5, 0, 4, 6, 7, 8, 0xff, 0xff, 0xff}, //DM9
|
||||||
|
{3, 2, 1, 5, 0, 4, 6, 7, 8, 9, 0xff, 0xff}, //Guess
|
||||||
|
{3, 2, 1, 5, 0, 4, 6, 7, 8, 9, 10, 0xff}, //Guess
|
||||||
|
{3, 2, 1, 5, 0, 4, 6, 7, 8, 9, 10, 11} }; //Guess
|
||||||
|
|
||||||
|
const uint8_t PROGMEM pncodes[5][9][8] = {
|
||||||
|
/* Note these are in order transmitted (LSB 1st) */
|
||||||
|
{ /* Row 0 */
|
||||||
|
/* Col 0 */ {0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8},
|
||||||
|
/* Col 1 */ {0x88, 0x17, 0x13, 0x3B, 0x2D, 0xBF, 0x06, 0xD6},
|
||||||
|
/* Col 2 */ {0xF1, 0x94, 0x30, 0x21, 0xA1, 0x1C, 0x88, 0xA9},
|
||||||
|
/* Col 3 */ {0xD0, 0xD2, 0x8E, 0xBC, 0x82, 0x2F, 0xE3, 0xB4},
|
||||||
|
/* Col 4 */ {0x8C, 0xFA, 0x47, 0x9B, 0x83, 0xA5, 0x66, 0xD0},
|
||||||
|
/* Col 5 */ {0x07, 0xBD, 0x9F, 0x26, 0xC8, 0x31, 0x0F, 0xB8},
|
||||||
|
/* Col 6 */ {0xEF, 0x03, 0x95, 0x89, 0xB4, 0x71, 0x61, 0x9D},
|
||||||
|
/* Col 7 */ {0x40, 0xBA, 0x97, 0xD5, 0x86, 0x4F, 0xCC, 0xD1},
|
||||||
|
/* Col 8 */ {0xD7, 0xA1, 0x54, 0xB1, 0x5E, 0x89, 0xAE, 0x86}
|
||||||
|
},
|
||||||
|
{ /* Row 1 */
|
||||||
|
/* Col 0 */ {0x83, 0xF7, 0xA8, 0x2D, 0x7A, 0x44, 0x64, 0xD3},
|
||||||
|
/* Col 1 */ {0x3F, 0x2C, 0x4E, 0xAA, 0x71, 0x48, 0x7A, 0xC9},
|
||||||
|
/* Col 2 */ {0x17, 0xFF, 0x9E, 0x21, 0x36, 0x90, 0xC7, 0x82},
|
||||||
|
/* Col 3 */ {0xBC, 0x5D, 0x9A, 0x5B, 0xEE, 0x7F, 0x42, 0xEB},
|
||||||
|
/* Col 4 */ {0x24, 0xF5, 0xDD, 0xF8, 0x7A, 0x77, 0x74, 0xE7},
|
||||||
|
/* Col 5 */ {0x3D, 0x70, 0x7C, 0x94, 0xDC, 0x84, 0xAD, 0x95},
|
||||||
|
/* Col 6 */ {0x1E, 0x6A, 0xF0, 0x37, 0x52, 0x7B, 0x11, 0xD4},
|
||||||
|
/* Col 7 */ {0x62, 0xF5, 0x2B, 0xAA, 0xFC, 0x33, 0xBF, 0xAF},
|
||||||
|
/* Col 8 */ {0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97}
|
||||||
|
},
|
||||||
|
{ /* Row 2 */
|
||||||
|
/* Col 0 */ {0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97},
|
||||||
|
/* Col 1 */ {0x8E, 0x4A, 0xD0, 0xA9, 0xA7, 0xFF, 0x20, 0xCA},
|
||||||
|
/* Col 2 */ {0x4C, 0x97, 0x9D, 0xBF, 0xB8, 0x3D, 0xB5, 0xBE},
|
||||||
|
/* Col 3 */ {0x0C, 0x5D, 0x24, 0x30, 0x9F, 0xCA, 0x6D, 0xBD},
|
||||||
|
/* Col 4 */ {0x50, 0x14, 0x33, 0xDE, 0xF1, 0x78, 0x95, 0xAD},
|
||||||
|
/* Col 5 */ {0x0C, 0x3C, 0xFA, 0xF9, 0xF0, 0xF2, 0x10, 0xC9},
|
||||||
|
/* Col 6 */ {0xF4, 0xDA, 0x06, 0xDB, 0xBF, 0x4E, 0x6F, 0xB3},
|
||||||
|
/* Col 7 */ {0x9E, 0x08, 0xD1, 0xAE, 0x59, 0x5E, 0xE8, 0xF0},
|
||||||
|
/* Col 8 */ {0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E}
|
||||||
|
},
|
||||||
|
{ /* Row 3 */
|
||||||
|
/* Col 0 */ {0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E},
|
||||||
|
/* Col 1 */ {0x80, 0x69, 0x26, 0x80, 0x08, 0xF8, 0x49, 0xE7},
|
||||||
|
/* Col 2 */ {0x7D, 0x2D, 0x49, 0x54, 0xD0, 0x80, 0x40, 0xC1},
|
||||||
|
/* Col 3 */ {0xB6, 0xF2, 0xE6, 0x1B, 0x80, 0x5A, 0x36, 0xB4},
|
||||||
|
/* Col 4 */ {0x42, 0xAE, 0x9C, 0x1C, 0xDA, 0x67, 0x05, 0xF6},
|
||||||
|
/* Col 5 */ {0x9B, 0x75, 0xF7, 0xE0, 0x14, 0x8D, 0xB5, 0x80},
|
||||||
|
/* Col 6 */ {0xBF, 0x54, 0x98, 0xB9, 0xB7, 0x30, 0x5A, 0x88},
|
||||||
|
/* Col 7 */ {0x35, 0xD1, 0xFC, 0x97, 0x23, 0xD4, 0xC9, 0x88},
|
||||||
|
/* Col 8 */ {0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40, 0x93}
|
||||||
|
// Wrong values used by Orange TX/RX
|
||||||
|
// /* Col 8 */ {0x88, 0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40}
|
||||||
|
},
|
||||||
|
{ /* Row 4 */
|
||||||
|
/* Col 0 */ {0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40, 0x93},
|
||||||
|
/* Col 1 */ {0xDC, 0x68, 0x08, 0x99, 0x97, 0xAE, 0xAF, 0x8C},
|
||||||
|
/* Col 2 */ {0xC3, 0x0E, 0x01, 0x16, 0x0E, 0x32, 0x06, 0xBA},
|
||||||
|
/* Col 3 */ {0xE0, 0x83, 0x01, 0xFA, 0xAB, 0x3E, 0x8F, 0xAC},
|
||||||
|
/* Col 4 */ {0x5C, 0xD5, 0x9C, 0xB8, 0x46, 0x9C, 0x7D, 0x84},
|
||||||
|
/* Col 5 */ {0xF1, 0xC6, 0xFE, 0x5C, 0x9D, 0xA5, 0x4F, 0xB7},
|
||||||
|
/* Col 6 */ {0x58, 0xB5, 0xB3, 0xDD, 0x0E, 0x28, 0xF1, 0xB0},
|
||||||
|
/* Col 7 */ {0x5F, 0x30, 0x3B, 0x56, 0x96, 0x45, 0xF4, 0xA1},
|
||||||
|
/* Col 8 */ {0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __attribute__((unused)) read_code(uint8_t *buf, uint8_t row, uint8_t col, uint8_t len)
|
||||||
|
{
|
||||||
|
if(DSM_orx==1 && row==3 && col==7 && len==16)
|
||||||
|
{
|
||||||
|
uint8_t dec=0;
|
||||||
|
for(uint8_t i=0;i<len;i++)
|
||||||
|
{
|
||||||
|
if(i==8)
|
||||||
|
{
|
||||||
|
buf[8]=0x88;
|
||||||
|
dec=1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
buf[i]=pgm_read_byte_near( &pncodes[row][col][i-dec] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
for(uint8_t i=0;i<len;i++)
|
||||||
|
buf[i]=pgm_read_byte_near( &pncodes[row][col][i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t __attribute__((unused)) get_pn_row(uint8_t channel)
|
||||||
|
{
|
||||||
|
return ((sub_protocol == DSMX_11 || sub_protocol == DSMX_22 )? (channel - 2) % 5 : channel % 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t PROGMEM init_vals[][2] = {
|
||||||
|
{CYRF_02_TX_CTRL, 0x02}, //0x00 in deviation but needed to know when transmit is over
|
||||||
|
{CYRF_05_RX_CTRL, 0x00},
|
||||||
|
{CYRF_28_CLK_EN, 0x02},
|
||||||
|
{CYRF_32_AUTO_CAL_TIME, 0x3c},
|
||||||
|
{CYRF_35_AUTOCAL_OFFSET, 0x14},
|
||||||
|
{CYRF_06_RX_CFG, 0x4A},
|
||||||
|
{CYRF_1B_TX_OFFSET_LSB, 0x55},
|
||||||
|
{CYRF_1C_TX_OFFSET_MSB, 0x05},
|
||||||
|
{CYRF_0F_XACT_CFG, 0x24}, // Force Idle
|
||||||
|
{CYRF_03_TX_CFG, 0x38 | CYRF_BIND_POWER}, //Set 64chip, SDR mode
|
||||||
|
{CYRF_12_DATA64_THOLD, 0x0a},
|
||||||
|
{CYRF_0F_XACT_CFG, 0x04}, // Idle
|
||||||
|
{CYRF_39_ANALOG_CTRL, 0x01},
|
||||||
|
{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, 0x38 | CYRF_BIND_POWER}, //Set 64chip, SDR mode
|
||||||
|
{CYRF_10_FRAMING_CFG, 0x4E}, //0x4a}, //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, 0x02}, //set EOP sync == 2
|
||||||
|
{CYRF_01_TX_LENGTH, 0x10}, //16byte packet
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __attribute__((unused)) cyrf_config()
|
||||||
|
{
|
||||||
|
for(uint8_t i = 0; i < sizeof(init_vals) / 2; i++)
|
||||||
|
CYRF_WriteRegister(pgm_read_byte_near(&init_vals[i][0]), pgm_read_byte_near(&init_vals[i][1]));
|
||||||
|
CYRF_WritePreamble(0x333304);
|
||||||
|
CYRF_ConfigRFChannel(0x61);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) build_bind_packet()
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
uint16_t sum = 384 - 0x10;//
|
||||||
|
packet[0] = 0xff ^ cyrfmfg_id[0];
|
||||||
|
packet[1] = 0xff ^ cyrfmfg_id[1];
|
||||||
|
packet[2] = 0xff ^ cyrfmfg_id[2];
|
||||||
|
packet[3] = 0xff ^ cyrfmfg_id[3];
|
||||||
|
packet[4] = packet[0];
|
||||||
|
packet[5] = packet[1];
|
||||||
|
packet[6] = packet[2];
|
||||||
|
packet[7] = packet[3];
|
||||||
|
for(i = 0; i < 8; i++)
|
||||||
|
sum += packet[i];
|
||||||
|
packet[8] = sum >> 8;
|
||||||
|
packet[9] = sum & 0xff;
|
||||||
|
packet[10] = 0x01; //???
|
||||||
|
packet[11] = DSM_num_ch;
|
||||||
|
|
||||||
|
if (sub_protocol==DSM2_22)
|
||||||
|
packet[12]=DSM_num_ch<8?0x01:0x02; // DSM2/1024 1 or 2 packets depending on the number of channels
|
||||||
|
if(sub_protocol==DSM2_11)
|
||||||
|
packet[12]=0x12; // DSM2/2048 2 packets
|
||||||
|
if(sub_protocol==DSMX_22)
|
||||||
|
#if defined DSM_TELEMETRY
|
||||||
|
packet[12] = 0xb2; // DSMX/2048 2 packets
|
||||||
|
#else
|
||||||
|
packet[12] = DSM_num_ch<8? 0xa2 : 0xb2; // DSMX/2048 1 or 2 packets depending on the number of channels
|
||||||
|
#endif
|
||||||
|
if(sub_protocol==DSMX_11 || sub_protocol==DSM_AUTO) // Force DSMX/1024 in mode Auto
|
||||||
|
packet[12]=0xb2; // DSMX/1024 2 packets
|
||||||
|
|
||||||
|
packet[13] = 0x00; //???
|
||||||
|
for(i = 8; i < 14; i++)
|
||||||
|
sum += packet[i];
|
||||||
|
packet[14] = sum >> 8;
|
||||||
|
packet[15] = sum & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) initialize_bind_phase()
|
||||||
|
{
|
||||||
|
uint8_t code[32];
|
||||||
|
|
||||||
|
CYRF_ConfigRFChannel(DSM_BIND_CHANNEL); //This seems to be random?
|
||||||
|
uint8_t pn_row = get_pn_row(DSM_BIND_CHANNEL);
|
||||||
|
//printf("Ch: %d Row: %d SOP: %d Data: %d\n", DSM_BIND_CHANNEL, pn_row, sop_col, 7 - sop_col);
|
||||||
|
CYRF_ConfigCRCSeed(crc);
|
||||||
|
|
||||||
|
read_code(code,pn_row,sop_col,8);
|
||||||
|
CYRF_ConfigSOPCode(code);
|
||||||
|
read_code(code,pn_row,7 - sop_col,16);
|
||||||
|
read_code(code+16,0,8,8);
|
||||||
|
memcpy(code + 24, (void *)"\xc6\x94\x22\xfe\x48\xe6\x57\x4e", 8);
|
||||||
|
CYRF_ConfigDataCode(code, 32);
|
||||||
|
|
||||||
|
build_bind_packet();
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t PROGMEM data_vals[][2] = {
|
||||||
|
{CYRF_05_RX_CTRL, 0x83}, //Initialize for reading RSSI
|
||||||
|
{CYRF_29_RX_ABORT, 0x20},
|
||||||
|
{CYRF_0F_XACT_CFG, 0x24},
|
||||||
|
{CYRF_29_RX_ABORT, 0x00},
|
||||||
|
{CYRF_03_TX_CFG, 0x08 | CYRF_HIGH_POWER},
|
||||||
|
{CYRF_10_FRAMING_CFG, 0xea},
|
||||||
|
{CYRF_1F_TX_OVERRIDE, 0x00},
|
||||||
|
{CYRF_1E_RX_OVERRIDE, 0x00},
|
||||||
|
{CYRF_03_TX_CFG, 0x28 | CYRF_HIGH_POWER},
|
||||||
|
{CYRF_12_DATA64_THOLD, 0x3f},
|
||||||
|
{CYRF_10_FRAMING_CFG, 0xff},
|
||||||
|
{CYRF_0F_XACT_CFG, 0x24}, //Switch from reading RSSI to Writing
|
||||||
|
{CYRF_29_RX_ABORT, 0x00},
|
||||||
|
{CYRF_12_DATA64_THOLD, 0x0a},
|
||||||
|
{CYRF_10_FRAMING_CFG, 0xea},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __attribute__((unused)) cyrf_configdata()
|
||||||
|
{
|
||||||
|
for(uint8_t i = 0; i < sizeof(data_vals) / 2; i++)
|
||||||
|
CYRF_WriteRegister(pgm_read_byte_near(&data_vals[i][0]), pgm_read_byte_near(&data_vals[i][1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) update_channels()
|
||||||
|
{
|
||||||
|
prev_option=option;
|
||||||
|
if(sub_protocol==DSM_AUTO)
|
||||||
|
DSM_num_ch=12; // Force 12 channels in mode Auto
|
||||||
|
else
|
||||||
|
if(option&0x80)
|
||||||
|
{
|
||||||
|
DSM_num_ch=-option;
|
||||||
|
DSM_orx=1; // Use orange table
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DSM_num_ch=option;
|
||||||
|
DSM_orx=0; // Use normal table
|
||||||
|
}
|
||||||
|
if(DSM_num_ch<4 || DSM_num_ch>12)
|
||||||
|
DSM_num_ch=6; // Default to 6 channels if invalid choice...
|
||||||
|
|
||||||
|
// Create channel map based on number of channels
|
||||||
|
for(uint8_t i=0;i<12;i++)
|
||||||
|
ch_map[i]=pgm_read_byte_near(&ch_map_progmem[DSM_num_ch-4][i]);
|
||||||
|
ch_map[12]=0xFF;
|
||||||
|
ch_map[13]=0xFF;
|
||||||
|
// TODO: if DSM2_11 or DSMX_11 then repeat lower channels to upper channels need to rewrite this part
|
||||||
|
if(DSM_num_ch<8)
|
||||||
|
for(uint8_t i=7;i<14;i++)
|
||||||
|
ch_map[i]=ch_map[i-7];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) build_data_packet(uint8_t upper)
|
||||||
|
{
|
||||||
|
uint16_t max = 2047;
|
||||||
|
uint8_t bits = 11;
|
||||||
|
|
||||||
|
if(prev_option!=option)
|
||||||
|
update_channels();
|
||||||
|
|
||||||
|
if (sub_protocol==DSMX_11 || sub_protocol==DSMX_22 )
|
||||||
|
{
|
||||||
|
packet[0] = cyrfmfg_id[2];
|
||||||
|
packet[1] = cyrfmfg_id[3];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
packet[0] = (0xff ^ cyrfmfg_id[2]);
|
||||||
|
packet[1] = (0xff ^ cyrfmfg_id[3]);
|
||||||
|
if(sub_protocol==DSM2_22)
|
||||||
|
{
|
||||||
|
max=1023; // Only DSM_22 is using a resolution of 1024
|
||||||
|
bits=10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
uint8_t idx = ch_map[(upper?7:0) + i];//1,5,2,3,0,4
|
||||||
|
uint16_t value = 0xffff;;
|
||||||
|
if (idx != 0xff)
|
||||||
|
{
|
||||||
|
if (!IS_BIND_DONE_on)
|
||||||
|
{ // Failsafe position during binding
|
||||||
|
value=max/2; //all channels to middle
|
||||||
|
if(idx==0)
|
||||||
|
value=1; //except throttle
|
||||||
|
}
|
||||||
|
else
|
||||||
|
value=map(Servo_data[CH_TAER[idx]],servo_min_125,servo_max_125,0,max);
|
||||||
|
value |= (upper ? 0x8000 : 0) | (idx << bits);
|
||||||
|
}
|
||||||
|
packet[i*2+2] = (value >> 8) & 0xff;
|
||||||
|
packet[i*2+3] = (value >> 0) & 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) set_sop_data_crc()
|
||||||
|
{
|
||||||
|
//The crc for channel '1' is NOT(mfgid[0] << 8 + mfgid[1])
|
||||||
|
//The crc for channel '2' is (mfgid[0] << 8 + mfgid[1])
|
||||||
|
uint16_t crc = (cyrfmfg_id[0] << 8) + cyrfmfg_id[1];
|
||||||
|
if(phase==DSM_CH1_CHECK_A||phase==DSM_CH1_CHECK_B)
|
||||||
|
CYRF_ConfigCRCSeed(crc); //CH2
|
||||||
|
else
|
||||||
|
CYRF_ConfigCRCSeed(~crc); //CH1
|
||||||
|
|
||||||
|
uint8_t pn_row = get_pn_row(hopping_frequency[hopping_frequency_no]);
|
||||||
|
uint8_t code[16];
|
||||||
|
read_code(code,pn_row,sop_col,8);
|
||||||
|
CYRF_ConfigSOPCode(code);
|
||||||
|
read_code(code,pn_row,7 - sop_col,16);
|
||||||
|
CYRF_ConfigDataCode(code, 16);
|
||||||
|
|
||||||
|
CYRF_ConfigRFChannel(hopping_frequency[hopping_frequency_no]);
|
||||||
|
hopping_frequency_no++;
|
||||||
|
if(sub_protocol == DSMX_11 || sub_protocol == DSMX_22)
|
||||||
|
hopping_frequency_no %=23;
|
||||||
|
else
|
||||||
|
hopping_frequency_no %=2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) calc_dsmx_channel()
|
||||||
|
{
|
||||||
|
uint8_t idx = 0;
|
||||||
|
uint32_t id = ~(((uint32_t)cyrfmfg_id[0] << 24) | ((uint32_t)cyrfmfg_id[1] << 16) | ((uint32_t)cyrfmfg_id[2] << 8) | (cyrfmfg_id[3] << 0));
|
||||||
|
uint32_t id_tmp = id;
|
||||||
|
while(idx < 23)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
uint8_t count_3_27 = 0, count_28_51 = 0, count_52_76 = 0;
|
||||||
|
id_tmp = id_tmp * 0x0019660D + 0x3C6EF35F; // Randomization
|
||||||
|
uint8_t next_ch = ((id_tmp >> 8) % 0x49) + 3; // Use least-significant byte and must be larger than 3
|
||||||
|
if ( (next_ch ^ cyrfmfg_id[3]) & 0x01 )
|
||||||
|
continue;
|
||||||
|
for (i = 0; i < idx; i++)
|
||||||
|
{
|
||||||
|
if(hopping_frequency[i] == next_ch)
|
||||||
|
break;
|
||||||
|
if(hopping_frequency[i] <= 27)
|
||||||
|
count_3_27++;
|
||||||
|
else
|
||||||
|
if (hopping_frequency[i] <= 51)
|
||||||
|
count_28_51++;
|
||||||
|
else
|
||||||
|
count_52_76++;
|
||||||
|
}
|
||||||
|
if (i != idx)
|
||||||
|
continue;
|
||||||
|
if ((next_ch < 28 && count_3_27 < 8)
|
||||||
|
||(next_ch >= 28 && next_ch < 52 && count_28_51 < 7)
|
||||||
|
||(next_ch >= 52 && count_52_76 < 8))
|
||||||
|
hopping_frequency[idx++] = next_ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t __attribute__((unused)) DSM_Check_RX_packet()
|
||||||
|
{
|
||||||
|
uint8_t result=1; // assume good packet
|
||||||
|
|
||||||
|
uint16_t sum = 384 - 0x10;
|
||||||
|
for(uint8_t i = 1; i < 9; i++)
|
||||||
|
{
|
||||||
|
sum += pkt[i];
|
||||||
|
if(i<5)
|
||||||
|
if(pkt[i] != (0xff ^ cyrfmfg_id[i-1]))
|
||||||
|
result=0; // bad packet
|
||||||
|
}
|
||||||
|
if( pkt[9] != (sum>>8) && pkt[10] != (uint8_t)sum )
|
||||||
|
result=0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ReadDsm()
|
||||||
|
{
|
||||||
|
#define DSM_CH1_CH2_DELAY 4010 // Time between write of channel 1 and channel 2
|
||||||
|
#define DSM_WRITE_DELAY 1550 // Time after write to verify write complete
|
||||||
|
#define DSM_READ_DELAY 600 // Time before write to check read phase, and switch channels. Was 400 but 600 seems what the 328p needs to read a packet
|
||||||
|
uint16_t start;
|
||||||
|
#if defined DSM_TELEMETRY
|
||||||
|
uint8_t rx_phase;
|
||||||
|
uint8_t len;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch(phase)
|
||||||
|
{
|
||||||
|
case DSM_BIND_WRITE:
|
||||||
|
if(bind_counter--==0)
|
||||||
|
#if defined DSM_TELEMETRY
|
||||||
|
phase=DSM_BIND_CHECK; //Check RX answer
|
||||||
|
#else
|
||||||
|
phase=DSM_CHANSEL; //Switch to normal mode
|
||||||
|
#endif
|
||||||
|
CYRF_WriteDataPacket(packet);
|
||||||
|
return 10000;
|
||||||
|
#if defined DSM_TELEMETRY
|
||||||
|
case DSM_BIND_CHECK:
|
||||||
|
CYRF_ConfigDataCode((const uint8_t *)"\x98\x88\x1B\xE4\x30\x79\x03\x84\xC9\x2C\x06\x93\x86\xB9\x9E", 16);
|
||||||
|
CYRF_SetTxRxMode(RX_EN); //Receive mode
|
||||||
|
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x83); //Prepare to receive
|
||||||
|
bind_counter=300;
|
||||||
|
phase++; // change from BIND_CHECK to BIND_READ
|
||||||
|
return 2000;
|
||||||
|
case DSM_BIND_READ:
|
||||||
|
//Read data from RX
|
||||||
|
rx_phase = CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
|
||||||
|
if((rx_phase & 0x03) == 0x02) // RXC=1, RXE=0 then 2nd check is required (debouncing)
|
||||||
|
rx_phase |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
|
||||||
|
if((rx_phase & 0x07) == 0x02)
|
||||||
|
{ // data received
|
||||||
|
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // need to set RXOW before data read
|
||||||
|
len=CYRF_ReadRegister(CYRF_09_RX_COUNT);
|
||||||
|
if(len>MAX_PKT-2)
|
||||||
|
len=MAX_PKT-2;
|
||||||
|
CYRF_ReadDataPacketLen(pkt+1, len);
|
||||||
|
if(len==10 && DSM_Check_RX_packet())
|
||||||
|
{
|
||||||
|
pkt[0]=0x80;
|
||||||
|
telemetry_link=1; // send received data on serial
|
||||||
|
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20);
|
||||||
|
CYRF_SetTxRxMode(TX_EN); // Write mode
|
||||||
|
phase++;
|
||||||
|
return 2000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Force end read phase
|
||||||
|
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x2C); // Force end phase
|
||||||
|
start=micros();
|
||||||
|
while ((uint16_t)micros()-start < 100) // Wait max 100 µs
|
||||||
|
if((CYRF_ReadRegister(CYRF_0F_XACT_CFG) & 0x20) == 0)
|
||||||
|
break;
|
||||||
|
if( --bind_counter == 0 )
|
||||||
|
{
|
||||||
|
phase++; // Exit if no answer has been received for some time
|
||||||
|
return 7000 ;
|
||||||
|
}
|
||||||
|
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x0C); // Read mode
|
||||||
|
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x83); // Prepare to receive
|
||||||
|
return 7000;
|
||||||
|
#endif
|
||||||
|
case DSM_CHANSEL:
|
||||||
|
BIND_DONE;
|
||||||
|
cyrf_configdata();
|
||||||
|
CYRF_SetTxRxMode(TX_EN);
|
||||||
|
hopping_frequency_no = 0;
|
||||||
|
phase = DSM_CH1_WRITE_A; // in fact phase++
|
||||||
|
set_sop_data_crc();
|
||||||
|
return 10000;
|
||||||
|
case DSM_CH1_WRITE_A:
|
||||||
|
case DSM_CH1_WRITE_B:
|
||||||
|
case DSM_CH2_WRITE_A:
|
||||||
|
case DSM_CH2_WRITE_B:
|
||||||
|
build_data_packet(phase == DSM_CH1_WRITE_B||phase == DSM_CH2_WRITE_B); // build lower or upper channels
|
||||||
|
CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS); // clear IRQ flags
|
||||||
|
CYRF_WriteDataPacket(packet);
|
||||||
|
phase++; // change from WRITE to CHECK mode
|
||||||
|
return DSM_WRITE_DELAY;
|
||||||
|
case DSM_CH1_CHECK_A:
|
||||||
|
case DSM_CH1_CHECK_B:
|
||||||
|
start=micros();
|
||||||
|
while ((uint16_t)micros()-start < 500) // Wait max 500µs
|
||||||
|
if(CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x02)
|
||||||
|
break;
|
||||||
|
set_sop_data_crc();
|
||||||
|
phase++; // change from CH1_CHECK to CH2_WRITE
|
||||||
|
return DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY;
|
||||||
|
case DSM_CH2_CHECK_A:
|
||||||
|
case DSM_CH2_CHECK_B:
|
||||||
|
start=micros();
|
||||||
|
while ((uint16_t)micros()-start < 500) // Wait max 500µs
|
||||||
|
if(CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x02)
|
||||||
|
break;
|
||||||
|
if (phase == DSM_CH2_CHECK_A)
|
||||||
|
CYRF_SetPower(0x28); //Keep transmit power in sync
|
||||||
|
#if defined DSM_TELEMETRY
|
||||||
|
phase++; // change from CH2_CHECK to CH2_READ
|
||||||
|
CYRF_SetTxRxMode(RX_EN); //Receive mode
|
||||||
|
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //0x80??? //Prepare to receive
|
||||||
|
return 11000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY - DSM_READ_DELAY;
|
||||||
|
case DSM_CH2_READ_A:
|
||||||
|
case DSM_CH2_READ_B:
|
||||||
|
//Read telemetry
|
||||||
|
rx_phase = CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
|
||||||
|
if((rx_phase & 0x03) == 0x02) // RXC=1, RXE=0 then 2nd check is required (debouncing)
|
||||||
|
rx_phase |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
|
||||||
|
if((rx_phase & 0x07) == 0x02)
|
||||||
|
{ // good data (complete with no errors)
|
||||||
|
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // need to set RXOW before data read
|
||||||
|
len=CYRF_ReadRegister(CYRF_09_RX_COUNT);
|
||||||
|
if(len>MAX_PKT-2)
|
||||||
|
len=MAX_PKT-2;
|
||||||
|
CYRF_ReadDataPacketLen(pkt+1, len);
|
||||||
|
pkt[0]=CYRF_ReadRegister(CYRF_13_RSSI)&0x1F;// store RSSI of the received telemetry signal
|
||||||
|
telemetry_link=1;
|
||||||
|
}
|
||||||
|
if (phase == DSM_CH2_READ_A && (sub_protocol==DSM2_22 || sub_protocol==DSMX_22) && DSM_num_ch < 8) // 22ms mode
|
||||||
|
{
|
||||||
|
//Force end read phase
|
||||||
|
CYRF_WriteRegister(CYRF_0F_XACT_CFG, (CYRF_ReadRegister(CYRF_0F_XACT_CFG) | 0x20)); // Force end phase
|
||||||
|
start=micros();
|
||||||
|
while ((uint16_t)micros()-start < 100) // Wait max 100 µs
|
||||||
|
if((CYRF_ReadRegister(CYRF_0F_XACT_CFG) & 0x20) == 0)
|
||||||
|
break;
|
||||||
|
phase = DSM_CH2_READ_B;
|
||||||
|
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //0x80??? //Prepare to receive
|
||||||
|
return 11000;
|
||||||
|
}
|
||||||
|
if (phase == DSM_CH2_READ_A)
|
||||||
|
phase = DSM_CH1_WRITE_B; //Transmit upper
|
||||||
|
else
|
||||||
|
phase = DSM_CH1_WRITE_A; //Transmit lower
|
||||||
|
CYRF_SetTxRxMode(TX_EN); //Write mode
|
||||||
|
set_sop_data_crc();
|
||||||
|
return DSM_READ_DELAY;
|
||||||
|
#else
|
||||||
|
// No telemetry
|
||||||
|
set_sop_data_crc();
|
||||||
|
if (phase == DSM_CH2_CHECK_A)
|
||||||
|
{
|
||||||
|
if(DSM_num_ch > 7 || sub_protocol==DSM2_11 || sub_protocol==DSMX_11)
|
||||||
|
phase = DSM_CH1_WRITE_B; //11ms mode or upper to transmit change from CH2_CHECK_A to CH1_WRITE_A
|
||||||
|
else
|
||||||
|
{ //Normal mode 22ms
|
||||||
|
phase = DSM_CH1_WRITE_A; // change from CH2_CHECK_A to CH1_WRITE_A (ie no upper)
|
||||||
|
return 22000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
phase = DSM_CH1_WRITE_A; // change from CH2_CHECK_B to CH1_WRITE_A (upper already transmitted so transmit lower)
|
||||||
|
return 11000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t initDsm()
|
||||||
|
{
|
||||||
|
CYRF_GetMfgData(cyrfmfg_id);//
|
||||||
|
//Model match
|
||||||
|
cyrfmfg_id[3]+=RX_num;
|
||||||
|
|
||||||
|
cyrf_config();
|
||||||
|
|
||||||
|
if (sub_protocol == DSMX_11 || sub_protocol == DSMX_22)
|
||||||
|
calc_dsmx_channel();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint8_t tmpch[10];
|
||||||
|
CYRF_FindBestChannels(tmpch, 10, 5, 3, 75);
|
||||||
|
//
|
||||||
|
uint8_t idx = random(0xfefefefe) % 10;
|
||||||
|
hopping_frequency[0] = tmpch[idx];
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
idx = random(0xfefefefe) % 10;
|
||||||
|
if (tmpch[idx] != hopping_frequency[0])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
hopping_frequency[1] = tmpch[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
sop_col = (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + 2) & 0x07;
|
||||||
|
|
||||||
|
CYRF_SetTxRxMode(TX_EN);
|
||||||
|
//
|
||||||
|
update_channels();
|
||||||
|
if(IS_AUTOBIND_FLAG_on )
|
||||||
|
{
|
||||||
|
BIND_IN_PROGRESS;
|
||||||
|
initialize_bind_phase();
|
||||||
|
phase = DSM_BIND_WRITE;
|
||||||
|
bind_counter=DSM_BIND_COUNT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
phase = DSM_CHANSEL;//
|
||||||
|
return 10000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -43,28 +43,6 @@ enum {
|
|||||||
DEVO_BOUND_10,
|
DEVO_BOUND_10,
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t PROGMEM DEVO_sopcodes[][8] = {
|
|
||||||
/* Note these are in order transmitted (LSB 1st) */
|
|
||||||
/* 0 */ {0x3C,0x37,0xCC,0x91,0xE2,0xF8,0xCC,0x91}, //0x91CCF8E291CC373C
|
|
||||||
/* 1 */ {0x9B,0xC5,0xA1,0x0F,0xAD,0x39,0xA2,0x0F}, //0x0FA239AD0FA1C59B
|
|
||||||
/* 2 */ {0xEF,0x64,0xB0,0x2A,0xD2,0x8F,0xB1,0x2A}, //0x2AB18FD22AB064EF
|
|
||||||
/* 3 */ {0x66,0xCD,0x7C,0x50,0xDD,0x26,0x7C,0x50}, //0x507C26DD507CCD66
|
|
||||||
/* 4 */ {0x5C,0xE1,0xF6,0x44,0xAD,0x16,0xF6,0x44}, //0x44F616AD44F6E15C
|
|
||||||
/* 5 */ {0x5A,0xCC,0xAE,0x46,0xB6,0x31,0xAE,0x46}, //0x46AE31B646AECC5A
|
|
||||||
/* 6 */ {0xA1,0x78,0xDC,0x3C,0x9E,0x82,0xDC,0x3C}, //0x3CDC829E3CDC78A1
|
|
||||||
/* 7 */ {0xB9,0x8E,0x19,0x74,0x6F,0x65,0x18,0x74}, //0x7418656F74198EB9
|
|
||||||
/* 8 */ {0xDF,0xB1,0xC0,0x49,0x62,0xDF,0xC1,0x49}, //0x49C1DF6249C0B1DF
|
|
||||||
/* 9 */ {0x97,0xE5,0x14,0x72,0x7F,0x1A,0x14,0x72}, //0x72141A7F7214E597
|
|
||||||
};
|
|
||||||
|
|
||||||
static void __attribute__((unused)) DEVO_ConfigSOPCode(uint8_t val)
|
|
||||||
{
|
|
||||||
uint8_t code[8];
|
|
||||||
for(uint8_t i=0;i<8;i++)
|
|
||||||
code[i]=pgm_read_byte_near(&DEVO_sopcodes[val][i]);
|
|
||||||
CYRF_ConfigSOPCode(code);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) DEVO_scramble_pkt()
|
static void __attribute__((unused)) DEVO_scramble_pkt()
|
||||||
{
|
{
|
||||||
#ifdef NO_SCRAMBLE
|
#ifdef NO_SCRAMBLE
|
||||||
@ -185,7 +163,7 @@ static void __attribute__((unused)) DEVO_cyrf_set_bound_sop_code()
|
|||||||
uint8_t sopidx = (0xff &((cyrfmfg_id[0] << 2) + cyrfmfg_id[1] + cyrfmfg_id[2])) % 10;
|
uint8_t sopidx = (0xff &((cyrfmfg_id[0] << 2) + cyrfmfg_id[1] + cyrfmfg_id[2])) % 10;
|
||||||
CYRF_SetTxRxMode(TX_EN);
|
CYRF_SetTxRxMode(TX_EN);
|
||||||
CYRF_ConfigCRCSeed((crc << 8) + crc);
|
CYRF_ConfigCRCSeed((crc << 8) + crc);
|
||||||
DEVO_ConfigSOPCode(sopidx);
|
CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[sopidx]);
|
||||||
CYRF_SetPower(0x08);
|
CYRF_SetPower(0x08);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,7 +295,7 @@ uint16_t DevoInit()
|
|||||||
CYRF_GetMfgData(cyrfmfg_id);
|
CYRF_GetMfgData(cyrfmfg_id);
|
||||||
CYRF_SetTxRxMode(TX_EN);
|
CYRF_SetTxRxMode(TX_EN);
|
||||||
CYRF_ConfigCRCSeed(0x0000);
|
CYRF_ConfigCRCSeed(0x0000);
|
||||||
DEVO_ConfigSOPCode(0);
|
CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[0]);
|
||||||
DEVO_set_radio_channels();
|
DEVO_set_radio_channels();
|
||||||
|
|
||||||
hopping_frequency_ptr = hopping_frequency;
|
hopping_frequency_ptr = hopping_frequency;
|
||||||
|
@ -35,7 +35,7 @@ static void __attribute__((unused)) ESKY_init(uint8_t bind)
|
|||||||
NRF24L01_Initialize();
|
NRF24L01_Initialize();
|
||||||
|
|
||||||
// 2-bytes CRC, radio off
|
// 2-bytes CRC, radio off
|
||||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO));
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO));
|
||||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgement
|
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgement
|
||||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0
|
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0
|
||||||
if (bind)
|
if (bind)
|
||||||
|
@ -105,7 +105,7 @@ uint16_t FY326_callback()
|
|||||||
switch (phase)
|
switch (phase)
|
||||||
{
|
{
|
||||||
case FY326_BIND1:
|
case FY326_BIND1:
|
||||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR))
|
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||||
{ // RX fifo data ready
|
{ // RX fifo data ready
|
||||||
NRF24L01_ReadPayload(packet, FY326_PACKET_SIZE);
|
NRF24L01_ReadPayload(packet, FY326_PACKET_SIZE);
|
||||||
rxid = packet[13];
|
rxid = packet[13];
|
||||||
@ -127,7 +127,7 @@ uint16_t FY326_callback()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FY326_BIND2:
|
case FY326_BIND2:
|
||||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_TX_DS))
|
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS))
|
||||||
{ // TX data sent -> switch to RX mode
|
{ // TX data sent -> switch to RX mode
|
||||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||||
NRF24L01_FlushRx();
|
NRF24L01_FlushRx();
|
||||||
|
@ -50,16 +50,11 @@ enum {
|
|||||||
FLAG_V912_BTMBTN= 0x80,
|
FLAG_V912_BTMBTN= 0x80,
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t chanrow;
|
|
||||||
uint8_t chancol;
|
|
||||||
uint8_t chanoffset;
|
|
||||||
|
|
||||||
const uint8_t PROGMEM V912_X17_SEQ[10] = { 0x14, 0x31, 0x40, 0x49, 0x49, // sometime first byte is 0x15 ?
|
const uint8_t PROGMEM V912_X17_SEQ[10] = { 0x14, 0x31, 0x40, 0x49, 0x49, // sometime first byte is 0x15 ?
|
||||||
0x49, 0x49, 0x49, 0x49, 0x49, };
|
0x49, 0x49, 0x49, 0x49, 0x49, };
|
||||||
|
|
||||||
static void __attribute__((unused)) flysky_apply_extension_flags()
|
static void __attribute__((unused)) flysky_apply_extension_flags()
|
||||||
{
|
{
|
||||||
|
|
||||||
static uint8_t seq_counter;
|
static uint8_t seq_counter;
|
||||||
switch(sub_protocol)
|
switch(sub_protocol)
|
||||||
{
|
{
|
||||||
@ -144,34 +139,14 @@ static void __attribute__((unused)) flysky_build_packet(uint8_t init)
|
|||||||
packet[2] = rx_tx_addr[2];
|
packet[2] = rx_tx_addr[2];
|
||||||
packet[3] = rx_tx_addr[1];
|
packet[3] = rx_tx_addr[1];
|
||||||
packet[4] = rx_tx_addr[0];
|
packet[4] = rx_tx_addr[0];
|
||||||
const uint8_t ch[]={AILERON, ELEVATOR, THROTTLE, RUDDER, AUX1, AUX2, AUX3, AUX4};
|
|
||||||
for(i = 0; i < 8; i++)
|
for(i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
packet[5 + i*2]=Servo_data[ch[i]]&0xFF; //low byte of servo timing(1000-2000us)
|
packet[5 + i*2]=Servo_data[CH_AETR[i]]&0xFF; //low byte of servo timing(1000-2000us)
|
||||||
packet[6 + i*2]=(Servo_data[ch[i]]>>8)&0xFF; //high byte of servo timing(1000-2000us)
|
packet[6 + i*2]=(Servo_data[CH_AETR[i]]>>8)&0xFF; //high byte of servo timing(1000-2000us)
|
||||||
}
|
}
|
||||||
flysky_apply_extension_flags();
|
flysky_apply_extension_flags();
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t PROGMEM tx_channels[16][16] = {
|
|
||||||
{0x0a, 0x5a, 0x14, 0x64, 0x1e, 0x6e, 0x28, 0x78, 0x32, 0x82, 0x3c, 0x8c, 0x46, 0x96, 0x50, 0xa0},
|
|
||||||
{0xa0, 0x50, 0x96, 0x46, 0x8c, 0x3c, 0x82, 0x32, 0x78, 0x28, 0x6e, 0x1e, 0x64, 0x14, 0x5a, 0x0a},
|
|
||||||
{0x0a, 0x5a, 0x50, 0xa0, 0x14, 0x64, 0x46, 0x96, 0x1e, 0x6e, 0x3c, 0x8c, 0x28, 0x78, 0x32, 0x82},
|
|
||||||
{0x82, 0x32, 0x78, 0x28, 0x8c, 0x3c, 0x6e, 0x1e, 0x96, 0x46, 0x64, 0x14, 0xa0, 0x50, 0x5a, 0x0a},
|
|
||||||
{0x28, 0x78, 0x0a, 0x5a, 0x50, 0xa0, 0x14, 0x64, 0x1e, 0x6e, 0x3c, 0x8c, 0x32, 0x82, 0x46, 0x96},
|
|
||||||
{0x96, 0x46, 0x82, 0x32, 0x8c, 0x3c, 0x6e, 0x1e, 0x64, 0x14, 0xa0, 0x50, 0x5a, 0x0a, 0x78, 0x28},
|
|
||||||
{0x50, 0xa0, 0x28, 0x78, 0x0a, 0x5a, 0x1e, 0x6e, 0x3c, 0x8c, 0x32, 0x82, 0x46, 0x96, 0x14, 0x64},
|
|
||||||
{0x64, 0x14, 0x96, 0x46, 0x82, 0x32, 0x8c, 0x3c, 0x6e, 0x1e, 0x5a, 0x0a, 0x78, 0x28, 0xa0, 0x50},
|
|
||||||
{0x50, 0xa0, 0x46, 0x96, 0x3c, 0x8c, 0x28, 0x78, 0x0a, 0x5a, 0x32, 0x82, 0x1e, 0x6e, 0x14, 0x64},
|
|
||||||
{0x64, 0x14, 0x6e, 0x1e, 0x82, 0x32, 0x5a, 0x0a, 0x78, 0x28, 0x8c, 0x3c, 0x96, 0x46, 0xa0, 0x50},
|
|
||||||
{0x46, 0x96, 0x3c, 0x8c, 0x50, 0xa0, 0x28, 0x78, 0x0a, 0x5a, 0x1e, 0x6e, 0x32, 0x82, 0x14, 0x64},
|
|
||||||
{0x64, 0x14, 0x82, 0x32, 0x6e, 0x1e, 0x5a, 0x0a, 0x78, 0x28, 0xa0, 0x50, 0x8c, 0x3c, 0x96, 0x46},
|
|
||||||
{0x46, 0x96, 0x0a, 0x5a, 0x3c, 0x8c, 0x14, 0x64, 0x50, 0xa0, 0x28, 0x78, 0x1e, 0x6e, 0x32, 0x82},
|
|
||||||
{0x82, 0x32, 0x6e, 0x1e, 0x78, 0x28, 0xa0, 0x50, 0x64, 0x14, 0x8c, 0x3c, 0x5a, 0x0a, 0x96, 0x46},
|
|
||||||
{0x46, 0x96, 0x0a, 0x5a, 0x50, 0xa0, 0x3c, 0x8c, 0x28, 0x78, 0x1e, 0x6e, 0x32, 0x82, 0x14, 0x64},
|
|
||||||
{0x64, 0x14, 0x82, 0x32, 0x6e, 0x1e, 0x78, 0x28, 0x8c, 0x3c, 0xa0, 0x50, 0x5a, 0x0a, 0x96, 0x46},
|
|
||||||
};
|
|
||||||
|
|
||||||
uint16_t ReadFlySky()
|
uint16_t ReadFlySky()
|
||||||
{
|
{
|
||||||
if (bind_counter)
|
if (bind_counter)
|
||||||
@ -185,28 +160,56 @@ uint16_t ReadFlySky()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
flysky_build_packet(0);
|
flysky_build_packet(0);
|
||||||
A7105_WriteData(21, pgm_read_byte_near(&tx_channels[chanrow][chancol])-chanoffset);
|
A7105_WriteData(21, hopping_frequency[hopping_frequency_no]);
|
||||||
chancol = (chancol + 1) % 16;
|
hopping_frequency_no = (hopping_frequency_no + 1) & 0x0F;
|
||||||
if (! chancol) //Keep transmit power updated
|
|
||||||
A7105_SetPower();
|
A7105_SetPower();
|
||||||
}
|
}
|
||||||
return 1510; //1460 on deviation but not working with the latest V911 bricks... Turnigy 9X v2 is 1533, Flysky TX for 9XR/9XR Pro is 1510, V911 TX is 1490.
|
return 1510; //1460 on deviation but not working with the latest V911 bricks... Turnigy 9X v2 is 1533, Flysky TX for 9XR/9XR Pro is 1510, V911 TX is 1490.
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t initFlySky() {
|
const uint8_t PROGMEM tx_channels[8][4] = {
|
||||||
|
{ 0x12, 0x34, 0x56, 0x78},
|
||||||
|
{ 0x18, 0x27, 0x36, 0x45},
|
||||||
|
{ 0x41, 0x82, 0x36, 0x57},
|
||||||
|
{ 0x84, 0x13, 0x65, 0x72},
|
||||||
|
{ 0x87, 0x64, 0x15, 0x32},
|
||||||
|
{ 0x76, 0x84, 0x13, 0x52},
|
||||||
|
{ 0x71, 0x62, 0x84, 0x35},
|
||||||
|
{ 0x71, 0x86, 0x43, 0x52}
|
||||||
|
};
|
||||||
|
|
||||||
|
uint16_t initFlySky()
|
||||||
|
{
|
||||||
|
uint8_t chanrow;
|
||||||
|
uint8_t chanoffset;
|
||||||
|
uint8_t temp;
|
||||||
|
|
||||||
A7105_Init(INIT_FLYSKY); //flysky_init();
|
A7105_Init(INIT_FLYSKY); //flysky_init();
|
||||||
|
|
||||||
if ((rx_tx_addr[3]&0xF0) > 0x90) // limit offset to 9 as higher values don't work with some RX (ie V912)
|
if ((rx_tx_addr[3]&0xF0) > 0x90) // limit offset to 9 as higher values don't work with some RX (ie V912)
|
||||||
rx_tx_addr[3]=rx_tx_addr[3]-0x70;
|
rx_tx_addr[3]=rx_tx_addr[3]-0x70;
|
||||||
chanrow=rx_tx_addr[3] & 0x0F;
|
chanrow=rx_tx_addr[3] & 0x0F;
|
||||||
chancol=0;
|
|
||||||
chanoffset=rx_tx_addr[3]/16;
|
chanoffset=rx_tx_addr[3]/16;
|
||||||
|
|
||||||
|
// Build frequency hop table
|
||||||
|
for(uint8_t i=0;i<16;i++)
|
||||||
|
{
|
||||||
|
temp=pgm_read_byte_near(&tx_channels[chanrow>>1][i>>2]);
|
||||||
|
if(i&0x01)
|
||||||
|
temp&=0x0F;
|
||||||
|
else
|
||||||
|
temp>>=4;
|
||||||
|
temp*=0x0A;
|
||||||
|
if(i&0x02)
|
||||||
|
temp+=0x50;
|
||||||
|
hopping_frequency[((chanrow&1)?15-i:i)]=temp-chanoffset;
|
||||||
|
}
|
||||||
|
hopping_frequency_no=0;
|
||||||
|
|
||||||
if(IS_AUTOBIND_FLAG_on)
|
if(IS_AUTOBIND_FLAG_on)
|
||||||
bind_counter = FLYSKY_BIND_COUNT;
|
bind_counter = FLYSKY_BIND_COUNT;
|
||||||
else
|
else
|
||||||
bind_counter = 0;
|
bind_counter = 0;
|
||||||
return 2400;
|
return 2400;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -13,30 +13,13 @@
|
|||||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(FRSKY_CC2500_INO)
|
#if defined(FRSKYD_CC2500_INO)
|
||||||
|
|
||||||
#include "iface_cc2500.h"
|
#include "iface_cc2500.h"
|
||||||
|
|
||||||
//##########Variables########
|
|
||||||
//uint32_t state;
|
|
||||||
//uint8_t len;
|
|
||||||
|
|
||||||
/*
|
|
||||||
enum {
|
|
||||||
FRSKY_BIND = 0,
|
|
||||||
FRSKY_BIND_DONE = 1000,
|
|
||||||
FRSKY_DATA1,
|
|
||||||
FRSKY_DATA2,
|
|
||||||
FRSKY_DATA3,
|
|
||||||
FRSKY_DATA4,
|
|
||||||
FRSKY_DATA5
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void __attribute__((unused)) frsky2way_init(uint8_t bind)
|
static void __attribute__((unused)) frsky2way_init(uint8_t bind)
|
||||||
{
|
{
|
||||||
// Configure cc2500 for tx mode
|
// Configure cc2500 for tx mode
|
||||||
CC2500_Reset();
|
|
||||||
//
|
//
|
||||||
for(uint8_t i=0;i<36;i++)
|
for(uint8_t i=0;i<36;i++)
|
||||||
{
|
{
|
||||||
@ -51,6 +34,7 @@ static void __attribute__((unused)) frsky2way_init(uint8_t bind)
|
|||||||
CC2500_WriteReg(reg,val);
|
CC2500_WriteReg(reg,val);
|
||||||
}
|
}
|
||||||
prev_option = option ;
|
prev_option = option ;
|
||||||
|
|
||||||
CC2500_SetTxRxMode(TX_EN);
|
CC2500_SetTxRxMode(TX_EN);
|
||||||
CC2500_SetPower();
|
CC2500_SetPower();
|
||||||
|
|
||||||
@ -143,7 +127,7 @@ uint16_t initFrSky_2way()
|
|||||||
if(IS_AUTOBIND_FLAG_on)
|
if(IS_AUTOBIND_FLAG_on)
|
||||||
{
|
{
|
||||||
frsky2way_init(1);
|
frsky2way_init(1);
|
||||||
state = FRSKY_BIND;//
|
state = FRSKY_BIND;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -206,14 +190,13 @@ uint16_t ReadFrSky_2way()
|
|||||||
CC2500_SetTxRxMode(TX_EN);
|
CC2500_SetTxRxMode(TX_EN);
|
||||||
CC2500_SetPower(); // Set tx_power
|
CC2500_SetPower(); // Set tx_power
|
||||||
}
|
}
|
||||||
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
|
CC2500_WriteReg(CC2500_0A_CHANNR, get_chan_num(counter % 47));
|
||||||
if ( prev_option != option )
|
if ( prev_option != option )
|
||||||
{
|
{
|
||||||
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack
|
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack
|
||||||
prev_option = option ;
|
prev_option = option ;
|
||||||
}
|
}
|
||||||
CC2500_Strobe(CC2500_SIDLE);
|
|
||||||
CC2500_WriteReg(CC2500_0A_CHANNR, get_chan_num(counter % 47));
|
|
||||||
CC2500_WriteReg(CC2500_23_FSCAL3, 0x89);
|
CC2500_WriteReg(CC2500_23_FSCAL3, 0x89);
|
||||||
CC2500_Strobe(CC2500_SFRX);
|
CC2500_Strobe(CC2500_SFRX);
|
||||||
frsky2way_data_frame();
|
frsky2way_data_frame();
|
||||||
|
@ -3,10 +3,12 @@
|
|||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
Multiprotocol is distributed in the hope that it will be useful,
|
Multiprotocol is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
uint8_t chanskip;
|
uint8_t chanskip;
|
||||||
uint8_t counter_rst;
|
uint8_t counter_rst;
|
||||||
uint8_t ctr;
|
uint8_t ctr;
|
||||||
uint8_t FS_flag=0;
|
|
||||||
uint8_t seq_last_sent;
|
uint8_t seq_last_sent;
|
||||||
uint8_t seq_last_rcvd;
|
uint8_t seq_last_rcvd;
|
||||||
|
|
||||||
@ -90,8 +89,6 @@ static void __attribute__((unused)) set_start(uint8_t ch )
|
|||||||
|
|
||||||
static void __attribute__((unused)) frskyX_init()
|
static void __attribute__((unused)) frskyX_init()
|
||||||
{
|
{
|
||||||
CC2500_Reset();
|
|
||||||
|
|
||||||
for(uint8_t i=0;i<36;i++)
|
for(uint8_t i=0;i<36;i++)
|
||||||
{
|
{
|
||||||
uint8_t reg=pgm_read_byte_near(&cc2500_conf[i][0]);
|
uint8_t reg=pgm_read_byte_near(&cc2500_conf[i][0]);
|
||||||
@ -215,10 +212,10 @@ static void __attribute__((unused)) frskyX_data_frame()
|
|||||||
packet[4] = (ctr<<6)+hopping_frequency_no;
|
packet[4] = (ctr<<6)+hopping_frequency_no;
|
||||||
packet[5] = counter_rst;
|
packet[5] = counter_rst;
|
||||||
packet[6] = RX_num;
|
packet[6] = RX_num;
|
||||||
//FLAGS 00 - standard packet
|
//packet[7] = FLAGS 00 - standard packet
|
||||||
//10, 12, 14, 16, 18, 1A, 1C, 1E - failsafe packet
|
//10, 12, 14, 16, 18, 1A, 1C, 1E - failsafe packet
|
||||||
//20 - range check packet
|
//20 - range check packet
|
||||||
packet[7] = FS_flag;
|
packet[7] = 0;
|
||||||
packet[8] = 0;
|
packet[8] = 0;
|
||||||
//
|
//
|
||||||
if ( lpass & 1 )
|
if ( lpass & 1 )
|
||||||
@ -286,7 +283,7 @@ uint16_t ReadFrSkyX()
|
|||||||
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack
|
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack
|
||||||
prev_option = option ;
|
prev_option = option ;
|
||||||
}
|
}
|
||||||
LED_ON;
|
LED_on;
|
||||||
CC2500_SetTxRxMode(TX_EN);
|
CC2500_SetTxRxMode(TX_EN);
|
||||||
set_start(hopping_frequency_no);
|
set_start(hopping_frequency_no);
|
||||||
CC2500_SetPower();
|
CC2500_SetPower();
|
||||||
@ -341,8 +338,6 @@ uint16_t initFrSkyX()
|
|||||||
{
|
{
|
||||||
#if defined STM32_board
|
#if defined STM32_board
|
||||||
randomSeed((uint32_t)analogRead(PB0) << 10 | analogRead(PB1));
|
randomSeed((uint32_t)analogRead(PB0) << 10 | analogRead(PB1));
|
||||||
#else
|
|
||||||
randomSeed((uint32_t)analogRead(A6) << 10 | analogRead(A7));
|
|
||||||
#endif
|
#endif
|
||||||
chanskip=random(0xfefefefe)%47;
|
chanskip=random(0xfefefefe)%47;
|
||||||
}
|
}
|
||||||
|
@ -120,9 +120,8 @@ static void __attribute__((unused)) build_ch_data()
|
|||||||
{
|
{
|
||||||
uint16_t temp;
|
uint16_t temp;
|
||||||
uint8_t i,j;
|
uint8_t i,j;
|
||||||
const uint8_t ch[]={AILERON, ELEVATOR, THROTTLE, RUDDER, AUX1, AUX2, AUX3, AUX4};
|
|
||||||
for (i = 0; i< 8; i++) {
|
for (i = 0; i< 8; i++) {
|
||||||
j=ch[i];
|
j=CH_AETR[i];
|
||||||
temp=map(limit_channel_100(j),servo_min_100,servo_max_100,0,1000);
|
temp=map(limit_channel_100(j),servo_min_100,servo_max_100,0,1000);
|
||||||
if (j == THROTTLE) // It is clear that hisky's throttle stick is made reversely, so I adjust it here on purpose
|
if (j == THROTTLE) // It is clear that hisky's throttle stick is made reversely, so I adjust it here on purpose
|
||||||
temp = 1000 -temp;
|
temp = 1000 -temp;
|
||||||
|
@ -121,7 +121,7 @@ static void __attribute__((unused)) HONTAI_send_packet(uint8_t bind)
|
|||||||
if(sub_protocol == FORMAT_JJRCX1)
|
if(sub_protocol == FORMAT_JJRCX1)
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
else
|
else
|
||||||
XN297_Configure(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP));
|
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||||
|
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? HONTAI_RF_BIND_CHANNEL : hopping_frequency[hopping_frequency_no++]);
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? HONTAI_RF_BIND_CHANNEL : hopping_frequency[hopping_frequency_no++]);
|
||||||
hopping_frequency_no %= 3;
|
hopping_frequency_no %= 3;
|
||||||
|
@ -347,8 +347,6 @@ uint16_t initHubsan() {
|
|||||||
|
|
||||||
#if defined STM32_board
|
#if defined STM32_board
|
||||||
randomSeed((uint32_t)analogRead(PB0) << 10 | analogRead(PB1));
|
randomSeed((uint32_t)analogRead(PB0) << 10 | analogRead(PB1));
|
||||||
#else
|
|
||||||
randomSeed((uint32_t)analogRead(A6) << 10 | analogRead(A7));
|
|
||||||
#endif
|
#endif
|
||||||
sessionid = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16);
|
sessionid = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16);
|
||||||
channel = allowed_ch[random(0xfefefefe) % sizeof(allowed_ch)];
|
channel = allowed_ch[random(0xfefefefe) % sizeof(allowed_ch)];
|
||||||
|
@ -35,30 +35,8 @@ enum PktState {
|
|||||||
J6PRO_CHAN_4,
|
J6PRO_CHAN_4,
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t j6pro_sopcodes[][8] = {
|
const uint8_t PROGMEM j6pro_bind_sop_code[] = {0x62, 0xdf, 0xc1, 0x49, 0xdf, 0xb1, 0xc0, 0x49};
|
||||||
/* Note these are in order transmitted (LSB 1st) */
|
const uint8_t j6pro_data_code[] = {0x02, 0xf9, 0x93, 0x97, 0x02, 0xfa, 0x5c, 0xe3, 0x01, 0x2b, 0xf1, 0xdb, 0x01, 0x32, 0xbe, 0x6f};
|
||||||
{0x3C, 0x37, 0xCC, 0x91, 0xE2, 0xF8, 0xCC, 0x91},
|
|
||||||
{0x9B, 0xC5, 0xA1, 0x0F, 0xAD, 0x39, 0xA2, 0x0F},
|
|
||||||
{0xEF, 0x64, 0xB0, 0x2A, 0xD2, 0x8F, 0xB1, 0x2A},
|
|
||||||
{0x66, 0xCD, 0x7C, 0x50, 0xDD, 0x26, 0x7C, 0x50},
|
|
||||||
{0x5C, 0xE1, 0xF6, 0x44, 0xAD, 0x16, 0xF6, 0x44},
|
|
||||||
{0x5A, 0xCC, 0xAE, 0x46, 0xB6, 0x31, 0xAE, 0x46},
|
|
||||||
{0xA1, 0x78, 0xDC, 0x3C, 0x9E, 0x82, 0xDC, 0x3C},
|
|
||||||
{0xB9, 0x8E, 0x19, 0x74, 0x6F, 0x65, 0x18, 0x74},
|
|
||||||
{0xDF, 0xB1, 0xC0, 0x49, 0x62, 0xDF, 0xC1, 0x49},
|
|
||||||
{0x97, 0xE5, 0x14, 0x72, 0x7F, 0x1A, 0x14, 0x72},
|
|
||||||
{0x82, 0xC7, 0x90, 0x36, 0x21, 0x03, 0xFF, 0x17},
|
|
||||||
{0xE2, 0xF8, 0xCC, 0x91, 0x3C, 0x37, 0xCC, 0x91}, //Note: the '03' was '9E' in the Cypress recommended table
|
|
||||||
{0xAD, 0x39, 0xA2, 0x0F, 0x9B, 0xC5, 0xA1, 0x0F}, //The following are the same as the 1st 8 above,
|
|
||||||
{0xD2, 0x8F, 0xB1, 0x2A, 0xEF, 0x64, 0xB0, 0x2A}, //but with the upper and lower word swapped
|
|
||||||
{0xDD, 0x26, 0x7C, 0x50, 0x66, 0xCD, 0x7C, 0x50},
|
|
||||||
{0xAD, 0x16, 0xF6, 0x44, 0x5C, 0xE1, 0xF6, 0x44},
|
|
||||||
{0xB6, 0x31, 0xAE, 0x46, 0x5A, 0xCC, 0xAE, 0x46},
|
|
||||||
{0x9E, 0x82, 0xDC, 0x3C, 0xA1, 0x78, 0xDC, 0x3C},
|
|
||||||
{0x6F, 0x65, 0x18, 0x74, 0xB9, 0x8E, 0x19, 0x74},
|
|
||||||
};
|
|
||||||
const uint8_t bind_sop_code[] = {0x62, 0xdf, 0xc1, 0x49, 0xdf, 0xb1, 0xc0, 0x49};
|
|
||||||
const uint8_t data_code[] = {0x02, 0xf9, 0x93, 0x97, 0x02, 0xfa, 0x5c, 0xe3, 0x01, 0x2b, 0xf1, 0xdb, 0x01, 0x32, 0xbe, 0x6f};
|
|
||||||
|
|
||||||
static void __attribute__((unused)) j6pro_build_bind_packet()
|
static void __attribute__((unused)) j6pro_build_bind_packet()
|
||||||
{
|
{
|
||||||
@ -106,7 +84,7 @@ static void __attribute__((unused)) j6pro_cyrf_init()
|
|||||||
CYRF_WriteRegister(CYRF_10_FRAMING_CFG, 0xee);
|
CYRF_WriteRegister(CYRF_10_FRAMING_CFG, 0xee);
|
||||||
CYRF_WriteRegister(CYRF_1F_TX_OVERRIDE, 0x00);
|
CYRF_WriteRegister(CYRF_1F_TX_OVERRIDE, 0x00);
|
||||||
CYRF_WriteRegister(CYRF_1E_RX_OVERRIDE, 0x00);
|
CYRF_WriteRegister(CYRF_1E_RX_OVERRIDE, 0x00);
|
||||||
CYRF_ConfigDataCode(data_code, 16);
|
CYRF_ConfigDataCode(j6pro_data_code, 16);
|
||||||
CYRF_WritePreamble(0x023333);
|
CYRF_WritePreamble(0x023333);
|
||||||
|
|
||||||
CYRF_GetMfgData(cyrfmfg_id);
|
CYRF_GetMfgData(cyrfmfg_id);
|
||||||
@ -121,7 +99,7 @@ static void __attribute__((unused)) cyrf_bindinit()
|
|||||||
CYRF_SetPower(0x28); //Deviation using max power, replaced by bind power...
|
CYRF_SetPower(0x28); //Deviation using max power, replaced by bind power...
|
||||||
|
|
||||||
CYRF_ConfigRFChannel(0x52);
|
CYRF_ConfigRFChannel(0x52);
|
||||||
CYRF_ConfigSOPCode(bind_sop_code);
|
CYRF_PROGMEM_ConfigSOPCode(j6pro_bind_sop_code);
|
||||||
CYRF_ConfigCRCSeed(0x0000);
|
CYRF_ConfigCRCSeed(0x0000);
|
||||||
CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a);
|
CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a);
|
||||||
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x83);
|
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x83);
|
||||||
@ -144,7 +122,7 @@ static void __attribute__((unused)) cyrf_datainit()
|
|||||||
uint16_t crc = (0xff & (cyrfmfg_id[1] - cyrfmfg_id[4] + cyrfmfg_id[5])) |
|
uint16_t 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);
|
((0xff & (cyrfmfg_id[2] + cyrfmfg_id[3] - cyrfmfg_id[4] + cyrfmfg_id[5])) << 8);
|
||||||
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x25);
|
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x25);
|
||||||
CYRF_ConfigSOPCode(j6pro_sopcodes[sop_idx]);
|
CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[sop_idx]);
|
||||||
CYRF_ConfigCRCSeed(crc);
|
CYRF_ConfigCRCSeed(crc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,7 +235,6 @@ uint16_t ReadJ6Pro()
|
|||||||
|
|
||||||
uint16_t initJ6Pro()
|
uint16_t initJ6Pro()
|
||||||
{
|
{
|
||||||
CYRF_Reset();
|
|
||||||
j6pro_cyrf_init();
|
j6pro_cyrf_init();
|
||||||
|
|
||||||
if(IS_AUTOBIND_FLAG_on) {
|
if(IS_AUTOBIND_FLAG_on) {
|
||||||
|
@ -246,7 +246,7 @@ static void __attribute__((unused)) kn_init()
|
|||||||
|
|
||||||
NRF24L01_Initialize();
|
NRF24L01_Initialize();
|
||||||
|
|
||||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO));
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO));
|
||||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement
|
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement
|
||||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0
|
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0
|
||||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
|
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
|
||||||
@ -259,7 +259,7 @@ static void __attribute__((unused)) kn_init()
|
|||||||
NRF24L01_Activate(0x73);
|
NRF24L01_Activate(0x73);
|
||||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 1); // Dynamic payload for data pipe 0
|
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 1); // Dynamic payload for data pipe 0
|
||||||
// Enable: Dynamic Payload Length to enable PCF
|
// Enable: Dynamic Payload Length to enable PCF
|
||||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, BV(NRF2401_1D_EN_DPL));
|
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, _BV(NRF2401_1D_EN_DPL));
|
||||||
|
|
||||||
NRF24L01_SetPower();
|
NRF24L01_SetPower();
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
// compatible with MJX WLH08, X600, X800, H26D
|
// compatible with MJX WLH08, X600, X800, H26D, Eachine E010
|
||||||
// Last sync with hexfet new_protocols/mjxq_nrf24l01.c dated 2016-01-17
|
// Last sync with hexfet new_protocols/mjxq_nrf24l01.c dated 2016-01-17
|
||||||
|
|
||||||
#if defined(MJXQ_NRF24L01_INO)
|
#if defined(MJXQ_NRF24L01_INO)
|
||||||
@ -26,6 +26,17 @@
|
|||||||
#define MJXQ_RF_NUM_CHANNELS 4
|
#define MJXQ_RF_NUM_CHANNELS 4
|
||||||
#define MJXQ_ADDRESS_LENGTH 5
|
#define MJXQ_ADDRESS_LENGTH 5
|
||||||
|
|
||||||
|
// haven't figured out txid<-->rf channel mapping for MJX models
|
||||||
|
const uint8_t PROGMEM MJXQ_map_rfchan[][4] = {
|
||||||
|
{0x0A, 0x46, 0x3A, 0x42},
|
||||||
|
{0x0A, 0x3C, 0x36, 0x3F},
|
||||||
|
{0x0A, 0x43, 0x36, 0x3F} };
|
||||||
|
const uint8_t PROGMEM MJXQ_map_txid[][3] = {
|
||||||
|
{0xF8, 0x4F, 0x1C},
|
||||||
|
{0xC8, 0x6E, 0x02},
|
||||||
|
{0x48, 0x6A, 0x40} };
|
||||||
|
|
||||||
|
|
||||||
#define MJXQ_PAN_TILT_COUNT 16 // for H26D - match stock tx timing
|
#define MJXQ_PAN_TILT_COUNT 16 // for H26D - match stock tx timing
|
||||||
#define MJXQ_PAN_DOWN 0x08
|
#define MJXQ_PAN_DOWN 0x08
|
||||||
#define MJXQ_PAN_UP 0x04
|
#define MJXQ_PAN_UP 0x04
|
||||||
@ -39,14 +50,14 @@ static uint8_t __attribute__((unused)) MJXQ_pan_tilt_value()
|
|||||||
packet_count++;
|
packet_count++;
|
||||||
if(packet_count & MJXQ_PAN_TILT_COUNT)
|
if(packet_count & MJXQ_PAN_TILT_COUNT)
|
||||||
{
|
{
|
||||||
if(Servo_AUX8)
|
if(Servo_data[AUX8]>PPM_MAX_COMMAND)
|
||||||
pan=MJXQ_PAN_UP;
|
pan=MJXQ_PAN_UP;
|
||||||
if(Servo_data[AUX8]<PPM_MIN_COMMAND)
|
if(Servo_data[AUX8]<PPM_MIN_COMMAND)
|
||||||
pan=MJXQ_PAN_DOWN;
|
pan=MJXQ_PAN_DOWN;
|
||||||
if(Servo_data[AUX9]>PPM_MIN_COMMAND)
|
if(Servo_data[AUX9]>PPM_MAX_COMMAND)
|
||||||
pan=MJXQ_TILT_UP;
|
pan+=MJXQ_TILT_UP;
|
||||||
if(Servo_data[AUX9]<PPM_MIN_COMMAND)
|
if(Servo_data[AUX9]<PPM_MIN_COMMAND)
|
||||||
pan=MJXQ_TILT_DOWN;
|
pan+=MJXQ_TILT_DOWN;
|
||||||
}
|
}
|
||||||
return pan;
|
return pan;
|
||||||
}
|
}
|
||||||
@ -57,10 +68,10 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
|
|||||||
packet[0] = convert_channel_8b(THROTTLE);
|
packet[0] = convert_channel_8b(THROTTLE);
|
||||||
packet[1] = convert_channel_s8b(RUDDER);
|
packet[1] = convert_channel_s8b(RUDDER);
|
||||||
packet[4] = 0x40; // rudder does not work well with dyntrim
|
packet[4] = 0x40; // rudder does not work well with dyntrim
|
||||||
packet[2] = convert_channel_s8b(ELEVATOR);
|
packet[2] = 0x80 ^ convert_channel_s8b(ELEVATOR);
|
||||||
packet[5] = MJXQ_CHAN2TRIM(packet[2]); // trim elevator
|
packet[5] = GET_FLAG(Servo_AUX5, 1) ? 0x40 : MJXQ_CHAN2TRIM(packet[2]); // trim elevator
|
||||||
packet[3] = convert_channel_s8b(AILERON);
|
packet[3] = convert_channel_s8b(AILERON);
|
||||||
packet[6] = MJXQ_CHAN2TRIM(packet[3]); // trim aileron
|
packet[6] = GET_FLAG(Servo_AUX5, 1) ? 0x40 : MJXQ_CHAN2TRIM(packet[3]); // trim aileron
|
||||||
packet[7] = rx_tx_addr[0];
|
packet[7] = rx_tx_addr[0];
|
||||||
packet[8] = rx_tx_addr[1];
|
packet[8] = rx_tx_addr[1];
|
||||||
packet[9] = rx_tx_addr[2];
|
packet[9] = rx_tx_addr[2];
|
||||||
@ -85,17 +96,6 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
|
|||||||
packet[10]=MJXQ_pan_tilt_value();
|
packet[10]=MJXQ_pan_tilt_value();
|
||||||
// fall through on purpose - no break
|
// fall through on purpose - no break
|
||||||
case WLH08:
|
case WLH08:
|
||||||
packet[10] += GET_FLAG(Servo_AUX6, 0x02) //RTH
|
|
||||||
| GET_FLAG(Servo_AUX5, 0x01); //HEADLESS
|
|
||||||
if (!bind)
|
|
||||||
{
|
|
||||||
packet[14] = 0x04
|
|
||||||
| GET_FLAG(Servo_AUX1, 0x01) //FLIP
|
|
||||||
| GET_FLAG(Servo_AUX3, 0x08) //PICTURE
|
|
||||||
| GET_FLAG(Servo_AUX4, 0x10) //VIDEO
|
|
||||||
| GET_FLAG(!Servo_AUX2, 0x20); // air/ground mode
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case E010:
|
case E010:
|
||||||
packet[10] += GET_FLAG(Servo_AUX6, 0x02) //RTH
|
packet[10] += GET_FLAG(Servo_AUX6, 0x02) //RTH
|
||||||
| GET_FLAG(Servo_AUX5, 0x01); //HEADLESS
|
| GET_FLAG(Servo_AUX5, 0x01); //HEADLESS
|
||||||
@ -109,11 +109,6 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case X600:
|
case X600:
|
||||||
if(Servo_AUX5) //HEADLESS
|
|
||||||
{ // driven trims cause issues when headless is enabled
|
|
||||||
packet[5] = 0x40;
|
|
||||||
packet[6] = 0x40;
|
|
||||||
}
|
|
||||||
packet[10] = GET_FLAG(!Servo_AUX2, 0x02); //LED
|
packet[10] = GET_FLAG(!Servo_AUX2, 0x02); //LED
|
||||||
packet[11] = GET_FLAG(Servo_AUX6, 0x01); //RTH
|
packet[11] = GET_FLAG(Servo_AUX6, 0x01); //RTH
|
||||||
if (!bind)
|
if (!bind)
|
||||||
@ -147,7 +142,7 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
|
|||||||
if (sub_protocol == H26D)
|
if (sub_protocol == H26D)
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
else
|
else
|
||||||
XN297_Configure(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP));
|
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||||
|
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++ / 2]);
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++ / 2]);
|
||||||
hopping_frequency_no %= 2 * MJXQ_RF_NUM_CHANNELS; // channels repeated
|
hopping_frequency_no %= 2 * MJXQ_RF_NUM_CHANNELS; // channels repeated
|
||||||
@ -170,12 +165,12 @@ static void __attribute__((unused)) MJXQ_init()
|
|||||||
if (sub_protocol == WLH08)
|
if (sub_protocol == WLH08)
|
||||||
memcpy(hopping_frequency, "\x12\x22\x32\x42", MJXQ_RF_NUM_CHANNELS);
|
memcpy(hopping_frequency, "\x12\x22\x32\x42", MJXQ_RF_NUM_CHANNELS);
|
||||||
else
|
else
|
||||||
if (sub_protocol == H26D)
|
if (sub_protocol == H26D || sub_protocol == E010)
|
||||||
memcpy(hopping_frequency, "\x36\x3e\x46\x2e", MJXQ_RF_NUM_CHANNELS);
|
memcpy(hopping_frequency, "\x36\x3e\x46\x2e", MJXQ_RF_NUM_CHANNELS);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy(hopping_frequency, "\x0a\x35\x42\x3d", MJXQ_RF_NUM_CHANNELS);
|
memcpy(hopping_frequency, "\x0a\x35\x42\x3d", MJXQ_RF_NUM_CHANNELS);
|
||||||
memcpy(addr, "\x6d\x6a\x73\x73\x73", MJXQ_RF_NUM_CHANNELS);
|
memcpy(addr, "\x6d\x6a\x73\x73\x73", MJXQ_ADDRESS_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -194,35 +189,34 @@ static void __attribute__((unused)) MJXQ_init()
|
|||||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
||||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, MJXQ_PACKET_SIZE); // rx pipe 0 (used only for blue board)
|
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, MJXQ_PACKET_SIZE); // rx pipe 0 (used only for blue board)
|
||||||
|
if (sub_protocol == E010)
|
||||||
|
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250K
|
||||||
|
else
|
||||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||||
NRF24L01_SetPower();
|
NRF24L01_SetPower();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((unused)) MJXQ_init2()
|
static void __attribute__((unused)) MJXQ_init2()
|
||||||
{
|
{
|
||||||
// haven't figured out txid<-->rf channel mapping for MJX models
|
|
||||||
static const uint8_t rf_map[][4] = {
|
|
||||||
{0x0A, 0x46, 0x3A, 0x42},
|
|
||||||
{0x0A, 0x3C, 0x36, 0x3F},
|
|
||||||
{0x0A, 0x43, 0x36, 0x3F} };
|
|
||||||
if (sub_protocol == H26D)
|
if (sub_protocol == H26D)
|
||||||
memcpy(hopping_frequency, "\x32\x3e\x42\x4e", MJXQ_RF_NUM_CHANNELS);
|
memcpy(hopping_frequency, "\x32\x3e\x42\x4e", MJXQ_RF_NUM_CHANNELS);
|
||||||
else
|
else
|
||||||
if (sub_protocol == WLH08)
|
if (sub_protocol != WLH08 && sub_protocol != E010)
|
||||||
memcpy(hopping_frequency, rf_map[rx_tx_addr[0]%3], MJXQ_RF_NUM_CHANNELS);
|
for(uint8_t i=0;i<MJXQ_RF_NUM_CHANNELS;i++)
|
||||||
|
hopping_frequency[i]=pgm_read_byte_near( &MJXQ_map_rfchan[rx_tx_addr[4]%3][i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((unused)) MJXQ_initialize_txid()
|
static void __attribute__((unused)) MJXQ_initialize_txid()
|
||||||
{
|
{
|
||||||
// haven't figured out txid<-->rf channel mapping for MJX models
|
rx_tx_addr[0]&=0xF8;
|
||||||
static const uint8_t tx_map[][3]={
|
if (sub_protocol == E010)
|
||||||
{0xF8, 0x4F, 0x1C},
|
{
|
||||||
{0xC8, 0x6E, 0x02},
|
rx_tx_addr[1]=(rx_tx_addr[1]&0xF0)|0x0C;
|
||||||
{0x48, 0x6A, 0x40} };
|
rx_tx_addr[2]&=0xF0;
|
||||||
if (sub_protocol == WLH08)
|
}
|
||||||
rx_tx_addr[0]&=0xF8; // txid must be multiple of 8
|
|
||||||
else
|
else
|
||||||
memcpy(rx_tx_addr,tx_map[rx_tx_addr[0]%3],3);
|
for(uint8_t i=0;i<3;i++)
|
||||||
|
rx_tx_addr[i]=pgm_read_byte_near( &MJXQ_map_txid[rx_tx_addr[4]%3][i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t MJXQ_callback()
|
uint16_t MJXQ_callback()
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
// compatible with MT99xx, Eachine H7, Yi Zhan i6S
|
// compatible with MT99xx, Eachine H7, Yi Zhan i6S and LS114/124
|
||||||
// Last sync with Goebish mt99xx_nrf24l01.c dated 2016-01-29
|
// Last sync with Goebish mt99xx_nrf24l01.c dated 2016-01-29
|
||||||
|
|
||||||
#if defined(MT99XX_NRF24L01_INO)
|
#if defined(MT99XX_NRF24L01_INO)
|
||||||
@ -53,34 +53,54 @@ enum {
|
|||||||
MT99XX_DATA
|
MT99XX_DATA
|
||||||
};
|
};
|
||||||
|
|
||||||
static void __attribute__((unused)) MT99XX_send_packet()
|
const uint8_t h7_mys_byte[] = {
|
||||||
{
|
|
||||||
const uint8_t yz_p4_seq[] = {0xa0, 0x20, 0x60};
|
|
||||||
const uint8_t mys_byte[] = {
|
|
||||||
0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 0x04, 0x14,
|
0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 0x04, 0x14,
|
||||||
0x05, 0x15, 0x06, 0x16, 0x07, 0x17, 0x00, 0x10
|
0x05, 0x15, 0x06, 0x16, 0x07, 0x17, 0x00, 0x10
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const uint8_t ls_mys_byte[] = {
|
||||||
|
0x05, 0x15, 0x25, 0x06, 0x16, 0x26,
|
||||||
|
0x07, 0x17, 0x27, 0x00, 0x10, 0x20,
|
||||||
|
0x01, 0x11, 0x21, 0x02, 0x12, 0x22,
|
||||||
|
0x03, 0x13, 0x23, 0x04, 0x14, 0x24
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __attribute__((unused)) MT99XX_send_packet()
|
||||||
|
{
|
||||||
|
const uint8_t yz_p4_seq[] = {0xa0, 0x20, 0x60};
|
||||||
static uint8_t yz_seq_num=0;
|
static uint8_t yz_seq_num=0;
|
||||||
|
static uint8_t ls_counter=0;
|
||||||
|
|
||||||
if(sub_protocol != YZ)
|
if(sub_protocol != YZ)
|
||||||
{ // MT99XX & H7
|
{ // MT99XX & H7 & LS
|
||||||
packet[0] = convert_channel_8b_scale(THROTTLE,0x00,0xE1); // throttle
|
packet[0] = convert_channel_8b_scale(THROTTLE,0xE1,0x00); // throttle
|
||||||
packet[1] = convert_channel_8b_scale(RUDDER ,0x00,0xE1); // rudder
|
packet[1] = convert_channel_8b_scale(RUDDER ,0x00,0xE1); // rudder
|
||||||
packet[2] = convert_channel_8b_scale(AILERON ,0x00,0xE1); // aileron
|
packet[2] = convert_channel_8b_scale(AILERON ,0xE1,0x00); // aileron
|
||||||
packet[3] = convert_channel_8b_scale(ELEVATOR,0x00,0xE1); // elevator
|
packet[3] = convert_channel_8b_scale(ELEVATOR,0x00,0xE1); // elevator
|
||||||
packet[4] = 0x20; // pitch trim (0x3f-0x20-0x00)
|
packet[4] = 0x20; // pitch trim (0x3f-0x20-0x00)
|
||||||
packet[5] = 0x20; // roll trim (0x00-0x20-0x3f)
|
packet[5] = 0x20; // roll trim (0x00-0x20-0x3f)
|
||||||
packet[6] = GET_FLAG( Servo_AUX1, FLAG_MT_FLIP )
|
packet[6] = GET_FLAG( Servo_AUX1, FLAG_MT_FLIP );
|
||||||
| GET_FLAG( Servo_AUX3, FLAG_MT_SNAPSHOT )
|
packet[7] = h7_mys_byte[hopping_frequency_no]; // next rf channel index ?
|
||||||
| GET_FLAG( Servo_AUX4, FLAG_MT_VIDEO );
|
|
||||||
if(sub_protocol==MT99)
|
if(sub_protocol==H7)
|
||||||
packet[6] |= 0x40 | FLAG_MT_RATE2;
|
|
||||||
else
|
|
||||||
packet[6] |= FLAG_MT_RATE1; // max rate on H7
|
packet[6] |= FLAG_MT_RATE1; // max rate on H7
|
||||||
// todo: mys_byte = next channel index ?
|
else
|
||||||
// low nibble: index in chan list ?
|
if(sub_protocol==MT99)
|
||||||
// high nibble: 0->start from start of list, 1->start from end of list ?
|
packet[6] |= 0x40 | FLAG_MT_RATE2
|
||||||
packet[7] = mys_byte[hopping_frequency_no];
|
| GET_FLAG( Servo_AUX3, FLAG_MT_SNAPSHOT )
|
||||||
|
| GET_FLAG( Servo_AUX4, FLAG_MT_VIDEO ); // max rate on MT99xx
|
||||||
|
else //LS
|
||||||
|
{
|
||||||
|
packet[6] |= FLAG_LS_RATE // max rate
|
||||||
|
| GET_FLAG( Servo_AUX2, FLAG_LS_INVERT ) //INVERT
|
||||||
|
| GET_FLAG( Servo_AUX3, FLAG_LS_SNAPSHOT ) //SNAPSHOT
|
||||||
|
| GET_FLAG( Servo_AUX4, FLAG_LS_VIDEO ) //VIDEO
|
||||||
|
| GET_FLAG( Servo_AUX5, FLAG_LS_HEADLESS ); //HEADLESS
|
||||||
|
packet[7] = ls_mys_byte[ls_counter++];
|
||||||
|
if(ls_counter >= sizeof(ls_mys_byte))
|
||||||
|
ls_counter=0;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t result=checksum_offset;
|
uint8_t result=checksum_offset;
|
||||||
for(uint8_t i=0; i<8; i++)
|
for(uint8_t i=0; i<8; i++)
|
||||||
result += packet[i];
|
result += packet[i];
|
||||||
@ -89,9 +109,9 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
|||||||
else
|
else
|
||||||
{ // YZ
|
{ // YZ
|
||||||
packet[0] = convert_channel_8b_scale(THROTTLE,0x00,0x64); // throttle
|
packet[0] = convert_channel_8b_scale(THROTTLE,0x00,0x64); // throttle
|
||||||
packet[1] = convert_channel_8b_scale(RUDDER ,0x00,0x64); // rudder
|
packet[1] = convert_channel_8b_scale(RUDDER ,0x64,0x00); // rudder
|
||||||
packet[2] = convert_channel_8b_scale(ELEVATOR,0x00,0x64); // elevator
|
packet[2] = convert_channel_8b_scale(ELEVATOR,0x00,0x64); // elevator
|
||||||
packet[3] = convert_channel_8b_scale(AILERON ,0x00,0x64); // aileron
|
packet[3] = convert_channel_8b_scale(AILERON ,0x64,0x00); // aileron
|
||||||
if(packet_count++ >= 23)
|
if(packet_count++ >= 23)
|
||||||
{
|
{
|
||||||
yz_seq_num ++;
|
yz_seq_num ++;
|
||||||
@ -111,6 +131,7 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
|||||||
packet[7] += packet[idx];
|
packet[7] += packet[idx];
|
||||||
packet[8] = 0xff;
|
packet[8] = 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sub_protocol == LS)
|
if(sub_protocol == LS)
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x2D); // LS always transmits on the same channel
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x2D); // LS always transmits on the same channel
|
||||||
else
|
else
|
||||||
@ -132,8 +153,11 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
|||||||
static void __attribute__((unused)) MT99XX_init()
|
static void __attribute__((unused)) MT99XX_init()
|
||||||
{
|
{
|
||||||
NRF24L01_Initialize();
|
NRF24L01_Initialize();
|
||||||
|
if(sub_protocol == YZ)
|
||||||
|
XN297_SetScrambledMode(XN297_UNSCRAMBLED);
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
NRF24L01_FlushTx();
|
NRF24L01_FlushTx();
|
||||||
|
XN297_SetTXAddr((uint8_t *)"\xCC\xCC\xCC\xCC\xCC", 5);
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
|
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
|
||||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||||
@ -145,7 +169,7 @@ static void __attribute__((unused)) MT99XX_init()
|
|||||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||||
NRF24L01_SetPower();
|
NRF24L01_SetPower();
|
||||||
|
|
||||||
XN297_Configure(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP) );
|
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,13 +177,17 @@ static void __attribute__((unused)) MT99XX_initialize_txid()
|
|||||||
{
|
{
|
||||||
rx_tx_addr[3] = 0xCC;
|
rx_tx_addr[3] = 0xCC;
|
||||||
rx_tx_addr[4] = 0xCC;
|
rx_tx_addr[4] = 0xCC;
|
||||||
|
|
||||||
if(sub_protocol == YZ)
|
if(sub_protocol == YZ)
|
||||||
{
|
{
|
||||||
rx_tx_addr[0] = 0x53; // test (SB id)
|
rx_tx_addr[0] = 0x53; // test (SB id)
|
||||||
rx_tx_addr[1] = 0x00;
|
rx_tx_addr[1] = 0x00;
|
||||||
rx_tx_addr[2] = 0x00;
|
rx_tx_addr[2] = 0x00;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
if(sub_protocol == LS)
|
||||||
|
rx_tx_addr[0] = 0xCC;
|
||||||
|
else //MT99 & H7
|
||||||
|
rx_tx_addr[2] = 0x00;
|
||||||
checksum_offset = rx_tx_addr[0] + rx_tx_addr[1] + rx_tx_addr[2];
|
checksum_offset = rx_tx_addr[0] + rx_tx_addr[1] + rx_tx_addr[2];
|
||||||
channel_offset = (((checksum_offset & 0xf0)>>4) + (checksum_offset & 0x0f)) % 8;
|
channel_offset = (((checksum_offset & 0xf0)>>4) + (checksum_offset & 0x0f)) % 8;
|
||||||
}
|
}
|
||||||
@ -208,6 +236,7 @@ uint16_t initMT99XX(void)
|
|||||||
MT99XX_init();
|
MT99XX_init();
|
||||||
|
|
||||||
packet[0] = 0x20;
|
packet[0] = 0x20;
|
||||||
|
packet_period = MT99XX_PACKET_PERIOD_MT;
|
||||||
switch(sub_protocol)
|
switch(sub_protocol)
|
||||||
{ // MT99 & H7
|
{ // MT99 & H7
|
||||||
case MT99:
|
case MT99:
|
||||||
@ -228,9 +257,9 @@ uint16_t initMT99XX(void)
|
|||||||
packet[3] = 0x11;
|
packet[3] = 0x11;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
packet[4] = rx_tx_addr[0]; // 1st byte for data state tx address
|
packet[4] = rx_tx_addr[0];
|
||||||
packet[5] = rx_tx_addr[1]; // 2nd byte for data state tx address (always 0x00 on Yi Zhan ?)
|
packet[5] = rx_tx_addr[1];
|
||||||
packet[6] = 0x00; // 3rd byte for data state tx address (always 0x00 ?)
|
packet[6] = rx_tx_addr[2];
|
||||||
packet[7] = checksum_offset; // checksum offset
|
packet[7] = checksum_offset; // checksum offset
|
||||||
packet[8] = 0xAA; // fixed
|
packet[8] = 0xAA; // fixed
|
||||||
packet_count=0;
|
packet_count=0;
|
||||||
|
@ -3,17 +3,18 @@
|
|||||||
|
|
||||||
#define XMEGA 1
|
#define XMEGA 1
|
||||||
|
|
||||||
|
// For BLUE module use:
|
||||||
|
//#define DSM_BLUE
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
static void protocol_init(void) ;
|
static void protocol_init(void) ;
|
||||||
static void update_aux_flags(void) ;
|
static void update_aux_flags(void) ;
|
||||||
static void PPM_Telemetry_serial_init(void) ;
|
|
||||||
static uint32_t random_id(uint16_t adress, uint8_t create_new) ;
|
static uint32_t random_id(uint16_t adress, uint8_t create_new) ;
|
||||||
static void update_serial_data(void) ;
|
static void update_serial_data(void) ;
|
||||||
static void Mprotocol_serial_init(void) ;
|
static void Mprotocol_serial_init(void) ;
|
||||||
static void module_reset(void) ;
|
|
||||||
static void update_led_status(void) ;
|
static void update_led_status(void) ;
|
||||||
static void set_rx_tx_addr(uint32_t id) ;
|
static void set_rx_tx_addr(uint32_t id) ;
|
||||||
uint16_t limit_channel_100(uint8_t ch) ;
|
uint16_t limit_channel_100(uint8_t ch) ;
|
||||||
@ -31,6 +32,8 @@ extern uint16_t initDsm2(void) ;
|
|||||||
extern uint16_t ReadDsm2(void) ;
|
extern uint16_t ReadDsm2(void) ;
|
||||||
extern uint16_t DevoInit(void) ;
|
extern uint16_t DevoInit(void) ;
|
||||||
extern uint16_t devo_callback(void) ;
|
extern uint16_t devo_callback(void) ;
|
||||||
|
extern uint16_t initJ6Pro(void) ;
|
||||||
|
extern uint16_t ReadJ6Pro(void) ;
|
||||||
|
|
||||||
extern void randomSeed(unsigned int seed) ;
|
extern void randomSeed(unsigned int seed) ;
|
||||||
extern long random(long howbig) ;
|
extern long random(long howbig) ;
|
||||||
@ -39,20 +42,19 @@ extern long map(long x, long in_min, long in_max, long out_min, long out_max) ;
|
|||||||
extern uint32_t millis(void) ;
|
extern uint32_t millis(void) ;
|
||||||
extern uint32_t micros(void) ;
|
extern uint32_t micros(void) ;
|
||||||
extern void delayMicroseconds(uint16_t x) ;
|
extern void delayMicroseconds(uint16_t x) ;
|
||||||
|
extern void delayMilliseconds(unsigned long ms) ;
|
||||||
extern void init(void) ;
|
extern void init(void) ;
|
||||||
|
|
||||||
extern int analogRead(uint8_t pin) ;
|
extern void modules_reset() ;
|
||||||
|
extern void Update_All() ;
|
||||||
#define A6 20
|
extern void tx_pause() ;
|
||||||
#define A7 21
|
extern void tx_resume() ;
|
||||||
|
extern void TelemetryUpdate() ;
|
||||||
|
extern uint16_t initDsm() ;
|
||||||
|
extern uint16_t ReadDsm() ;
|
||||||
|
|
||||||
#define yield()
|
#define yield()
|
||||||
|
|
||||||
//void _delay_us( uint16_t x )
|
|
||||||
//{
|
|
||||||
// delayMicroseconds( x ) ;
|
|
||||||
//}
|
|
||||||
|
|
||||||
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
|
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
|
||||||
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
|
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
|
||||||
|
|
||||||
@ -69,219 +71,6 @@ extern int analogRead(uint8_t pin) ;
|
|||||||
#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
|
#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
|
||||||
#define FRACT_MAX (1000 >> 3)
|
#define FRACT_MAX (1000 >> 3)
|
||||||
|
|
||||||
volatile unsigned long timer0_overflow_count = 0;
|
|
||||||
volatile unsigned long timer0_millis = 0;
|
|
||||||
static unsigned char timer0_fract = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//void chipInit()
|
|
||||||
//{
|
|
||||||
// PR.PRGEN = 0 ; // RTC and event system active
|
|
||||||
// PR.PRPC = 0 ; // No power reduction port C
|
|
||||||
// PR.PRPD = 0 ; // No power reduction port D
|
|
||||||
// PMIC.CTRL = 7 ;
|
|
||||||
// OSC.CTRL = 0xC3 ; // unclear
|
|
||||||
// OSC.CTRL |= 0x08 ; // Enable external oscillator
|
|
||||||
// while( ( OSC.STATUS & 0x08 ) == 0 ) ; // Wait for ext osc to be ready
|
|
||||||
// OSC.PLLCTRL = 0xC2 ; // Ext. Osc times 2
|
|
||||||
// OSC.CTRL |= 0x10 ; // Enable PLL
|
|
||||||
// while( ( OSC.STATUS & 0x10 ) == 0 ) ; // Wait PLL ready
|
|
||||||
// CPU_CCP = 0xD8 ; // 0x34
|
|
||||||
// CLK.CTRL = 0 ; // Select 2MHz internal clock
|
|
||||||
// CPU_CCP = 0xD8 ; // 0x34
|
|
||||||
// CLK.CTRL = 0x04 ; // Select PLL as clock (32MHz)
|
|
||||||
// PORTD.OUTSET = 0x17 ;
|
|
||||||
// PORTD.DIRSET = 0xB2 ;
|
|
||||||
// PORTD.DIRCLR = 0x4D ;
|
|
||||||
// PORTD.PIN0CTRL = 0x18 ;
|
|
||||||
// PORTD.PIN2CTRL = 0x18 ;
|
|
||||||
// PORTE.DIRSET = 0x01 ;
|
|
||||||
// PORTE.DIRCLR = 0x02 ;
|
|
||||||
// PORTE.OUTSET = 0x01 ;
|
|
||||||
// PORTA.DIRCLR = 0xFF ;
|
|
||||||
// PORTA.PIN0CTRL = 0x18 ;
|
|
||||||
// PORTA.PIN1CTRL = 0x18 ;
|
|
||||||
// PORTA.PIN2CTRL = 0x18 ;
|
|
||||||
// PORTA.PIN3CTRL = 0x18 ;
|
|
||||||
// PORTA.PIN4CTRL = 0x18 ;
|
|
||||||
// PORTA.PIN5CTRL = 0x18 ;
|
|
||||||
// PORTA.PIN6CTRL = 0x18 ;
|
|
||||||
// PORTA.PIN7CTRL = 0x18 ;
|
|
||||||
// PORTC.DIRSET = 0x20 ;
|
|
||||||
// PORTC.OUTCLR = 0x20 ;
|
|
||||||
// SPID.CTRL = 0x51 ;
|
|
||||||
// PORTC.OUTSET = 0x08 ;
|
|
||||||
// PORTC.DIRSET = 0x08 ;
|
|
||||||
// PORTC.PIN3CTRL = 0x18 ;
|
|
||||||
// PORTC.PIN2CTRL = 0x18 ;
|
|
||||||
// USARTC0.BAUDCTRLA = 19 ;
|
|
||||||
// USARTC0.BAUDCTRLB = 0 ;
|
|
||||||
// USARTC0.CTRLB = 0x18 ;
|
|
||||||
// USARTC0.CTRLA = (USARTC0.CTRLA & 0xCF) | 0x10 ;
|
|
||||||
// USARTC0.CTRLC = 0x03 ;
|
|
||||||
|
|
||||||
// TCC0.CTRLB = 0 ;
|
|
||||||
// TCC0.CTRLC = 0 ;
|
|
||||||
// TCC0.CTRLD = 0 ;
|
|
||||||
// TCC0.CTRLE = 0 ;
|
|
||||||
// TCC0.INTCTRLA = 0x01 ;
|
|
||||||
// TCC0.INTCTRLB = 0 ;
|
|
||||||
// TCC0.PER = 0x00FF ;
|
|
||||||
// TCC0.CTRLA = 4 ;
|
|
||||||
|
|
||||||
// TCC1.CTRLB = 0 ;
|
|
||||||
// TCC1.CTRLC = 0 ;
|
|
||||||
// TCC1.CTRLD = 0 ;
|
|
||||||
// TCC1.CTRLE = 0 ;
|
|
||||||
// TCC1.INTCTRLA = 0x03 ;
|
|
||||||
// TCC1.INTCTRLB = 0 ;
|
|
||||||
// TCC1.PER = 0xFFFF ;
|
|
||||||
// TCC1.CNT = 0 ;
|
|
||||||
// TCC1.CTRLA = 4 ;
|
|
||||||
|
|
||||||
// TCD0.CTRLA = 4 ;
|
|
||||||
// TCD0.INTCTRLA = 0x03 ;
|
|
||||||
// TCD0.PER = 0x02ED ;
|
|
||||||
|
|
||||||
//// L0EDB() ;
|
|
||||||
|
|
||||||
// NVM.CTRLB &= 0xF7 ; // No EEPROM mapping
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ISR(TCC0_OVF_vect)
|
|
||||||
{
|
|
||||||
// copy these to local variables so they can be stored in registers
|
|
||||||
// (volatile variables must be read from memory on every access)
|
|
||||||
unsigned long m = timer0_millis;
|
|
||||||
unsigned char f = timer0_fract;
|
|
||||||
|
|
||||||
m += MILLIS_INC;
|
|
||||||
f += FRACT_INC;
|
|
||||||
if (f >= FRACT_MAX) {
|
|
||||||
f -= FRACT_MAX;
|
|
||||||
m += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
timer0_fract = f;
|
|
||||||
timer0_millis = m;
|
|
||||||
timer0_overflow_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long millis()
|
|
||||||
{
|
|
||||||
unsigned long m;
|
|
||||||
uint8_t oldSREG = SREG;
|
|
||||||
|
|
||||||
// disable interrupts while we read timer0_millis or we might get an
|
|
||||||
// inconsistent value (e.g. in the middle of a write to timer0_millis)
|
|
||||||
cli();
|
|
||||||
m = timer0_millis;
|
|
||||||
SREG = oldSREG;
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long micros()
|
|
||||||
{
|
|
||||||
unsigned long m;
|
|
||||||
uint8_t oldSREG = SREG, t;
|
|
||||||
|
|
||||||
cli();
|
|
||||||
m = timer0_overflow_count;
|
|
||||||
t = TCC0.CNT ;
|
|
||||||
|
|
||||||
if ((TCC0.INTFLAGS & TC0_OVFIF_bm) && (t < 255))
|
|
||||||
m++;
|
|
||||||
|
|
||||||
SREG = oldSREG;
|
|
||||||
|
|
||||||
return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
|
|
||||||
}
|
|
||||||
|
|
||||||
void delay(unsigned long ms)
|
|
||||||
{
|
|
||||||
uint16_t start = (uint16_t)micros();
|
|
||||||
|
|
||||||
while (ms > 0) {
|
|
||||||
yield();
|
|
||||||
if (((uint16_t)micros() - start) >= 1000) {
|
|
||||||
ms--;
|
|
||||||
start += 1000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Delay for the given number of microseconds. Assumes a 8 or 16 MHz clock. */
|
|
||||||
void delayMicroseconds(unsigned int us)
|
|
||||||
{
|
|
||||||
// calling avrlib's delay_us() function with low values (e.g. 1 or
|
|
||||||
// 2 microseconds) gives delays longer than desired.
|
|
||||||
//delay_us(us);
|
|
||||||
#if F_CPU >= 20000000L
|
|
||||||
// for the 20 MHz clock on rare Arduino boards
|
|
||||||
|
|
||||||
// for a one-microsecond delay, simply wait 2 cycle and return. The overhead
|
|
||||||
// of the function call yields a delay of exactly a one microsecond.
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
"nop" "\n\t"
|
|
||||||
"nop"); //just waiting 2 cycle
|
|
||||||
if (--us == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// the following loop takes a 1/5 of a microsecond (4 cycles)
|
|
||||||
// per iteration, so execute it five times for each microsecond of
|
|
||||||
// delay requested.
|
|
||||||
us = (us<<2) + us; // x5 us
|
|
||||||
|
|
||||||
// account for the time taken in the preceeding commands.
|
|
||||||
us -= 2;
|
|
||||||
|
|
||||||
#elif F_CPU >= 16000000L
|
|
||||||
// for the 16 MHz clock on most Arduino boards
|
|
||||||
|
|
||||||
// for a one-microsecond delay, simply return. the overhead
|
|
||||||
// of the function call yields a delay of approximately 1 1/8 us.
|
|
||||||
if (--us == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// the following loop takes a quarter of a microsecond (4 cycles)
|
|
||||||
// per iteration, so execute it four times for each microsecond of
|
|
||||||
// delay requested.
|
|
||||||
us <<= 2;
|
|
||||||
|
|
||||||
// account for the time taken in the preceeding commands.
|
|
||||||
us -= 2;
|
|
||||||
#else
|
|
||||||
// for the 8 MHz internal clock on the ATmega168
|
|
||||||
|
|
||||||
// for a one- or two-microsecond delay, simply return. the overhead of
|
|
||||||
// the function calls takes more than two microseconds. can't just
|
|
||||||
// subtract two, since us is unsigned; we'd overflow.
|
|
||||||
if (--us == 0)
|
|
||||||
return;
|
|
||||||
if (--us == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// the following loop takes half of a microsecond (4 cycles)
|
|
||||||
// per iteration, so execute it twice for each microsecond of
|
|
||||||
// delay requested.
|
|
||||||
us <<= 1;
|
|
||||||
|
|
||||||
// partially compensate for the time taken by the preceeding commands.
|
|
||||||
// we can't subtract any more than this or we'd overflow w/ small delays.
|
|
||||||
us--;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// busy wait
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
"1: sbiw %0,1" "\n\t" // 2 cycles
|
|
||||||
"brne 1b" : "=w" (us) : "0" (us) // 2 cycles
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef cbi
|
#ifndef cbi
|
||||||
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
|
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
|
||||||
#endif
|
#endif
|
||||||
@ -314,27 +103,6 @@ void init()
|
|||||||
PMIC.CTRL = 7 ; // Enable all interrupt levels
|
PMIC.CTRL = 7 ; // Enable all interrupt levels
|
||||||
sei();
|
sei();
|
||||||
|
|
||||||
// on the ATmega168, timer 0 is also used for fast hardware pwm
|
|
||||||
// (using phase-correct PWM would mean that timer 0 overflowed half as often
|
|
||||||
// resulting in different millis() behavior on the ATmega8 and ATmega168)
|
|
||||||
//#if defined(TCCR0A) && defined(WGM01)
|
|
||||||
// sbi(TCCR0A, WGM01);
|
|
||||||
// sbi(TCCR0A, WGM00);
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
|
|
||||||
// TCC0 counts 0-255 at 4uS clock rate
|
|
||||||
EVSYS.CH2MUX = 0x80 + 0x07 ; // Prescaler of 128
|
|
||||||
TCC0.CTRLB = 0 ;
|
|
||||||
TCC0.CTRLC = 0 ;
|
|
||||||
TCC0.CTRLD = 0 ;
|
|
||||||
TCC0.CTRLE = 0 ;
|
|
||||||
TCC0.INTCTRLA = 0x01 ;
|
|
||||||
TCC0.INTCTRLB = 0 ;
|
|
||||||
TCC0.PER = 0x00FF ;
|
|
||||||
TCC0.CTRLA = 0x0A ;
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(ADCSRA)
|
#if defined(ADCSRA)
|
||||||
// set a2d prescale factor to 128
|
// set a2d prescale factor to 128
|
||||||
// 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range.
|
// 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range.
|
||||||
@ -357,12 +125,6 @@ void init()
|
|||||||
UCSR0B = 0;
|
UCSR0B = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// PPM interrupt
|
|
||||||
PORTD.DIRCLR = 0x08 ; // D3 is input
|
|
||||||
PORTD.PIN3CTRL = 0x01 ; // Rising edge
|
|
||||||
PORTD.INT0MASK = 0x08 ;
|
|
||||||
PORTD.INTCTRL = 0x02 ; // Medium level interrupt
|
|
||||||
|
|
||||||
// Dip Switch inputs
|
// Dip Switch inputs
|
||||||
PORTA.DIRCLR = 0xFF ;
|
PORTA.DIRCLR = 0xFF ;
|
||||||
PORTA.PIN0CTRL = 0x18 ;
|
PORTA.PIN0CTRL = 0x18 ;
|
||||||
@ -375,95 +137,15 @@ void init()
|
|||||||
PORTA.PIN7CTRL = 0x18 ;
|
PORTA.PIN7CTRL = 0x18 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFAULT 1
|
|
||||||
|
|
||||||
uint8_t analog_reference = DEFAULT;
|
|
||||||
|
|
||||||
void analogReference(uint8_t mode)
|
|
||||||
{
|
|
||||||
// can't actually set the register here because the default setting
|
|
||||||
// will connect AVCC and the AREF pin, which would cause a short if
|
|
||||||
// there's something connected to AREF.
|
|
||||||
analog_reference = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
int analogRead(uint8_t pin)
|
|
||||||
{
|
|
||||||
uint8_t low, high;
|
|
||||||
|
|
||||||
#if defined(analogPinToChannel)
|
|
||||||
#if defined(__AVR_ATmega32U4__)
|
|
||||||
if (pin >= 18) pin -= 18; // allow for channel or pin numbers
|
|
||||||
#endif
|
|
||||||
pin = analogPinToChannel(pin);
|
|
||||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
|
||||||
if (pin >= 54) pin -= 54; // allow for channel or pin numbers
|
|
||||||
#elif defined(__AVR_ATmega32U4__)
|
|
||||||
if (pin >= 18) pin -= 18; // allow for channel or pin numbers
|
|
||||||
#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
|
|
||||||
if (pin >= 24) pin -= 24; // allow for channel or pin numbers
|
|
||||||
#else
|
|
||||||
if (pin >= 14) pin -= 14; // allow for channel or pin numbers
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(ADCSRB) && defined(MUX5)
|
|
||||||
// the MUX5 bit of ADCSRB selects whether we're reading from channels
|
|
||||||
// 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
|
|
||||||
ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// set the analog reference (high two bits of ADMUX) and select the
|
|
||||||
// channel (low 4 bits). this also sets ADLAR (left-adjust result)
|
|
||||||
// to 0 (the default).
|
|
||||||
#if defined(ADMUX)
|
|
||||||
ADMUX = (analog_reference << 6) | (pin & 0x07);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// without a delay, we seem to read from the wrong channel
|
|
||||||
//delay(1);
|
|
||||||
|
|
||||||
#if defined(ADCSRA) && defined(ADCL)
|
|
||||||
// start the conversion
|
|
||||||
sbi(ADCSRA, ADSC);
|
|
||||||
|
|
||||||
// ADSC is cleared when the conversion finishes
|
|
||||||
while (bit_is_set(ADCSRA, ADSC));
|
|
||||||
|
|
||||||
// we have to read ADCL first; doing so locks both ADCL
|
|
||||||
// and ADCH until ADCH is read. reading ADCL second would
|
|
||||||
// cause the results of each conversion to be discarded,
|
|
||||||
// as ADCL and ADCH would be locked when it completed.
|
|
||||||
low = ADCL;
|
|
||||||
high = ADCH;
|
|
||||||
#else
|
|
||||||
// we dont have an ADC, return 0
|
|
||||||
low = 0;
|
|
||||||
high = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// combine the two bytes
|
|
||||||
return (high << 8) | low;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void A7105_Reset()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
void CC2500_Reset()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
void NRF24L01_Reset()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#include "Multiprotocol.ino"
|
#include "Multiprotocol.ino"
|
||||||
|
#include "SPI.ino"
|
||||||
|
#include "Convert.ino"
|
||||||
|
#include "Arduino.ino"
|
||||||
|
|
||||||
#include "cyrf6936_SPI.ino"
|
#include "cyrf6936_SPI.ino"
|
||||||
#include "DSM2_cyrf6936.ino"
|
#include "DSM_cyrf6936.ino"
|
||||||
#include "Devo_cyrf6936.ino"
|
#include "Devo_cyrf6936.ino"
|
||||||
|
#include "J6Pro_cyrf6936.ino"
|
||||||
|
|
||||||
#include "Telemetry.ino"
|
#include "Telemetry.ino"
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
//---------------------------
|
//---------------------------
|
||||||
#include "iface_nrf24l01.h"
|
#include "iface_nrf24l01.h"
|
||||||
|
|
||||||
|
|
||||||
//---------------------------
|
//---------------------------
|
||||||
// NRF24L01+ SPI Specific Functions
|
// NRF24L01+ SPI Specific Functions
|
||||||
//---------------------------
|
//---------------------------
|
||||||
@ -156,6 +157,42 @@ void NRF24L01_SetPower()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NRF24L01_SetTxRxMode(enum TXRX_State mode)
|
||||||
|
{
|
||||||
|
if(mode == TX_EN) {
|
||||||
|
NRF_CSN_off;
|
||||||
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, (1 << NRF24L01_07_RX_DR) //reset the flag(s)
|
||||||
|
| (1 << NRF24L01_07_TX_DS)
|
||||||
|
| (1 << NRF24L01_07_MAX_RT));
|
||||||
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_EN_CRC) // switch to TX mode
|
||||||
|
| (1 << NRF24L01_00_CRCO)
|
||||||
|
| (1 << NRF24L01_00_PWR_UP));
|
||||||
|
_delay_us(130);
|
||||||
|
NRF_CSN_on;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (mode == RX_EN) {
|
||||||
|
NRF_CSN_off;
|
||||||
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // reset the flag(s)
|
||||||
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x0F); // switch to RX mode
|
||||||
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, (1 << NRF24L01_07_RX_DR) //reset the flag(s)
|
||||||
|
| (1 << NRF24L01_07_TX_DS)
|
||||||
|
| (1 << NRF24L01_07_MAX_RT));
|
||||||
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_EN_CRC) // switch to RX mode
|
||||||
|
| (1 << NRF24L01_00_CRCO)
|
||||||
|
| (1 << NRF24L01_00_PWR_UP)
|
||||||
|
| (1 << NRF24L01_00_PRIM_RX));
|
||||||
|
_delay_us(130);
|
||||||
|
NRF_CSN_on;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_EN_CRC)); //PowerDown
|
||||||
|
NRF_CSN_off;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void NRF24L01_SetTxRxMode(enum TXRX_State mode)
|
void NRF24L01_SetTxRxMode(enum TXRX_State mode)
|
||||||
{
|
{
|
||||||
if(mode == TX_EN) {
|
if(mode == TX_EN) {
|
||||||
@ -167,7 +204,7 @@ void NRF24L01_SetTxRxMode(enum TXRX_State mode)
|
|||||||
| (1 << NRF24L01_00_CRCO)
|
| (1 << NRF24L01_00_CRCO)
|
||||||
| (1 << NRF24L01_00_PWR_UP));
|
| (1 << NRF24L01_00_PWR_UP));
|
||||||
delayMicroseconds(130);
|
delayMicroseconds(130);
|
||||||
NRF_CSN_on;
|
NRF_CE_on;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (mode == RX_EN) {
|
if (mode == RX_EN) {
|
||||||
@ -190,7 +227,7 @@ void NRF24L01_SetTxRxMode(enum TXRX_State mode)
|
|||||||
NRF_CE_off;
|
NRF_CE_off;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
void NRF24L01_Reset()
|
void NRF24L01_Reset()
|
||||||
{
|
{
|
||||||
//** not in deviation but needed to hot switch between models
|
//** not in deviation but needed to hot switch between models
|
||||||
@ -205,24 +242,25 @@ void NRF24L01_Reset()
|
|||||||
NRF24L01_Strobe(0xff); // NOP
|
NRF24L01_Strobe(0xff); // NOP
|
||||||
NRF24L01_ReadReg(NRF24L01_07_STATUS);
|
NRF24L01_ReadReg(NRF24L01_07_STATUS);
|
||||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||||
_delay_us(100);
|
delayMicroseconds(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t NRF24L01_packet_ack()
|
uint8_t NRF24L01_packet_ack()
|
||||||
{
|
{
|
||||||
switch (NRF24L01_ReadReg(NRF24L01_07_STATUS) & (BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT)))
|
switch (NRF24L01_ReadReg(NRF24L01_07_STATUS) & (_BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_MAX_RT)))
|
||||||
{
|
{
|
||||||
case BV(NRF24L01_07_TX_DS):
|
case _BV(NRF24L01_07_TX_DS):
|
||||||
return PKT_ACKED;
|
return PKT_ACKED;
|
||||||
case BV(NRF24L01_07_MAX_RT):
|
case _BV(NRF24L01_07_MAX_RT):
|
||||||
return PKT_TIMEOUT;
|
return PKT_TIMEOUT;
|
||||||
}
|
}
|
||||||
return PKT_PENDING;
|
return PKT_PENDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
// XN297 emulation layer
|
// XN297 emulation layer
|
||||||
uint8_t xn297_scramble_enabled=1; //enabled by default
|
uint8_t xn297_scramble_enabled=XN297_SCRAMBLED; //enabled by default
|
||||||
uint8_t xn297_addr_len;
|
uint8_t xn297_addr_len;
|
||||||
uint8_t xn297_tx_addr[5];
|
uint8_t xn297_tx_addr[5];
|
||||||
uint8_t xn297_rx_addr[5];
|
uint8_t xn297_rx_addr[5];
|
||||||
@ -235,13 +273,6 @@ static const uint8_t xn297_scramble[] = {
|
|||||||
0x1b, 0x5d, 0x19, 0x10, 0x24, 0xd3, 0xdc, 0x3f,
|
0x1b, 0x5d, 0x19, 0x10, 0x24, 0xd3, 0xdc, 0x3f,
|
||||||
0x8e, 0xc5, 0x2f};
|
0x8e, 0xc5, 0x2f};
|
||||||
|
|
||||||
const uint16_t PROGMEM xn297_crc_xorout[] = {
|
|
||||||
0x0000, 0x3d5f, 0xa6f1, 0x3a23, 0xaa16, 0x1caf,
|
|
||||||
0x62b2, 0xe0eb, 0x0821, 0xbe07, 0x5f1a, 0xaf15,
|
|
||||||
0x4f0a, 0xad24, 0x5e48, 0xed34, 0x068c, 0xf2c9,
|
|
||||||
0x1852, 0xdf36, 0x129d, 0xb17c, 0xd5f5, 0x70d7,
|
|
||||||
0xb798, 0x5133, 0x67db, 0xd94e};
|
|
||||||
|
|
||||||
const uint16_t PROGMEM xn297_crc_xorout_scrambled[] = {
|
const uint16_t PROGMEM xn297_crc_xorout_scrambled[] = {
|
||||||
0x0000, 0x3448, 0x9BA7, 0x8BBB, 0x85E1, 0x3E8C,
|
0x0000, 0x3448, 0x9BA7, 0x8BBB, 0x85E1, 0x3E8C,
|
||||||
0x451E, 0x18E6, 0x6B24, 0xE7AB, 0x3828, 0x814B,
|
0x451E, 0x18E6, 0x6B24, 0xE7AB, 0x3828, 0x814B,
|
||||||
@ -249,6 +280,13 @@ const uint16_t PROGMEM xn297_crc_xorout_scrambled[] = {
|
|||||||
0x8B17, 0x2920, 0x8B5F, 0x61B1, 0xD391, 0x7401,
|
0x8B17, 0x2920, 0x8B5F, 0x61B1, 0xD391, 0x7401,
|
||||||
0x2138, 0x129F, 0xB3A0, 0x2988};
|
0x2138, 0x129F, 0xB3A0, 0x2988};
|
||||||
|
|
||||||
|
const uint16_t PROGMEM xn297_crc_xorout[] = {
|
||||||
|
0x0000, 0x3d5f, 0xa6f1, 0x3a23, 0xaa16, 0x1caf,
|
||||||
|
0x62b2, 0xe0eb, 0x0821, 0xbe07, 0x5f1a, 0xaf15,
|
||||||
|
0x4f0a, 0xad24, 0x5e48, 0xed34, 0x068c, 0xf2c9,
|
||||||
|
0x1852, 0xdf36, 0x129d, 0xb17c, 0xd5f5, 0x70d7,
|
||||||
|
0xb798, 0x5133, 0x67db, 0xd94e};
|
||||||
|
|
||||||
static uint8_t bit_reverse(uint8_t b_in)
|
static uint8_t bit_reverse(uint8_t b_in)
|
||||||
{
|
{
|
||||||
uint8_t b_out = 0;
|
uint8_t b_out = 0;
|
||||||
@ -260,10 +298,9 @@ static uint8_t bit_reverse(uint8_t b_in)
|
|||||||
return b_out;
|
return b_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const uint16_t polynomial = 0x1021;
|
||||||
static uint16_t crc16_update(uint16_t crc, uint8_t a)
|
static uint16_t crc16_update(uint16_t crc, uint8_t a)
|
||||||
{
|
{
|
||||||
static const uint16_t polynomial = 0x1021;
|
|
||||||
|
|
||||||
crc ^= a << 8;
|
crc ^= a << 8;
|
||||||
for (uint8_t i = 0; i < 8; ++i)
|
for (uint8_t i = 0; i < 8; ++i)
|
||||||
if (crc & 0x8000)
|
if (crc & 0x8000)
|
||||||
@ -309,14 +346,18 @@ void XN297_SetRXAddr(const uint8_t* addr, uint8_t len)
|
|||||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, buf, 5);
|
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, buf, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XN297_Configure(uint16_t flags)
|
void XN297_Configure(uint8_t flags)
|
||||||
{
|
{
|
||||||
xn297_scramble_enabled = !(flags & BV(XN297_UNSCRAMBLED));
|
xn297_crc = !!(flags & _BV(NRF24L01_00_EN_CRC));
|
||||||
xn297_crc = !!(flags & BV(NRF24L01_00_EN_CRC));
|
flags &= ~(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO));
|
||||||
flags &= ~(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO));
|
|
||||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, flags & 0xFF);
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, flags & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XN297_SetScrambledMode(const uint8_t mode)
|
||||||
|
{
|
||||||
|
xn297_scramble_enabled = mode;
|
||||||
|
}
|
||||||
|
|
||||||
void XN297_WritePayload(uint8_t* msg, uint8_t len)
|
void XN297_WritePayload(uint8_t* msg, uint8_t len)
|
||||||
{
|
{
|
||||||
uint8_t buf[32];
|
uint8_t buf[32];
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
#include "iface_cc2500.h"
|
#include "iface_cc2500.h"
|
||||||
|
|
||||||
|
|
||||||
#define SFHSS_COARSE 0
|
#define SFHSS_COARSE 0
|
||||||
|
|
||||||
#define SFHSS_PACKET_LEN 13
|
#define SFHSS_PACKET_LEN 13
|
||||||
@ -27,11 +26,11 @@
|
|||||||
uint8_t fhss_code; // 0-27
|
uint8_t fhss_code; // 0-27
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
SFHSS_START = 0x101,
|
SFHSS_START = 0x00,
|
||||||
SFHSS_CAL = 0x102,
|
SFHSS_CAL = 0x01,
|
||||||
SFHSS_TUNE = 0x103,
|
SFHSS_DATA1 = 0x02, // do not change this value
|
||||||
SFHSS_DATA1 = 0x02,
|
SFHSS_DATA2 = 0x0B, // do not change this value
|
||||||
SFHSS_DATA2 = 0x0b
|
SFHSS_TUNE = 0x0F
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SFHSS_FREQ0_VAL 0xC4
|
#define SFHSS_FREQ0_VAL 0xC4
|
||||||
@ -75,12 +74,11 @@ const PROGMEM uint8_t SFHSS_init_values[] = {
|
|||||||
|
|
||||||
static void __attribute__((unused)) SFHSS_rf_init()
|
static void __attribute__((unused)) SFHSS_rf_init()
|
||||||
{
|
{
|
||||||
CC2500_Reset();
|
|
||||||
CC2500_Strobe(CC2500_SIDLE);
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 39; ++i)
|
for (uint8_t i = 0; i < 39; ++i)
|
||||||
CC2500_WriteReg(i, pgm_read_byte_near(&SFHSS_init_values[i]));
|
CC2500_WriteReg(i, pgm_read_byte_near(&SFHSS_init_values[i]));
|
||||||
//CC2500_WriteRegisterMulti(CC2500_00_IOCFG2, init_values, sizeof(init_values));
|
|
||||||
prev_option = option;
|
prev_option = option;
|
||||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||||
|
|
||||||
@ -102,16 +100,14 @@ static void __attribute__((unused)) SFHSS_tune_chan_fast()
|
|||||||
CC2500_WriteReg(CC2500_25_FSCAL1, calData[rf_ch_num]);
|
CC2500_WriteReg(CC2500_25_FSCAL1, calData[rf_ch_num]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) SFHSS_tune_freq()
|
||||||
static void __attribute__((unused)) SFHSS_tune_freq() {
|
{
|
||||||
// May be we'll need this tuning routine - some receivers are more sensitive to
|
|
||||||
// frequency impreciseness, and though CC2500 has a procedure to handle it it
|
|
||||||
// may not be applied in receivers, so we need to compensate for it on TX
|
|
||||||
if ( prev_option != option )
|
if ( prev_option != option )
|
||||||
{
|
{
|
||||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||||
CC2500_WriteReg(CC2500_0F_FREQ0, SFHSS_FREQ0_VAL + SFHSS_COARSE);
|
CC2500_WriteReg(CC2500_0F_FREQ0, SFHSS_FREQ0_VAL + SFHSS_COARSE);
|
||||||
prev_option = option ;
|
prev_option = option ;
|
||||||
|
phase = SFHSS_START; // Restart the tune process if option is changed to get good tuned values
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,23 +126,20 @@ static void __attribute__((unused)) SFHSS_calc_next_chan()
|
|||||||
// Values grow down and to the right, so we just revert every channel.
|
// Values grow down and to the right, so we just revert every channel.
|
||||||
static uint16_t __attribute__((unused)) SFHSS_convert_channel(uint8_t num)
|
static uint16_t __attribute__((unused)) SFHSS_convert_channel(uint8_t num)
|
||||||
{
|
{
|
||||||
return (uint16_t) (map(limit_channel_100(num),PPM_MIN_100,PPM_MAX_100,906,86));
|
return (uint16_t) (map(limit_channel_100(num),servo_min_100,servo_max_100,906,86));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void __attribute__((unused)) SFHSS_build_data_packet()
|
static void __attribute__((unused)) SFHSS_build_data_packet()
|
||||||
{
|
{
|
||||||
#define spacer1 0x02 //0b10
|
#define spacer1 0x02 //0b10
|
||||||
#define spacer2 (spacer1 << 4)
|
#define spacer2 (spacer1 << 4)
|
||||||
uint8_t ch_offset = state == SFHSS_DATA1 ? 0 : 4;
|
uint8_t ch_offset = phase == SFHSS_DATA1 ? 0 : 4;
|
||||||
const uint8_t ch[]={AILERON, ELEVATOR, THROTTLE, RUDDER, AUX1, AUX2, AUX3, AUX4};
|
uint16_t ch1 = SFHSS_convert_channel(CH_AETR[ch_offset+0]);
|
||||||
|
uint16_t ch2 = SFHSS_convert_channel(CH_AETR[ch_offset+1]);
|
||||||
|
uint16_t ch3 = SFHSS_convert_channel(CH_AETR[ch_offset+2]);
|
||||||
|
uint16_t ch4 = SFHSS_convert_channel(CH_AETR[ch_offset+3]);
|
||||||
|
|
||||||
uint16_t ch1 = SFHSS_convert_channel(ch[ch_offset+0]);
|
packet[0] = 0x81; // can be 80 or 81 for Orange, only 81 for XK
|
||||||
uint16_t ch2 = SFHSS_convert_channel(ch[ch_offset+1]);
|
|
||||||
uint16_t ch3 = SFHSS_convert_channel(ch[ch_offset+2]);
|
|
||||||
uint16_t ch4 = SFHSS_convert_channel(ch[ch_offset+3]);
|
|
||||||
|
|
||||||
packet[0] = 0x81; // can be 80, 81, 81 for Orange, only 81 for XK
|
|
||||||
packet[1] = rx_tx_addr[0];
|
packet[1] = rx_tx_addr[0];
|
||||||
packet[2] = rx_tx_addr[1];
|
packet[2] = rx_tx_addr[1];
|
||||||
packet[3] = 0;
|
packet[3] = 0;
|
||||||
@ -158,23 +151,22 @@ static void __attribute__((unused)) SFHSS_build_data_packet()
|
|||||||
packet[9] = (ch3 >> 1);
|
packet[9] = (ch3 >> 1);
|
||||||
packet[10] = (ch3 << 7) | spacer2 | ((ch4 >> 5) & 0x1F /*0b11111*/);
|
packet[10] = (ch3 << 7) | spacer2 | ((ch4 >> 5) & 0x1F /*0b11111*/);
|
||||||
packet[11] = (ch4 << 3) | ((fhss_code >> 2) & 0x07 /*0b111 */);
|
packet[11] = (ch4 << 3) | ((fhss_code >> 2) & 0x07 /*0b111 */);
|
||||||
packet[12] = (fhss_code << 6) | state;
|
packet[12] = (fhss_code << 6) | phase;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((unused)) SFHSS_send_packet()
|
static void __attribute__((unused)) SFHSS_send_packet()
|
||||||
{
|
{
|
||||||
//SFHSS_tune_chan_fast();
|
|
||||||
CC2500_WriteData(packet, SFHSS_PACKET_LEN);
|
CC2500_WriteData(packet, SFHSS_PACKET_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ReadSFHSS()
|
uint16_t ReadSFHSS()
|
||||||
{
|
{
|
||||||
switch(state)
|
switch(phase)
|
||||||
{
|
{
|
||||||
case SFHSS_START:
|
case SFHSS_START:
|
||||||
rf_ch_num = 0;
|
rf_ch_num = 0;
|
||||||
SFHSS_tune_chan();
|
SFHSS_tune_chan();
|
||||||
state = SFHSS_CAL;
|
phase = SFHSS_CAL;
|
||||||
return 2000;
|
return 2000;
|
||||||
case SFHSS_CAL:
|
case SFHSS_CAL:
|
||||||
calData[rf_ch_num]=CC2500_ReadReg(CC2500_25_FSCAL1);
|
calData[rf_ch_num]=CC2500_ReadReg(CC2500_25_FSCAL1);
|
||||||
@ -183,7 +175,7 @@ uint16_t ReadSFHSS()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
rf_ch_num = 0;
|
rf_ch_num = 0;
|
||||||
state = SFHSS_DATA1;
|
phase = SFHSS_DATA1;
|
||||||
}
|
}
|
||||||
return 2000;
|
return 2000;
|
||||||
|
|
||||||
@ -191,16 +183,16 @@ uint16_t ReadSFHSS()
|
|||||||
case SFHSS_DATA1:
|
case SFHSS_DATA1:
|
||||||
SFHSS_build_data_packet();
|
SFHSS_build_data_packet();
|
||||||
SFHSS_send_packet();
|
SFHSS_send_packet();
|
||||||
state = SFHSS_DATA2;
|
phase = SFHSS_DATA2;
|
||||||
return 1650;
|
return 1650;
|
||||||
case SFHSS_DATA2:
|
case SFHSS_DATA2:
|
||||||
SFHSS_build_data_packet();
|
SFHSS_build_data_packet();
|
||||||
SFHSS_send_packet();
|
SFHSS_send_packet();
|
||||||
SFHSS_calc_next_chan();
|
SFHSS_calc_next_chan();
|
||||||
state = SFHSS_TUNE;
|
phase = SFHSS_TUNE;
|
||||||
return 2000;
|
return 2000;
|
||||||
case SFHSS_TUNE:
|
case SFHSS_TUNE:
|
||||||
state = SFHSS_DATA1;
|
phase = SFHSS_DATA1;
|
||||||
SFHSS_tune_freq();
|
SFHSS_tune_freq();
|
||||||
SFHSS_tune_chan_fast();
|
SFHSS_tune_chan_fast();
|
||||||
CC2500_SetPower();
|
CC2500_SetPower();
|
||||||
@ -241,13 +233,13 @@ static void __attribute__((unused)) SFHSS_get_tx_id()
|
|||||||
|
|
||||||
uint16_t initSFHSS()
|
uint16_t initSFHSS()
|
||||||
{
|
{
|
||||||
BIND_DONE; // No bind protocol
|
BIND_DONE; // Not a TX bind protocol
|
||||||
SFHSS_get_tx_id();
|
SFHSS_get_tx_id();
|
||||||
|
|
||||||
fhss_code=rx_tx_addr[2]%28; // Initialize it to random 0-27 inclusive
|
fhss_code=rx_tx_addr[2]%28; // Initialize it to random 0-27 inclusive
|
||||||
|
|
||||||
SFHSS_rf_init();
|
SFHSS_rf_init();
|
||||||
state = SFHSS_START;
|
phase = SFHSS_START;
|
||||||
|
|
||||||
return 10000;
|
return 10000;
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,12 @@
|
|||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
Multiprotocol is distributed in the hope that it will be useful,
|
Multiprotocol is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -93,7 +95,7 @@ uint16_t SHENQI_callback()
|
|||||||
SHENQI_send_packet();
|
SHENQI_send_packet();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR))
|
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||||
{
|
{
|
||||||
if(LT8900_ReadPayload(packet, 3))
|
if(LT8900_ReadPayload(packet, 3))
|
||||||
{
|
{
|
||||||
@ -115,7 +117,7 @@ uint16_t initSHENQI()
|
|||||||
SHENQI_init();
|
SHENQI_init();
|
||||||
hopping_frequency_no = 0;
|
hopping_frequency_no = 0;
|
||||||
packet_count=0;
|
packet_count=0;
|
||||||
packet_period=100;
|
packet_period=500;
|
||||||
return 1000;
|
return 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ enum {
|
|||||||
static void __attribute__((unused)) SLT_init()
|
static void __attribute__((unused)) SLT_init()
|
||||||
{
|
{
|
||||||
NRF24L01_Initialize();
|
NRF24L01_Initialize();
|
||||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO)); // 2-bytes CRC, radio off
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)); // 2-bytes CRC, radio off
|
||||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement
|
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement
|
||||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0
|
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0
|
||||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x02); // 4-byte RX/TX address
|
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x02); // 4-byte RX/TX address
|
||||||
@ -93,7 +93,7 @@ static void __attribute__((unused)) SLT_set_tx_id(void)
|
|||||||
static void __attribute__((unused)) SLT_wait_radio()
|
static void __attribute__((unused)) SLT_wait_radio()
|
||||||
{
|
{
|
||||||
if (packet_sent)
|
if (packet_sent)
|
||||||
while (!(NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_TX_DS))) ;
|
while (!(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS))) ;
|
||||||
packet_sent = 0;
|
packet_sent = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +101,7 @@ static void __attribute__((unused)) SLT_send_data(uint8_t *data, uint8_t len)
|
|||||||
{
|
{
|
||||||
SLT_wait_radio();
|
SLT_wait_radio();
|
||||||
NRF24L01_FlushTx();
|
NRF24L01_FlushTx();
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_RX_DR) | BV(NRF24L01_07_MAX_RT));
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, _BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_RX_DR) | _BV(NRF24L01_07_MAX_RT));
|
||||||
NRF24L01_WritePayload(data, len);
|
NRF24L01_WritePayload(data, len);
|
||||||
//NRF24L01_PulseCE();
|
//NRF24L01_PulseCE();
|
||||||
packet_sent = 1;
|
packet_sent = 1;
|
||||||
|
@ -174,7 +174,7 @@ static void __attribute__((unused)) symax_init()
|
|||||||
NRF24L01_SetTxRxMode(TX_EN);
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
//
|
//
|
||||||
NRF24L01_ReadReg(NRF24L01_07_STATUS);
|
NRF24L01_ReadReg(NRF24L01_07_STATUS);
|
||||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO));
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO));
|
||||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement
|
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement
|
||||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x3F); // Enable all data pipes (even though not used?)
|
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x3F); // Enable all data pipes (even though not used?)
|
||||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
|
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
|
||||||
|
@ -80,7 +80,7 @@ static void __attribute__((unused)) v202_init()
|
|||||||
NRF24L01_Initialize();
|
NRF24L01_Initialize();
|
||||||
|
|
||||||
// 2-bytes CRC, radio off
|
// 2-bytes CRC, radio off
|
||||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO));
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO));
|
||||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement
|
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement
|
||||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x3F); // Enable all data pipes
|
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x3F); // Enable all data pipes
|
||||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
|
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
|
||||||
@ -116,7 +116,7 @@ static void __attribute__((unused)) V202_init2()
|
|||||||
|
|
||||||
// Turn radio power on
|
// Turn radio power on
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
//Done by TX_EN??? => NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP));
|
//Done by TX_EN??? => NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((unused)) V2X2_set_tx_id(void)
|
static void __attribute__((unused)) V2X2_set_tx_id(void)
|
||||||
|
@ -34,13 +34,6 @@
|
|||||||
|
|
||||||
#define YD717_PAYLOADSIZE 8 // receive data pipes set to this size, but unused
|
#define YD717_PAYLOADSIZE 8 // receive data pipes set to this size, but unused
|
||||||
|
|
||||||
enum {
|
|
||||||
YD717_INIT1 = 0,
|
|
||||||
YD717_BIND2,
|
|
||||||
YD717_BIND3,
|
|
||||||
YD717_DATA
|
|
||||||
};
|
|
||||||
|
|
||||||
static void __attribute__((unused)) yd717_send_packet(uint8_t bind)
|
static void __attribute__((unused)) yd717_send_packet(uint8_t bind)
|
||||||
{
|
{
|
||||||
uint8_t rudder_trim, elevator_trim, aileron_trim;
|
uint8_t rudder_trim, elevator_trim, aileron_trim;
|
||||||
@ -108,7 +101,7 @@ static void __attribute__((unused)) yd717_send_packet(uint8_t bind)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// clear packet status bits and TX FIFO
|
// clear packet status bits and TX FIFO
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, (BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT)));
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, (_BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_MAX_RT)));
|
||||||
NRF24L01_FlushTx();
|
NRF24L01_FlushTx();
|
||||||
|
|
||||||
if( sub_protocol == YD717 )
|
if( sub_protocol == YD717 )
|
||||||
@ -131,117 +124,62 @@ static void __attribute__((unused)) yd717_init()
|
|||||||
|
|
||||||
// CRC, radio on
|
// CRC, radio on
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_PWR_UP));
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_PWR_UP));
|
||||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x3F); // Auto Acknoledgement on all data pipes
|
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // Disable Acknoledgement on all data pipes
|
||||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x3F); // Enable all data pipes
|
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x00); // Disable all data pipes
|
||||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
|
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
|
||||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x1A); // 500uS retransmit t/o, 10 tries
|
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // No retransmit
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, YD717_RF_CHANNEL); // Channel 3C
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, YD717_RF_CHANNEL); // Channel 3C
|
||||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||||
NRF24L01_SetPower();
|
NRF24L01_SetPower();
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||||
NRF24L01_WriteReg(NRF24L01_0C_RX_ADDR_P2, 0xC3); // LSB byte of pipe 2 receive address
|
|
||||||
NRF24L01_WriteReg(NRF24L01_0D_RX_ADDR_P3, 0xC4);
|
|
||||||
NRF24L01_WriteReg(NRF24L01_0E_RX_ADDR_P4, 0xC5);
|
|
||||||
NRF24L01_WriteReg(NRF24L01_0F_RX_ADDR_P5, 0xC6);
|
|
||||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, YD717_PAYLOADSIZE); // bytes of data payload for pipe 1
|
|
||||||
NRF24L01_WriteReg(NRF24L01_12_RX_PW_P1, YD717_PAYLOADSIZE);
|
|
||||||
NRF24L01_WriteReg(NRF24L01_13_RX_PW_P2, YD717_PAYLOADSIZE);
|
|
||||||
NRF24L01_WriteReg(NRF24L01_14_RX_PW_P3, YD717_PAYLOADSIZE);
|
|
||||||
NRF24L01_WriteReg(NRF24L01_15_RX_PW_P4, YD717_PAYLOADSIZE);
|
|
||||||
NRF24L01_WriteReg(NRF24L01_16_RX_PW_P5, YD717_PAYLOADSIZE);
|
|
||||||
NRF24L01_WriteReg(NRF24L01_17_FIFO_STATUS, 0x00); // Just in case, no real bits to write here
|
|
||||||
|
|
||||||
NRF24L01_Activate(0x73); // Activate feature register
|
NRF24L01_Activate(0x73); // Activate feature register
|
||||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3F); // Enable dynamic payload length on all pipes
|
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3F); // Enable dynamic payload length on all pipes
|
||||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07); // Set feature bits on
|
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07); // Set feature bits on
|
||||||
NRF24L01_Activate(0x73);
|
NRF24L01_Activate(0x73);
|
||||||
|
|
||||||
// set tx id
|
|
||||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, 5);
|
|
||||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) YD717_init1()
|
|
||||||
{
|
|
||||||
// for bind packets set address to prearranged value known to receiver
|
// for bind packets set address to prearranged value known to receiver
|
||||||
uint8_t bind_rx_tx_addr[] = {0x65, 0x65, 0x65, 0x65, 0x65};
|
uint8_t bind_rx_tx_addr[] = {0x65, 0x65, 0x65, 0x65, 0x65};
|
||||||
uint8_t i;
|
|
||||||
if( sub_protocol==SYMAX4 )
|
if( sub_protocol==SYMAX4 )
|
||||||
for(i=0; i < 5; i++)
|
for(uint8_t i=0; i < 5; i++)
|
||||||
bind_rx_tx_addr[i] = 0x60;
|
bind_rx_tx_addr[i] = 0x60;
|
||||||
else
|
else
|
||||||
if( sub_protocol==NIHUI )
|
if( sub_protocol==NIHUI )
|
||||||
for(i=0; i < 5; i++)
|
for(uint8_t i=0; i < 5; i++)
|
||||||
bind_rx_tx_addr[i] = 0x64;
|
bind_rx_tx_addr[i] = 0x64;
|
||||||
|
|
||||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, bind_rx_tx_addr, 5);
|
|
||||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, bind_rx_tx_addr, 5);
|
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, bind_rx_tx_addr, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((unused)) YD717_init2()
|
|
||||||
{
|
|
||||||
// set rx/tx address for data phase
|
|
||||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, 5);
|
|
||||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t yd717_callback()
|
uint16_t yd717_callback()
|
||||||
{
|
{
|
||||||
switch (phase)
|
if(IS_BIND_DONE_on)
|
||||||
{
|
|
||||||
case YD717_INIT1:
|
|
||||||
yd717_send_packet(0); // receiver doesn't re-enter bind mode if connection lost...check if already bound
|
|
||||||
phase = YD717_BIND3;
|
|
||||||
break;
|
|
||||||
case YD717_BIND2:
|
|
||||||
if (counter == 0)
|
|
||||||
{
|
|
||||||
if (NRF24L01_packet_ack() == PKT_PENDING)
|
|
||||||
return YD717_PACKET_CHKTIME; // packet send not yet complete
|
|
||||||
YD717_init2(); // change to data phase rx/tx address
|
|
||||||
yd717_send_packet(0);
|
yd717_send_packet(0);
|
||||||
phase = YD717_BIND3;
|
else
|
||||||
|
{
|
||||||
|
if (bind_counter == 0)
|
||||||
|
{
|
||||||
|
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5); // set address
|
||||||
|
yd717_send_packet(0);
|
||||||
|
BIND_DONE; // bind complete
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (NRF24L01_packet_ack() == PKT_PENDING)
|
|
||||||
return YD717_PACKET_CHKTIME; // packet send not yet complete;
|
|
||||||
yd717_send_packet(1);
|
yd717_send_packet(1);
|
||||||
counter--;
|
bind_counter--;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case YD717_BIND3:
|
|
||||||
switch (NRF24L01_packet_ack())
|
|
||||||
{
|
|
||||||
case PKT_PENDING:
|
|
||||||
return YD717_PACKET_CHKTIME; // packet send not yet complete
|
|
||||||
case PKT_ACKED:
|
|
||||||
phase = YD717_DATA;
|
|
||||||
BIND_DONE; // bind complete
|
|
||||||
break;
|
|
||||||
case PKT_TIMEOUT:
|
|
||||||
YD717_init1(); // change to bind rx/tx address
|
|
||||||
counter = YD717_BIND_COUNT;
|
|
||||||
phase = YD717_BIND2;
|
|
||||||
yd717_send_packet(1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case YD717_DATA:
|
|
||||||
if (NRF24L01_packet_ack() == PKT_PENDING)
|
|
||||||
return YD717_PACKET_CHKTIME; // packet send not yet complete
|
|
||||||
yd717_send_packet(0);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return YD717_PACKET_PERIOD; // Packet every 8ms
|
return YD717_PACKET_PERIOD; // Packet every 8ms
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t initYD717()
|
uint16_t initYD717()
|
||||||
{
|
{
|
||||||
|
BIND_IN_PROGRESS; // autobind protocol
|
||||||
rx_tx_addr[4] = 0xC1; // always uses first data port
|
rx_tx_addr[4] = 0xC1; // always uses first data port
|
||||||
yd717_init();
|
yd717_init();
|
||||||
phase = YD717_INIT1;
|
bind_counter = YD717_BIND_COUNT;
|
||||||
BIND_IN_PROGRESS; // autobind protocol
|
|
||||||
|
|
||||||
// Call callback in 50ms
|
// Call callback in 50ms
|
||||||
return YD717_INITIAL_WAIT;
|
return YD717_INITIAL_WAIT;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user