diff --git a/Multiprotocol/A7105_SPI.ino b/Multiprotocol/A7105_SPI.ino index 251d31e..349de65 100644 --- a/Multiprotocol/A7105_SPI.ino +++ b/Multiprotocol/A7105_SPI.ino @@ -30,12 +30,12 @@ void A7105_WriteData(uint8_t len, uint8_t channel) A7105_Strobe(A7105_TX); } -void A7105_ReadData() { +void A7105_ReadData(uint8_t len=16) { uint8_t i; A7105_Strobe(0xF0); //A7105_RST_RDPTR A7105_CSN_off; SPI_Write(0x45); - for (i=0;i<16;i++) + for (i=0;i= Model.num_channels) { packet[chmap[i]] = 0x64; continue; } - uint32_t value = (uint32_t)Servo_data[i] * 0x66 / PPM_MAX + 0x66; - if (value < 0) { value = 0; } - if (value > 0xff) { value = 0xff; } + uint32_t value = map(limit_channel_100(i),servo_min_100,servo_max_100,0,204); packet[chmap[i]] = value; } packet[8] = 0x64; diff --git a/Multiprotocol/CX10_nrf24l01.ino b/Multiprotocol/CX10_nrf24l01.ino index adc7279..f836e02 100644 --- a/Multiprotocol/CX10_nrf24l01.ino +++ b/Multiprotocol/CX10_nrf24l01.ino @@ -25,10 +25,6 @@ #define Q282_PACKET_SIZE 21 #define CX10_PACKET_PERIOD 1316 // Timeout for callback in uSec #define CX10A_PACKET_PERIOD 6000 -<<<<<<< HEAD -#define CX10A_BIND_COUNT 400 // 2 seconds -======= ->>>>>>> refs/remotes/pascallanger/master #define CX10_INITIAL_WAIT 500 @@ -201,30 +197,15 @@ uint16_t CX10_callback() } break; case CX10_BIND2: -<<<<<<< HEAD - 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)) -======= if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) ->>>>>>> refs/remotes/pascallanger/master { // RX fifo data ready XN297_ReadPayload(packet, packet_length); NRF24L01_SetTxRxMode(TXRX_OFF); NRF24L01_SetTxRxMode(TX_EN); if(packet[9] == 1) { -<<<<<<< HEAD - phase = CX10_BIND1; - bind_counter=0; -======= BIND_DONE; phase = CX10_DATA; ->>>>>>> refs/remotes/pascallanger/master } } else @@ -234,11 +215,7 @@ uint16_t CX10_callback() NRF24L01_FlushTx(); NRF24L01_SetTxRxMode(TX_EN); CX10_Write_Packet(1); -<<<<<<< HEAD - delayMicroseconds(400); // 300µs in deviation but not working so using 400µs instead -======= delayMicroseconds(400); ->>>>>>> refs/remotes/pascallanger/master // switch to RX mode NRF24L01_SetTxRxMode(TXRX_OFF); NRF24L01_FlushRx(); @@ -288,10 +265,6 @@ uint16_t initCX10(void) packet_period = CX10A_PACKET_PERIOD; phase = CX10_BIND2; -<<<<<<< HEAD - bind_counter=CX10A_BIND_COUNT; -======= ->>>>>>> refs/remotes/pascallanger/master for(uint8_t i=0; i<4; i++) packet[5+i] = 0xff; // clear aircraft id diff --git a/Multiprotocol/CYRF6936_SPI.ino b/Multiprotocol/CYRF6936_SPI.ino index 6a3bae6..2b2d52a 100644 --- a/Multiprotocol/CYRF6936_SPI.ino +++ b/Multiprotocol/CYRF6936_SPI.ino @@ -192,18 +192,11 @@ static void CYRF_StartReceive() CYRF_ReadRegisterMulti(CYRF_21_RX_BUFFER, dpbuffer, 0x10); } */ -<<<<<<< HEAD -static void CYRF_ReadDataPacketLen(uint8_t dpbuffer[], uint8_t length) -======= void CYRF_ReadDataPacketLen(uint8_t dpbuffer[], uint8_t length) ->>>>>>> refs/remotes/pascallanger/master { CYRF_ReadRegisterMulti(CYRF_21_RX_BUFFER, dpbuffer, length); } -<<<<<<< HEAD -======= ->>>>>>> refs/remotes/pascallanger/master static void CYRF_WriteDataPacketLen(const uint8_t dpbuffer[], uint8_t len) { CYRF_WriteRegister(CYRF_01_TX_LENGTH, len); diff --git a/Multiprotocol/CYRF6936_j6pro.ino b/Multiprotocol/CYRF6936_j6pro.ino deleted file mode 100644 index 623ae5f..0000000 --- a/Multiprotocol/CYRF6936_j6pro.ino +++ /dev/null @@ -1,277 +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 . - */ - -#if defined(J6PRO_CYRF6936_INO) -#include "iface_cyrf6936.h" - -#define NUM_WAIT_LOOPS (100 / 5) //each loop is ~5us. Do not wait more than 100us - -//For Debug -//#define NO_SCRAMBLE - -enum J6ProState { - J6PRO_BIND, - J6PRO_BIND_01, - J6PRO_BIND_03_START, - J6PRO_BIND_03_CHECK, - J6PRO_BIND_05_1, - J6PRO_BIND_05_2, - J6PRO_BIND_05_3, - J6PRO_BIND_05_4, - J6PRO_BIND_05_5, - J6PRO_BIND_05_6, - J6PRO_CHANSEL, - J6PRO_CHAN_1, - J6PRO_CHAN_2, - J6PRO_CHAN_3, - J6PRO_CHAN_4, -}; - -static const uint8_t J6Pro_sopcodes[][8] = { - /* Note these are in order transmitted (LSB 1st) */ - {0x3C, 0x37, 0xCC, 0x91, 0xE2, 0xF8, 0xCC, 0x91}, - {0x9B, 0xC5, 0xA1, 0x0F, 0xAD, 0x39, 0xA2, 0x0F}, - {0xEF, 0x64, 0xB0, 0x2A, 0xD2, 0x8F, 0xB1, 0x2A}, - {0x66, 0xCD, 0x7C, 0x50, 0xDD, 0x26, 0x7C, 0x50}, - {0x5C, 0xE1, 0xF6, 0x44, 0xAD, 0x16, 0xF6, 0x44}, - {0x5A, 0xCC, 0xAE, 0x46, 0xB6, 0x31, 0xAE, 0x46}, - {0xA1, 0x78, 0xDC, 0x3C, 0x9E, 0x82, 0xDC, 0x3C}, - {0xB9, 0x8E, 0x19, 0x74, 0x6F, 0x65, 0x18, 0x74}, - {0xDF, 0xB1, 0xC0, 0x49, 0x62, 0xDF, 0xC1, 0x49}, - {0x97, 0xE5, 0x14, 0x72, 0x7F, 0x1A, 0x14, 0x72}, - {0x82, 0xC7, 0x90, 0x36, 0x21, 0x03, 0xFF, 0x17}, - {0xE2, 0xF8, 0xCC, 0x91, 0x3C, 0x37, 0xCC, 0x91}, //Note: the '03' was '9E' in the Cypress recommended table - {0xAD, 0x39, 0xA2, 0x0F, 0x9B, 0xC5, 0xA1, 0x0F}, //The following are the same as the 1st 8 above, - {0xD2, 0x8F, 0xB1, 0x2A, 0xEF, 0x64, 0xB0, 0x2A}, //but with the upper and lower word swapped - {0xDD, 0x26, 0x7C, 0x50, 0x66, 0xCD, 0x7C, 0x50}, - {0xAD, 0x16, 0xF6, 0x44, 0x5C, 0xE1, 0xF6, 0x44}, - {0xB6, 0x31, 0xAE, 0x46, 0x5A, 0xCC, 0xAE, 0x46}, - {0x9E, 0x82, 0xDC, 0x3C, 0xA1, 0x78, 0xDC, 0x3C}, - {0x6F, 0x65, 0x18, 0x74, 0xB9, 0x8E, 0x19, 0x74}, -}; -const uint8_t bind_sop_code[] = {0x62, 0xdf, 0xc1, 0x49, 0xdf, 0xb1, 0xc0, 0x49}; -const uint8_t data_code[] = {0x02, 0xf9, 0x93, 0x97, 0x02, 0xfa, 0x5c, 0xe3, 0x01, 0x2b, 0xf1, 0xdb, 0x01, 0x32, 0xbe, 0x6f}; - -static uint8_t stateJ6P; -static uint8_t radio_ch[4]; -static uint8_t num_channels; - -void J6Pro_build_bind_packet() -{ - packet[0] = 0x01; //Packet type - packet[1] = 0x01; //FIXME: What is this? Model number maybe? - packet[2] = 0x56; //FIXME: What is this? - packet[3] = cyrfmfg_id[0]; - packet[4] = cyrfmfg_id[1]; - packet[5] = cyrfmfg_id[2]; - packet[6] = cyrfmfg_id[3]; - packet[7] = cyrfmfg_id[4]; - packet[8] = cyrfmfg_id[5]; -} -void J6Pro_build_data_packet() -{ - uint8_t i; - uint32_t upperbits = 0; - packet[0] = 0xaa; //FIXME what is this? - for (i = 0; i < 12; i++) { - if (i >= num_channels) { - packet[i+1] = 0xff; - continue; - } - uint32_t value = (uint32_t)Servo_data[i] * 0x200 / PPM_MAX + 0x200; - if (value < 0) - value = 0; - if (value > 0x3ff) - value = 0x3ff; - packet[i+1] = value & 0xff; - upperbits |= (value >> 8) << (i * 2); - } - packet[13] = upperbits & 0xff; - packet[14] = (upperbits >> 8) & 0xff; - packet[15] = (upperbits >> 16) & 0xff; -} - -static void J6Pro_cyrf_init() -{ - /* Initialise CYRF chip */ - CYRF_WriteRegister(CYRF_28_CLK_EN, 0x02); - CYRF_WriteRegister(CYRF_32_AUTO_CAL_TIME, 0x3c); - CYRF_WriteRegister(CYRF_35_AUTOCAL_OFFSET, 0x14); - CYRF_WriteRegister(CYRF_1C_TX_OFFSET_MSB, 0x05); - CYRF_WriteRegister(CYRF_1B_TX_OFFSET_LSB, 0x55); - CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x25); - CYRF_WriteRegister(CYRF_03_TX_CFG, 0x05 | CYRF_BIND_POWER); - CYRF_WriteRegister(CYRF_06_RX_CFG, 0x8a); - CYRF_WriteRegister(CYRF_03_TX_CFG, 0x28 | CYRF_BIND_POWER); - CYRF_WriteRegister(CYRF_12_DATA64_THOLD, 0x0e); - CYRF_WriteRegister(CYRF_10_FRAMING_CFG, 0xee); - CYRF_WriteRegister(CYRF_1F_TX_OVERRIDE, 0x00); - CYRF_WriteRegister(CYRF_1E_RX_OVERRIDE, 0x00); - CYRF_ConfigDataCode(data_code, 16); - CYRF_WritePreamble(0x023333); -} -static void J6Pro_cyrf_bindinit() -{ -/* Use when binding */ - //0.060470# 03 2f - CYRF_WriteRegister(CYRF_03_TX_CFG, 0x28 | 0x07); //Use max power for binding in case there is no telem module - - CYRF_ConfigRFChannel(0x52); - CYRF_ConfigSOPCode(bind_sop_code); - CYRF_ConfigCRCSeed(0x0000); - CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a); - CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x83); - //0.061511# 13 20 - - CYRF_ConfigRFChannel(0x52); - //0.062684# 0f 05 - CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x25); - //0.062792# 0f 05 - CYRF_WriteRegister(CYRF_02_TX_CTRL, 0x40); - J6Pro_build_bind_packet(); //01 01 e9 49 ec a9 c4 c1 ff - //CYRF_WriteDataPacketLen(packet, 0x09); -} -static void J6Pro_cyrf_datainit() -{ -/* Use when already bound */ - //0.094007# 0f 05 - uint8_t sop_idx = (0xff & (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + cyrfmfg_id[3] - cyrfmfg_id[5])) % 19; - uint16_t crc = (0xff & (cyrfmfg_id[1] - cyrfmfg_id[4] + cyrfmfg_id[5])) | - ((0xff & (cyrfmfg_id[2] + cyrfmfg_id[3] - cyrfmfg_id[4] + cyrfmfg_id[5])) << 8); - CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x25); - CYRF_ConfigSOPCode(J6Pro_sopcodes[sop_idx]); - CYRF_ConfigCRCSeed(crc); -} - -static void J6Pro_set_radio_channels() -{ - //FIXME: Query free channels - //lowest channel is 0x08, upper channel is 0x4d? - CYRF_FindBestChannels(radio_ch, 3, 5, 8, 77); - radio_ch[3] = radio_ch[0]; -} - -static uint16_t j6pro_cb() -{ - switch(stateJ6P) { - case J6PRO_BIND: - J6Pro_cyrf_bindinit(); - stateJ6P = J6PRO_BIND_01; - //no break because we want to send the 1st bind packet now - case J6PRO_BIND_01: - CYRF_ConfigRFChannel(0x52); - CYRF_SetTxRxMode(TX_EN); - //0.062684# 0f 05 - CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x25); - //0.062684# 0f 05 - CYRF_WriteDataPacketLen(packet, 0x09); - stateJ6P = J6PRO_BIND_03_START; - return 3000; //3msec - case J6PRO_BIND_03_START: - { - int i = 0; - while (! (CYRF_ReadRegister(0x04) & 0x06)) - if(++i > NUM_WAIT_LOOPS) - break; - } - CYRF_ConfigRFChannel(0x53); - CYRF_SetTxRxMode(RX_EN); - CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a); - CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x83); - stateJ6P = J6PRO_BIND_03_CHECK; - return 30000; //30msec - case J6PRO_BIND_03_CHECK: - { - uint8_t rx = CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS); - if((rx & 0x1a) == 0x1a) { - rx = CYRF_ReadRegister(CYRF_0A_RX_LENGTH); - if(rx == 0x0f) { - rx = CYRF_ReadRegister(CYRF_09_RX_COUNT); - if(rx == 0x0f) { - //Expected and actual length are both 15 - CYRF_ReadDataPacketLen(packet, rx); - if (packet[0] == 0x03 && - packet[3] == cyrfmfg_id[0] && - packet[4] == cyrfmfg_id[1] && - packet[5] == cyrfmfg_id[2] && - packet[6] == cyrfmfg_id[3] && - packet[7] == cyrfmfg_id[4] && - packet[8] == cyrfmfg_id[5]) - { - //Send back Ack - packet[0] = 0x05; - CYRF_ConfigRFChannel(0x54); - CYRF_SetTxRxMode(TX_EN); - stateJ6P = J6PRO_BIND_05_1; - return 2000; //2msec - } - } - } - } - stateJ6P = J6PRO_BIND_01; - return 500; - } - case J6PRO_BIND_05_1: - case J6PRO_BIND_05_2: - case J6PRO_BIND_05_3: - case J6PRO_BIND_05_4: - case J6PRO_BIND_05_5: - case J6PRO_BIND_05_6: - CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x25); - CYRF_WriteDataPacketLen(packet, 0x0f); - stateJ6P = stateJ6P + 1; - return 4600; //4.6msec - case J6PRO_CHANSEL: - BIND_DONE; - J6Pro_set_radio_channels(); - J6Pro_cyrf_datainit(); - stateJ6P = J6PRO_CHAN_1; - case J6PRO_CHAN_1: - //Keep transmit power updated - CYRF_SetPower(CYRF_HIGH_POWER); - J6Pro_build_data_packet(); - //return 3400; - case J6PRO_CHAN_2: - //return 3500; - case J6PRO_CHAN_3: - //return 3750 - case J6PRO_CHAN_4: - CYRF_ConfigRFChannel(radio_ch[stateJ6P - J6PRO_CHAN_1]); - CYRF_SetTxRxMode(TX_EN); - CYRF_WriteDataPacket(packet); - if (stateJ6P == J6PRO_CHAN_4) { - stateJ6P = J6PRO_CHAN_1; - return 13900; - } - stateJ6P = stateJ6P + 1; - return 3550; - } - return 0; -} - -static uint16_t j6pro_setup() -{ - CYRF_Reset(); - J6Pro_cyrf_init(); - num_channels = 8; - if (IS_AUTOBIND_FLAG_on) { - stateJ6P = J6PRO_BIND; - BIND_IN_PROGRESS; - } else { - stateJ6P = J6PRO_CHANSEL; - } - return 2400; -} -#endif diff --git a/Multiprotocol/Cc2500_skyartec.ino b/Multiprotocol/Cc2500_skyartec.ino index 7f3a932..e54abb3 100644 --- a/Multiprotocol/Cc2500_skyartec.ino +++ b/Multiprotocol/Cc2500_skyartec.ino @@ -37,53 +37,53 @@ enum { static void skyartec_init() { CC2500_Reset(); - cc2500_writeReg(CC2500_16_MCSM2, 0x07); - cc2500_writeReg(CC2500_17_MCSM1, 0x30); - cc2500_writeReg(CC2500_1E_WOREVT1, 0x87); - cc2500_writeReg(CC2500_1F_WOREVT0, 0x6b); - cc2500_writeReg(CC2500_20_WORCTRL, 0xf8); - cc2500_writeReg(CC2500_2A_PTEST, 0x7f); - cc2500_writeReg(CC2500_2B_AGCTEST, 0x3f); - cc2500_writeReg(CC2500_0B_FSCTRL1, 0x09); - cc2500_writeReg(CC2500_0C_FSCTRL0, 0x00); - cc2500_writeReg(CC2500_0D_FREQ2, 0x5d); - cc2500_writeReg(CC2500_0E_FREQ1, 0x93); - cc2500_writeReg(CC2500_0F_FREQ0, 0xb1); - cc2500_writeReg(CC2500_10_MDMCFG4, 0x2d); - cc2500_writeReg(CC2500_11_MDMCFG3, 0x20); - cc2500_writeReg(CC2500_12_MDMCFG2, 0x73); - cc2500_writeReg(CC2500_13_MDMCFG1, 0x22); - cc2500_writeReg(CC2500_14_MDMCFG0, 0xf8); - cc2500_writeReg(CC2500_0A_CHANNR, 0xcd); - cc2500_writeReg(CC2500_15_DEVIATN, 0x50); - cc2500_writeReg(CC2500_21_FREND1, 0xb6); - cc2500_writeReg(CC2500_22_FREND0, 0x10); - cc2500_writeReg(CC2500_18_MCSM0, 0x18); - cc2500_writeReg(CC2500_19_FOCCFG, 0x1d); - cc2500_writeReg(CC2500_1A_BSCFG, 0x1c); - cc2500_writeReg(CC2500_1B_AGCCTRL2, 0xc7); - cc2500_writeReg(CC2500_1C_AGCCTRL1, 0x00); - cc2500_writeReg(CC2500_1D_AGCCTRL0, 0xb2); - cc2500_writeReg(CC2500_23_FSCAL3, 0xea); - cc2500_writeReg(CC2500_24_FSCAL2, 0x0a); - cc2500_writeReg(CC2500_25_FSCAL1, 0x00); - cc2500_writeReg(CC2500_26_FSCAL0, 0x11); - cc2500_writeReg(CC2500_29_FSTEST, 0x59); - cc2500_writeReg(CC2500_2C_TEST2, 0x88); - cc2500_writeReg(CC2500_2D_TEST1, 0x31); - cc2500_writeReg(CC2500_2E_TEST0, 0x0b); - cc2500_writeReg(CC2500_07_PKTCTRL1, 0x05); - cc2500_writeReg(CC2500_08_PKTCTRL0, 0x05); - cc2500_writeReg(CC2500_09_ADDR, 0x43); - cc2500_writeReg(CC2500_06_PKTLEN, 0xff); - cc2500_writeReg(CC2500_04_SYNC1, 0x13); - cc2500_writeReg(CC2500_05_SYNC0, 0x18); + CC2500_WriteReg(CC2500_16_MCSM2, 0x07); + CC2500_WriteReg(CC2500_17_MCSM1, 0x30); + CC2500_WriteReg(CC2500_1E_WOREVT1, 0x87); + CC2500_WriteReg(CC2500_1F_WOREVT0, 0x6b); + CC2500_WriteReg(CC2500_20_WORCTRL, 0xf8); + CC2500_WriteReg(CC2500_2A_PTEST, 0x7f); + CC2500_WriteReg(CC2500_2B_AGCTEST, 0x3f); + CC2500_WriteReg(CC2500_0B_FSCTRL1, 0x09); + CC2500_WriteReg(CC2500_0C_FSCTRL0, 0x00); + CC2500_WriteReg(CC2500_0D_FREQ2, 0x5d); + CC2500_WriteReg(CC2500_0E_FREQ1, 0x93); + CC2500_WriteReg(CC2500_0F_FREQ0, 0xb1); + CC2500_WriteReg(CC2500_10_MDMCFG4, 0x2d); + CC2500_WriteReg(CC2500_11_MDMCFG3, 0x20); + CC2500_WriteReg(CC2500_12_MDMCFG2, 0x73); + CC2500_WriteReg(CC2500_13_MDMCFG1, 0x22); + CC2500_WriteReg(CC2500_14_MDMCFG0, 0xf8); + CC2500_WriteReg(CC2500_0A_CHANNR, 0xcd); + CC2500_WriteReg(CC2500_15_DEVIATN, 0x50); + CC2500_WriteReg(CC2500_21_FREND1, 0xb6); + CC2500_WriteReg(CC2500_22_FREND0, 0x10); + CC2500_WriteReg(CC2500_18_MCSM0, 0x18); + CC2500_WriteReg(CC2500_19_FOCCFG, 0x1d); + CC2500_WriteReg(CC2500_1A_BSCFG, 0x1c); + CC2500_WriteReg(CC2500_1B_AGCCTRL2, 0xc7); + CC2500_WriteReg(CC2500_1C_AGCCTRL1, 0x00); + CC2500_WriteReg(CC2500_1D_AGCCTRL0, 0xb2); + CC2500_WriteReg(CC2500_23_FSCAL3, 0xea); + CC2500_WriteReg(CC2500_24_FSCAL2, 0x0a); + CC2500_WriteReg(CC2500_25_FSCAL1, 0x00); + CC2500_WriteReg(CC2500_26_FSCAL0, 0x11); + CC2500_WriteReg(CC2500_29_FSTEST, 0x59); + CC2500_WriteReg(CC2500_2C_TEST2, 0x88); + CC2500_WriteReg(CC2500_2D_TEST1, 0x31); + CC2500_WriteReg(CC2500_2E_TEST0, 0x0b); + CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x05); + CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x05); + CC2500_WriteReg(CC2500_09_ADDR, 0x43); + CC2500_WriteReg(CC2500_06_PKTLEN, 0xff); + CC2500_WriteReg(CC2500_04_SYNC1, 0x13); + CC2500_WriteReg(CC2500_05_SYNC0, 0x18); CC2500_SetTxRxMode(TX_EN); CC2500_SetPower(); - cc2500_strobe(CC2500_SFTX); - cc2500_strobe(CC2500_SFRX); - cc2500_strobe(CC2500_SXOFF); - cc2500_strobe(CC2500_SIDLE); + CC2500_Strobe(CC2500_SFTX); + CC2500_Strobe(CC2500_SFRX); + CC2500_Strobe(CC2500_SXOFF); + CC2500_Strobe(CC2500_SIDLE); } static void add_pkt_suffix() { @@ -104,7 +104,7 @@ static void send_data_packet() { packet[1] = TX_ADDR; //Tx Addr? packet[2] = 0x01; //??? for(int i = 0; i < 7; i++) { - uint32_t value = (uint32_t)Servo_data[i] * 0x280 / PPM_MAX + 0x280; + uint32_t value = map(limit_channel_100(i),servo_min_100,servo_max_100,0,1280); if(value < 0) { value = 0; } if(value > 0x500) { value = 0x500; } packet[3+2*i] = value >> 8; @@ -112,11 +112,11 @@ static void send_data_packet() { } add_pkt_suffix(); //for(int i = 0; i < 20; i++) printf("%02x ", packet[i]); printf("\n"); - cc2500_writeReg(CC2500_04_SYNC1, ((binding_idx >> 0) & 0xff)); - cc2500_writeReg(CC2500_05_SYNC0, ((binding_idx >> 8) & 0xff)); - cc2500_writeReg(CC2500_09_ADDR, TX_ADDR); - cc2500_writeReg(CC2500_0A_CHANNR, TX_CHANNEL); - cc2500_writeFifo(packet, 20); + CC2500_WriteReg(CC2500_04_SYNC1, ((binding_idx >> 0) & 0xff)); + CC2500_WriteReg(CC2500_05_SYNC0, ((binding_idx >> 8) & 0xff)); + CC2500_WriteReg(CC2500_09_ADDR, TX_ADDR); + CC2500_WriteReg(CC2500_0A_CHANNR, TX_CHANNEL); + CC2500_WriteData(packet, 20); } static void send_bind_packet() { @@ -135,16 +135,16 @@ static void send_bind_packet() { uint8_t xore = 0; for(int i = 3; i < 11; i++) { xore ^= packet[i]; } packet[11] = xore; - cc2500_writeReg(CC2500_04_SYNC1, 0x7d); - cc2500_writeReg(CC2500_05_SYNC0, 0x7d); - cc2500_writeReg(CC2500_09_ADDR, 0x7d); - cc2500_writeReg(CC2500_0A_CHANNR, 0x7d); - cc2500_writeFifo(packet, 12); + CC2500_WriteReg(CC2500_04_SYNC1, 0x7d); + CC2500_WriteReg(CC2500_05_SYNC0, 0x7d); + CC2500_WriteReg(CC2500_09_ADDR, 0x7d); + CC2500_WriteReg(CC2500_0A_CHANNR, 0x7d); + CC2500_WriteData(packet, 12); } static uint16_t skyartec_cb() { if (state & 0x01) { - cc2500_strobe(CC2500_SIDLE); + CC2500_Strobe(CC2500_SIDLE); if (state == SKYARTEC_LAST) { CC2500_SetPower(); state = SKYARTEC_PKT1; } else { state++; } return 3000; diff --git a/Multiprotocol/DSM2_cyrf6936.ino b/Multiprotocol/DSM2_cyrf6936.ino deleted file mode 100644 index 19a969e..0000000 --- a/Multiprotocol/DSM2_cyrf6936.ino +++ /dev/null @@ -1,538 +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. - - 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 . - */ - -#if defined(DSM2_CYRF6936_INO) - -#include "iface_cyrf6936.h" - -#define RANDOM_CHANNELS 0 // disabled -//#define RANDOM_CHANNELS 1 // enabled -#define BIND_CHANNEL 0x0d //13 This can be any odd channel -#define NUM_WAIT_LOOPS (100 / 5) //each loop is ~5us. Do not wait more than 100us - -//During binding we will send BIND_COUNT/2 packets -//One packet each 10msec -#define BIND_COUNT1 600 - -enum { - DSM2_BIND = 0, - DSM2_CHANSEL = BIND_COUNT1 + 0, - DSM2_CH1_WRITE_A = BIND_COUNT1 + 1, - DSM2_CH1_CHECK_A = BIND_COUNT1 + 2, - DSM2_CH2_WRITE_A = BIND_COUNT1 + 3, - DSM2_CH2_CHECK_A = BIND_COUNT1 + 4, - DSM2_CH2_READ_A = BIND_COUNT1 + 5, - DSM2_CH1_WRITE_B = BIND_COUNT1 + 6, - DSM2_CH1_CHECK_B = BIND_COUNT1 + 7, - DSM2_CH2_WRITE_B = BIND_COUNT1 + 8, - DSM2_CH2_CHECK_B = BIND_COUNT1 + 9, - DSM2_CH2_READ_B = BIND_COUNT1 + 10, -}; - -const uint8_t PROGMEM pncodes[5][9][8] = { - /* Note these are in order transmitted (LSB 1st) */ - { /* Row 0 */ - /* Col 0 */ {0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8}, - /* Col 1 */ {0x88, 0x17, 0x13, 0x3B, 0x2D, 0xBF, 0x06, 0xD6}, - /* Col 2 */ {0xF1, 0x94, 0x30, 0x21, 0xA1, 0x1C, 0x88, 0xA9}, - /* Col 3 */ {0xD0, 0xD2, 0x8E, 0xBC, 0x82, 0x2F, 0xE3, 0xB4}, - /* Col 4 */ {0x8C, 0xFA, 0x47, 0x9B, 0x83, 0xA5, 0x66, 0xD0}, - /* Col 5 */ {0x07, 0xBD, 0x9F, 0x26, 0xC8, 0x31, 0x0F, 0xB8}, - /* Col 6 */ {0xEF, 0x03, 0x95, 0x89, 0xB4, 0x71, 0x61, 0x9D}, - /* Col 7 */ {0x40, 0xBA, 0x97, 0xD5, 0x86, 0x4F, 0xCC, 0xD1}, - /* Col 8 */ {0xD7, 0xA1, 0x54, 0xB1, 0x5E, 0x89, 0xAE, 0x86} - }, - { /* Row 1 */ - /* Col 0 */ {0x83, 0xF7, 0xA8, 0x2D, 0x7A, 0x44, 0x64, 0xD3}, - /* Col 1 */ {0x3F, 0x2C, 0x4E, 0xAA, 0x71, 0x48, 0x7A, 0xC9}, - /* Col 2 */ {0x17, 0xFF, 0x9E, 0x21, 0x36, 0x90, 0xC7, 0x82}, - /* Col 3 */ {0xBC, 0x5D, 0x9A, 0x5B, 0xEE, 0x7F, 0x42, 0xEB}, - /* Col 4 */ {0x24, 0xF5, 0xDD, 0xF8, 0x7A, 0x77, 0x74, 0xE7}, - /* Col 5 */ {0x3D, 0x70, 0x7C, 0x94, 0xDC, 0x84, 0xAD, 0x95}, - /* Col 6 */ {0x1E, 0x6A, 0xF0, 0x37, 0x52, 0x7B, 0x11, 0xD4}, - /* Col 7 */ {0x62, 0xF5, 0x2B, 0xAA, 0xFC, 0x33, 0xBF, 0xAF}, - /* Col 8 */ {0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97} - }, - { /* Row 2 */ - /* Col 0 */ {0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97}, - /* Col 1 */ {0x8E, 0x4A, 0xD0, 0xA9, 0xA7, 0xFF, 0x20, 0xCA}, - /* Col 2 */ {0x4C, 0x97, 0x9D, 0xBF, 0xB8, 0x3D, 0xB5, 0xBE}, - /* Col 3 */ {0x0C, 0x5D, 0x24, 0x30, 0x9F, 0xCA, 0x6D, 0xBD}, - /* Col 4 */ {0x50, 0x14, 0x33, 0xDE, 0xF1, 0x78, 0x95, 0xAD}, - /* Col 5 */ {0x0C, 0x3C, 0xFA, 0xF9, 0xF0, 0xF2, 0x10, 0xC9}, - /* Col 6 */ {0xF4, 0xDA, 0x06, 0xDB, 0xBF, 0x4E, 0x6F, 0xB3}, - /* Col 7 */ {0x9E, 0x08, 0xD1, 0xAE, 0x59, 0x5E, 0xE8, 0xF0}, - /* Col 8 */ {0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E} - }, - { /* Row 3 */ - /* Col 0 */ {0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E}, - /* Col 1 */ {0x80, 0x69, 0x26, 0x80, 0x08, 0xF8, 0x49, 0xE7}, - /* Col 2 */ {0x7D, 0x2D, 0x49, 0x54, 0xD0, 0x80, 0x40, 0xC1}, - /* Col 3 */ {0xB6, 0xF2, 0xE6, 0x1B, 0x80, 0x5A, 0x36, 0xB4}, - /* Col 4 */ {0x42, 0xAE, 0x9C, 0x1C, 0xDA, 0x67, 0x05, 0xF6}, - /* Col 5 */ {0x9B, 0x75, 0xF7, 0xE0, 0x14, 0x8D, 0xB5, 0x80}, - /* Col 6 */ {0xBF, 0x54, 0x98, 0xB9, 0xB7, 0x30, 0x5A, 0x88}, - /* Col 7 */ {0x35, 0xD1, 0xFC, 0x97, 0x23, 0xD4, 0xC9, 0x88}, - /* Col 8 */ {0x88, 0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40} - }, - { /* Row 4 */ - /* Col 0 */ {0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40, 0x93}, - /* Col 1 */ {0xDC, 0x68, 0x08, 0x99, 0x97, 0xAE, 0xAF, 0x8C}, - /* Col 2 */ {0xC3, 0x0E, 0x01, 0x16, 0x0E, 0x32, 0x06, 0xBA}, - /* Col 3 */ {0xE0, 0x83, 0x01, 0xFA, 0xAB, 0x3E, 0x8F, 0xAC}, - /* Col 4 */ {0x5C, 0xD5, 0x9C, 0xB8, 0x46, 0x9C, 0x7D, 0x84}, - /* Col 5 */ {0xF1, 0xC6, 0xFE, 0x5C, 0x9D, 0xA5, 0x4F, 0xB7}, - /* Col 6 */ {0x58, 0xB5, 0xB3, 0xDD, 0x0E, 0x28, 0xF1, 0xB0}, - /* Col 7 */ {0x5F, 0x30, 0x3B, 0x56, 0x96, 0x45, 0xF4, 0xA1}, - /* Col 8 */ {0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8} - }, -}; - -static void __attribute__((unused)) read_code(uint8_t *buf, uint8_t row, uint8_t col, uint8_t len) -{ - for(uint8_t i=0;i> 8; - packet[1] = crc & 0xff; - packet[2] = 0xff ^ cyrfmfg_id[2]; - packet[3] = (0xff ^ cyrfmfg_id[3]) + RX_num; - packet[4] = packet[0]; - packet[5] = packet[1]; - packet[6] = packet[2]; - packet[7] = packet[3]; - for(i = 0; i < 8; i++) - sum += packet[i]; - packet[8] = sum >> 8; - packet[9] = sum & 0xff; - packet[10] = 0x01; //??? - packet[11] = option>3?option:option+4; - if(sub_protocol==DSMX) //DSMX type - packet[12] = 0xb2; // Telemetry off: packet[12] = num_channels < 8 && Model.proto_opts[PROTOOPTS_TELEMETRY] == TELEM_OFF ? 0xa2 : 0xb2; - else - packet[12] = option<8?0x01:0x02; - packet[13] = 0x00; //??? - for(i = 8; i < 14; i++) - sum += packet[i]; - packet[14] = sum >> 8; - packet[15] = sum & 0xff; -} - -static uint8_t __attribute__((unused)) PROTOCOL_SticksMoved(uint8_t init) -{ -#define STICK_MOVEMENT 15*(PPM_MAX-PPM_MIN)/100 // defines when the bind dialog should be interrupted (stick movement STICK_MOVEMENT %) - static uint16_t ele_start, ail_start; - uint16_t ele = Servo_data[ELEVATOR];//CHAN_ReadInput(MIXER_MapChannel(INP_ELEVATOR)); - uint16_t ail = Servo_data[AILERON];//CHAN_ReadInput(MIXER_MapChannel(INP_AILERON)); - if(init) { - ele_start = ele; - ail_start = ail; - return 0; - } - uint16_t ele_diff = ele_start - ele;//abs(ele_start - ele); - uint16_t ail_diff = ail_start - ail;//abs(ail_start - ail); - return ((ele_diff + ail_diff) > STICK_MOVEMENT);// -} - -static void __attribute__((unused)) build_data_packet(uint8_t upper)// -{ - uint8_t i; - uint8_t bits; - - uint8_t ch_map[] = {3, 2, 1, 5, 0, 4, 6, 7, 8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; //9 Channels - DM9 TX - switch(option>3?option:option+4) // Create channel map based on number of channels - { - case 12: - ch_map[11]=11; // 12 channels - case 11: - ch_map[10]=10; // 11 channels - case 10: - ch_map[9]=9; // 10 channels - break; - case 8: - memcpy(ch_map,"\x01\x05\x02\x03\x06\xFF\xFF\x04\x00\x07",10); // 8 channels - DX8 TX - break; - case 7: - memcpy(ch_map,"\x01\x05\x02\x04\x03\x06\x00",7); // 7 channels - DX6i TX - break; - case 6: - memcpy(ch_map,"\x01\x05\x02\x03\x00\x04\xFF",7); // 6 channels - HP6DSM TX - break; - case 4: - case 5: - memcpy(ch_map,"\x00\x01\x02\x03\xFF\xFF\xFF",7); // 4 channels - Guess - if(option&0x01) - ch_map[4]=4; // 5 channels - Guess - break; - } - // - if( binding && PROTOCOL_SticksMoved(0) ) - binding = 0; - if (sub_protocol==DSMX) - { - packet[0] = cyrfmfg_id[2]; - packet[1] = cyrfmfg_id[3] + RX_num; - bits=11; - } - else - { - packet[0] = (0xff ^ cyrfmfg_id[2]); - packet[1] = (0xff ^ cyrfmfg_id[3]) + RX_num; - bits=10; - } - // - uint16_t max = 1 << bits;//max=2048 for DSMX & 1024 for DSM2 less than 8 ch and 2048 otherwise - //uint16_t pct_100 = (uint32_t)max * 100 / 150;//682 1024*100/150 - // - for (i = 0; i < 7; i++) - { - uint8_t idx = ch_map[upper * 7 + i];//1,5,2,3,0,4 - uint16_t value; - if (idx == 0xff) - value = 0xffff; - else - { - if (binding) - { // Failsafe position during binding - value=max/2; //all channels to middle - if(idx==0) - value=1; //except throttle - } - else - { - switch(idx) - { - case 0: - value=Servo_data[THROTTLE];//85.75-938.25=125%//171-853=100% - break; - case 1: - value=Servo_data[AILERON]; - break; - case 2: - value=Servo_data[ELEVATOR]; - break; - case 3: - value=Servo_data[RUDDER]; - break; - case 4: - value=Servo_data[AUX1]; - break; - case 5: - value=Servo_data[AUX2]; - break; - case 6: - value=Servo_data[AUX3]; - break; - case 7: - value=Servo_data[AUX4]; - break; - } - value=map(value,PPM_MIN,PPM_MAX,0,max-1); - } - value |= (upper && i == 0 ? 0x8000 : 0) | (idx << bits); - } - packet[i*2+2] = (value >> 8) & 0xff; - packet[i*2+3] = (value >> 0) & 0xff; - } -} - -static uint8_t __attribute__((unused)) get_pn_row(uint8_t channel) -{ - return (sub_protocol == DSMX ? (channel - 2) % 5 : channel % 5); -} - -const uint8_t init_vals[][2] = { - {CYRF_02_TX_CTRL, 0x00}, - {CYRF_05_RX_CTRL, 0x00}, - {CYRF_28_CLK_EN, 0x02}, - {CYRF_32_AUTO_CAL_TIME, 0x3c}, - {CYRF_35_AUTOCAL_OFFSET, 0x14}, - {CYRF_06_RX_CFG, 0x4A}, - {CYRF_1B_TX_OFFSET_LSB, 0x55}, - {CYRF_1C_TX_OFFSET_MSB, 0x05}, - {CYRF_0F_XACT_CFG, 0x24}, // Force Idle - {CYRF_03_TX_CFG, 0x38 | CYRF_BIND_POWER}, //Set 64chip, SDR mode - {CYRF_12_DATA64_THOLD, 0x0a}, - {CYRF_0F_XACT_CFG, 0x04}, // Idle - {CYRF_39_ANALOG_CTRL, 0x01}, - {CYRF_0F_XACT_CFG, 0x24}, //Force IDLE - {CYRF_29_RX_ABORT, 0x00}, //Clear RX abort - {CYRF_12_DATA64_THOLD, 0x0a}, //set pn correlation threshold - {CYRF_10_FRAMING_CFG, 0x4a}, //set sop len and threshold - {CYRF_29_RX_ABORT, 0x0f}, //Clear RX abort? - {CYRF_03_TX_CFG, 0x38 | CYRF_BIND_POWER}, //Set 64chip, SDR mode - {CYRF_10_FRAMING_CFG, 0x4a}, //set sop len and threshold - {CYRF_1F_TX_OVERRIDE, 0x04}, //disable tx CRC - {CYRF_1E_RX_OVERRIDE, 0x14}, //disable rx crc - {CYRF_14_EOP_CTRL, 0x02}, //set EOP sync == 2 - {CYRF_01_TX_LENGTH, 0x10}, //16byte packet -}; - -static void __attribute__((unused)) cyrf_config() -{ - for(uint8_t i = 0; i < sizeof(init_vals) / 2; i++) - CYRF_WriteRegister(init_vals[i][0], init_vals[i][1]); - CYRF_WritePreamble(0x333304); - CYRF_ConfigRFChannel(0x61); -} - -static void __attribute__((unused)) initialize_bind_state() -{ - uint8_t code[32]; - - CYRF_ConfigRFChannel(BIND_CHANNEL); //This seems to be random? - uint8_t pn_row = get_pn_row(BIND_CHANNEL); - //printf("Ch: %d Row: %d SOP: %d Data: %d\n", BIND_CHANNEL, pn_row, sop_col, data_col); - CYRF_ConfigCRCSeed(crc); - - read_code(code,pn_row,sop_col,8); - CYRF_ConfigSOPCode(code); - read_code(code,pn_row,data_col,16); - read_code(code+16,0,8,8); - memcpy(code + 24, "\xc6\x94\x22\xfe\x48\xe6\x57\x4e", 8); - CYRF_ConfigDataCode(code, 32); - - build_bind_packet(); -} - -const uint8_t data_vals[][2] = { - {CYRF_05_RX_CTRL, 0x83}, //Initialize for reading RSSI - {CYRF_29_RX_ABORT, 0x20}, - {CYRF_0F_XACT_CFG, 0x24}, - {CYRF_29_RX_ABORT, 0x00}, - {CYRF_03_TX_CFG, 0x08 | CYRF_HIGH_POWER}, - {CYRF_10_FRAMING_CFG, 0xea}, - {CYRF_1F_TX_OVERRIDE, 0x00}, - {CYRF_1E_RX_OVERRIDE, 0x00}, - {CYRF_03_TX_CFG, 0x28 | CYRF_HIGH_POWER}, - {CYRF_12_DATA64_THOLD, 0x3f}, - {CYRF_10_FRAMING_CFG, 0xff}, - {CYRF_0F_XACT_CFG, 0x24}, //Switch from reading RSSI to Writing - {CYRF_29_RX_ABORT, 0x00}, - {CYRF_12_DATA64_THOLD, 0x0a}, - {CYRF_10_FRAMING_CFG, 0xea}, -}; - -static void __attribute__((unused)) cyrf_configdata() -{ - for(uint8_t i = 0; i < sizeof(data_vals) / 2; i++) - CYRF_WriteRegister(data_vals[i][0], data_vals[i][1]); -} - -static void __attribute__((unused)) set_sop_data_crc() -{ - uint8_t code[16]; - uint8_t pn_row = get_pn_row(hopping_frequency[chidx]); - //printf("Ch: %d Row: %d SOP: %d Data: %d\n", ch[chidx], pn_row, sop_col, data_col); - CYRF_ConfigRFChannel(hopping_frequency[chidx]); - CYRF_ConfigCRCSeed(crcidx ? ~crc : crc); - - read_code(code,pn_row,sop_col,8); - CYRF_ConfigSOPCode(code); - read_code(code,pn_row,data_col,16); - CYRF_ConfigDataCode(code, 16); - - if(sub_protocol == DSMX) - chidx = (chidx + 1) % 23; - else - chidx = (chidx + 1) % 2; - crcidx = !crcidx; -} - -static void __attribute__((unused)) calc_dsmx_channel() -{ - uint8_t idx = 0; - uint32_t id = ~(((uint32_t)cyrfmfg_id[0] << 24) | ((uint32_t)cyrfmfg_id[1] << 16) | ((uint32_t)cyrfmfg_id[2] << 8) | (cyrfmfg_id[3] << 0)); - uint32_t id_tmp = id; - while(idx < 23) - { - uint8_t i; - uint8_t count_3_27 = 0, count_28_51 = 0, count_52_76 = 0; - id_tmp = id_tmp * 0x0019660D + 0x3C6EF35F; // Randomization - uint8_t next_ch = ((id_tmp >> 8) % 0x49) + 3; // Use least-significant byte and must be larger than 3 - if (((next_ch ^ id) & 0x01 )== 0) - continue; - for (i = 0; i < idx; i++) - { - if(hopping_frequency[i] == next_ch) - break; - if(hopping_frequency[i] <= 27) - count_3_27++; - else - if (hopping_frequency[i] <= 51) - count_28_51++; - else - count_52_76++; - } - if (i != idx) - continue; - if ((next_ch < 28 && count_3_27 < 8) - ||(next_ch >= 28 && next_ch < 52 && count_28_51 < 7) - ||(next_ch >= 52 && count_52_76 < 8)) - hopping_frequency[idx++] = next_ch; - } -} - -uint16_t ReadDsm2() -{ -#define CH1_CH2_DELAY 4010 // Time between write of channel 1 and channel 2 -#define WRITE_DELAY 1650 // 1550 original, Time after write to verify write complete -#define READ_DELAY 400 // Time before write to check read state, and switch channels - uint8_t i = 0; - - switch(cyrf_state) - { - default: - //Binding - cyrf_state++; - if(cyrf_state & 1) - { - //Send packet on even states - //Note state has already incremented, - // so this is actually 'even' state - CYRF_WriteDataPacket(packet); - return 8500; - } - else - { - //Check status on odd states - CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS); - return 1500; - } - case DSM2_CHANSEL: - BIND_DONE; - //Select channels and configure for writing data - //CYRF_FindBestChannels(ch, 2, 10, 1, 79); - cyrf_configdata(); - CYRF_SetTxRxMode(TX_EN); - chidx = 0; - crcidx = 0; - cyrf_state = DSM2_CH1_WRITE_A; // in fact cyrf_state++ - set_sop_data_crc(); - return 10000; - case DSM2_CH1_WRITE_A: - case DSM2_CH1_WRITE_B: - build_data_packet(cyrf_state == DSM2_CH1_WRITE_B);//compare state and DSM2_CH1_WRITE_B return 0 or 1 - case DSM2_CH2_WRITE_A: - case DSM2_CH2_WRITE_B: - CYRF_WriteDataPacket(packet); - cyrf_state++; // change from WRITE to CHECK mode - return WRITE_DELAY; - case DSM2_CH1_CHECK_A: - case DSM2_CH1_CHECK_B: - while (! (CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x02)) - if(++i > NUM_WAIT_LOOPS) - break; - set_sop_data_crc(); - cyrf_state++; // change from CH1_CHECK to CH2_WRITE - return CH1_CH2_DELAY - WRITE_DELAY; - case DSM2_CH2_CHECK_A: - case DSM2_CH2_CHECK_B: - while (! (CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x02)) - if(++i > NUM_WAIT_LOOPS) - break; - if (cyrf_state == DSM2_CH2_CHECK_A) - CYRF_SetPower(0x28); //Keep transmit power in sync - // No telemetry... - set_sop_data_crc(); - if (cyrf_state == DSM2_CH2_CHECK_A) - { - if(option < 8) - { - cyrf_state = DSM2_CH1_WRITE_A; // change from CH2_CHECK_A to CH1_WRITE_A (ie no upper) - if(option>3) - return 11000 - CH1_CH2_DELAY - WRITE_DELAY ; // force 11ms if option>3 ie 4,5,6,7 channels @11ms - else - return 22000 - CH1_CH2_DELAY - WRITE_DELAY ; // normal 22ms mode if option<=3 ie 4,5,6,7 channels @22ms - } - else - cyrf_state = DSM2_CH1_WRITE_B; // change from CH2_CHECK_A to CH1_WRITE_A (to transmit upper) - } - else - cyrf_state = DSM2_CH1_WRITE_A; // change from CH2_CHECK_B to CH1_WRITE_A (upper already transmitted so transmit lower) - return 11000 - CH1_CH2_DELAY - WRITE_DELAY; - } - return 0; -} - -uint16_t initDsm2() -{ - CYRF_Reset(); - CYRF_GetMfgData(cyrfmfg_id);// - - cyrf_config(); - - if (sub_protocol ==DSMX) - calc_dsmx_channel(); - else - { -#if RANDOM_CHANNELS == 1 - uint8_t tmpch[10]; - CYRF_FindBestChannels(tmpch, 10, 5, 3, 75); - // - randomSeed((uint32_t)analogRead(A6)<<10|analogRead(A7));//seed - uint8_t idx = random(0xfefefefe) % 10; - hopping_frequency[0] = tmpch[idx]; - while(1) - { - idx = random(0xfefefefe) % 10; - if (tmpch[idx] != hopping_frequency[0]) - break; - } - hopping_frequency[1] = tmpch[idx]; -#else - hopping_frequency[0] = (cyrfmfg_id[0] + cyrfmfg_id[2] + cyrfmfg_id[4]) % 39 + 1; - hopping_frequency[1] = (cyrfmfg_id[1] + cyrfmfg_id[3] + cyrfmfg_id[5]) % 40 + 40; -#endif - } - - ///} - crc = ~((cyrfmfg_id[0] << 8) + cyrfmfg_id[1]); //The crc for channel 'a' is NOT(mfgid[1] << 8 + mfgid[0]) - crcidx = 0;//The crc for channel 'b' is (mfgid[1] << 8 + mfgid[0]) - // - sop_col = (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + 2) & 0x07;//Ok - data_col = 7 - sop_col;//ok - - CYRF_SetTxRxMode(TX_EN); - // - if(IS_AUTOBIND_FLAG_on) - { - cyrf_state = DSM2_BIND; - PROTOCOL_SticksMoved(1); //Initialize Stick position - initialize_bind_state(); - binding = 1; - } - else - { - cyrf_state = DSM2_CHANSEL;// - binding = 0; - } - return 10000; -} - -#endif diff --git a/Multiprotocol/Devo_cyrf6936.ino b/Multiprotocol/Devo_cyrf6936.ino index 91d752e..a677de9 100644 --- a/Multiprotocol/Devo_cyrf6936.ino +++ b/Multiprotocol/Devo_cyrf6936.ino @@ -43,31 +43,7 @@ enum { DEVO_BOUND_10, }; -<<<<<<< HEAD -const uint8_t sopcodes[][8] = { - /* Note these are in order transmitted (LSB 1st) */ - /* 0 */ {0x3C,0x37,0xCC,0x91,0xE2,0xF8,0xCC,0x91}, //0x91CCF8E291CC373C - /* 1 */ {0x9B,0xC5,0xA1,0x0F,0xAD,0x39,0xA2,0x0F}, //0x0FA239AD0FA1C59B - /* 2 */ {0xEF,0x64,0xB0,0x2A,0xD2,0x8F,0xB1,0x2A}, //0x2AB18FD22AB064EF - /* 3 */ {0x66,0xCD,0x7C,0x50,0xDD,0x26,0x7C,0x50}, //0x507C26DD507CCD66 - /* 4 */ {0x5C,0xE1,0xF6,0x44,0xAD,0x16,0xF6,0x44}, //0x44F616AD44F6E15C - /* 5 */ {0x5A,0xCC,0xAE,0x46,0xB6,0x31,0xAE,0x46}, //0x46AE31B646AECC5A - /* 6 */ {0xA1,0x78,0xDC,0x3C,0x9E,0x82,0xDC,0x3C}, //0x3CDC829E3CDC78A1 - /* 7 */ {0xB9,0x8E,0x19,0x74,0x6F,0x65,0x18,0x74}, //0x7418656F74198EB9 - /* 8 */ {0xDF,0xB1,0xC0,0x49,0x62,0xDF,0xC1,0x49}, //0x49C1DF6249C0B1DF - /* 9 */ {0x97,0xE5,0x14,0x72,0x7F,0x1A,0x14,0x72}, //0x72141A7F7214E597 -}; - -uint8_t txState; -uint8_t pkt_num; -uint8_t ch_idx; -uint8_t use_fixed_id; -uint8_t failsafe_pkt; - -static void __attribute__((unused)) scramble_pkt() -======= static void __attribute__((unused)) DEVO_scramble_pkt() ->>>>>>> refs/remotes/pascallanger/master { #ifdef NO_SCRAMBLE return; @@ -77,11 +53,7 @@ static void __attribute__((unused)) DEVO_scramble_pkt() #endif } -<<<<<<< HEAD -static void __attribute__((unused)) add_pkt_suffix() -======= static void __attribute__((unused)) DEVO_add_pkt_suffix() ->>>>>>> refs/remotes/pascallanger/master { uint8_t bind_state; #ifdef ENABLE_PPM @@ -119,11 +91,7 @@ static void __attribute__((unused)) DEVO_add_pkt_suffix() packet[15] = (MProtocol_id >> 16) & 0xff; } -<<<<<<< HEAD -static void __attribute__((unused)) build_beacon_pkt(uint8_t upper) -======= static void __attribute__((unused)) DEVO_build_beacon_pkt(uint8_t upper) ->>>>>>> refs/remotes/pascallanger/master { packet[0] = (DEVO_NUM_CHANNELS << 4) | 0x07; uint8_t max = 8; @@ -138,11 +106,7 @@ static void __attribute__((unused)) DEVO_build_beacon_pkt(uint8_t upper) DEVO_add_pkt_suffix(); } -<<<<<<< HEAD -static void __attribute__((unused)) build_bind_pkt() -======= static void __attribute__((unused)) DEVO_build_bind_pkt() ->>>>>>> refs/remotes/pascallanger/master { packet[0] = (DEVO_NUM_CHANNELS << 4) | 0x0a; packet[1] = bind_counter & 0xff; @@ -162,11 +126,7 @@ static void __attribute__((unused)) DEVO_build_bind_pkt() packet[15] ^= cyrfmfg_id[2]; } -<<<<<<< HEAD -static void __attribute__((unused)) build_data_pkt() -======= static void __attribute__((unused)) DEVO_build_data_pkt() ->>>>>>> refs/remotes/pascallanger/master { static uint8_t ch_idx=0; @@ -190,11 +150,7 @@ static void __attribute__((unused)) DEVO_build_data_pkt() DEVO_add_pkt_suffix(); } -<<<<<<< HEAD -static void __attribute__((unused)) cyrf_set_bound_sop_code() -======= static void __attribute__((unused)) DEVO_cyrf_set_bound_sop_code() ->>>>>>> refs/remotes/pascallanger/master { /* crc == 0 isn't allowed, so use 1 if the math results in 0 */ uint8_t crc = (cyrfmfg_id[0] + (cyrfmfg_id[1] >> 6) + cyrfmfg_id[2]); @@ -207,9 +163,6 @@ static void __attribute__((unused)) DEVO_cyrf_set_bound_sop_code() CYRF_SetPower(0x08); } -<<<<<<< HEAD -static void __attribute__((unused)) cyrf_init() -======= const uint8_t PROGMEM DEVO_init_vals[][2] = { { CYRF_1D_MODE_OVERRIDE, 0x38 }, { CYRF_03_TX_CFG, 0x08 }, @@ -233,18 +186,13 @@ const uint8_t PROGMEM DEVO_init_vals[][2] = { }; static void __attribute__((unused)) DEVO_cyrf_init() ->>>>>>> refs/remotes/pascallanger/master { /* Initialise CYRF chip */ for(uint8_t i = 0; i < sizeof(DEVO_init_vals) / 2; i++) CYRF_WriteRegister(pgm_read_byte( &DEVO_init_vals[i][0]), pgm_read_byte( &DEVO_init_vals[i][1]) ); } -<<<<<<< HEAD -static void __attribute__((unused)) set_radio_channels() -======= static void __attribute__((unused)) DEVO_set_radio_channels() ->>>>>>> refs/remotes/pascallanger/master { CYRF_FindBestChannels(hopping_frequency, 3, 4, 4, 80); hopping_frequency[3] = hopping_frequency[0]; @@ -337,35 +285,6 @@ uint16_t devo_callback() return 1200; } -<<<<<<< HEAD -/*static void __attribute__((unused)) devo_bind() -{ - fixed_id = Model_fixed_id; - bind_counter = DEVO_BIND_COUNT; - use_fixed_id = 1; - //PROTOCOL_SetBindState(0x1388 * 2400 / 1000); //msecs 12000ms -} - - -static void __attribute__((unused)) generate_fixed_id_bind(){ -if(BIND_0){ -//randomSeed((uint32_t)analogRead(A6)<<10|analogRead(A7));//seed -uint8_t txid[4]; -//Model_fixed_id = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16); -Model_fixed_id=0x332211; -txid[0]= (id &0xFF); -txid[1] = ((id >> 8) & 0xFF); -txid[2] = ((id >> 16) & 0xFF); -//txid[3] = ((id >> 24) & 0xFF); -eeprom_write_block((const void*)txid,(void*)40,3); -devo_bind(); -} -} -*/ - - -======= ->>>>>>> refs/remotes/pascallanger/master uint16_t DevoInit() { DEVO_cyrf_init(); diff --git a/Multiprotocol/FY326_nrf24l01.ino b/Multiprotocol/FY326_nrf24l01.ino index 670103f..fdb441d 100644 --- a/Multiprotocol/FY326_nrf24l01.ino +++ b/Multiprotocol/FY326_nrf24l01.ino @@ -15,26 +15,17 @@ // Last sync with hexfet new_protocols/fy326_nrf24l01.c dated 2015-07-29 #if defined(FY326_NRF24L01_INO) -<<<<<<< HEAD -======= - ->>>>>>> refs/remotes/pascallanger/master #include "iface_nrf24l01.h" #define FY326_INITIAL_WAIT 500 #define FY326_PACKET_PERIOD 1500 #define FY326_PACKET_CHKTIME 300 #define FY326_PACKET_SIZE 15 -<<<<<<< HEAD -#define FY326_BIND_COUNT 16 -======= #define FY326_BIND_COUNT 16 ->>>>>>> refs/remotes/pascallanger/master #define FY326_RF_BIND_CHANNEL 0x17 #define FY326_NUM_RF_CHANNELS 5 enum { -<<<<<<< HEAD FY326_INIT1 = 0, FY326_BIND1, FY326_BIND2, @@ -42,11 +33,6 @@ enum { FY319_INIT1, FY319_BIND1, FY319_BIND2, -======= - FY326_BIND1=0, - FY326_BIND2, - FY326_DATA ->>>>>>> refs/remotes/pascallanger/master }; #define rxid channel @@ -56,11 +42,7 @@ static void __attribute__((unused)) FY326_send_packet(uint8_t bind) { packet[0] = rx_tx_addr[3]; if(bind) -<<<<<<< HEAD packet[1] = 0x55; -======= - packet[1] = 0x55; ->>>>>>> refs/remotes/pascallanger/master else packet[1] = GET_FLAG(Servo_AUX3, 0x80) // Headless | GET_FLAG(Servo_AUX2, 0x40) // RTH @@ -71,11 +53,10 @@ static void __attribute__((unused)) FY326_send_packet(uint8_t bind) packet[3] = convert_channel_8b_scale(ELEVATOR, 0, 200); // elevator packet[4] = 200 - convert_channel_8b_scale(RUDDER, 0, 200); // rudder packet[5] = convert_channel_8b_scale(THROTTLE, 0, 200); // throttle -<<<<<<< HEAD if(sub_protocol == FY319) { - packet[6] = 255 - scale_channel(AILERON, 0, 255); - packet[7] = scale_channel(ELEVATOR, 0, 255); - packet[8] = 255 - scale_channel(RUDDER, 0, 255); + packet[6] = 255 - convert_channel_8b_scale(AILERON, 0, 255); + packet[7] = convert_channel_8b_scale(ELEVATOR, 0, 255); + packet[8] = 255 - convert_channel_8b_scale(RUDDER, 0, 255); } else { packet[6] = rx_tx_addr[0]; @@ -87,16 +68,6 @@ static void __attribute__((unused)) FY326_send_packet(uint8_t bind) packet[11] = CHAN_TO_TRIM(packet[4]); // rudder_trim; packet[12] = 0; // throttle_trim; packet[13] = rxid; -======= - packet[6] = rx_tx_addr[0]; - packet[7] = rx_tx_addr[1]; - packet[8] = rx_tx_addr[2]; - packet[9] = CHAN_TO_TRIM(packet[2]); // aileron_trim; - packet[10] = CHAN_TO_TRIM(packet[3]); // elevator_trim; - packet[11] = CHAN_TO_TRIM(packet[4]); // rudder_trim; - packet[12] = 0; // throttle_trim; - packet[13] = rxid; ->>>>>>> refs/remotes/pascallanger/master packet[14] = rx_tx_addr[4]; if (bind) @@ -105,20 +76,12 @@ static void __attribute__((unused)) FY326_send_packet(uint8_t bind) { NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++]); hopping_frequency_no %= FY326_NUM_RF_CHANNELS; -<<<<<<< HEAD } // clear packet status bits and TX FIFO NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); NRF24L01_FlushTx(); -======= - } - - // clear packet status bits and TX FIFO - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - NRF24L01_FlushTx(); ->>>>>>> refs/remotes/pascallanger/master NRF24L01_WritePayload(packet, FY326_PACKET_SIZE); @@ -127,18 +90,12 @@ static void __attribute__((unused)) FY326_send_packet(uint8_t bind) static void __attribute__((unused)) FY326_init() { -<<<<<<< HEAD NRF24L01_Initialize(); NRF24L01_SetTxRxMode(TX_EN); if(sub_protocol == FY319) NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // Five-byte rx/tx address else NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x01); // Three-byte rx/tx address -======= - NRF24L01_Initialize(); - NRF24L01_SetTxRxMode(TX_EN); - NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x01); // Three-byte rx/tx address ->>>>>>> refs/remotes/pascallanger/master NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)"\x15\x59\x23\xc6\x29", 5); NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t *)"\x15\x59\x23\xc6\x29", 5); NRF24L01_FlushTx(); @@ -150,20 +107,14 @@ static void __attribute__((unused)) FY326_init() NRF24L01_WriteReg(NRF24L01_05_RF_CH, FY326_RF_BIND_CHANNEL); NRF24L01_SetBitrate(NRF24L01_BR_250K); NRF24L01_SetPower(); -<<<<<<< HEAD NRF24L01_Activate(0x73); -======= - - NRF24L01_Activate(0x73); ->>>>>>> refs/remotes/pascallanger/master NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3f); NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07); NRF24L01_Activate(0x73); } -<<<<<<< HEAD -uint16_t fy326_callback() +uint16_t FY326_callback() { uint8_t i; switch (phase) { @@ -171,19 +122,19 @@ uint16_t fy326_callback() NRF24L01_SetTxRxMode(TXRX_OFF); NRF24L01_FlushRx(); NRF24L01_SetTxRxMode(RX_EN); - NRF24L01_WriteReg(NRF24L01_05_RF_CH, RF_BIND_CHANNEL); + NRF24L01_WriteReg(NRF24L01_05_RF_CH, FY326_RF_BIND_CHANNEL); phase = FY319_BIND1; BIND_IN_PROGRESS; - return FY326_CHKTIME; + return FY326_PACKET_CHKTIME; break; case FY319_BIND1: - if(NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR)) { - NRF24L01_ReadPayload(packet, FY326_SIZE); + if(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) { + NRF24L01_ReadPayload(packet, FY326_PACKET_SIZE); rxid = packet[13]; - packet[0] = txid[3]; + packet[0] = rx_tx_addr[3]; packet[1] = 0x80; - packet[14]= txid[4]; + packet[14]= rx_tx_addr[4]; bind_counter = FY326_BIND_COUNT; NRF24L01_SetTxRxMode(TXRX_OFF); NRF24L01_SetTxRxMode(TX_EN); @@ -191,16 +142,16 @@ uint16_t fy326_callback() NRF24L01_FlushTx(); bind_counter = 255; for(i=2; i<6; i++) - packet[i] = rf_chans[0]; + packet[i] = hopping_frequency[0]; phase = FY319_BIND2; } - return FY326_CHKTIME; + return FY326_PACKET_CHKTIME; break; case FY319_BIND2: NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); NRF24L01_FlushTx(); - NRF24L01_WritePayload(packet, FY326_SIZE); + NRF24L01_WritePayload(packet, FY326_PACKET_SIZE); if(bind_counter == 250) packet[1] = 0x40; if(--bind_counter == 0) { @@ -212,12 +163,12 @@ uint16_t fy326_callback() case FY326_INIT1: bind_counter = FY326_BIND_COUNT; phase = FY326_BIND2; - send_packet(1); - return FY326_CHKTIME; + FY326_send_packet(1); + return FY326_PACKET_CHKTIME; break; case FY326_BIND1: - if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR)) + if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) { // RX fifo data ready NRF24L01_ReadPayload(packet, FY326_PACKET_SIZE); rxid = packet[13]; @@ -240,7 +191,7 @@ uint16_t fy326_callback() break; case FY326_BIND2: - if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_TX_DS)) + if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS)) { // TX data sent -> switch to RX mode NRF24L01_SetTxRxMode(TXRX_OFF); NRF24L01_FlushRx(); @@ -255,55 +206,11 @@ uint16_t fy326_callback() FY326_send_packet(0); break; } -======= -uint16_t FY326_callback() -{ - switch (phase) - { - case FY326_BIND1: - if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) - { // RX fifo data ready - NRF24L01_ReadPayload(packet, FY326_PACKET_SIZE); - rxid = packet[13]; - rx_tx_addr[0] = 0xAA; - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_SetTxRxMode(TX_EN); - BIND_DONE; - phase = FY326_DATA; - } - else - if (bind_counter-- == 0) - { - bind_counter = FY326_BIND_COUNT; - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_SetTxRxMode(TX_EN); - FY326_send_packet(1); - phase = FY326_BIND2; - return FY326_PACKET_CHKTIME; - } - break; - case FY326_BIND2: - if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS)) - { // TX data sent -> switch to RX mode - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_FlushRx(); - NRF24L01_SetTxRxMode(RX_EN); - phase = FY326_BIND1; - } - else - return FY326_PACKET_CHKTIME; - break; - case FY326_DATA: - FY326_send_packet(0); - break; - } ->>>>>>> refs/remotes/pascallanger/master return FY326_PACKET_PERIOD; } static void __attribute__((unused)) FY326_initialize_txid() { -<<<<<<< HEAD if(sub_protocol == FY319) { hopping_frequency[0] = (rx_tx_addr[0]&0x0f) & ~0x80; hopping_frequency[1] = (rx_tx_addr[0] >> 4) & ~0x80; @@ -317,34 +224,19 @@ static void __attribute__((unused)) FY326_initialize_txid() hopping_frequency[3] = 0x30 + (rx_tx_addr[1] >> 4); hopping_frequency[4] = 0x40 + (rx_tx_addr[2] >> 4); } -======= - hopping_frequency[0] = (rx_tx_addr[0]&0x0f); - hopping_frequency[1] = 0x10 + (rx_tx_addr[0] >> 4); - hopping_frequency[2] = 0x20 + (rx_tx_addr[1]&0x0f); - hopping_frequency[3] = 0x30 + (rx_tx_addr[1] >> 4); - hopping_frequency[4] = 0x40 + (rx_tx_addr[2] >> 4); ->>>>>>> refs/remotes/pascallanger/master } uint16_t initFY326(void) { BIND_IN_PROGRESS; // autobind protocol -<<<<<<< HEAD - rxid = 0xaa; + rxid = 0xAA; bind_counter = 0; FY326_initialize_txid(); - fy326_init(); + FY326_init(); if(sub_protocol == FY319) phase = FY319_INIT1; else phase = FY326_INIT1; -======= - rxid = 0xAA; - bind_counter = 0; - FY326_initialize_txid(); - FY326_init(); - phase=FY326_BIND1; ->>>>>>> refs/remotes/pascallanger/master return FY326_INITIAL_WAIT; } diff --git a/Multiprotocol/FlySky_a7105.ino b/Multiprotocol/FlySky_a7105.ino index 1165aea..43ccffd 100644 --- a/Multiprotocol/FlySky_a7105.ino +++ b/Multiprotocol/FlySky_a7105.ino @@ -21,34 +21,6 @@ //FlySky constants & variables #define FLYSKY_BIND_COUNT 2500 -<<<<<<< HEAD -const uint8_t PROGMEM tx_channels[] = { - 0x0a, 0x5a, 0x14, 0x64, 0x1e, 0x6e, 0x28, 0x78, 0x32, 0x82, 0x3c, 0x8c, 0x46, 0x96, 0x50, 0xa0, - 0xa0, 0x50, 0x96, 0x46, 0x8c, 0x3c, 0x82, 0x32, 0x78, 0x28, 0x6e, 0x1e, 0x64, 0x14, 0x5a, 0x0a, - 0x0a, 0x5a, 0x50, 0xa0, 0x14, 0x64, 0x46, 0x96, 0x1e, 0x6e, 0x3c, 0x8c, 0x28, 0x78, 0x32, 0x82, - 0x82, 0x32, 0x78, 0x28, 0x8c, 0x3c, 0x6e, 0x1e, 0x96, 0x46, 0x64, 0x14, 0xa0, 0x50, 0x5a, 0x0a, - 0x28, 0x78, 0x0a, 0x5a, 0x50, 0xa0, 0x14, 0x64, 0x1e, 0x6e, 0x3c, 0x8c, 0x32, 0x82, 0x46, 0x96, - 0x96, 0x46, 0x82, 0x32, 0x8c, 0x3c, 0x6e, 0x1e, 0x64, 0x14, 0xa0, 0x50, 0x5a, 0x0a, 0x78, 0x28, - 0x50, 0xa0, 0x28, 0x78, 0x0a, 0x5a, 0x1e, 0x6e, 0x3c, 0x8c, 0x32, 0x82, 0x46, 0x96, 0x14, 0x64, - 0x64, 0x14, 0x96, 0x46, 0x82, 0x32, 0x8c, 0x3c, 0x6e, 0x1e, 0x5a, 0x0a, 0x78, 0x28, 0xa0, 0x50, - 0x50, 0xa0, 0x46, 0x96, 0x3c, 0x8c, 0x28, 0x78, 0x0a, 0x5a, 0x32, 0x82, 0x1e, 0x6e, 0x14, 0x64, - 0x64, 0x14, 0x6e, 0x1e, 0x82, 0x32, 0x5a, 0x0a, 0x78, 0x28, 0x8c, 0x3c, 0x96, 0x46, 0xa0, 0x50, - 0x46, 0x96, 0x3c, 0x8c, 0x50, 0xa0, 0x28, 0x78, 0x0a, 0x5a, 0x1e, 0x6e, 0x32, 0x82, 0x14, 0x64, - 0x64, 0x14, 0x82, 0x32, 0x6e, 0x1e, 0x5a, 0x0a, 0x78, 0x28, 0xa0, 0x50, 0x8c, 0x3c, 0x96, 0x46, - 0x46, 0x96, 0x0a, 0x5a, 0x3c, 0x8c, 0x14, 0x64, 0x50, 0xa0, 0x28, 0x78, 0x1e, 0x6e, 0x32, 0x82, - 0x82, 0x32, 0x6e, 0x1e, 0x78, 0x28, 0xa0, 0x50, 0x64, 0x14, 0x8c, 0x3c, 0x5a, 0x0a, 0x96, 0x46, - 0x46, 0x96, 0x0a, 0x5a, 0x50, 0xa0, 0x3c, 0x8c, 0x28, 0x78, 0x1e, 0x6e, 0x32, 0x82, 0x14, 0x64, - 0x64, 0x14, 0x82, 0x32, 0x6e, 0x1e, 0x78, 0x28, 0x8c, 0x3c, 0xa0, 0x50, 0x5a, 0x0a, 0x96, 0x46 -}; - -enum { - // flags going to byte 10 - FLAG_V9X9_VIDEO = 0x40, - FLAG_V9X9_CAMERA= 0x80, - // flags going to byte 12 - FLAG_V9X9_FLIP = 0x10, - FLAG_V9X9_LED = 0x20, -======= enum { // flags going to byte 10 FLAG_V9X9_VIDEO = 0x40, @@ -56,27 +28,26 @@ enum { // flags going to byte 12 FLAG_V9X9_FLIP = 0x10, FLAG_V9X9_LED = 0x20, ->>>>>>> refs/remotes/pascallanger/master }; enum { - // flags going to byte 13 - FLAG_V6X6_HLESS1= 0x80, - // flags going to byte 14 - FLAG_V6X6_VIDEO = 0x01, - FLAG_V6X6_YCAL = 0x02, - FLAG_V6X6_XCAL = 0x04, - FLAG_V6X6_RTH = 0x08, - FLAG_V6X6_CAMERA= 0x10, - FLAG_V6X6_HLESS2= 0x20, - FLAG_V6X6_LED = 0x40, - FLAG_V6X6_FLIP = 0x80, + // flags going to byte 13 + FLAG_V6X6_HLESS1= 0x80, + // flags going to byte 14 + FLAG_V6X6_VIDEO = 0x01, + FLAG_V6X6_YCAL = 0x02, + FLAG_V6X6_XCAL = 0x04, + FLAG_V6X6_RTH = 0x08, + FLAG_V6X6_CAMERA= 0x10, + FLAG_V6X6_HLESS2= 0x20, + FLAG_V6X6_LED = 0x40, + FLAG_V6X6_FLIP = 0x80, }; enum { - // flags going to byte 14 - FLAG_V912_TOPBTN= 0x40, - FLAG_V912_BTMBTN= 0x80, + // flags going to byte 14 + FLAG_V912_TOPBTN= 0x40, + FLAG_V912_BTMBTN= 0x80, }; const uint8_t PROGMEM V912_X17_SEQ[10] = { 0x14, 0x31, 0x40, 0x49, 0x49, // sometime first byte is 0x15 ? @@ -84,79 +55,6 @@ const uint8_t PROGMEM V912_X17_SEQ[10] = { 0x14, 0x31, 0x40, 0x49, 0x49, // static void __attribute__((unused)) flysky_apply_extension_flags() { -<<<<<<< HEAD - const uint8_t V912_X17_SEQ[10] = { 0x14, 0x31, 0x40, 0x49, 0x49, // sometime first byte is 0x15 ? - 0x49, 0x49, 0x49, 0x49, 0x49, }; - static uint8_t seq_counter; - switch(sub_protocol) - { - case V9X9: - if(Servo_AUX1) - packet[12] |= FLAG_V9X9_FLIP; - if(Servo_AUX2) - packet[12] |= FLAG_V9X9_LED; - if(Servo_AUX3) - packet[10] |= FLAG_V9X9_CAMERA; - if(Servo_AUX4) - packet[10] |= FLAG_V9X9_VIDEO; - break; - - case V6X6: - packet[13] = 0x03; // 3 = 100% rate (0=40%, 1=60%, 2=80%) - packet[14] = 0x00; - if(Servo_AUX1) - packet[14] |= FLAG_V6X6_FLIP; - if(Servo_AUX2) - packet[14] |= FLAG_V6X6_LED; - if(Servo_AUX3) - packet[14] |= FLAG_V6X6_CAMERA; - if(Servo_AUX4) - packet[14] |= FLAG_V6X6_VIDEO; - if(Servo_AUX5) - { - packet[13] |= FLAG_V6X6_HLESS1; - packet[14] |= FLAG_V6X6_HLESS2; - } - if(Servo_AUX6) //use option to manipulate these bytes - packet[14] |= FLAG_V6X6_RTH; - if(Servo_AUX7) - packet[14] |= FLAG_V6X6_XCAL; - if(Servo_AUX8) - packet[14] |= FLAG_V6X6_YCAL; - packet[15] = 0x10; // unknown - packet[16] = 0x10; // unknown - packet[17] = 0xAA; // unknown - packet[18] = 0xAA; // unknown - packet[19] = 0x60; // unknown, changes at irregular interval in stock TX - packet[20] = 0x02; // unknown - break; - - case V912: - seq_counter++; - if( seq_counter > 9) - seq_counter = 0; - packet[12] |= 0x20; // bit 6 is always set ? - packet[13] = 0x00; // unknown - packet[14] = 0x00; - if(Servo_AUX1) - packet[14] = FLAG_V912_BTMBTN; - if(Servo_AUX2) - packet[14] |= FLAG_V912_TOPBTN; - packet[15] = 0x27; // [15] and [16] apparently hold an analog channel with a value lower than 1000 - packet[16] = 0x03; // maybe it's there for a pitch channel for a CP copter ? - packet[17] = V912_X17_SEQ[seq_counter]; // not sure what [17] & [18] are for - if(seq_counter == 0) // V912 Rx does not even read those bytes... [17-20] - packet[18] = 0x02; - else - packet[18] = 0x00; - packet[19] = 0x00; // unknown - packet[20] = 0x00; // unknown - break; - - default: - break; - } -======= static uint8_t seq_counter; switch(sub_protocol) { @@ -226,78 +124,39 @@ static void __attribute__((unused)) flysky_apply_extension_flags() default: break; } ->>>>>>> refs/remotes/pascallanger/master } static void __attribute__((unused)) flysky_build_packet(uint8_t init) { uint8_t i; - //servodata timing range for flysky. - ////-100% =~ 0x03e8//=1000us(min) - //+100% =~ 0x07ca//=1994us(max) - //Center = 0x5d9//=1497us(center) - //channel order AIL;ELE;THR;RUD;AUX1;AUX2;AUX3;AUX4 + //servodata timing range for flysky. + ////-100% =~ 0x03e8//=1000us(min) + //+100% =~ 0x07ca//=1994us(max) + //Center = 0x5d9//=1497us(center) + //channel order AIL;ELE;THR;RUD;AUX1;AUX2;AUX3;AUX4 packet[0] = init ? 0xaa : 0x55; packet[1] = rx_tx_addr[3]; packet[2] = rx_tx_addr[2]; packet[3] = rx_tx_addr[1]; packet[4] = rx_tx_addr[0]; -<<<<<<< HEAD - const uint8_t ch[]={AILERON, ELEVATOR, THROTTLE, RUDDER, AUX1, AUX2, AUX3, AUX4}; - for(i = 0; i < 8; i++) - { - packet[5+2*i]=lowByte(Servo_data[ch[i]]); //low byte of servo timing(1000-2000us) - packet[6+2*i]=highByte(Servo_data[ch[i]]); //high byte of servo timing(1000-2000us) - } -======= for(i = 0; i < 8; i++) { packet[5 + i*2]=Servo_data[CH_AETR[i]]&0xFF; //low byte of servo timing(1000-2000us) packet[6 + i*2]=(Servo_data[CH_AETR[i]]>>8)&0xFF; //high byte of servo timing(1000-2000us) } ->>>>>>> refs/remotes/pascallanger/master flysky_apply_extension_flags(); } uint16_t ReadFlySky() { if (bind_counter) - { + { flysky_build_packet(1); A7105_WriteData(21, 1); bind_counter--; if (! bind_counter) BIND_DONE; } -<<<<<<< HEAD - else - { - flysky_build_packet(0); - A7105_WriteData(21, pgm_read_byte_near(&tx_channels[chanrow*16+chancol])-chanoffset); - chancol = (chancol + 1) % 16; - if (! chancol) //Keep transmit power updated - A7105_SetPower(); - } - return 1460; -} - -uint16_t initFlySky() { - //A7105_Reset(); - A7105_Init(INIT_FLYSKY); //flysky_init(); - - if (rx_tx_addr[3] > 0x90) // limit offset to 9 as higher values don't work with some RX (ie V912) - rx_tx_addr[3] = rx_tx_addr[3] - 0x70; - chanrow=rx_tx_addr[3] % 16; - chancol=0; - chanoffset=rx_tx_addr[3] / 16; - - - if(IS_AUTOBIND_FLAG_on) - bind_counter = FLYSKY_BIND_COUNT; - else - bind_counter = 0; - return 2400; -======= else { flysky_build_packet(0); @@ -352,7 +211,5 @@ uint16_t initFlySky() else bind_counter = 0; return 2400; ->>>>>>> refs/remotes/pascallanger/master } #endif - diff --git a/Multiprotocol/Flysky_afhds2a_a7105.ino b/Multiprotocol/Flysky_afhds2a_a7105.ino new file mode 100644 index 0000000..c83a582 --- /dev/null +++ b/Multiprotocol/Flysky_afhds2a_a7105.ino @@ -0,0 +1,317 @@ +// adaptation de https://github.com/goebish/deviation/blob/c5dd9fcc1441fc05fe9effa4c378886aeb3938d4/src/protocol/flysky_afhds2a_a7105.c +#ifdef AFHDS2A_A7105_INO + #define EEPROMadress 0 // rx ID 32bit + #define SERVO_HZ 0 //Frequency's servo 0=50 1=400 2=5 + + #define TXPACKET_SIZE 38 + #define RXPACKET_SIZE 37 + #define NUMFREQ 16 + #define TXID_SIZE 4 + #define RXID_SIZE 4 + + static uint8_t rxid[RXID_SIZE]; + static uint8_t packet_type; + static uint8_t bind_reply; + + + enum{ + PACKET_STICKS, + PACKET_SETTINGS, + PACKET_FAILSAFE, + }; + + enum{ + BIND1, + BIND2, + BIND3, + BIND4, + DATA1, + }; + enum { + PWM_IBUS = 0, + PPM_IBUS, + PWM_SBUS, + PPM_SBUS + }; + + + static void build_packet(uint8_t type) { + switch(type) { + case PACKET_STICKS: + packet[0] = 0x58; + memcpy( &packet[1], rx_tx_addr, 4); + memcpy( &packet[5], rxid, 4); + for(uint8_t ch=0; ch<14; ch++) { + packet[9 + ch*2] = Servo_data[CH_AETR[ch]]&0xFF; + packet[10 + ch*2] = (Servo_data[CH_AETR[ch]]>>8)&0xFF; + } + packet[37] = 0x00; + break; + + case PACKET_SETTINGS: + packet[0] = 0xaa; + memcpy( &packet[1], rx_tx_addr, 4); + memcpy( &packet[5], rxid, 4); + packet[9] = 0xfd; + packet[10]= 0xff; + packet[11]= SERVO_HZ & 0xff; + packet[12]= (SERVO_HZ >> 8) & 0xff; + if(option == PPM_IBUS || option == PPM_SBUS) + packet[13] = 0x01; // PPM output enabled + else + packet[13] = 0x00; + packet[14]= 0x00; + for(uint8_t i=15; i<37; i++) + packet[i] = 0xff; + packet[18] = 0x05; // ? + packet[19] = 0xdc; // ? + packet[20] = 0x05; // ? + if(option == PWM_SBUS || option == PPM_SBUS) + packet[21] = 0xdd; // SBUS output enabled + else + packet[21] = 0xde; + packet[37] = 0x00; + break; + + case PACKET_FAILSAFE: + packet[0] = 0x56; + memcpy( &packet[1], rx_tx_addr, 4); + memcpy( &packet[5], rxid, 4); + for(uint8_t ch=0; ch<14; ch++) { + if(ch==0) { + // if(ch < Model.num_channels && (Model.limits[ch].flags & CH_FAILSAFE_EN)) { + uint32_t value = ((uint32_t)Servo_data[AUX11] + 100) * 5 + 1000; + packet[9 + ch*2] = value & 0xff; + packet[10+ ch*2] = (value >> 8) & 0xff; + } + else { + packet[9 + ch*2] = 0xff; + packet[10+ ch*2] = 0xff; + } + } + packet[37] = 0x00; + break; + } + } + + #if defined(TELEMETRY) + // telemetry sensors ID + enum{ + SENSOR_RX_VOLTAGE = 0x00, + SENSOR_RX_ERR_RATE = 0xfe, + SENSOR_RX_RSSI = 0xfc, + SENSOR_RX_NOISE = 0xfb, + SENSOR_RX_SNR = 0xfa, + }; + + static void update_telemetry() { + // AA | TXID | RXID | sensor id | sensor # | value 16 bit big endian | sensor id ...... + // max 7 sensors per packet + + for(uint8_t sensor=0; sensor<7; sensor++) { + uint8_t index = 9+(4*sensor); + switch(packet[index]) { + case SENSOR_RX_VOLTAGE: + v_lipo = packet[index+3]<<8 | packet[index+2]; + telemetry_link=1; + break; + case SENSOR_RX_ERR_RATE: + // packet[index+2]; + break; + case SENSOR_RX_RSSI: + RSSI_dBm = -packet[index+2]; + break; + case 0xff: + return; + default: + // unknown sensor ID + break; + } + } + } + #endif + + static void afhds2a_build_bind_packet() { + uint8_t ch; + memcpy( &packet[1], rx_tx_addr, 4); + memset( &packet[5], 0xff, 4); + packet[10]= 0x00; + for(ch=0; ch<16; ch++) { + packet[11+ch] = hopping_frequency[ch]; + } + memset( &packet[27], 0xff, 10); + packet[37] = 0x00; + switch(phase) { + case BIND1: + packet[0] = 0xbb; + packet[9] = 0x01; + break; + case BIND2: + case BIND3: + case BIND4: + packet[0] = 0xbc; + if(phase == BIND4) { + memcpy( &packet[5], &rxid, 4); + memset( &packet[11], 0xff, 16); + } + packet[9] = phase-1; + if(packet[9] > 0x02) + packet[9] = 0x02; + packet[27]= 0x01; + packet[28]= 0x80; + break; + } + } + + static void calc_afhds_channels(uint32_t seed) { + int idx = 0; + uint32_t rnd = seed; + while (idx < NUMFREQ) { + int i; + int count_1_42 = 0, count_43_85 = 0, count_86_128 = 0, count_129_168=0; + rnd = rnd * 0x0019660D + 0x3C6EF35F; // Randomization + + uint8_t next_ch = ((rnd >> (idx%32)) % 0xa8) + 1; + // Keep the distance 2 between the channels - either odd or even + if (((next_ch ^ seed) & 0x01 )== 0) + continue; + // Check that it's not duplicate and spread uniformly + for (i = 0; i < idx; i++) { + if(hopping_frequency[i] == next_ch) + break; + if(hopping_frequency[i] <= 42) + count_1_42++; + else if (hopping_frequency[i] <= 85) + count_43_85++; + else if (hopping_frequency[i] <= 128) + count_86_128++; + else + count_129_168++; + } + if (i != idx) + continue; + if ((next_ch <= 42 && count_1_42 < 5) + ||(next_ch >= 43 && next_ch <= 85 && count_43_85 < 5) + ||(next_ch >= 86 && next_ch <=128 && count_86_128 < 5) + ||(next_ch >= 129 && count_129_168 < 5)) + { + hopping_frequency[idx++] = next_ch; + } + } + } + + #define WAIT_WRITE 0x80 + static uint16_t afhds2a_cb() { + switch(phase) { + case BIND1: + case BIND2: + case BIND3: + A7105_Strobe(A7105_STANDBY); + afhds2a_build_bind_packet(); + A7105_WriteData(38, packet_count%2 ? 0x0d : 0x8c); + if(A7105_ReadReg(0) == 0x1b) { // todo: replace with check crc+fec + A7105_Strobe(A7105_RST_RDPTR); + A7105_ReadData(RXPACKET_SIZE); + if(packet[0] == 0xbc) { + for(uint8_t i=0; i<4; i++) { + rxid[i] = packet[5+i]; + } + eeprom_write_block((const void*)rxid,(void*)EEPROMadress,4); + if(packet[9] == 0x01) + phase = BIND4; + } + } + packet_count++; + phase |= WAIT_WRITE; + return 1700; + case BIND1|WAIT_WRITE: + case BIND2|WAIT_WRITE: + case BIND3|WAIT_WRITE: + A7105_Strobe(A7105_RX); + phase &= ~WAIT_WRITE; + phase++; + if(phase > BIND3) + phase = BIND1; + return 2150; + case BIND4: + A7105_Strobe(A7105_STANDBY); + afhds2a_build_bind_packet(); + A7105_WriteData(38, packet_count%2 ? 0x0d : 0x8c); + packet_count++; + bind_reply++; + if(bind_reply>=4) { + packet_count=0; + channel=1; + phase = DATA1; + BIND_DONE; + } + phase |= WAIT_WRITE; + return 1700; + case BIND4|WAIT_WRITE: + A7105_Strobe(A7105_RX); + phase &= ~WAIT_WRITE; + return 2150; + case DATA1: + A7105_Strobe(A7105_STANDBY); + build_packet(packet_type); + A7105_WriteData(38, hopping_frequency[channel++]); + if(channel >= 16) + channel = 0; + if(!(packet_count % 1313)) + packet_type = PACKET_SETTINGS; + else if(!(packet_count % 1569)) + packet_type = PACKET_FAILSAFE; + else + packet_type = PACKET_STICKS; // todo : check for settings changes + // got some data from RX ? + // we've no way to know if RX fifo has been filled + // as we can't poll GIO1 or GIO2 to check WTR + // we can't check A7105_MASK_TREN either as we know + // it's currently in transmit mode. + if(!(A7105_ReadReg(0) & (1<<5 | 1<<6))) { // FECF+CRCF Ok + A7105_Strobe(A7105_RST_RDPTR); + A7105_ReadData(1); + if(packet[0] == 0xaa) { + A7105_Strobe(A7105_RST_RDPTR); + A7105_ReadData(RXPACKET_SIZE); + if(packet[9] == 0xfc) { // rx is asking for settings + packet_type=PACKET_SETTINGS; + } + else { + #if defined(TELEMETRY) + update_telemetry(); + #endif + } + } + } + packet_count++; + phase |= WAIT_WRITE; + return 1700; + case DATA1|WAIT_WRITE: + phase &= ~WAIT_WRITE; + A7105_Strobe(A7105_RX); + return 2150; + } + return 3850; // never reached, please the compiler + } + + static uint16_t AFHDS2A_setup() + { + A7105_Init(INIT_FLYSKY_AFHDS2A); //flysky_init(); + + calc_afhds_channels(MProtocol_id); + packet_type = PACKET_STICKS; + packet_count = 0; + bind_reply = 0; + if(IS_AUTOBIND_FLAG_on) { + phase = BIND1; + BIND_IN_PROGRESS; + } + else { + phase = DATA1; + eeprom_read_block((void*)rxid,(const void*)EEPROMadress,4); + } + channel = 0; + return 50000; + } +#endif diff --git a/Multiprotocol/FrSkyX_cc2500.ino b/Multiprotocol/FrSkyX_cc2500.ino index 5f5f6ba..be159b3 100644 --- a/Multiprotocol/FrSkyX_cc2500.ino +++ b/Multiprotocol/FrSkyX_cc2500.ino @@ -17,297 +17,9 @@ */ #if defined(FRSKYX_CC2500_INO) - - #include "iface_cc2500.h" - - uint8_t chanskip; - uint8_t calData[48][3]; - uint8_t channr; - uint8_t pass_ = 1 ; - uint8_t counter_rst; - uint8_t ctr; - uint8_t FS_flag=0; - // uint8_t ptr[4]={0x01,0x12,0x23,0x30}; - //uint8_t ptr[4]={0x00,0x11,0x22,0x33}; - - const PROGMEM uint8_t hop_data[]={ - 0x02, 0xD4, 0xBB, 0xA2, 0x89, - 0x70, 0x57, 0x3E, 0x25, 0x0C, - 0xDE, 0xC5, 0xAC, 0x93, 0x7A, - 0x61, 0x48, 0x2F, 0x16, 0xE8, - 0xCF, 0xB6, 0x9D, 0x84, 0x6B, - 0x52, 0x39, 0x20, 0x07, 0xD9, - 0xC0, 0xA7, 0x8E, 0x75, 0x5C, - 0x43, 0x2A, 0x11, 0xE3, 0xCA, - 0xB1, 0x98, 0x7F, 0x66, 0x4D, - 0x34, 0x1B, 0x00, 0x1D, 0x03 - }; - static uint8_t __attribute__((unused)) hop(uint8_t byte) - { - return pgm_read_byte_near(&hop_data[byte]); - } +#include "iface_cc2500.h" - static void __attribute__((unused)) set_start(uint8_t ch ) - { - cc2500_strobe(CC2500_SIDLE); - cc2500_writeReg(CC2500_23_FSCAL3, calData[ch][0]); - cc2500_writeReg(CC2500_24_FSCAL2, calData[ch][1]); - cc2500_writeReg(CC2500_25_FSCAL1, calData[ch][2]); - cc2500_writeReg(CC2500_0A_CHANNR, ch==47?0:pgm_read_word(&hop_data[ch])); - } - - static void __attribute__((unused)) frskyX_init() - { - CC2500_Reset(); - - for(uint8_t i=0;i<36;i++) - { - uint8_t reg=pgm_read_byte_near(&cc2500_conf[i][0]); - uint8_t val=pgm_read_byte_near(&cc2500_conf[i][1]); - - if(reg==CC2500_06_PKTLEN) - val=0x1E; - else - if(reg==CC2500_08_PKTCTRL0) - val=0x01; - else - if(reg==CC2500_0B_FSCTRL1) - val=0x0A; - else - if(reg==CC2500_10_MDMCFG4) - val=0x7B; - else - if(reg==CC2500_11_MDMCFG3) - val=0x61; - else - if(reg==CC2500_12_MDMCFG2) - val=0x13; - else - if(reg==CC2500_15_DEVIATN) - val=0x51; - - cc2500_writeReg(reg,val); - } - - cc2500_writeReg(CC2500_07_PKTCTRL1, 0x04); - cc2500_writeReg(CC2500_0C_FSCTRL0, option); - cc2500_strobe(CC2500_SIDLE); - // - for(uint8_t c=0;c < 47;c++){//calibrate hop channels - cc2500_strobe(CC2500_SIDLE); - cc2500_writeReg(CC2500_0A_CHANNR,pgm_read_word(&hop_data[c])); - cc2500_strobe(CC2500_SCAL); - delayMicroseconds(900);// - calData[c][0] = cc2500_readReg(CC2500_23_FSCAL3); - calData[c][1] = cc2500_readReg(CC2500_24_FSCAL2); - calData[c][2] = cc2500_readReg(CC2500_25_FSCAL1); - } - cc2500_strobe(CC2500_SIDLE); - cc2500_writeReg(CC2500_0A_CHANNR,0x00); - cc2500_strobe(CC2500_SCAL); - delayMicroseconds(900); - calData[47][0] = cc2500_readReg(CC2500_23_FSCAL3); - calData[47][1] = cc2500_readReg(CC2500_24_FSCAL2); - calData[47][2] = cc2500_readReg(CC2500_25_FSCAL1); - //#######END INIT######## - } - - static void __attribute__((unused)) initialize_data(uint8_t adr) - { - cc2500_writeReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack - cc2500_writeReg(CC2500_18_MCSM0, 0x8); - cc2500_writeReg(CC2500_09_ADDR, adr ? 0x03 : rx_tx_addr[3]); - cc2500_writeReg(CC2500_07_PKTCTRL1,0x05); - } - - static uint8_t __attribute__((unused)) crc_Byte( uint8_t byte ) - { - crc = (crc<<8) ^ pgm_read_word(&CRCTable[((uint8_t)(crc>>8) ^ byte) & 0xFF]); - return byte; - } - - static uint16_t __attribute__((unused)) scaleForPXX( uint8_t i ) - { //mapped 860,2140(125%) range to 64,1984(PXX values); - return (uint16_t)(((Servo_data[i]-PPM_MIN)*3)>>1)+64; - } - - static void __attribute__((unused)) frskyX_build_bind_packet() - { - crc=0; - packet[0] = 0x1D; - packet[1] = 0x03; - packet[2] = 0x01; - // - packet[3] = crc_Byte(rx_tx_addr[3]); - packet[4] = crc_Byte(rx_tx_addr[2]); - int idx = ((state -FRSKY_BIND) % 10) * 5; - packet[5] = crc_Byte(idx); - packet[6] = crc_Byte(pgm_read_word(&hop_data[idx++])); - packet[7] = crc_Byte(pgm_read_word(&hop_data[idx++])); - packet[8] = crc_Byte(pgm_read_word(&hop_data[idx++])); - packet[9] = crc_Byte(pgm_read_word(&hop_data[idx++])); - packet[10] = crc_Byte(pgm_read_word(&hop_data[idx++])); - packet[11] = crc_Byte(0x02); - packet[12] = crc_Byte(RX_num); - // - for(uint8_t i=13;i<28;i++) - packet[i]=crc_Byte(0); - // - packet[28]=highByte(crc); - packet[29]=lowByte(crc); - // - } - - static void __attribute__((unused)) frskyX_data_frame() - { - //0x1D 0xB3 0xFD 0x02 0x56 0x07 0x15 0x00 0x00 0x00 0x04 0x40 0x00 0x04 0x40 0x00 0x04 0x40 0x00 0x04 0x40 0x08 0x00 0x00 0x00 0x00 0x00 0x00 0x96 0x12 - // - uint8_t lpass = pass_ ; - uint16_t chan_0 ; - uint16_t chan_1 ; - uint8_t flag2 = 0; - uint8_t startChan = 0; - crc = 0; - //static uint8_t p = 0; - // - packet[0] = 0x1D; - packet[1] = rx_tx_addr[3]; - packet[2] = rx_tx_addr[2]; - packet[3] = crc_Byte(0x02); - // - packet[4] = crc_Byte((ctr<<6)+channr); //*64 - packet[5] = crc_Byte(counter_rst); - packet[6] = crc_Byte(RX_num); - // FLAGS 00 - standard packet - //10, 12, 14, 16, 18, 1A, 1C, 1E - failsafe packet - //20 - range check packet - packet[7] = crc_Byte(FS_flag); - packet[8] = crc_Byte(flag2); - // - if ( lpass & 1 ) - startChan += 8 ; - - for(uint8_t i = 0; i <12 ; i+=3) - {//12 bytes - chan_0 = scaleForPXX(startChan); - if(lpass & 1 ) - chan_0+=2048; - - packet[9+i] = crc_Byte(lowByte(chan_0));//3 bytes*4 - startChan++; - chan_1 = scaleForPXX(startChan); - if(lpass & 1 ) - chan_1+= 2048; - - startChan++; - packet[9+i+1]=crc_Byte((((chan_0>>8) & 0x0F)|(chan_1 << 4))); - packet[9+i+2]=crc_Byte(chan_1>>4); - } - //packet[21]=crc_Byte(0x08);//first - packet[21]=crc_Byte(0x80);//??? when received first telemetry frame is changed to 0x80 - //packet[21]=crc_Byte(ptr[p]);//??? - //p=(p+1)%4;//repeating 4 bytes sequence pattern every 4th frame. - - pass_=lpass+1; - - for (uint8_t i=22;i<28;i++) - packet[i]=crc_Byte(0); - - packet[28]=highByte(crc); - packet[29]=lowByte(crc); - } - -<<<<<<< HEAD - uint16_t ReadFrSkyX() - { - switch(state) - { - default: - set_start(47); - CC2500_SetPower(); - cc2500_strobe(CC2500_SFRX); - // - frskyX_build_bind_packet(); - cc2500_strobe(CC2500_SIDLE); - cc2500_writeFifo(packet, packet[0]+1); - state++; - return 9000; - case FRSKY_BIND_DONE: - initialize_data(0); - channr=0; - BIND_DONE; - state++; - break; - case FRSKY_DATA1: - LED_ON; - CC2500_SetTxRxMode(TX_EN); - set_start(channr); - CC2500_SetPower(); - cc2500_strobe(CC2500_SFRX); - channr = (channr+chanskip)%47; - cc2500_strobe(CC2500_SIDLE); - cc2500_writeFifo(packet, packet[0]+1); - // - frskyX_data_frame(); - state++; - return 5500; - case FRSKY_DATA2: - CC2500_SetTxRxMode(RX_EN); - cc2500_strobe(CC2500_SIDLE); - state++; - return 200; - case FRSKY_DATA3: - cc2500_strobe(CC2500_SRX); - state++; - return 3000; - case FRSKY_DATA4: - len = cc2500_readReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F; - if (len &&(len>2; - //for test*************** - //rx_tx_addr[3]=0xB3; - //rx_tx_addr[2]=0xFD; - //************************ - frskyX_init(); - // - if(IS_AUTOBIND_FLAG_on) - { - state = FRSKY_BIND; - initialize_data(1); - } - else - { - state = FRSKY_DATA1; - initialize_data(0); - } - return 10000; - } -======= uint8_t chanskip; uint8_t counter_rst; uint8_t ctr; @@ -617,5 +329,4 @@ uint16_t initFrSkyX() seq_last_rcvd = 8; return 10000; } ->>>>>>> refs/remotes/pascallanger/master #endif \ No newline at end of file diff --git a/Multiprotocol/FrSky_cc2500.ino b/Multiprotocol/FrSky_cc2500.ino deleted file mode 100644 index ec17450..0000000 --- a/Multiprotocol/FrSky_cc2500.ino +++ /dev/null @@ -1,219 +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. - - 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 . - */ - -#if defined(FRSKY_CC2500_INO) - -#include "iface_cc2500.h" - -//##########Variables######## -//uint32_t state; -//uint8_t len; - -/* -enum { - FRSKY_BIND = 0, - FRSKY_BIND_DONE = 1000, - FRSKY_DATA1, - FRSKY_DATA2, - FRSKY_DATA3, - FRSKY_DATA4, - FRSKY_DATA5 -}; -*/ - -static void __attribute__((unused)) frsky2way_init(uint8_t bind) -{ - // Configure cc2500 for tx mode - CC2500_Reset(); - // - for(uint8_t i=0;i<36;i++) - { - uint8_t reg=pgm_read_byte_near(&cc2500_conf[i][0]); - uint8_t val=pgm_read_byte_near(&cc2500_conf[i][1]); - - if(reg==CC2500_0C_FSCTRL0) - val=option; - else - if(reg==CC2500_1B_AGCCTRL2) - val=bind ? 0x43 : 0x03; - cc2500_writeReg(reg,val); - } - - CC2500_SetTxRxMode(TX_EN); - CC2500_SetPower(); - - cc2500_strobe(CC2500_SIDLE); - - cc2500_writeReg(CC2500_09_ADDR, bind ? 0x03 : rx_tx_addr[3]); - cc2500_writeReg(CC2500_07_PKTCTRL1, 0x05); - cc2500_strobe(CC2500_SIDLE); // Go to idle... - // - cc2500_writeReg(CC2500_0A_CHANNR, 0x00); - cc2500_writeReg(CC2500_23_FSCAL3, 0x89); - cc2500_strobe(CC2500_SFRX); - //#######END INIT######## -} - -static uint8_t __attribute__((unused)) get_chan_num(uint16_t idx) -{ - uint8_t ret = (idx * 0x1e) % 0xeb; - if(idx == 3 || idx == 23 || idx == 47) - ret++; - if(idx > 47) - return 0; - return ret; -} - -static void __attribute__((unused)) frsky2way_build_bind_packet() -{ - //11 03 01 d7 2d 00 00 1e 3c 5b 78 00 00 00 00 00 00 01 - //11 03 01 19 3e 00 02 8e 2f bb 5c 00 00 00 00 00 00 01 - packet[0] = 0x11; - packet[1] = 0x03; - packet[2] = 0x01; - packet[3] = rx_tx_addr[3]; - packet[4] = rx_tx_addr[2]; - uint16_t idx = ((state -FRSKY_BIND) % 10) * 5; - packet[5] = idx; - packet[6] = get_chan_num(idx++); - packet[7] = get_chan_num(idx++); - packet[8] = get_chan_num(idx++); - packet[9] = get_chan_num(idx++); - packet[10] = get_chan_num(idx++); - packet[11] = 0x00; - packet[12] = 0x00; - packet[13] = 0x00; - packet[14] = 0x00; - packet[15] = 0x00; - packet[16] = 0x00; - packet[17] = 0x01; -} - -static void __attribute__((unused)) frsky2way_data_frame() -{//pachet[4] is telemetry user frame counter(hub) - //11 d7 2d 22 00 01 c9 c9 ca ca 88 88 ca ca c9 ca 88 88 - //11 57 12 00 00 01 f2 f2 f2 f2 06 06 ca ca ca ca 18 18 - packet[0] = 0x11; //Length - packet[1] = rx_tx_addr[3]; - packet[2] = rx_tx_addr[2]; - packet[3] = counter;// - #if defined TELEMETRY - packet[4] = telemetry_counter; - #else - packet[4] = 0x00; - #endif - - packet[5] = 0x01; - // - packet[10] = 0; - packet[11] = 0; - packet[16] = 0; - packet[17] = 0; - for(uint8_t i = 0; i < 8; i++) - { - uint16_t value; - value = convert_channel_frsky(i); - if(i < 4) - { - packet[6+i] = value & 0xff; - packet[10+(i>>1)] |= ((value >> 8) & 0x0f) << (4 *(i & 0x01)); - } - else - { - packet[8+i] = value & 0xff; - packet[16+((i-4)>>1)] |= ((value >> 8) & 0x0f) << (4 * ((i-4) & 0x01)); - } - } -} - -uint16_t initFrSky_2way() -{ - if(IS_AUTOBIND_FLAG_on) - { - frsky2way_init(1); - state = FRSKY_BIND;// - } - else - { - frsky2way_init(0); - state = FRSKY_DATA2; - } - return 10000; -} - -uint16_t ReadFrSky_2way() -{ - if (state < FRSKY_BIND_DONE) - { - frsky2way_build_bind_packet(); - cc2500_strobe(CC2500_SIDLE); - cc2500_writeReg(CC2500_0A_CHANNR, 0x00); - cc2500_writeReg(CC2500_23_FSCAL3, 0x89); - cc2500_strobe(CC2500_SFRX);//0x3A - cc2500_writeFifo(packet, packet[0]+1); - state++; - return 9000; - } - if (state == FRSKY_BIND_DONE) - { - state = FRSKY_DATA2; - frsky2way_init(0); - counter = 0; - BIND_DONE; - } - else - if (state == FRSKY_DATA5) - { - cc2500_strobe(CC2500_SRX);//0x34 RX enable - state = FRSKY_DATA1; - return 9200; - } - counter = (counter + 1) % 188; - if (state == FRSKY_DATA4) - { //telemetry receive - CC2500_SetTxRxMode(RX_EN); - cc2500_strobe(CC2500_SIDLE); - cc2500_writeReg(CC2500_0A_CHANNR, get_chan_num(counter % 47)); - cc2500_writeReg(CC2500_23_FSCAL3, 0x89); - state++; - return 1300; - } - else - { - if (state == FRSKY_DATA1) - { - len = cc2500_readReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F; - if (len<=MAX_PKT)//27 bytes - { - cc2500_readFifo(pkt, len); //received telemetry packets - #if defined(TELEMETRY) - //parse telemetry packet here - frsky_check_telemetry(pkt,len); //check if valid telemetry packets and buffer them. - #endif - } - CC2500_SetTxRxMode(TX_EN); - CC2500_SetPower(); // Set tx_power - } - cc2500_strobe(CC2500_SIDLE); - cc2500_writeReg(CC2500_0A_CHANNR, get_chan_num(counter % 47)); - cc2500_writeReg(CC2500_23_FSCAL3, 0x89); - cc2500_strobe(CC2500_SFRX); - frsky2way_data_frame(); - cc2500_writeFifo(packet, packet[0]+1); - state++; - } - return state == FRSKY_DATA4 ? 7500 : 9000; -} -#endif diff --git a/Multiprotocol/Hisky_nrf24l01.ino b/Multiprotocol/Hisky_nrf24l01.ino index ddf935b..a32cf67 100644 --- a/Multiprotocol/Hisky_nrf24l01.ino +++ b/Multiprotocol/Hisky_nrf24l01.ino @@ -122,7 +122,7 @@ static void __attribute__((unused)) build_ch_data() uint8_t i,j; for (i = 0; i< 8; i++) { j=CH_AETR[i]; - temp=map(limit_channel_100(j),servo_min_100,servo_max_100,0,1000); + temp=map(limit_channel_100(j),servo_min_100,servo_max_100,0,1000); if (j == THROTTLE) // It is clear that hisky's throttle stick is made reversely, so I adjust it here on purpose temp = 1000 -temp; if (j == AUX3) diff --git a/Multiprotocol/Hontai_nrf24l01.ino b/Multiprotocol/Hontai_nrf24l01.ino index 64f61a9..f522ef8 100644 --- a/Multiprotocol/Hontai_nrf24l01.ino +++ b/Multiprotocol/Hontai_nrf24l01.ino @@ -70,6 +70,7 @@ static void __attribute__((unused)) HONTAI_send_packet(uint8_t bind) } else { +/* if(sub_protocol == FORMAT_JJRCX1) packet[0] = GET_FLAG(Servo_AUX2, 0x02); // Arm else @@ -112,7 +113,60 @@ static void __attribute__((unused)) HONTAI_send_packet(uint8_t bind) packet[9] = convert_channel_8b_scale(ELEVATOR, 0, 63)-31; // Elevator trim else packet[9] = convert_channel_8b_scale(ELEVATOR, 0, 32)-16; // Elevator trim +*/ + packet[1] = 0x00; + packet[2] = 0x00; + packet[3] = (convert_channel_8b_scale(THROTTLE, 0, 127) << 1); // Throttle + packet[4] = convert_channel_8b_scale(AILERON, 63, 0); // Aileron + packet[5] = convert_channel_8b_scale(ELEVATOR, 0, 63); // Elevator + packet[6] = convert_channel_8b_scale(RUDDER, 0, 63); // Rudder + if(sub_protocol == FORMAT_X5C1) + packet[7] = convert_channel_8b_scale(AILERON, 0, 63)-31; // Aileron trim + else + packet[7] = convert_channel_8b_scale(AILERON, 0, 32)-16; // Aileron trim + if (sub_protocol == FORMAT_X5C1) + packet[9] = convert_channel_8b_scale(ELEVATOR, 0, 63)-31; // Elevator trim + else + packet[9] = convert_channel_8b_scale(ELEVATOR, 0, 32)-16; // Elevator trim + switch(sub_protocol) { + case FORMAT_HONTAI: + packet[0] = 0x0b; + packet[3] |= GET_FLAG(Servo_AUX3, 0x01); // Picture + packet[4] |= GET_FLAG(Servo_AUX6, 0x80) // RTH + | GET_FLAG(Servo_AUX5, 0x40); // Headless + packet[5] |= GET_FLAG(Servo_AUX7, 0x80) // Calibrate + | GET_FLAG(Servo_AUX1, 0x40); // Flip + packet[6] |= GET_FLAG(Servo_AUX4, 0x80); // Video + packet[8] = convert_channel_8b_scale(RUDDER, 0, 32)-16; // Rudder trim + break; + case FORMAT_X5C1: + case FORMAT_JJRCX1: + packet[0] = GET_FLAG(Servo_AUX2, 0x02); //Arm + packet[3] |= GET_FLAG(Servo_AUX3, 0x01); // Picture + packet[4] |= 0x80; // unknown + if (sub_protocol == FORMAT_X5C1) + packet[4] |= GET_FLAG(Servo_AUX2, 0x40); // Lights (X5C1) + packet[5] |= GET_FLAG(Servo_AUX7, 0x80) // Calibrate + | GET_FLAG(Servo_AUX1, 0x40); // Flip + packet[6] |= GET_FLAG(Servo_AUX4, 0x80); // Video + packet[8] = 0xc0 // high rate, no rudder trim + | GET_FLAG(Servo_AUX6, 0x02) // RTH + | GET_FLAG(Servo_AUX5, 0x01); // Headless + break; + case FORMAT_FQ777: + // todo: add missing calibration flag + packet[0] = GET_FLAG(Servo_AUX3, 0x01) // Picture + | GET_FLAG(Servo_AUX4, 0x02); // Video + packet[3] |= GET_FLAG(Servo_AUX1, 0x01); // Flip + packet[4] |= 0xc0; // high rate (mid=0xa0, low=0x60) + packet[6] |= GET_FLAG(Servo_AUX5, 0x40); // Headless + if((packet[4] & 0x3f) > 0x3d && (packet[5] & 0x3f) < 3) + packet[5] |= 0x80; // accelerometer recalibration + break; + packet[8] = convert_channel_8b_scale(RUDDER, 0, 32)-16; // Rudder trim + } + packet_size=HONTAI_PACKET_SIZE; } crc16(packet, packet_size); @@ -172,7 +226,8 @@ static void __attribute__((unused)) HONTAI_init() const uint8_t PROGMEM hopping_frequency_nonels[][3] = { {0x05, 0x19, 0x28}, // Hontai - {0x0a, 0x1e, 0x2d}}; // JJRC X1 + {0x0a, 0x1e, 0x2d}, // JJRC X1 + {0x05, 0x19, 0x28}}; // FQ777-951 const uint8_t PROGMEM addr_vals[4][16] = { {0x24, 0x26, 0x2a, 0x2c, 0x32, 0x34, 0x36, 0x4a, 0x4c, 0x4e, 0x54, 0x56, 0x5a, 0x64, 0x66, 0x6a}, diff --git a/Multiprotocol/Hubsan_a7105.ino b/Multiprotocol/Hubsan_a7105.ino index de0c2bf..227134c 100644 --- a/Multiprotocol/Hubsan_a7105.ino +++ b/Multiprotocol/Hubsan_a7105.ino @@ -18,24 +18,51 @@ #if defined(HUBSAN_A7105_INO) #include "iface_a7105.h" +enum { + FORMAT_H107 = 0, + FORMAT_H301, + FORMAT_H501, +}; enum{ - // flags going to packet[9] (Normal) + // flags going to packet[9] (H107 Normal) HUBSAN_FLAG_VIDEO= 0x01, // record video HUBSAN_FLAG_FLIP = 0x08, // enable flips HUBSAN_FLAG_LED = 0x04 // enable LEDs }; enum{ - // flags going to packet[9] (Plus series) + // flags going to packet[9] (H107 Plus series) HUBSAN_FLAG_HEADLESS = 0x08, // headless mode }; - enum{ - // flags going to packet[13] (Plus series) + // flags going to packet[9] (H301) + FLAG_H301_VIDEO = 0x01, + FLAG_H301_STAB = 0x02, + FLAG_H301_LED = 0x10, + FLAG_H301_RTH = 0x40, +}; +enum{ + // flags going to packet[13] (H107 Plus series) HUBSAN_FLAG_SNAPSHOT = 0x01, HUBSAN_FLAG_FLIP_PLUS = 0x80, }; +enum{ + // flags going to packet[9] (H501S) + FLAG_H501_VIDEO = 0x01, + FLAG_H501_LED = 0x04, + FLAG_H501_RTH = 0x20, + FLAG_H501_HEADLESS1 = 0x40, + FLAG_H501_GPS_HOLD = 0x80, +}; + +enum{ + // flags going to packet[13] (H501S) + FLAG_H501_SNAPSHOT = 0x01, + FLAG_H501_HEADLESS2 = 0x02, + FLAG_H501_ALT_HOLD = 0x08, +}; + uint32_t sessionid,id_data; @@ -76,7 +103,7 @@ static void __attribute__((unused)) hubsan_build_bind_packet(uint8_t bind_state) packet[3] = (sessionid >> 16) & 0xFF; packet[4] = (sessionid >> 8) & 0xFF; packet[5] = (sessionid >> 0) & 0xFF; - if(id_data == ID_NORMAL) + if(id_data == ID_NORMAL && sub_protocol != FORMAT_H501) { packet[6] = 0x08; packet[7] = 0xe4; @@ -89,7 +116,7 @@ static void __attribute__((unused)) hubsan_build_bind_packet(uint8_t bind_state) packet[13] = 0x26; packet[14] = 0x79; } - else + else if(id_data == ID_PLUS || sub_protocol == FORMAT_H501) { //ID_PLUS if(phase >= BIND_3) { @@ -109,6 +136,7 @@ static void __attribute__((unused)) hubsan_build_bind_packet(uint8_t bind_state) static void __attribute__((unused)) hubsan_build_packet() { static uint8_t vtx_freq = 0; + static uint32_t h501_packet = 0; memset(packet, 0, 16); if(vtx_freq != option || packet_count==100) // set vTX frequency (H107D) { @@ -127,7 +155,7 @@ static void __attribute__((unused)) hubsan_build_packet() packet[4] = 0xFF - convert_channel_8b(RUDDER); //Rudder is reversed packet[6] = 0xFF - convert_channel_8b(ELEVATOR); //Elevator is reversed packet[8] = convert_channel_8b(AILERON); //Aileron - if(id_data == ID_NORMAL) + if(id_data == ID_NORMAL && sub_protocol == FORMAT_H107) // H107/L/C/D, H102D { if( packet_count < 100) { @@ -151,21 +179,50 @@ static void __attribute__((unused)) hubsan_build_packet() packet[13] = 0x26; packet[14] = 0x79; } - else - { //ID_PLUS - packet[3] = 0x64; - packet[5] = 0x64; - packet[7] = 0x64; - packet[9] = 0x06; - //FLIP|LIGHT|PICTURE|VIDEO|HEADLESS - if(Servo_AUX4) packet[9] |= HUBSAN_FLAG_VIDEO; - if(Servo_AUX5) packet[9] |= HUBSAN_FLAG_HEADLESS; - packet[10]= 0x19; - packet[12]= 0x5C; // ghost channel ? - packet[13] = 0; - if(Servo_AUX3) packet[13] = HUBSAN_FLAG_SNAPSHOT; - if(Servo_AUX1) packet[13] |= HUBSAN_FLAG_FLIP_PLUS; - packet[14]= 0x49; // ghost channel ? + else if( sub_protocol == FORMAT_H301) { + if(packet_count < 100) { + packet[9] = FLAG_H301_STAB; + packet_count++; + } else { + packet[9] = 0; + if(Servo_AUX1) packet[9] |= FLAG_H301_LED; + if(Servo_AUX2) packet[9] |= FLAG_H301_STAB; + if(Servo_AUX3) packet[9] |= FLAG_H301_RTH; + if(Servo_AUX4) packet[9] |= FLAG_H301_VIDEO; // H102D + } + packet[10] = 0x18; // ? + packet[12] = 0x5c; // ? + packet[14] = 0xf6; // ? + } else + { //ID_PLUS +FORMAT_H501 + packet[3] = sub_protocol == FORMAT_H501 ? 0x00 : 0x64; + packet[5] = sub_protocol == FORMAT_H501 ? 0x00 : 0x64; + packet[7] = sub_protocol == FORMAT_H501 ? 0x00 : 0x64; + if( sub_protocol == FORMAT_H501) { // H501S + packet[9] = 0x02; + if(Servo_AUX1) packet[9] |= HUBSAN_FLAG_FLIP; + if(Servo_AUX2) packet[9] |= FLAG_H501_LED; + if(Servo_AUX3) packet[9] |= FLAG_H501_RTH; + if(Servo_AUX4) packet[9] |= FLAG_H501_VIDEO; + if(Servo_AUX5) packet[9] |= FLAG_H501_HEADLESS1; + if(Servo_AUX6) packet[9] |= FLAG_H501_GPS_HOLD; + packet[13] = 0; + if(Servo_AUX5) packet[9] |= FLAG_H501_HEADLESS2; + if(Servo_AUX7) packet[9] |= FLAG_H501_ALT_HOLD; + if(Servo_AUX8) packet[9] |= FLAG_H501_SNAPSHOT; + } + else { // H107P/C+/D+ + packet[9] = 0x06; + //FLIP|LIGHT|PICTURE|VIDEO|HEADLESS + if(Servo_AUX4) packet[9] |= HUBSAN_FLAG_VIDEO; + if(Servo_AUX5) packet[9] |= HUBSAN_FLAG_HEADLESS; + packet[10]= sub_protocol == FORMAT_H501 ? 0x1a : 0x19; + packet[12]= 0x5C; // ghost channel ? + packet[13] = 0; + if(Servo_AUX3) packet[13] = HUBSAN_FLAG_SNAPSHOT; + if(Servo_AUX1) packet[13] |= HUBSAN_FLAG_FLIP_PLUS; + packet[14]= 0x49; // ghost channel ? + } if(packet_count < 100) { // set channels to neutral for first 100 packets packet[2] = 0x80; // throttle neutral is at mid stick on plus series @@ -176,6 +233,18 @@ static void __attribute__((unused)) hubsan_build_packet() packet[13]= 0x00; packet_count++; } + if(sub_protocol == FORMAT_H501) { + h501_packet++; + if(h501_packet == 10) { + memset(packet, 0, 16); + packet[0] = 0xe8; + } + else if(h501_packet == 20) { + memset(packet, 0, 16); + packet[0] = 0xe9; + } + if(h501_packet >= 20) h501_packet = 0; + } } hubsan_update_crc(); } @@ -205,7 +274,7 @@ uint16_t ReadHubsan() switch(phase) { case BIND_1: bind_count++; - if(bind_count >= 20) + if(bind_count >= 20 && sub_protocol != FORMAT_H501) { if(id_data == ID_NORMAL) id_data = ID_PLUS; @@ -287,7 +356,15 @@ uint16_t ReadHubsan() A7105_SetPower(); //Keep transmit power in sync hubsan_build_packet(); A7105_Strobe(A7105_STANDBY); - A7105_WriteData(16, phase == DATA_5 && id_data == ID_NORMAL ? channel + 0x23 : channel); + u8 ch; + if((phase == DATA_5 && id_data == ID_NORMAL) && sub_protocol == FORMAT_H107) { + ch = channel + 0x23; + } + else { + ch = channel; + } + A7105_WriteData( 16, ch); +// A7105_WriteData(16, phase == DATA_5 && id_data == ID_NORMAL ? channel + 0x23 : channel); if (phase == DATA_5) phase = DATA_1; else diff --git a/Multiprotocol/KN_nrf24l01.ino b/Multiprotocol/KN_nrf24l01.ino index 5675181..14e9566 100644 --- a/Multiprotocol/KN_nrf24l01.ino +++ b/Multiprotocol/KN_nrf24l01.ino @@ -246,11 +246,7 @@ static void __attribute__((unused)) kn_init() NRF24L01_Initialize(); -<<<<<<< HEAD - NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO)); -======= NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)); ->>>>>>> refs/remotes/pascallanger/master NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address @@ -263,11 +259,7 @@ static void __attribute__((unused)) kn_init() NRF24L01_Activate(0x73); NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 1); // Dynamic payload for data pipe 0 // Enable: Dynamic Payload Length to enable PCF -<<<<<<< HEAD - NRF24L01_WriteReg(NRF24L01_1D_FEATURE, BV(NRF2401_1D_EN_DPL)); -======= NRF24L01_WriteReg(NRF24L01_1D_FEATURE, _BV(NRF2401_1D_EN_DPL)); ->>>>>>> refs/remotes/pascallanger/master NRF24L01_SetPower(); diff --git a/Multiprotocol/Lua Generateur.htm b/Multiprotocol/Lua Generateur.htm new file mode 100644 index 0000000..a70b4e4 --- /dev/null +++ b/Multiprotocol/Lua Generateur.htm @@ -0,0 +1,5468 @@ + +Lua Generateur + + +

Script LUA

+
+
Programmation :
+ +T :
+A :
+E :
+R :
+FLIP :
+HEADLESS :
+LIGHT :
+VIDEO :
+PICTURE :
+DEFAULT :
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
0 SERIAL 0.0. . . . .   42 ESKY 16.0. . . . .   NRF24L01 7ESKY
1 FLYSKY 1.0FLYSKY   A7105 9FLYSKY43 MT99XX 17.0MT99   NRF24L01 10MT99XXAuto
2 FLYSKY 1.1V9X9   A7105 9FLYSKY => V9X944 MT99XX 17.1H7   NRF24L01 10MT99XX => H7Auto
3 FLYSKY 1.2V6X6   A7105 13FLYSKY => V6X645 MT99XX 17.2YZ   NRF24L01 10MT99XX => YZAuto
4 FLYSKY 1.3V912   A7105 7FLYSKY => V91246 MT99XX 17.3LS   NRF24L01 10MT99XX => LSAuto
5 HUBSAN 2.0H107   A7105 10HUBSAN47 MJXQ 18.0WLH08   NRF24L01 14MJXQAuto
6 HUBSAN 2.1H301   A7105 9HUBSAN => H30148 MJXQ 18.1X600   NRF24L01 14MJXQ => X600Auto
7 HUBSAN 2.2H501   A7105 14HUBSAN => H50149 MJXQ 18.2X800   NRF24L01 14MJXQ => X800Auto
8 FRSKYD 3.0. . . . .   CC2500 8FRSKYD50 MJXQ 18.3H26D   NRF24L01 14MJXQ => H26DAuto
9 HISKY 4.0HISKY   NRF24L01 9HISKY51 MJXQ 18.4E010   NRF24L01 14MJXQ => E010Auto
10 HISKY 4.1HK310   NRF24L01 10HISKY => HK31052 SHENQI 19.0. . . . .   NRF24L01 5ShenqiAuto
11 V2X2 5.0. . . . .   NRF24L01 12V2X253 FY326 20.0FY326   NRF24L01 10Fy326
12 DSM 6.0DSM2_22   CYRF6936 12DSM54 FY326 20.1FY319   NRF24L01 10Fy326 => FY319
13 DSM 6.1DSM2_11   CYRF6936 12DSM => DSM2_1155 SFHSS 21.0. . . . .   CC2500 9SFHSS
14 DSM 6.2DSMX_22   CYRF6936 12DSM => DSMX_2256 J6PRO 22.0. . . . .   CYRF6936 13J6PRO
15 DSM 6.3DSMX_11   CYRF6936 12DSM => DSMX_1157 FQ777 23.0. . . . .   NRF24L01 9FQ777
16 DSM 6.4AUTO   CYRF6936 12DSM => AUTO58 ASSAN 24.0. . . . .   NRF24L01 11ASSAN
17 DEVO 7.0. . . . .   CYRF6936 9DEVO59 FRSKYV 25.0. . . . .   CC2500 4FRSKYV = FrSky 1 way
18 YD717 8.0YD717   NRF24L01 10YD717Auto60 HONTAI 26.0HONTAI   NRF24L01 12HONTAI
19 YD717 8.1SKYWLKR   NRF24L01 10YD717 => SKYWLKRAuto61 HONTAI 26.1JJRCX1   NRF24L01 7HONTAI => JJRCX1
20 YD717 8.2SYMAX4   NRF24L01 10YD717 => SYMAX4Auto62 HONTAI 26.2X5C1   NRF24L01 12HONTAI => X5C1
21 YD717 8.3XINXUN   NRF24L01 10YD717 => XINXUNAuto63 HONTAI 26.3FQ777   NRF24L01 9HONTAI => FQ777
22 YD717 8.4NIHUI   NRF24L01 10YD717 => NIHUIAuto64 OPENLRS 27.0. . . . .   Other OPENLRS
23 KN 9.0WLTOYS   NRF24L01 12KN65 JOYSWAY 40.0. . . . .   A7105 5Joysway
24 KN 9.1FEILUN   NRF24L01 12KN => FEILUN66 WK2X01 41.0WK2801   CYRF6936 9WK2x01
25 SYMAX 10.0SYMAX   NRF24L01 10SymaxAuto67 WK2X01 41.1WK2601   CYRF6936 8WK2x01 => WK2601
26 SYMAX 10.1SYMAX5C   NRF24L01 10Symax => SYMAX5CAuto68 WK2X01 41.2WK2401   CYRF6936 5WK2x01 => WK2401
27 SLT 11.0. . . . .   NRF24L01 7SLTAuto69 SKYARTEC 42.0. . . . .   CC2500 8SKYARTEC
28 CX10 12.0GREEN   NRF24L01 7CX10Auto70 UDI 44.0U816_V1   NRF24L01 11UDI
29 CX10 12.1BLUE   NRF24L01 9CX10 => BLUEAuto71 UDI 44.1U816_V2   NRF24L01 11UDI => U816_V2
30 CX10 12.2DM007   NRF24L01 10CX10 => DM007Auto72 UDI 44.2U839_2014   NRF24L01 11UDI => U839_2014
31 CX10 12.3Q282   NRF24L01 13CX10 => Q282 and Q242Auto73 FBL100 45.0FBL100   NRF24L01 9FBL100
32 CX10 12.4JC3015_1   NRF24L01 9CX10 => JC3015_1Auto74 FBL100 45.1HP100   NRF24L01 9FBL100 => HP100
33 CX10 12.5JC3015_2   NRF24L01 9CX10 => JC3015_2Auto75 HM830 50.0. . . . .   NRF24L01 6HM830
34 CX10 12.6MK33041   NRF24L01 11CX10 => MK33041Auto76 CFLIE 51.0. . . . .   NRF24L01 5CFLIE
35 CX10 12.7Q242   NRF24L01 13CX10 => Q282 and Q242Auto77 H377 52.0. . . . .   NRF24L01 9H377
36 CG023 13.0CG023   NRF24L01 10CG023Auto78 ESKY150 53.0. . . . .   NRF24L01 5ESKY150
37 CG023 13.1YD829   NRF24L01 10CG023 => YD829Auto79 BLUEFLY 54.0. . . . .   NRF24L01 7BLUEFLY
38 CG023 13.2H8_3D   NRF24L01 10CG023 => H8_3DAuto80 NE260 55.0. . . . .   NRF24L01 5NE260
39 BAYANG 14.0. . . . .   NRF24L01 11BAYANGAuto81 AFHDS2A 56.0. . . . .   A7105 15Flysky AFHDS2A
40 FRSKYX 15.0CH_16   CC2500 16FRSKYX82 INAV 57.0. . . . .   NRF24L01 1INAV
41 FRSKYX 15.1CH_8   CC2500 8FRSKYX => CH_8

+ +
+

SERIAL

+

. . . . .

+

+
+ + + +
+

Close

+ +
+

FLYSKY

+

FLYSKY

+

+
+ + Extended limits supported
Note that the RX ouput will be AETR.

+ + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH14
AETRCH5CH6CH7CH8Reset/Bind
+

Close

+ +
+

FLYSKY

+

V9X9

+

+
+ + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH14
AETRFLIPLIGHTPICTUREVIDEOReset/Bind
+

Close

+ +
+

FLYSKY

+

V6X6

+

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH12CH14
AETRFLIPLIGHTPICTUREVIDEOHEADLESSRTHXCALYCALReset/Bind
+

Close

+ +
+

FLYSKY

+

V912

+

+
+ + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH14
AETRBTMBTNTOPBTNReset/Bind
+

Close

+ +
+

HUBSAN

+

H107

+

+
+ + Models: Hubsan H102D, H107/L/C/D and Hubsan H107P/C+/D+
Autobind protocol
Telemetry enabled for battery voltage and TX RSSI
Option=vTX frequency (H107D) 5645 - 5900 MHz

+ + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH14
AETRFLIPLIGHTPICTUREVIDEOHEADLESSReset/Bind
+

Close

+ +
+

HUBSAN

+

H301

+

+
+ + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH14
AETRLEDSTABRTHVIDEOReset/Bind
+

Close

+ +
+

HUBSAN

+

H501

+

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH12CH0CH14
AETRFLIPLIGHTRTHVIDEOHEADLESSGPS_HOLDALT_HOLDSNAPSHOT---Reset/Bind
+

Close

+ +
+

FRSKYD

+

. . . . .

+

+ Modèle : FrSky receivers D4R and D8R. DIY RX-F801 and RX-F802 receivers.
+ Option : fine frequency tuning. This value is different +for each board. To determine the option value, find the two limits where + the RX loses connection then set the option value to half way between +them. If you have a 4in1 V2 board the value is around 40.
+ Extended limits supported
Telemetry enabled for A0, A1, RSSI, TSSI and Hub

+ + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8
------------------------
+

Close

+ +
+

HISKY

+

HISKY

+

+
+ + GYRO: -100%=6G, +100%=3G

+ + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH14
AETRGEARPITCHGYROCH8Reset/Bind
+

Close

+ +
+

HISKY

+

HK310

+

+ Modèle : RX HK-3000, HK3100 and XY3000 (TX are HK-300, HK-310 and TL-3C)
+ + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH0CH14
TRAUXT_FSAFER_FSAFEAUX_FSAFEReset/Bind
+

Close

+ +
+

V2X2

+

. . . . .

+

+ Modèle : WLToys V202/252/272, JXD 385/388, JJRC H6C, Yizhan Tarantula X6 ...
+ + PICTURE: also automatic Missile Launcher and Hoist in one direction
VIDEO: also Sprayer, Bubbler, Missile Launcher(1), and Hoist in the other dir

+ + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH14
AETRFLIPLIGHTPICTUREVIDEOHEADLESSMAG_CAL_XMAG_CAL_YReset/Bind
+

Close

+ +
+

DSM

+

DSM2_22

+

+
+ + Extended limits supported
Telemetry enabled for TSSI and plugins
option=number of channels from 4 to 12. An invalid option value will end up with 6 channels.
Notes:
- + model/type/number of channels indicated on the RX can be different from + what the RX is in fact wanting to see. So don't hesitate to test +different combinations until you have something working. Using Auto is +the best way to find these settings.
- RX ouput will always be TAER independently of the input AETR, RETA...
DSM2, Resolution 1024, refresh rate 22ms

+ + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH12
AETRCH5CH6CH7CH8CH9CH10CH11CH12
+

Close

+ +
+

DSM

+

DSM2_11

+

+
+ + DSM2, Resolution 2048, refresh rate 11ms

+ + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH12
AETRCH5CH6CH7CH8CH9CH10CH11CH12
+

Close

+ +
+

DSM

+

DSMX_22

+

+
+ + DSMX, Resolution 2048, refresh rate 22ms

+ + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH12
AETRCH5CH6CH7CH8CH9CH10CH11CH12
+

Close

+ +
+

DSM

+

DSMX_11

+

+
+ + DSMX, Resolution 2048, refresh rate 11ms

+ + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH12
AETRCH5CH6CH7CH8CH9CH10CH11CH12
+

Close

+ +
+

DSM

+

AUTO

+

+
+ + The "AUTO" feature enables the TX to automatically choose what are the + best settings for your DSM RX and update your model protocol settings +accordingly.
The current radio firmware which are able to use the +"AUTO" feature are ersky9x (9XR Pro, 9Xtreme, Taranis, ...) and er9x for + M128 (9XR) and M2561.
For these firmwares, you must have a telemetry enabled TX and you have to make sure you set the Telemetry "Usr proto" to "DSMx".
Also + on er9x you will need to be sure to match the polarity of the telemetry + serial (normal or inverted by bitbashing), while on ersky9x you can set + "Invert COM1" accordinlgy.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH12
AETRCH5CH6CH7CH8CH9CH10CH11CH12
+

Close

+ +
+

DEVO

+

. . . . .

+

+
+ + Extended limits supported
Note that the RX ouput will be EATR.
Bind procedure using serial:
- + With the TX off, put the binding plug in and power on the RX (RX LED +slow blink), then power it down and remove the binding plug. Receiver +should now be in autobind mode.
- Turn on the TX, set protocol = Devo with option=0, turn off the TX (TX is now in autobind mode).
- Turn on RX (RX LED fast blink).
- Turn on TX (RX LED solid, TX LED fast blink).
- Wait for bind on the TX to complete (TX LED solid).
- Make sure to set the RX_Num value for model match.
- Change option to 1 to use the global ID.
- Do not touch option/RX_Num anymore.
Bind procedure using PPM:
- + With the TX off, put the binding plug in and power on the RX (RX LED +slow blink), then power it down and remove the binding plug. Receiver +should now be in autobind mode.
- Turn on RX (RX LED fast blink).
- Turn the dial to the model number running protocol DEVO on the module.
- Press the bind button and turn on the TX. TX is now in autobind mode.
- Release bind button after 1 second: RX LED solid, TX LED fast blink.
- Wait for bind on the TX to complete (TX LED solid).
- Press the bind button for 1 second. TX/RX is now in fixed ID mode.
- To verify that the TX is in fixed mode: power cycle the TX, the module LED should be solid ON (no blink).
- + Note: Autobind/fixed ID mode is linked to the dial number. Which means +that you can have multiple dial numbers set to the same protocol DEVO +with different RX_Num and have different bind modes at the same time. It + enables PPM users to get model match under DEVO.

+ + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH14
AETRCH5CH6CH7CH8Reset/Bind
+

Close

+ +
+

YD717

+

YD717

+ Autobind

+
+ + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH14
AETRFLIPLIGHTPICTUREVIDEOHEADLESSReset/Bind
+

Close

+ +
+

YD717

+

SKYWLKR

+ Autobind

+
+ + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH14
AETRFLIPLIGHTPICTUREVIDEOHEADLESSReset/Bind
+

Close

+ +
+

YD717

+

SYMAX4

+ Autobind

+
+ + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH14
AETRFLIPLIGHTPICTUREVIDEOHEADLESSReset/Bind
+

Close

+ +
+

YD717

+

XINXUN

+ Autobind

+
+ + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH14
AETRFLIPLIGHTPICTUREVIDEOHEADLESSReset/Bind
+

Close

+ +
+

YD717

+

NIHUI

+ Autobind

+
+ + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH14
AETRFLIPLIGHTPICTUREVIDEOHEADLESSReset/Bind
+

Close

+ +
+

KN

+

WLTOYS

+

+
+ + Dual Rate: +100%=full range, Throttle Hold: +100%=hold, Idle Up: +100%=3D, GYRO: -100%=6G, +100%=3G

+ + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH14
AETRDRTHOLDIDLEUPGYROTtrimAtrimEtrimReset/Bind
+

Close

+ +
+

KN

+

FEILUN

+

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH14
AETRDRTHOLDIDLEUPGYROTtrimAtrimEtrimReset/Bind
+

Close

+ +
+

SYMAX

+

SYMAX

+ Autobind

+ Modèle : Syma X5C-1/X11/X11C/X12
+ + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH14
AETRFLIPPICTUREVIDEOHEADLESSReset/Bind
+

Close

+ +
+

SYMAX

+

SYMAX5C

+ Autobind

+
+ + Model: Syma X5C (original) and X2

+ + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH14
AETRFLIPPICTUREVIDEOHEADLESSReset/Bind
+

Close

+ +
+

SLT

+

. . . . .

+ Autobind

+
+ + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH14
AETRGEARPITCHReset/Bind
+

Close

+ +
+

CX10

+

GREEN

+ Autobind

+ Modèle : Cheerson CX-10 green pcb
+ + Extended limits supported
Rate: -100%=rate 1, 0%=rate 2, +100%=rate 3

+ + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH14
AETRFLIPRATEReset/Bind
+

Close

+ +
+

CX10

+

BLUE

+ Autobind

+ Modèle : Cheerson CX-10 blue pcb & some newer red pcb, CX-10A, CX-10C, CX11, CX12, Floureon FX10, JJRC DHD D1
+ + Rate: -100%=rate 1, 0%=rate 2, +100%=rate 3 or headless for CX-10A

+ + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH14
AETRFLIPRATEPICTUREVIDEOReset/Bind
+

Close

+ +
+

CX10

+

DM007

+ Autobind

+
+ + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH14
AETRFLIPMODEPICTUREVIDEOHEADLESSReset/Bind
+

Close

+ +
+

CX10

+

Q282

+ Autobind

+
+ + Model: JXD 509 is using Q282 with CH12=Start/Stop motors

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH12CH14
AETRFLIPLEDPICTUREVIDEOHEADLESSRTHXCALYCALReset/Bind
+

Close

+ +
+

CX10

+

JC3015_1

+ Autobind

+
+ + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH14
AETRFLIPMODEPICTUREVIDEOReset/Bind
+

Close

+ +
+

CX10

+

JC3015_2

+ Autobind

+
+ + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH14
AETRFLIPMODELEDDFLIPReset/Bind
+

Close

+ +
+

CX10

+

MK33041

+ Autobind

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH14
AETRFLIPMODEPICTUREVIDEOHEADLESSRTHReset/Bind
+

Close

+ +
+

CX10

+

Q242

+ Autobind

+
+ + Model: JXD 509 is using Q282 with CH12=Start/Stop motors

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH12CH14
AETRFLIPLEDPICTUREVIDEOHEADLESSRTHXCALYCALReset/Bind
+

Close

+ +
+

CG023

+

CG023

+ Autobind

+ Modèle : EAchine CG023/CG031/3D X4
+ + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH14
AETRFLIPLIGHTPICTUREVIDEOHEADLESSReset/Bind
+

Close

+ +
+

CG023

+

YD829

+ Autobind

+ Modèle : Attop YD-822/YD-829/YD-829C ...
+ + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH14
AETRFLIPPICTUREVIDEOHEADLESSReset/Bind
+

Close

+ +
+

CG023

+

H8_3D

+ Autobind

+ Modèle : EAchine H8 mini 3D, JJRC H20/H22
+ + JJRC H20: OPT1=Headless, OPT2=RTH
JJRC H22: OPT1=RTH, OPT2=180/360° flip mode
H8 3D: OPT1=RTH then press a direction to enter headless mode (like stock TX), OPT2=switch 180/360° flip mode
CAL: calibrate accelerometers

+ + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH14
AETRFLIPLIGTHOPT1OPT2CALReset/Bind
+

Close

+ +
+

BAYANG

+

. . . . .

+ Autobind

+ Modèle : EAchine H8(C) mini, BayangToys X6/X7/X9, JJRC JJ850, Floureon H101 ...
+ + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH14
AETRFLIPRTHPICTUREVIDEOHEADLESSINVERTEDReset/Bind
+

Close

+ +
+

FRSKYX

+

CH_16

+

+ Modèle : FrSky receivers X4R, X6R and X8R.
+ Option : fine frequency tuning. This value is different +for each board. To determine the option value, find the two limits where + the RX loses connection then set the option value to half way between +them. If you have a 4in1 V2 board the value is around 40.
+ Extended limits supported
Telemetry enabled for A1 (RxBatt), A2, RSSI, TSSI and Hub

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH12CH13CH14CH15CH16
-------------------------------------------------------
+

Close

+ +
+

FRSKYX

+

CH_8

+

+
+ + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8
------------------------
+

Close

+ +
+

ESKY

+

. . . . .

+

+
+ + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH14
AETRGYROPITCHReset/Bind
+

Close

+ +
+

MT99XX

+

MT99

+ Autobind

+
+ + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH14
AETRFLIPLEDPICTUREVIDEOHEADLESSReset/Bind
+

Close

+ +
+

MT99XX

+

H7

+ Autobind

+ Modèle : Eachine H7, Cheerson CX023
+ + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH14
AETRFLIPLEDPICTUREVIDEOHEADLESSReset/Bind
+

Close

+ +
+

MT99XX

+

YZ

+ Autobind

+
+ + Model: Yi Zhan i6S
Only one model can be flown at the same time since the ID is hardcoded.

+ + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH14
AETRFLIPLEDPICTUREVIDEOHEADLESSReset/Bind
+

Close

+ +
+

MT99XX

+

LS

+ Autobind

+ Modèle : LS114, 124, 215
+ + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH14
AETRFLIPINVERTPICTUREVIDEOHEADLESSReset/Bind
+

Close

+ +
+

MJXQ

+

WLH08

+ Autobind

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH12CH13CH14
AETRFLIPLEDPICTUREVIDEOHEADLESSRTHAUTOFLIPPANTILTReset/Bind
+

Close

+ +
+

MJXQ

+

X600

+ Autobind

+
+ + Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH12CH13CH14
AETRFLIPLEDPICTUREVIDEOHEADLESSRTHAUTOFLIPPANTILTReset/Bind
+

Close

+ +
+

MJXQ

+

X800

+ Autobind

+
+ + Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH12CH13CH14
AETRFLIPLEDPICTUREVIDEOHEADLESSRTHAUTOFLIPPANTILTReset/Bind
+

Close

+ +
+

MJXQ

+

H26D

+ Autobind

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH12CH13CH14
AETRFLIPLEDPICTUREVIDEOHEADLESSRTHAUTOFLIPPANTILTReset/Bind
+

Close

+ +
+

MJXQ

+

E010

+ Autobind

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH12CH13CH14
AETRFLIPLEDPICTUREVIDEOHEADLESSRTHAUTOFLIPPANTILTReset/Bind
+

Close

+ +
+

SHENQI

+

. . . . .

+ Autobind

+
+ + Model: Shenqiwei 1/20 Mini Motorcycle
Throttle +100%=full forward,0%=stop,-100%=full backward.

+ + + + + + + + + + + +
CH1CH2CH3CH4CH14
TRReset/Bind
+

Close

+ +
+

FY326

+

FY326

+

+
+ + Autobind

+ + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH14
AETRFLIPHEADLESSRTHCalibrateExpertReset/Bind
+

Close

+ +
+

FY326

+

FY319

+

+
+ + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH14
AETRFLIPHEADLESSRTHCalibrateExpertReset/Bind
+

Close

+ +
+

SFHSS

+

. . . . .

+

+ Modèle : Futaba RXs and XK models.
+ Option : fine frequency tuning. This value is different +for each board. To determine the option value, find the two limits where + the RX loses connection then set the option value to half way between +them. If you have a 4in1 V2 board the value is around 40.
+ ***

+ + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH14
AETRCH5CH6CH7CH8Reset/Bind
+

Close

+ +
+

J6PRO

+

. . . . .

+

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH12CH14
------------------------------------Reset/Bind
+

Close

+ +
+

FQ777

+

. . . . .

+

+
+ + Model: FQ777-124

+ + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH14
AETRFLIPRTHHEADLESSEXPERTReset/Bind
+

Close

+ +
+

ASSAN

+

. . . . .

+

+
+ + Extended limits supported
The transmitter must be close to the receiver while binding.

+ + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH14
------------------------------Reset/Bind
+

Close

+ +
+

FRSKYV

+

. . . . .

+

+ Modèle : FrSky receivers V8R4, V8R7 and V8FR.
+ Option : fine frequency tuning. This value is different +for each board. To determine the option value, find the two limits where + the RX loses connection then set the option value to half way between +them. If you have a 4in1 V2 board the value is around 40.
+ Extended limits supported

+ + + + + + + + + +
CH1CH2CH3CH4
------------
+

Close

+ +
+

HONTAI

+

HONTAI

+

+
+ + Autobind protocol

+ + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH14
AETRFLIPLEDPICTUREVIDEOHEADLESSRTHCALReset/Bind
+

Close

+ +
+

HONTAI

+

JJRCX1

+

+
+ + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH6CH0CH14
AETRARMReset/Bind
+

Close

+ +
+

HONTAI

+

X5C1

+

+
+ + X5C1 clone

+ + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH14
AETRFLIPLEDPICTUREVIDEOHEADLESSRTHCALReset/Bind
+

Close

+ +
+

HONTAI

+

FQ777

+

+
+ + Format FQ777-951C

+ + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH6CH7CH8CH9CH14
AETRFLIPSNAPSHOTVIDEOHEADLESSReset/Bind
+

Close

+ +
+

OPENLRS

+

. . . . .

+

+
+ + Empty protocol

+ +
+

Close

+ +
+

JOYSWAY

+

. . . . .

+

+
+ + + + + + + + + + + + + +
CH1CH2CH3CH4CH14
AETRReset/Bind
+

Close

+ +
+

WK2X01

+

WK2801

+

+
+ + Autobind

+ + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH14
------------------------Reset/Bind
+

Close

+ +
+

WK2X01

+

WK2601

+

+
+ + Option:
0 = 5+1
2 = 6+1
..1 = Hélicoptère (. = autres options pour ce mode)
.01 = Hélicoptère normal
.11 = Hélicoptère avec pit inversé
0.1 = Pitch curve -100
1.1 = Pitch curve 100
CONF: Option 1 = Rate Throtle
Option 2 = Pitch

+ + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH14
---------------------Reset/Bind
+

Close

+ +
+

WK2X01

+

WK2401

+

+
+ + + + + + + + + + + + + +
CH1CH2CH3CH4CH14
------------Reset/Bind
+

Close

+ +
+

SKYARTEC

+

. . . . .

+

+
+ + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH14
? ? ? ? ? ? ?Reset/Bind
+

Close

+ +
+

UDI

+

U816_V1

+

+
+ + Modele: Known UDI 2.4GHz protocol variants, all using BK2421
* UDI U819 coaxial 3ch helicoper
* UDI U816/817/818 quadcopters
- "V1" with orange LED on TX, U816 RX labeled '' , U817/U818 RX labeled 'UD-U817B'
- "V2" with red LEDs on TX, U816 RX labeled '', U817/U818 RX labeled 'UD-U817OG'
- "V3" with green LEDs on TX. Did not get my hands on yet.
* U830 mini quadcopter with tilt steering ("Protocol 2014")
* U839 nano quadcopter ("Protocol 2014")
Autobind

+ + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH14
AETRFLIP 360FLIPVIDEOLEDMODE 2---Reset/Bind
+

Close

+ +
+

UDI

+

U816_V2

+

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH14
AETRFLIP 360FLIPVIDEOLEDMODE 2---Reset/Bind
+

Close

+ +
+

UDI

+

U839_2014

+

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH14
AETRFLIP 360FLIPVIDEOLEDMODE 2---Reset/Bind
+

Close

+ +
+

FBL100

+

FBL100

+

+
+ + Autobind

+ + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH14
? ? ? ? ? ? ? ?Reset/Bind
+

Close

+ +
+

FBL100

+

HP100

+

+
+ + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH14
? ? ? ? ? ? ? ?Reset/Bind
+

Close

+ +
+

HM830

+

. . . . .

+

+
+ + Modele: HM Hobby HM830 RC Paper Airplane
Autobind

+ + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH14
ATurboTTrimBoutonReset/Bind
+

Close

+ +
+

CFLIE

+

. . . . .

+

+
+ + Modele: CrazyFlie Nano quad
Autobind

+ + + + + + + + + + + +
CH1CH2CH3CH4CH14
AETRReset/Bind
+

Close

+ +
+

H377

+

. . . . .

+

+
+ + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH14
AETRCH5CH6CH7CH8Reset/Bind
+

Close

+ +
+

ESKY150

+

. . . . .

+

+
+ + Autobind

+ + + + + + + + + + + +
CH1CH2CH3CH4CH14
AETRReset/Bind
+

Close

+ +
+

BLUEFLY

+

. . . . .

+

+
+ + Autobind

+ + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH14
AETRGEARPITCHReset/Bind
+

Close

+ +
+

NE260

+

. . . . .

+

+
+ + Modele: Nine Eagles SoloPro
Autobind

+ + + + + + + + + + + +
CH1CH2CH3CH4CH14
AETRReset/Bind
+

Close

+ +
+

AFHDS2A

+

. . . . .

+

+
+ + Telemetry enabled for battery voltage and TX RSSI
Option= 0-PWM_IBUS 1-PPM_IBUS 2-PWM_SBUS 3-PPM_SBUS

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CH1CH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH12CH13CH14CH15
TCH2CH3CH4CH5CH6CH7CH8CH9CH10CH11CH12CH13CH14Failsave T
+

Close

+ +
+

INAV

+

. . . . .

+

+
+ + En cours de passage

+ + + +
CH14
Reset/Bind
+

Close

+ +
+
+

LUA Script       Close

+ +

Liste Protocoles       Close

+ +
+ \ No newline at end of file diff --git a/Multiprotocol/MJXQ_nrf24l01.ino b/Multiprotocol/MJXQ_nrf24l01.ino index a1cb14a..ae95060 100644 --- a/Multiprotocol/MJXQ_nrf24l01.ino +++ b/Multiprotocol/MJXQ_nrf24l01.ino @@ -12,11 +12,7 @@ You should have received a copy of the GNU General Public License along with Multiprotocol. If not, see . */ -<<<<<<< HEAD -// compatible with MJX WLH08, X600, X800, H26D -======= // compatible with MJX WLH08, X600, X800, H26D, Eachine E010 ->>>>>>> refs/remotes/pascallanger/master // Last sync with hexfet new_protocols/mjxq_nrf24l01.c dated 2016-01-17 #if defined(MJXQ_NRF24L01_INO) @@ -30,8 +26,6 @@ #define MJXQ_RF_NUM_CHANNELS 4 #define MJXQ_ADDRESS_LENGTH 5 -<<<<<<< HEAD -======= // haven't figured out txid<-->rf channel mapping for MJX models const uint8_t PROGMEM MJXQ_map_rfchan[][4] = { {0x0A, 0x46, 0x3A, 0x42}, @@ -43,7 +37,6 @@ const uint8_t PROGMEM MJXQ_map_txid[][3] = { {0x48, 0x6A, 0x40} }; ->>>>>>> refs/remotes/pascallanger/master #define MJXQ_PAN_TILT_COUNT 16 // for H26D - match stock tx timing #define MJXQ_PAN_DOWN 0x08 #define MJXQ_PAN_UP 0x04 @@ -57,16 +50,6 @@ static uint8_t __attribute__((unused)) MJXQ_pan_tilt_value() packet_count++; if(packet_count & MJXQ_PAN_TILT_COUNT) { -<<<<<<< HEAD - if(Servo_AUX8) - pan=MJXQ_PAN_UP; - if(Servo_data[AUX8]PPM_MIN_COMMAND) - pan=MJXQ_TILT_UP; - if(Servo_data[AUX9]PPM_MAX_COMMAND) pan=MJXQ_PAN_UP; if(Servo_data[AUX8]>>>>>> refs/remotes/pascallanger/master } return pan; } @@ -86,17 +68,10 @@ 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 -<<<<<<< HEAD - 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[2] = 0x80 ^ convert_channel_s8b(ELEVATOR); packet[5] = GET_FLAG(Servo_AUX5, 1) ? 0x40 : MJXQ_CHAN2TRIM(packet[2]); // trim elevator packet[3] = convert_channel_s8b(AILERON); packet[6] = GET_FLAG(Servo_AUX5, 1) ? 0x40 : MJXQ_CHAN2TRIM(packet[3]); // trim aileron ->>>>>>> refs/remotes/pascallanger/master packet[7] = rx_tx_addr[0]; packet[8] = rx_tx_addr[1]; packet[9] = rx_tx_addr[2]; @@ -121,10 +96,7 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind) packet[10]=MJXQ_pan_tilt_value(); // fall through on purpose - no break case WLH08: -<<<<<<< HEAD -======= case E010: ->>>>>>> refs/remotes/pascallanger/master packet[10] += GET_FLAG(Servo_AUX6, 0x02) //RTH | GET_FLAG(Servo_AUX5, 0x01); //HEADLESS if (!bind) @@ -137,14 +109,6 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind) } break; case X600: -<<<<<<< HEAD - if(Servo_AUX5) //HEADLESS - { // driven trims cause issues when headless is enabled - packet[5] = 0x40; - packet[6] = 0x40; - } -======= ->>>>>>> refs/remotes/pascallanger/master packet[10] = GET_FLAG(!Servo_AUX2, 0x02); //LED packet[11] = GET_FLAG(Servo_AUX6, 0x01); //RTH if (!bind) @@ -178,11 +142,7 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind) if (sub_protocol == H26D) NRF24L01_SetTxRxMode(TX_EN); else -<<<<<<< HEAD - XN297_Configure(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP)); -======= XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); ->>>>>>> refs/remotes/pascallanger/master NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++ / 2]); hopping_frequency_no %= 2 * MJXQ_RF_NUM_CHANNELS; // channels repeated @@ -205,20 +165,12 @@ static void __attribute__((unused)) MJXQ_init() if (sub_protocol == WLH08) memcpy(hopping_frequency, "\x12\x22\x32\x42", MJXQ_RF_NUM_CHANNELS); else -<<<<<<< HEAD - if (sub_protocol == H26D) -======= if (sub_protocol == H26D || sub_protocol == E010) ->>>>>>> refs/remotes/pascallanger/master memcpy(hopping_frequency, "\x36\x3e\x46\x2e", MJXQ_RF_NUM_CHANNELS); else { memcpy(hopping_frequency, "\x0a\x35\x42\x3d", MJXQ_RF_NUM_CHANNELS); -<<<<<<< HEAD - memcpy(addr, "\x6d\x6a\x73\x73\x73", MJXQ_RF_NUM_CHANNELS); -======= memcpy(addr, "\x6d\x6a\x73\x73\x73", MJXQ_ADDRESS_LENGTH); ->>>>>>> refs/remotes/pascallanger/master } @@ -237,53 +189,25 @@ static void __attribute__((unused)) MJXQ_init() 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) -<<<<<<< HEAD - NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps -======= if (sub_protocol == E010) NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250K else NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps ->>>>>>> refs/remotes/pascallanger/master NRF24L01_SetPower(); } static void __attribute__((unused)) MJXQ_init2() { -<<<<<<< HEAD - // 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); -======= if (sub_protocol == H26D) memcpy(hopping_frequency, "\x32\x3e\x42\x4e", MJXQ_RF_NUM_CHANNELS); else if (sub_protocol != WLH08 && sub_protocol != E010) for(uint8_t i=0;i>>>>>> refs/remotes/pascallanger/master } static void __attribute__((unused)) MJXQ_initialize_txid() { -<<<<<<< HEAD - // 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); -======= rx_tx_addr[0]&=0xF8; if (sub_protocol == E010) { @@ -293,7 +217,6 @@ static void __attribute__((unused)) MJXQ_initialize_txid() else for(uint8_t i=0;i<3;i++) rx_tx_addr[i]=pgm_read_byte_near( &MJXQ_map_txid[rx_tx_addr[4]%3][i] ); ->>>>>>> refs/remotes/pascallanger/master } uint16_t MJXQ_callback() diff --git a/Multiprotocol/MT99xx_nrf24l01.ino b/Multiprotocol/MT99xx_nrf24l01.ino index dff51d7..4fb2d65 100644 --- a/Multiprotocol/MT99xx_nrf24l01.ino +++ b/Multiprotocol/MT99xx_nrf24l01.ino @@ -12,11 +12,7 @@ You should have received a copy of the GNU General Public License along with Multiprotocol. If not, see . */ -<<<<<<< HEAD -// compatible with MT99xx, Eachine H7, Yi Zhan i6S -======= // compatible with MT99xx, Eachine H7, Yi Zhan i6S and LS114/124 ->>>>>>> refs/remotes/pascallanger/master // Last sync with Goebish mt99xx_nrf24l01.c dated 2016-01-29 #if defined(MT99XX_NRF24L01_INO) @@ -41,8 +37,6 @@ enum{ FLAG_MT_FLIP = 0x80, }; -<<<<<<< HEAD -======= enum{ // flags going to packet[6] (LS) FLAG_LS_INVERT = 0x01, @@ -53,43 +47,12 @@ enum{ FLAG_LS_FLIP = 0x80, }; ->>>>>>> refs/remotes/pascallanger/master enum { MT99XX_INIT = 0, MT99XX_BIND, MT99XX_DATA }; -<<<<<<< HEAD -static void __attribute__((unused)) MT99XX_send_packet() -{ - const uint8_t yz_p4_seq[] = {0xa0, 0x20, 0x60}; - 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] = 0x20; // pitch trim (0x3f-0x20-0x00) - packet[5] = 0x20; // 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]; -======= const uint8_t h7_mys_byte[] = { 0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 0x04, 0x14, 0x05, 0x15, 0x06, 0x16, 0x07, 0x17, 0x00, 0x10 @@ -138,7 +101,6 @@ static void __attribute__((unused)) MT99XX_send_packet() ls_counter=0; } ->>>>>>> refs/remotes/pascallanger/master uint8_t result=checksum_offset; for(uint8_t i=0; i<8; i++) result += packet[i]; @@ -147,15 +109,9 @@ static void __attribute__((unused)) MT99XX_send_packet() else { // YZ packet[0] = convert_channel_8b_scale(THROTTLE,0x00,0x64); // throttle -<<<<<<< HEAD - 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 -======= packet[1] = convert_channel_8b_scale(RUDDER ,0x64,0x00); // rudder packet[2] = convert_channel_8b_scale(ELEVATOR,0x00,0x64); // elevator packet[3] = convert_channel_8b_scale(AILERON ,0x64,0x00); // aileron ->>>>>>> refs/remotes/pascallanger/master if(packet_count++ >= 23) { yz_seq_num ++; @@ -176,14 +132,10 @@ static void __attribute__((unused)) MT99XX_send_packet() packet[8] = 0xff; } -<<<<<<< HEAD - NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no] + channel_offset); -======= if(sub_protocol == LS) NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x2D); // LS always transmits on the same channel else NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no] + channel_offset); ->>>>>>> refs/remotes/pascallanger/master NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); NRF24L01_FlushTx(); XN297_WritePayload(packet, MT99XX_PACKET_SIZE); @@ -201,16 +153,11 @@ static void __attribute__((unused)) MT99XX_send_packet() static void __attribute__((unused)) MT99XX_init() { NRF24L01_Initialize(); -<<<<<<< HEAD - NRF24L01_SetTxRxMode(TX_EN); - NRF24L01_FlushTx(); -======= if(sub_protocol == YZ) XN297_SetScrambledMode(XN297_UNSCRAMBLED); NRF24L01_SetTxRxMode(TX_EN); NRF24L01_FlushTx(); XN297_SetTXAddr((uint8_t *)"\xCC\xCC\xCC\xCC\xCC", 5); ->>>>>>> refs/remotes/pascallanger/master 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 @@ -222,31 +169,18 @@ static void __attribute__((unused)) MT99XX_init() NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps NRF24L01_SetPower(); -<<<<<<< HEAD - XN297_Configure(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP) | (sub_protocol == YZ ? BV(XN297_UNSCRAMBLED):0) ); - - XN297_SetTXAddr((uint8_t *)"\xCC\xCC\xCC\xCC\xCC", 5); -======= XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) ); ->>>>>>> refs/remotes/pascallanger/master } static void __attribute__((unused)) MT99XX_initialize_txid() { -<<<<<<< HEAD -======= rx_tx_addr[3] = 0xCC; rx_tx_addr[4] = 0xCC; ->>>>>>> refs/remotes/pascallanger/master if(sub_protocol == YZ) { rx_tx_addr[0] = 0x53; // test (SB id) rx_tx_addr[1] = 0x00; -<<<<<<< HEAD - } - checksum_offset = (rx_tx_addr[0] + rx_tx_addr[1]) & 0xff; -======= rx_tx_addr[2] = 0x00; } else @@ -255,7 +189,6 @@ static void __attribute__((unused)) MT99XX_initialize_txid() else //MT99 & H7 rx_tx_addr[2] = 0x00; checksum_offset = rx_tx_addr[0] + rx_tx_addr[1] + rx_tx_addr[2]; ->>>>>>> refs/remotes/pascallanger/master channel_offset = (((checksum_offset & 0xf0)>>4) + (checksum_offset & 0x0f)) % 8; } @@ -267,26 +200,16 @@ uint16_t MT99XX_callback() { if (bind_counter == 0) { -<<<<<<< HEAD - rx_tx_addr[2] = 0x00; - rx_tx_addr[3] = 0xCC; - rx_tx_addr[4] = 0xCC; -======= ->>>>>>> refs/remotes/pascallanger/master // set tx address for data packets XN297_SetTXAddr(rx_tx_addr, 5); BIND_DONE; } else { -<<<<<<< HEAD - NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]); -======= if(sub_protocol == LS) NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x2D); // LS always transmits on the same channel else NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]); ->>>>>>> refs/remotes/pascallanger/master NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); NRF24L01_FlushTx(); XN297_WritePayload(packet, MT99XX_PACKET_SIZE); // bind packet @@ -313,25 +236,6 @@ uint16_t initMT99XX(void) MT99XX_init(); packet[0] = 0x20; -<<<<<<< HEAD - 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]; // 1st byte for data state tx address - packet[5] = rx_tx_addr[1]; // 2nd byte for data state tx address (always 0x00 on Yi Zhan ?) - packet[6] = 0x00; // 3rd byte for data state tx address (always 0x00 ?) -======= packet_period = MT99XX_PACKET_PERIOD_MT; switch(sub_protocol) { // MT99 & H7 @@ -356,7 +260,6 @@ uint16_t initMT99XX(void) packet[4] = rx_tx_addr[0]; packet[5] = rx_tx_addr[1]; packet[6] = rx_tx_addr[2]; ->>>>>>> refs/remotes/pascallanger/master packet[7] = checksum_offset; // checksum offset packet[8] = 0xAA; // fixed packet_count=0; diff --git a/Multiprotocol/Multiprotocol 2.zip b/Multiprotocol/Multiprotocol 2.zip new file mode 100644 index 0000000..1f14be8 Binary files /dev/null and b/Multiprotocol/Multiprotocol 2.zip differ diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino index fe73f45..7659c50 100644 --- a/Multiprotocol/Multiprotocol.ino +++ b/Multiprotocol/Multiprotocol.ino @@ -5,13 +5,8 @@ http://www.rcgroups.com/forums/showthread.php?t=2165676 https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/edit/master/README.md -<<<<<<< HEAD - Thanks to PhracturedBlue, Hexfet, Goebish and all protocol developers - Ported from deviation firmware -======= Thanks to PhracturedBlue, Hexfet, Goebish, Victzh and all protocol developers - Ported from deviation firmware ->>>>>>> refs/remotes/pascallanger/master + Ported from deviation firmware 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 @@ -26,21 +21,14 @@ You should have received a copy of the GNU General Public License along with Multiprotocol. If not, see . */ -#include + #include #include -<<<<<<< HEAD -#include -======= //#define DEBUG_TX #include "Pins.h" ->>>>>>> refs/remotes/pascallanger/master #include "Multiprotocol.h" //Multiprotocol module configuration file #include "_Config.h" -<<<<<<< HEAD - -======= #include "TX_Def.h" #ifdef XMEGA @@ -53,39 +41,29 @@ #define DSM_TELEMETRY // Enable DSM telemetry #endif ->>>>>>> refs/remotes/pascallanger/master //Global constants/variables uint32_t MProtocol_id;//tx id, uint32_t MProtocol_id_master; -uint32_t blink=0; +uint32_t blink=0; // uint16_t counter; -uint8_t channel; -uint8_t packet[40]; +uint8_t channel; +uint8_t packet[40]; #define NUM_CHN 16 // Servo data uint16_t Servo_data[NUM_CHN]; uint8_t Servo_AUX; -<<<<<<< HEAD -const uint8_t ch[]={AILERON, ELEVATOR, THROTTLE, RUDDER, AUX1, AUX2, AUX3, AUX4}; - -// Protocol variables -uint8_t rx_tx_addr[5]; -uint8_t phase; -======= uint16_t servo_max_100,servo_min_100,servo_max_125,servo_min_125; // Protocol variables uint8_t cyrfmfg_id[6];//for dsm2 and devo -uint8_t rx_tx_addr[5]; -uint8_t phase; ->>>>>>> refs/remotes/pascallanger/master +uint8_t rx_tx_addr[5]; +uint8_t phase; uint16_t bind_counter; -uint8_t bind_phase; -uint8_t binding_idx; +uint8_t bind_phase; +uint8_t binding_idx; uint16_t packet_period; -<<<<<<< HEAD uint8_t packet_count; uint8_t packet_sent; uint8_t packet_length; @@ -96,38 +74,22 @@ uint8_t rf_ch_num; uint8_t throttle, rudder, elevator, aileron; uint8_t flags; uint16_t crc; -// -uint32_t state; -uint8_t len; -uint8_t RX_num; -======= -uint8_t packet_count; -uint8_t packet_sent; -uint8_t packet_length; -uint8_t hopping_frequency[23]; -uint8_t *hopping_frequency_ptr; -uint8_t hopping_frequency_no=0; -uint8_t rf_ch_num; -uint8_t throttle, rudder, elevator, aileron; -uint8_t flags; -uint16_t crc; uint8_t crc8; uint16_t seed; // uint16_t state; -uint8_t len; -uint8_t RX_num; +uint8_t len; +uint8_t RX_num; #if defined(FRSKYX_CC2500_INO) || defined(SFHSS_CC2500_INO) uint8_t calData[48]; #endif //Channel mapping for protocols -const uint8_t CH_AETR[]={AILERON, ELEVATOR, THROTTLE, RUDDER, AUX1, AUX2, AUX3, AUX4, AUX5, AUX6, AUX7, AUX8}; -const uint8_t CH_TAER[]={THROTTLE, AILERON, ELEVATOR, RUDDER, AUX1, AUX2, AUX3, AUX4, AUX5, AUX6, AUX7, AUX8}; -const uint8_t CH_RETA[]={RUDDER, ELEVATOR, THROTTLE, AILERON, AUX1, AUX2, AUX3, AUX4, AUX5, AUX6, AUX7, AUX8}; -const uint8_t CH_EATR[]={ELEVATOR, AILERON, THROTTLE, RUDDER, AUX1, AUX2, AUX3, AUX4, AUX5, AUX6, AUX7, AUX8}; ->>>>>>> refs/remotes/pascallanger/master + const uint8_t CH_AETR[]={AILERON, ELEVATOR, THROTTLE, RUDDER, AUX1, AUX2, AUX3, AUX4, AUX5, AUX6, AUX7, AUX8, AUX9, AUX10}; + const uint8_t CH_TAER[]={THROTTLE, AILERON, ELEVATOR, RUDDER, AUX1, AUX2, AUX3, AUX4, AUX5, AUX6, AUX7, AUX8, AUX9, AUX10}; + const uint8_t CH_RETA[]={RUDDER, ELEVATOR, THROTTLE, AILERON, AUX1, AUX2, AUX3, AUX4, AUX5, AUX6, AUX7, AUX8, AUX9, AUX10}; + const uint8_t CH_EATR[]={ELEVATOR, AILERON, THROTTLE, RUDDER, AUX1, AUX2, AUX3, AUX4, AUX5, AUX6, AUX7, AUX8, AUX9, AUX10}; // Mode_select variables uint8_t mode_select; @@ -136,20 +98,10 @@ uint8_t protocol_flags=0,protocol_flags2=0; // PPM variable volatile uint16_t PPM_data[NUM_CHN]; -<<<<<<< HEAD -// Serial variables -#define RXBUFFER_SIZE 25 -#define TXBUFFER_SIZE 12 -volatile uint8_t rx_buff[RXBUFFER_SIZE]; -volatile uint8_t rx_ok_buff[RXBUFFER_SIZE]; -volatile uint8_t tx_buff[TXBUFFER_SIZE]; -volatile uint8_t idx = 0; -======= #ifndef XMEGA -//Random variable -volatile uint32_t gWDT_entropy=0; + //Random variable + volatile uint32_t gWDT_entropy=0; #endif ->>>>>>> refs/remotes/pascallanger/master //Serial protocol uint8_t sub_protocol; @@ -192,11 +144,6 @@ volatile uint8_t discard_frame = 0; #define MAX_PKT 27 uint8_t pkt[MAX_PKT];//telemetry receiving packets #if defined(TELEMETRY) -<<<<<<< HEAD -uint8_t pktt[MAX_PKT];//telemetry receiving packets - volatile uint8_t tx_head; - volatile uint8_t tx_tail; -======= #ifdef INVERT_TELEMETRY // enable bit bash for serial #ifndef XMEGA @@ -212,7 +159,6 @@ uint8_t pktt[MAX_PKT];//telemetry receiving packets volatile uint8_t tx_head=0; volatile uint8_t tx_tail=0; #endif // BASH_SERIAL ->>>>>>> refs/remotes/pascallanger/master uint8_t v_lipo; int16_t RSSI_dBm; //const uint8_t RSSI_offset=72;//69 71.72 values db @@ -244,11 +190,11 @@ void setup() TCC1.PER = 0xFFFF ; TCNT1 = 0 ; TCC1.CTRLA = 0x0B ; // Event3 (prescale of 16) - #else + #else // General pinout // all inputs DDRB=0x00;DDRC=0x00;DDRD=0x00; - // outputs + // outputs SDI_output; SCLK_output; #ifdef A7105_INSTALLED @@ -268,12 +214,12 @@ void setup() PE2_output; SERIAL_TX_output; - // pullups + //pullup on dial (D10=PB2,D11=PB3,D12=PB4) and bind button MODE_DIAL1_port |= _BV(MODE_DIAL1_pin); MODE_DIAL2_port |= _BV(MODE_DIAL2_pin); MODE_DIAL3_port |= _BV(MODE_DIAL3_pin); MODE_DIAL4_port |= _BV(MODE_DIAL4_pin); - BIND_port |= _BV(BIND_pin); + BIND_port |= _BV(BIND_pin); // Timer1 config TCCR1A = 0; @@ -284,19 +230,6 @@ void setup() #endif // Set Chip selects -<<<<<<< HEAD - CS_on; - CC25_CSN_on; - NRF_CSN_on; - CYRF_CSN_on; - // Set SPI lines - SDI_on; - SCK_off; - - // Timer1 config - TCCR1A = 0; - TCCR1B = (1 << CS11); //prescaler8, set timer1 to increment every 0.5us(16Mhz) and start timer -======= #ifdef A7105_INSTALLED A7105_CSN_on; #endif @@ -309,63 +242,32 @@ void setup() #ifdef NRF24L01_INSTALLED NRF_CSN_on; #endif - // Set SPI lines + // Set SPI lines SDI_on; SCLK_off; ->>>>>>> refs/remotes/pascallanger/master // Set servos positions for(uint8_t i=0;i>2)&0x07 ) | ( (PINC<<3)&0x08) );//encoder dip switches 1,2,4,8=>B2,B3,B4,C0 - //********************************** -//mode_select=1; // here to test PPM - //********************************** - - // Update LED - LED_OFF; - LED_SET_OUTPUT; - - // Read or create protocol id - MProtocol_id_master=random_id(10,false); - - //Init RF modules - #ifdef CC2500_INSTALLED - CC2500_Reset(); - #endif - -======= Servo_data[THROTTLE]=servo_min_100; #ifdef ENABLE_PPM memcpy((void *)PPM_data,Servo_data, sizeof(Servo_data)); #endif - + //Wait for every component to start delayMilliseconds(100); // Read status of bind button if( IS_BIND_BUTTON_on ) - BIND_BUTTON_FLAG_on; // If bind button pressed save the status for protocol id reset under hubsan + BIND_BUTTON_FLAG_on; // If bind button pressed save the status for protocol id reset under hubsan // Read status of mode select binary switch // after this mode_select will be one of {0000, 0001, ..., 1111} #ifndef ENABLE_PPM mode_select = MODE_SERIAL ; // force serial mode #else - mode_select = +// mode_select=0x0F - ( ( (PINB>>2)&0x07 ) | ( (PINC<<3)&0x08) );//encoder dip switches 1,2,4,8=>B2,B3,B4,C0 + mode_select = ((MODE_DIAL1_ipr & _BV(MODE_DIAL1_pin)) ? 0 : 1) + ((MODE_DIAL2_ipr & _BV(MODE_DIAL2_pin)) ? 0 : 2) + ((MODE_DIAL3_ipr & _BV(MODE_DIAL3_pin)) ? 0 : 4) + @@ -379,66 +281,50 @@ void setup() //Init RF modules modules_reset(); -#ifndef XMEGA - //Init the seed with a random value created from watchdog timer for all protocols requiring random values - randomSeed(random_value()); -#endif + #ifndef XMEGA + //Init the seed with a random value created from watchdog timer for all protocols requiring random values + randomSeed(random_value()); + #endif // Read or create protocol id MProtocol_id_master=random_id(10,false); + + #ifdef ENABLE_PPM + //Protocol and interrupts initialization + if(mode_select != MODE_SERIAL) + { // PPM + mode_select--; + protocol = PPM_prot[mode_select].protocol; + cur_protocol[1] = protocol; + sub_protocol = PPM_prot[mode_select].sub_proto; + RX_num = PPM_prot[mode_select].rx_num; + MProtocol_id = RX_num + MProtocol_id_master; + option = PPM_prot[mode_select].option; + if(PPM_prot[mode_select].power) POWER_FLAG_on; + if(PPM_prot[mode_select].autobind) AUTOBIND_FLAG_on; + mode_select++; + servo_max_100=PPM_MAX_100; servo_min_100=PPM_MIN_100; + servo_max_125=PPM_MAX_125; servo_min_125=PPM_MIN_125; -#ifdef ENABLE_PPM ->>>>>>> refs/remotes/pascallanger/master - //Protocol and interrupts initialization - if(mode_select != MODE_SERIAL) - { // PPM - mode_select--; -<<<<<<< HEAD - cur_protocol[0] = PPM_prot[mode_select].protocol; -======= - protocol = PPM_prot[mode_select].protocol; - cur_protocol[1] = protocol; ->>>>>>> refs/remotes/pascallanger/master - sub_protocol = PPM_prot[mode_select].sub_proto; - RX_num = PPM_prot[mode_select].rx_num; - MProtocol_id = RX_num + MProtocol_id_master; - option = PPM_prot[mode_select].option; - if(PPM_prot[mode_select].power) POWER_FLAG_on; - if(PPM_prot[mode_select].autobind) AUTOBIND_FLAG_on; - mode_select++; -<<<<<<< HEAD - - protocol_init(); - - //Configure PPM interrupt - EICRA |=(1<>>>>>> refs/remotes/pascallanger/master - #endif - } - else -#endif //ENABLE_PPM + #if defined(TELEMETRY) + PPM_Telemetry_serial_init(); // Configure serial for telemetry + #endif + } + else + #endif //ENABLE_PPM { // Serial #ifdef ENABLE_SERIAL for(uint8_t i=0;i<3;i++) @@ -454,40 +340,7 @@ void setup() // Main // Protocol scheduler void loop() -<<<<<<< HEAD { - if(mode_select==MODE_SERIAL && IS_RX_FLAG_on) // Serial mode and something has been received - { - update_serial_data(); // Update protocol and data - update_aux_flags(); - if(IS_CHANGE_PROTOCOL_FLAG_on) - { // Protocol needs to be changed - LED_OFF; //led off during protocol init - module_reset(); //reset previous module - protocol_init(); //init new protocol - CHANGE_PROTOCOL_FLAG_off; //done - } - } - if(mode_select!=MODE_SERIAL && IS_PPM_FLAG_on) // PPM mode and a full frame has been received - { - for(uint8_t i=0;iPPM_SWITCH && !( (cur_protocol[0]&0x1F)==MODE_FRSKYD || (cur_protocol[0]&0x1F)==MODE_DSM || (cur_protocol[0]&0x1F)==MODE_AFHDS2A ) ) { CHANGE_PROTOCOL_FLAG_on; } // Rebind voie if(IS_CHANGE_PROTOCOL_FLAG_on) { // Protocol needs to be changed LED_off; //led off during protocol init @@ -574,10 +428,9 @@ void Update_All() #endif //ENABLE_PPM update_led_status(); #if defined(TELEMETRY) - if((protocol==MODE_FRSKYD) || (protocol==MODE_HUBSAN) || (protocol==MODE_FRSKYX) || (protocol==MODE_DSM) ) + if((protocol==MODE_FRSKYD) || (protocol==MODE_HUBSAN) || (protocol==MODE_FRSKYX) || (protocol==MODE_DSM) || (protocol==MODE_AFHDS2A) ) TelemetryUpdate(); - #endif ->>>>>>> refs/remotes/pascallanger/master + #endif } // Update Servo_AUX flags based on servo AUX positions @@ -594,13 +447,8 @@ static void update_led_status(void) { if(blink>>>>>> refs/remotes/pascallanger/master + blink+=BLINK_SERIAL_TIME; //blink slowly while waiting a valid serial input else if(remote_callback == 0) { // Invalid protocol @@ -611,58 +459,17 @@ static void update_led_status(void) } else if(IS_BIND_DONE_on) -<<<<<<< HEAD - LED_OFF; //bind completed -> led on + LED_off; //bind completed -> led on else blink+=BLINK_BIND_TIME; //blink fastly during binding - LED_TOGGLE; - } -} - -// Protocol scheduler -static void CheckTimer(uint16_t (*cb)(void)) -{ - uint16_t next_callback; - uint32_t prev; - if( (TIFR1 & (1< micros()) - { // Callback did not took more than requested time for next callback - if(next_callback>32000) - { // next_callback should not be more than 32767 so we will wait here... - delayMicroseconds(next_callback-2000); - cli(); // disable global int - OCR1A=TCNT1+4000; - sei(); // enable global int - } - else - { - cli(); // disable global int - OCR1A+=next_callback*2; // set compare A for callback - sei(); // enable global int - } - TIFR1=(1< led on - else - blink+=BLINK_BIND_TIME; //blink fastly during binding LED_toggle; } } inline void tx_pause() -{ +{ #ifdef TELEMETRY - #ifdef XMEGA + #ifdef XMEGA USARTC0.CTRLA &= ~0x03 ; // Pause telemetry by disabling transmitter interrupt #else #ifndef BASH_SERIAL @@ -677,7 +484,7 @@ inline void tx_resume() #ifdef TELEMETRY if(!IS_TX_PAUSE_on) { - #ifdef XMEGA + #ifdef XMEGA cli() ; USARTC0.CTRLA = (USARTC0.CTRLA & 0xFC) | 0x01 ; // Resume telemetry by enabling transmitter interrupt sei() ; @@ -686,11 +493,10 @@ inline void tx_resume() UCSR0B |= _BV(UDRIE0); // Resume telemetry by enabling transmitter interrupt #else resumeBashSerial() ; - #endif + #endif #endif } #endif ->>>>>>> refs/remotes/pascallanger/master } // Protocol start @@ -718,229 +524,26 @@ static void protocol_init() else BIND_DONE; -<<<<<<< HEAD - CTRL1_on; //NRF24L01 antenna RF3 by default - CTRL2_off; //NRF24L01 antenna RF3 by default - - switch(cur_protocol[0]&0x1F) // Init the requested protocol - { -#if defined(HM830_NRF24L01_INO) - case MODE_HM830: - next_callback=HM830_setup(); - remote_callback = HM830_callback; - break; -#endif -#if defined(CFlie_NRF24L01_INO) - case MODE_CFLIE: - next_callback=Cflie_setup(); - remote_callback = cflie_callback; - break; -#endif -#if defined(JOYSWAY_A7105_INO) - case MODE_JOYSWAY: - next_callback=JOYSWAY_Setup(); - remote_callback = joysway_cb; - break; -#endif -#if defined(H377_NRF24L01_INO) - case MODE_H377: - next_callback=h377_setup(); - remote_callback = h377_cb; - break; -#endif -#if defined(J6PRO_CYRF6936_INO) - case MODE_J6PRO: - next_callback=j6pro_setup(); - remote_callback = j6pro_cb; - break; -#endif -#if defined(WK2x01_CYRF6936_INO) - case MODE_WK2x01: - next_callback=wk_setup(); - remote_callback = wk_cb; - break; -#endif -#if defined(ESKY150_NRF24L01_INO) - case MODE_ESKY150: - next_callback=esky150_setup(); - remote_callback = esky150_callback; - break; -#endif -#if defined(BlueFly_NRF24L01_INO) - case MODE_BlueFly: - next_callback=BlueFly_setup(); - remote_callback = bluefly_cb; - break; -#endif -#if defined(HonTai_NRF24L01_INO) - case MODE_HonTai: - next_callback=ht_setup(); - remote_callback = ht_callback; - break; -#endif -#if defined(UDI_NRF24L01_INO) - case MODE_UDI: - next_callback=UDI_setup(); - remote_callback = UDI_callback; - break; -#endif -#if defined(NE260_NRF24L01_INO) - case MODE_NE260: - next_callback=NE260_setup(); - remote_callback = ne260_cb; - break; -#endif -#if defined(SKYARTEC_CC2500_INO) - case MODE_SKYARTEC: - next_callback=skyartec_setup(); - remote_callback = skyartec_cb; - break; -#endif -#if defined(FBL100_NRF24L01_INO) - case MODE_FBL100: - next_callback=fbl_setup(); - remote_callback = ne260_cb; - break; -#endif - -#if defined(FLYSKY_A7105_INO) - case MODE_FLYSKY: - CTRL1_off; //antenna RF1 - next_callback = initFlySky(); - remote_callback = ReadFlySky; - break; -#endif -#if defined(HUBSAN_A7105_INO) - case MODE_HUBSAN: - CTRL1_off; //antenna RF1 - if(IS_BIND_BUTTON_FLAG_on) random_id(10,true); // Generate new ID if bind button is pressed. - next_callback = initHubsan(); - remote_callback = ReadHubsan; - break; -#endif -#if defined(FRSKY_CC2500_INO) - case MODE_FRSKY: - CTRL1_off; //antenna RF2 - CTRL2_on; - next_callback = initFrSky_2way(); - remote_callback = ReadFrSky_2way; - break; -#endif -#if defined(FRSKYX_CC2500_INO) - case MODE_FRSKYX: - CTRL1_off; //antenna RF2 - CTRL2_on; - next_callback = initFrSkyX(); - remote_callback = ReadFrSkyX; - break; -#endif -#if defined(DSM2_CYRF6936_INO) - case MODE_DSM2: - CTRL2_on; //antenna RF4 - next_callback = initDsm2(); - //Servo_data[2]=1500;//before binding - remote_callback = ReadDsm2; - break; -#endif -#if defined(DEVO_CYRF6936_INO) - case MODE_DEVO: - CTRL2_on; //antenna RF4 - next_callback = DevoInit(); - remote_callback = devo_callback; - break; -#endif -#if defined(HISKY_NRF24L01_INO) - case MODE_HISKY: - next_callback=initHiSky(); - remote_callback = hisky_cb; - break; -#endif -#if defined(V2X2_NRF24L01_INO) - case MODE_V2X2: - next_callback = initV2x2(); - remote_callback = ReadV2x2; - break; -#endif -#if defined(YD717_NRF24L01_INO) - case MODE_YD717: - next_callback=initYD717(); - remote_callback = yd717_callback; - break; -#endif -#if defined(KN_NRF24L01_INO) - case MODE_KN: - next_callback = initKN(); - remote_callback = kn_callback; - break; -#endif -#if defined(SYMAX_NRF24L01_INO) - case MODE_SYMAX: - next_callback = initSymax(); - remote_callback = symax_callback; - break; -#endif -#if defined(SLT_NRF24L01_INO) - case MODE_SLT: - next_callback=initSLT(); - remote_callback = SLT_callback; - break; -#endif -#if defined(CX10_NRF24L01_INO) - case MODE_CX10: - next_callback=initCX10(); - remote_callback = CX10_callback; - break; -#endif -#if defined(CG023_NRF24L01_INO) - case MODE_CG023: - next_callback=initCG023(); - remote_callback = CG023_callback; - break; -#endif -#if defined(BAYANG_NRF24L01_INO) - case MODE_BAYANG: - next_callback=initBAYANG(); - remote_callback = BAYANG_callback; - break; -#endif -#if defined(ESKY_NRF24L01_INO) - case MODE_ESKY: - next_callback=initESKY(); - remote_callback = ESKY_callback; - break; -#endif -#if defined(MT99XX_NRF24L01_INO) - case MODE_MT99XX: - next_callback=initMT99XX(); - remote_callback = MT99XX_callback; - break; -#endif -#if defined(MJXQ_NRF24L01_INO) - case MODE_MJXQ: - next_callback=initMJXQ(); - remote_callback = MJXQ_callback; - break; -#endif -#if defined(SHENQI_NRF24L01_INO) - case MODE_SHENQI: - next_callback=initSHENQI(); - remote_callback = SHENQI_callback; - break; -#endif -#if defined(FY326_NRF24L01_INO) - case MODE_FY326: - next_callback=initFY326(); - remote_callback = FY326_callback; - break; -#endif - } -======= PE1_on; //NRF24L01 antenna RF3 by default - PE2_off; //NRF24L01 antenna RF3 by default - + PE2_off; //NRF24L01 antenna RF3 by default + switch(protocol) // Init the requested protocol { + #ifdef A7105_INSTALLED + #if defined(JOYSWAY_A7105_INO) + case MODE_JOYSWAY: + next_callback=JOYSWAY_Setup(); + remote_callback = joysway_cb; + break; + #endif + #if defined(AFHDS2A_A7105_INO) + case MODE_AFHDS2A: + next_callback=AFHDS2A_setup(); + remote_callback = afhds2a_cb; + break; + #endif + #if defined(FLYSKY_A7105_INO) case MODE_FLYSKY: PE1_off; //antenna RF1 @@ -958,6 +561,13 @@ static void protocol_init() #endif #endif #ifdef CC2500_INSTALLED + #if defined(SKYARTEC_CC2500_INO) + case MODE_SKYARTEC: + next_callback=skyartec_setup(); + remote_callback = skyartec_cb; + break; + #endif + #if defined(FRSKYD_CC2500_INO) case MODE_FRSKYD: PE1_off; //antenna RF2 @@ -992,6 +602,13 @@ static void protocol_init() #endif #endif #ifdef CYRF6936_INSTALLED + #if defined(WK2x01_CYRF6936_INO) + case MODE_WK2x01: + next_callback=wk_setup(); + remote_callback = wk_cb; + break; + #endif + #if defined(DSM_CYRF6936_INO) case MODE_DSM: PE2_on; //antenna RF4 @@ -1031,6 +648,61 @@ static void protocol_init() #endif #endif #ifdef NRF24L01_INSTALLED + #if defined(HM830_NRF24L01_INO) + case MODE_HM830: + next_callback=HM830_setup(); + remote_callback = HM830_callback; + break; + #endif + #if defined(CFlie_NRF24L01_INO) + case MODE_CFLIE: + next_callback=Cflie_setup(); + remote_callback = cflie_callback; + break; + #endif + #if defined(H377_NRF24L01_INO) + case MODE_H377: + next_callback=h377_setup(); + remote_callback = h377_cb; + break; + #endif + #if defined(ESKY150_NRF24L01_INO) + case MODE_ESKY150: + next_callback=esky150_setup(); + remote_callback = esky150_callback; + break; + #endif + #if defined(BlueFly_NRF24L01_INO) + case MODE_BlueFly: + next_callback=BlueFly_setup(); + remote_callback = bluefly_cb; + break; + #endif + #if defined(NE260_NRF24L01_INO) + case MODE_NE260: + next_callback=NE260_setup(); + remote_callback = ne260_cb; + break; + #endif + #if defined(UDI_NRF24L01_INO) + case MODE_UDI: + next_callback=UDI_setup(); + remote_callback = UDI_callback; + break; + #endif + #if defined(FBL100_NRF24L01_INO) + case MODE_FBL100: + next_callback=fbl_setup(); + remote_callback = ne260_cb; + break; + #endif + #if defined(INAV_NRF24L01_INO) + case MODE_INAV: + next_callback=INAV_setup(); + remote_callback = inav_cb; + break; + #endif + #if defined(HISKY_NRF24L01_INO) case MODE_HISKY: next_callback=initHiSky(); @@ -1135,85 +807,42 @@ static void protocol_init() #endif #endif } ->>>>>>> refs/remotes/pascallanger/master if(next_callback>32000) { // next_callback should not be more than 32767 so we will wait here... uint16_t temp=(next_callback>>10)-2; delayMilliseconds(temp); - next_callback-=temp<<10; // between 2-3ms left at this stage + next_callback-=temp<<10; // between 2-3ms left at this stage } -<<<<<<< HEAD cli(); // disable global int OCR1A=TCNT1+next_callback*2; // set compare A for callback sei(); // enable global int - TIFR1=(1<>>>>>> refs/remotes/pascallanger/master } void update_serial_data() { -<<<<<<< HEAD - if(rx_ok_buff[0]&0x20) //check range - RANGE_FLAG_on; - else - RANGE_FLAG_off; - if(rx_ok_buff[0]&0xC0) //check autobind(0x40) & bind(0x80) together - AUTOBIND_FLAG_on; - else - AUTOBIND_FLAG_off; - if(rx_ok_buff[1]&0x80) //if rx_ok_buff[1] ==1,power is low ,0-power high - POWER_FLAG_off; //power low - else - POWER_FLAG_on; //power high - - option=rx_ok_buff[2]; -======= RX_DONOTUPDTAE_on; - RX_FLAG_off; //data is being processed + RX_FLAG_off; //data is being processed if(rx_ok_buff[1]&0x20) //check range RANGE_FLAG_on; else - RANGE_FLAG_off; + RANGE_FLAG_off; if(rx_ok_buff[1]&0xC0) //check autobind(0x40) & bind(0x80) together AUTOBIND_FLAG_on; else AUTOBIND_FLAG_off; if(rx_ok_buff[2]&0x80) //if rx_ok_buff[2] ==1,power is low ,0-power high - POWER_FLAG_off; //power low + POWER_FLAG_off; //power low else - POWER_FLAG_on; //power high ->>>>>>> refs/remotes/pascallanger/master - + POWER_FLAG_on; //power high + option=rx_ok_buff[3]; - + if( (rx_ok_buff[0] != cur_protocol[0]) || ((rx_ok_buff[1]&0x5F) != (cur_protocol[1]&0x5F)) || ( (rx_ok_buff[2]&0x7F) != (cur_protocol[2]&0x7F) ) ) { // New model has been selected -<<<<<<< HEAD - prev_protocol=cur_protocol[0]&0x1F; //store previous protocol so we can reset the module - cur_protocol[1] = rx_ok_buff[1]&0x7F; //store current protocol - CHANGE_PROTOCOL_FLAG_on; //change protocol - sub_protocol=(rx_ok_buff[1]>>4)& 0x07; //subprotocol no (0-7) bits 4-6 - RX_num=rx_ok_buff[1]& 0x0F; - MProtocol_id=MProtocol_id_master+RX_num; //personalized RX bind + rx num // rx_num bits 0---3 - } - else - if( ((rx_ok_buff[0]&0x80)!=0) && ((cur_protocol[0]&0x80)==0) ) // Bind flag has been set - CHANGE_PROTOCOL_FLAG_on; //restart protocol with bind - cur_protocol[0] = rx_ok_buff[0]; //store current protocol - -// decode channel values - volatile uint8_t *p=rx_ok_buff+2; - uint8_t dec=-3; -======= - CHANGE_PROTOCOL_FLAG_on; //change protocol + CHANGE_PROTOCOL_FLAG_on; //change protocol protocol=(rx_ok_buff[0]==0x55?0:32) + (rx_ok_buff[1]&0x1F); //protocol no (0-63) bits 4-6 of buff[1] and bit 0 of buf[0] sub_protocol=(rx_ok_buff[2]>>4)& 0x07; //subprotocol no (0-7) bits 4-6 RX_num=rx_ok_buff[2]& 0x0F; // rx_num bits 0---3 @@ -1222,7 +851,7 @@ void update_serial_data() } else if( ((rx_ok_buff[1]&0x80)!=0) && ((cur_protocol[1]&0x80)==0) ) // Bind flag has been set - CHANGE_PROTOCOL_FLAG_on; //restart protocol with bind + CHANGE_PROTOCOL_FLAG_on; //restart protocol with bind else CHANGE_PROTOCOL_FLAG_off; //no need to restart //store current protocol values @@ -1232,68 +861,32 @@ void update_serial_data() // decode channel values volatile uint8_t *p=rx_ok_buff+3; uint8_t dec=-3; ->>>>>>> refs/remotes/pascallanger/master for(uint8_t i=0;i=8) { -<<<<<<< HEAD - dec-=8; - p++; - } - p++; - Servo_data[i]=((((*((uint32_t *)p))>>dec)&0x7FF)*5)/8+860; //value range 860<->2140 -125%<->+125% - } - RX_FLAG_off; //data has been processed -} - -static void module_reset() -{ - if(remote_callback) - { // previous protocol loaded - remote_callback = 0; - switch(prev_protocol) - { - case MODE_FLYSKY: - case MODE_HUBSAN: - A7105_Reset(); - break; - case MODE_FRSKY: - case MODE_FRSKYX: - CC2500_Reset(); - break; - case MODE_DSM2: - 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, MODE_MT99XX, MODE_MJXQ, MODE_SHENQI, MODE_FY326 - NRF24L01_Reset(); - break; - } -======= dec-=8; p++; } p++; - Servo_data[i]=((((*((uint32_t *)p))>>dec)&0x7FF)*5)/8+860; //value range 860<->2140 -125%<->+125% + Servo_data[i]=((((*((uint32_t *)p))>>dec)&0x7FF)*5)/8+860; //value range 860<->2140 -125%<->+125% } RX_DONOTUPDTAE_off; #ifdef XMEGA cli(); #else - UCSR0B &= ~_BV(RXCIE0); // RX interrupt disable + UCSR0B &= ~_BV(RXCIE0); // RX interrupt disable #endif - if(IS_RX_MISSED_BUFF_on) // If the buffer is still valid + if(IS_RX_MISSED_BUFF_on) // If the buffer is still valid { memcpy((void*)rx_ok_buff,(const void*)rx_buff,RXBUFFER_SIZE);// Duplicate the buffer - RX_FLAG_on; // data to be processed next time... + RX_FLAG_on; // data to be processed next time... RX_MISSED_BUFF_off; ->>>>>>> refs/remotes/pascallanger/master } #ifdef XMEGA sei(); #else - UCSR0B |= _BV(RXCIE0) ; // RX interrupt enable + UCSR0B |= _BV(RXCIE0) ; // RX interrupt enable #endif } @@ -1303,18 +896,18 @@ void modules_reset() CC2500_Reset(); #endif #ifdef A7105_INSTALLED - A7105_Reset(); + A7105_Reset(); #endif #ifdef CYRF6936_INSTALLED - CYRF_Reset(); + CYRF_Reset(); #endif #ifdef NRF24L01_INSTALLED - NRF24L01_Reset(); + NRF24L01_Reset(); #endif //Wait for every component to reset delayMilliseconds(100); - prev_power=0xFD; // unused power value + prev_power=0xFD; // unused power value } void Mprotocol_serial_init() @@ -1322,7 +915,7 @@ void Mprotocol_serial_init() #ifdef XMEGA PORTC.OUTSET = 0x08 ; PORTC.DIRSET = 0x08 ; - + USARTC0.BAUDCTRLA = 19 ; USARTC0.BAUDCTRLB = 0 ; @@ -1333,17 +926,17 @@ void Mprotocol_serial_init() #ifdef INVERT_TELEMETRY PORTC.PIN3CTRL |= 0x40 ; #endif - #else - #include + #else + #include UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE; UCSR0A = 0 ; // Clear X2 bit //Set frame format to 8 data bits, even parity, 2 stop bits - UCSR0C = _BV(UPM01)|_BV(USBS0)|_BV(UCSZ01)|_BV(UCSZ00); + UCSR0C = _BV(UPM01)|_BV(USBS0)|_BV(UCSZ01)|_BV(UCSZ00); while ( UCSR0A & (1 << RXC0) )//flush receive buffer UDR0; //enable reception and RC complete interrupt - UCSR0B = _BV(RXEN0)|_BV(RXCIE0);//rx enable and interrupt + UCSR0B = _BV(RXEN0)|_BV(RXCIE0);//rx enable and interrupt #ifndef DEBUG_TX #if defined(TELEMETRY) initTXSerial( SPEED_100K ) ; @@ -1353,37 +946,17 @@ void Mprotocol_serial_init() } #if defined(TELEMETRY) -void PPM_Telemetry_serial_init() -{ -<<<<<<< HEAD - if(Servo_data[ch]>PPM_MAX_100) - return PPM_MAX_100; - else - if (Servo_data[ch]>>>>>> refs/remotes/pascallanger/master -} + } #endif -<<<<<<< HEAD -#if defined(TELEMETRY) -void Serial_write(uint8_t data) -{ - cli(); // disable global int - if(++tx_head>=TXBUFFER_SIZE) - tx_head=0; - tx_buff[tx_head]=data; - sei(); // enable global int - UCSR0B |= (1<>>>>>> refs/remotes/pascallanger/master } static uint32_t random_value(void) { -<<<<<<< HEAD - #include - UBRR0H = UBRRH_VALUE; - UBRR0L = UBRRL_VALUE; - UCSR0A = 0 ; // Clear X2 bit - //Set frame format to 8 data bits, even parity, 2 stop bits - UCSR0C = (1<>>>>>> refs/remotes/pascallanger/master } #endif -#if defined(TELEMETRY) -static void PPM_Telemetry_serial_init() -{ - //9600 bauds - UBRR0H = 0x00; - UBRR0L = 0x67; - UCSR0A = 0 ; // Clear X2 bit - //Set frame format to 8 data bits, none, 1 stop bit - UCSR0C = (1<> 24) & 0xFF; - rx_tx_addr[1] = (id >> 16) & 0xFF; - rx_tx_addr[2] = (id >> 8) & 0xFF; - rx_tx_addr[3] = (id >> 0) & 0xFF; - rx_tx_addr[4] = 0xC1; // for YD717: always uses first data port -} - static uint32_t random_id(uint16_t adress, uint8_t create_new) { + #define nb_txid 5 uint32_t id; - uint8_t txid[4]; + uint8_t txid[nb_txid]; - if(eeprom_read_byte((uint8_t*)(adress+10))==0xf0 && !create_new) + if (eeprom_read_byte((uint8_t*)(adress+10))==0xf0 && !create_new) { // TXID exists in EEPROM - eeprom_read_block((void*)txid,(const void*)adress,4); + eeprom_read_block((void*)txid,(const void*)adress,nb_txid); id=(txid[0] | ((uint32_t)txid[1]<<8) | ((uint32_t)txid[2]<<16) | ((uint32_t)txid[3]<<24)); if(id!=0x2AD141A7) //ID with seed=0 return id; @@ -1467,7 +1003,7 @@ static uint32_t random_id(uint16_t adress, uint8_t create_new) txid[1] = ((id >> 8) & 0xFF); txid[2] = ((id >> 16) & 0xFF); txid[3] = ((id >> 24) & 0xFF); - eeprom_write_block((const void*)txid,(void*)adress,4); + eeprom_write_block((const void*)txid,(void*)adress,nb_txid); eeprom_write_byte((uint8_t*)(adress+10),0xf0);//write bind flag in eeprom. return id; } @@ -1479,13 +1015,6 @@ static uint32_t random_id(uint16_t adress, uint8_t create_new) /**************************/ //PPM -<<<<<<< HEAD -ISR(INT1_vect) -{ // Interrupt on PPM pin - static int8_t chan=-1; - static uint16_t Prev_TCNT1=0; - uint16_t Cur_TCNT1; -======= #ifdef ENABLE_PPM #ifdef XMEGA #if PPM_pin == 2 @@ -1504,36 +1033,22 @@ ISR(INT1_vect) static int8_t chan=-1; static uint16_t Prev_TCNT1=0; uint16_t Cur_TCNT1; ->>>>>>> refs/remotes/pascallanger/master - - Cur_TCNT1 = TCNT1 - Prev_TCNT1 ; // Capture current Timer1 value + + Cur_TCNT1=TCNT1-Prev_TCNT1; // Capture current Timer1 value if(Cur_TCNT1<1000) - chan=-1; // bad frame + chan=-1; // bad frame else if(Cur_TCNT1>4840) { - chan=0; // start of frame - PPM_FLAG_on; // full frame present (even at startup since PPM_data has been initialized) + chan=0; // start of frame + PPM_FLAG_on; // full frame present (even at startup since PPM_data has been initialized) } -<<<<<<< HEAD - Prev_TCNT1+=Cur_TCNT1; -} - -//Serial RX -ISR(USART_RX_vect) -{ // RX interrupt - if((UCSR0A&0x1C)==0) // Check frame error, data overrun and parity error - { // received byte is ok to process - if(idx==0) - { // Let's try to sync at this point - if(UDR0==0x55) // If 1st byte is 0x55 it looks ok -======= else - if(chan!=-1) // need to wait for start of frame + if(chan!=-1) // need to wait for start of frame { //servo values between 500us and 2420us will end up here PPM_data[chan]= Cur_TCNT1>>1;; if(chan++>=NUM_CHN) - chan=-1; // don't accept any new channels + chan=-1; // don't accept any new channels } Prev_TCNT1+=Cur_TCNT1; } @@ -1547,21 +1062,21 @@ ISR(USART_RX_vect) ISR(USART_RX_vect) #endif { // RX interrupt - static uint8_t idx=0; + static uint8_t idx=0; #ifdef XMEGA - if((USARTC0.STATUS & 0x1C)==0) // Check frame error, data overrun and parity error + if((USARTC0.STATUS & 0x1C)==0) // Check frame error, data overrun and parity error #else - UCSR0B &= ~_BV(RXCIE0) ; // RX interrupt disable + UCSR0B &= ~_BV(RXCIE0) ; // RX interrupt disable sei() ; - if((UCSR0A&0x1C)==0) // Check frame error, data overrun and parity error + if((UCSR0A&0x1C)==0) // Check frame error, data overrun and parity error #endif { // received byte is ok to process if(idx==0||discard_frame==1) { // Let's try to sync at this point idx=0;discard_frame=0; - RX_MISSED_BUFF_off; // If rx_buff was good it's not anymore... - rx_buff[0]=UDR0; - if((rx_buff[0]&0xFE)==0x54) // If 1st byte is 0x54 or 0x55 it looks ok + RX_MISSED_BUFF_off; // If rx_buff was good it's not anymore... + rx_buff[0]=UDR0; + if((rx_buff[0]&0xFE)==0x54) // If 1st byte is 0x54 or 0x55 it looks ok { TX_RX_PAUSE_on; tx_pause(); @@ -1572,36 +1087,35 @@ ISR(USART_RX_vect) } } else ->>>>>>> refs/remotes/pascallanger/master { - rx_buff[idx++]=UDR0; // Store received byte - if(idx>=RXBUFFER_SIZE) + rx_buff[idx++]=UDR0; // Store received byte + if(idx>=RXBUFFER_SIZE) { // A full frame has been received if(!IS_RX_DONOTUPDTAE_on) { //Good frame received and main is not working on the buffer memcpy((void*)rx_ok_buff,(const void*)rx_buff,RXBUFFER_SIZE);// Duplicate the buffer - RX_FLAG_on; // flag for main to process servo data + RX_FLAG_on; // flag for main to process servo data } else - RX_MISSED_BUFF_on; // notify that rx_buff is good - discard_frame=1; // start again + RX_MISSED_BUFF_on; // notify that rx_buff is good + discard_frame=1; // start again } } } else { - idx=UDR0; // Dummy read - discard_frame=1; // Error encountered discard full frame... + idx=UDR0; // Dummy read + discard_frame=1; // Error encountered discard full frame... } if(discard_frame==1) { - CLR_TIMSK1_OCIE1B; // Disable interrupt on compare B match + CLR_TIMSK1_OCIE1B; // Disable interrupt on compare B match TX_RX_PAUSE_off; tx_resume(); } #ifndef XMEGA cli() ; - UCSR0B |= _BV(RXCIE0) ; // RX interrupt enable + UCSR0B |= _BV(RXCIE0) ; // RX interrupt enable #endif } @@ -1613,60 +1127,34 @@ ISR(USART_RX_vect) #endif { // Timer1 compare B interrupt discard_frame=1; - CLR_TIMSK1_OCIE1B; // Disable interrupt on compare B match + CLR_TIMSK1_OCIE1B; // Disable interrupt on compare B match tx_resume(); } #endif //ENABLE_SERIAL #ifndef XMEGA - // Random interrupt service routine called every time the WDT interrupt is triggered. - // It is only enabled at startup to generate a seed. - ISR(WDT_vect) +// Random interrupt service routine called every time the WDT interrupt is triggered. +// It is only enabled at startup to generate a seed. +ISR(WDT_vect) +{ + static uint8_t gWDT_buffer_position=0; + #define gWDT_buffer_SIZE 32 + static uint8_t gWDT_buffer[gWDT_buffer_SIZE]; + gWDT_buffer[gWDT_buffer_position] = TCNT1L; // Record the Timer 1 low byte (only one needed) + gWDT_buffer_position++; // every time the WDT interrupt is triggered + if (gWDT_buffer_position >= gWDT_buffer_SIZE) { - static uint8_t gWDT_buffer_position=0; - #define gWDT_buffer_SIZE 32 - static uint8_t gWDT_buffer[gWDT_buffer_SIZE]; - gWDT_buffer[gWDT_buffer_position] = TCNT1L; // Record the Timer 1 low byte (only one needed) - gWDT_buffer_position++; // every time the WDT interrupt is triggered - if (gWDT_buffer_position >= gWDT_buffer_SIZE) + // The following code is an implementation of Jenkin's one at a time hash + for(uint8_t gWDT_loop_counter = 0; gWDT_loop_counter < gWDT_buffer_SIZE; ++gWDT_loop_counter) { - // The following code is an implementation of Jenkin's one at a time hash - for(uint8_t gWDT_loop_counter = 0; gWDT_loop_counter < gWDT_buffer_SIZE; ++gWDT_loop_counter) - { - gWDT_entropy += gWDT_buffer[gWDT_loop_counter]; - gWDT_entropy += (gWDT_entropy << 10); - gWDT_entropy ^= (gWDT_entropy >> 6); - } - gWDT_entropy += (gWDT_entropy << 3); - gWDT_entropy ^= (gWDT_entropy >> 11); - gWDT_entropy += (gWDT_entropy << 15); - WDTCSR = 0; // Disable Watchdog interrupt + gWDT_entropy += gWDT_buffer[gWDT_loop_counter]; + gWDT_entropy += (gWDT_entropy << 10); + gWDT_entropy ^= (gWDT_entropy >> 6); } + gWDT_entropy += (gWDT_entropy << 3); + gWDT_entropy ^= (gWDT_entropy >> 11); + gWDT_entropy += (gWDT_entropy << 15); + WDTCSR = 0; // Disable Watchdog interrupt } -<<<<<<< HEAD } - -//Serial timer -ISR(TIMER1_COMPB_vect) -{ // Timer1 compare B interrupt - idx=0; -} - -#if defined(TELEMETRY) -//Serial TX -ISR(USART_UDRE_vect) -{ // Transmit interrupt - uint8_t t = tx_tail; - if(tx_head!=t) - { - if(++t>=TXBUFFER_SIZE)//head - t=0; - UDR0=tx_buff[t]; - tx_tail=t; - } - if (t == tx_head) - UCSR0B &= ~(1<>>>>>> refs/remotes/pascallanger/master -#endif +#endif \ No newline at end of file diff --git a/Multiprotocol/NRF24l01_SPI.ino b/Multiprotocol/NRF24l01_SPI.ino index dc740c5..c9073e5 100644 --- a/Multiprotocol/NRF24l01_SPI.ino +++ b/Multiprotocol/NRF24l01_SPI.ino @@ -94,6 +94,14 @@ static void NRF24L01_ReadPayload(uint8_t * data, uint8_t length) data[i] = SPI_Read(); NRF_CSN_on; } +static uint8_t NRF24L01_GetDynamicPayloadSize(void) +{ + NRF_CSN_off; + SPI_Write(R_RX_PL_WID); + uint8_t res = SPI_Read(); + NRF_CSN_on; + return res; +} static void NRF24L01_Strobe(uint8_t state) { @@ -234,11 +242,7 @@ uint8_t NRF24L01_packet_ack() /////////////// // XN297 emulation layer -<<<<<<< HEAD -uint8_t xn297_scramble_enabled; -======= uint8_t xn297_scramble_enabled=XN297_SCRAMBLED; //enabled by default ->>>>>>> refs/remotes/pascallanger/master uint8_t xn297_addr_len; uint8_t xn297_tx_addr[5]; uint8_t xn297_rx_addr[5]; @@ -251,16 +255,6 @@ static const uint8_t xn297_scramble[] = { 0x1b, 0x5d, 0x19, 0x10, 0x24, 0xd3, 0xdc, 0x3f, 0x8e, 0xc5, 0x2f}; -<<<<<<< HEAD -const uint16_t PROGMEM xn297_crc_xorout[] = { - 0x0000, 0x3d5f, 0xa6f1, 0x3a23, 0xaa16, 0x1caf, - 0x62b2, 0xe0eb, 0x0821, 0xbe07, 0x5f1a, 0xaf15, - 0x4f0a, 0xad24, 0x5e48, 0xed34, 0x068c, 0xf2c9, - 0x1852, 0xdf36, 0x129d, 0xb17c, 0xd5f5, 0x70d7, - 0xb798, 0x5133, 0x67db, 0xd94e}; - -======= ->>>>>>> refs/remotes/pascallanger/master const uint16_t PROGMEM xn297_crc_xorout_scrambled[] = { 0x0000, 0x3448, 0x9BA7, 0x8BBB, 0x85E1, 0x3E8C, 0x451E, 0x18E6, 0x6B24, 0xE7AB, 0x3828, 0x814B, @@ -334,14 +328,8 @@ void XN297_SetRXAddr(const uint8_t* addr, uint8_t len) NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, buf, 5); } -void XN297_Configure(uint16_t flags) +void XN297_Configure(uint8_t flags) { -<<<<<<< HEAD - xn297_scramble_enabled = !(flags & BV(XN297_UNSCRAMBLED)); - xn297_crc = !!(flags & BV(NRF24L01_00_EN_CRC)); - flags &= ~(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO)); - NRF24L01_WriteReg(NRF24L01_00_CONFIG, flags & 0xFF); -======= xn297_crc = !!(flags & _BV(NRF24L01_00_EN_CRC)); flags &= ~(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)); NRF24L01_WriteReg(NRF24L01_00_CONFIG, flags & 0xFF); @@ -350,7 +338,6 @@ void XN297_Configure(uint16_t flags) void XN297_SetScrambledMode(const u8 mode) { xn297_scramble_enabled = mode; ->>>>>>> refs/remotes/pascallanger/master } void XN297_WritePayload(uint8_t* msg, uint8_t len) @@ -412,32 +399,6 @@ void XN297_ReadPayload(uint8_t* msg, uint8_t len) // End of XN297 emulation /////////////// -<<<<<<< HEAD -// LT8910 emulation layer -uint8_t LT8910_buffer[64]; -uint8_t LT8910_buffer_start; -uint16_t LT8910_buffer_overhead_bits; -uint8_t LT8910_addr[8]; -uint8_t LT8910_addr_size; -uint8_t LT8910_Preamble_Len; -uint8_t LT8910_Tailer_Len; -uint8_t LT8910_CRC_Initial_Data; -uint8_t LT8910_Flags; -#define LT8910_CRC_ON 6 -#define LT8910_SCRAMBLE_ON 5 -#define LT8910_PACKET_LENGTH_EN 4 -#define LT8910_DATA_PACKET_TYPE_1 3 -#define LT8910_DATA_PACKET_TYPE_0 2 -#define LT8910_FEC_TYPE_1 1 -#define LT8910_FEC_TYPE_0 0 - -void LT8910_Config(uint8_t preamble_len, uint8_t trailer_len, uint8_t flags, uint8_t crc_init) -{ - //Preamble 1 to 8 bytes - LT8910_Preamble_Len=preamble_len; - //Trailer 4 to 18 bits - LT8910_Tailer_Len=trailer_len; -======= // LT8900 emulation layer uint8_t LT8900_buffer[64]; uint8_t LT8900_buffer_start; @@ -462,37 +423,23 @@ void LT8900_Config(uint8_t preamble_len, uint8_t trailer_len, uint8_t flags, uin LT8900_Preamble_Len=preamble_len; //Trailer 4 to 18 bits LT8900_Tailer_Len=trailer_len; ->>>>>>> refs/remotes/pascallanger/master //Flags // CRC_ON: 1 on, 0 off // SCRAMBLE_ON: 1 on, 0 off // PACKET_LENGTH_EN: 1 1st byte of payload is payload size // DATA_PACKET_TYPE: 00 NRZ, 01 Manchester, 10 8bit/10bit line code, 11 interleave data type // FEC_TYPE: 00 No FEC, 01 FEC13, 10 FEC23, 11 reserved -<<<<<<< HEAD - LT8910_Flags=flags; - //CRC init constant - LT8910_CRC_Initial_Data=crc_init; -} - -void LT8910_SetChannel(uint8_t channel) -======= LT8900_Flags=flags; //CRC init constant LT8900_CRC_Initial_Data=crc_init; } void LT8900_SetChannel(uint8_t channel) ->>>>>>> refs/remotes/pascallanger/master { NRF24L01_WriteReg(NRF24L01_05_RF_CH, channel +2); //NRF24L01 is 2400+channel but LT8900 is 2402+channel } -<<<<<<< HEAD -void LT8910_SetTxRxMode(enum TXRX_State mode) -======= void LT8900_SetTxRxMode(enum TXRX_State mode) ->>>>>>> refs/remotes/pascallanger/master { if(mode == TX_EN) { @@ -518,35 +465,12 @@ void LT8900_SetTxRxMode(enum TXRX_State mode) NRF24L01_SetTxRxMode(TXRX_OFF); } -<<<<<<< HEAD -void LT8910_BuildOverhead() -======= void LT8900_BuildOverhead() ->>>>>>> refs/remotes/pascallanger/master { uint8_t pos; //Build overhead //preamble -<<<<<<< HEAD - memset(LT8910_buffer,LT8910_addr[0]&0x01?0xAA:0x55,LT8910_Preamble_Len-1); - pos=LT8910_Preamble_Len-1; - //address - for(uint8_t i=0;i5?5:pos; -} - -void LT8910_SetAddress(uint8_t *address,uint8_t addr_size) -======= memset(LT8900_buffer,LT8900_addr[0]&0x01?0xAA:0x55,LT8900_Preamble_Len-1); pos=LT8900_Preamble_Len-1; //address @@ -564,33 +488,10 @@ void LT8910_SetAddress(uint8_t *address,uint8_t addr_size) } void LT8900_SetAddress(uint8_t *address,uint8_t addr_size) ->>>>>>> refs/remotes/pascallanger/master { uint8_t addr[5]; //Address size (SyncWord) 2 to 8 bytes, 16/32/48/64 bits -<<<<<<< HEAD - LT8910_addr_size=addr_size; - memcpy(LT8910_addr,address,LT8910_addr_size); - - //Build overhead - LT8910_BuildOverhead(); - - //Set NRF RX&TX address based on overhead content - NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, LT8910_buffer_start-2); - for(uint8_t i=0;i>>>>>> refs/remotes/pascallanger/master //Read payload NRF24L01_ReadPayload(buffer,end+1); //Check address + trail for(i=0;i>>>>>> refs/remotes/pascallanger/master for(i=pos;i>8)&0xFF; } //Check len -<<<<<<< HEAD - if(LT8910_Flags&_BV(LT8910_PACKET_LENGTH_EN)) -======= if(LT8900_Flags&_BV(LT8900_PACKET_LENGTH_EN)) ->>>>>>> refs/remotes/pascallanger/master { crc=crc16_update(crc,buffer[pos]); if(bit_reverse(len)!=buffer[pos++]) @@ -652,11 +541,7 @@ uint8_t LT8900_ReadPayload(uint8_t* msg, uint8_t len) msg[i]=bit_reverse(buffer[pos++]); } //Check CRC -<<<<<<< HEAD - if(LT8910_Flags&_BV(LT8910_CRC_ON)) -======= if(LT8900_Flags&_BV(LT8900_CRC_ON)) ->>>>>>> refs/remotes/pascallanger/master { if(buffer[pos++]!=((crc>>8)&0xFF)) return 0; // wrong CRC... if(buffer[pos]!=(crc&0xFF)) return 0; // wrong CRC... @@ -665,21 +550,12 @@ uint8_t LT8900_ReadPayload(uint8_t* msg, uint8_t len) return 1; } -<<<<<<< HEAD -void LT8910_WritePayload(uint8_t* msg, uint8_t len) -{ - unsigned int crc=LT8910_CRC_Initial_Data,a,mask; - uint8_t i, pos=0,tmp, buffer[64], pos_final,shift; - //Add packet len - if(LT8910_Flags&_BV(LT8910_PACKET_LENGTH_EN)) -======= void LT8900_WritePayload(uint8_t* msg, uint8_t len) { unsigned int crc=LT8900_CRC_Initial_Data,a,mask; uint8_t i, pos=0,tmp, buffer[64], pos_final,shift; //Add packet len if(LT8900_Flags&_BV(LT8900_PACKET_LENGTH_EN)) ->>>>>>> refs/remotes/pascallanger/master { tmp=bit_reverse(len); buffer[pos++]=tmp; @@ -693,27 +569,12 @@ void LT8900_WritePayload(uint8_t* msg, uint8_t len) crc=crc16_update(crc,tmp); } //Add CRC -<<<<<<< HEAD - if(LT8910_Flags&_BV(LT8910_CRC_ON)) -======= if(LT8900_Flags&_BV(LT8900_CRC_ON)) ->>>>>>> refs/remotes/pascallanger/master { buffer[pos++]=crc>>8; buffer[pos++]=crc; } //Shift everything to fit behind the trailer (4 to 18 bits) -<<<<<<< HEAD - shift=LT8910_buffer_overhead_bits&0x7; - pos_final=LT8910_buffer_overhead_bits/8; - mask=~(0xFF<<(8-shift)); - LT8910_buffer[pos_final+pos]=0xFF; - for(i=pos-1;i!=0xFF;i--) - { - a=buffer[i]<<(8-shift); - LT8910_buffer[pos_final+i]=(LT8910_buffer[pos_final+i]&mask>>8)|a>>8; - LT8910_buffer[pos_final+i+1]=(LT8910_buffer[pos_final+i+1]&mask)|a; -======= shift=LT8900_buffer_overhead_bits&0x7; pos_final=LT8900_buffer_overhead_bits/8; mask=~(0xFF<<(8-shift)); @@ -723,17 +584,10 @@ void LT8900_WritePayload(uint8_t* msg, uint8_t len) a=buffer[i]<<(8-shift); LT8900_buffer[pos_final+i]=(LT8900_buffer[pos_final+i]&mask>>8)|a>>8; LT8900_buffer[pos_final+i+1]=(LT8900_buffer[pos_final+i+1]&mask)|a; ->>>>>>> refs/remotes/pascallanger/master } if(shift) pos++; //Send everything -<<<<<<< HEAD - NRF24L01_WritePayload(LT8910_buffer+LT8910_buffer_start,pos_final+pos-LT8910_buffer_start); -} -// End of LT8910 emulation -======= NRF24L01_WritePayload(LT8900_buffer+LT8900_buffer_start,pos_final+pos-LT8900_buffer_start); } // End of LT8900 emulation ->>>>>>> refs/remotes/pascallanger/master diff --git a/Multiprotocol/Nrf24l01_bluefly.ino b/Multiprotocol/Nrf24l01_bluefly.ino index 3a7f918..ae3db7a 100644 --- a/Multiprotocol/Nrf24l01_bluefly.ino +++ b/Multiprotocol/Nrf24l01_bluefly.ino @@ -51,7 +51,7 @@ static void bluefly_init() { NRF24L01_WriteReg(NRF24L01_05_RF_CH, 81); // binding packet must be set in channel 81 // 2-bytes CRC, radio on - NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP)); + NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address (byte -2) NRF24L01_SetBitrate(NRF24L01_BR_250K); // BlueFly - 250kbps NRF24L01_SetPower(); @@ -63,7 +63,7 @@ static void bluefly_ch_data() { uint32_t temp; int i; for (i = 0; i< 8; ++i) { - temp = (uint32_t)Servo_data[ch[i]] * 300/PPM_MAX + 500; // 200-800 range + temp = map(limit_channel_100(i),servo_min_100,servo_max_100,200,800); // 200-800 range if (temp < 0) ch_data_bluefly[i] = 0; else if (temp > 1000) @@ -140,6 +140,7 @@ static uint16_t bluefly_cb() { } static uint16_t BlueFly_setup() { + MProtocol_id = (MProtocol_id | ((uint32_t)txid[3]<<32)); hopping_frequency_start = ((MProtocol_id >> 8) % 47) + 2; bluefly_binding_packet(); bluefly_init(); diff --git a/Multiprotocol/Nrf24l01_cflie.ino b/Multiprotocol/Nrf24l01_cflie.ino index d4b0208..455b97c 100644 --- a/Multiprotocol/Nrf24l01_cflie.ino +++ b/Multiprotocol/Nrf24l01_cflie.ino @@ -13,12 +13,6 @@ along with Deviation. If not, see . */ -/* NB: Not implemented - Uncomment define below to enable telemetry. Also add CFlie protocol to TELEMETRY_SetTypeByProtocol to set type to DSM. -#define CFLIE_TELEMETRY - */ - - #if defined(CFlie_NRF24L01_INO) #include "iface_nrf24l01.h" @@ -59,30 +53,15 @@ enum { CFLIE_DATA }; -#ifdef CFLIE_TELEMETRY -static const char * const cflie_opts[] = { - _tr_noop("Telemetry"), _tr_noop("Off"), _tr_noop("On"), NULL, - NULL -}; -enum { - PROTOOPTS_TELEMETRY = 0, - LAST_PROTO_OPT, -}; -ctassert(LAST_PROTO_OPT <= NUM_PROTO_OPTS, too_many_protocol_opts); - -#define TELEM_OFF 0 -#define TELEM_ON 1 -#endif - -#define PACKET_CHKTIME 500 // time to wait if packet not yet acknowledged or timed out +#define PACKET_CFLIE_CHKTIME 500 // time to wait if packet not yet acknowledged or timed out static uint16_t dbg_cnt = 0; static uint8_t packet_ack() { if (++dbg_cnt > 50) { dbg_cnt = 0; } - switch (NRF24L01_ReadReg(NRF24L01_07_STATUS) & (BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT))) { - case BV(NRF24L01_07_TX_DS): + switch (NRF24L01_ReadReg(NRF24L01_07_STATUS) & (_BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_MAX_RT))) { + case _BV(NRF24L01_07_TX_DS): return PKT_ACKED; - case BV(NRF24L01_07_MAX_RT): + case _BV(NRF24L01_07_MAX_RT): return PKT_TIMEOUT; } return PKT_PENDING; @@ -97,7 +76,7 @@ static void send_search_packet() { uint8_t buf[1]; buf[0] = 0xff; // clear packet status bits and TX FIFO - NRF24L01_WriteReg(NRF24L01_07_STATUS, (BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT))); + NRF24L01_WriteReg(NRF24L01_07_STATUS, (_BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_MAX_RT))); NRF24L01_FlushTx(); if (rf_channel++ > 125) { @@ -119,7 +98,7 @@ static void send_search_packet() { NRF24L01_WritePayload(buf, sizeof(buf)); - ++packet_counter; + ++packet_count; } // Frac 16.16 @@ -151,33 +130,39 @@ static void send_cmd_packet() { // Channels in AETR order // Roll, aka aileron, float +- 50.0 in degrees - // float roll = -(float) Servo_data[AILERON]*50.0/10000; - uint32_t f_roll = -Servo_data[AILERON] * FRAC_SCALE / (10000 / 50); + uint32_t f_roll = -map(limit_channel_100(AILERON),servo_min_100,servo_max_100,-50,50); // Pitch, aka elevator, float +- 50.0 degrees - //float pitch = -(float) Servo_data[ELEVATOR]*50.0/10000; - uint32_t f_pitch = -Servo_data[ELEVATOR] * FRAC_SCALE / (10000 / 50); + uint32_t f_pitch = -map(limit_channel_100(ELEVATOR),servo_min_100,servo_max_100,-50,50); // Thrust, aka throttle 0..65535, working range 5535..65535 // No space for overshoot here, hard limit Channel3 by -10000..10000 uint32_t ch = Servo_data[THROTTLE]; - if (ch < PPM_MIN) { - ch = PPM_MIN; - } else if (ch > PPM_MAX) { - ch = PPM_MAX; + if (ch < servo_min_125) { + ch = servo_min_125; + } else if (ch > servo_max_125) { + ch = servo_max_125; } uint16_t thrust = ch*3L + 35535L; // Yaw, aka rudder, float +- 400.0 deg/s - // float yaw = -(float) Servo_data[RUDDER]*400.0/10000; - uint32_t f_yaw = - Servo_data[RUDDER] * FRAC_SCALE / (10000 / 400); + uint32_t f_yaw = - map(limit_channel_100(RUDDER),servo_min_100,servo_max_100,-40,40); frac2float(f_yaw, &yaw); - // Convert + to X. 181 / 256 = 0.70703125 ~= sqrt(2) / 2 - uint32_t f_x_roll = (f_roll + f_pitch) * 181 / 256; - frac2float(f_x_roll, &x_roll); - uint32_t f_x_pitch = (f_pitch - f_roll) * 181 / 256; - frac2float(f_x_pitch, &x_pitch); + // Switch on/off? + if(Servo_AUX1) + { + frac2float(f_roll, &x_roll); + frac2float(f_pitch, &x_pitch); + } + else + { + // Convert + to X. 181 / 256 = 0.70703125 ~= sqrt(2) / 2 + uint32_t f_x_roll = (f_roll + f_pitch) * 181 / 256; + frac2float(f_x_roll, &x_roll); + uint32_t f_x_pitch = (f_pitch - f_roll) * 181 / 256; + frac2float(f_x_pitch, &x_pitch); + } int bufptr = 0; buf[bufptr++] = 0x30; // Commander packet to channel 0 @@ -188,12 +173,12 @@ static void send_cmd_packet() { // clear packet status bits and TX FIFO - NRF24L01_WriteReg(NRF24L01_07_STATUS, (BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT))); + NRF24L01_WriteReg(NRF24L01_07_STATUS, (_BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_MAX_RT))); NRF24L01_FlushTx(); NRF24L01_WritePayload(buf, sizeof(buf)); - ++packet_counter; + ++packet_count; NRF24L01_SetPower(); } @@ -203,7 +188,7 @@ static int cflie_init() { // CRC, radio on NRF24L01_SetTxRxMode(TX_EN); - NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP)); + NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); // NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgement NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x01); // Auto Acknowledgement for data pipe 0 NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 @@ -236,21 +221,6 @@ static int cflie_init() { return 50000; } - -#ifdef CFLIE_TELEMETRY -static void update_telemetry() { - static uint8_t frameloss = 0; - - frameloss += NRF24L01_ReadReg(NRF24L01_08_OBSERVE_TX) >> 4; - NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_channel); // reset packet loss counter - - Telemetry.p.dsm.flog.frameloss = frameloss; -// Telemetry.p.dsm.flog.volt[0] = read battery voltage from ack payload - TELEMETRY_SetUpdated(TELEM_DSM_FLOG_FRAMELOSS); -} -#endif - - static uint16_t cflie_callback() { switch (phase) { case CFLIE_INIT_SEARCH: @@ -264,7 +234,7 @@ static uint16_t cflie_callback() { case CFLIE_SEARCH: switch (packet_ack()) { case PKT_PENDING: - return PACKET_CHKTIME; // packet send not yet complete + return PACKET_CFLIE_CHKTIME; // packet send not yet complete case PKT_ACKED: phase = CFLIE_DATA; BIND_DONE; @@ -275,11 +245,8 @@ static uint16_t cflie_callback() { } break; case CFLIE_DATA: - #ifdef CFLIE_TELEMETRY - update_telemetry(); - #endif if (packet_ack() == PKT_PENDING) - return PACKET_CHKTIME; // packet send not yet complete + return PACKET_CFLIE_CHKTIME; // packet send not yet complete send_cmd_packet(); break; } @@ -287,31 +254,21 @@ static uint16_t cflie_callback() { } -// Generate address to use from TX id and manufacturer id (STM32 unique id) -static uint8_t initialize_rx_tx_addr() { +static uint16_t Cflie_setup() { rx_tx_addr[0] = rx_tx_addr[1] = rx_tx_addr[2] = rx_tx_addr[3] = rx_tx_addr[4] = 0xE7; // CFlie uses fixed address - data_rate = NRF24L01_BR_250K; - rf_channel = 0; - return CFLIE_INIT_SEARCH; - // return CFLIE_INIT_DATA; -} - -static uint16_t Cflie_setup() { - phase = initialize_rx_tx_addr(); - packet_counter = 0; + data_rate = NRF24L01_BR_250K; + rf_channel = 0; + packet_count = 0; int delay = cflie_init(); - #ifdef CFLIE_TELEMETRY - memset(&Telemetry, 0, sizeof(Telemetry)); - TELEMETRY_SetType(TELEM_DSM); - #endif - if (phase == CFLIE_INIT_SEARCH) { BIND_IN_PROGRESS; } + phase = CFLIE_INIT_SEARCH; + BIND_IN_PROGRESS; return delay; } diff --git a/Multiprotocol/Nrf24l01_esky150.ino b/Multiprotocol/Nrf24l01_esky150.ino index b3d9c43..5460561 100644 --- a/Multiprotocol/Nrf24l01_esky150.ino +++ b/Multiprotocol/Nrf24l01_esky150.ino @@ -32,15 +32,15 @@ enum { static uint8_t esky150_packet_ack() { - switch (NRF24L01_ReadReg(NRF24L01_07_STATUS) & (BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT))) { - case BV(NRF24L01_07_TX_DS): return PKT_ACKED; - case BV(NRF24L01_07_MAX_RT): return PKT_TIMEOUT; + switch (NRF24L01_ReadReg(NRF24L01_07_STATUS) & (_BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_MAX_RT))) { + case _BV(NRF24L01_07_TX_DS): return PKT_ACKED; + case _BV(NRF24L01_07_MAX_RT): return PKT_TIMEOUT; } return PKT_PENDING; } // 2-bytes CRC -#define CRC_CONFIG (BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO)) +#define CRC_CONFIG (_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)) static uint16_t esky150_init() { uint8_t rx_addr[ADDR_esky150_SIZE] = { 0x73, 0x73, 0x74, 0x63 }; uint8_t tx_addr[ADDR_esky150_SIZE] = { 0x71, 0x0A, 0x31, 0xF4 }; @@ -64,7 +64,7 @@ static uint16_t esky150_init() { NRF24L01_Activate(0x73); NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 1); // Dynamic payload for data pipe 0 // Enable: Dynamic Payload Length, Payload with ACK , W_TX_PAYLOAD_NOACK - NRF24L01_WriteReg(NRF24L01_1D_FEATURE, BV(NRF2401_1D_EN_DPL) | BV(NRF2401_1D_EN_ACK_PAY) | BV(NRF2401_1D_EN_DYN_ACK)); + NRF24L01_WriteReg(NRF24L01_1D_FEATURE, _BV(NRF2401_1D_EN_DPL) | _BV(NRF2401_1D_EN_ACK_PAY) | _BV(NRF2401_1D_EN_DYN_ACK)); // Delay 50 ms return 50000; @@ -80,51 +80,26 @@ static uint16_t esky150_init2() { // Turn radio power on NRF24L01_SetTxRxMode(TX_EN); - NRF24L01_WriteReg(NRF24L01_00_CONFIG, CRC_CONFIG | BV(NRF24L01_00_PWR_UP)); + NRF24L01_WriteReg(NRF24L01_00_CONFIG, CRC_CONFIG | _BV(NRF24L01_00_PWR_UP)); // delayMicroseconds(150); return 150; } -static void calc_fh_channels(uint32_t seed) { - // Use channels 2..79 - uint8_t first = seed % 37 + 2; - uint8_t second = first + 40; - hopping_frequency[0] = first; // 0x22; - hopping_frequency[1] = second; // 0x4a; -} - - -static uint8_t convert_channel(uint8_t num) { - uint32_t ch = Servo_data[num]; - if (ch < PPM_MIN) { ch = PPM_MIN; } - else if (ch > PPM_MAX) { ch = PPM_MAX; } - return (uint8_t) ((ch * 500 / PPM_MAX) + 1500); -} -static void read_controls(uint8_t* throttle, uint8_t* aileron, uint8_t* elevator, uint8_t* rudder) { - *throttle = convert_channel(THROTTLE); - *aileron = convert_channel(AILERON); - *elevator = convert_channel(ELEVATOR); - *rudder = convert_channel(RUDDER); -} - - static void esky150_send_packet() { uint8_t rf_ch = hopping_frequency[rf_ch_num]; rf_ch_num = 1 - rf_ch_num; - read_controls(&throttle, &aileron, &elevator, &rudder); - packet[0] = hopping_frequency[0]; packet[1] = hopping_frequency[1]; - packet[2] = (throttle >> 8) & 0xFF; - packet[3] = throttle & 0xFF; - packet[4] = (aileron >> 8) & 0xFF; - packet[5] = aileron & 0xFF; - packet[6] = (elevator >> 8) & 0xFF; - packet[7] = elevator & 0xFF; - packet[8] = (rudder >> 8) & 0xFF; - packet[9] = rudder & 0xFF; + packet[2] = highByte(Servo_data[THROTTLE]); + packet[3] = lowByte(Servo_data[THROTTLE]); + packet[4] = highByte(Servo_data[AILERON]); + packet[5] = lowByte(Servo_data[AILERON]); + packet[6] = highByte(Servo_data[ELEVATOR]); + packet[7] = lowByte(Servo_data[ELEVATOR]); + packet[8] = highByte(Servo_data[RUDDER]); + packet[9] = lowByte(Servo_data[RUDDER]); // Constant values 00 d8 18 f8 packet[10] = 0x00; packet[11] = 0xd8; @@ -166,6 +141,12 @@ static uint16_t esky150_callback() { static uint16_t esky150_setup() { total_packets = 0; uint16_t timeout = esky150_init(); + + // Use channels 2..79 + uint8_t first = MProtocol_id % 37 + 2; + uint8_t second = first + 40; + hopping_frequency[0] = first; // 0x22; + hopping_frequency[1] = second; // 0x4a; return timeout; } diff --git a/Multiprotocol/Nrf24l01_fbl100.ino b/Multiprotocol/Nrf24l01_fbl100.ino index f25e368..cdc7f94 100644 --- a/Multiprotocol/Nrf24l01_fbl100.ino +++ b/Multiprotocol/Nrf24l01_fbl100.ino @@ -93,7 +93,7 @@ static void config_nrf24l01() { NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // 0:No Auto Acknoledgement; 1:Auto Acknoledgement NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, packet_length); // fbl100/v922's packet size = 10, hp100 = 12 // 2-bytes CRC, radio off - NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP)); + NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address (byte -2) NRF24L01_SetBitrate(sub_protocol == HP100? NRF24L01_BR_250K:NRF24L01_BR_1M); //hp100:250kbps; fbl100: 1Mbps NRF24L01_SetPower(); @@ -108,7 +108,7 @@ static void fbl100_build_ch_data() { uint32_t temp; uint8_t i; for (i = 0; i< 8; i++) { - temp = (uint32_t)Servo_data[i] * 500/PPM_MAX + 500; + temp = (uint32_t)Servo_data[i] -1000; if (i == 2) { temp = 1000 -temp; } // It is clear that fbl100's thro stick is made reversely,so I adjust it here on purposely if (temp < 0) { fbl_data[i] = 0; } else if (temp > 1000) { fbl_data[i] = 1000; } @@ -131,11 +131,12 @@ static void hp100_build_ch_data() { uint32_t temp; uint8_t i; for (i = 0; i< 8; i++) { - temp = (uint32_t)Servo_data[i] * 300/PPM_MAX + 500; + temp=map(limit_channel_100(i),servo_min_100,servo_max_100,200,800); +/* temp = (uint32_t)Servo_data[i] * 300/PPM_MAX + 500; if (temp < 0) { temp = 0; } else if (temp > 1000) { temp = 1000; } if (i == 3 || i == 5) { temp = 1000 -temp; } // hp100's rudd and pit channel are made reversely,so I adjust them on purposely - +*/ fbl_data[i] = (unsigned int)temp; packet[i] = (uint8_t)fbl_data[i]; } diff --git a/Multiprotocol/Nrf24l01_h377.ino b/Multiprotocol/Nrf24l01_h377.ino index 439178d..0771dcf 100644 --- a/Multiprotocol/Nrf24l01_h377.ino +++ b/Multiprotocol/Nrf24l01_h377.ino @@ -90,7 +90,7 @@ static void h377_init() { // 2-bytes CRC, radio off NRF24L01_SetTxRxMode(TX_EN); - NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP)); + NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address (byte -2) NRF24L01_SetBitrate(0); // 1Mbps NRF24L01_SetPower(); @@ -100,10 +100,11 @@ static void h377_init() { // H377 channel sequence: AILE ELEV THRO RUDD GEAR PITH, channel data value is from 0 to 1000 static void h377_ch_data() { uint32_t temp; - uint8_t i; + uint8_t i,j; for (i = 0; i< 8; i++) { - temp = (uint32_t)Servo_data[i] * 450/PPM_MAX + 500; // max/min servo range is +-125% - if (i == 2) // It is clear that h377's thro stick is made reversely, so I adjust it here on purpose + j=CH_AETR[i]; + temp=map(limit_channel_100(j),servo_min_100,servo_max_100,0,1000); // max/min servo range is +-125% + if (j == THROTTLE) // It is clear that h377's thro stick is made reversely, so I adjust it here on purpose temp = 1000 -temp; //if (i == 0) // It is clear that h377's thro stick is made reversely, so I adjust it here on purpose // temp = 1000 -temp; diff --git a/Multiprotocol/Nrf24l01_hm830.ino b/Multiprotocol/Nrf24l01_hm830.ino index bb30d3a..d81d809 100644 --- a/Multiprotocol/Nrf24l01_hm830.ino +++ b/Multiprotocol/Nrf24l01_hm830.ino @@ -76,7 +76,7 @@ static uint8_t count; static uint8_t rf_ch[] = {0x08, 0x35, 0x12, 0x3f, 0x1c, 0x49, 0x26}; static uint8_t bind_addr[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xc2}; -static uint8_t crc8(uint32_t result, uint8_t *data, int len) { +static uint8_t HM830_crc8(uint32_t result, uint8_t *data, int len) { int polynomial = 0x01; for(int i = 0; i < len; i++) { result = result ^ data[i]; @@ -114,26 +114,26 @@ static void HM830_init() { static void build_bind_packet_hm830() { for(int i = 0; i < 6; i++) { packet[i] = rx_tx_addr[i]; } - packet[6] = crc8(0xa5, packet, 6); + packet[6] = HM830_crc8(0xa5, packet, 6); } static void build_data_packet() { uint8_t ail_sign = 0, trim_sign = 0; - throttle = (uint32_t)Servo_data[THROTTLE] * 50 / PPM_MAX + 50; + throttle = (uint32_t)map(limit_channel_100(THROTTLE),servo_min_100,servo_max_100,0,100); if (throttle < 0) { throttle = 0; } - aileron = (uint32_t)Servo_data[AILERON] * 8 / PPM_MAX; + aileron = (uint32_t)map(limit_channel_100(AILERON),servo_min_100,servo_max_100,-8,8); if (aileron < 0) { aileron = -aileron; ail_sign = 1; } if (aileron > 7) { aileron = 7; } - uint8_t turbo = (uint32_t)Servo_data[ELEVATOR] > 0 ? 1 : 0; + uint8_t turbo = Servo_data[ELEVATOR] > PPM_SWITCH ? 1 : 0; - uint8_t trim = ((uint32_t)Servo_data[RUDDER] * 0x1f / PPM_MAX); + uint8_t trim = map(limit_channel_100(RUDDER),servo_min_100,servo_max_100,-31,31); if (trim < 0) { trim = -trim; trim_sign = 1; } if (trim > 0x1f) { trim = 0x1f; } - uint8_t rbutton = (uint32_t)Servo_data[4] > 0 ? 1 : 0; + uint8_t rbutton = Servo_data[4] > PPM_SWITCH ? 1 : 0; packet[0] = throttle; packet[1] = aileron; if (ail_sign) { packet[1] |= 0x20; } @@ -141,7 +141,7 @@ static void build_data_packet() { if (rbutton) { packet[1] |= 0x80; } packet[5] = trim; if (trim_sign) { packet[5] |= 0x20;} - packet[6] = crc8(0xa5, packet, 6); + packet[6] = HM830_crc8(0xa5, packet, 6); } static void send_packet_hm830() { diff --git a/Multiprotocol/Nrf24l01_hontai.ino b/Multiprotocol/Nrf24l01_hontai.ino deleted file mode 100644 index 4408014..0000000 --- a/Multiprotocol/Nrf24l01_hontai.ino +++ /dev/null @@ -1,272 +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 . - */ - - -#if defined(HonTai_NRF24L01_INO) -#include "iface_nrf24l01.h" - -#define BIND_HT_COUNT 80 -#define PACKET_HT_PERIOD 13500 // Timeout for callback in uSec -//printf inside an interrupt handler is really dangerous -//this shouldn't be enabled even in debug builds without explicitly -//turning it on -#define dbgprintf if(0) printf - -#define INITIAL_HT_WAIT 500 -#define BIND_HT_PACKET_SIZE 10 -#define PACKET_HT_SIZE 12 -#define RF_BIND_HT_CHANNEL 0 - -enum { - FORMAT_HONTAI = 0, - FORMAT_JJRCX1, -}; - - -#define CHANNEL_LED AUX1 -#define CHANNEL_ARM AUX1 // for JJRC X1 -#define CHANNEL_FLIP AUX2 -#define CHANNEL_PICTURE AUX3 -#define CHANNEL_VIDEO AUX4 -#define CHANNEL_HEADLESS AUX5 -#define CHANNEL_RTH AUX6 -#define CHANNEL_CALIBRATE AUX7 - -enum { - HonTai_INIT1 = 0, - HonTai_BIND2, - HonTai_DATA -}; - -static uint8_t ht_txid[5]; - -static uint8_t rf_chan = 0; -static uint8_t rf_channels[][3] = {{0x05, 0x19, 0x28}, // Hontai - {0x0a, 0x1e, 0x2d}}; // JJRC X1 -static uint8_t rx_tx_ht_addr[] = {0xd2, 0xb5, 0x99, 0xb3, 0x4a}; -static uint8_t addr_vals[4][16] = { - {0x24, 0x26, 0x2a, 0x2c, 0x32, 0x34, 0x36, 0x4a, 0x4c, 0x4e, 0x54, 0x56, 0x5a, 0x64, 0x66, 0x6a}, - {0x92, 0x94, 0x96, 0x9a, 0xa4, 0xa6, 0xac, 0xb2, 0xb4, 0xb6, 0xca, 0xcc, 0xd2, 0xd4, 0xd6, 0xda}, - {0x93, 0x95, 0x99, 0x9b, 0xa5, 0xa9, 0xab, 0xad, 0xb3, 0xb5, 0xc9, 0xcb, 0xcd, 0xd3, 0xd5, 0xd9}, - {0x25, 0x29, 0x2b, 0x2d, 0x33, 0x35, 0x49, 0x4b, 0x4d, 0x59, 0x5b, 0x65, 0x69, 0x6b, 0x6d, 0x6e}}; - -// proudly swiped from http://www.drdobbs.com/implementing-the-ccitt-cyclical-redundan/199904926 -#define POLY 0x8408 -static uint16_t crc16(uint8_t *data_p, uint32_t length) -{ - uint8_t i; - uint32_t data; - uint32_t crc; - - crc = 0xffff; - - if (length == 0) return (~crc); - - length -= 2; - do { - for (i = 0, data = (uint8_t)0xff & *data_p++; - i < 8; - i++, data >>= 1) { - if ((crc & 0x0001) ^ (data & 0x0001)) - crc = (crc >> 1) ^ POLY; - else - crc >>= 1; - } - } while (--length); - - crc = ~crc; - data = crc; - crc = (crc << 8) | (data >> 8 & 0xFF); - *data_p++ = crc >> 8; - *data_p = crc & 0xff; - return crc; -} - -#define CHAN_RANGE (PPM_MAX - PPM_MIN) -static uint8_t scale_HT_channel(uint8_t ch, uint8_t start, uint8_t end) -{ - uint32_t range = end - start; - uint32_t chanval = Servo_data[ch]; - - if (chanval < PPM_MIN) chanval = PPM_MIN; - else if (chanval > PPM_MAX) chanval = PPM_MAX; - - uint32_t round = range < 0 ? 0 : CHAN_RANGE / range; // channels round up - if (start < 0) round = CHAN_RANGE / range / 2; // trims zero centered around zero - return (range * (chanval - PPM_MIN + round)) / CHAN_RANGE + start; -} - -#define GET_FLAG(ch, mask) (Servo_data[ch] > 0 ? mask : 0) -static void send_HT_packet(uint8_t bind) -{ - if (bind) { - memcpy(packet, ht_txid, 5); - memset(&packet[5], 0, 3); - } else { - if (sub_protocol == FORMAT_HONTAI) { - packet[0] = 0x0b; - } else { - packet[0] = GET_FLAG(CHANNEL_ARM, 0x02); - } - packet[1] = 0x00; - packet[2] = 0x00; - packet[3] = (scale_HT_channel(THROTTLE, 0, 127) << 1) // throttle - | GET_FLAG(CHANNEL_PICTURE, 0x01); - packet[4] = scale_HT_channel(AILERON, 63, 0); // aileron - if (sub_protocol == FORMAT_HONTAI) { - packet[4] |= GET_FLAG(CHANNEL_RTH, 0x80) - | GET_FLAG(CHANNEL_HEADLESS, 0x40); - } else { - packet[4] |= 0x80; // not sure what this bit does - } - packet[5] = scale_channel(CHANNEL2, 0, 63) // elevator - | GET_FLAG(CHANNEL_CALIBRATE, 0x80) - | GET_FLAG(CHANNEL_FLIP, 0x40); - packet[6] = scale_HT_channel(RUDDER, 0, 63) // rudder - | GET_FLAG(CHANNEL_VIDEO, 0x80); - packet[7] = scale_HT_channel(AILERON, -16, 16); // aileron trim - if (sub_protocol == FORMAT_HONTAI) { - packet[8] = scale_HT_channel(RUDDER, -16, 16); // rudder trim - } else { - packet[8] = 0xc0 // always in expert mode - | GET_FLAG(CHANNEL_RTH, 0x02) - | GET_FLAG(CHANNEL_HEADLESS, 0x01); - } - packet[9] = scale_HT_channel(ELEVATOR, -16, 16); // elevator trim - } - crc16(packet, bind ? BIND_HT_PACKET_SIZE : PACKET_HT_SIZE); - - // Power on, TX mode, 2byte CRC - if (sub_protocol == FORMAT_HONTAI) { - XN297_Configure(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP)); - } else { - NRF24L01_SetTxRxMode(TX_EN); - } - - NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? RF_BIND_HT_CHANNEL : rf_channels[sub_protocol][rf_chan++]); - rf_chan %= sizeof(rf_channels); - - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); - NRF24L01_FlushTx(); - - if (sub_protocol == FORMAT_HONTAI) { - XN297_WritePayload(packet, bind ? BIND_HT_PACKET_SIZE : PACKET_HT_SIZE); - } else { - NRF24L01_WritePayload(packet, bind ? BIND_HT_PACKET_SIZE : PACKET_HT_SIZE); - } - - NRF24L01_SetPower(); -} - -static void ht_init() -{ - NRF24L01_Initialize(); - - NRF24L01_SetTxRxMode(TX_EN); - - // SPI trace of stock TX has these writes to registers that don't appear in - // nRF24L01 or Beken 2421 datasheets. Uncomment if you have an XN297 chip? - // NRF24L01_WriteRegisterMulti(0x3f, "\x4c\x84\x67,\x9c,\x20", 5); - // NRF24L01_WriteRegisterMulti(0x3e, "\xc9\x9a\xb0,\x61,\xbb,\xab,\x9c", 7); - // NRF24L01_WriteRegisterMulti(0x39, "\x0b\xdf\xc4,\xa7,\x03,\xab,\x9c", 7); - - if (sub_protocol == FORMAT_HONTAI) { - XN297_SetTXAddr(rx_tx_ht_addr, sizeof(rx_tx_ht_addr)); - } else { - NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_ht_addr, sizeof(rx_tx_ht_addr)); - } - - 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 Acknowldgement on all data pipes - NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps - NRF24L01_SetPower(); - NRF24L01_Activate(0x73); // Activate feature register - if (sub_protocol == FORMAT_HONTAI) { - NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits - NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes - NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x00); - NRF24L01_Activate(0x73); // Deactivate feature register - } else { - NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0xff); // JJRC uses dynamic payload length - NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3f); // match other stock settings even though AA disabled... - NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07); - } -} - -static void ht_init2() -{ - uint8_t data_tx_addr[] = {0x2a, 0xda, 0xa5, 0x25, 0x24}; - - data_tx_addr[0] = addr_vals[0][ ht_txid[3] & 0x0f]; - data_tx_addr[1] = addr_vals[1][(ht_txid[3] >> 4) & 0x0f]; - data_tx_addr[2] = addr_vals[2][ ht_txid[4] & 0x0f]; - data_tx_addr[3] = addr_vals[3][(ht_txid[4] >> 4) & 0x0f]; - - if (sub_protocol == FORMAT_HONTAI) { - XN297_SetTXAddr(data_tx_addr, sizeof(data_tx_addr)); - } else { - NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, data_tx_addr, sizeof(data_tx_addr)); - } -} - -static uint16_t ht_callback() -{ - switch (phase) { - case HonTai_INIT1: - phase = HonTai_BIND2; - break; - case HonTai_BIND2: - if (counter == 0) { - ht_init2(); - phase = HonTai_DATA; - BIND_DONE; - } else { - send_HT_packet(1); - counter -= 1; - } - break; - - case HonTai_DATA: - send_HT_packet(0); - break; - } - return PACKET_HT_PERIOD; -} - -static uint16_t ht_setup() -{ - counter = BIND_HT_COUNT; - - if (sub_protocol == FORMAT_HONTAI) { - ht_txid[0] = 0x4c; // first three bytes some kind of model id? - set same as stock tx - ht_txid[1] = 0x4b; - ht_txid[2] = 0x3a; - } else { - ht_txid[0] = 0x4b; // JJRC X1 - ht_txid[1] = 0x59; - ht_txid[2] = 0x3a; - } - ht_txid[3] = (MProtocol_id >> 8 ) & 0xff; - ht_txid[4] = MProtocol_id & 0xff; - - ht_init(); - phase = HonTai_INIT1; - - return INITIAL_HT_WAIT; -} -#endif - diff --git a/Multiprotocol/Nrf24l01_inav.ino b/Multiprotocol/Nrf24l01_inav.ino new file mode 100644 index 0000000..2d04acc --- /dev/null +++ b/Multiprotocol/Nrf24l01_inav.ino @@ -0,0 +1,733 @@ +/*** + * iNav Protocol + * + * Data rate is 250Kbps - lower data rate for better reliability and range + * + * Uses auto acknowledgment and dynamic payload size + * ACK payload is used for handshaking in bind phase and telemetry in data phase + * + * Bind payload size is 16 bytes + * Data payload size is 16 bytes dependent on variant of protocol, (small payload is read more quickly (marginal benefit)) + * + * Bind and data payloads are whitened (XORed with a pseudo-random bitstream) to remove strings of 0s or 1s in transmission + * packet. This improves reception by helping keep the TX and RX clocks in sync. + * + * Bind Phase + * uses address {0x4b,0x5c,0x6d,0x7e,0x8f} + * uses channel 0x4c (76) + * + * Data Phase + * 1) Uses the address received in bind packet + * + * 2) Hops between RF channels generated from the address received in bind packet. + * The number of RF hopping channels is set during bind handshaking: + * the transmitter requests a number of hopping channels in payload[7] + * the receiver sets ackPayload[7] with the number of hopping channels actually allocated - the transmitter must + * use this value. + * + * 3) There are 16 channels: eight 10-bit analog channels, two 8-bit analog channels, and six digital channels as follows: + * Channels 0 to 3, are the AETR channels, values 1000 to 2000 with resolution of 1 (10-bit channels) + * Channel AUX1 by deviation convention is used for rate, values 1000, 1500, 2000 + * Channels AUX2 to AUX6 are binary channels, values 1000 or 2000, + * by deviation convention these channels are used for: flip, picture, video, headless, and return to home + * Channels AUX7 to AUX10 are analog channels, values 1000 to 2000 with resolution of 1 (10-bit channels) + * Channels AUX11 and AUX12 are analog channels, values 1000 to 2000 with resolution of 4 (8-bit channels) +***/ + +// debug build flags +//#define NO_RF_CHANNEL_HOPPING + +#define USE_AUTO_ACKKNOWLEDGEMENT +#define USE_WHITENING + +#define INAV_TELEMETRY +//#define INAV_TELEMETRY_DEBUG + +#define UNUSED(x) (void)(x) + +#ifdef INAV_NRF24L01_INO + static uint8_t INAV_setup() { return 1000; } + static uint16_t inav_cb() {} +#endif +#if 0 +/* +*/ + + #include "iface_nrf24l01.h" + + #define BIND_COUNT 345 // 1.5 seconds + #define FIRST_PACKET_DELAY 12000 + + #define PACKET_PERIOD 4000 // Timeout for callback in uSec + #define INITIAL_WAIT 500 + + // For code readability + enum { + CHANNEL1 = 0, + CHANNEL2, + CHANNEL3, + CHANNEL4, + CHANNEL5, + CHANNEL6, + CHANNEL7, + CHANNEL8, + CHANNEL9, + CHANNEL10, + CHANNEL11, + CHANNEL12, + CHANNEL13, + CHANNEL14, + CHANNEL15, + CHANNEL16, + }; + + // Deviation transmitter channels + #define DEVIATION_CHANNEL_COUNT 12 // Max supported by Devo 7e + //#define CHANNEL_LED CHANNEL5 + #define CHANNEL_RATE CHANNEL5 + #define CHANNEL_FLIP CHANNEL6 + #define CHANNEL_PICTURE CHANNEL7 + #define CHANNEL_VIDEO CHANNEL8 + #define CHANNEL_HEADLESS CHANNEL9 + #define CHANNEL_RTH CHANNEL10 + #define CHANNEL_XCAL CHANNEL11 + #define CHANNEL_YCAL CHANNEL12 +// #define GET_FLAG(ch, mask) (Channels[ch] > 0 ? mask : 0) + + + enum { + RATE_LOW = 0, + RATE_MID = 1, + RATE_HIGH = 2, + }; + + enum { + FLAG_FLIP = 0x01, + FLAG_PICTURE = 0x02, + FLAG_VIDEO = 0x04, + FLAG_RTH = 0x08, + FLAG_HEADLESS = 0x10, + }; + + typedef enum { + PHASE_INAV_INIT = 0, + PHASE_INAV_BIND, + PHASE_INAV_DATA + }; + + typedef enum { + DATA_PACKET = 0, + BIND_PACKET = 1, + }; + + static const char * const inav_opts[] = { + #ifdef INAV_TELEMETRY + _tr_noop("Telemetry"), _tr_noop("On"), _tr_noop("Off"), NULL, + #endif + "RxTx Addr1", "-32768", "32767", "1", NULL, // todo: store that elsewhere + "RxTx Addr2", "-32768", "32767", "1", NULL, // ^^^^^^^^^^^^^^^^^^^^^^^^^^ + NULL + }; + + enum { + #ifdef INAV_TELEMETRY + PROTOOPTS_TELEMETRY, + #endif + PROTOOPTS_RX_TX_ADDR1, // todo: store that elsewhere + PROTOOPTS_RX_TX_ADDR2, // ^^^^^^^^^^^^^^^^^^^^^^^^^^ + LAST_PROTO_OPT + }; + + enum { + OPTS_6_CHANNELS = 0, + OPTS_12_CHANNELS + }; + + enum { + TELEM_ON = 0, + TELEM_OFF, + }; + + // Bit vector from bit position + #define BV(bit) (1 << bit) + + // Bit position mnemonics + enum { + + NRF24L01_1D_EN_DYN_ACK = 0, + NRF24L01_1D_EN_ACK_PAY = 1, + NRF24L01_1D_EN_DPL = 2, + }; + + // Pre-shifted and combined bits + enum { + NRF24L01_03_SETUP_AW_5BYTES = 0x03, + }; + + enum { + NRF24L01_MAX_PAYLOAD_SIZE = 32, + }; + + #define INAV_PROTOCOL_PAYLOAD_SIZE_MIN 8 + #define INAV_PROTOCOL_PAYLOAD_SIZE_DEFAULT 16 + #define INAV_PROTOCOL_PAYLOAD_SIZE_MAX 16 + + static uint32_t lost_packet_counter; + + #define RC_CHANNEL_COUNT_MIN 6 + #define RC_CHANNEL_COUNT_DEFAULT 16 + #define RC_CHANNEL_COUNT_MAX 18 + + static uint8_t rc_channel_count; + + static uint8_t tx_power; + + #define RX_TX_ADDR_LEN 5 + static const uint8_t rx_tx_addr_bind[RX_TX_ADDR_LEN] = {0x4b,0x5c,0x6d,0x7e,0x8f}; + static uint8_t rx_tx_addr[RX_TX_ADDR_LEN]; + #define RX_TX_ADDR_4 0xD2 // rxTxAddr[4] always set to this value + + #define BIND_PAYLOAD0 0xad // 10101101 + #define BIND_PAYLOAD1 0xc9 // 11001001 + #define BIND_ACK_PAYLOAD0 0x95 // 10010101 + #define BIND_ACK_PAYLOAD1 0xa9 // 10101001 + #define TELEMETRY_ACK_PAYLOAD0 0x5a // 01011010 + // TELEMETRY_ACK_PAYLOAD1 is sequence count + #define DATA_PAYLOAD0 0x00 + #define DATA_PAYLOAD1 0x00 + + #ifdef USE_AUTO_ACKKNOWLEDGEMENT + static uint8_t ackPayloadSize; + static uint8_t ackPayload[NRF24L01_MAX_PAYLOAD_SIZE]; + #endif + + // frequency channel management + #define RF_CHANNEL_COUNT_DEFAULT 4 + #define RF_CHANNEL_COUNT_MAX 4 + #define RF_CHANNEL_BIND 0x4c + static uint8_t rf_channel_index; + static uint8_t rf_channels[RF_CHANNEL_COUNT_MAX]; + static uint8_t rf_channel_count; + + static protocol_phase_t phase; + + #ifndef TELEM_LTM + // use DSM telemetry until LTM telemetry is implemented + #define TELEM_LTM TELEM_DSM + // repurpose the DSM FADESL, FADESR and HOLDS fields to display roll, pitch and yaw + #define TELEM_LTM_ATTITUDE_PITCH TELEM_DSM_FLOG_FADESL + #define TELEM_LTM_ATTITUDE_ROLL TELEM_DSM_FLOG_FADESR + #define TELEM_LTM_ATTITUDE_YAW TELEM_DSM_FLOG_HOLDS + // use DSM VOLT2, AMPS1 and AIRSPEED fields + #define TELEM_LTM_STATUS_VBAT TELEM_DSM_FLOG_VOLT2 + #define TELEM_LTM_STATUS_CURRENT TELEM_DSM_AMPS1 + #define TELEM_LTM_STATUS_RSSI TELEM_DSM_FLOG_FRAMELOSS + #define TELEM_LTM_STATUS_AIRSPEED TELEM_DSM_AIRSPEED + /* + currently unused LTM telemetry fields + TELEM_LTM_STATUS_ARMED + TELEM_LTM_STATUS_FAILSAFE + TELEM_LTM_STATUS_FLIGHTMODE + TELEM_LTM_NAVIGATION_GPS_MODE + TELEM_LTM_NAVIGATION_NAV_MODE + TELEM_LTM_NAVIGATION_ACTION + TELEM_LTM_NAVIGATION_WAYPOINT_NUMBER + TELEM_LTM_NAVIGATION_ERROR + TELEM_LTM_NAVIGATION_FLAGS + TELEM_LTM_GPSX_HDOP + TELEM_LTM_TUNING_P_ROLL + TELEM_LTM_TUNING_I_ROLL + TELEM_LTM_TUNING_D_ROLL + TELEM_LTM_TUNING_P_PITCH + TELEM_LTM_TUNING_I_PITCH + TELEM_LTM_TUNING_D_PITCH + TELEM_LTM_TUNING_P_YAW + TELEM_LTM_TUNING_I_YAW + TELEM_LTM_TUNING_D_YAW + TELEM_LTM_TUNING_RATES_ROLL + TELEM_LTM_TUNING_RATES_PITCH + TELEM_LTM_TUNING_RATES_YAW + */ + #endif + + /* + uint8_t convert_channel_8b(uint8_t channel) + { + return (uint8_t)(convert_channel(channel) >> 2); + } + */ + + static void whiten_payload(uint8_t *payload, uint8_t len) + { + #ifdef USE_WHITENING + uint8_t whitenCoeff = 0x6b; // 01101011 + while (len--) { + for (uint8_t m = 1; m; m <<= 1) { + if (whitenCoeff & 0x80) { + whitenCoeff ^= 0x11; + (*payload) ^= m; + } + whitenCoeff <<= 1; + } + payload++; + } + #else + UNUSED(payload); + UNUSED(len); + #endif + } + + static void build_bind_packet(void) + { + memset(packet, 0, INAV_PROTOCOL_PAYLOAD_SIZE_MAX); + packet[0] = BIND_PAYLOAD0; + packet[1] = BIND_PAYLOAD1; + packet[2] = rx_tx_addr[0]; + packet[3] = rx_tx_addr[1]; + packet[4] = rx_tx_addr[2]; + packet[5] = rx_tx_addr[3]; + packet[6] = rx_tx_addr[4]; + packet[7] = rf_channel_count; + packet[8] = packet_length; + packet[9] = rc_channel_count; + } + + static void build_data_packet(void) + { + packet[0] = 0; + packet[1] = 0; + // AETR channels have 10 bit resolution + const uint16_t aileron = convert_channel_10b(AILERON); + const uint16_t elevator = convert_channel_10b(ELEVATOR); + const uint16_t throttle = convert_channel_10b(THROTTLE); + const uint16_t rudder = convert_channel_10b(RUDDER); + packet[2] = aileron >> 2; + packet[3] = elevator >> 2; + packet[4] = throttle >> 2; + packet[5] = rudder >> 2; + // pack the AETR low bits + packet[6] = (aileron & 0x03) | ((elevator & 0x03) << 2) | ((throttle & 0x03) << 4) | ((rudder & 0x03) << 6); + + uint8_t rate = RATE_LOW; + if (Channels[CHANNEL_RATE] > 0) { + rate = RATE_HIGH; + } else if (Channels[CHANNEL_RATE] == 0) { + rate = RATE_MID; + } + packet[7] = rate; // rate, deviation channel 5, is mapped to AUX1 + + const uint8_t flags = GET_FLAG(CHANNEL_FLIP, FLAG_FLIP) + | GET_FLAG(CHANNEL_PICTURE, FLAG_PICTURE) + | GET_FLAG(CHANNEL_VIDEO, FLAG_VIDEO) + | GET_FLAG(CHANNEL_RTH, FLAG_RTH) + | GET_FLAG(CHANNEL_HEADLESS, FLAG_HEADLESS); + packet[8] = flags; // flags, deviation channels 6-10 are mapped to AUX2 t0 AUX6 + + // map deviation channels 9-12 to RC channels AUX7-AUX10, use 10 bit resolution + // deviation CHANNEL9 (headless) and CHANNEL10 (RTH) are mapped for a second time + // duplicate mapping makes maximum use of deviation's 12 channels + const uint16_t channel9 = convert_channel_10b(CHANNEL9); + const uint16_t channel10 = convert_channel_10b(CHANNEL10); + const uint16_t channel11 = convert_channel_10b(CHANNEL11); + const uint16_t channel12 = convert_channel_10b(CHANNEL12); + packet[9] = channel9 >> 2; + packet[10] = channel10 >> 2; + packet[11] = channel11 >> 2; + packet[12] = channel12 >> 2; + packet[13] = (channel9 & 0x03) | ((channel10 & 0x03) << 2) | ((channel11 & 0x03) << 4) | ((channel12 & 0x03) << 6); + + // map deviation channels 7 and 8 to RC channels AUX11 and AUX12, use 10 bit resolution + // deviation channels 7 (picture) and 8 (video) are mapped for a second time + packet[14] = convert_channel_8b(CHANNEL7); + packet[15] = convert_channel_8b(CHANNEL8); + } + + + static uint8_t packet_ack(void) + { + #ifdef USE_AUTO_ACKKNOWLEDGEMENT + const uint8_t status = NRF24L01_ReadReg(NRF24L01_07_STATUS); + if (status & BV(NRF24L01_07_TX_DS)) { // NRF24L01_07_TX_DS asserted when ack payload received + // ack payload recieved + ackPayloadSize = NRF24L01_GetDynamicPayloadSize(); + if (ackPayloadSize > NRF24L01_MAX_PAYLOAD_SIZE) { + ackPayloadSize = 0; + NRF24L01_FlushRx(); + return PKT_PENDING; + } + NRF24L01_ReadPayload(ackPayload, ackPayloadSize); + whiten_payload(ackPayload, ackPayloadSize); + NRF24L01_WriteReg(NRF24L01_07_STATUS, BV(NRF24L01_07_TX_DS)); // clear TX_DS interrupt + return PKT_ACKED; + } + if (status & BV(NRF24L01_07_MAX_RT)) { + // max retries exceeded + // clear MAX_RT interrupt to allow further transmission + NRF24L01_WriteReg(NRF24L01_07_STATUS, BV(NRF24L01_07_MAX_RT)); + NRF24L01_FlushTx(); // payload wasn't successfully transmitted, so remove it from TX FIFO + return PKT_TIMEOUT; + } + return PKT_PENDING; + #else + return PKT_TIMEOUT; // if not using AUTO ACK just return a timeout + #endif + } + + void transmit_packet(void) + { + // clear packet MAX_RT status bit so that transmission is not blocked + NRF24L01_WriteReg(NRF24L01_07_STATUS, BV(NRF24L01_07_MAX_RT)); + // set NRF24L01_00_MASK_TX_DS and clear NRF24L01_00_PRIM_RX to initiate transmit + // NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_PWR_UP) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_MASK_TX_DS) | BV(NRF24L01_00_MASK_MAX_RT)); + whiten_payload(packet, packet_length); + NRF24L01_WritePayload(packet, packet_length);// asynchronous call + } + + static void hop_to_next_channel(void) + { + #ifndef NO_RF_CHANNEL_HOPPING + if (phase == PHASE_INAV_BIND) { + return; + } + ++rf_channel_index; + if (rf_channel_index >= rf_channel_count) { + rf_channel_index = 0; + } + NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_channels[rf_channel_index]); + #endif + } + + static void send_packet(uint8_t packet_type) + { + if (packet_type == DATA_PACKET) { + build_data_packet(); + } else { + build_bind_packet(); + } + transmit_packet(); + hop_to_next_channel(); + ++packet_count; + + // Check and adjust transmission power. We do this after + // transmission to not bother with timeout after power + // settings change - we have plenty of time until next + // packet. + if (tx_power != Model.tx_power) { + //Keep transmit power updated + tx_power = Model.tx_power; + NRF24L01_SetPower(tx_power); + } + } + + static void set_data_phase(void) + { + packet_count = 0; + lost_packet_counter = 0; + phase = PHASE_INAV_DATA; + rf_channel_index = 0; + NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_channels[0]); + // RX_ADDR_P0 must equal TX_ADDR for auto ACK + NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, RX_TX_ADDR_LEN); + NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, RX_TX_ADDR_LEN); + } + + static void init_nrf24l01(void) + { + NRF24L01_Initialize(); + // sets PWR_UP, EN_CRC, CRCO - 2 byte CRC + NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_PWR_UP) | BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO)); + + #ifdef USE_AUTO_ACKKNOWLEDGEMENT + // Note that for some cheap NFR24L01 clones the NO_ACK bit in the packet control field is inverted, + // see https://ncrmnt.org/2015/03/13/how-do-i-cost-optimize-nrf24l01/ + // (see section 7.3.3, p28 of nRF24L01+ Product Specification for descripton of packet control field). + // This means AUTO_ACK will no work between them and genuine NRF24L01 modules, although AUTO_ACK + // between these clones should work. + NRF24L01_WriteReg(NRF24L01_01_EN_AA, BV(NRF24L01_01_ENAA_P0)); // auto acknowledgment on P0 + NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, BV(NRF24L01_02_ERX_P0)); // Enable RX on P0 for Auto Ack + #else + NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); + #endif + NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, NRF24L01_03_SETUP_AW_5BYTES); // 5-byte RX/TX address + // ARD of 1500us is minimum required for 32 byte ACK payload in 250kbps mode (section 7.4.2, p33 of nRF24L01+ Product Specification) + NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, NRF24L01_04_ARD_2500us | NRF24L01_04_ARC_1); // 1 retry after 1500us + NRF24L01_WriteReg(NRF24L01_05_RF_CH, RF_CHANNEL_BIND); + // bitrate and power are set using regigister NRF24L01_06_RF_SETUP + NRF24L01_SetBitrate(NRF24L01_BR_250K); + NRF24L01_SetPower(Model.tx_power); + // Writing to the STATUS register clears the specified interrupt bits + NRF24L01_WriteReg(NRF24L01_07_STATUS, BV(NRF24L01_07_RX_DR) | BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT)); + // NRF24L01_08_OBSERVE_TX is read only register + // NRF24L01_09_RPD is read only register (called RPD for NRF24L01+, CD for NRF24L01) + NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr_bind, RX_TX_ADDR_LEN); // RX_ADDR_P0 must equal TX_ADDR for auto ACK + // RX_ADDR for pipes P1-P5 (registers 0B to 0F) aret left at default values + NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr_bind, RX_TX_ADDR_LEN); + // Payload Widths for P0-P5 (registers 11 to 16) aret left at default values + // NRF24L01_17_FIFO_STATUS is read only register for all non-reserved bits + // No registers with values 18 to 1B + #ifdef USE_AUTO_ACKKNOWLEDGEMENT + NRF24L01_ReadReg(NRF24L01_1D_FEATURE); + NRF24L01_Activate(0x73); // Activate feature register, needed for NRF24L01 (harmless for NRF24L01+) + NRF24L01_ReadReg(NRF24L01_1D_FEATURE); + NRF24L01_WriteReg(NRF24L01_1C_DYNPD, BV(NRF24L01_1C_DYNPD_P0)); // dynamic payload length on pipes P0 + NRF24L01_WriteReg(NRF24L01_1D_FEATURE, BV(NRF24L01_1D_EN_ACK_PAY) | BV(NRF24L01_1D_EN_DPL)); + #endif + + NRF24L01_Activate(0x53); // switch bank back + + NRF24L01_SetTxRxMode(TX_EN); // enter transmit mode, sets up NRF24L01_00_CONFIG register + } + + // Generate address to use from TX id and manufacturer id (STM32 unique id) + static void initialize_rx_tx_addr(void) + { + uint32_t lfsr = 0xb2c54a2ful; + + #ifndef USE_FIXED_MFGID + uint8_t var[12]; + MCU_SerialNumber(var, 12); + for (int i = 0; i < 12; ++i) { + rand32_r(&lfsr, var[i]); + } + #endif + + if (Model.fixed_id) { + for (uint8_t i = 0, j = 0; i < sizeof(Model.fixed_id); ++i, j += 8) + rand32_r(&lfsr, (Model.fixed_id >> j) & 0xff); + } + // Pump zero bytes for LFSR to diverge more + for (uint8_t i = 0; i < sizeof(lfsr); ++i) rand32_r(&lfsr, 0); + + for (uint8_t i = 0; i < sizeof(rx_tx_addr)-1; ++i) { + rx_tx_addr[i] = lfsr & 0xff; + rand32_r(&lfsr, i); + } + rx_tx_addr[1] &= 0x7f; // clear top bit so saved Model.proto_opts value is positive + rx_tx_addr[3] &= 0x7f; // clear top bit so saved Model.proto_opts value is positive + rx_tx_addr[4] = RX_TX_ADDR_4; // set to constant, so variable part of rx_tx_addr can be stored in 32-bit value + } + + // The hopping channels are determined by the value of rx_tx_addr[0] + static void set_hopping_channels(void) + { + rf_channel_index = 0; + const uint8_t addr = rx_tx_addr[0]; + uint8_t ch = 0x10 + (addr & 0x07); + for (int i = 0; i < rf_channel_count; ++i) { + rf_channels[i] = ch; + ch += 0x0c; + } + } + + static void update_telemetry(void) + { + #ifdef INAV_TELEMETRY + const uint8_t observeTx = NRF24L01_ReadReg(NRF24L01_08_OBSERVE_TX); + const uint8_t lostPacketCount = (observeTx & NRF24L01_08_PLOS_CNT_MASK) >> 4; + // const uint8_t autoRetryCount = observeTx & NRF24L01_08_ARC_CNT_MASK; + NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_channels[rf_channel_index]); // reset packet loss counter + + lost_packet_counter += lostPacketCount; + Telemetry.value[TELEM_LTM_STATUS_RSSI] = 100 - 100 * lost_packet_counter / packet_count; + TELEMETRY_SetUpdated(TELEM_LTM_STATUS_RSSI); + + // ackPayload contains telemetry in LTM format. + // See https://github.com/stronnag/mwptools/blob/master/docs/ltm-definition.txt + // ackPayload[0] is a sequence count, LTM begins at ackPayload[2] + const uint8_t *ltm = &ackPayload[2]; + switch (ltm[0]) { // frame type + case 'G': // GPS frame + { + // LTM lat/long: int32 decimal degrees * 10,000,000 (1E7) + // LTM 1 degree = 1,000,000 + // Deviation longitude: +/-180degrees = +/- 180*60*60*1000; W if value<0, E if value>=0; -180degrees = 180degrees + // Deviation latitude: +/-90degrees = +/- 90*60*60*1000; S if value<0, N if value>=0 + // Deviation 1 degree = 3,600,000 + // Scale factor = 36/10 = 18/5 + uint32_t latitude; + memcpy(&latitude, <m[1], sizeof(uint32_t)); + Telemetry.gps.latitude = latitude * 18 / 5; + TELEMETRY_SetUpdated(TELEM_GPS_LAT); + + uint32_t longitude; + memcpy(&longitude, <m[5], sizeof(uint32_t)); + Telemetry.gps.longitude = longitude * 18 / 5; + TELEMETRY_SetUpdated(TELEM_GPS_LONG); + + Telemetry.gps.velocity = ltm[9] * 1000; // LTM m/s; DEV mm/s + TELEMETRY_SetUpdated(TELEM_GPS_SPEED); + + uint32_t altitude; + memcpy(&altitude, <m[10], sizeof(uint32_t)); + Telemetry.gps.altitude = altitude * 10; // LTM:cm; DEV:mm + TELEMETRY_SetUpdated(TELEM_GPS_ALT); + + Telemetry.gps.satcount = ltm[14] >> 2; + TELEMETRY_SetUpdated(TELEM_GPS_SATCOUNT); + } + break; + case 'A': // Attitude frame + { + const uint16_t heading = ltm[5] | (ltm[6] << 8); + Telemetry.gps.heading = heading; + TELEMETRY_SetUpdated(TELEM_GPS_HEADING); + + const s16 pitch = ltm[1] | (ltm[2] << 8); + Telemetry.value[TELEM_LTM_ATTITUDE_PITCH] = pitch; // LTM:degrees [-180,180] + TELEMETRY_SetUpdated(TELEM_LTM_ATTITUDE_PITCH); + + const s16 roll = ltm[3] | (ltm[4] << 8); + Telemetry.value[TELEM_LTM_ATTITUDE_ROLL] = roll; // LTM:degrees [-180,180] + TELEMETRY_SetUpdated(TELEM_LTM_ATTITUDE_ROLL); + + Telemetry.value[TELEM_LTM_ATTITUDE_YAW] = heading; + TELEMETRY_SetUpdated(TELEM_LTM_ATTITUDE_YAW); + } + break; + case 'S': // Status frame + { + const uint16_t vBat = ltm[1] | (ltm[2] << 8); + Telemetry.value[TELEM_LTM_STATUS_VBAT] = (uint32_t)(vBat); // LTM:mV; DEV:V/10 + TELEMETRY_SetUpdated(TELEM_LTM_STATUS_VBAT); + + const uint16_t amps = ltm[3] | (ltm[4] << 8); + Telemetry.value[TELEM_LTM_STATUS_CURRENT] = (uint32_t)(amps); // LTM:mA; DEV:A/10 + TELEMETRY_SetUpdated(TELEM_LTM_STATUS_CURRENT); + + Telemetry.value[TELEM_LTM_STATUS_AIRSPEED] = ltm[6]; + TELEMETRY_SetUpdated(TELEM_LTM_STATUS_AIRSPEED); + } + break; + default: + break; + } + #endif + } + + void save_rx_tx_addr(void) + { + Model.proto_opts[PROTOOPTS_RX_TX_ADDR1] = rx_tx_addr[0] | ((uint16_t)rx_tx_addr[1] << 8); + Model.proto_opts[PROTOOPTS_RX_TX_ADDR2] = rx_tx_addr[2] | ((uint16_t)rx_tx_addr[3] << 8); + } + + void load_rx_tx_addr(void) + { + rx_tx_addr[0] = (Model.proto_opts[PROTOOPTS_RX_TX_ADDR1]) & 0xff; + rx_tx_addr[1] = (Model.proto_opts[PROTOOPTS_RX_TX_ADDR1] >> 8) & 0xff; + rx_tx_addr[2] = (Model.proto_opts[PROTOOPTS_RX_TX_ADDR2]) & 0xff; + rx_tx_addr[3] = (Model.proto_opts[PROTOOPTS_RX_TX_ADDR2] >> 8) & 0xff; + rx_tx_addr[4] = RX_TX_ADDR_4; // set to constant, so variable part of rx_tx_addr can be stored in 32-bit value + } + + static void inav_init() + { + // check options before proceeding with initialiasation + packet_length = INAV_PROTOCOL_PAYLOAD_SIZE_DEFAULT; + rc_channel_count = RC_CHANNEL_COUNT_DEFAULT; + rf_channel_count = RF_CHANNEL_COUNT_DEFAULT; + if(IS_AUTOBIND_FLAG_on) { + initialize_rx_tx_addr(); + save_rx_tx_addr(); + } else { + load_rx_tx_addr(); + } + + packet_count = 0; + set_hopping_channels(); + } + + static uint16_t inav_cb() + { + static uint16_t bind_counter; + static uint8_t bind_acked; + + switch (phase) { + case PHASE_INAV_INIT: + phase = PHASE_INAV_BIND; + bind_counter = BIND_COUNT; + bind_acked = 0; + return FIRST_PACKET_DELAY; + break; + + case PHASE_INAV_BIND: + if (bind_counter == 0) { + set_data_phase(); + BIND_DONE; + } else { + if (packet_ack() == PKT_ACKED) { + bind_acked = 1; + } + if (bind_acked == 1) { + // bind packet acked, so set bind_counter to zero to enter data phase on next callback + bind_counter = 0; + return PACKET_PERIOD; + } + send_packet(BIND_PACKET); + --bind_counter; + } + break; + + case PHASE_INAV_DATA: + update_telemetry(); + /*#define PACKET_CHKTIME 500 // time to wait if packet not yet acknowledged or timed out + if (packet_ack() == PKT_PENDING) { + return PACKET_CHKTIME; // packet send not yet complete + }*/ + packet_ack(); + send_packet(DATA_PACKET); + break; + } + return PACKET_PERIOD; + } + + static uint8_t INAV_setup() + { + CLOCK_StopTimer(); + tx_power = Model.tx_power; + ackPayloadSize = 0; + memset(ackPayload, 0, NRF24L01_MAX_PAYLOAD_SIZE); + inav_init(bind); + init_nrf24l01(); + + #ifdef INAV_TELEMETRY + memset(&Telemetry, 0, sizeof(Telemetry)); + TELEMETRY_SetType(TELEM_LTM); + #endif + + if(IS_AUTOBIND_FLAG_on) { + phase = PHASE_INAV_INIT; +// PROTOCOL_SetBindState(BIND_COUNT * PACKET_PERIOD / 1000); + } else { + set_data_phase(); +// BIND_DONE; + } + return INITIAL_WAIT; + } +/* + const void *INAV_Cmds(enum ProtoCmds cmd) + { + switch(cmd) { + case PROTOCMD_INIT: initialize(INIT_BIND); return 0; + case PROTOCMD_DEINIT: + case PROTOCMD_RESET: + CLOCK_StopTimer(); + return (void *)(NRF24L01_Reset() ? 1L : -1L); + //case PROTOCMD_CHECK_AUTOBIND: return 0; + case PROTOCMD_CHECK_AUTOBIND: return (void *)1L; // always Autobind + case PROTOCMD_BIND: initialize(INIT_BIND); return 0; + case PROTOCMD_NUMCHAN: return (void *)((long)rc_channel_count); + case PROTOCMD_DEFAULT_NUMCHAN: return (void *)((long)RC_CHANNEL_COUNT_DEFAULT); + case PROTOCMD_CURRENT_ID: return 0; + case PROTOCMD_GETOPTIONS: return inav_opts; + #ifdef INAV_TELEMETRY + case PROTOCMD_TELEMETRYSTATE: return (void *)(long)(Model.proto_opts[PROTOOPTS_TELEMETRY] == TELEM_ON ? PROTO_TELEM_ON : PROTO_TELEM_OFF); + #else + case PROTOCMD_TELEMETRYSTATE: return (void *)(long)PROTO_TELEM_UNSUPPORTED; + #endif + default: break; + } + return 0; + } +*/ +#endif + diff --git a/Multiprotocol/Nrf24l01_ne260.ino b/Multiprotocol/Nrf24l01_ne260.ino index 598c15b..85f6ec3 100644 --- a/Multiprotocol/Nrf24l01_ne260.ino +++ b/Multiprotocol/Nrf24l01_ne260.ino @@ -189,9 +189,9 @@ static void ne260_init() { NRF24L01_WriteReg(NRF24L01_07_STATUS, vRX_DR | vTX_DS | vMAX_RT); // reset the IRQ flags } -static void send_data_packet() { +static void send_ne_data_packet() { for(int i = 0; i < 4; i++) { - uint32_t value = (uint32_t)Servo_data[NE_ch[i]] * 0x40 / PPM_MAX + 0x40; + uint32_t value = (uint32_t)map(limit_channel_100(NE_ch[i]),servo_min_100,servo_max_100,0,80); if (value > 0x7f) value = 0x7f; else if(value < 0) @@ -210,7 +210,7 @@ static void send_data_packet() { NRF24L01_WritePayload((uint8_t*) packet, PACKET_NE_LENGTH); } -static void send_bind_packet() { +static void send_ne_bind_packet() { packet[0] = 0xAA; //throttle packet[1] = 0xAA; //rudder packet[2] = 0xAA; //elevator @@ -243,7 +243,7 @@ static uint16_t ne260_cb() { } } NRF24L01_SetTxRxMode(TX_EN); - send_bind_packet(); + send_ne_bind_packet(); state = NE260_BINDRX; return 500; } else if (state == NE260_BINDRX) { @@ -259,7 +259,7 @@ static uint16_t ne260_cb() { else if (state == NE260_DATA1) { neChannel = 10; state = NE260_DATA2; } else if (state == NE260_DATA2) { neChannel = 30; state = NE260_DATA3; } else if (state == NE260_DATA3) { neChannel = 50; state = NE260_DATA1; } - send_data_packet(); + send_ne_data_packet(); return 2500; } diff --git a/Multiprotocol/Nrf24l01_udi.ino b/Multiprotocol/Nrf24l01_udi.ino index a8eac63..de078eb 100644 --- a/Multiprotocol/Nrf24l01_udi.ino +++ b/Multiprotocol/Nrf24l01_udi.ino @@ -112,9 +112,9 @@ static const uint8_t * rf_udi_channels = NULL; static uint8_t packet_udi_ack() { - switch (NRF24L01_ReadReg(NRF24L01_07_STATUS) & (BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT))) { - case BV(NRF24L01_07_TX_DS): return PKT_ACKED; - case BV(NRF24L01_07_MAX_RT): return PKT_TIMEOUT; + switch (NRF24L01_ReadReg(NRF24L01_07_STATUS) & (_BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_MAX_RT))) { + case _BV(NRF24L01_07_TX_DS): return PKT_ACKED; + case _BV(NRF24L01_07_MAX_RT): return PKT_TIMEOUT; } return PKT_PENDING; } @@ -207,7 +207,7 @@ static void UDI_init2() // Turn radio power on NRF24L01_SetTxRxMode(TX_EN); - uint8_t config = BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP); + uint8_t config = _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP); NRF24L01_WriteReg(NRF24L01_00_CONFIG, config); // Implicit delay in callback // delayMicroseconds(150); @@ -239,15 +239,11 @@ static void add_pkt_checksum() static uint8_t convert_channel(uint8_t num, uint8_t chn_max, uint8_t sign_ofs) { - uint32_t ch = Servo_data[num]; - if (ch < PPM_MIN) { - ch = PPM_MIN; - } else if (ch > PPM_MAX) { - ch = PPM_MAX; - } + uint32_t ch = map(limit_channel_100(num),servo_min_100,servo_max_100,-1000, 1000); + uint32_t chn_val; - if (sign_ofs) chn_val = (((ch * chn_max / PPM_MAX) + sign_ofs) >> 1); - else chn_val = (ch * chn_max / PPM_MAX); + if (sign_ofs) chn_val = (((ch * chn_max / servo_max_100) + sign_ofs) >> 1); + else chn_val = (ch * chn_max / servo_max_100); if (chn_val < 0) chn_val = 0; else if (chn_val > chn_max) chn_val = chn_max; return (uint8_t) chn_val; @@ -260,8 +256,8 @@ static void read_controls(uint8_t* throttle, uint8_t* rudder, uint8_t* elevator, // Protocol is registered AETRG, that is // Aileron is channel 0, Elevator - 1, Throttle - 2, Rudder - 3 // Sometimes due to imperfect calibration or mixer settings - // throttle can be less than PPM_MIN or larger than - // PPM_MAX. As we have no space here, we hard-limit + // throttle can be less than servo_min_100 or larger than + // servo_max_100. As we have no space here, we hard-limit // channels values by min..max range // Channel 3: throttle is 0-100 @@ -277,28 +273,28 @@ static void read_controls(uint8_t* throttle, uint8_t* rudder, uint8_t* elevator, *aileron = convert_channel(AILERON, 0x3f, 0x20); // Channel 5 - if (Servo_data[AUX1] <= 0) *flags &= ~UDI_FLIP360; - else *flags |= UDI_FLIP360; + if (Servo_AUX1) *flags |= UDI_FLIP360; + else *flags &= ~UDI_FLIP360; // Channel 6 - if (Servo_data[AUX2] <= 0) *flags &= ~UDI_FLIP; - else *flags |= UDI_FLIP; + if (Servo_AUX2) *flags |= UDI_FLIP; + else *flags &= ~UDI_FLIP; // Channel 7 - if (Servo_data[AUX3] <= 0) *flags &= ~UDI_CAMERA; - else *flags |= UDI_CAMERA; + if (Servo_AUX3) *flags |= UDI_CAMERA; + else *flags &= ~UDI_CAMERA; // Channel 8 - if (Servo_data[AUX4] <= 0) *flags &= ~UDI_VIDEO; - else *flags |= UDI_VIDEO; + if (Servo_AUX4) *flags |= UDI_VIDEO; + else *flags &= ~UDI_VIDEO; // Channel 9 - if (Servo_data[AUX5] <= 0) *flags &= ~UDI_LIGHTS; - else *flags |= UDI_LIGHTS; + if (Servo_AUX5) *flags |= UDI_LIGHTS; + else *flags &= ~UDI_LIGHTS; // Channel 10 - if (Servo_data[AUX6] <= 0) *flags &= ~UDI_MODE2; - else *flags |= UDI_MODE2; + if (Servo_AUX6) *flags |= UDI_MODE2; + else *flags &= ~UDI_MODE2; } static void send_udi_packet(uint8_t bind) @@ -325,7 +321,7 @@ static void send_udi_packet(uint8_t bind) packet[5] = randoms[1]; packet[6] = randoms[2]; if (sub_protocol == U839_2014) { - packet[7] = (packet_counter < 4) ? 0x3f : 0x04; // first four packets use 0x3f here, then 0x04 + packet[7] = (packet_count < 4) ? 0x3f : 0x04; // first four packets use 0x3f here, then 0x04 } } else if (bind == 2) { // Bind phase 2 @@ -374,7 +370,7 @@ static void send_udi_packet(uint8_t bind) uint8_t status = NRF24L01_ReadReg(NRF24L01_07_STATUS); NRF24L01_WriteReg(NRF24L01_07_STATUS,status); - if (packet_sent && bind && (status & BV(NRF24L01_07_TX_DS))) { + if (packet_sent && bind && (status & _BV(NRF24L01_07_TX_DS))) { bind_step_success = 1; } @@ -396,7 +392,7 @@ static void send_udi_packet(uint8_t bind) } NRF24L01_FlushTx(); NRF24L01_WritePayload(packet, payload_size); - ++packet_counter; + ++packet_count; packet_sent = 1; } @@ -433,7 +429,7 @@ static uint16_t UDI_callback() { break; case UDI_BIND1_RX: // Check if data has been received - if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR) ) { + if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR) ) { uint8_t data[UDI_PAYLOADSIZE]; NRF24L01_ReadPayload(data, payload_size); NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x4E); // On original TX this is done on LAST packet check only ! @@ -514,7 +510,7 @@ static uint16_t UDI_callback() { case UDI_BIND2_RX: // Check if data has been received - if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR) ) { + if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR) ) { uint8_t data[UDI_PAYLOADSIZE]; NRF24L01_ReadPayload(data, payload_size); NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x4E); @@ -570,7 +566,7 @@ static uint16_t UDI_callback() { static uint16_t UDI_setup() { - packet_counter = 0; + packet_count = 0; UDI_init(); phase = UDI_INIT2; diff --git a/Multiprotocol/README.md b/Multiprotocol/README.md new file mode 100644 index 0000000..037ea5f --- /dev/null +++ b/Multiprotocol/README.md @@ -0,0 +1,230 @@ +# DIY-Multiprotocol-TX-Module + +![Screenshot](http://static.rcgroups.net/forums/attachments/4/0/8/5/8/3/t7952733-114-thumb-P4100002.JPG?d=1433910155) ![Screenshot](http://static.rcgroups.net/forums/attachments/4/0/8/5/8/3/t7952734-189-thumb-P4100003.JPG?d=1433910159) + +Fork du projet https://github.com/pascallanger/DIY-Multiprotocol-TX-Module + +Afin d'ajouter : +- Un rebind hardware en PPM +- La radio TARANIS (TAERB, B = rebind ;-) ) et redéclaration des radios + + + +Programme des évolutions : +- Ajout du futur protocole INAV + + +#Schematic +![Screenshot](http://static.rcgroups.net/forums/attachments/4/0/8/5/8/3/a8443844-119-multiprotocol_diagram_rotary_serial_2.jpg) + +Notes: +- Attention: All modules are 3.3V only, never power them with 5V. + + +#Protocoles ajoutés mais non testés (Issue de Deviation) +##Other +###OPENLRS +Empty protocol + +##CYRF6936 RF Module +###J6PRO +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12 +---|---|---|---|---|---|---|---|---|---|---|--- +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12 + +###WK2x01 +Autobind + +####Sub_protocol WK2401 +CH1|CH2|CH3|CH4 +---|---|---|--- +CH1|CH2|CH3|CH4 + + +####Sub_protocol WK2601 +Option: + + 0 = 5+1 + 2 = 6+1 + ..1 = Hélicoptère (. = autres options pour ce mode) + .01 = Hélicoptère normal + .11 = Hélicoptère avec pit inversé + 0.1 = Pitch curve -100 + 1.1 = Pitch curve 100 + +CH1|CH2|CH3|CH4|CH5|CH6|CH7 +---|---|---|---|---|---|--- +CH1|CH2|CH3|CH4|???|CONF|Gyro & Rudder mix + +CONF: Option 1 = Rate Throtle + + Option 2 = Pitch + + +####Sub_protocol WK2801 +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8 +---|---|---|---|---|---|---|--- +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8 + + +##A7105 RF Module +###Flysky AFHDS2A +Telemetry enabled for battery voltage and TX RSSI +Option= 0-PWM_IBUS 1-PPM_IBUS 2-PWM_SBUS 3-PPM_SBUS + +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15 +---|---|---|---|---|---|---|---|---|---|---|---|---|---|--- +T|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|Failsave T + +###HUBSAN +Models: Hubsan H102D, H107/L/C/D and Hubsan H107P/C+/D+ + +Autobind protocol + +Telemetry enabled for battery voltage and TX RSSI + +Option=vTX frequency (H107D) 5645 - 5900 MHz + +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9 +---|---|---|---|---|---|---|---|--- +A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS +####Sub_protocol H301 +CH5|CH6|CH7|CH8 +---|---|---|--- +LED|STAB|RTH|VIDEO + +####Sub_protocol H501 +CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12 +---|---|---|---|---|---|---|---|---|---|---|--- +FLIP|LIGHT|RTH|VIDEO|HEADLESS|GPS_HOLD|ALT_HOLD|SNAPSHOT + +###Joysway +CH1|CH2|CH3|CH4 +---|---|---|--- +A|E|T|R + +##CC2500 RF Module +###SKYARTEC +CH1|CH2|CH3|CH4|CH5|CH6|CH7 +---|---|---|---|---|---|--- + ? | ? | ? | ? | ? | ? | ? + +##NRF24L01 RF Module +###BLUEFLY +Autobind + +CH1|CH2|CH3|CH4|CH5|CH6 +---|---|---|---|---|--- +A|E|T|R|GEAR|PITCH + +###CFLIE +Modele: CrazyFlie Nano quad + +Autobind + +CH1|CH2|CH3|CH4 +---|---|---|--- +A|E|T|R + +###ESKY150 + +Autobind + +CH1|CH2|CH3|CH4 +---|---|---|--- +A|E|T|R + +###FBL100 +Autobind + +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8 +---|---|---|---|---|---|---|--- + ? | ? | ? | ? | ? | ? | ? | ? + +####Sub_protocol HP100 +Same channels assignement as above. + +###Fy326 +Autobind + +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9 +---|---|---|---|---|---|---|---|--- +A|E|T|R|FLIP|HEADLESS|RTH|Calibrate|Expert + +####Sub_protocol FY319 +Same channels assignement as above. + +###H377 +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8 +---|---|---|---|---|---|---|--- +A|E|T|R|CH5|CH6|CH7|CH8 + +###HM830 +Modele: HM Hobby HM830 RC Paper Airplane + +Autobind + +CH1|CH2|CH3|CH4|CH5 +---|---|---|--- +A|Turbo|T|Trim|Bouton + +###HONTAI +Autobind protocol + +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11 +---|---|---|---|---|---|---|---|---|----|---- +A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|CAL + +####Sub_protocol HONTAI +####Sub_protocol JJRCX1 +CH6| +---| +ARM| + +####Sub_protocol X5C1 +X5C1 clone +CH5|CH6|CH7|CH8|CH9|CH10|CH11 +---|---|---|---|---|----|---- +FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|CAL +####Sub_protocol FQ777 +Format FQ777-951C + +CH6|CH7|CH8|CH9 +---|---|---|--- +FLIP|SNAPSHOT|VIDEO|HEADLESS + +###INAV +En cours de passage + +###NE260 +Modele: Nine Eagles SoloPro + +Autobind + +CH1|CH2|CH3|CH4 +---|---|---|--- +A|E|T|R + +###UDI +Modele: Known UDI 2.4GHz protocol variants, all using BK2421 +* UDI U819 coaxial 3ch helicoper +* UDI U816/817/818 quadcopters + - "V1" with orange LED on TX, U816 RX labeled '' , U817/U818 RX labeled 'UD-U817B' + - "V2" with red LEDs on TX, U816 RX labeled '', U817/U818 RX labeled 'UD-U817OG' + - "V3" with green LEDs on TX. Did not get my hands on yet. +* U830 mini quadcopter with tilt steering ("Protocol 2014") +* U839 nano quadcopter ("Protocol 2014") + +Autobind + +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10 +---|---|---|---|---|---|---|---|---|--- +A|E|T|R|FLIP 360|FLIP|VIDEO|LED|MODE 2 + +####Sub_protocol U816_V1 (orange) +####Sub_protocol U816_V2 (red) +####Sub_protocol U839_2014 +Same channels assignement as above. + + +###D'autres à venir \ No newline at end of file diff --git a/Multiprotocol/SHENQI_nrf24l01.ino b/Multiprotocol/SHENQI_nrf24l01.ino index b8ab94b..2ffc2fc 100644 --- a/Multiprotocol/SHENQI_nrf24l01.ino +++ b/Multiprotocol/SHENQI_nrf24l01.ino @@ -1,5 +1,3 @@ -<<<<<<< HEAD -======= /* 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 @@ -15,7 +13,6 @@ along with Multiprotocol. If not, see . */ ->>>>>>> refs/remotes/pascallanger/master #if defined(SHENQI_NRF24L01_INO) #include "iface_nrf24l01.h" @@ -42,17 +39,10 @@ void SHENQI_init() NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5 bytes rx/tx address -<<<<<<< HEAD - LT8910_Config(4, 8, _BV(LT8910_CRC_ON)|_BV(LT8910_PACKET_LENGTH_EN), 0xAA); - LT8910_SetChannel(2); - LT8910_SetAddress((uint8_t *)"\x9A\x9A\x9A\x9A",4); - LT8910_SetTxRxMode(RX_EN); -======= LT8900_Config(4, 8, _BV(LT8900_CRC_ON)|_BV(LT8900_PACKET_LENGTH_EN), 0xAA); LT8900_SetChannel(2); LT8900_SetAddress((uint8_t *)"\x9A\x9A\x9A\x9A",4); LT8900_SetTxRxMode(RX_EN); ->>>>>>> refs/remotes/pascallanger/master } void SHENQI_send_packet() @@ -61,16 +51,6 @@ void SHENQI_send_packet() if(packet_count==0) { uint8_t bind_addr[4]; -<<<<<<< HEAD - bind_addr[0]=0x9A; - bind_addr[1]=0x9A; - bind_addr[2]=rx_tx_addr[2]; - bind_addr[3]=rx_tx_addr[3]; - LT8910_SetAddress(bind_addr,4); - LT8910_SetChannel(2); - packet[1]=rx_tx_addr[1]; - packet[2]=rx_tx_addr[0]; -======= bind_addr[0]=rx_tx_addr[0]; bind_addr[1]=rx_tx_addr[1]; bind_addr[2]=0x9A; @@ -79,39 +59,24 @@ void SHENQI_send_packet() LT8900_SetChannel(2); packet[1]=rx_tx_addr[2]; packet[2]=rx_tx_addr[3]; ->>>>>>> refs/remotes/pascallanger/master packet_period=2508; } else { -<<<<<<< HEAD - LT8910_SetAddress(rx_tx_addr,4); - packet[1]=255-convert_channel_8b(RUDDER); - packet[2]=255-convert_channel_8b_scale(THROTTLE,0x60,0xA0); - uint8_t freq=pgm_read_byte_near(&SHENQI_Freq[hopping_frequency_no])+(rx_tx_addr[1]&0x0F); - LT8910_SetChannel(freq); -======= LT8900_SetAddress(rx_tx_addr,4); packet[1]=255-convert_channel_8b(RUDDER); packet[2]=255-convert_channel_8b_scale(THROTTLE,0x60,0xA0); uint8_t freq=pgm_read_byte_near(&SHENQI_Freq[hopping_frequency_no])+(rx_tx_addr[2]&0x0F); LT8900_SetChannel(freq); ->>>>>>> refs/remotes/pascallanger/master hopping_frequency_no++; if(hopping_frequency_no==60) hopping_frequency_no=0; packet_period=1750; } // Send packet + 1 retransmit - not sure why but needed (not present on original TX...) -<<<<<<< HEAD - LT8910_WritePayload(packet,3); - while(NRF24L01_packet_ack()!=PKT_ACKED); - LT8910_WritePayload(packet,3); -======= LT8900_WritePayload(packet,3); while(NRF24L01_packet_ack()!=PKT_ACKED); LT8900_WritePayload(packet,3); ->>>>>>> refs/remotes/pascallanger/master packet_count++; if(packet_count==7) @@ -129,16 +94,6 @@ uint16_t SHENQI_callback() SHENQI_send_packet(); else { -<<<<<<< HEAD - if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR)) - { - if(LT8910_ReadPayload(packet, 3)) - { - BIND_DONE; - rx_tx_addr[3]=packet[1]; - rx_tx_addr[2]=packet[2]; - LT8910_SetTxRxMode(TX_EN); -======= if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) { if(LT8900_ReadPayload(packet, 3)) @@ -147,7 +102,6 @@ uint16_t SHENQI_callback() rx_tx_addr[0]=packet[1]; rx_tx_addr[1]=packet[2]; LT8900_SetTxRxMode(TX_EN); ->>>>>>> refs/remotes/pascallanger/master packet_period=14000; } NRF24L01_FlushRx(); @@ -162,11 +116,7 @@ uint16_t initSHENQI() SHENQI_init(); hopping_frequency_no = 0; packet_count=0; -<<<<<<< HEAD - packet_period=100; -======= packet_period=500; ->>>>>>> refs/remotes/pascallanger/master return 1000; } diff --git a/Multiprotocol/TX_Def.h b/Multiprotocol/TX_Def.h index 08e131a..66193d0 100644 --- a/Multiprotocol/TX_Def.h +++ b/Multiprotocol/TX_Def.h @@ -22,6 +22,16 @@ #define PPM_MIN_125 1000 // 125% #endif +// TAARANIS PPM and channels +#if defined(TX_TARANIS) + #define PPM_MAX_100 1900 // 100% + #define PPM_MIN_100 1100 // 100% + #define PPM_MAX_125 2000 // 125% + #define PPM_MIN_125 1000 // 125% + + #define INVERT_TELEMETRY +#endif + // HISKY #if defined(TX_HISKY) #define PPM_MAX_100 1900 // 100% @@ -37,7 +47,6 @@ #define PPM_MAX_125 2050 // 125% #define PPM_MIN_125 1150 // 125% #endif - //Serial MIN MAX values #define SERIAL_MAX_100 2012 // 100% #define SERIAL_MIN_100 988 // 100% diff --git a/Multiprotocol/Telemetry.ino b/Multiprotocol/Telemetry.ino index ad5e419..af368ad 100644 --- a/Multiprotocol/Telemetry.ino +++ b/Multiprotocol/Telemetry.ino @@ -1,178 +1,3 @@ -<<<<<<< HEAD -//************************************* -// FrSky Telemetry serial code * -// By Midelic on RCGroups * -//************************************* - -#if defined TELEMETRY - #if defined FRSKYX_CC2500_INO - #define SPORT_TELEMETRY - #endif - #if defined FRSKY_CC2500_INO - #define HUB_TELEMETRY - #endif - #if defined SPORT_TELEMETRY - #define SPORT_TELEMETRY - #define SPORT_TIME 12000 - uint32_t last=0; - uint8_t sport_counter=0; - uint8_t RxBt=0; - uint8_t rssi; - uint8_t ADC2; - #endif - #if defined HUB_TELEMETRY - #define MAX_PKTX 10 - uint8_t pktx[MAX_PKTX]; - uint8_t index; - uint8_t prev_index; - uint8_t pass = 0; - #endif - #define USER_MAX_BYTES 6 - uint8_t frame[18]; - - void frskySendStuffed() - { - Serial_write(0x7E); - for (uint8_t i = 0; i < 9; i++) - { - if ((frame[i] == 0x7e) || (frame[i] == 0x7d)) - { - Serial_write(0x7D); - frame[i] ^= 0x20; - } - Serial_write(frame[i]); - } - Serial_write(0x7E); - } - - void compute_RSSIdbm(){ - - RSSI_dBm = (((uint16_t)(pktt[len-2])*18)>>5); - if(pktt[len-2] >=128) - RSSI_dBm -= 82; - else - 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;i0) - telemetry_counter=(telemetry_counter+1)%32; - } - } - - void frsky_link_frame() - { - frame[0] = 0xFE; - if ((cur_protocol[0]&0x1F)==MODE_FRSKY) - { - compute_RSSIdbm(); - frame[1] = pktt[3]; - frame[2] = pktt[4]; - frame[3] = (uint8_t)RSSI_dBm; - frame[4] = pktt[5]*2; - } - else - if ((cur_protocol[0]&0x1F)==MODE_HUBSAN) - { - frame[1] = v_lipo*2; //v_lipo; common 0x2A=42/10=4.2V - frame[2] = frame[1]; - frame[3] = 0x00; - frame[4] = (uint8_t)RSSI_dBm; - } - frame[5] = frame[6] = frame[7] = frame[8] = 0; - frskySendStuffed(); - } - - #if defined HUB_TELEMETRY - void frsky_user_frame() - { - uint8_t indexx = 0, c=0, j=8, n=0, i; - - if(pktt[6]>0 && pktt[6]<=MAX_PKTX) - {//only valid hub frames - frame[0] = 0xFD; - frame[1] = 0; - frame[2] = pktt[7]; - - switch(pass) - { - case 0: - indexx=pktt[6]; - for(i=0;i>>>>>> refs/remotes/pascallanger/master 7E 98 10 05 F1 20 23 0F 00 A6 SWR_ID 7E 98 10 01 F1 33 00 00 00 C9 RSSI_ID 7E 98 10 04 F1 58 00 00 00 A1 BATT_ID @@ -417,24 +242,15 @@ pkt[6]|(counter++)|00 01 02 03 04 05 06 07 08 09 7E BA 10 03 F1 E2 00 00 00 18 ADC2_ID -<<<<<<< HEAD - Telemetry frames(RF) SPORT info 15 bytes - SPORT frame 6+3 bytes -======= Telemetry frames(RF) SPORT info 15 bytes payload SPORT frame valid 6+3 bytes ->>>>>>> refs/remotes/pascallanger/master [00] PKLEN 0E 0E 0E 0E [01] TXID1 DD DD DD DD [02] TXID2 6D 6D 6D 6D [03] CONST 02 02 02 02 [04] RS/RB 2C D0 2C CE //D0;CE=2*RSSI;....2C = RX battery voltage(5V from Bec) -<<<<<<< HEAD - [05] ????? 03 10 21 32 //TX/RX telemetry hand-shake bytes -======= [05] HD-SK 03 10 21 32 //TX/RX telemetry hand-shake bytes ->>>>>>> refs/remotes/pascallanger/master [06] NO.BT 00 00 06 03 //No.of valid SPORT frame bytes in the frame [07] STRM1 00 00 7E 00 [08] STRM2 00 00 1A 00 @@ -442,146 +258,6 @@ pkt[6]|(counter++)|00 01 02 03 04 05 06 07 08 09 [10] STRM4 03 03 03 03 [11] STRM5 F1 F1 F1 F1 [12] STRM6 D1 D1 D0 D0 -<<<<<<< HEAD - [13] CHKSUM1 - [14] CHKSUM2 - */ - - - void sportSend(uint8_t *p) - { - uint16_t crc_s = 0; - Serial_write(0x7e);//+9 - for (uint8_t i = 0; i < 9; i++) - { - if (i == 8) - p[i] = 0xff - crc_s; - if ((p[i] == 0x7e) || (p[i] == 0x7d)) - { - Serial_write(0x7d); - Serial_write(0x20 ^ p[i]); - } - else - Serial_write(p[i]); - if (i>0) - { - crc_s += p[i]; //0-1FF - crc_s += crc_s >> 8; //0-100 - crc_s &= 0x00ff; - } - } - } - - void sportIdle() - { - Serial_write(0x7e); - } - - void sportSendFrame() - { - //at the moment only SWR RSSI,RxBt and A2. - sport_counter = (sport_counter + 1) %9; - - for (uint8_t i=5;i<8;i++) - frame[i]=0; - - switch (sport_counter) - { - case 0: // SWR - frame[0] = 0x98; - frame[1] = 0x10; - frame[2] = 0x05; - frame[3] = 0xf1; - frame[4] = 0x20;//dummy values if swr 20230f00 - frame[5] = 0x23; - frame[6] = 0x0F; - frame[7] = 0x00; - break; - case 1: // RSSI - frame[0] = 0x98; - frame[1] = 0x10; - frame[2] = 0x01; - frame[3] = 0xf1; - frame[4] = rssi; - break; - case 2: //BATT - frame[0] = 0x98; - frame[1] = 0x10; - frame[2] = 0x04; - frame[3] = 0xf1; - frame[4] = RxBt;//a1; - break; - case 3: //ADC2(A2) - frame[0] = 0x1A; - frame[1] = 0x10; - frame[2] = 0x03; - frame[3] = 0xf1; - frame[4] = ADC2;//a2;; - break; - default: - sportIdle(); - return; - } - sportSend(frame); - } - - void process_sport_data()//only for ADC2 - { - uint8_t j=7; - if(pktt[6]>0 && pktt[6]<=USER_MAX_BYTES) - { - for(uint8_t i=0;i<6;i++) - if(pktt[j++]==0x03) - if(pktt[j]==0xF1) - { - ADC2=pktt[j+1]; - break; - } - pktt[6]=0;//new frame - } - } - #endif - - - void frskyUpdate() - { - if(telemetry_link && (cur_protocol[0]&0x1F) != MODE_FRSKYX ) - { - frsky_link_frame(); - telemetry_link=0; - return; - } - #if defined HUB_TELEMETRY - if(!telemetry_link && (cur_protocol[0]&0x1F) != MODE_HUBSAN && (cur_protocol[0]&0x1F) != MODE_FRSKYX) - { - frsky_user_frame(); - return; - } - #endif - #if defined SPORT_TELEMETRY - if ((cur_protocol[0]&0x1F)==MODE_FRSKYX) - { - if(telemetry_link) - { - process_sport_data(); - if(pktt[4]>0x36) - rssi=pktt[4]/2; - else - RxBt=pktt[4]; - telemetry_link=0; - } - uint32_t now = micros(); - if ((now - last) > SPORT_TIME) - { - sportSendFrame(); - last = now; - } - } - #endif - } - -#endif -======= [13] CHKSUM1 --|2 CRC bytes sent by RX (calculated on RX side crc16/table) [14] CHKSUM2 --| +2 appended bytes automatically RSSI and LQI/CRC bytes(len=0x0E+3); @@ -732,92 +408,92 @@ void proces_sport_data(uint8_t data) void TelemetryUpdate() { -#if defined SPORT_TELEMETRY - if (protocol==MODE_FRSKYX) - { // FrSkyX - if(telemetry_link) - { - if(pktt[4] & 0x80) - rssi=pktt[4] & 0x7F ; - else - RxBt = (pktt[4]<<1) + 1 ; - for (uint8_t i=0; i < pktt[6]; i++) - proces_sport_data(pktt[7+i]); - telemetry_link=0; + #if defined SPORT_TELEMETRY + if (protocol==MODE_FRSKYX) + { // FrSkyX + if(telemetry_link) + { + if(pktt[4] & 0x80) + rssi=pktt[4] & 0x7F ; + else + RxBt = (pktt[4]<<1) + 1 ; + for (uint8_t i=0; i < pktt[6]; i++) + proces_sport_data(pktt[7+i]); + telemetry_link=0; + } } - } -#endif + #endif // check for space in tx buffer -#ifdef BASH_SERIAL - uint8_t h ; - uint8_t t ; - h = SerialControl.head ; - t = SerialControl.tail ; - if ( h >= t ) - { - t += 64 - h ; - } - else - { - t -= h ; - } - if ( t < 32 ) - { - return ; - } + #ifdef BASH_SERIAL + uint8_t h ; + uint8_t t ; + h = SerialControl.head ; + t = SerialControl.tail ; + if ( h >= t ) + { + t += 64 - h ; + } + else + { + t -= h ; + } + if ( t < 32 ) + { + return ; + } -#else - uint8_t h ; - uint8_t t ; - h = tx_head ; - t = tx_tail ; - if ( h >= t ) - { - t += TXBUFFER_SIZE - h ; - } - else - { - t -= h ; - } - if ( t < 16 ) - { - return ; - } -#endif + #else + uint8_t h ; + uint8_t t ; + h = tx_head ; + t = tx_tail ; + if ( h >= t ) + { + t += TXBUFFER_SIZE - h ; + } + else + { + t -= h ; + } + if ( t < 16 ) + { + return ; + } + #endif #if defined DSM_TELEMETRY - if(telemetry_link && protocol == MODE_DSM ) - { // DSM - DSM_frame(); - telemetry_link=0; - return; - } + if(telemetry_link && protocol == MODE_DSM ) + { // DSM + DSM_frame(); + telemetry_link=0; + return; + } #endif if(telemetry_link && protocol != MODE_FRSKYX ) - { // FrSky + Hubsan + { // FrSky + Hubsan + Flysky AFHDS2A frsky_link_frame(); telemetry_link=0; return; } #if defined HUB_TELEMETRY - if(!telemetry_link && protocol == MODE_FRSKYD) - { // FrSky - frsky_user_frame(); - return; - } + if(!telemetry_link && protocol == MODE_FRSKYD) + { // FrSky + frsky_user_frame(); + return; + } #endif #if defined SPORT_TELEMETRY - if (protocol==MODE_FRSKYX) - { // FrSkyX - uint32_t now = micros(); - if ((now - last) > SPORT_TIME) - { - sportSendFrame(); - last += SPORT_TIME ; + if (protocol==MODE_FRSKYX) + { // FrSkyX + uint32_t now = micros(); + if ((now - last) > SPORT_TIME) + { + sportSendFrame(); + last += SPORT_TIME ; + } } - } #endif } @@ -846,19 +522,19 @@ void initTXSerial( uint8_t speed) #ifdef ENABLE_PPM if(speed==SPEED_9600) { // 9600 - #ifdef XMEGA - USARTC0.BAUDCTRLA = 207 ; - USARTC0.BAUDCTRLB = 0 ; - USARTC0.CTRLB = 0x18 ; - USARTC0.CTRLA = (USARTC0.CTRLA & 0xCF) | 0x10 ; - USARTC0.CTRLC = 0x03 ; - #else - //9600 bauds - UBRR0H = 0x00; - UBRR0L = 0x67; - UCSR0A = 0 ; // Clear X2 bit - //Set frame format to 8 data bits, none, 1 stop bit - UCSR0C = (1<>= 7 ; // Top bit if ( SerialControl.speed == SPEED_100K ) { - #ifdef INVERT_SERIAL - byteLo |= 0x02 ; // Parity bit - #else - byteLo |= 0xFC ; // Stop bits - #endif - // calc parity +#ifdef INVERT_SERIAL + byteLo |= 0x02 ; // Parity bit +#else + byteLo |= 0xFC ; // Stop bits +#endif + // calc parity temp = byte ; temp >>= 4 ; temp = byte ^ temp ; @@ -975,21 +651,21 @@ void Serial_write( uint8_t byte ) temp1 <<= 1 ; temp ^= temp1 ; temp &= 0x02 ; - #ifdef INVERT_SERIAL - byteLo ^= temp ; - #else - byteLo |= temp ; - #endif +#ifdef INVERT_SERIAL + byteLo ^= temp ; +#else + byteLo |= temp ; +#endif } else { byteLo |= 0xFE ; // Stop bit } byte <<= 1 ; - #ifdef INVERT_SERIAL - byte |= 1 ; // Start bit - #endif - uint8_t next = (SerialControl.head + 2) & 0x3f ; +#ifdef INVERT_SERIAL + byte |= 1 ; // Start bit +#endif + uint8_t next = (SerialControl.head + 2) & 0x3f ; if ( next != SerialControl.tail ) { SerialControl.data[SerialControl.head] = byte ; @@ -1007,11 +683,11 @@ void resumeBashSerial() { sei() ; // Start the transmission here - #ifdef INVERT_SERIAL - GPIOR2 = 0 ; - #else - GPIOR2 = 0x01 ; - #endif +#ifdef INVERT_SERIAL + GPIOR2 = 0 ; +#else + GPIOR2 = 0x01 ; +#endif if ( SerialControl.speed == SPEED_100K ) { GPIOR1 = 1 ; @@ -1149,4 +825,4 @@ ISR(TIMER0_OVF_vect) #endif // BASH_SERIAL #endif // TELEMETRY ->>>>>>> refs/remotes/pascallanger/master + diff --git a/Multiprotocol/YD717_nrf24l01.ino b/Multiprotocol/YD717_nrf24l01.ino index e3a3756..4e6a634 100644 --- a/Multiprotocol/YD717_nrf24l01.ino +++ b/Multiprotocol/YD717_nrf24l01.ino @@ -34,16 +34,6 @@ #define YD717_PAYLOADSIZE 8 // receive data pipes set to this size, but unused -<<<<<<< HEAD -enum { - YD717_INIT1 = 0, - YD717_BIND2, - YD717_BIND3, - YD717_DATA -}; - -======= ->>>>>>> refs/remotes/pascallanger/master static void __attribute__((unused)) yd717_send_packet(uint8_t bind) { uint8_t rudder_trim, elevator_trim, aileron_trim; @@ -149,11 +139,6 @@ static void __attribute__((unused)) yd717_init() NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07); // Set feature bits on NRF24L01_Activate(0x73); -<<<<<<< HEAD -static void __attribute__((unused)) YD717_init1() -{ -======= ->>>>>>> refs/remotes/pascallanger/master // for bind packets set address to prearranged value known to receiver uint8_t bind_rx_tx_addr[] = {0x65, 0x65, 0x65, 0x65, 0x65}; @@ -168,16 +153,6 @@ static void __attribute__((unused)) YD717_init1() NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, bind_rx_tx_addr, 5); } -<<<<<<< HEAD -static void __attribute__((unused)) YD717_init2() -{ - // set rx/tx address for data phase - NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, 5); - NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5); -} - -======= ->>>>>>> refs/remotes/pascallanger/master uint16_t yd717_callback() { if(IS_BIND_DONE_on) diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index 17c740a..556eea7 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -13,85 +13,6 @@ along with Multiprotocol. If not, see . */ -<<<<<<< HEAD -/** Multiprotocol module configuration file ***/ - -//Uncomment your TX type -#define TARANIS //TARANIS TAER (1100<->1900µs) -//#define TX_ER9X //ER9X AETR (988<->2012µs) -//#define TX_DEVO7 //DEVO7 EATR (1120<->1920µs) -//#define TX_SPEKTRUM //Spektrum TAER (1100<->1900µs) -//#define TX_HISKY //HISKY AETR (1100<->1900µs) - -//Uncomment to enable telemetry -#define TELEMETRY - -//Comment if a module is not installed -#define A7105_INSTALLED -#define CYRF6936_INSTALLED -//#define CC2500_INSTALLED -#define NFR24L01_INSTALLED - -//Comment a protocol to exclude it from compilation -#ifdef A7105_INSTALLED - #define JOYSWAY_A7105_INO - - #define FLYSKY_A7105_INO - #define HUBSAN_A7105_INO -#endif -#ifdef CYRF6936_INSTALLED - #define J6PRO_CYRF6936_INO - #define WK2x01_CYRF6936_INO - - #define DEVO_CYRF6936_INO - #define DSM2_CYRF6936_INO -#endif -#ifdef CC2500_INSTALLED - #define SKYARTEC_CC2500_INO - - #define FRSKY_CC2500_INO - #define FRSKYX_CC2500_INO -#endif -#ifdef NFR24L01_INSTALLED - #define HM830_NRF24L01_INO - #define CFlie_NRF24L01_INO - #define H377_NRF24L01_INO - #define ESKY150_NRF24L01_INO - #define HonTai_NRF24L01_INO - #define UDI_NRF24L01_INO - #define NE260_NRF24L01_INO - #define BlueFly_NRF24L01_INO //probleme gene id - #define FBL100_NRF24L01_INO // finir id - - #define BAYANG_NRF24L01_INO - #define CG023_NRF24L01_INO - #define CX10_NRF24L01_INO - #define ESKY_NRF24L01_INO - #define HISKY_NRF24L01_INO - #define KN_NRF24L01_INO - #define SLT_NRF24L01_INO - #define SYMAX_NRF24L01_INO - #define V2X2_NRF24L01_INO - #define YD717_NRF24L01_INO - #define MT99XX_NRF24L01_INO - #define MJXQ_NRF24L01_INO - #define SHENQI_NRF24L01_INO - #define FY326_NRF24L01_INO -#endif - -//Update this table to set which protocol and all associated settings are called for the corresponding dial number -const PPM_Parameters PPM_prot[15]= { -// Dial Protocol Sub protocol RX_Num Power Auto Bind Option -/* 1 */ {MODE_FLYSKY, Flysky , 0 , P_HIGH , AUTOBIND , 0 }, -/* 2 */ {MODE_HUBSAN, 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, -/* 3 */ {MODE_FRSKY , 0 , 0 , P_HIGH , NO_AUTOBIND , 0xD7 }, // D7 fine tuning -/* 4 */ {MODE_HISKY , Hisky , 0 , P_HIGH , NO_AUTOBIND , 0 }, -/* 5 */ {MODE_V2X2 , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, -/* 6 */ {MODE_DSM2 , DSM2 , 0 , P_HIGH , NO_AUTOBIND , 6 }, // 6 channels @ 11ms -/* 7 */ {MODE_DEVO , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, -/* 8 */ {MODE_YD717 , YD717 , 0 , P_HIGH , NO_AUTOBIND , 0 }, -/* 9 */ {MODE_KN , FEILUN , 0 , P_HIGH , AUTOBIND , 0 }, -======= /**********************************************/ /** Multiprotocol module configuration file ***/ /**********************************************/ @@ -102,7 +23,7 @@ const PPM_Parameters PPM_prot[15]= { //Modify the channel order based on your TX: AETR, TAER, RETA... //Examples: Flysky & DEVO is AETR, JR/Spektrum radio is TAER, Multiplex is AERT... //Default is AETR. -#define AETR +#define EATR /**************************/ @@ -112,10 +33,10 @@ const PPM_Parameters PPM_prot[15]= { //If a chip is not installed all associated protocols are disabled. //4-in-1 modules have all RF chips installed //!!!If a RF chip is present it MUST be marked as installed!!! or weird things will happen you have been warned. -#define A7105_INSTALLED -#define CYRF6936_INSTALLED -#define CC2500_INSTALLED -#define NRF24L01_INSTALLED + #define A7105_INSTALLED + #define CYRF6936_INSTALLED +// #define CC2500_INSTALLED + #define NRF24L01_INSTALLED /****************************/ @@ -126,39 +47,55 @@ const PPM_Parameters PPM_prot[15]= { //Comment the protocols you are not using with "//" to save Flash space. //The protocols below need an A7105 to be installed -#define FLYSKY_A7105_INO -#define HUBSAN_A7105_INO + #define AFHDS2A_A7105_INO +// #define JOYSWAY_A7105_INO + #define FLYSKY_A7105_INO + #define HUBSAN_A7105_INO //The protocols below need a CYRF6936 to be installed -#define DEVO_CYRF6936_INO -#define DSM_CYRF6936_INO -#define J6PRO_CYRF6936_INO +// #define WK2x01_CYRF6936_INO //!\\ //pb voie + + #define DEVO_CYRF6936_INO + #define DSM_CYRF6936_INO +// #define J6PRO_CYRF6936_INO //The protocols below need a CC2500 to be installed -#define FRSKYD_CC2500_INO -#define FRSKYV_CC2500_INO -#define FRSKYX_CC2500_INO -#define SFHSS_CC2500_INO + #define SKYARTEC_CC2500_INO + + #define FRSKYD_CC2500_INO + #define FRSKYV_CC2500_INO + #define FRSKYX_CC2500_INO + #define SFHSS_CC2500_INO //The protocols below need a NRF24L01 to be installed -#define BAYANG_NRF24L01_INO -#define CG023_NRF24L01_INO -#define CX10_NRF24L01_INO -#define ESKY_NRF24L01_INO -#define HISKY_NRF24L01_INO -#define KN_NRF24L01_INO -#define SLT_NRF24L01_INO -#define SYMAX_NRF24L01_INO -#define V2X2_NRF24L01_INO -#define YD717_NRF24L01_INO -#define MT99XX_NRF24L01_INO -#define MJXQ_NRF24L01_INO -#define SHENQI_NRF24L01_INO -#define FY326_NRF24L01_INO -#define FQ777_NRF24L01_INO -#define ASSAN_NRF24L01_INO -#define HONTAI_NRF24L01_INO - + #define HM830_NRF24L01_INO +// #define CFlie_NRF24L01_INO //!\\ //pb voie gaz +// #define H377_NRF24L01_INO +// #define ESKY150_NRF24L01_INO +// #define HonTai_NRF24L01_INO +// #define UDI_NRF24L01_INO +// #define NE260_NRF24L01_INO +// #define BlueFly_NRF24L01_INO //probleme gene id +// #define FBL100_NRF24L01_INO // finir id //!\\ //pb voie ??? + #define INAV_NRF24L01_INO + + #define BAYANG_NRF24L01_INO + #define CG023_NRF24L01_INO + #define CX10_NRF24L01_INO + #define ESKY_NRF24L01_INO +// #define HISKY_NRF24L01_INO + #define KN_NRF24L01_INO + #define SLT_NRF24L01_INO + #define SYMAX_NRF24L01_INO + #define V2X2_NRF24L01_INO + #define YD717_NRF24L01_INO +// #define MT99XX_NRF24L01_INO +// #define MJXQ_NRF24L01_INO +// #define SHENQI_NRF24L01_INO +// #define FY326_NRF24L01_INO +// #define FQ777_NRF24L01_INO +// #define ASSAN_NRF24L01_INO +// #define HONTAI_NRF24L01_INO /**************************/ /*** TELEMETRY SETTINGS ***/ @@ -173,9 +110,9 @@ const PPM_Parameters PPM_prot[15]= { //#define INVERT_TELEMETRY //Comment a line to disable a protocol telemetry -#define DSM_TELEMETRY -#define SPORT_TELEMETRY -#define HUB_TELEMETRY + #define DSM_TELEMETRY + #define SPORT_TELEMETRY + #define HUB_TELEMETRY /****************************/ @@ -200,7 +137,8 @@ const PPM_Parameters PPM_prot[15]= { //It is important for the module to know the endpoints of your radio. //Below are some standard transmitters already preconfigured. //Uncomment only the one which matches your transmitter. -#define TX_ER9X //ER9X/ERSKY9X/OpenTX ( 988<->2012µs) +//#define TX_ER9X //ER9X/ERSKY9X/OpenTX ( 988<->2012µs) +#define TX_TARANIS //TARANIS TAER (1100<->1900µs) //#define TX_DEVO7 //DEVO (1120<->1920µs) //#define TX_SPEKTRUM //Spektrum (1100<->1900µs) //#define TX_HISKY //HISKY (1100<->1900µs) @@ -225,7 +163,7 @@ const PPM_Parameters PPM_prot[15]= { //Example: You can associate multiple times the same protocol to different dial positions to take advantage of the model match (RX_Num) const PPM_Parameters PPM_prot[15]= { // Dial Protocol Sub protocol RX_Num Power Auto Bind Option -/* 1 */ {MODE_FLYSKY, Flysky , 0 , P_HIGH , NO_AUTOBIND , 0 }, +/* 1 */ {MODE_FLYSKY, Flysky , 0 , P_HIGH , AUTOBIND , 0 }, /* 2 */ {MODE_HUBSAN, 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, /* 3 */ {MODE_FRSKYD, 0 , 0 , P_HIGH , NO_AUTOBIND , 40 }, // option=fine freq tuning /* 4 */ {MODE_HISKY , Hisky , 0 , P_HIGH , NO_AUTOBIND , 0 }, @@ -234,7 +172,6 @@ const PPM_Parameters PPM_prot[15]= { /* 7 */ {MODE_DEVO , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, /* 8 */ {MODE_YD717 , YD717 , 0 , P_HIGH , NO_AUTOBIND , 0 }, /* 9 */ {MODE_KN , WLTOYS , 0 , P_HIGH , NO_AUTOBIND , 0 }, ->>>>>>> refs/remotes/pascallanger/master /* 10 */ {MODE_SYMAX , SYMAX , 0 , P_HIGH , NO_AUTOBIND , 0 }, /* 11 */ {MODE_SLT , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, /* 12 */ {MODE_CX10 , CX10_BLUE , 0 , P_HIGH , NO_AUTOBIND , 0 }, @@ -242,11 +179,7 @@ const PPM_Parameters PPM_prot[15]= { /* 14 */ {MODE_BAYANG, 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, /* 15 */ {MODE_SYMAX , SYMAX5C , 0 , P_HIGH , NO_AUTOBIND , 0 } }; -<<<<<<< HEAD -/* Available protocols and associated sub protocols: -======= /* Available protocols and associated sub protocols to pick and choose from ->>>>>>> refs/remotes/pascallanger/master MODE_FLYSKY Flysky V9X9 @@ -254,28 +187,18 @@ const PPM_Parameters PPM_prot[15]= { V912 MODE_HUBSAN NONE -<<<<<<< HEAD - MODE_FRSKY -======= MODE_FRSKYD ->>>>>>> refs/remotes/pascallanger/master NONE MODE_HISKY Hisky HK310 MODE_V2X2 NONE -<<<<<<< HEAD - MODE_DSM2 - DSM2 - DSMX -======= MODE_DSM DSM2_22 DSM2_11 DSMX_22 DSMX_11 ->>>>>>> refs/remotes/pascallanger/master MODE_DEVO NONE MODE_YD717 @@ -308,142 +231,26 @@ const PPM_Parameters PPM_prot[15]= { MODE_BAYANG NONE MODE_FRSKYX -<<<<<<< HEAD - NONE -======= CH_16 CH_8 ->>>>>>> refs/remotes/pascallanger/master MODE_ESKY NONE MODE_MT99XX MT99 H7 YZ -<<<<<<< HEAD -======= LS ->>>>>>> refs/remotes/pascallanger/master MODE_MJXQ WLH08 X600 X800 H26D -<<<<<<< HEAD + E010 MODE_SHENQI NONE MODE_FY326 FY326 FY319 - -RX_Num value between 0 and 15 - -Power P_HIGH or P_LOW - -Auto Bind AUTOBIND or NO_AUTOBIND - -Option value between 0 and 255. 0xD7 or 0x00 for Frsky fine tuning. -*/ - -//****************** -//TX definitions with timing endpoints and channels order - -// Turnigy PPM and channels -#if defined(TX_ER9X) - #define PPM_MAX 2140 - #define PPM_MIN 860 - #define PPM_MAX_100 2012 - #define PPM_MIN_100 988 - #define AETR -#endif - -// Devo PPM and channels -#if defined(TX_DEVO7) - #define PPM_MAX 2100 - #define PPM_MIN 900 - #define PPM_MAX_100 1920 - #define PPM_MIN_100 1120 - #define EATR -#endif - -// SPEKTRUM PPM and channels -#if defined(TX_SPEKTRUM) - #define PPM_MAX 2000 - #define PPM_MIN 1000 - #define PPM_MAX_100 1900 - #define PPM_MIN_100 1100 - #define TAER -#endif - -// TARANIS PPM and channels -#if defined(TARANIS) - #define PPM_MAX 2000 - #define PPM_MIN 1000 - #define PPM_MAX_100 1900 - #define PPM_MIN_100 1100 - #define EATR -#endif - -// HISKY -#if defined(TX_HISKY) - #define PPM_MAX 2000 - #define PPM_MIN 1000 - #define PPM_MAX_100 1900 - #define PPM_MIN_100 1100 - #define AETR -#endif - -#if defined(EATR) - enum chan_order{ - ELEVATOR=0, - AILERON, - THROTTLE, - RUDDER, - }; -#endif - -#if defined(TAER) - enum chan_order{ - THROTTLE=0, - AILERON, - ELEVATOR, - RUDDER, - }; -#endif - -#if defined(AETR) - enum chan_order{ - AILERON =0, - ELEVATOR, - THROTTLE, - RUDDER, - }; -#endif -enum chan_orders{ - AUX1 =4, - AUX2, - AUX3, - AUX4, - AUX5, - AUX6, - AUX7, - AUX8, - AUX9 -}; - -#define PPM_MIN_COMMAND 1250 -#define PPM_SWITCH 1550 -#define PPM_MAX_COMMAND 1750 - -//Uncoment the desired serial speed -#define BAUD 100000 -//#define BAUD 125000 -======= - E010 - MODE_SHENQI - NONE - MODE_FY326 - NONE MODE_SFHSS NONE MODE_J6PRO @@ -458,6 +265,7 @@ enum chan_orders{ FORMAT_HONTAI FORMAT_JJRCX1 FORMAT_X5C1 + FQ777-951 */ // RX_Num is used for model match. Using RX_Num values different for each receiver will prevent starting a model with the false config loaded... @@ -471,5 +279,4 @@ enum chan_orders{ // As an exxample, it's usefull for the WLTOYS F929/F939/F949/F959 (all using the Flysky protocol) which requires a bind at each power up. // Option: the value is between -127 and +127. -// The option value is only valid for some protocols, read this page for more information: https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/Protocols_Details.md ->>>>>>> refs/remotes/pascallanger/master +// The option value is only valid for some protocols, read this page for more information: https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/Protocols_Details.md \ No newline at end of file diff --git a/Multiprotocol/_EEPROM.txt b/Multiprotocol/_EEPROM.txt new file mode 100644 index 0000000..4e78f4e --- /dev/null +++ b/Multiprotocol/_EEPROM.txt @@ -0,0 +1,4 @@ +0-4 rx Flysky afhds2a +10+ 0-4 tx id + +10 réf gene id +30+6 devo reset Autobind auto \ No newline at end of file diff --git a/Multiprotocol/calcul chanel.ods b/Multiprotocol/calcul chanel.ods new file mode 100644 index 0000000..4f8f154 Binary files /dev/null and b/Multiprotocol/calcul chanel.ods differ diff --git a/Multiprotocol/iface_a7105.h b/Multiprotocol/iface_a7105.h index f8792d9..5df2714 100644 --- a/Multiprotocol/iface_a7105.h +++ b/Multiprotocol/iface_a7105.h @@ -89,6 +89,7 @@ enum A7105_MASK { enum { INIT_FLYSKY, + INIT_FLYSKY_AFHDS2A, INIT_HUBSAN }; diff --git a/Multiprotocol/iface_nrf24l01.h b/Multiprotocol/iface_nrf24l01.h index 6aab6c1..cc8b6fe 100644 --- a/Multiprotocol/iface_nrf24l01.h +++ b/Multiprotocol/iface_nrf24l01.h @@ -103,13 +103,8 @@ enum { //#define NOP 0xFF // XN297 emulation layer -<<<<<<< HEAD -#define XN297_UNSCRAMBLED 8 - -======= enum { XN297_UNSCRAMBLED = 0, XN297_SCRAMBLED }; ->>>>>>> refs/remotes/pascallanger/master #endif \ No newline at end of file diff --git a/Multiprotocol/multi.lua b/Multiprotocol/multi.lua deleted file mode 100644 index 07721ae..0000000 --- a/Multiprotocol/multi.lua +++ /dev/null @@ -1,94 +0,0 @@ --- Multiprotocole Midelic et Pascallanger -local debut = 0 -local tps = 0 -local tpsact = 1024 -local mix, mixe -local channel - -local inp = { - { "Protocole", VALUE, 1, 26, 2 }, - { "Switch", SOURCE } -} --- 6 7 8 15 16 17 24 25 26 --- 4 5 12 13 14 21 22 23 --- 1 2 3 9 10 11 18 19 20 -local out = { "Bind", "Gaz", "Aile", "Prof", "Dir" } - -local function run_func(proto, sw) - -- test mixage lua - if debut == 0 then - -- passage en lua - for channel = 0, 3, 1 do - local mix = model.getMix(channel, 0) - mix_source = mix["source"] - if mix_source < 33 or 1 then - model.deleteMix(channel, 0) - mix["source"] = channel + 34 - mix["name"] = "Lua " - model.insertMix(channel, 0, mix) - end - end - end - -- inter install - channel = 4 - mix = { name="Raz Bind", source=33, weight=100, switch=0, multiplex=REPLACE } - count = model.getMixesCount(channel + 0) - if count == 0 and inter == 1 then - model.insertMix(channel + 0, 0, mix) - elseif count == 1 and inter == 0 then - mixe = model.getMix(channel, 0) - if mixe["name"] == mix["name"] then - model.deleteMix(channel, 0) - end - end - - -- delais init - if proto ~= debut then - tps = getTime() + 250 -- delai pour mini 12 cycle PPM - tpsact = 1024 - debut = proto - end - - local gaz = 1024 - local ail = 0 - local dir = 0 - local pro = 0 - - if tpsact == 0 and sw < 100 then - -- reprise valeur input - pro = getValue(1) - ail = getValue(2) - gaz = getValue(3) - dir = getValue(4) - elseif tpsact ~= 0 then - -- decallage pour position memo (centre) - if proto > 4 then proto = proto + 1 end - - -- calcul position - -- decallage pour > 18 - if proto > 18 then - ail = 1024 - proto = proto - 18 - end - -- decallage pour > 9 - if proto > 9 then - ail = -1024 - proto = proto - 9 - end - - if proto < 4 then pro = -1024 end - if proto > 6 then pro = 1024 end - - if proto % 3 == 1 then dir = -1024 end - if proto % 3 == 0 then dir = 1024 end - - if tps < getTime() then - tpsact = tpsact - 512 - if tpsact>-20 then tps = getTime() + 250 end - end - sw = tpsact - end - - return sw, gaz, ail, pro, dir -end -return { run=run_func, input=inp, output=out} diff --git a/Multiprotocol/multiprotocol.h b/Multiprotocol/multiprotocol.h index 672b922..3ca59f2 100644 --- a/Multiprotocol/multiprotocol.h +++ b/Multiprotocol/multiprotocol.h @@ -16,7 +16,7 @@ // Check selected board type #ifndef XMEGA #if not defined(ARDUINO_AVR_PRO) && not defined(ARDUINO_AVR_MINI) && not defined(ARDUINO_AVR_NANO) - #error You must select the board type "Arduino Pro or Pro Mini" or "Arduino Mini" +// #error You must select the board type "Arduino Pro or Pro Mini" or "Arduino Mini" #endif #if F_CPU != 16000000L || not defined(__AVR_ATmega328P__) #error You must select the processor type "ATmega328(5V, 16MHz)" @@ -24,10 +24,27 @@ #endif //****************** -// Protocols +// Protocols max 31 x2 //****************** enum PROTOCOLS { + MODE_JOYSWAY = 40, // =>A7105 + MODE_WK2x01 = 41, // =>CYRF6936 + MODE_SKYARTEC = 42, // =>CC2500 + + MODE_UDI = 44, // =>NRF24L01 + MODE_FBL100 = 45, // =>NRF24L01 + + MODE_HM830 = 50, // =>NRF24L01 + MODE_CFLIE = 51, // =>NRF24L01 + MODE_H377 = 52, // =>NRF24L01 + MODE_ESKY150 = 53, // =>NRF24L01 + MODE_BlueFly = 54, // =>NRF24L01 + MODE_NE260 = 55, // =>NRF24L01 + + MODE_AFHDS2A = 31, // =>A7105 + MODE_INAV = 57, // =>NRF24L01 + MODE_SERIAL = 0, // Serial commands MODE_FLYSKY = 1, // =>A7105 MODE_HUBSAN = 2, // =>A7105 @@ -57,18 +74,17 @@ enum PROTOCOLS MODE_HONTAI = 26, // =>NRF24L01 MODE_OPENLRS = 27, // =>OpenLRS hardware }; - enum Flysky { - Flysky = 0, - V9X9 = 1, - V6X6 = 2, - V912 = 3 + Flysky=0, + V9X9=1, + V6X6=2, + V912=3 }; enum Hisky { - Hisky = 0, - HK310 = 1 + Hisky=0, + HK310=1 }; enum DSM { @@ -80,38 +96,38 @@ enum DSM }; enum YD717 { - YD717 = 0, - SKYWLKR = 1, - SYMAX4 = 2, - XINXUN = 3, - NIHUI = 4 + YD717=0, + SKYWLKR=1, + SYMAX4=2, + XINXUN=3, + NIHUI=4 }; enum KN { - WLTOYS = 0, - FEILUN = 1 + WLTOYS=0, + FEILUN=1 }; enum SYMAX { - SYMAX = 0, - SYMAX5C = 1 + SYMAX=0, + SYMAX5C=1 }; enum CX10 { - CX10_GREEN = 0, - CX10_BLUE = 1, // also compatible with CX10-A, CX12 - DM007 = 2, - Q282 = 3, - JC3015_1 = 4, - JC3015_2 = 5, - MK33041 = 6, - Q242 = 7 + CX10_GREEN = 0, + CX10_BLUE=1, // also compatible with CX10-A, CX12 + DM007=2, + Q282=3, + JC3015_1=4, + JC3015_2=5, + MK33041=6, + Q242=7 }; enum CG023 { - CG023 = 0, - YD829 = 1, - H8_3D = 2 + CG023 = 0, + YD829 = 1, + H8_3D = 2 }; enum MT99XX { @@ -135,9 +151,41 @@ enum FRSKYX }; enum HONTAI { - FORMAT_HONTAI = 0, + FORMAT_HONTAI = 0, FORMAT_JJRCX1 = 1, - FORMAT_X5C1 = 2 + FORMAT_X5C1 = 2, + FORMAT_FQ777 = 3 +}; + +enum HUBSAN +{ + H107 = 0, + H301 = 1, + H501 = 2 +}; +enum FY326 +{ + FY326 = 0, + FY319 = 1 +}; + +enum WK2X01 +{ + WK2801 = 0, + WK2601 = 1, + WK2401 = 2 +}; + +enum UDI +{ + U816_V1 = 0, + U816_V2 = 1, + U839_2014 = 2 +}; +enum FBL100 +{ + FBL100 = 0, + HP100 = 1 }; #define NONE 0 @@ -188,7 +236,7 @@ struct PPM_Parameters #define IS_RX_FLAG_on ( ( protocol_flags & _BV(0) ) !=0 ) // #define CHANGE_PROTOCOL_FLAG_on protocol_flags |= _BV(1) -#define CHANGE_PROTOCOL_FLAG_off protocol_flags &= ~_BV(1) +#define CHANGE_PROTOCOL_FLAG_off protocol_flags &= ~_BV(1) #define IS_CHANGE_PROTOCOL_FLAG_on ( ( protocol_flags & _BV(1) ) !=0 ) // #define POWER_FLAG_on protocol_flags |= _BV(2) @@ -206,8 +254,9 @@ struct PPM_Parameters #define BIND_BUTTON_FLAG_on protocol_flags |= _BV(5) #define BIND_BUTTON_FLAG_off protocol_flags &= ~_BV(5) #define IS_BIND_BUTTON_FLAG_on ( ( protocol_flags & _BV(5) ) !=0 ) + //PPM RX OK -#define PPM_FLAG_off protocol_flags &= ~_BV(6) +#define PPM_FLAG_off protocol_flags &= ~_BV(6) #define PPM_FLAG_on protocol_flags |= _BV(6) #define IS_PPM_FLAG_on ( ( protocol_flags & _BV(6) ) !=0 ) //Bind flag @@ -227,19 +276,21 @@ struct PPM_Parameters #define RX_MISSED_BUFF_on protocol_flags2 |= _BV(2) #define IS_RX_MISSED_BUFF_on ( ( protocol_flags2 & _BV(2) ) !=0 ) //TX Pause -#define TX_MAIN_PAUSE_off protocol_flags2 &= ~_BV(3) -#define TX_MAIN_PAUSE_on protocol_flags2 |= _BV(3) -#define IS_TX_MAIN_PAUSE_on ( ( protocol_flags2 & _BV(3) ) !=0 ) +#define TX_MAIN_PAUSE_off protocol_flags2 &= ~_BV(3) +#define TX_MAIN_PAUSE_on protocol_flags2 |= _BV(3) +#define IS_TX_MAIN_PAUSE_on ( ( protocol_flags2 & _BV(3) ) !=0 ) + #define TX_RX_PAUSE_off protocol_flags2 &= ~_BV(4) -#define TX_RX_PAUSE_on protocol_flags2 |= _BV(4) -#define IS_TX_RX_PAUSE_on ( ( protocol_flags2 & _BV(4) ) !=0 ) +#define TX_RX_PAUSE_on protocol_flags2 |= _BV(4) +#define IS_TX_RX_PAUSE_on ( ( protocol_flags2 & _BV(4) ) !=0 ) + #define IS_TX_PAUSE_on ( ( protocol_flags2 & (_BV(4)|_BV(3)) ) !=0 ) //******************** //*** Blink timing *** //******************** -#define BLINK_BIND_TIME 100 -#define BLINK_SERIAL_TIME 500 +#define BLINK_BIND_TIME 100 +#define BLINK_SERIAL_TIME 500 #define BLINK_BAD_PROTO_TIME_LOW 1000 #define BLINK_BAD_PROTO_TIME_HIGH 50 @@ -416,30 +467,30 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- RxNum value is 0..15 (bits 0..3) Type is 0..7 <<4 (bit 4..6) sub_protocol==Flysky - Flysky 0 - V9x9 1 - V6x6 2 - V912 3 + Flysky 0 + V9x9 1 + V6x6 2 + V912 3 sub_protocol==Hisky - Hisky 0 - HK310 1 + Hisky 0 + HK310 1 sub_protocol==DSM DSM2_22 0 DSM2_11 1 DSMX_22 2 DSMX_11 3 sub_protocol==YD717 - YD717 0 - SKYWLKR 1 - SYMAX4 2 - XINXUN 3 - NIHUI 4 + YD717 0 + SKYWLKR 1 + SYMAX4 2 + XINXUN 3 + NIHUI 4 sub_protocol==KN - WLTOYS 0 - FEILUN 1 + WLTOYS 0 + FEILUN 1 sub_protocol==SYMAX - SYMAX 0 - SYMAX5C 1 + SYMAX 0 + SYMAX5C 1 sub_protocol==CX10 CX10_GREEN 0 CX10_BLUE 1 // also compatible with CX10-A, CX12 @@ -464,14 +515,18 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- X800 2 H26D 3 E010 4 + sub_protocol==FY326 + FY326 0 + FY319 1 sub_protocol==FRSKYX CH_16 0 CH_8 1 sub_protocol==HONTAI - FORMAT_HONTAI 0 - FORMAT_JJRCX1 1 - FORMAT_X5C1 2 - Power value => 0x80 0=High/1=Low + HONTAI 0 + JJRCX1 1 + X5C1 2 + FQ777-521 3 + Power value => 0x80 0=High/1=Low Stream[3] = option_protocol; option_protocol value is -127..127 Stream[4] to [25] = Channels @@ -483,3 +538,4 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- 2047 +125% Channels bits are concatenated to fit in 22 bytes like in SBUS protocol */ + diff --git a/Multiprotocol/opentx-multi-2015-24-12.bin b/Multiprotocol/opentx-multi-2015-24-12.bin deleted file mode 100644 index fe1836e..0000000 Binary files a/Multiprotocol/opentx-multi-2015-24-12.bin and /dev/null differ diff --git a/Multiprotocol/opentx.bin b/Multiprotocol/opentx.bin deleted file mode 100644 index 8e886c4..0000000 Binary files a/Multiprotocol/opentx.bin and /dev/null differ diff --git a/Multiprotocol/sync.ffs_db b/Multiprotocol/sync.ffs_db new file mode 100644 index 0000000..1d9eca3 Binary files /dev/null and b/Multiprotocol/sync.ffs_db differ