Suivit du projet

This commit is contained in:
tipouic 2016-02-05 08:57:31 +01:00
parent 8faf5abe38
commit eb2e9477b3
15 changed files with 688 additions and 673 deletions

View File

@ -104,6 +104,8 @@ static void __attribute__((unused)) CG023_send_packet(uint8_t bind)
packet[6] = 0x08;
packet[7] = 0x03;
packet[9] = throttle;
if(rudder==0x01) rudder=0; // Small deadband
if(rudder==0x81) rudder=0; // Small deadband
packet[10] = rudder;
packet[11] = elevator;
packet[12] = aileron;
@ -112,15 +114,11 @@ static void __attribute__((unused)) CG023_send_packet(uint8_t bind)
packet[14] = 0x20;
packet[15] = 0x20;
packet[16] = 0x20;
packet[17] = H8_3D_FLAG_RATE_HIGH;
if(Servo_AUX1)
packet[17] |= H8_3D_FLAG_FLIP;
if(Servo_AUX2)
packet[17] |= H8_3D_FLAG_LIGTH; //H22 light
if(Servo_AUX3)
packet[17] |= H8_3D_FLAG_HEADLESS;
if(Servo_AUX4)
packet[17] |= H8_3D_FLAG_RTH; // 180/360 flip mode on H8 3D
packet[17] = H8_3D_FLAG_RATE_HIGH
| GET_FLAG(Servo_AUX1,H8_3D_FLAG_FLIP)
| GET_FLAG(Servo_AUX2,H8_3D_FLAG_LIGTH) //H22 light
| GET_FLAG(Servo_AUX3,H8_3D_FLAG_HEADLESS)
| GET_FLAG(Servo_AUX4,H8_3D_FLAG_RTH); // 180/360 flip mode on H8 3D
if(Servo_AUX5)
packet[18] = H8_3D_FLAG_CALIBRATE;
}
@ -152,32 +150,21 @@ static void __attribute__((unused)) CG023_send_packet(uint8_t bind)
if(sub_protocol==CG023)
{
// rate
packet[13] = CG023_FLAG_RATE_HIGH;
// flags
if(Servo_AUX1)
packet[13] |= CG023_FLAG_FLIP;
if(Servo_AUX2)
packet[13] |= CG023_FLAG_LED_OFF;
if(Servo_AUX3)
packet[13] |= CG023_FLAG_STILL;
if(Servo_AUX4)
packet[13] |= CG023_FLAG_VIDEO;
if(Servo_AUX5)
packet[13] |= CG023_FLAG_EASY;
packet[13] = CG023_FLAG_RATE_HIGH
| GET_FLAG(Servo_AUX1,CG023_FLAG_FLIP)
| GET_FLAG(Servo_AUX2,CG023_FLAG_LED_OFF)
| GET_FLAG(Servo_AUX3,CG023_FLAG_STILL)
| GET_FLAG(Servo_AUX4,CG023_FLAG_VIDEO)
| GET_FLAG(Servo_AUX5,CG023_FLAG_EASY);
}
else
{// YD829
// rate
packet[13] = YD829_FLAG_RATE_HIGH;
// flags
if(Servo_AUX1)
packet[13] |= YD829_FLAG_FLIP;
if(Servo_AUX3)
packet[13] |= YD829_FLAG_STILL;
if(Servo_AUX4)
packet[13] |= YD829_FLAG_VIDEO;
if(Servo_AUX5)
packet[13] |= YD829_FLAG_HEADLESS;
packet[13] = YD829_FLAG_RATE_HIGH
| GET_FLAG(Servo_AUX1,YD829_FLAG_FLIP)
| GET_FLAG(Servo_AUX3,YD829_FLAG_STILL)
| GET_FLAG(Servo_AUX4,YD829_FLAG_VIDEO)
| GET_FLAG(Servo_AUX5,YD829_FLAG_HEADLESS);
}
packet[14] = 0;
}
@ -237,13 +224,7 @@ uint16_t CG023_callback()
bind_counter--;
}
}
if(sub_protocol==CG023)
return CG023_PACKET_PERIOD;
else
if(sub_protocol==YD829)
return YD829_PACKET_PERIOD;
return H8_3D_PACKET_PERIOD;
return packet_period;
}
static void __attribute__((unused)) CG023_initialize_txid()
@ -276,11 +257,13 @@ uint16_t initCG023(void)
CG023_initialize_txid();
CG023_init();
if(sub_protocol==CG023)
return CG023_INITIAL_WAIT+CG023_PACKET_PERIOD;
packet_period=CG023_PACKET_PERIOD;
else
if(sub_protocol==YD829)
return CG023_INITIAL_WAIT+YD829_PACKET_PERIOD;
return CG023_INITIAL_WAIT+H8_3D_PACKET_PERIOD;
packet_period=YD829_PACKET_PERIOD;
else
packet_period=H8_3D_PACKET_PERIOD;
return CG023_INITIAL_WAIT+YD829_PACKET_PERIOD;
}
#endif

View File

@ -12,21 +12,22 @@
You should have received a copy of the GNU General Public License
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/
// compatible with Cheerson CX-10 blue & newer red pcb, CX-10A, CX11, CX-10 green pcb, DM007, Floureon FX-10, CX-Stars
// compatible with Cheerson CX-10 blue & newer red pcb, CX-10A, CX11, CX-10 green pcb, DM007, Floureon FX-10, JXD 509 (Q282)
// Last sync with hexfet new_protocols/cx10_nrf24l01.c dated 2015-11-26
#if defined(CX10_NRF24L01_INO)
#include "iface_nrf24l01.h"
#define CX10_BIND_COUNT 4360 // 6 seconds
#define CX10_PACKET_SIZE 15
#define CX10A_PACKET_SIZE 19 // CX10 blue board packets have 19-byte payload
#define Q282_PACKET_SIZE 21
#define CX10_PACKET_PERIOD 1316 // Timeout for callback in uSec
#define CX10A_PACKET_PERIOD 6000
#define CX10_BIND_COUNT 4360 // 6 seconds
#define CX10_PACKET_SIZE 15
#define CX10A_PACKET_SIZE 19 // CX10 blue board packets have 19-byte payload
#define Q282_PACKET_SIZE 21
#define CX10_PACKET_PERIOD 1316 // Timeout for callback in uSec
#define CX10A_PACKET_PERIOD 6000
#define CX10A_BIND_COUNT 400 // 2 seconds
#define INITIAL_WAIT 500
#define CX10_INITIAL_WAIT 500
// flags
#define CX10_FLAG_FLIP 0x10 // goes to rudder channel
@ -37,8 +38,8 @@
#define CX10_FLAG_SNAPSHOT 0x04
// frequency channel management
#define RF_BIND_CHANNEL 0x02
#define NUM_RF_CHANNELS 4
#define CX10_RF_BIND_CHANNEL 0x02
#define CX10_NUM_RF_CHANNELS 4
enum {
CX10_BIND1 = 0,
@ -86,63 +87,61 @@ static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind)
switch(sub_protocol)
{
case CX10_BLUE:
if(Servo_AUX3) flags |= 0x10; // Channel 7 - picture
if(Servo_AUX4) flags |= 0x08; // Channel 8 - video
flags |= GET_FLAG(!Servo_AUX3, 0x10) // Channel 7 - picture
|GET_FLAG( Servo_AUX4, 0x08); // Channel 8 - video
break;
case Q282:
case Q242:
memcpy(&packet[15], "\x10\x10\xaa\xaa\x00\x00", 6);
//FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|XCAL|YCAL
if(Servo_AUX1) flags2 =0x80; // Channel 5 - FLIP
if(Servo_AUX2) flags2|=0x40; // Channel 6 - LED
if(Servo_AUX5) flags2|=0x08; // Channel 9 - HEADLESS
flags2 = GET_FLAG(Servo_AUX1, 0x80) // Channel 5 - FLIP
|GET_FLAG(Servo_AUX2, 0x40) // Channel 6 - LED
|GET_FLAG(Servo_AUX5, 0x08) // Channel 9 - HEADLESS
|GET_FLAG(Servo_AUX7, 0x04) // Channel 11 - XCAL
|GET_FLAG(Servo_AUX8, 0x02); // Channel 12 - YCAL or Start/Stop motors on JXD 509
if(sub_protocol==Q282)
{
if(Servo_AUX3) flags2|=0x10; // Channel 7 - picture
if(Servo_AUX4) // Channel 8 - video
flags=3;
if(Servo_AUX4) // Channel 8 - video
{
if (!(video_state & 0x20)) video_state ^= 0x21;
}
else
if (video_state & 0x20) video_state &= 0x01;
flags2 |= video_state;
flags=3;
flags2 |= video_state
|GET_FLAG(Servo_AUX3,0x10); // Channel 7 - picture
}
else
{
if(Servo_AUX3) flags2|=0x01; // Channel 7 - picture
if(Servo_AUX4) flags2|=0x10; // Channel 8 - video
flags=2;
flags2|= GET_FLAG(Servo_AUX3,0x01) // Channel 7 - picture
|GET_FLAG(Servo_AUX4,0x10); // Channel 8 - video
packet[17]=0x00;
packet[18]=0x00;
}
if(Servo_AUX6) flags |=0x80; // Channel 10 - RTH
if(Servo_AUX7) flags2|=0x04; // Channel 11 - XCAL
if(Servo_AUX8) flags2|=0x02; // Channel 12 - YCAL
if(Servo_AUX6) flags |=0x80; // Channel 10 - RTH
break;
case DM007:
//FLIP|MODE|PICTURE|VIDEO|HEADLESS
if(Servo_AUX3) flags2 = CX10_FLAG_SNAPSHOT; // Channel 7 - picture
if(Servo_AUX4) flags2|= CX10_FLAG_VIDEO; // Channel 8 - video
if(Servo_AUX5) flags |= CX10_FLAG_HEADLESS; // Channel 9 - headless
break;
case JC3015_1:
//FLIP|MODE|PICTURE|VIDEO
if(Servo_AUX3) flags2 = _BV(3); // Channel 7 - picture
if(Servo_AUX4) flags2|= _BV(4); // Channel 8 - video
flags2= GET_FLAG(Servo_AUX3,CX10_FLAG_SNAPSHOT) // Channel 7 - picture
|GET_FLAG(Servo_AUX4,CX10_FLAG_VIDEO); // Channel 8 - video
if(Servo_AUX5) flags |= CX10_FLAG_HEADLESS; // Channel 9 - headless
break;
case JC3015_2:
//FLIP|MODE|LED|DFLIP
if(Servo_AUX3) flags2 = _BV(3); // Channel 7 - LED
if(Servo_AUX4) flags2|= _BV(4); // Channel 8 - DFLIP
if(Servo_AUX4) packet[12] &= ~CX10_FLAG_FLIP;
case JC3015_1:
//FLIP|MODE|PICTURE|VIDEO
flags2= GET_FLAG(Servo_AUX3,_BV(3)) // Channel 7
|GET_FLAG(Servo_AUX4,_BV(4)); // Channel 8
break;
case MK33041:
//FLIP|MODE|PICTURE|VIDEO|HEADLESS|RTH
if(Servo_AUX3) flags |= _BV(7); // Channel 7 - picture
if(Servo_AUX4) flags2 = _BV(0); // Channel 8 - video
if(Servo_AUX5) flags2|= _BV(5); // Channel 9 - headless
if(Servo_AUX6) flags |= _BV(2); // Channel 10 - rth
flags|=GET_FLAG(Servo_AUX3,_BV(7)) // Channel 7 - picture
|GET_FLAG(Servo_AUX6,_BV(2)); // Channel 10 - rth
flags2=GET_FLAG(Servo_AUX4,_BV(0)) // Channel 8 - video
|GET_FLAG(Servo_AUX5,_BV(5)); // Channel 9 - headless
break;
}
packet[13+offset]=flags;
@ -152,11 +151,11 @@ static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind)
// 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));
if (bind)
NRF24L01_WriteReg(NRF24L01_05_RF_CH, RF_BIND_CHANNEL);
NRF24L01_WriteReg(NRF24L01_05_RF_CH, CX10_RF_BIND_CHANNEL);
else
{
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++]);
hopping_frequency_no %= NUM_RF_CHANNELS;
hopping_frequency_no %= CX10_NUM_RF_CHANNELS;
}
// clear packet status bits and TX FIFO
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
@ -178,7 +177,7 @@ static void __attribute__((unused)) CX10_init()
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgment on all data pipes
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, packet_length); // rx pipe 0 (used only for blue board)
NRF24L01_WriteReg(NRF24L01_05_RF_CH, RF_BIND_CHANNEL);
NRF24L01_WriteReg(NRF24L01_05_RF_CH, CX10_RF_BIND_CHANNEL);
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
NRF24L01_SetPower();
}
@ -198,13 +197,22 @@ uint16_t CX10_callback() {
}
break;
case CX10_BIND2:
bind_counter--;
if(bind_counter==0)
{ // Needed for some CX-10A to properly finish the bind
CX10_init();
bind_counter=CX10A_BIND_COUNT;
}
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR))
{ // RX fifo data ready
XN297_ReadPayload(packet, packet_length);
NRF24L01_SetTxRxMode(TXRX_OFF);
NRF24L01_SetTxRxMode(TX_EN);
if(packet[9] == 1)
{
phase = CX10_BIND1;
bind_counter=0;
}
}
else
{
@ -226,7 +234,7 @@ uint16_t CX10_callback() {
return packet_period;
}
static void __attribute__((unused)) initialize_txid()
static void __attribute__((unused)) CX10_initialize_txid()
{
rx_tx_addr[1]%= 0x30;
if(sub_protocol==Q282)
@ -259,8 +267,10 @@ uint16_t initCX10(void)
{
packet_length = CX10A_PACKET_SIZE;
packet_period = CX10A_PACKET_PERIOD;
phase = CX10_BIND2;
bind_counter=0;
bind_counter=CX10A_BIND_COUNT;
for(uint8_t i=0; i<4; i++)
packet[5+i] = 0xff; // clear aircraft id
packet[9] = 0;
@ -275,10 +285,10 @@ uint16_t initCX10(void)
phase = CX10_BIND1;
bind_counter = CX10_BIND_COUNT;
}
initialize_txid();
CX10_initialize_txid();
CX10_init();
BIND_IN_PROGRESS; // autobind protocol
return INITIAL_WAIT+packet_period;
return CX10_INITIAL_WAIT+packet_period;
}
#endif

View File

@ -178,26 +178,6 @@ uint16_t initFrSky_2way()
return 10000;
}
#if defined(TELEMETRY)
static void __attribute__((unused)) check_telemetry(uint8_t *pkt,uint8_t len)
{
if(pkt[1] != rx_tx_addr[3] || pkt[2] != rx_tx_addr[2] || len != pkt[0] + 3)
{//only packets with the required id and packet length
for(uint8_t i=3;i<6;i++)
pktt[i]=0;
return;
}
else
{
for (uint8_t i=3;i<len;i++)
pktt[i]=pkt[i];
telemetry_link=1;
if(pktt[6]>0)
telemetry_counter=(telemetry_counter+1)%32;
}
}
#endif
uint16_t ReadFrSky_2way()
{
if (state < FRSKY_BIND_DONE)
@ -245,7 +225,7 @@ uint16_t ReadFrSky_2way()
cc2500_readFifo(pkt, len); //received telemetry packets
#if defined(TELEMETRY)
//parse telemetry packet here
check_telemetry(pkt,len); //check if valid telemetry packets and buffer them.
frsky_check_telemetry(pkt,len); //check if valid telemetry packets and buffer them.
#endif
}
CC2500_SetTxRxMode(TX_EN);

View File

@ -144,13 +144,13 @@ static void __attribute__((unused)) kn_update_packet_control_data()
packet[11] = 0x64; // R
flags=0;
if (Servo_data[AUX1] > PPM_SWITCH)
if (Servo_AUX1)
flags = KN_FLAG_DR;
if (Servo_data[AUX2] > PPM_SWITCH)
if (Servo_AUX2)
flags |= KN_FLAG_TH;
if (Servo_data[AUX3] > PPM_SWITCH)
if (Servo_AUX3)
flags |= KN_FLAG_IDLEUP;
if (Servo_data[AUX4] > PPM_SWITCH)
if (Servo_AUX4)
flags |= KN_FLAG_GYRO3;
packet[12] = flags;

View File

@ -0,0 +1,247 @@
/*
This project is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Multiprotocol is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/
// compatible with MJX WLH08, X600, X800, H26D
// Last sync with hexfet new_protocols/mjxq_nrf24l01.c dated 2016-01-17
#if defined(MJXQ_NRF24L01_INO)
#include "iface_nrf24l01.h"
#define MJXQ_BIND_COUNT 150
#define MJXQ_PACKET_PERIOD 4000 // Timeout for callback in uSec
#define MJXQ_INITIAL_WAIT 500
#define MJXQ_PACKET_SIZE 16
#define MJXQ_RF_NUM_CHANNELS 4
#define MJXQ_ADDRESS_LENGTH 5
#define MJXQ_PAN_TILT_COUNT 16 // for H26D - match stock tx timing
#define MJXQ_PAN_DOWN 0x08
#define MJXQ_PAN_UP 0x04
#define MJXQ_TILT_DOWN 0x20
#define MJXQ_TILT_UP 0x10
static uint8_t __attribute__((unused)) MJXQ_pan_tilt_value()
{
// Servo_AUX8 PAN // H26D
// Servo_AUX9 TILT
uint8_t pan = 0;
packet_count++;
if(packet_count & MJXQ_PAN_TILT_COUNT)
{
if(Servo_AUX8)
pan=MJXQ_PAN_UP;
if(Servo_data[AUX8]<PPM_MIN_COMMAND)
pan=MJXQ_PAN_DOWN;
if(Servo_data[AUX9]>PPM_MIN_COMMAND)
pan=MJXQ_TILT_UP;
if(Servo_data[AUX9]<PPM_MIN_COMMAND)
pan=MJXQ_TILT_DOWN;
}
return pan;
}
#define MJXQ_CHAN2TRIM(X) (((X) & 0x80 ? (X) : 0x7f - (X)) >> 1)
static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
{
packet[0] = convert_channel_8b(THROTTLE);
packet[1] = convert_channel_s8b(RUDDER);
packet[4] = 0x40; // rudder does not work well with dyntrim
packet[2] = convert_channel_s8b(ELEVATOR);
packet[5] = MJXQ_CHAN2TRIM(packet[2]); // trim elevator
packet[3] = convert_channel_s8b(AILERON);
packet[6] = MJXQ_CHAN2TRIM(packet[3]); // trim aileron
packet[7] = rx_tx_addr[0];
packet[8] = rx_tx_addr[1];
packet[9] = rx_tx_addr[2];
packet[10] = 0x00; // overwritten below for feature bits
packet[11] = 0x00; // overwritten below for X600
packet[12] = 0x00;
packet[13] = 0x00;
packet[14] = 0xC0; // bind value
// Servo_AUX1 FLIP
// Servo_AUX2 LED
// Servo_AUX3 PICTURE
// Servo_AUX4 VIDEO
// Servo_AUX5 HEADLESS
// Servo_AUX6 RTH
// Servo_AUX7 AUTOFLIP // X800, X600
switch(sub_protocol)
{
case H26D:
packet[10]=MJXQ_pan_tilt_value();
// fall through on purpose - no break
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 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[11] = GET_FLAG(Servo_AUX6, 0x01); //RTH
if (!bind)
{
packet[14] = 0x02 // always high rates by bit2 = 1
| GET_FLAG(Servo_AUX1, 0x04) //FLIP
| GET_FLAG(Servo_AUX7, 0x10) //AUTOFLIP
| GET_FLAG(Servo_AUX5, 0x20); //HEADLESS
}
break;
case X800:
default:
packet[10] = 0x10
| GET_FLAG(!Servo_AUX2, 0x02) //LED
| GET_FLAG(Servo_AUX7, 0x01); //AUTOFLIP
if (!bind)
{
packet[14] = 0x02 // always high rates by bit2 = 1
| GET_FLAG(Servo_AUX1, 0x04) //FLIP
| GET_FLAG(Servo_AUX3, 0x08) //PICTURE
| GET_FLAG(Servo_AUX4, 0x10); //VIDEO
}
break;
}
uint8_t sum = packet[0];
for (uint8_t i=1; i < MJXQ_PACKET_SIZE-1; i++) sum += packet[i];
packet[15] = sum;
// Power on, TX mode, 2byte CRC
if (sub_protocol == H26D)
NRF24L01_SetTxRxMode(TX_EN);
else
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]);
hopping_frequency_no %= 2 * MJXQ_RF_NUM_CHANNELS; // channels repeated
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
NRF24L01_FlushTx();
if (sub_protocol == H26D)
NRF24L01_WritePayload(packet, MJXQ_PACKET_SIZE);
else
XN297_WritePayload(packet, MJXQ_PACKET_SIZE);
NRF24L01_SetPower();
}
static void __attribute__((unused)) MJXQ_init()
{
uint8_t addr[MJXQ_ADDRESS_LENGTH];
memcpy(addr, "\x6d\x6a\x77\x77\x77", MJXQ_ADDRESS_LENGTH);
if (sub_protocol == WLH08)
memcpy(hopping_frequency, "\x12\x22\x32\x42", MJXQ_RF_NUM_CHANNELS);
else
if (sub_protocol == H26D)
memcpy(hopping_frequency, "\x36\x3e\x46\x2e", MJXQ_RF_NUM_CHANNELS);
else
{
memcpy(hopping_frequency, "\x0a\x35\x42\x3d", MJXQ_RF_NUM_CHANNELS);
memcpy(addr, "\x6d\x6a\x73\x73\x73", MJXQ_RF_NUM_CHANNELS);
}
NRF24L01_Initialize();
NRF24L01_SetTxRxMode(TX_EN);
if (sub_protocol == H26D)
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, addr, MJXQ_ADDRESS_LENGTH);
else
XN297_SetTXAddr(addr, MJXQ_ADDRESS_LENGTH);
NRF24L01_FlushTx();
NRF24L01_FlushRx();
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgment on all data pipes
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
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_SetBitrate(NRF24L01_BR_1M); // 1Mbps
NRF24L01_SetPower();
}
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)
memcpy(hopping_frequency, "\x32\x3e\x42\x4e", MJXQ_RF_NUM_CHANNELS);
else
if (sub_protocol == WLH08)
memcpy(hopping_frequency, rf_map[rx_tx_addr[0]%3], MJXQ_RF_NUM_CHANNELS);
}
static void __attribute__((unused)) MJXQ_initialize_txid()
{
// haven't figured out txid<-->rf channel mapping for MJX models
static const uint8_t tx_map[][3]={
{0xF8, 0x4F, 0x1C},
{0xC8, 0x6E, 0x02},
{0x48, 0x6A, 0x40} };
if (sub_protocol == WLH08)
rx_tx_addr[0]&=0xF8; // txid must be multiple of 8
else
memcpy(rx_tx_addr,tx_map[rx_tx_addr[0]%3],3);
}
uint16_t MJXQ_callback()
{
if(IS_BIND_DONE_on)
MJXQ_send_packet(0);
else
{
if (bind_counter == 0)
{
MJXQ_init2();
BIND_DONE;
}
else
{
bind_counter--;
MJXQ_send_packet(1);
}
}
return MJXQ_PACKET_PERIOD;
}
uint16_t initMJXQ(void)
{
BIND_IN_PROGRESS; // autobind protocol
bind_counter = MJXQ_BIND_COUNT;
MJXQ_initialize_txid();
MJXQ_init();
packet_count=0;
return MJXQ_INITIAL_WAIT+MJXQ_PACKET_PERIOD;
}
#endif

View File

@ -0,0 +1,221 @@
/*
This project is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Multiprotocol is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/
// compatible with MT99xx, Eachine H7, Yi Zhan i6S
// Last sync with Goebish mt99xx_nrf24l01.c dated 2016-01-29
#if defined(MT99XX_NRF24L01_INO)
#include "iface_nrf24l01.h"
#define MT99XX_BIND_COUNT 928
#define MT99XX_PACKET_PERIOD_MT 2625
#define MT99XX_PACKET_PERIOD_YZ 3125
#define MT99XX_INITIAL_WAIT 500
#define MT99XX_PACKET_SIZE 9
#define checksum_offset rf_ch_num
#define channel_offset phase
enum{
// flags going to packet[6] (MT99xx, H7)
FLAG_MT_RATE1 = 0x01, // (H7 high rate)
FLAG_MT_RATE2 = 0x02, // (MT9916 only)
FLAG_MT_VIDEO = 0x10,
FLAG_MT_SNAPSHOT= 0x20,
FLAG_MT_FLIP = 0x80,
};
enum{
// flags going to ?????? (Yi Zhan i6S)ROLL
BLABLA,
};
enum {
MT99XX_INIT = 0,
MT99XX_BIND,
MT99XX_DATA
};
static uint8_t __attribute__((unused)) MT99XX_calcChecksum()
{
uint8_t result=checksum_offset;
for(uint8_t i=0; i<8; i++)
result += packet[i];
return result;
}
static void __attribute__((unused)) MT99XX_send_packet()
{
static const uint8_t yz_p4_seq[] = {0xa0, 0x20, 0x60};
static const uint8_t mys_byte[] = {
0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 0x04, 0x14,
0x05, 0x15, 0x06, 0x16, 0x07, 0x17, 0x00, 0x10
};
static uint8_t yz_seq_num=0;
if(sub_protocol != YZ)
{ // MT99XX & H7
packet[0] = convert_channel_8b_scale(THROTTLE,0x00,0xE1); // throttle
packet[1] = convert_channel_8b_scale(RUDDER ,0x00,0xE1); // rudder
packet[2] = convert_channel_8b_scale(AILERON ,0x00,0xE1); // aileron
packet[3] = convert_channel_8b_scale(ELEVATOR,0x00,0xE1); // elevator
packet[4] = convert_channel_8b_scale(AUX5,0x00,0x3F); // pitch trim (0x3f-0x20-0x00)
packet[5] = convert_channel_8b_scale(AUX6,0x00,0x3F); // roll trim (0x00-0x20-0x3f)
packet[6] = GET_FLAG( Servo_AUX1, FLAG_MT_FLIP )
| GET_FLAG( Servo_AUX3, FLAG_MT_SNAPSHOT )
| GET_FLAG( Servo_AUX4, FLAG_MT_VIDEO );
if(sub_protocol==MT99)
packet[6] |= 0x40 | FLAG_MT_RATE2;
else
packet[6] |= FLAG_MT_RATE1; // max rate on H7
// todo: mys_byte = next channel index ?
// low nibble: index in chan list ?
// high nibble: 0->start from start of list, 1->start from end of list ?
packet[7] = mys_byte[hopping_frequency_no];
packet[8] = MT99XX_calcChecksum();
}
else
{ // YZ
packet[0] = convert_channel_8b_scale(THROTTLE,0x00,0x64); // throttle
packet[1] = convert_channel_8b_scale(RUDDER ,0x00,0x64); // rudder
packet[2] = convert_channel_8b_scale(ELEVATOR,0x00,0x64); // elevator
packet[3] = convert_channel_8b_scale(AILERON ,0x00,0x64); // aileron
if(packet_count++ >= 23)
{
yz_seq_num ++;
if(yz_seq_num > 2)
yz_seq_num = 0;
packet_count=0;
}
packet[4] = yz_p4_seq[yz_seq_num];
packet[5] = 0x02; // expert ? (0=unarmed, 1=normal)
packet[6] = 0x80;
packet[7] = packet[0];
for(uint8_t idx = 1; idx < MT99XX_PACKET_SIZE-2; idx++)
packet[7] += packet[idx];
packet[8] = 0xff;
}
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no] + channel_offset);
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
NRF24L01_FlushTx();
XN297_WritePayload(packet, MT99XX_PACKET_SIZE);
hopping_frequency_no++;
if(sub_protocol == YZ)
hopping_frequency_no++; // skip every other channel
if(hopping_frequency_no > 15)
hopping_frequency_no = 0;
NRF24L01_SetPower();
}
static void __attribute__((unused)) MT99XX_init()
{
NRF24L01_Initialize();
NRF24L01_SetTxRxMode(TX_EN);
NRF24L01_FlushTx();
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_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5 bytes address
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no auto retransmit
if(sub_protocol == YZ)
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps (nRF24L01+ only)
else
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
NRF24L01_SetPower();
XN297_SetTXAddr((uint8_t *)"\0xCC\0xCC\0xCC\0xCC\0xCC", 5);
}
static void __attribute__((unused)) MT99XX_initialize_txid()
{
if(sub_protocol == YZ)
{
rx_tx_addr[0] = 0x53; // test (SB id)
rx_tx_addr[1] = 0x00;
}
checksum_offset = (rx_tx_addr[0] + rx_tx_addr[1]) & 0xff;
channel_offset = (((checksum_offset & 0xf0)>>4) + (checksum_offset & 0x0f)) % 8;
}
uint16_t MT99XX_callback()
{
if(IS_BIND_DONE_on)
MT99XX_send_packet();
else
{
if (bind_counter == 0)
{
rx_tx_addr[2] = 0x00;
rx_tx_addr[3] = 0xCC;
rx_tx_addr[4] = 0xCC;
// set tx address for data packets
XN297_SetTXAddr(rx_tx_addr, 5);
BIND_DONE;
}
else
{
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
NRF24L01_FlushTx();
XN297_WritePayload(packet, MT99XX_PACKET_SIZE); // bind packet
hopping_frequency_no++;
if(sub_protocol == YZ)
hopping_frequency_no++; // skip every other channel
if(hopping_frequency_no > 15)
hopping_frequency_no = 0;
bind_counter--;
}
}
return packet_period;
}
uint16_t initMT99XX(void)
{
BIND_IN_PROGRESS; // autobind protocol
bind_counter = MT99XX_BIND_COUNT;
memcpy(hopping_frequency,"\0x02\0x48\0x0C\0x3e\0x16\0x34\0x20\0x2A,\0x2A\0x20\0x34\0x16\0x3e\0x0c\0x48\0x02",16);
MT99XX_initialize_txid();
MT99XX_init();
packet[0] = 0x20;
if(sub_protocol!=YZ)
{ // MT99 & H7
packet_period = MT99XX_PACKET_PERIOD_MT;
packet[1] = 0x14;
packet[2] = 0x03;
packet[3] = 0x25;
}
else
{ // YZ
packet_period = MT99XX_PACKET_PERIOD_YZ;
packet[1] = 0x15;
packet[2] = 0x05;
packet[3] = 0x06;
}
packet[4] = rx_tx_addr[0]; // 1th byte for data state tx address
packet[5] = rx_tx_addr[1]; // 2th byte for data state tx address (always 0x00 on Yi Zhan ?)
packet[6] = 0x00; // 3th byte for data state tx address (always 0x00 ?)
packet[7] = checksum_offset; // checksum offset
packet[8] = 0xAA; // fixed
packet_count=0;
return MT99XX_INITIAL_WAIT+MT99XX_PACKET_PERIOD_MT;
}
#endif

View File

@ -419,18 +419,17 @@ static void protocol_init()
remote_callback = ESKY_callback;
break;
#endif
// Ajout protocol
#if defined(H7_NRF24L01_INO)
case MODE_H7:
next_callback=H7_init();
remote_callback = process_H7;
#if defined(MT99XX_NRF24L01_INO)
case MODE_MT99XX:
next_callback=initMT99XX();
remote_callback = MT99XX_callback;
break;
#endif
#if defined(HM830_NRF24L01_INO)
case MODE_HM830:
next_callback=HM830_setup();
remote_callback = HM830_callback;
break;
#if defined(MJXQ_NRF24L01_INO)
case MODE_MJXQ:
next_callback=initMJXQ();
remote_callback = MJXQ_callback;
break;
#endif
}
@ -448,7 +447,12 @@ static void protocol_init()
static void update_ppm_data() {
#if defined(POTAR_SELECT)
if(Servo_data[AUX1]>PPM_SWITCH) { CHANGE_PROTOCOL_FLAG_on; }
if(Servo_data[AUX1]>PPM_SWITCH) {
CHANGE_PROTOCOL_FLAG_on;
tone(BUZZER, BUZZER_HTZ);
delay(BUZZER_TPS);
noTone(BUZZER);
}
#endif
if(IS_CHANGE_PROTOCOL_FLAG_on) {
ppm_select = 10;
@ -458,7 +462,7 @@ static void update_ppm_data() {
while(!IS_PPM_FLAG_on) {} // wait
update_PPM_servo();
if(Servo_data[AUX1] < PPM_MAX_100) { ppm_select--; }
} // attente de la déactivation du rebind
} // attente de la d<EFBFBD>activation du rebind
}
prev_protocol = ppm_select;
@ -491,7 +495,7 @@ static void update_ppm_data() {
ppm_select++;
}
while(Servo_data[THROTTLE] > PPM_MIN_100) { delay(100); update_PPM_servo(); } // attente de la remise des gaz à zéro (poussé à fond avec le script lua)
while(Servo_data[THROTTLE] > PPM_MIN_100) { delay(100); update_PPM_servo(); } // attente de la remise des gaz <EFBFBD> z<>ro (pouss<73> <20> fond avec le script lua)
}
}
static void update_serial_data()
@ -561,7 +565,7 @@ static void module_reset()
case MODE_DEVO:
CYRF_Reset();
break;
default: // MODE_HISKY, MODE_V2X2, MODE_YD717, MODE_KN, MODE_SYMAX, MODE_SLT, MODE_CX10, MODE_CG023, MODE_BAYANG, MODE_ESKY
default: // MODE_HISKY, MODE_V2X2, MODE_YD717, MODE_KN, MODE_SYMAX, MODE_SLT, MODE_CX10, MODE_CG023, MODE_BAYANG, MODE_ESKY, MODE_MT99XX, MODE_MJXQ
NRF24L01_Reset();
break;
}

View File

@ -37,6 +37,24 @@ void compute_RSSIdbm(){
RSSI_dBm += 65;
}
void frsky_check_telemetry(uint8_t *pkt,uint8_t len)
{
if(pkt[1] != rx_tx_addr[3] || pkt[2] != rx_tx_addr[2] || len != pkt[0] + 3)
{//only packets with the required id and packet length
for(uint8_t i=3;i<6;i++)
pktt[i]=0;
return;
}
else
{
for (uint8_t i=3;i<len;i++)
pktt[i]=pkt[i];
telemetry_link=1;
if(pktt[6]>0)
telemetry_counter=(telemetry_counter+1)%32;
}
}
void frsky_link_frame()
{
frame[0] = 0xFE;

View File

@ -180,13 +180,13 @@ static void __attribute__((unused)) V2X2_send_packet(uint8_t bind)
//Flags2
// Channel 9
if (Servo_data[AUX5] > PPM_SWITCH)
if (Servo_AUX5)
flags2 = V2X2_FLAG_HEADLESS;
// Channel 10
if (Servo_data[AUX6] > PPM_SWITCH)
if (Servo_AUX6)
flags2 |= V2X2_FLAG_MAG_CAL_X;
// Channel 11
if (Servo_data[AUX7] > PPM_SWITCH)
if (Servo_AUX7)
flags2 |= V2X2_FLAG_MAG_CAL_Y;
}
// TX id

View File

@ -35,46 +35,48 @@
//Comment a protocol to exclude it from compilation
//A7105 protocols
#define FLYSKY_A7105_INO
#define HUBSAN_A7105_INO
//CYRF6936 protocols
#define DEVO_CYRF6936_INO
#define DSM2_CYRF6936_INO
//CC2500 protocols
#define FRSKY_CC2500_INO
//#define FRSKYX_CC2500_INO
//NFR24L01 protocols
#define BAYANG_NRF24L01_INO
#define CG023_NRF24L01_INO
#define CX10_NRF24L01_INO
#define DEVO_CYRF6936_INO
#define DSM2_CYRF6936_INO
#define ESKY_NRF24L01_INO
#define FLYSKY_A7105_INO
#define FRSKY_CC2500_INO // FRSKY2way
//#define FRSKYX_CC2500_INO
#define HISKY_NRF24L01_INO
#define HUBSAN_A7105_INO
#define KN_NRF24L01_INO
#define SLT_NRF24L01_INO
#define SYMAX_NRF24L01_INO
#define V2X2_NRF24L01_INO
#define YD717_NRF24L01_INO
#define H7_NRF24L01_INO
//#define HM830_NRF24L01_INO
//#define CFlie_NRF24L01_INO
#define MT99XX_NRF24L01_INO
#define MJXQ_NRF24L01_INO
//Update this table to set which protocol and all associated settings are called for the corresponding dial number
static const PPM_Parameters PPM_prot[15]=
{
// Protocol , Sub protocol , RX_Num , Power , Auto Bind , Option
{MODE_DSM2 , DSM2 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=1
{MODE_FLYSKY, Flysky , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=2
{MODE_HUBSAN, 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=3
{MODE_DEVO , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=4
{MODE_CG023 , CG023 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=5
{MODE_CX10 , CX10_BLUE , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=6
{MODE_HISKY , Hisky , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=7
{MODE_V2X2 , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=8
{MODE_YD717 , YD717 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=9
{MODE_KN , WLTOYS , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=10
{MODE_SYMAX , SYMAX , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=11
{MODE_SLT , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=12
{MODE_BAYANG, 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=13
{MODE_SYMAX , SYMAX5C , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=14
{MODE_FRSKY , 0 , 0 , P_HIGH , NO_AUTOBIND , 0xD7 }, //Dial=15
// Protocol Sub protocol RX_Num Power Auto Bind Option
{MODE_FLYSKY, Flysky , 0 , P_HIGH , AUTOBIND , 0 }, //Dial=1
{MODE_HUBSAN, 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=2
{MODE_FRSKY , 0 , 0 , P_HIGH , NO_AUTOBIND , 0xD7 }, //Dial=3
{MODE_HISKY , Hisky , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=4
{MODE_V2X2 , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=5
{MODE_DSM2 , DSM2 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=6
{MODE_DEVO , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=7
{MODE_YD717 , YD717 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=8
{MODE_KN , WLTOYS , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=9
{MODE_SYMAX , SYMAX , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=10
{MODE_SLT , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=11
{MODE_CX10 , CX10_BLUE , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=12
{MODE_CG023 , CG023 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=13
{MODE_BAYANG, 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, //Dial=14
{MODE_SYMAX , SYMAX5C , 0 , P_HIGH , NO_AUTOBIND , 0 } //Dial=15
};
/* Available protocols and associated sub protocols:
MODE_FLYSKY
@ -129,6 +131,15 @@ static const PPM_Parameters PPM_prot[15]=
NONE
MODE_ESKY
NONE
MODE_MT99XX
MT99
H7
YZ
MODE_MJXQ
WLH08
X600
X800
H26D
RX_Num value between 0 and 15
@ -184,14 +195,6 @@ Option value between 0 and 255. 0xD7 or 0x00 for Frsky fine tuning.
AILERON,
THROTTLE,
RUDDER,
AUX1,
AUX2,
AUX3,
AUX4,
AUX5,
AUX6,
AUX7,
AUX8
};
#endif
@ -201,33 +204,28 @@ Option value between 0 and 255. 0xD7 or 0x00 for Frsky fine tuning.
AILERON,
ELEVATOR,
RUDDER,
AUX1,
AUX2,
AUX3,
AUX4,
AUX5,
AUX6,
AUX7,
AUX8
};
};
#endif
#if defined(AETR)
enum chan_order{
AILERON =0,
ELEVATOR,
THROTTLE,
RUDDER,
};
#endif
enum chan_order{
AILERON =0,
ELEVATOR,
THROTTLE,
RUDDER,
AUX1,
AUX1 =4,
AUX2,
AUX3,
AUX4,
AUX5,
AUX6,
AUX7,
AUX8
AUX8,
AUX9
};
#endif
#define PPM_MIN_COMMAND 1250
#define PPM_SWITCH 1550

View File

@ -27,26 +27,24 @@
enum PROTOCOLS
{
MODE_SERIAL = 0, // Serial commands
MODE_FLYSKY = 1, // =>A7105 / FLYSKY protocol
MODE_HUBSAN = 2, // =>A7105 / HUBSAN protocol
MODE_FRSKY = 3, // =>CC2500 / FRSKY protocol
MODE_HISKY = 4, // =>NRF24L01 / HISKY protocol
MODE_V2X2 = 5, // =>NRF24L01 / V2x2 protocol
MODE_DSM2 = 6, // =>CYRF6936 / DSM2 protocol
MODE_DEVO =7, // =>CYRF6936 / DEVO protocol
MODE_YD717 = 8, // =>NRF24L01 / YD717 protocol (CX10 red pcb)
MODE_KN = 9, // =>NRF24L01 / KN protocol
MODE_SYMAX = 10, // =>NRF24L01 / SYMAX protocol
MODE_SLT = 11, // =>NRF24L01 / SLT protocol
MODE_CX10 = 12, // =>NRF24L01 / CX-10 protocol
MODE_CG023 = 13, // =>NRF24L01 / CG023 protocol
MODE_BAYANG = 14, // =>NRF24L01 / BAYANG protocol
MODE_FRSKYX = 15, // =>CC2500 / FRSKYX protocol
MODE_ESKY = 16, // =>NRF24L01 / ESKY protocol
// Ajout
MODE_H7 = 21, // =>NRF24L01 / EAchine MT99xx (H7, MT9916 ...)
// MODE_HM830 =22, // =>NRF24L01 / HM830
MODE_CFLIE =23, // =>NRF24L01 / CFlie
MODE_FLYSKY = 1, // =>A7105
MODE_HUBSAN = 2, // =>A7105
MODE_FRSKY = 3, // =>CC2500
MODE_HISKY = 4, // =>NRF24L01
MODE_V2X2 = 5, // =>NRF24L01
MODE_DSM2 = 6, // =>CYRF6936
MODE_DEVO =7, // =>CYRF6936
MODE_YD717 = 8, // =>NRF24L01
MODE_KN = 9, // =>NRF24L01
MODE_SYMAX = 10, // =>NRF24L01
MODE_SLT = 11, // =>NRF24L01
MODE_CX10 = 12, // =>NRF24L01
MODE_CG023 = 13, // =>NRF24L01
MODE_BAYANG = 14, // =>NRF24L01
MODE_FRSKYX = 15, // =>CC2500
MODE_ESKY = 16, // =>NRF24L01
MODE_MT99XX=17, // =>NRF24L01
MODE_MJXQ=18 // =>NRF24L01
};
enum Flysky
{
@ -99,7 +97,19 @@ enum CG023
YD829 = 1,
H8_3D = 2
};
enum MT99XX
{
MT99 = 0,
H7 = 1,
YZ = 2
};
enum MJXQ
{
WLH08 = 0,
X600 = 1,
X800 = 2,
H26D = 3
};
#define NONE 0
#define P_HIGH 1
@ -120,6 +130,10 @@ struct PPM_Parameters
//*******************
//*** Pinouts ***
//*******************
#define BUZZER 19 //A5
#define BUZZER_HTZ 440 // La clé de sol
#define BUZZER_TPS 300
//#define BIND_pin 13
#define LED_pin 13 //Promini original led on B5
//
@ -241,6 +255,8 @@ struct PPM_Parameters
#define Servo_AUX7 Servo_AUX & _BV(6)
#define Servo_AUX8 Servo_AUX & _BV(7)
#define GET_FLAG(ch, mask) ( ch ? mask : 0)
//************************
//*** Power settings ***
//************************
@ -405,6 +421,8 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
Bayang 14
FrskyX 15
ESky 16
MT99XX 17
MJXQ 18
BindBit=> 0x80 1=Bind/0=No
AutoBindBit=> 0x40 1=Yes /0=No
RangeCheck=> 0x20 1=Yes /0=No
@ -447,6 +465,15 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
CG023 0
YD829 1
H8_3D 2
sub_protocol==MT99XX
MT99 0
H7 1
YZ 2
sub_protocol==MJXQ
WLH08 0
X600 1
X800 2
H26D 3
Power value => 0x80 0=High/1=Low
Stream[3] = option_protocol;
option_protocol value is -127..127

View File

@ -1,151 +0,0 @@
/*
This program 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.
This program 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. If not, see <http://www.gnu.org/licenses/>.
*/
// EAchine MT99xx (H7, MT9916 ...) TX protocol
// Auxiliary channels:
// CH5: rate (3 pos)
// CH6: flip flag
// CH7: still camera
// CH8: video camera
// CH10: elevator trim
// CH11: aileron trim
#if defined(H7_NRF24L01_INO)
#include "iface_nrf24l01.h"
static const uint8_t H7_freq[] = {
0x02, 0x48, 0x0C, 0x3e, 0x16, 0x34, 0x20, 0x2A,
0x2A, 0x20, 0x34, 0x16, 0x3e, 0x0c, 0x48, 0x02
};
static const uint8_t H7_mys_byte[] = {
0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 0x04, 0x14,
0x05, 0x15, 0x06, 0x16, 0x07, 0x17, 0x00, 0x10
};
// flags going to packet[6]
// H7_FLAG_RATE0, // default rate, no flag
#define H7_FLAG_RATE1 0x01
#define H7_FLAG_RATE2 0x02
#define H7_FLAG_VIDEO 0x10
#define H7_FLAG_SNAPSHOT 0x20
#define H7_FLAG_FLIP 0x80
uint8_t H7_tx_addr[5];
uint8_t checksum_offset;
uint8_t channel_offset;
#define H7_PACKET_PERIOD 2625
#define H7_PAYPLOAD_SIZE 9
void H7_initTXID() {
checksum_offset = (rx_tx_addr[0] + rx_tx_addr[1]) & 0xff;
channel_offset = (((checksum_offset & 0xf0)>>4) + (checksum_offset & 0x0f)) % 8;
}
uint16_t H7_init() {
H7_initTXID();
NRF24L01_Reset();
NRF24L01_Initialize();
delay(10);
NRF24L01_FlushTx();
for(u8 i=0; i<5; i++) { H7_tx_addr[i] = 0xCC; }
XN297_SetTXAddr(H7_tx_addr, 5);
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // clear data ready, data sent, and retransmit
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // no AA
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // enable data pipe 0 only
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5 bytes address
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x2D); // set RF channel
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00);// no auto retransmit
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, 0x09); // rx payload size (unused ?)
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
NRF24L01_SetPower();
NRF24L01_Activate(0x73);
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00);
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x00);
NRF24L01_ReadReg(NRF24L01_1D_FEATURE); // read reg 1D back ?
delay(150);
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
delay(100);
H7_bind();
return H7_PACKET_PERIOD;
}
void H7_bind() {
BIND_IN_PROGRESS;
uint8_t counter = 58;
packet[0] = 0x20; // fixed (firmware date 2014-03-25 ?)
packet[1] = 0x14; // fixed
packet[2] = 0x03; // fixed
packet[3] = 0x25; // fixed
packet[4] = rx_tx_addr[0]; // 1st byte for data phase tx address
packet[5] = rx_tx_addr[1]; // 2nd byte for data phase tx address
packet[6] = 0x00; // 3rd byte for data phase tx address (always 0x00 ?)
packet[7] = checksum_offset; // checksum offset
packet[8] = 0xAA; // fixed
while(counter--) {
for (uint8_t ch = 0; ch < 16; ch++) {
delayMicroseconds(5);
NRF24L01_WriteReg(NRF24L01_07_STATUS,0x70);
NRF24L01_FlushTx();
NRF24L01_WriteReg(NRF24L01_05_RF_CH,H7_freq[ch]);
XN297_WritePayload(packet, H7_PAYPLOAD_SIZE); //(bind packet)
delayMicroseconds(H7_PACKET_PERIOD);
}
}
delay(15);
H7_tx_addr[0] = rx_tx_addr[0];
H7_tx_addr[1] = rx_tx_addr[1];
H7_tx_addr[2] = 0;
XN297_SetTXAddr(H7_tx_addr, 5);
BIND_DONE;
}
uint8_t H7_calcChecksum() {
uint8_t result=checksum_offset;
for(uint8_t i=0; i<8; i++) { result += packet[i]; }
return result & 0xFF;
}
void H7_WritePacket() {
static uint8_t channel=0;
packet[0] = map(Servo_data[THROTTLE], PPM_MIN, PPM_MAX, 0xE1, 0x00);
packet[1] = map(Servo_data[RUDDER], PPM_MIN, PPM_MAX, 0xE1, 0x00);
packet[2] = map(Servo_data[AILERON], PPM_MIN, PPM_MAX, 0x00, 0xE1);
packet[3] = map(Servo_data[ELEVATOR], PPM_MIN, PPM_MAX, 0x00, 0xE1);
packet[4] = map(Servo_data[AUX7], PPM_MIN, PPM_MAX, 0x3f, 0x00); // elevator trim 0x3f - 0x00
packet[5] = map(Servo_data[AUX8], PPM_MIN, PPM_MAX, 0x3f, 0x00); // aileron trim 0x3f - 0x00
packet[6] = 0x40; // flags (default is 0x00 on H7, 0x40 on MT9916 stock TX)
if(Servo_data[AUX2] > PPM_MAX_COMMAND) { packet[6] |= H7_FLAG_FLIP; }
if(Servo_data[AUX1] > PPM_MAX_COMMAND) { packet[6] |= H7_FLAG_RATE2; }
else if(Servo_data[AUX1] > PPM_MIN_COMMAND) { packet[6] |= H7_FLAG_RATE1; }
if(Servo_data[AUX5] > PPM_MAX_COMMAND) { packet[6] |= H7_FLAG_SNAPSHOT; }
if(Servo_data[AUX6] > PPM_MAX_COMMAND) { packet[6] |= H7_FLAG_VIDEO; }
packet[7] = H7_mys_byte[channel]; // looks like this byte has no importance actually
packet[8] = H7_calcChecksum();
NRF24L01_WriteReg(NRF24L01_05_RF_CH, H7_freq[channel]+channel_offset);
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
NRF24L01_FlushTx();
XN297_WritePayload(packet, H7_PAYPLOAD_SIZE);
channel++;
if(channel > 15) { channel = 0; }
}
uint16_t process_H7() {
H7_WritePacket();
return H7_PACKET_PERIOD;
}
#endif

View File

@ -1,321 +0,0 @@
/*
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.
Deviation 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 Deviation. If not, see <http://www.gnu.org/licenses/>.
*/
/* This protocol is for the HM Hobby HM830 RC Paper Airplane
Protocol spec:
Channel data:
AA BB CC DD EE FF GG
AA : Throttle Min=0x00 max =0x64
BB :
bit 0,1,2: Left/Right magnitude, bit 5 Polarity (set = right)
bit 6: Accelerate
bit 7: Right button (also the ABC Button)
CC : bit 0 seems to be impacted by the Right button
DD
EE
FF : Trim (bit 0-5: Magnitude, bit 6 polarity (set = right)
GG : Checksum (CRC8 on bytes AA-FF), init = 0xa5, poly = 0x01
*/
#ifdef HM830_NRF24L01_INO
#include "iface_nrf24l01.h"
enum {
HM830_BIND1A = 0,
HM830_BIND2A,
HM830_BIND3A,
HM830_BIND4A,
HM830_BIND5A,
HM830_BIND6A,
HM830_BIND7A,
HM830_DATA1,
HM830_DATA2,
HM830_DATA3,
HM830_DATA4,
HM830_DATA5,
HM830_DATA6,
HM830_DATA7,
HM830_BIND1B = 0x80,
HM830_BIND2B,
HM830_BIND3B,
HM830_BIND4B,
HM830_BIND5B,
HM830_BIND6B,
HM830_BIND7B,
};
static const uint8_t init_vals[][2] = {
{NRF24L01_17_FIFO_STATUS, 0x00},
{NRF24L01_16_RX_PW_P5, 0x07},
{NRF24L01_15_RX_PW_P4, 0x07},
{NRF24L01_14_RX_PW_P3, 0x07},
{NRF24L01_13_RX_PW_P2, 0x07},
{NRF24L01_12_RX_PW_P1, 0x07},
{NRF24L01_11_RX_PW_P0, 0x07},
{NRF24L01_0F_RX_ADDR_P5, 0xC6},
{NRF24L01_0E_RX_ADDR_P4, 0xC5},
{NRF24L01_0D_RX_ADDR_P3, 0xC4},
{NRF24L01_0C_RX_ADDR_P2, 0xC3},
{NRF24L01_09_CD, 0x00},
{NRF24L01_08_OBSERVE_TX, 0x00},
{NRF24L01_07_STATUS, 0x07},
// {NRF24L01_06_RF_SETUP, 0x07},
{NRF24L01_05_RF_CH, 0x18},
{NRF24L01_04_SETUP_RETR, 0x3F},
{NRF24L01_03_SETUP_AW, 0x03},
{NRF24L01_02_EN_RXADDR, 0x3F},
{NRF24L01_01_EN_AA, 0x3F},
{NRF24L01_00_CONFIG, 0x0E},
};
static uint8_t count;
static const uint8_t rf_ch[] = {0x08, 0x35, 0x12, 0x3f, 0x1c, 0x49, 0x26};
static const uint8_t bind_addr[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xc2};
static uint8_t crc8(uint32_t result, uint8_t *data, int len) {
int polynomial = 0x01;
for(int i = 0; i < len; i++) {
result = result ^ data[i];
for(int j = 0; j < 8; j++) {
if(result & 0x80) { result = (result << 1) ^ polynomial; }
else { result = result << 1; }
}
}
return result & 0xff;
}
static void HM830_init() {
NRF24L01_Initialize();
for (uint32_t i = 0; i < sizeof(init_vals) / sizeof(init_vals[0]); i++) { NRF24L01_WriteReg(init_vals[i][0], init_vals[i][1]); }
NRF24L01_SetTxRxMode(TX_EN);
NRF24L01_SetBitrate(0);
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, bind_addr, 5);
NRF24L01_WriteRegisterMulti(NRF24L01_0B_RX_ADDR_P1, bind_addr+1, 5);
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, bind_addr, 5);
NRF24L01_Activate(0x73); //Enable FEATURE
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07);
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3F);
//NRF24L01_ReadReg(NRF24L01_07_STATUS) ==> 0x07
// Check for Beken BK2421/BK2423 chip
// It is done by using Beken specific activate code, 0x53 and checking that status register changed appropriately
// There is no harm to run it on nRF24L01 because following closing activate command changes state back even if it does something on nRF24L01
// For detailed description of what's happening here see : http://www.inhaos.com/uploadfile/otherpic/AN0008-BK2423%20Communication%20In%20250Kbps%20Air%20Rate.pdf
NRF24L01_Activate(0x53); // magic for BK2421 bank switch
// printf("=>H377 : Trying to switch banks\n");
if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & 0x80) {
// printf("=>H377 : BK2421 detected\n");
long nul = 0;
// Beken registers don't have such nice names, so we just mention them by their numbers
// It's all magic, eavesdropped from real transfer and not even from the data sheet - it has slightly different values
NRF24L01_WriteRegisterMulti(0x00, (uint8_t *) "\x40\x4B\x01\xE2", 4);
NRF24L01_WriteRegisterMulti(0x01, (uint8_t *) "\xC0\x4B\x00\x00", 4);
NRF24L01_WriteRegisterMulti(0x02, (uint8_t *) "\xD0\xFC\x8C\x02", 4);
NRF24L01_WriteRegisterMulti(0x03, (uint8_t *) "\xF9\x00\x39\x21", 4);
NRF24L01_WriteRegisterMulti(0x04, (uint8_t *) "\xC1\x96\x9A\x1B", 4);
NRF24L01_WriteRegisterMulti(0x05, (uint8_t *) "\x24\x06\x7F\xA6", 4);
NRF24L01_WriteRegisterMulti(0x06, (uint8_t *) &nul, 4);
NRF24L01_WriteRegisterMulti(0x07, (uint8_t *) &nul, 4);
NRF24L01_WriteRegisterMulti(0x08, (uint8_t *) &nul, 4);
NRF24L01_WriteRegisterMulti(0x09, (uint8_t *) &nul, 4);
NRF24L01_WriteRegisterMulti(0x0A, (uint8_t *) &nul, 4);
NRF24L01_WriteRegisterMulti(0x0B, (uint8_t *) &nul, 4);
NRF24L01_WriteRegisterMulti(0x0C, (uint8_t *) "\x00\x12\x73\x00", 4);
NRF24L01_WriteRegisterMulti(0x0D, (uint8_t *) "\x46\xB4\x80\x00", 4);
//NRF24L01_WriteRegisterMulti(0x0E, (uint8_t *) "\x41\x10\x04\x82\x20\x08\x08\xF2\x7D\xEF\xFF", 11);
NRF24L01_WriteRegisterMulti(0x04, (uint8_t *) "\xC7\x96\x9A\x1B", 4);
NRF24L01_WriteRegisterMulti(0x04, (uint8_t *) "\xC1\x96\x9A\x1B", 4);
} else { } // printf("=>H377 : nRF24L01 detected\n");
//NRF24L01_ReadReg(NRF24L01_07_STATUS) ==> 0x07
NRF24L01_Activate(0x53); // switch bank back
NRF24L01_FlushTx();
//NRF24L01_ReadReg(NRF24L01_07_STATUS) ==> 0x0e
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x0e);
//NRF24L01_ReadReg(NRF24L01_00_CONFIG); ==> 0x0e
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x0e);
NRF24L01_ReadReg(NRF24L01_01_EN_AA); // No Auto Acknoledgement
}
static void build_bind_packet() {
for(int i = 0; i < 6; i++) { packet[i] = rx_tx_addr[i]; }
packet[6] = crc8(0xa5, packet, 6);
}
static void build_data_packet() {
uint8_t ail_sign = 0, trim_sign = 0;
throttle = (uint32_t)Servo_data[2] * 50 / PPM_MAX + 50;
if (throttle < 0) { throttle = 0; }
aileron = (uint32_t)Servo_data[0] * 8 / PPM_MAX;
if (aileron < 0) { aileron = -aileron; ail_sign = 1; }
if (aileron > 7) { aileron = 7; }
uint8_t turbo = (uint32_t)Servo_data[1] > 0 ? 1 : 0;
uint8_t trim = ((uint32_t)Servo_data[3] * 0x1f / PPM_MAX);
if (trim < 0) { trim = -trim; trim_sign = 1; }
if (trim > 0x1f) { trim = 0x1f; }
uint8_t rbutton = (uint32_t)Channels[4] > 0 ? 1 : 0;
packet[0] = throttle;
packet[1] = aileron;
if (ail_sign) { packet[1] |= 0x20; }
if (turbo) { packet[1] |= 0x40; }
if (rbutton) { packet[1] |= 0x80; }
packet[5] = trim;
if (trim_sign) { packet[5] |= 0x20;}
packet[6] = crc8(0xa5, packet, 6);
}
static void send_packet_hm830() {
NRF24L01_ReadReg(NRF24L01_17_FIFO_STATUS);
NRF24L01_WritePayload(packet, 7);
}
static uint16_t handle_binding() {
uint8_t status = NRF24L01_ReadReg(NRF24L01_07_STATUS);
if (status & 0x20) {
//Binding complete
phase = HM830_DATA1 + ((phase&0x7F)-HM830_BIND1A);
count = 0;
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, 5);
NRF24L01_WriteRegisterMulti(NRF24L01_0B_RX_ADDR_P1, rx_tx_addr+1, 5);
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5);
NRF24L01_FlushTx();
build_data_packet();
uint8_t rb = NRF24L01_ReadReg(NRF24L01_07_STATUS); //==> 0x0E
NRF24L01_WriteReg(NRF24L01_07_STATUS, rb);
rb = NRF24L01_ReadReg(NRF24L01_00_CONFIG); //==> 0x0E
NRF24L01_WriteReg(NRF24L01_00_CONFIG, rb);
send_packet_hm830();
return 14000;
}
switch (phase) {
case HM830_BIND1A:
//Look for a Rx that is already bound
NRF24L01_SetPower();
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, 5);
NRF24L01_WriteRegisterMulti(NRF24L01_0B_RX_ADDR_P1, rx_tx_addr+1, 5);
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5);
NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_ch[0]);
build_bind_packet();
break;
case HM830_BIND1B:
//Look for a Rx that is not yet bound
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, bind_addr, 5);
NRF24L01_WriteRegisterMulti(NRF24L01_0B_RX_ADDR_P1, bind_addr+1, 5);
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, bind_addr, 5);
NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_ch[0]);
break;
case HM830_BIND2A:
case HM830_BIND3A:
case HM830_BIND4A:
case HM830_BIND5A:
case HM830_BIND6A:
case HM830_BIND7A:
case HM830_BIND2B:
case HM830_BIND3B:
case HM830_BIND4B:
case HM830_BIND5B:
case HM830_BIND6B:
case HM830_BIND7B:
NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_ch[(phase&0x7F)-HM830_BIND1A]);
break;
}
NRF24L01_FlushTx();
uint8_t rb = NRF24L01_ReadReg(NRF24L01_07_STATUS); //==> 0x0E
NRF24L01_WriteReg(NRF24L01_07_STATUS, rb);
rb = NRF24L01_ReadReg(NRF24L01_00_CONFIG); //==> 0x0E
NRF24L01_WriteReg(NRF24L01_00_CONFIG, rb);
send_packet_hm830();
phase++;
if (phase == HM830_BIND7B+1) { phase = HM830_BIND1A; }
else if (phase == HM830_BIND7A+1) { phase = HM830_BIND1B; }
return 20000;
}
static uint16_t handle_data() {
uint8_t status = NRF24L01_ReadReg(NRF24L01_07_STATUS);
if (count <= 0 || !(status & 0x20)) {
if(count < 0 || ! (status & 0x20)) {
count = 0;
//We didn't get a response on this channel, try the next one
phase++;
if (phase-HM830_DATA1 > 6) { phase = HM830_DATA1; }
NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_ch[0]);
NRF24L01_FlushTx();
build_data_packet();
uint8_t rb = NRF24L01_ReadReg(NRF24L01_07_STATUS); //==> 0x0E
NRF24L01_WriteReg(NRF24L01_07_STATUS, rb);
rb = NRF24L01_ReadReg(NRF24L01_00_CONFIG); //==> 0x0E
NRF24L01_WriteReg(NRF24L01_00_CONFIG, rb);
send_packet_hm830();
return 14000;
}
}
build_data_packet();
count++;
if(count == 98) {
count = -1;
NRF24L01_SetPower();
}
uint8_t rb = NRF24L01_ReadReg(NRF24L01_07_STATUS); //==> 0x0E
NRF24L01_WriteReg(NRF24L01_07_STATUS, rb);
rb = NRF24L01_ReadReg(NRF24L01_00_CONFIG); //==> 0x0E
NRF24L01_WriteReg(NRF24L01_00_CONFIG, rb);
send_packet_hm830();
return 20000;
}
static uint32_t HM830_callback() {
if ((phase & 0x7F) < HM830_DATA1) { return handle_binding(); }
else { return handle_data(); }
}
static uint32_t HM830_setup(){
count = 0;
// initialize_tx_id
rx_tx_addr[4] = 0xee;
rx_tx_addr[5] = 0xc2;
HM830_init();
phase = HM830_BIND1A;
return 500;
// CLOCK_StartTimer(50000, HM830_callback);
}
/*
const void *HM830_Cmds(enum ProtoCmds cmd)
{
switch(cmd) {
case PROTOCMD_INIT: initialize(); return 0;
case PROTOCMD_DEINIT:
case PROTOCMD_RESET:
CLOCK_StopTimer();
return (void *)(NRF24L01_Reset() ? 1L : -1L);
case PROTOCMD_CHECK_AUTOBIND: return (void *)1L; // Always Autobind
case PROTOCMD_BIND: initialize(); return 0;
case PROTOCMD_NUMCHAN: return (void *) 5L; // T, A, E, R, G
case PROTOCMD_DEFAULT_NUMCHAN: return (void *)5L;
// TODO: return id correctly
case PROTOCMD_CURRENT_ID: return Model.fixed_id ? (void *)((unsigned long)Model.fixed_id) : 0;
case PROTOCMD_TELEMETRYSTATE: return (void *)(long)PROTO_TELEM_UNSUPPORTED;
default: break;
}
return 0;
}
*/
#endif //PROTO_HAS_NRF24L01

View File

@ -9,7 +9,6 @@ Afin d'ajouter :
- Un rebind hardware en PPM
- La radio TARANIS (TAERB, B = rebind ;-) ) et redéclaration des radios
- Un script "LUA" afin de faciliter la position des manches
- Le protocole H7

Binary file not shown.