mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-07-03 03:57:51 +00:00
Suivit du projet
This commit is contained in:
parent
8faf5abe38
commit
eb2e9477b3
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
247
Multiprotocol/MJXQ_nrf24l01.ino
Normal file
247
Multiprotocol/MJXQ_nrf24l01.ino
Normal 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
|
221
Multiprotocol/MT99xx_nrf24l01.ino
Normal file
221
Multiprotocol/MT99xx_nrf24l01.ino
Normal 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
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
BIN
sync.ffs_db
BIN
sync.ffs_db
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user