diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ea1407 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.ffs_db +*.ffs_db +*.ffs_db +*.hc +*.ffs_db \ No newline at end of file diff --git a/Multiprotocol/A7105_SPI.ino b/Multiprotocol/A7105_SPI.ino index 251d31e..fe54cfd 100644 --- a/Multiprotocol/A7105_SPI.ino +++ b/Multiprotocol/A7105_SPI.ino @@ -15,6 +15,7 @@ /********************/ /** A7105 routines **/ /********************/ +#ifdef A7105_INSTALLED #include "iface_a7105.h" void A7105_WriteData(uint8_t len, uint8_t channel) @@ -22,21 +23,27 @@ void A7105_WriteData(uint8_t len, uint8_t channel) uint8_t i; A7105_CSN_off; SPI_Write(A7105_RST_WRPTR); - SPI_Write(0x05); + SPI_Write(A7105_05_FIFO_DATA); for (i = 0; i < len; i++) SPI_Write(packet[i]); A7105_CSN_on; - A7105_WriteReg(0x0F, channel); + if(protocol!=MODE_FLYSKY) + { + A7105_Strobe(A7105_STANDBY); //Force standby mode, ie cancel any TX or RX... + A7105_SetTxRxMode(TX_EN); //Switch to PA + } + A7105_WriteReg(A7105_0F_PLL_I, channel); A7105_Strobe(A7105_TX); } -void A7105_ReadData() { +void A7105_ReadData(uint8_t len) +{ uint8_t i; - A7105_Strobe(0xF0); //A7105_RST_RDPTR + A7105_Strobe(A7105_RST_RDPTR); A7105_CSN_off; - SPI_Write(0x45); - for (i=0;i<16;i++) - packet[i]=SPI_SDIO_Read(); + SPI_Write(0x40 | A7105_05_FIFO_DATA); //bit 6 =1 for reading + for (i=0;i RXSW and RX_EN -> TXSW //This means that sleep mode is wired as RX_EN = 1 and TX_EN = 1 @@ -81,21 +95,22 @@ uint8_t A7105_Reset() { uint8_t result; - A7105_WriteReg(0x00, 0x00); + A7105_WriteReg(A7105_00_MODE, 0x00); delayMilliseconds(1); A7105_SetTxRxMode(TXRX_OFF); //Set both GPIO as output and low - result=A7105_ReadReg(0x10) == 0x9E; //check if is reset. + result=A7105_ReadReg(A7105_10_PLL_II) == 0x9E; //check if is reset. A7105_Strobe(A7105_STANDBY); return result; } -void A7105_WriteID(uint32_t ida) { +void A7105_WriteID(uint32_t ida) +{ A7105_CSN_off; - SPI_Write(0x06);//ex id=0x5475c52a ;txid3txid2txid1txid0 - SPI_Write((ida>>24)&0xff);//53 - SPI_Write((ida>>16)&0xff);//75 - SPI_Write((ida>>8)&0xff);//c5 - SPI_Write((ida>>0)&0xff);//2a + SPI_Write(A7105_06_ID_DATA); //ex id=0x5475c52a ;txid3txid2txid1txid0 + SPI_Write((ida>>24)&0xff); //53 + SPI_Write((ida>>16)&0xff); //75 + SPI_Write((ida>>8)&0xff); //c5 + SPI_Write((ida>>0)&0xff); //2a A7105_CSN_on; } @@ -136,7 +151,7 @@ void A7105_SetPower() power=A7105_RANGE_POWER; if(prev_power != power) { - A7105_WriteReg(0x28, power); + A7105_WriteReg(A7105_28_TX_TEST, power); prev_power=power; } } @@ -146,53 +161,79 @@ void A7105_Strobe(uint8_t address) { SPI_Write(address); A7105_CSN_on; } - +#ifdef HUBSAN_A7105_INO const uint8_t PROGMEM HUBSAN_A7105_regs[] = { 0xFF, 0x63, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF ,0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2B, 0xFF, 0xFF, 0x62, 0x80, 0xFF, 0xFF, 0x0A, 0xFF, 0xFF, 0x07, 0x17, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x47, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF + 0xFF, 0xFF }; +#endif +#ifdef FLYSKY_A7105_INO const uint8_t PROGMEM FLYSKY_A7105_regs[] = { 0xff, 0x42, 0x00, 0x14, 0x00, 0xff, 0xff ,0x00, 0x00, 0x00, 0x00, 0x01, 0x21, 0x05, 0x00, 0x50, 0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x00, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x32, 0xc3, 0x0f, 0x13, 0xc3, 0x00, 0xff, 0x00, 0x00, 0x3b, 0x00, 0x17, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00, - 0x01, 0x0f, 0xff + 0x01, 0x0f }; +#endif +#ifdef AFHDS2A_A7105_INO +const uint8_t PROGMEM AFHDS2A_A7105_regs[] = { + 0xFF, 0x42 | (1<<5), 0x00, 0x25, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3c, 0x05, 0x00, 0x50, // 00 - 0f + 0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x4f, 0x62, 0x80, 0xFF, 0xFF, 0x2a, 0x32, 0xc3, 0x1f, // 10 - 1f + 0x1e, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x3b, 0x00, 0x17, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00, // 20 - 2f + 0x01, 0x0f // 30 - 31 +}; +#endif + #define ID_NORMAL 0x55201041 #define ID_PLUS 0xAA201041 -void A7105_Init(uint8_t protocol) +void A7105_Init(void) { - void *A7105_Regs; + uint8_t *A7105_Regs=0; - if(protocol==INIT_FLYSKY) + #ifdef HUBSAN_A7105_INO + if(protocol==MODE_HUBSAN) + { + A7105_WriteID(ID_NORMAL); + A7105_Regs=(uint8_t*)HUBSAN_A7105_regs; + } + else + #endif + { + A7105_WriteID(0x5475c52A);//0x2Ac57554 + #ifdef FLYSKY_A7105_INO + if(protocol==MODE_FLYSKY) + A7105_Regs=(uint8_t*)FLYSKY_A7105_regs; + else + #endif + { + #ifdef AFHDS2A_A7105_INO + A7105_Regs=(uint8_t*)AFHDS2A_A7105_regs; + #endif + } + } + + for (uint8_t i = 0; i < 0x32; i++) { - A7105_WriteID(0x5475c52A);//0x2Ac57554 - A7105_Regs=(void *)FLYSKY_A7105_regs; - } - else - { - A7105_WriteID(ID_NORMAL); - A7105_Regs=(void *)HUBSAN_A7105_regs; - } - for (uint8_t i = 0; i < 0x33; i++){ - if( pgm_read_byte_near((uint16_t)(A7105_Regs)+i) != 0xFF) - A7105_WriteReg(i, pgm_read_byte_near((uint16_t)(A7105_Regs)+i)); + uint8_t val=pgm_read_byte_near(&A7105_Regs[i]); + if( val != 0xFF) + A7105_WriteReg(i, val); } A7105_Strobe(A7105_STANDBY); //IF Filter Bank Calibration A7105_WriteReg(A7105_02_CALC,1); - while(A7105_ReadReg(A7105_02_CALC)); // Wait for calibration to end + while(A7105_ReadReg(A7105_02_CALC)); // Wait for calibration to end // A7105_ReadReg(A7105_22_IF_CALIB_I); // A7105_ReadReg(A7105_24_VCO_CURCAL); - if(protocol==INIT_FLYSKY) + if(protocol!=MODE_HUBSAN) { //VCO Current Calibration - A7105_WriteReg(A7105_24_VCO_CURCAL,0x13); //Recommended calibration from A7105 Datasheet + A7105_WriteReg(A7105_24_VCO_CURCAL,0x13); //Recommended calibration from A7105 Datasheet //VCO Bank Calibration - A7105_WriteReg(A7105_26_VCO_SBCAL_II,0x3b); //Recommended calibration from A7105 Datasheet + A7105_WriteReg(A7105_26_VCO_SBCAL_II,0x3b); //Recommended calibration from A7105 Datasheet } //VCO Bank Calibrate channel 0 @@ -208,11 +249,12 @@ void A7105_Init(uint8_t protocol) // A7105_ReadReg(A7105_25_VCO_SBCAL_I); //Reset VCO Band calibration - if(protocol==INIT_FLYSKY) - A7105_WriteReg(A7105_25_VCO_SBCAL_I,0x08); + if(protocol!=MODE_HUBSAN) + A7105_WriteReg(A7105_25_VCO_SBCAL_I,protocol==MODE_FLYSKY?0x08:0x0A); A7105_SetTxRxMode(TX_EN); A7105_SetPower(); A7105_Strobe(A7105_STANDBY); } +#endif \ No newline at end of file diff --git a/Multiprotocol/A7105_joysway.ino b/Multiprotocol/A7105_joysway.ino index 1aed90d..e29fc2b 100644 --- a/Multiprotocol/A7105_joysway.ino +++ b/Multiprotocol/A7105_joysway.ino @@ -19,146 +19,107 @@ #define EVEN_ODD 0x00 //#define EVEN_ODD 0x01 -static const uint8_t A7105_regs[] = { - 0x00, 0x62, -1, 0x0f, 0x00, -1 , -1 , 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0xf5, 0x00, 0x15, + +const uint8_t PROGMEM JOYSWAY_A7105_regs[] = { + 0x00, 0x62, 0xFF, 0x0f, 0x00, 0xFF , 0xFF , 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0xf5, 0x00, 0x15, 0x9e, 0x4b, 0x00, 0x03, 0x56, 0x2b, 0x12, 0x4a, 0x02, 0x80, 0x80, 0x00, 0x0e, 0x91, 0x03, 0x0f, - 0x16, 0x2a, 0x00, -1, -1, -1, 0x3a, 0x06, 0x1f, 0x47, 0x80, 0x01, 0x05, 0x45, 0x18, 0x00, + 0x16, 0x2a, 0x00, 0xFF, 0xFF, 0xFF, 0x3a, 0x06, 0x1f, 0x47, 0x80, 0x01, 0x05, 0x45, 0x18, 0x00, 0x01, 0x0f, 0x00 }; - -static uint8_t next_ch; - -static int joysway_init() -{ - int i; - uint8_t if_calibration1; - //uint8_t vco_calibration0; - //uint8_t vco_calibration1; - - phase = 0; - next_ch = 0x30; - - for (i = 0; i < 0x33; i++) - if((uint8_t)A7105_regs[i] != -1) - A7105_WriteReg(i, A7105_regs[i]); - A7105_WriteID(0x5475c52a); - - A7105_Strobe(A7105_PLL); - - //IF Filter Bank Calibration - A7105_WriteReg(0x02, 1); - A7105_ReadReg(0x02); - uint32_t ms = micros(); - while(micros() - ms < 500) { - if(! A7105_ReadReg(0x02)) - break; - } - if (micros() - ms >= 500) - return 0; - A7105_Strobe(A7105_STANDBY); - if_calibration1 = A7105_ReadReg(0x22); - if(if_calibration1 & A7105_MASK_FBCF) { - //Calibration failed...what do we do? - return 0; - } - - //VCO Current Calibration - A7105_WriteReg(0x24, 0x13); //Recomended calibration from A7105 Datasheet - A7105_WriteReg(0x25, 0x09); //Recomended calibration from A7105 Datasheet - - A7105_WriteID(MProtocol_id_master); - A7105_Strobe(A7105_PLL); - A7105_WriteReg(0x02, 1); - ms = micros(); - while(micros() - ms < 500) { - if(! A7105_ReadReg(0x02)) - break; - } - if (micros() - ms >= 500) - return 0; - A7105_Strobe(A7105_STANDBY); - if_calibration1 = A7105_ReadReg(0x22); - if(if_calibration1 & A7105_MASK_FBCF) { - //Calibration failed...what do we do? - return 0; - } - A7105_WriteReg(0x24, 0x13); //Recomended calibration from A7105 Datasheet - A7105_WriteReg(0x25, 0x09); //Recomended calibration from A7105 Datasheet - - A7105_SetTxRxMode(TX_EN); - A7105_SetPower(); - - A7105_Strobe(A7105_STANDBY); - return 1; +static void joysway_build_packet() { + int i; + //-100% =~ 0x03e8 + //+100% =~ 0x07ca + //Calculate: + //Center = 0x5d9 + //1 % = 5 + packet[0] = phase == 0 ? 0xdd : 0xff; + packet[1] = (MProtocol_id >> 24) & 0xff; + packet[2] = (MProtocol_id >> 16) & 0xff; + packet[3] = (MProtocol_id >> 8) & 0xff; + packet[4] = (MProtocol_id >> 0) & 0xff; + packet[5] = 0x00; + static const int chmap[4] = {6, 7, 10, 11}; + for (i = 0; i < 4; i++) { +// if (i >= Model.num_channels) { packet[chmap[i]] = 0x64; continue; } + packet[chmap[i]] = map(limit_channel_100(i),servo_min_100,servo_max_100,0,204); + } + packet[8] = 0x64; + packet[9] = 0x64; + packet[12] = 0x64; + packet[13] = 0x64; + packet[14] = phase == 0 ? 0x30 : 0xaa; + uint8_t value = 0; + for (int i = 0; i < 15; i++) { value += packet[i]; } + packet[15] = value; } -static void joysway_build_packet() -{ - int i; - //-100% =~ 0x03e8 - //+100% =~ 0x07ca - //Calculate: - //Center = 0x5d9 - //1 % = 5 - packet[0] = phase == 0 ? 0xdd : 0xff; - packet[1] = (MProtocol_id_master >> 24) & 0xff; - packet[2] = (MProtocol_id_master >> 16) & 0xff; - packet[3] = (MProtocol_id_master >> 8) & 0xff; - packet[4] = (MProtocol_id_master >> 0) & 0xff; - packet[5] = 0x00; - static const int chmap[4] = {6, 7, 10, 11}; - for (i = 0; i < 4; i++) { -// if (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; } - packet[chmap[i]] = value; - } - packet[8] = 0x64; - packet[9] = 0x64; - packet[12] = 0x64; - packet[13] = 0x64; - packet[14] = phase == 0 ? 0x30 : 0xaa; - uint8_t value = 0; - for (int i = 0; i < 15; i++) { value += packet[i]; } - packet[15] = value; -} - -static uint16_t joysway_cb() -{ - uint8_t ch; - if (phase == 254) { - phase = 0; - A7105_WriteID(0x5475c52a); - ch = 0x0a; - } else if (phase == 2) { - A7105_WriteID(MProtocol_id_master); - ch = 0x30; - } else { - if ((phase & 0x01) ^ EVEN_ODD) { - ch = 0x30; - } else { - ch = next_ch; - } - } - if (! ((phase & 0x01) ^ EVEN_ODD)) { - next_ch++; - if (next_ch == 0x45) - next_ch = 0x30; - } - joysway_build_packet(); - A7105_Strobe(A7105_STANDBY); - A7105_WriteData(16, ch); - phase++; - return 6000; +static uint16_t joysway_cb() { + if (phase == 254) { + phase = 0; + A7105_WriteID(0x5475c52a); + hopping_frequency_no = 0x0a; + } else if (phase == 2) { + A7105_WriteID(MProtocol_id); + hopping_frequency_no = 0x30; + } else { + if ((phase & 0x01) ^ EVEN_ODD) { + hopping_frequency_no = 0x30; + } else { + hopping_frequency_no = rf_ch_num; + } + } + if (! ((phase & 0x01) ^ EVEN_ODD)) { + rf_ch_num++; + if (rf_ch_num == 0x45) + rf_ch_num = 0x30; + } + joysway_build_packet(); + A7105_Strobe(A7105_STANDBY); + A7105_WriteData(16, hopping_frequency_no); + phase++; + return 6000; } static uint16_t JOYSWAY_Setup() { - while(1) { - A7105_Reset(); - if (joysway_init()) - break; + int i; + u8 if_calibration1; + //u8 vco_calibration0; + //u8 vco_calibration1; + + counter = 0; +// next_ch = 0x30; + + for (i = 0; i < 0x33; i++) { + uint8_t val=pgm_read_byte_near(&JOYSWAY_A7105_regs[i]); + if( val != 0xFF) + A7105_WriteReg(i, val); } + A7105_WriteID(0x5475c52a); + + A7105_Strobe(A7105_PLL); + + //IF Filter Bank Calibration + A7105_WriteReg(0x02, 1); + while(A7105_ReadReg(A7105_02_CALC)); // Wait for calibration to end + A7105_Strobe(A7105_STANDBY); + + //VCO Current Calibration + A7105_WriteReg(0x24, 0x13); //Recomended calibration from A7105 Datasheet + A7105_WriteReg(0x25, 0x09); //Recomended calibration from A7105 Datasheet + + A7105_WriteID(MProtocol_id); + A7105_Strobe(A7105_PLL); + A7105_WriteReg(0x02, 1); + while(A7105_ReadReg(A7105_02_CALC)); // Wait for calibration to end + A7105_Strobe(A7105_STANDBY); + A7105_WriteReg(0x24, 0x13); //Recomended calibration from A7105 Datasheet + A7105_WriteReg(0x25, 0x09); //Recomended calibration from A7105 Datasheet + + A7105_SetTxRxMode(TX_EN); + A7105_SetPower(); + + A7105_Strobe(A7105_STANDBY); return 2400; } #endif diff --git a/Multiprotocol/AFHDS2A_a7105.ino b/Multiprotocol/AFHDS2A_a7105.ino new file mode 100644 index 0000000..869b5a8 --- /dev/null +++ b/Multiprotocol/AFHDS2A_a7105.ino @@ -0,0 +1,351 @@ +/* + 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 . + */ +// Last sync with hexfet new_protocols/flysky_a7105.c dated 2015-09-28 + +#ifdef AFHDS2A_A7105_INO + +#define AFHDS2A_TXPACKET_SIZE 38 +#define AFHDS2A_RXPACKET_SIZE 37 +#define AFHDS2A_NUMFREQ 16 + +enum{ + AFHDS2A_PACKET_STICKS, + AFHDS2A_PACKET_SETTINGS, + AFHDS2A_PACKET_FAILSAFE, +}; + +enum{ + AFHDS2A_BIND1, + AFHDS2A_BIND2, + AFHDS2A_BIND3, + AFHDS2A_BIND4, + AFHDS2A_DATA, +}; + +static void AFHDS2A_calc_channels() +{ + uint8_t idx = 0; + uint32_t rnd = MProtocol_id; + while (idx < AFHDS2A_NUMFREQ) + { + uint8_t i; + uint8_t 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 ^ MProtocol_id) & 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; + } +} + +#if defined(TELEMETRY) +// telemetry sensors ID +enum{ + AFHDS2A_SENSOR_RX_VOLTAGE = 0x00, + AFHDS2A_SENSOR_RX_ERR_RATE = 0xfe, + AFHDS2A_SENSOR_RX_RSSI = 0xfc, + AFHDS2A_SENSOR_RX_NOISE = 0xfb, + AFHDS2A_SENSOR_RX_SNR = 0xfa, +}; + +static void AFHDS2A_update_telemetry() +{ + // AA | TXID | rx_id | sensor id | sensor # | value 16 bit big endian | sensor id ...... + // max 7 sensors per packet +#if defined AFHDS2A_TELEMETRY + if (option & 0x80) { + // forward telemetry to TX, skip rx and tx id to save space + pkt[0]= TX_RSSI; + for(int i=9;i < AFHDS2A_RXPACKET_SIZE; i++) + pkt[i-8]=packet[i]; + + telemetry_link=2; + return; + } +#endif + for(uint8_t sensor=0; sensor<7; sensor++) + { + uint8_t index = 9+(4*sensor); + switch(packet[index]) + { + case AFHDS2A_SENSOR_RX_VOLTAGE: + v_lipo = packet[index+3]<<8 | packet[index+2]; + telemetry_link=1; + break; + /*case AFHDS2A_SENSOR_RX_ERR_RATE: + // packet[index+2]; + break;*/ + case AFHDS2A_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 0x02) + packet[9] = 0x02; + packet[27]= 0x01; + packet[28]= 0x80; + break; + } +} + +static void AFHDS2A_build_packet(uint8_t type) +{ + memcpy( &packet[1], rx_tx_addr, 4); + memcpy( &packet[5], rx_id, 4); + switch(type) + { + case AFHDS2A_PACKET_STICKS: + packet[0] = 0x58; + 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; + } + break; + case AFHDS2A_PACKET_FAILSAFE: + packet[0] = 0x56; + for(uint8_t ch=0; ch<14; ch++) + { + /*if((Model.limits[ch].flags & CH_FAILSAFE_EN)) + { + packet[9 + ch*2] = Servo_data[CH_AETR[ch]] & 0xff; + packet[10+ ch*2] = (Servo_data[CH_AETR[ch]] >> 8) & 0xff; + } + else*/ + { + packet[9 + ch*2] = 0xff; + packet[10+ ch*2] = 0xff; + } + } + break; + case AFHDS2A_PACKET_SETTINGS: + packet[0] = 0xaa; + packet[9] = 0xfd; + packet[10]= 0xff; + uint16_t val_hz=5*(option & 0x7f)+50; // option value should be between 0 and 70 which gives a value between 50 and 400Hz + if(val_hz<50 || val_hz>400) val_hz=50; // default is 50Hz + packet[11]= val_hz; + packet[12]= val_hz >> 8; + if(sub_protocol == PPM_IBUS || sub_protocol == 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(sub_protocol == PWM_SBUS || sub_protocol == PPM_SBUS) + packet[21] = 0xdd; // SBUS output enabled + else + packet[21] = 0xde; // IBUS + break; + } + packet[37] = 0x00; +} + +#define AFHDS2A_WAIT_WRITE 0x80 +uint16_t ReadAFHDS2A() +{ + static uint8_t packet_type = AFHDS2A_PACKET_STICKS; + static uint16_t packet_counter=0; + uint8_t data_rx; + uint16_t start; + switch(phase) + { + case AFHDS2A_BIND1: + case AFHDS2A_BIND2: + case AFHDS2A_BIND3: + AFHDS2A_build_bind_packet(); + A7105_WriteData(AFHDS2A_TXPACKET_SIZE, packet_count%2 ? 0x0d : 0x8c); + if(!(A7105_ReadReg(A7105_00_MODE) & (1<<5 | 1<<6))) + { // FECF+CRCF Ok + A7105_ReadData(AFHDS2A_RXPACKET_SIZE); + if(packet[0] == 0xbc && packet[9] == 0x01) + { + uint8_t temp=50+RX_num*4; + uint8_t i; + for(i=0; i<4; i++) + { + rx_id[i] = packet[5+i]; + eeprom_write_byte((EE_ADDR)(temp+i),rx_id[i]); + } + phase = AFHDS2A_BIND4; + packet_count++; + return 3850; + } + } + packet_count++; + phase |= AFHDS2A_WAIT_WRITE; + return 1700; + case AFHDS2A_BIND1|AFHDS2A_WAIT_WRITE: + case AFHDS2A_BIND2|AFHDS2A_WAIT_WRITE: + case AFHDS2A_BIND3|AFHDS2A_WAIT_WRITE: + //Wait for TX completion + start=micros(); + while ((uint16_t)micros()-start < 700) // Wait max 700µs, using serial+telemetry exit in about 120µs + if(!(A7105_ReadReg(A7105_00_MODE) & 0x01)) + break; + A7105_SetTxRxMode(RX_EN); + A7105_Strobe(A7105_RX); + phase &= ~AFHDS2A_WAIT_WRITE; + phase++; + if(phase > AFHDS2A_BIND3) + phase = AFHDS2A_BIND1; + return 2150; + case AFHDS2A_BIND4: + AFHDS2A_build_bind_packet(); + A7105_WriteData(AFHDS2A_TXPACKET_SIZE, packet_count%2 ? 0x0d : 0x8c); + packet_count++; + bind_phase++; + if(bind_phase>=4) + { + packet_counter=0; + packet_type = AFHDS2A_PACKET_STICKS; + hopping_frequency_no=1; + phase = AFHDS2A_DATA; + BIND_DONE; + } + return 3850; + case AFHDS2A_DATA: + AFHDS2A_build_packet(packet_type); + if((A7105_ReadReg(A7105_00_MODE) & 0x01)) // Check if something has been received... + data_rx=0; + else + data_rx=1; // Yes + A7105_WriteData(AFHDS2A_TXPACKET_SIZE, hopping_frequency[hopping_frequency_no++]); + if(hopping_frequency_no >= AFHDS2A_NUMFREQ) + hopping_frequency_no = 0; + if(!(packet_counter % 1313)) + packet_type = AFHDS2A_PACKET_SETTINGS; + else if(!(packet_counter % 1569)) + packet_type = AFHDS2A_PACKET_FAILSAFE; + else + packet_type = AFHDS2A_PACKET_STICKS; // todo : check for settings changes + if(!(A7105_ReadReg(A7105_00_MODE) & (1<<5 | 1<<6)) && data_rx==1) + { // RX+FECF+CRCF Ok + A7105_ReadData(AFHDS2A_RXPACKET_SIZE); + if(packet[0] == 0xaa) + { + if(packet[9] == 0xfc) + packet_type=AFHDS2A_PACKET_SETTINGS; // RX is asking for settings + #if defined(TELEMETRY) + else + { + // Read TX RSSI + int16_t temp=256-(A7105_ReadReg(A7105_1D_RSSI_THOLD)*8)/5; // value from A7105 is between 8 for maximum signal strength to 160 or less + if(temp<0) temp=0; + else if(temp>255) temp=255; + TX_RSSI=temp; + AFHDS2A_update_telemetry(); + } + #endif + } + } + packet_counter++; + phase |= AFHDS2A_WAIT_WRITE; + return 1700; + case AFHDS2A_DATA|AFHDS2A_WAIT_WRITE: + //Wait for TX completion + start=micros(); + while ((uint16_t)micros()-start < 700) // Wait max 700µs, using serial+telemetry exit in about 120µs + if(!(A7105_ReadReg(A7105_00_MODE) & 0x01)) + break; + A7105_SetTxRxMode(RX_EN); + A7105_Strobe(A7105_RX); + phase &= ~AFHDS2A_WAIT_WRITE; + return 2150; + } + return 3850; // never reached, please the compiler +} + +uint16_t initAFHDS2A() +{ + A7105_Init(); + + AFHDS2A_calc_channels(); + packet_count = 0; + bind_phase = 0; + if(IS_AUTOBIND_FLAG_on) + phase = AFHDS2A_BIND1; + else + { + phase = AFHDS2A_DATA; + //Read RX ID from EEPROM based on RX_num, RX_num must be uniq for each RX + uint8_t temp=50+RX_num*4; + for(uint8_t i=0;i<4;i++) + rx_id[i]=eeprom_read_byte((EE_ADDR)(temp+i)); + } + hopping_frequency_no = 0; + return 50000; +} +#endif diff --git a/Multiprotocol/Arduino.ino b/Multiprotocol/Arduino.ino index 7382ac9..0074077 100644 --- a/Multiprotocol/Arduino.ino +++ b/Multiprotocol/Arduino.ino @@ -12,9 +12,23 @@ You should have received a copy of the GNU General Public License along with Multiprotocol. If not, see . */ +#ifndef STM32_BOARD +/************************************/ /************************************/ /** Arduino replacement routines **/ /************************************/ +// replacement map() +int16_t map( int16_t x, int16_t in_min, int16_t in_max, int16_t out_min, int16_t out_max) +{ +// return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; + long y ; + x -= in_min ; + y = out_max - out_min ; + y *= x ; + x = y / (in_max - in_min) ; + return x + out_min ; +} + // replacement millis() and micros() // These work polled, no interrupts // micros() MUST be called at least once every 32 milliseconds @@ -106,7 +120,7 @@ void delayMicroseconds(unsigned int us) return; us <<= 2; // * 4 us -= 2; // - 2 -#ifdef XMEGA +#ifdef ORANGE_TX __asm__ __volatile__ ( "1: sbiw %0,1" "\n\t" // 2 cycles "nop \n" @@ -123,11 +137,12 @@ void delayMicroseconds(unsigned int us) #endif } -#ifndef XMEGA +#ifndef ORANGE_TX void init() { // this needs to be called before setup() or some functions won't work there sei(); } -#endif //XMEGA +#endif //ORANGE_TX +#endif //STM32_BOARD diff --git a/Multiprotocol/Build_orangetx.cmd b/Multiprotocol/Build_orangetx.cmd new file mode 100644 index 0000000..58c6f24 --- /dev/null +++ b/Multiprotocol/Build_orangetx.cmd @@ -0,0 +1,20 @@ +@echo off +if "%AVR32_HOME%"=="" ( +echo. +echo You must install winavr to compile Multi for OrangeTX: https://sourceforge.net/projects/winavr/ +echo. +pause +exit /b +) +if exist MultiOrange.cpp.orangetx ren *.orangetx *. +if exist .dep (make clean) +md .dep +make +if exist MultiOrange.hex ( +objcopy -I ihex MultiOrange.hex -O binary MultiOrange.bin +echo. +echo Compilation OK. +echo Use MultiOrange.hex to program your OrangeTX module. +echo. +) +pause diff --git a/Multiprotocol/CC2500_SPI.ino b/Multiprotocol/CC2500_SPI.ino index 4628b03..ac39670 100644 --- a/Multiprotocol/CC2500_SPI.ino +++ b/Multiprotocol/CC2500_SPI.ino @@ -1,3 +1,4 @@ + /* 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 @@ -17,6 +18,7 @@ //CC2500 SPI routines //------------------------------- //------------------------------- +#ifdef CC2500_INSTALLED #include "iface_cc2500.h" //---------------------------- @@ -152,4 +154,4 @@ void CC2500_SetPower() prev_power=power; } } - +#endif \ No newline at end of file diff --git a/Multiprotocol/CG023_nrf24l01.ino b/Multiprotocol/CG023_nrf24l01.ino index 8169b8f..91425a8 100644 --- a/Multiprotocol/CG023_nrf24l01.ino +++ b/Multiprotocol/CG023_nrf24l01.ino @@ -56,18 +56,23 @@ enum YD829_FLAGS { }; enum H8_3D_FLAGS { - // flags going to packet[17] - H8_3D_FLAG_FLIP = 0x01, - H8_3D_FLAG_RATE_MID = 0x02, - H8_3D_FLAG_RATE_HIGH = 0x04, - H8_3D_FLAG_LIGTH = 0x08, // Light on H22 - H8_3D_FLAG_HEADLESS = 0x10, // RTH + headless on H8, headless on JJRC H20, RTH on H22 - H8_3D_FLAG_RTH = 0x20, // 360 flip mode on H8 3D and H22, RTH on JJRC H20 + // flags going to packet[17] + H8_3D_FLAG_FLIP = 0x01, + H8_3D_FLAG_RATE_MID = 0x02, + H8_3D_FLAG_RATE_HIGH = 0x04, + H8_3D_FLAG_LIGTH = 0x08, // Light on H22 + H8_3D_FLAG_HEADLESS = 0x10, // RTH + headless on H8, headless on JJRC H20, RTH on H22 + H8_3D_FLAG_RTH = 0x20, // 360 flip mode on H8 3D and H22, RTH on JJRC H20 }; enum H8_3D_FLAGS_2 { - // flags going to packet[18] - H8_3D_FLAG_CALIBRATE = 0x20, // accelerometer calibration + // flags going to packet[18] + H8_3D_FLAG_CAM_UP = 0x04, + H8_3D_FLAG_CAM_DOWN = 0x08, + H8_3D_FLAG_CALIBRATE2 = 0x10, // acc calib. (H11D, H20) + H8_3D_FLAG_CALIBRATE = 0x20, // acc calib. (H8 3D), headless calib (H20) + H8_3D_FLAG_SNAPSHOT = 0x40, + H8_3D_FLAG_VIDEO = 0x80, }; static void __attribute__((unused)) CG023_send_packet(uint8_t bind) @@ -119,8 +124,10 @@ static void __attribute__((unused)) CG023_send_packet(uint8_t bind) | GET_FLAG(Servo_AUX2,H8_3D_FLAG_LIGTH) //H22 light | GET_FLAG(Servo_AUX3,H8_3D_FLAG_HEADLESS) | GET_FLAG(Servo_AUX4,H8_3D_FLAG_RTH); // 180/360 flip mode on H8 3D - if(Servo_AUX5) - packet[18] = H8_3D_FLAG_CALIBRATE; + packet[18] = GET_FLAG(Servo_AUX5,H8_3D_FLAG_CALIBRATE) + | GET_FLAG(Servo_AUX5,H8_3D_FLAG_CALIBRATE2) + | GET_FLAG(Servo_AUX6,H8_3D_FLAG_SNAPSHOT) + | GET_FLAG(Servo_AUX7,H8_3D_FLAG_VIDEO); } uint8_t sum = packet[9]; for (uint8_t i=10; i < H8_3D_PACKET_SIZE-1; i++) 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..96fd9c8 100644 --- a/Multiprotocol/CYRF6936_SPI.ino +++ b/Multiprotocol/CYRF6936_SPI.ino @@ -12,9 +12,9 @@ You should have received a copy of the GNU General Public License along with Multiprotocol. If not, see . */ +#ifdef CYRF6936_INSTALLED #include "iface_cyrf6936.h" - void CYRF_WriteRegister(uint8_t address, uint8_t data) { CYRF_CSN_off; @@ -182,28 +182,16 @@ void CYRF_WritePreamble(uint32_t preamble) /* * */ -static void CYRF_StartReceive() -{ - CYRF_WriteRegister(CYRF_05_RX_CTRL,0x87); -} - /*static void CYRF_ReadDataPacket(uint8_t dpbuffer[]) { 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); @@ -250,10 +238,14 @@ void CYRF_FindBestChannels(uint8_t *channels, uint8_t len, uint8_t minspace, uin for(i = 0; i < NUM_FREQ; i++) { CYRF_ConfigRFChannel(i); - CYRF_ReadRegister(CYRF_13_RSSI); - CYRF_StartReceive(); - delayMicroseconds(10); - rssi[i] = CYRF_ReadRegister(CYRF_13_RSSI); + delayMicroseconds(270); //slow channel require 270usec for synthesizer to settle + if( !(CYRF_ReadRegister(CYRF_05_RX_CTRL) & 0x80)) { + CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80); //Prepare to receive + delayMicroseconds(15); + CYRF_ReadRegister(CYRF_13_RSSI); //dummy read + delayMicroseconds(15); //The conversion can occur as often as once every 12us + } + rssi[i] = CYRF_ReadRegister(CYRF_13_RSSI)&0x1F; } for (i = 0; i < len; i++) @@ -269,7 +261,9 @@ void CYRF_FindBestChannels(uint8_t *channels, uint8_t len, uint8_t minspace, uin rssi[j] = 0xff; } } + CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20); // Abort RX operation CYRF_SetTxRxMode(TX_EN); + CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20); // Clear abort RX } #if defined(DEVO_CYRF6936_INO) || defined(J6PRO_CYRF6936_INO) @@ -304,4 +298,5 @@ static void __attribute__((unused)) CYRF_PROGMEM_ConfigSOPCode(const uint8_t *da for(uint8_t i=0;i<8;i++) code[i]=pgm_read_byte_near(&data[i]); CYRF_ConfigSOPCode(code); -} \ No newline at end of file +} +#endif \ No newline at end of file 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/Convert.ino b/Multiprotocol/Convert.ino index 3e2920e..07e7b2c 100644 --- a/Multiprotocol/Convert.ino +++ b/Multiprotocol/Convert.ino @@ -15,17 +15,6 @@ /************************/ /** Convert routines **/ /************************/ -int16_t map( int16_t x, int16_t in_min, int16_t in_max, int16_t out_min, int16_t out_max) -{ -// return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; - long y ; - x -= in_min ; - y = out_max - out_min ; - y *= x ; - x = y / (in_max - in_min) ; - return x + out_min ; -} - // Channel value is converted to 8bit values full scale uint8_t convert_channel_8b(uint8_t num) { 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/DSM_cyrf6936.ino b/Multiprotocol/DSM_cyrf6936.ino index 85c5735..acc4331 100644 --- a/Multiprotocol/DSM_cyrf6936.ino +++ b/Multiprotocol/DSM_cyrf6936.ino @@ -135,8 +135,7 @@ static uint8_t __attribute__((unused)) get_pn_row(uint8_t channel) } const uint8_t PROGMEM init_vals[][2] = { - {CYRF_02_TX_CTRL, 0x03}, // TX interrupt complete and error enabled - //0x00 in deviation but needed to know when transmit is over + {CYRF_02_TX_CTRL, 0x00}, // All TX interrupt disabled {CYRF_05_RX_CTRL, 0x00}, // All RX interrupt disabled {CYRF_28_CLK_EN, 0x02}, // Force receive clock enable {CYRF_32_AUTO_CAL_TIME, 0x3c}, // Default init value @@ -369,13 +368,13 @@ static uint8_t __attribute__((unused)) DSM_Check_RX_packet() uint16_t ReadDsm() { #define DSM_CH1_CH2_DELAY 4010 // Time between write of channel 1 and channel 2 -#define DSM_WRITE_DELAY 1550 // Time after write to verify write complete +#define DSM_WRITE_DELAY 1950 // Time after write to verify write complete #define DSM_READ_DELAY 600 // Time before write to check read phase, and switch channels. Was 400 but 600 seems what the 328p needs to read a packet - uint16_t start; #if defined DSM_TELEMETRY uint8_t rx_phase; uint8_t len; #endif + uint8_t start; switch(phase) { @@ -451,19 +450,28 @@ uint16_t ReadDsm() return DSM_WRITE_DELAY; case DSM_CH1_CHECK_A: case DSM_CH1_CHECK_B: - start=micros(); - while ((uint16_t)micros()-start < 500) // Wait max 500µs - if(CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x02) - break; - set_sop_data_crc(); - phase++; // change from CH1_CHECK to CH2_WRITE - return DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY; case DSM_CH2_CHECK_A: case DSM_CH2_CHECK_B: start=micros(); - while ((uint16_t)micros()-start < 500) // Wait max 500µs + while ((uint8_t)micros()-start < 100) // Wait max 100µs, max I've seen is 50µs if(CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x02) break; + if(phase==DSM_CH1_CHECK_A || phase==DSM_CH1_CHECK_B) + { + #if defined DSM_TELEMETRY + // reset cyrf6936 if freezed after switching from TX to RX + if (((CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x22) == 0x20) || (CYRF_ReadRegister(CYRF_02_TX_CTRL) & 0x80)) + { + CYRF_Reset(); + cyrf_config(); + cyrf_configdata(); + CYRF_SetTxRxMode(TX_EN); + } + #endif + set_sop_data_crc(); + phase++; // change from CH1_CHECK to CH2_WRITE + return DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY; + } if (phase == DSM_CH2_CHECK_A) CYRF_SetPower(0x28); //Keep transmit power in sync #if defined DSM_TELEMETRY diff --git a/Multiprotocol/Devo_cyrf6936.ino b/Multiprotocol/Devo_cyrf6936.ino index 91d752e..885e6c0 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 @@ -91,7 +63,7 @@ static void __attribute__((unused)) DEVO_add_pkt_suffix() BIND_SET_PULLUP; // set pullup if(IS_BIND_BUTTON_on) { - eeprom_write_byte((uint8_t*)(30+mode_select),0x01); // Set fixed id mode for the current model + eeprom_write_byte((EE_ADDR)(30+mode_select),0x01); // Set fixed id mode for the current model option=1; } BIND_SET_OUTPUT; @@ -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..c1632e7 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); @@ -325,7 +184,7 @@ uint16_t initFlySky() uint8_t chanoffset; uint8_t temp; - A7105_Init(INIT_FLYSKY); //flysky_init(); + A7105_Init(); if ((rx_tx_addr[3]&0xF0) > 0x90) // limit offset to 9 as higher values don't work with some RX (ie V912) rx_tx_addr[3]=rx_tx_addr[3]-0x70; @@ -352,7 +211,5 @@ uint16_t initFlySky() else bind_counter = 0; return 2400; ->>>>>>> refs/remotes/pascallanger/master } #endif - diff --git a/Multiprotocol/FrSkyX_cc2500.ino b/Multiprotocol/FrSkyX_cc2500.ino index 5f5f6ba..474f190 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; @@ -562,13 +274,14 @@ uint16_t ReadFrSkyX() return 3000; case FRSKY_DATA4: len = CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F; - if (len && (len>>>>>> 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..4b681ec 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; @@ -218,7 +287,6 @@ uint16_t ReadHubsan() case BIND_5: case BIND_7: hubsan_build_bind_packet(phase == BIND_7 ? 9 : (phase == BIND_5 ? 1 : phase + 1 - BIND_1)); - A7105_Strobe(A7105_STANDBY); A7105_WriteData(16, channel); phase |= WAIT_WRITE; return 3000; @@ -253,7 +321,7 @@ uint16_t ReadHubsan() phase = BIND_1; return 4500; //No signal, restart binding procedure. 12msec elapsed since last write } - A7105_ReadData(); + A7105_ReadData(16); phase++; if (phase == BIND_5) A7105_WriteID(((uint32_t)packet[2] << 24) | ((uint32_t)packet[3] << 16) | ((uint32_t)packet[4] << 8) | packet[5]); @@ -264,7 +332,7 @@ uint16_t ReadHubsan() phase = BIND_7; return 15000; //22.5msec elapsed since last write } - A7105_ReadData(); + A7105_ReadData(16); if(packet[1] == 9 && id_data == ID_NORMAL) { phase = DATA_1; A7105_WriteReg(A7105_1F_CODE_I, 0x0F); @@ -286,8 +354,15 @@ uint16_t ReadHubsan() if( phase == DATA_1) 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 @@ -314,7 +389,7 @@ uint16_t ReadHubsan() { if( !(A7105_ReadReg(A7105_00_MODE) & 0x01)) { // data received - A7105_ReadData(); + A7105_ReadData(16); if( hubsan_check_integrity() ) { v_lipo=packet[13];// hubsan lipo voltage 8bits the real value is h_lipo/10(0x2A=42 -> 4.2V) @@ -322,9 +397,10 @@ uint16_t ReadHubsan() } A7105_Strobe(A7105_RX); // Read TX RSSI - RSSI_dBm=256-(A7105_ReadReg(A7105_1D_RSSI_THOLD)*8)/5; // value from A7105 is between 8 for maximum signal strength to 160 or less - if(RSSI_dBm<0) RSSI_dBm=0; - else if(RSSI_dBm>255) RSSI_dBm=255; + int16_t temp=256-(A7105_ReadReg(A7105_1D_RSSI_THOLD)*8)/5; // value from A7105 is between 8 for maximum signal strength to 160 or less + if(temp<0) temp=0; + else if(temp>255) temp=255; + TX_RSSI=temp; break; } } @@ -343,7 +419,7 @@ uint16_t ReadHubsan() uint16_t initHubsan() { const uint8_t allowed_ch[] = {0x14, 0x1e, 0x28, 0x32, 0x3c, 0x46, 0x50, 0x5a, 0x64, 0x6e, 0x78, 0x82}; - A7105_Init(INIT_HUBSAN); //hubsan_init(); + A7105_Init(); sessionid = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16); channel = allowed_ch[random(0xfefefefe) % sizeof(allowed_ch)]; diff --git a/Multiprotocol/J6Pro_cyrf6936.ino b/Multiprotocol/J6Pro_cyrf6936.ino index acc0971..1846716 100644 --- a/Multiprotocol/J6Pro_cyrf6936.ino +++ b/Multiprotocol/J6Pro_cyrf6936.ino @@ -55,10 +55,10 @@ static void __attribute__((unused)) j6pro_build_data_packet() { uint8_t i; uint32_t upperbits = 0; - uint16_t value; + uint16_t value; packet[0] = 0xaa; //FIXME what is this? for (i = 0; i < 12; i++) - { + { value = convert_channel_10b(CH_AETR[i]); packet[i+1] = value & 0xff; upperbits |= (value >> 8) << (i * 2); @@ -76,16 +76,16 @@ static void __attribute__((unused)) j6pro_cyrf_init() 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_SetPower(0x05); - CYRF_WriteRegister(CYRF_06_RX_CFG, 0x8a); + //CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24); + //CYRF_SetPower(0x05); + CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a); CYRF_SetPower(0x28); 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(j6pro_data_code, 16); - CYRF_WritePreamble(0x023333); + CYRF_WritePreamble(0x333302); CYRF_GetMfgData(cyrfmfg_id); //Model match @@ -94,36 +94,28 @@ static void __attribute__((unused)) j6pro_cyrf_init() static void __attribute__((unused)) cyrf_bindinit() { -/* Use when binding */ - //0.060470# 03 2f - CYRF_SetPower(0x28); //Deviation using max power, replaced by bind power... - - CYRF_ConfigRFChannel(0x52); - CYRF_PROGMEM_ConfigSOPCode(j6pro_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); + /* Use when binding */ + CYRF_SetPower(0x28); //Deviation using max power, replaced by bind power... + //CYRF_ConfigRFChannel(0x52); + CYRF_PROGMEM_ConfigSOPCode(j6pro_bind_sop_code); + CYRF_ConfigCRCSeed(0x0000); + //CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a); + //CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80); + //CYRF_ConfigRFChannel(0x52); + //CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24); + //CYRF_WriteRegister(CYRF_02_TX_CTRL, 0x40); + j6pro_build_bind_packet(); } static void __attribute__((unused)) 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_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[sop_idx]); - CYRF_ConfigCRCSeed(crc); + /* Use when already bound */ + 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, 0x24); + CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[sop_idx]); + CYRF_ConfigCRCSeed(crc); } static void __attribute__((unused)) j6pro_set_radio_channels() @@ -136,10 +128,10 @@ static void __attribute__((unused)) j6pro_set_radio_channels() uint16_t ReadJ6Pro() { - uint32_t start; + uint32_t start; switch(phase) - { + { case J6PRO_BIND: cyrf_bindinit(); phase = J6PRO_BIND_01; @@ -147,9 +139,7 @@ uint16_t ReadJ6Pro() 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_WriteRegister(CYRF_0F_XACT_CFG, 0x24); CYRF_WriteDataPacketLen(packet, 0x09); phase = J6PRO_BIND_03_START; return 3000; //3msec @@ -160,8 +150,8 @@ uint16_t ReadJ6Pro() break; CYRF_ConfigRFChannel(0x53); CYRF_SetTxRxMode(RX_EN); - CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a); - CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x83); + //CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a); + CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80); phase = J6PRO_BIND_03_CHECK; return 30000; //30msec case J6PRO_BIND_03_CHECK: @@ -201,7 +191,7 @@ uint16_t ReadJ6Pro() case J6PRO_BIND_05_4: case J6PRO_BIND_05_5: case J6PRO_BIND_05_6: - CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x25); + //CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24); CYRF_WriteDataPacketLen(packet, 0x0f); phase = phase + 1; return 4600; //4.6msec @@ -212,7 +202,7 @@ uint16_t ReadJ6Pro() phase = J6PRO_CHAN_1; case J6PRO_CHAN_1: //Keep transmit power updated - CYRF_SetPower(0); + CYRF_SetPower(0x28); j6pro_build_data_packet(); //return 3400; case J6PRO_CHAN_2: @@ -237,12 +227,10 @@ uint16_t initJ6Pro() { j6pro_cyrf_init(); - if(IS_AUTOBIND_FLAG_on) { + if(IS_AUTOBIND_FLAG_on) phase = J6PRO_BIND; - } - else { + else phase = J6PRO_CHANSEL; - } return 2400; } 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..04cf9d6 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,20 +26,17 @@ #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}, - {0x0A, 0x3C, 0x36, 0x3F}, - {0x0A, 0x43, 0x36, 0x3F} }; const uint8_t PROGMEM MJXQ_map_txid[][3] = { {0xF8, 0x4F, 0x1C}, {0xC8, 0x6E, 0x02}, {0x48, 0x6A, 0x40} }; +const uint8_t PROGMEM MJXQ_map_rfchan[][4] = { + {0x0A, 0x46, 0x3A, 0x42}, + {0x0A, 0x3C, 0x36, 0x3F}, + {0x0A, 0x43, 0x36, 0x3F} }; ->>>>>>> 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]; @@ -115,16 +90,15 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind) // Servo_AUX5 HEADLESS // Servo_AUX6 RTH // Servo_AUX7 AUTOFLIP // X800, X600 +// Servo_AUX8 ARM // H26WH switch(sub_protocol) { case H26D: + case H26WH: 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) @@ -135,16 +109,13 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind) | GET_FLAG(Servo_AUX4, 0x10) //VIDEO | GET_FLAG(!Servo_AUX2, 0x20); // air/ground mode } + if (sub_protocol == H26WH) { + packet[10] &= ~0x40; + packet[14] &= ~0x24; + packet[14] |= GET_FLAG(Servo_AUX2, 0x04); + } 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) @@ -175,14 +146,15 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind) packet[15] = sum; // Power on, TX mode, 2byte CRC - 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 + switch (Model.proto_opts[PROTOOPTS_FORMAT]) { + case H26D: + case H26WH: + NRF24L01_SetTxRxMode(TX_EN); + break; + default: + XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); + break; + } NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++ / 2]); hopping_frequency_no %= 2 * MJXQ_RF_NUM_CHANNELS; // channels repeated @@ -190,10 +162,15 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind) NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); NRF24L01_FlushTx(); - if (sub_protocol == H26D) - NRF24L01_WritePayload(packet, MJXQ_PACKET_SIZE); - else - XN297_WritePayload(packet, MJXQ_PACKET_SIZE); + switch (Model.proto_opts[PROTOOPTS_FORMAT]) { + case H26D: + case H26WH: + NRF24L01_WritePayload(packet, MJXQ_PACKET_SIZE); + break; + default: + XN297_WritePayload(packet, MJXQ_PACKET_SIZE); + break; + } NRF24L01_SetPower(); } @@ -202,31 +179,26 @@ static void __attribute__((unused)) MJXQ_init() { uint8_t addr[MJXQ_ADDRESS_LENGTH]; memcpy(addr, "\x6d\x6a\x77\x77\x77", MJXQ_ADDRESS_LENGTH); + NRF24L01_Initialize(); + NRF24L01_SetTxRxMode(TX_EN); + 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 + if (sub_protocol == H26D || sub_protocol == H26WH || sub_protocol == E010) 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 } - NRF24L01_Initialize(); - NRF24L01_SetTxRxMode(TX_EN); - - if (sub_protocol == H26D) + if (sub_protocol == H26D || sub_protocol == H26WH) + { + NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, addr, MJXQ_ADDRESS_LENGTH); + } else XN297_SetTXAddr(addr, MJXQ_ADDRESS_LENGTH); @@ -237,63 +209,39 @@ 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 + hopping_frequency[i]=pgm_read_byte_near( &MJXQ_map_rfchan[rx_tx_addr[3]%3][i] ); } 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) + rx_tx_addr[2]=rx_tx_addr[3]; // Make use of RX_Num + if (sub_protocol == H26WH) + { + memcpy(txid, "\xa4\x03\x00", sizeof(txid)); + } + else if (sub_protocol == E010) { rx_tx_addr[1]=(rx_tx_addr[1]&0xF0)|0x0C; - rx_tx_addr[2]&=0xF0; + rx_tx_addr[2]<<=4; // Make use of RX_Num } 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 + rx_tx_addr[i]=pgm_read_byte_near( &MJXQ_map_txid[rx_tx_addr[3]%3][i] ); } uint16_t MJXQ_callback() diff --git a/Multiprotocol/MT99xx_nrf24l01.ino b/Multiprotocol/MT99xx_nrf24l01.ino index dff51d7..4b68594 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,49 +47,18 @@ 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 }; -static const u8 ls_mys_byte[] = { +static const uint8_t ls_mys_byte[] = { 0x05, 0x15, 0x25, 0x06, 0x16, 0x26, 0x07, 0x17, 0x27, 0x00, 0x10, 0x20, 0x01, 0x11, 0x21, 0x02, 0x12, 0x22, @@ -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/Makefile.xmega b/Multiprotocol/Makefile.orangetx similarity index 100% rename from Multiprotocol/Makefile.xmega rename to Multiprotocol/Makefile.orangetx diff --git a/Multiprotocol/MultiOrange.cpp.xmega b/Multiprotocol/MultiOrange.cpp.orangetx similarity index 99% rename from Multiprotocol/MultiOrange.cpp.xmega rename to Multiprotocol/MultiOrange.cpp.orangetx index d9a916c..76fdf4d 100644 --- a/Multiprotocol/MultiOrange.cpp.xmega +++ b/Multiprotocol/MultiOrange.cpp.orangetx @@ -1,7 +1,7 @@ #define ARDUINO_AVR_PRO 1 //#define __AVR_ATmega328P__ 1 -#define XMEGA 1 +#define ORANGE_TX 1 // For BLUE module use: //#define DSM_BLUE 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..94ca4f4 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,66 +21,60 @@ You should have received a copy of the GNU General Public License along with Multiprotocol. If not, see . */ -#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 "Pins.h" #include "TX_Def.h" +#include "Validate.h" -#ifdef XMEGA - #undef ENABLE_PPM // Disable PPM for OrangeTX module - #undef A7105_INSTALLED // Disable A7105 for OrangeTX module - #undef CC2500_INSTALLED // Disable CC2500 for OrangeTX module - #undef NRF24L01_INSTALLED // Disable NRF for OrangeTX module - #define TELEMETRY // Enable telemetry - #define INVERT_TELEMETRY // Enable invert telemetry - #define DSM_TELEMETRY // Enable DSM telemetry +#ifndef STM32_BOARD + #include +#else +/* + #include + #include + #include + #include + #include + HardwareTimer timer(2); + void PPM_decode(); + void ISR_COMPB(); + extern "C" + { + void __irq_usart2(void); + void __irq_usart3(void); + } +*/ #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_id[4]; +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 +85,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 +109,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; +#ifndef ORANGE_TX + //Random variable + volatile uint32_t gWDT_entropy=0; #endif ->>>>>>> refs/remotes/pascallanger/master //Serial protocol uint8_t sub_protocol; @@ -166,40 +129,13 @@ volatile uint8_t rx_buff[RXBUFFER_SIZE]; volatile uint8_t rx_ok_buff[RXBUFFER_SIZE]; volatile uint8_t discard_frame = 0; -//Make sure telemetry is selected correctly -#ifndef TELEMETRY - #undef INVERT_TELEMETRY - #undef DSM_TELEMETRY - #undef SPORT_TELEMETRY - #undef HUB_TELEMETRY -#else - #if not defined(CYRF6936_INSTALLED) || not defined(DSM_CYRF6936_INO) - #undef DSM_TELEMETRY - #endif - #if (not defined(CC2500_INSTALLED) || not defined(FRSKYD_CC2500_INO)) && (not defined(A7105_INSTALLED) || not defined(HUBSAN_A7105_INO)) - #undef HUB_TELEMETRY - #endif - #if not defined(CC2500_INSTALLED) || not defined(FRSKYX_CC2500_INO) - #undef SPORT_TELEMETRY - #endif -#endif -#if not defined(DSM_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(SPORT_TELEMETRY) - #undef TELEMETRY - #undef INVERT_TELEMETRY -#endif - // Telemetry -#define MAX_PKT 27 +#define MAX_PKT 29 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 + #if not defined(ORANGE_TX) && not defined(STM32_BOARD) + // enable bit bash for serial #define BASH_SERIAL 1 #endif #define INVERT_SERIAL 1 @@ -212,12 +148,12 @@ 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 + uint8_t TX_RSSI; uint8_t telemetry_link=0; uint8_t telemetry_counter=0; + uint8_t telemetry_lost; #endif // Callback @@ -227,8 +163,9 @@ void_function_t remote_callback = 0; // Init void setup() { - #ifdef XMEGA // General pinout + #ifdef ORANGE_TX + //XMEGA PORTD.OUTSET = 0x17 ; PORTD.DIRSET = 0xB2 ; PORTD.DIRCLR = 0x4D ; @@ -244,8 +181,40 @@ void setup() TCC1.PER = 0xFFFF ; TCNT1 = 0 ; TCC1.CTRLA = 0x0B ; // Event3 (prescale of 16) - #else - // General pinout + #elif defined STM32_BOARD + //STM32 + pinMode(A7105_CSN_pin,OUTPUT); + pinMode(CC25_CSN_pin,OUTPUT); + pinMode(NRF_CSN_pin,OUTPUT); + pinMode(CYRF_CSN_pin,OUTPUT); + pinMode(CYRF_RST_pin,OUTPUT); + pinMode(PE1_pin,OUTPUT); + pinMode(PE2_pin,OUTPUT); + #if defined TELEMETRY + pinMode(TX_INV_pin,OUTPUT); + pinMode(RX_INV_pin,OUTPUT); + #if defined INVERT_SERIAL + TX_INV_on;//activated inverter for both serial TX and RX signals + RX_INV_on; + #else + TX_INV_off; + RX_INV_off; + #endif + #endif + pinMode(BIND_pin,INPUT_PULLUP); + pinMode(PPM_pin,INPUT); + pinMode(S1_pin,INPUT_PULLUP);//dial switch + pinMode(S2_pin,INPUT_PULLUP); + pinMode(S3_pin,INPUT_PULLUP); + pinMode(S4_pin,INPUT_PULLUP); + //Random pins + pinMode(PB0, INPUT_ANALOG); // set up pin for analog input + pinMode(PB1, INPUT_ANALOG); // set up pin for analog input + + //select the counter clock. + start_timer2();//0.5us + #else + //ATMEGA328p // all inputs DDRB=0x00;DDRC=0x00;DDRD=0x00; // outputs @@ -268,12 +237,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 +253,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 +265,38 @@ void setup() #ifdef NRF24L01_INSTALLED NRF_CSN_on; #endif - // Set SPI lines - SDI_on; - SCLK_off; ->>>>>>> refs/remotes/pascallanger/master + // Set SPI lines + #ifdef STM32_BOARD + initSPI2(); + #else + SDI_on; + SCLK_off; + #endif // 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 + #elif defined STM32_BOARD + mode_select= 0x0F -(uint8_t)(((GPIOA->regs->IDR)>>4)&0x0F); #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 +310,58 @@ 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 ORANGE_TX + //Init the seed with a random value created from watchdog timer for all protocols requiring random values + #ifdef STM32_BOARD + randomSeed((uint32_t)analogRead(PB0) << 10 | analogRead(PB1)); + #else + randomSeed(random_value()); + #endif + #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(); + + #ifndef STM32_BOARD + //Configure PPM interrupt + #if PPM_pin == 2 + EICRA |= _BV(ISC01); // The rising edge of INT0 pin D2 generates an interrupt request + EIMSK |= _BV(INT0); // INT0 interrupt enable + #elif PPM_pin == 3 + EICRA |=_BV(ISC11); // The rising edge of INT1 pin D3 generates an interrupt request + EIMSK |= _BV(INT1); // INT1 interrupt enable + #else + #error PPM pin can only be 2 or 3 + #endif + #else + attachInterrupt(PPM_pin,PPM_decode,FALLING); + #endif - protocol_init(); - - //Configure PPM interrupt - EICRA |=(1<>>>>>> refs/remotes/pascallanger/master - #endif - } - else -#endif //ENABLE_PPM + #endif + } + else + #endif //ENABLE_PPM { // Serial #ifdef ENABLE_SERIAL for(uint8_t i=0;i<3;i++) @@ -454,40 +377,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;iSR & TIMER_SR_CC1IF)!=0) + { + cli(); + OCR1A = TCNT1; + sei(); + } + else + while((TIMER2_BASE->SR & TIMER_SR_CC1IF )==0); // Wait before callback + #endif do { TX_MAIN_PAUSE_on; @@ -520,18 +421,30 @@ void loop() next_callback-=2000; // We will wait below for 2ms cli(); // Disable global int due to RW of 16 bits registers OCR1A += 2000*2 ; // set compare A for callback - TIFR1=OCF1A_bm; // clear compare A=callback flag + #ifndef STM32_BOARD + TIFR1=OCF1A_bm; // clear compare A=callback flag + #else + TIMER2_BASE->SR &= ~TIMER_SR_CC1IF; //clear compare Flag + #endif sei(); // enable global int Update_All(); if(IS_CHANGE_PROTOCOL_FLAG_on) break; // Protocol has been changed - while((TIFR1 & OCF1A_bm) == 0); // wait 2ms... + #ifndef STM32_BOARD + while((TIFR1 & OCF1A_bm) == 0); // wait 2ms... + #else + while((TIMER2_BASE->SR & TIMER_SR_CC1IF)==0);//2ms wait + #endif } // at this point we have a maximum of 4ms in next_callback next_callback *= 2 ; cli(); // Disable global int due to RW of 16 bits registers OCR1A+= next_callback ; // set compare A for callback - TIFR1=OCF1A_bm; // clear compare A=callback flag + #ifndef STM32_BOARD + TIFR1=OCF1A_bm; // clear compare A=callback flag + #else + TIMER2_BASE->SR &= ~TIMER_SR_CC1IF; //clear compare Flag write zero + #endif diff=OCR1A-TCNT1; // compare timer and comparator sei(); // enable global int } @@ -545,14 +458,8 @@ void Update_All() #ifdef ENABLE_SERIAL if(mode_select==MODE_SERIAL && IS_RX_FLAG_on) // Serial mode and something has been received { - update_serial_data(); // Update protocol and data + 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 - modules_reset(); //reset all modules - protocol_init(); //init new protocol - } } #endif //ENABLE_SERIAL #ifdef ENABLE_PPM @@ -570,14 +477,15 @@ void Update_All() } update_aux_flags(); PPM_FLAG_off; // wait for next frame before update + INPUT_SIGNAL_on; //valid signal received + last_signal=millis(); } #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_AFHDS2A) || (protocol==MODE_FRSKYX) || (protocol==MODE_DSM) ) TelemetryUpdate(); - #endif ->>>>>>> refs/remotes/pascallanger/master + #endif + update_led_status(); } // Update Servo_AUX flags based on servo AUX positions @@ -587,86 +495,64 @@ static void update_aux_flags(void) for(uint8_t i=0;i<8;i++) if(Servo_data[AUX1+i]>PPM_SWITCH) Servo_AUX|=1<PPM_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 + modules_reset(); //reset all modules + #ifdef ENABLE_PPM + AUTOBIND_FLAG_on; + #endif //ENABLE_PPM + protocol_init(); //init new protocol + } } // Update led status based on binding and serial static void update_led_status(void) { + if(IS_INPUT_SIGNAL_on) + if(millis()-last_signal>50) + INPUT_SIGNAL_off; //no valid signal (PPM or Serial) received for 50ms if(blink>>>>>> refs/remotes/pascallanger/master + if(IS_INPUT_SIGNAL_off) + { + if(mode_select==MODE_SERIAL) + blink+=BLINK_SERIAL_TIME; //blink slowly if no valid serial input + else + blink+=BLINK_PPM_TIME; //blink more slowly if no valid PPM input + } else - if(remote_callback == 0) - { // Invalid protocol + if(remote_callback == 0) + { // Invalid protocol if(IS_LED_on) //flash to indicate invalid protocol blink+=BLINK_BAD_PROTO_TIME_LOW; else blink+=BLINK_BAD_PROTO_TIME_HIGH; - } - else - if(IS_BIND_DONE_on) -<<<<<<< HEAD - 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 + if(IS_BIND_DONE_on) + LED_off; //bind completed force led on + blink+=BLINK_BIND_TIME; //blink fastly during binding } - TIFR1=(1< led on - else - blink+=BLINK_BIND_TIME; //blink fastly during binding LED_toggle; } } inline void tx_pause() -{ +{ #ifdef TELEMETRY - #ifdef XMEGA - USARTC0.CTRLA &= ~0x03 ; // Pause telemetry by disabling transmitter interrupt + // Pause telemetry by disabling transmitter interrupt + #ifdef ORANGE_TX + USARTC0.CTRLA &= ~0x03 ; #else #ifndef BASH_SERIAL - UCSR0B &= ~_BV(UDRIE0); // Pause telemetry by disabling transmitter interrupt + #ifdef STM32_BOARD + USART3_BASE->CR1 &= ~ USART_CR1_TXEIE; + #else + UCSR0B &= ~_BV(UDRIE0); + #endif #endif #endif #endif @@ -675,24 +561,43 @@ inline void tx_pause() inline void tx_resume() { #ifdef TELEMETRY + // Resume telemetry by enabling transmitter interrupt if(!IS_TX_PAUSE_on) { - #ifdef XMEGA + #ifdef ORANGE_TX cli() ; - USARTC0.CTRLA = (USARTC0.CTRLA & 0xFC) | 0x01 ; // Resume telemetry by enabling transmitter interrupt + USARTC0.CTRLA = (USARTC0.CTRLA & 0xFC) | 0x01 ; sei() ; #else #ifndef BASH_SERIAL - UCSR0B |= _BV(UDRIE0); // Resume telemetry by enabling transmitter interrupt + #ifdef STM32_BOARD + USART3_BASE->CR1 |= USART_CR1_TXEIE; + #else + UCSR0B |= _BV(UDRIE0); + #endif #else resumeBashSerial() ; - #endif + #endif #endif } #endif ->>>>>>> refs/remotes/pascallanger/master } +#ifdef STM32_BOARD + void start_timer2() + { + // Pause the timer while we're configuring it + timer.pause(); + TIMER2_BASE->PSC = 35; //36-1;for 72 MHZ /0.5sec/(35+1) + TIMER2_BASE->ARR = 0xFFFF; //count till max + timer.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE); + timer.setMode(TIMER_CH2, TIMER_OUTPUT_COMPARE); + // Refresh the timer's count, prescale, and overflow + timer.refresh(); + timer.resume(); + } +#endif + // Protocol start static void protocol_init() { @@ -704,10 +609,13 @@ static void protocol_init() tx_pause(); pass=0; telemetry_link=0; + telemetry_lost=1; #ifndef BASH_SERIAL tx_tail=0; tx_head=0; #endif + TX_RX_PAUSE_off; + TX_MAIN_PAUSE_off; #endif blink=millis(); @@ -718,229 +626,19 @@ 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(FLYSKY_A7105_INO) case MODE_FLYSKY: PE1_off; //antenna RF1 @@ -948,6 +646,13 @@ static void protocol_init() remote_callback = ReadFlySky; break; #endif + #if defined(AFHDS2A_A7105_INO) + case MODE_AFHDS2A: + PE1_off; //antenna RF1 + next_callback = initAFHDS2A(); + remote_callback = ReadAFHDS2A; + break; + #endif #if defined(HUBSAN_A7105_INO) case MODE_HUBSAN: PE1_off; //antenna RF1 @@ -958,6 +663,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 +704,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 @@ -1007,12 +726,12 @@ static void protocol_init() { if(IS_BIND_BUTTON_FLAG_on) { - eeprom_write_byte((uint8_t*)(30+mode_select),0x00); // reset to autobind mode for the current model + eeprom_write_byte((EE_ADDR)(30+mode_select),0x00); // reset to autobind mode for the current model option=0; } else { - option=eeprom_read_byte((uint8_t*)(30+mode_select)); // load previous mode: autobind or fixed id + option=eeprom_read_byte((EE_ADDR)(30+mode_select)); // load previous mode: autobind or fixed id if(option!=1) option=0; // if not fixed id mode then it should be autobind } } @@ -1031,6 +750,67 @@ 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(Q303_NRF24L01_INO) + case MODE_Q303: + next_callback=q303_init(); + remote_callback = q303_callback; + break; + #endif + #if defined(HISKY_NRF24L01_INO) case MODE_HISKY: next_callback=initHiSky(); @@ -1135,85 +915,46 @@ 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<SR &= ~TIMER_SR_CC1IF; //clear compare Flag write zero + #endif BIND_BUTTON_FLAG_off; // do not bind/reset id anymore even if protocol change -======= - cli(); // disable global int - OCR1A = TCNT1 + next_callback*2; // set compare A for callback - sei(); // enable global int - TIFR1 = OCF1A_bm ; // clear compare A flag - BIND_BUTTON_FLAG_off; // do not bind/reset id anymore even if protocol change ->>>>>>> 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 +963,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 +973,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 + #ifdef ORANGE_TX 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 + #ifdef ORANGE_TX sei(); #else - UCSR0B |= _BV(RXCIE0) ; // RX interrupt enable + UCSR0B |= _BV(RXCIE0) ; // RX interrupt enable #endif } @@ -1303,26 +1008,26 @@ 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() { - #ifdef XMEGA + #ifdef ORANGE_TX PORTC.OUTSET = 0x08 ; PORTC.DIRSET = 0x08 ; - + USARTC0.BAUDCTRLA = 19 ; USARTC0.BAUDCTRLB = 0 ; @@ -1330,60 +1035,47 @@ void Mprotocol_serial_init() USARTC0.CTRLA = (USARTC0.CTRLA & 0xCF) | 0x10 ; USARTC0.CTRLC = 0x2B ; UDR0 ; - #ifdef INVERT_TELEMETRY + #ifdef INVERT_SERIAL PORTC.PIN3CTRL |= 0x40 ; #endif - #else - #include + #elif defined STM32_BOARD + usart2_begin(100000,SERIAL_8E2); + usart3_begin(100000,SERIAL_8E2); + USART2_BASE->CR1 |= USART_CR1_PCE_BIT; + USART3_BASE->CR1 &= ~ USART_CR1_RE;//disable + USART2_BASE->CR1 &= ~ USART_CR1_TE;//disable transmit + #else + //ATMEGA328p + #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 ) ; #endif //TELEMETRY #endif //DEBUG_TX - #endif //XMEGA + #endif //ORANGE_TX } #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) { - uint32_t id; - uint8_t txid[4]; + uint32_t id=0; - if(eeprom_read_byte((uint8_t*)(adress+10))==0xf0 && !create_new) + if(eeprom_read_byte((EE_ADDR)(adress+10))==0xf0 && !create_new) { // TXID exists in EEPROM - eeprom_read_block((void*)txid,(const void*)adress,4); - id=(txid[0] | ((uint32_t)txid[1]<<8) | ((uint32_t)txid[2]<<16) | ((uint32_t)txid[3]<<24)); +// 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)); + for(uint8_t i=4;i>0;i--) + { + id<<=8; + id|=eeprom_read_byte((EE_ADDR)adress+i-1); + } if(id!=0x2AD141A7) //ID with seed=0 return id; } // Generate a random ID id = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16); - txid[0]= (id &0xFF); +/* 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*)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. +*/ + for(uint8_t i=0;i<4;i++) + { + eeprom_write_byte((EE_ADDR)adress+i,id); + id>>=8; + } + eeprom_write_byte((EE_ADDR)(adress+10),0xf0);//write bind flag in eeprom. return id; } @@ -1479,20 +1144,15 @@ 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 + #ifdef ORANGE_TX #if PPM_pin == 2 ISR(PORTD_INT0_vect) #else ISR(PORTD_INT1_vect) #endif + #elif defined STM32_BOARD + void PPM_decode() #else #if PPM_pin == 2 ISR(INT0_vect, ISR_NOBLOCK) @@ -1501,39 +1161,27 @@ ISR(INT1_vect) #endif #endif { // Interrupt on PPM pin - static int8_t chan=-1; + static int8_t chan=0,bad_frame=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 + bad_frame=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) + { //start of frame + if(chan>3) + PPM_FLAG_on; // good frame received if at least 4 channels have been seen + chan=0; // reset channel counter + bad_frame=0; } -<<<<<<< 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(bad_frame==0) // 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 + bad_frame=1; // don't accept any new channels } Prev_TCNT1+=Cur_TCNT1; } @@ -1541,84 +1189,104 @@ ISR(USART_RX_vect) //Serial RX #ifdef ENABLE_SERIAL - #ifdef XMEGA + #ifdef ORANGE_TX ISR(USARTC0_RXC_vect) + #elif defined STM32_BOARD + void __irq_usart2() #else ISR(USART_RX_vect) #endif { // RX interrupt - static uint8_t idx=0; - #ifdef XMEGA - if((USARTC0.STATUS & 0x1C)==0) // Check frame error, data overrun and parity error + static uint8_t idx=0; + #ifdef ORANGE_TX + if((USARTC0.STATUS & 0x1C)==0) // Check frame error, data overrun and parity error + #elif defined STM32_BOARD + if((USART2_BASE->SR & USART_SR_RXNE) && (USART2_BASE->SR &0x0F)==0) #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(); - OCR1B = TCNT1+(6500L) ; // Full message should be received within timer of 3250us - TIFR1 = OCF1B_bm ; // clear OCR1B match flag - SET_TIMSK1_OCIE1B ; // enable interrupt on compare B match + #if defined STM32_BOARD + uint16_t OCR1B; + OCR1B =TCNT1+(6500L); + timer.setCompare(TIMER_CH2,OCR1B); + timer.attachCompare2Interrupt(ISR_COMPB); + #else + OCR1B = TCNT1+(6500L) ; // Full message should be received within timer of 3250us + TIFR1 = OCF1B_bm ; // clear OCR1B match flag + SET_TIMSK1_OCIE1B ; // enable interrupt on compare B match + #endif idx++; } } 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 + #ifdef STM32_BOARD + detachInterrupt(2); // Disable interrupt on ch2 + #else + CLR_TIMSK1_OCIE1B; // Disable interrupt on compare B match + #endif TX_RX_PAUSE_off; tx_resume(); } - #ifndef XMEGA + #if not defined (ORANGE_TX) && not defined (STM32_BOARD) cli() ; - UCSR0B |= _BV(RXCIE0) ; // RX interrupt enable + UCSR0B |= _BV(RXCIE0) ; // RX interrupt enable #endif } //Serial timer - #ifdef XMEGA + #ifdef ORANGE_TX ISR(TCC1_CCB_vect) + #elif defined STM32_BOARD + void ISR_COMPB() #else ISR(TIMER1_COMPB_vect, ISR_NOBLOCK ) #endif { // Timer1 compare B interrupt discard_frame=1; - CLR_TIMSK1_OCIE1B; // Disable interrupt on compare B match + #ifdef STM32_BOARD + detachInterrupt(2); // Disable interrupt on ch2 + #else + CLR_TIMSK1_OCIE1B; // Disable interrupt on compare B match + #endif tx_resume(); } #endif //ENABLE_SERIAL -#ifndef XMEGA +#if not defined (ORANGE_TX) && not defined (STM32_BOARD) // 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) @@ -1643,30 +1311,4 @@ ISR(USART_RX_vect) 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..37faed1 100644 --- a/Multiprotocol/NRF24l01_SPI.ino +++ b/Multiprotocol/NRF24l01_SPI.ino @@ -14,9 +14,7 @@ */ -//--------------------------- -// AVR nrf chip bitbang SPI functions -//--------------------------- +#ifdef NRF24L01_INSTALLED #include "iface_nrf24l01.h" @@ -94,6 +92,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) { @@ -181,7 +187,8 @@ void NRF24L01_SetTxRxMode(enum TXRX_State mode) NRF_CE_on; } else - if (mode == RX_EN) { + if (mode == RX_EN) + { NRF_CE_off; NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // reset the flag(s) NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x0F); // switch to RX mode @@ -234,11 +241,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 +254,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,23 +327,16 @@ 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); } -void XN297_SetScrambledMode(const u8 mode) +void XN297_SetScrambledMode(const uint8_t mode) { xn297_scramble_enabled = mode; ->>>>>>> refs/remotes/pascallanger/master } void XN297_WritePayload(uint8_t* msg, uint8_t len) @@ -412,32 +398,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 +422,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 +464,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 +487,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 +540,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 +549,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 +568,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 +583,11 @@ 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 +#endif 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..6dd6f43 100644 --- a/Multiprotocol/Nrf24l01_hm830.ino +++ b/Multiprotocol/Nrf24l01_hm830.ino @@ -1,10 +1,11 @@ /* - 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 . + 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 . */ -/* This protocol is for the HM Hobby HM830 RC Paper Airplane +/* + This protocol is for the HM Hobby HM830 RC Paper Airplane Protocol spec: Channel data: AA BB CC DD EE FF GG @@ -76,7 +77,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 +115,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 +142,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..d8cfa0a --- /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 INAV_BIND_COUNT 345 // 1.5 seconds + #define FIRST_INAV_PACKET_DELAY 12000 + + #define INAV_PACKET_PERIOD 4000 // Timeout for callback in uSec + #define INAV_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 { + INAV_RATE_LOW = 0, + INAV_RATE_MID = 1, + INAV_RATE_HIGH = 2, + }; + + enum { + INAV_FLAG_FLIP = 0x01, + INAV_FLAG_PICTURE = 0x02, + INAV_FLAG_VIDEO = 0x04, + INAV_FLAG_RTH = 0x08, + INAV_FLAG_HEADLESS = 0x10, + }; + + typedef enum { + PHASE_INIT = 0, + PHASE_INAV_BIND, + PHASE_INAV_DATA + }; + + typedef enum { + DATA_INAV_PACKET = 0, + BIND_INAV_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 = INAV_RATE_LOW; + if (Channels[CHANNEL_RATE] > 0) { + rate = INAV_RATE_HIGH; + } else if (Channels[CHANNEL_RATE] == 0) { + rate = INAV_RATE_MID; + } + packet[7] = rate; // rate, deviation channel 5, is mapped to AUX1 + + const uint8_t flags = GET_FLAG(CHANNEL_FLIP, INAV_FLAG_FLIP) + | GET_FLAG(CHANNEL_PICTURE, INAV_FLAG_PICTURE) + | GET_FLAG(CHANNEL_VIDEO, INAV_FLAG_VIDEO) + | GET_FLAG(CHANNEL_RTH, INAV_FLAG_RTH) + | GET_FLAG(CHANNEL_HEADLESS, INAV_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_INAV_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 = INAV_BIND_COUNT; + bind_acked = 0; + return FIRST_INAV_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 INAV_PACKET_PERIOD; + } + send_packet(BIND_INAV_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_INAV_PACKET); + break; + } + return INAV_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(INAV_BIND_COUNT * INAV_PACKET_PERIOD / 1000); + } else { + set_data_phase(); +// BIND_DONE; + } + return INAV_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_q303.ino b/Multiprotocol/Nrf24l01_q303.ino new file mode 100644 index 0000000..729373b --- /dev/null +++ b/Multiprotocol/Nrf24l01_q303.ino @@ -0,0 +1,152 @@ +#ifdef Q303_NRF24L01_INO + +#include "iface_nrf24l01.h" + +#define Q303_BIND_COUNT 1200 + +#define Q303_PACKET_SIZE 10 +#define Q303_PACKET_PERIOD 1500 // Timeout for callback in uSec +#define Q303_INITIAL_WAIT 500 +#define Q303_RF_BIND_CHANNEL 0x02 +#define Q303_NUM_RF_CHANNELS 4 + +static uint8_t tx_addr[5]; +static uint8_t current_chan; +uint8_t txid[4] = {0xAE, 0x89, 0x97, 0x87}; +static uint8_t rf_chans[4] = {0x4A, 0x4C, 0x4E, 0x48}; + +// haven't figured out txid<-->rf channel mapping yet +// static const struct { uint8_t txid[sizeof(txid)]; uint8_t rfchan[Q303_NUM_RF_CHANNELS]; } q303_tx_rf_map[] = {{{0xAE, 0x89, 0x97, 0x87}, {0x4A, 0x4C, 0x4E, 0x48}}}; + +enum { + Q303_BIND, + Q303_DATA +}; + +// flags going to packet[8] +#define Q303_FLAG_HIGHRATE 0x03 +#define Q303_FLAG_AHOLD 0x40 +#define Q303_FLAG_RTH 0x80 + +// flags going to packet[9] +#define Q303_FLAG_GIMBAL_DN 0x04 +#define Q303_FLAG_GIMBAL_UP 0x20 +#define Q303_FLAG_HEADLESS 0x08 +#define Q303_FLAG_FLIP 0x80 +#define Q303_FLAG_SNAPSHOT 0x10 +#define Q303_FLAG_VIDEO 0x01 + +static void send_packet(uint8_t bind) +{ + if(bind) { + packet[0] = 0xaa; + memcpy(&packet[1], txid, 4); + memset(&packet[5], 0, 5); + } + else { + aileron = map(Servo_data[AILERON], 1000, 2000, 0, 1000); + elevator = 1000 - map(Servo_data[ELEVATOR], 1000, 2000, 0, 1000); + throttle = map(Servo_data[THROTTLE], 1000, 2000, 0, 1000); + rudder = 1000 - map(Servo_data[RUDDER], 1000, 2000, 0, 1000); + + packet[0] = 0x55; + packet[1] = aileron >> 2 ; // 8 bits + packet[2] = (aileron & 0x03) << 6 // 2 bits + | (elevator >> 4); // 6 bits + packet[3] = (elevator & 0x0f) << 4 // 4 bits + | (throttle >> 6); // 4 bits + packet[4] = (throttle & 0x3f) << 2 // 6 bits + | (rudder >> 8); // 2 bits + packet[5] = rudder & 0xff; // 8 bits + packet[6] = 0x10; // trim(s) ? + packet[7] = 0x10; // trim(s) ? + packet[8] = 0x03 // high rate (0-3) + | GET_FLAG(Servo_AUX1, Q303_FLAG_AHOLD) + | GET_FLAG(Servo_AUX6, Q303_FLAG_RTH); + packet[9] = 0x40 // always set + | GET_FLAG(Servo_AUX5, Q303_FLAG_HEADLESS) + | GET_FLAG(Servo_AUX2, Q303_FLAG_FLIP) + | GET_FLAG(Servo_AUX3, Q303_FLAG_SNAPSHOT) + | GET_FLAG(Servo_AUX4, Q303_FLAG_VIDEO); + if(Servo_data[AUX7] < (servo_max_100-PPM_SWITCH)) + packet[9] |= Q303_FLAG_GIMBAL_DN; + else if(Servo_data[AUX7] > PPM_SWITCH) + packet[9] |= Q303_FLAG_GIMBAL_UP; + // set low rate for first packets + if(bind_counter != 0) { + packet[8] &= ~0x03; + bind_counter--; + } + } + + // Power on, TX mode, CRC enabled + XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); + if (bind) { + NRF24L01_WriteReg(NRF24L01_05_RF_CH, Q303_RF_BIND_CHANNEL); + } else { + NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_chans[current_chan++]); + current_chan %= Q303_NUM_RF_CHANNELS; + } + + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); + NRF24L01_FlushTx(); + + XN297_WritePayload(packet, Q303_PACKET_SIZE); +} + +static uint16_t q303_callback() +{ + switch (phase) { + case Q303_BIND: + if (bind_counter == 0) { + tx_addr[0] = 0x55; + memcpy(&tx_addr[1], txid, 4); + XN297_SetTXAddr(tx_addr, 5); + phase = Q303_DATA; + bind_counter = Q303_BIND_COUNT; + BIND_DONE; + } else { + send_packet(1); + bind_counter--; + } + break; + case Q303_DATA: + send_packet(0); + break; + } + return Q303_PACKET_PERIOD; +} + +static uint16_t q303_init() +{ +// memcpy(txid, q303_tx_rf_map[MProtocol_id % (sizeof(q303_tx_rf_map)/sizeof(q303_tx_rf_map[0]))].txid, sizeof(txid)); +// memcpy(rf_chans, q303_tx_rf_map[MProtocol_id % (sizeof(q303_tx_rf_map)/sizeof(q303_tx_rf_map[0]))].rfchan, sizeof(rf_chans)); + + NRF24L01_Initialize(); + NRF24L01_SetTxRxMode(TX_EN); + + XN297_SetTXAddr((uint8_t *) "\xCC\xCC\xCC\xCC\xCC", 5); + NRF24L01_FlushTx(); + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit + NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes + NRF24L01_WriteReg(NRF24L01_05_RF_CH, Q303_RF_BIND_CHANNEL); + NRF24L01_SetBitrate(NRF24L01_BR_250K); + NRF24L01_SetPower(); + + // this sequence necessary for module from stock tx + NRF24L01_ReadReg(NRF24L01_1D_FEATURE); + NRF24L01_Activate(0x73); // Activate feature register + NRF24L01_ReadReg(NRF24L01_1D_FEATURE); + NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes + NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x00); // Set feature bits on + NRF24L01_Activate(0x53); // switch bank back + + BIND_IN_PROGRESS; + bind_counter = Q303_BIND_COUNT; + current_chan = 0; +// PROTOCOL_SetBindState(Q303_BIND_COUNT * Q303_PACKET_PERIOD / 1000); + phase = Q303_BIND; + return Q303_INITIAL_WAIT; +} + +#endif \ No newline at end of file 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/PPM_SERIE.txt b/Multiprotocol/PPM_SERIE.txt new file mode 100644 index 0000000..263c90b --- /dev/null +++ b/Multiprotocol/PPM_SERIE.txt @@ -0,0 +1,89 @@ +#define PPM_TEST 3 //test voie valeur + +#define PPM_MIN_COMMAND 1250 +#define PPM_SWITCH 1550 +#define PPM_MAX_COMMAND 1750 +#define isterie 10 + + +#define PPM_Pin 3 //this must be 2 or 3 +int ppm[18]; //array for storing up to 16 servo signals +int maxi = 0, mini = 3000, decal, moy, a,r, val; + +void setup() { + Serial.begin(115200); Serial.println("ready"); + pinMode(PPM_Pin, INPUT); attachInterrupt(PPM_Pin - 2, read_ppm, CHANGE); + + TCCR1A = 0; //reset timer1 + TCCR1B = 0; + TCCR1B |= (1 << CS11); //set timer1 to increment every 0,5 us +} + +void loop() { + //You can delete everithing inside loop() and put your own code here + int count; + if(ppm[PPM_TEST]maxi) { + maxi = max( maxi, ppm[PPM_TEST]); + mini = min( mini, ppm[PPM_TEST]); + moy = (maxi + mini)/2; + decal = (maxi - moy) / 125 * 100; + a = moy + decal; + r = moy - decal; + } + Serial.print(a); Serial.print(" "); + Serial.print(r); Serial.print(" "); + Serial.print(maxi); Serial.print(" "); + Serial.print(mini); Serial.print(" "); + Serial.print(moy); Serial.print(" "); + if((PPM_SWITCH - isterie) < moy < (PPM_SWITCH + isterie)) { + Serial.print(" . Pb istérie PPM middel "); + Serial.print(PPM_SWITCH); + } + else { + Serial.print(" . "); + + count = 0; + Serial.print(ppm[count]); Serial.print(" "); count++; + Serial.print(ppm[count]); Serial.print(" "); count++; + Serial.print(ppm[count]); Serial.print(" "); count++; + Serial.print(ppm[count]); Serial.print(" "); count++; + for( ;count<17;count++) { + val=ppm[count]; + if((moy-2*isterie) < val < (moy+2*isterie)) { Serial.print("2"); } + else if(PPM_MAX_COMMAND < val < 2200) { Serial.print("3"); } + else if(PPM_MAX_COMMAND < val) { Serial.print("+"); } + else if(800 < val < PPM_MIN_COMMAND) { Serial.print("1"); } + else { Serial.print("."); } + + } +/* + while(ppm[count] != 0){ //print out the servo values + Serial.print(count); Serial.print(" "); + Serial.print(ppm[count]); Serial.print(" "); + count++; + } +*/ + } + Serial.println(""); + delay(100); //you can even use delays!!! +} + +void read_ppm(){ //leave this alone + #if F_CPU == 16000000 + #define PPM_SCALE 1L + #elif F_CPU == 8000000 + #define PPM_SCALE 0L + #else + #error // 8 or 16MHz only ! + #endif + static unsigned int pulse; + static unsigned long counter; + static byte channel; + + counter = TCNT1; + TCNT1 = 0; + + if(counter < 510 << PPM_SCALE){ pulse = counter; } //must be a pulse if less than 510us + else if(counter > 1910 << PPM_SCALE){ channel = 0; } //sync pulses over 1910us + else{ ppm[channel] = (counter + pulse) >> PPM_SCALE; channel++; } //servo values between 510us and 2420us will end up here +} \ No newline at end of file diff --git a/Multiprotocol/Pins.h b/Multiprotocol/Pins.h index 463d395..c163b38 100644 --- a/Multiprotocol/Pins.h +++ b/Multiprotocol/Pins.h @@ -15,195 +15,323 @@ //******************* //*** Pinouts *** //******************* +#ifndef STM32_BOARD + // TX + #define SERIAL_TX_pin 1 //PD1 + #define SERIAL_TX_port PORTD + #define SERIAL_TX_ddr DDRD + #define SERIAL_TX_output SERIAL_TX_ddr |= _BV(SERIAL_TX_pin) + #define SERIAL_TX_on SERIAL_TX_port |= _BV(SERIAL_TX_pin) + #define SERIAL_TX_off SERIAL_TX_port &= ~_BV(SERIAL_TX_pin) + #ifdef DEBUG_TX + #define DEBUG_TX_on SERIAL_TX_on + #define DEBUG_TX_off SERIAL_TX_off + #define DEBUG_TX_toggle SERIAL_TX_port ^= _BV(SERIAL_TX_pin) + #else + #define DEBUG_TX_on + #define DEBUG_TX_off + #define DEBUG_TX_toggle + #endif -// TX -#define SERIAL_TX_pin 1 //PD1 -#define SERIAL_TX_port PORTD -#define SERIAL_TX_ddr DDRD -#define SERIAL_TX_output SERIAL_TX_ddr |= _BV(SERIAL_TX_pin) -#define SERIAL_TX_on SERIAL_TX_port |= _BV(SERIAL_TX_pin) -#define SERIAL_TX_off SERIAL_TX_port &= ~_BV(SERIAL_TX_pin) -#ifdef DEBUG_TX - #define DEBUG_TX_on SERIAL_TX_ON - #define DEBUG_TX_off SERIAL_TX_OFF - #define DEBUG_TX_toggle SERIAL_TX_port ^= _BV(SERIAL_TX_pin) -#else - #define DEBUG_TX_on - #define DEBUG_TX_off - #define DEBUG_TX_toggle + // Dial + #define MODE_DIAL1_pin 2 + #define MODE_DIAL1_port PORTB + #define MODE_DIAL1_ipr PINB + #define MODE_DIAL2_pin 3 + #define MODE_DIAL2_port PORTB + #define MODE_DIAL2_ipr PINB + #define MODE_DIAL3_pin 4 + #define MODE_DIAL3_port PORTB + #define MODE_DIAL3_ipr PINB + #define MODE_DIAL4_pin 0 + #define MODE_DIAL4_port PORTC + #define MODE_DIAL4_ipr PINC + + // PPM + #define PPM_pin 3 //D3 = PD3 + #define PPM_port PORTD + + // SDIO + #define SDI_pin 5 //D5 = PD5 + #define SDI_port PORTD + #define SDI_ipr PIND + #define SDI_ddr DDRD + #ifdef ORANGE_TX + #define SDI_on SDI_port.OUTSET = _BV(SDI_pin) + #define SDI_off SDI_port.OUTCLR = _BV(SDI_pin) + #else + #define SDI_on SDI_port |= _BV(SDI_pin) + #define SDI_off SDI_port &= ~_BV(SDI_pin) + #define SDI_1 (SDI_ipr & _BV(SDI_pin)) + #define SDI_0 (SDI_ipr & _BV(SDI_pin)) == 0x00 + #endif + #define SDI_input SDI_ddr &= ~_BV(SDI_pin) + #define SDI_output SDI_ddr |= _BV(SDI_pin) + + //SDO + #define SDO_pin 6 //D6 = PD6 + #define SDO_port PORTD + #define SDO_ipr PIND + #ifdef ORANGE_TX + #define SDO_1 (SDO_port.IN & _BV(SDO_pin)) + #define SDO_0 (SDO_port.IN & _BV(SDO_pin)) == 0x00 + #else + #define SDO_1 (SDO_ipr & _BV(SDO_pin)) + #define SDO_0 (SDO_ipr & _BV(SDO_pin)) == 0x00 + #endif + + // SCLK + #define SCLK_port PORTD + #define SCLK_ddr DDRD + #ifdef ORANGE_TX + #define SCLK_pin 7 //PD7 + #define SCLK_on SCLK_port.OUTSET = _BV(SCLK_pin) + #define SCLK_off SCLK_port.OUTCLR = _BV(SCLK_pin) + #else + #define SCLK_pin 4 //D4 = PD4 + #define SCLK_output SCLK_ddr |= _BV(SCLK_pin) + #define SCLK_on SCLK_port |= _BV(SCLK_pin) + #define SCLK_off SCLK_port &= ~_BV(SCLK_pin) + #endif + + // A7105 + #define A7105_CSN_pin 2 //D2 = PD2 + #define A7105_CSN_port PORTD + #define A7105_CSN_ddr DDRD + #define A7105_CSN_output A7105_CSN_ddr |= _BV(A7105_CSN_pin) + #define A7105_CSN_on A7105_CSN_port |= _BV(A7105_CSN_pin) + #define A7105_CSN_off A7105_CSN_port &= ~_BV(A7105_CSN_pin) + + // CC2500 + #define CC25_CSN_pin 7 //D7 = PD7 + #define CC25_CSN_port PORTD + #define CC25_CSN_ddr DDRD + #define CC25_CSN_output CC25_CSN_ddr |= _BV(CC25_CSN_pin) + #define CC25_CSN_on CC25_CSN_port |= _BV(CC25_CSN_pin) + #define CC25_CSN_off CC25_CSN_port &= ~_BV(CC25_CSN_pin) + + // NRF24L01 + #define NRF_CSN_pin 0 //D8 = PB0 + #define NRF_CSN_port PORTB + #define NRF_CSN_ddr DDRB + #define NRF_CSN_output NRF_CSN_ddr |= _BV(NRF_CSN_pin) + #define NRF_CSN_on NRF_CSN_port |= _BV(NRF_CSN_pin) + #define NRF_CSN_off NRF_CSN_port &= ~_BV(NRF_CSN_pin) + #define NRF_CE_on + #define NRF_CE_off + + // CYRF6936 + #ifdef ORANGE_TX + #define CYRF_CSN_pin 4 //PD4 + #define CYRF_CSN_port PORTD + #define CYRF_CSN_ddr DDRD + #define CYRF_CSN_on CYRF_CSN_port.OUTSET = _BV(CYRF_CSN_pin) + #define CYRF_CSN_off CYRF_CSN_port.OUTCLR = _BV(CYRF_CSN_pin) + + #define CYRF_RST_pin 0 //PE0 + #define CYRF_RST_port PORTE + #define CYRF_RST_ddr DDRE + #define CYRF_RST_HI CYRF_RST_port.OUTSET = _BV(CYRF_RST_pin) + #define CYRF_RST_LO CYRF_RST_port.OUTCLR = _BV(CYRF_RST_pin) + #else + #define CYRF_CSN_pin 1 //D9 = PB1 + #define CYRF_CSN_port PORTB + #define CYRF_CSN_ddr DDRB + #define CYRF_CSN_output CYRF_CSN_ddr |= _BV(CYRF_CSN_pin) + #define CYRF_CSN_on CYRF_CSN_port |= _BV(CYRF_CSN_pin) + #define CYRF_CSN_off CYRF_CSN_port &= ~_BV(CYRF_CSN_pin) + + #define CYRF_RST_pin 5 //A5 = PC5 + #define CYRF_RST_port PORTC + #define CYRF_RST_ddr DDRC + #define CYRF_RST_output CYRF_RST_ddr |= _BV(CYRF_RST_pin) + #define CYRF_RST_HI CYRF_RST_port |= _BV(CYRF_RST_pin) + #define CYRF_RST_LO CYRF_RST_port &= ~_BV(CYRF_RST_pin) + #endif + + //RF Switch + #ifdef ORANGE_TX + #define PE1_on + #define PE1_off + #define PE2_on + #define PE2_off + #else + #define PE1_pin 1 //A1 = PC1 + #define PE1_port PORTC + #define PE1_ddr DDRC + #define PE1_output PE1_ddr |= _BV(PE1_pin) + #define PE1_on PE1_port |= _BV(PE1_pin) + #define PE1_off PE1_port &= ~_BV(PE1_pin) + + #define PE2_pin 2 //A2 = PC2 + #define PE2_port PORTC + #define PE2_ddr DDRC + #define PE2_output PE2_ddr |= _BV(PE2_pin) + #define PE2_on PE2_port |= _BV(PE2_pin) + #define PE2_off PE2_port &= ~_BV(PE2_pin) + #endif + + // LED + #ifdef ORANGE_TX + #define LED_pin 1 //PD1 + #define LED_port PORTD + #define LED_ddr DDRD + #define LED_on LED_port.OUTCLR = _BV(LED_pin) + #define LED_off LED_port.OUTSET = _BV(LED_pin) + #define LED_toggle LED_port.OUTTGL = _BV(LED_pin) + #define LED_output LED_port.DIRSET = _BV(LED_pin) + #define IS_LED_on (LED_port.OUT & _BV(LED_pin)) + #else + #define LED_pin 5 //D13 = PB5 + #define LED_port PORTB + #define LED_ddr DDRB + #define LED_on LED_port |= _BV(LED_pin) + #define LED_off LED_port &= ~_BV(LED_pin) + #define LED_toggle LED_port ^= _BV(LED_pin) + #define LED_output LED_ddr |= _BV(LED_pin) + #define IS_LED_on (LED_port & _BV(LED_pin)) + #endif + + //BIND + #ifdef ORANGE_TX + #define BIND_pin 2 //PD2 + #define BIND_port PORTD + #define IS_BIND_BUTTON_on ( (BIND_port.IN & _BV(BIND_pin)) == 0x00 ) + #else + #define BIND_pin 5 //D13 = PB5 + #define BIND_port PORTB + #define BIND_ipr PINB + #define BIND_ddr DDRB + #define BIND_SET_INPUT BIND_ddr &= ~_BV(BIND_pin) + #define BIND_SET_OUTPUT BIND_ddr |= _BV(BIND_pin) + #define BIND_SET_PULLUP BIND_port |= _BV(BIND_pin) + #define IS_BIND_BUTTON_on ( (BIND_ipr & _BV(BIND_pin)) == 0x00 ) + #endif +#else //STM32_BOARD + #define BIND_pin PA0 + #define LED_pin PA1 + // + #define PPM_pin PA8 //PPM 5V tolerant + // + #define S1_pin PA4 //Dial switch pins + #define S2_pin PA5 + #define S3_pin PA6 + #define S4_pin PA7 + // + #define PE1_pin PB4 //PE1 + #define PE2_pin PB5 //PE2 + //CS pins + #define CC25_CSN_pin PB6 //CC2500 + #define NRF_CSN_pin PB7 //NRF24L01 + #define CYRF_RST_pin PB8 //CYRF RESET + #define A7105_CSN_pin PB9 //A7105 + #define CYRF_CSN_pin PB12 //CYRF CSN + //SPI pins + #define SCK_pin PB13 //SCK + #define SDO_pin PB14 //MISO + #define SDI_pin PB15 //MOSI + // + #define TX_INV_pin PB3 + #define RX_INV_pin PB1 + // + #define PE1_on digitalWrite(PE1_pin,HIGH) + #define PE1_off digitalWrite(PE1_pin,LOW) + // + #define PE2_on digitalWrite(PE2_pin,HIGH) + #define PE2_off digitalWrite(PE2_pin,LOW) + + #define A7105_CSN_on digitalWrite(A7105_CSN_pin,HIGH) + #define A7105_CSN_off digitalWrite(A7105_CSN_pin,LOW) + + #define NRF_CE_on + #define NRF_CE_off + + #define SCK_on digitalWrite(SCK_pin,HIGH) + #define SCK_off digitalWrite(SCK_pin,LOW) + + #define SDI_on digitalWrite(SDI_pin,HIGH) + #define SDI_off digitalWrite(SDI_pin,LOW) + + #define SDI_1 (digitalRead(SDI_pin)==HIGH) + #define SDI_0 (digitalRead(SDI_pin)==LOW) + + #define CC25_CSN_on digitalWrite(CC25_CSN_pin,HIGH) + #define CC25_CSN_off digitalWrite(CC25_CSN_pin,LOW) + + #define NRF_CSN_on digitalWrite(NRF_CSN_pin,HIGH) + #define NRF_CSN_off digitalWrite(NRF_CSN_pin,LOW) + + #define CYRF_CSN_on digitalWrite(CYRF_CSN_pin,HIGH) + #define CYRF_CSN_off digitalWrite(CYRF_CSN_pin,LOW) + + #define CYRF_RST_HI digitalWrite(CYRF_RST_pin,HIGH) //reset cyrf + #define CYRF_RST_LO digitalWrite(CYRF_RST_pin,LOW) // + + #define SDO_1 (digitalRead(SDO_pin)==HIGH) + #define SDO_0 (digitalRead(SDO_pin)==LOW) + + #define TX_INV_on digitalWrite(TX_INV_pin,HIGH) + #define TX_INV_off digitalWrite(TX_INV_pin,LOW) + + #define RX_INV_on digitalWrite(RX_INV_pin,HIGH) + #define RX_INV_off digitalWrite(RX_INV_pin,LOW) + + #define LED_on digitalWrite(LED_pin,HIGH) + #define LED_off digitalWrite(LED_pin,LOW) + #define LED_toggle digitalWrite(LED_pin ,!digitalRead(LED_pin)) + #define LED_output pinMode(LED_pin,OUTPUT) + #define IS_LED_on ( digitalRead(LED_pin)==HIGH) + + #define BIND_SET_INPUT pinMode(BIND_pin,INPUT) + #define BIND_SET_PULLUP digitalWrite(BIND_pin,HIGH) + #define BIND_SET_OUTPUT pinMode(BIND_pin,OUTPUT) + #define IS_BIND_BUTTON_on (digitalRead(BIND_pin)==LOW) + + #define cli() noInterrupts() + #define sei() interrupts() + #define delayMilliseconds(x) delay(x) #endif -// Dial -#define MODE_DIAL1_pin 2 -#define MODE_DIAL1_port PORTB -#define MODE_DIAL1_ipr PINB -#define MODE_DIAL2_pin 3 -#define MODE_DIAL2_port PORTB -#define MODE_DIAL2_ipr PINB -#define MODE_DIAL3_pin 4 -#define MODE_DIAL3_port PORTB -#define MODE_DIAL3_ipr PINB -#define MODE_DIAL4_pin 0 -#define MODE_DIAL4_port PORTC -#define MODE_DIAL4_ipr PINC - -// PPM -#define PPM_pin 3 //D3 = PD3 -#define PPM_port PORTD - -// SDIO -#define SDI_pin 5 //D5 = PD5 -#define SDI_port PORTD -#define SDI_ipr PIND -#define SDI_ddr DDRD -#ifdef XMEGA - #define SDI_on SDI_port.OUTSET = _BV(SDI_pin) - #define SDI_off SDI_port.OUTCLR = _BV(SDI_pin) +//******************* +//*** Timer *** +//******************* +#ifdef ORANGE_TX + #define TIFR1 TCC1.INTFLAGS + #define OCF1A_bm TC1_CCAIF_bm + #define OCR1A TCC1.CCA + #define TCNT1 TCC1.CNT + #define UDR0 USARTC0.DATA + #define OCF1B_bm TC1_CCBIF_bm + #define OCR1B TCC1.CCB + #define TIMSK1 TCC1.INTCTRLB + #define SET_TIMSK1_OCIE1B TIMSK1 = (TIMSK1 & 0xF3) | 0x04 + #define CLR_TIMSK1_OCIE1B TIMSK1 &= 0xF3 #else - #define SDI_on SDI_port |= _BV(SDI_pin) - #define SDI_off SDI_port &= ~_BV(SDI_pin) - #define SDI_1 (SDI_ipr & _BV(SDI_pin)) - #define SDI_0 (SDI_ipr & _BV(SDI_pin)) == 0x00 -#endif -#define SDI_input SDI_ddr &= ~_BV(SDI_pin) -#define SDI_output SDI_ddr |= _BV(SDI_pin) - -//SDO -#define SDO_pin 6 //D6 = PD6 -#define SDO_port PORTD -#define SDO_ipr PIND -#ifdef XMEGA - #define SDO_1 (SDO_port.IN & _BV(SDO_pin)) - #define SDO_0 (SDO_port.IN & _BV(SDO_pin)) == 0x00 -#else - #define SDO_1 (SDO_ipr & _BV(SDO_pin)) - #define SDO_0 (SDO_ipr & _BV(SDO_pin)) == 0x00 + #ifdef STM32_BOARD + #define OCR1A TIMER2_BASE->CCR1 + #define TCNT1 TIMER2_BASE->CNT + #define UDR0 USART2_BASE->DR + #define TIFR1 TIMER2_BASE->SR + #define OCF1A_bm TIMER_SR_CC1IF + #define UCSR0B USART2_BASE->CR1 + #define RXCIE0 USART_CR1_RXNEIE_BIT + #define TXCIE0 USART_CR1_TXEIE_BIT + //#define TIFR1 TIMER2_BASE->SR + #else + #define OCF1A_bm _BV(OCF1A) + #define OCF1B_bm _BV(OCF1B) + #define SET_TIMSK1_OCIE1B TIMSK1 |= _BV(OCIE1B) + #define CLR_TIMSK1_OCIE1B TIMSK1 &=~_BV(OCIE1B) + #endif #endif -// SCLK -#define SCLK_port PORTD -#define SCLK_ddr DDRD -#ifdef XMEGA - #define SCLK_pin 7 //PD7 - #define SCLK_on SCLK_port.OUTSET = _BV(SCLK_pin) - #define SCLK_off SCLK_port.OUTCLR = _BV(SCLK_pin) +//******************* +//*** EEPROM *** +//******************* +#ifdef STM32_BOARD + #define EE_ADDR uint16 + #define eeprom_write_byte EEPROM.write + #define eeprom_read_byte EEPROM.read #else - #define SCLK_pin 4 //D4 = PD4 - #define SCLK_output SCLK_ddr |= _BV(SCLK_pin) - #define SCLK_on SCLK_port |= _BV(SCLK_pin) - #define SCLK_off SCLK_port &= ~_BV(SCLK_pin) -#endif - -// A7105 -#define A7105_CSN_pin 2 //D2 = PD2 -#define A7105_CSN_port PORTD -#define A7105_CSN_ddr DDRD -#define A7105_CSN_output A7105_CSN_ddr |= _BV(A7105_CSN_pin) -#define A7105_CSN_on A7105_CSN_port |= _BV(A7105_CSN_pin) -#define A7105_CSN_off A7105_CSN_port &= ~_BV(A7105_CSN_pin) - -// CC2500 -#define CC25_CSN_pin 7 //D7 = PD7 -#define CC25_CSN_port PORTD -#define CC25_CSN_ddr DDRD -#define CC25_CSN_output CC25_CSN_ddr |= _BV(CC25_CSN_pin) -#define CC25_CSN_on CC25_CSN_port |= _BV(CC25_CSN_pin) -#define CC25_CSN_off CC25_CSN_port &= ~_BV(CC25_CSN_pin) - -// NRF24L01 -#define NRF_CSN_pin 0 //D8 = PB0 -#define NRF_CSN_port PORTB -#define NRF_CSN_ddr DDRB -#define NRF_CSN_output NRF_CSN_ddr |= _BV(NRF_CSN_pin) -#define NRF_CSN_on NRF_CSN_port |= _BV(NRF_CSN_pin) -#define NRF_CSN_off NRF_CSN_port &= ~_BV(NRF_CSN_pin) -#define NRF_CE_on -#define NRF_CE_off - -// CYRF6936 -#ifdef XMEGA - #define CYRF_CSN_pin 4 //PD4 - #define CYRF_CSN_port PORTD - #define CYRF_CSN_ddr DDRD - #define CYRF_CSN_on CYRF_CSN_port.OUTSET = _BV(CYRF_CSN_pin) - #define CYRF_CSN_off CYRF_CSN_port.OUTCLR = _BV(CYRF_CSN_pin) - - #define CYRF_RST_pin 0 //PE0 - #define CYRF_RST_port PORTE - #define CYRF_RST_ddr DDRE - #define CYRF_RST_HI CYRF_RST_port.OUTSET = _BV(CYRF_RST_pin) - #define CYRF_RST_LO CYRF_RST_port.OUTCLR = _BV(CYRF_RST_pin) -#else - #define CYRF_CSN_pin 1 //D9 = PB1 - #define CYRF_CSN_port PORTB - #define CYRF_CSN_ddr DDRB - #define CYRF_CSN_output CYRF_CSN_ddr |= _BV(CYRF_CSN_pin) - #define CYRF_CSN_on CYRF_CSN_port |= _BV(CYRF_CSN_pin) - #define CYRF_CSN_off CYRF_CSN_port &= ~_BV(CYRF_CSN_pin) - - #define CYRF_RST_pin 5 //A5 = PC5 - #define CYRF_RST_port PORTC - #define CYRF_RST_ddr DDRC - #define CYRF_RST_output CYRF_RST_ddr |= _BV(CYRF_RST_pin) - #define CYRF_RST_HI CYRF_RST_port |= _BV(CYRF_RST_pin) - #define CYRF_RST_LO CYRF_RST_port &= ~_BV(CYRF_RST_pin) -#endif - -//RF Switch -#ifdef XMEGA - #define PE1_on - #define PE1_off - #define PE2_on - #define PE2_off -#else - #define PE1_pin 1 //A1 = PC1 - #define PE1_port PORTC - #define PE1_ddr DDRC - #define PE1_output PE1_ddr |= _BV(PE1_pin) - #define PE1_on PE1_port |= _BV(PE1_pin) - #define PE1_off PE1_port &= ~_BV(PE1_pin) - - #define PE2_pin 2 //A2 = PC2 - #define PE2_port PORTC - #define PE2_ddr DDRC - #define PE2_output PE2_ddr |= _BV(PE2_pin) - #define PE2_on PE2_port |= _BV(PE2_pin) - #define PE2_off PE2_port &= ~_BV(PE2_pin) -#endif - -// LED -#ifdef XMEGA - #define LED_pin 1 //PD1 - #define LED_port PORTD - #define LED_ddr DDRD - #define LED_on LED_port.OUTCLR = _BV(LED_pin) - #define LED_off LED_port.OUTSET = _BV(LED_pin) - #define LED_toggle LED_port.OUTTGL = _BV(LED_pin) - #define LED_output LED_port.DIRSET = _BV(LED_pin) - #define IS_LED_on (LED_port.OUT & _BV(LED_pin)) -#else - #define LED_pin 5 //D13 = PB5 - #define LED_port PORTB - #define LED_ddr DDRB - #define LED_on LED_port |= _BV(LED_pin) - #define LED_off LED_port &= ~_BV(LED_pin) - #define LED_toggle LED_port ^= _BV(LED_pin) - #define LED_output LED_ddr |= _BV(LED_pin) - #define IS_LED_on (LED_port & _BV(LED_pin)) -#endif - -//BIND -#ifdef XMEGA - #define BIND_pin 2 //PD2 - #define BIND_port PORTD - #define IS_BIND_BUTTON_on ( (BIND_port.IN & _BV(BIND_pin)) == 0x00 ) -#else - #define BIND_pin 5 //D13 = PB5 - #define BIND_port PORTB - #define BIND_ipr PINB - #define BIND_ddr DDRB - #define BIND_SET_INPUT BIND_ddr &= ~_BV(BIND_pin) - #define BIND_SET_OUTPUT BIND_ddr |= _BV(BIND_pin) - #define BIND_SET_PULLUP BIND_port |= _BV(BIND_pin) - #define IS_BIND_BUTTON_on ( (BIND_ipr & _BV(BIND_pin)) == 0x00 ) + #define EE_ADDR uint8_t* #endif diff --git a/Multiprotocol/README.md b/Multiprotocol/README.md new file mode 100644 index 0000000..dc2450b --- /dev/null +++ b/Multiprotocol/README.md @@ -0,0 +1,275 @@ +# 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 + +###CG023 +###Sub_protocol H8_3D +Models: EAchine H8 mini 3D, JJRC H20/H22, JJRC H11D + +CH5|CH6|CH7|CH8|CH9|CH10|CH11 +---|---|---|---|---|---|--- +FLIP|LIGTH|OPT1|OPT2|CAL|SNAPSHOT|VIDEO + +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 + +###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 + +###HISKY +####Sub_protocol HK310 + +###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 + +###MJX +####Sub_protocol H26WH + +###NE260 +Modele: Nine Eagles SoloPro + +Autobind + +CH1|CH2|CH3|CH4 +---|---|---|--- +A|E|T|R + +###Q303 + +Autobind + +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11 +---|---|---|---|---|---|---|---|---|---|--- +A|E|T|R|AHOLD|FLIP|SNAPSHOT|VIDEO|HEADLESS|RTH|GIMBAL + +###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. + +###V2X2 +####Sub_protocol V2X2 +Models: WLToys V202/252/272, JXD 385/388, JJRC H6C, Yizhan Tarantula X6 ... + +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11 +---|---|---|---|---|---|---|---|---|----|---- +A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS|MAG_CAL_X|MAG_CAL_Y + +PICTURE: also automatic Missile Launcher and Hoist in one direction + +VIDEO: also Sprayer, Bubbler, Missile Launcher(1), and Hoist in the other dir +####Sub_protocol JXD-506 +CH10|CH11|CH12 +----|----|---- +ARM|EMERGENCY|PAN CAMERA + +###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/SLT_nrf24l01.ino b/Multiprotocol/SLT_nrf24l01.ino index 8d4e486..9778d3c 100644 --- a/Multiprotocol/SLT_nrf24l01.ino +++ b/Multiprotocol/SLT_nrf24l01.ino @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with Multiprotocol. If not, see . */ -// Last sync with hexfet new_protocols/slt_nrf24l01.c dated 2015-02-13 +// Last sync with deviation main github branch #if defined(SLT_NRF24L01_INO) @@ -24,11 +24,11 @@ #define SLT_TXID_SIZE 4 enum { - SLT_INIT2 = 0, - SLT_BIND, + SLT_BUILD=0, SLT_DATA1, SLT_DATA2, - SLT_DATA3 + SLT_DATA3, + SLT_BIND }; static void __attribute__((unused)) SLT_init() @@ -45,24 +45,18 @@ static void __attribute__((unused)) SLT_init() NRF24L01_SetPower(); NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t*)"\xC3\xC3\xAA\x55", 4); NRF24L01_FlushRx(); -} - -static void __attribute__((unused)) SLT_init2() -{ + NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, SLT_TXID_SIZE); NRF24L01_FlushTx(); - packet_sent = 0; - hopping_frequency_no = 0; - // Turn radio power on NRF24L01_SetTxRxMode(TX_EN); } -static void __attribute__((unused)) SLT_set_tx_id(void) +static void __attribute__((unused)) SLT_set_freq(void) { // Frequency hopping sequence generation - for (uint8_t i = 0; i < 4; ++i) + for (uint8_t i = 0; i < SLT_TXID_SIZE; ++i) { - uint8_t next_i = (i+1) % 4; // is & 3 better than % 4 ? + uint8_t next_i = (i+1) % SLT_TXID_SIZE; // is & 3 better than % 4 ? uint8_t base = i < 2 ? 0x03 : 0x10; hopping_frequency[i*4 + 0] = (rx_tx_addr[i] & 0x3f) + base; hopping_frequency[i*4 + 1] = (rx_tx_addr[i] >> 2) + base; @@ -72,8 +66,9 @@ static void __attribute__((unused)) SLT_set_tx_id(void) } // unique - uint8_t done = 0; for (uint8_t i = 0; i < SLT_NFREQCHANNELS; ++i) + { + uint8_t done = 0; while (!done) { done = 1; @@ -86,14 +81,13 @@ static void __attribute__((unused)) SLT_set_tx_id(void) hopping_frequency[i] = hopping_frequency[i] - 0x50 + 0x03; } } - - NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 4); + } } static void __attribute__((unused)) SLT_wait_radio() { if (packet_sent) - while (!(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS))) ; + while (!(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS))); packet_sent = 0; } @@ -109,9 +103,15 @@ static void __attribute__((unused)) SLT_send_data(uint8_t *data, uint8_t len) static void __attribute__((unused)) SLT_build_packet() { - // aileron, elevator, throttle, rudder, gear, pitch + // Set radio channel - once per packet batch + NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]); + if (++hopping_frequency_no >= SLT_NFREQCHANNELS) + hopping_frequency_no = 0; + + // aileron, elevator, throttle, rudder, gear, pitch uint8_t e = 0; // byte where extension 2 bits for every 10-bit channel are packed - for (uint8_t i = 0; i < 4; ++i) { + for (uint8_t i = 0; i < 4; ++i) + { uint16_t v = convert_channel_10b(CH_AETR[i]); packet[i] = v; e = (e >> 2) | (uint8_t) ((v >> 2) & 0xC0); @@ -121,81 +121,71 @@ static void __attribute__((unused)) SLT_build_packet() // 8-bit channels packet[5] = convert_channel_8b(AUX1); packet[6] = convert_channel_8b(AUX2); - - // Set radio channel - once per packet batch - NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]); - if (++hopping_frequency_no >= SLT_NFREQCHANNELS) - hopping_frequency_no = 0; } static void __attribute__((unused)) SLT_send_bind_packet() { SLT_wait_radio(); - BIND_IN_PROGRESS; // autobind protocol + BIND_IN_PROGRESS; //Limit TX power to bind level NRF24L01_SetPower(); - NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)"\x7E\xB8\x63\xA9", 4); + BIND_DONE; + NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)"\x7E\xB8\x63\xA9", SLT_TXID_SIZE); NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x50); - SLT_send_data(rx_tx_addr, 4); + SLT_send_data(rx_tx_addr, SLT_TXID_SIZE); - // NB: we should wait until the packet's sent before changing TX address! - SLT_wait_radio(); + SLT_wait_radio(); //Wait until the packet's sent before changing TX address! - BIND_DONE; - NRF24L01_SetPower(); - NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 4); + NRF24L01_SetPower(); //Change power back to normal level + NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, SLT_TXID_SIZE); } uint16_t SLT_callback() { - uint16_t delay_us = 20000; // 3 packets with 1ms intervals every 22ms switch (phase) { - case SLT_INIT2: - SLT_init2(); - phase = SLT_BIND; - delay_us = 150; - break; - case SLT_BIND: - SLT_send_bind_packet(); - phase = SLT_DATA1; - delay_us = 19000; - break; - case SLT_DATA1: + case SLT_BUILD: SLT_build_packet(); - SLT_send_data(packet, 7); - phase = SLT_DATA2; - delay_us = 1000; - break; + phase++; + return 1000; + case SLT_DATA1: + SLT_send_data(packet, SLT_PAYLOADSIZE); + phase++; + return 1000; case SLT_DATA2: - SLT_send_data(packet, 7); - phase = SLT_DATA3; - delay_us = 1000; - break; + SLT_send_data(packet, SLT_PAYLOADSIZE); + phase++; + return 1000; case SLT_DATA3: - SLT_send_data(packet, 7); - if (++counter >= 100) + SLT_send_data(packet, SLT_PAYLOADSIZE); + if (++packet_count >= 100) { - counter = 0; - phase = SLT_BIND; - delay_us = 1000; + packet_count = 0; + phase++; + return 1000; } else { NRF24L01_SetPower(); // Set tx_power - phase = SLT_DATA1; + phase = SLT_BUILD; + return 19000; } - break; + case SLT_BIND: + SLT_send_bind_packet(); + phase = SLT_BUILD; + return 18000; } - return delay_us; + return 19000; } uint16_t initSLT() { - counter = 0; + packet_count = 0; + packet_sent = 0; + hopping_frequency_no = 0; + SLT_set_freq(); SLT_init(); - phase = SLT_INIT2; - SLT_set_tx_id(); + phase = SLT_BIND; return 50000; } diff --git a/Multiprotocol/SPI.ino b/Multiprotocol/SPI.ino index fcf2936..d652fc1 100644 --- a/Multiprotocol/SPI.ino +++ b/Multiprotocol/SPI.ino @@ -15,72 +15,145 @@ /********************/ /** SPI routines **/ /********************/ -#ifdef XMEGA - #define XNOP() NOP() +#ifdef STM32_BOARD + + SPIClass SPI_2(2); //Create an instance of the SPI Class called SPI_2 that uses the 2nd SPI Port + + void initSPI2() + { + //SPI_DISABLE(); + SPI_2.end(); + SPI2_BASE->CR1 &= ~SPI_CR1_DFF_8_BIT; //8 bits format This bit should be written only when SPI is disabled (SPE = ?0?) for correct operation. + SPI_2.begin(); //Initialize the SPI_2 port. + + SPI_2.setBitOrder(MSBFIRST); // Set the SPI_2 bit order + SPI_2.setDataMode(SPI_MODE0); // Set the SPI_2 data mode 0 + SPI_2.setClockDivider(SPI_CLOCK_DIV8); // Set the speed (36 / 8 = 4.5 MHz SPI_2 speed) + } + + void SPI_Write(uint8_t command) + {//working OK + SPI2_BASE->DR = command; //Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag). + while (!(SPI2_BASE->SR & SPI_SR_RXNE)); + command = SPI2_BASE->DR; // ... and read the last received data. + } + + uint8_t SPI_Read(void) + { + SPI_Write(0x00); + return SPI2_BASE->DR; + } + + uint8_t SPI_SDI_Read() + { + uint8_t rx=0; + cli(); //Fix Hubsan droputs?? + while(!(SPI2_BASE->SR & SPI_SR_TXE)); + while((SPI2_BASE->SR & SPI_SR_BSY)); + // + SPI_DISABLE(); + SPI_SET_BIDIRECTIONAL(); + volatile uint8_t x = SPI2_BASE->DR; + (void)x; + SPI_ENABLE(); + // + SPI_DISABLE(); + while(!(SPI2_BASE->SR& SPI_SR_RXNE)); + rx=SPI2_BASE->DR; + SPI_SET_UNIDIRECTIONAL(); + SPI_ENABLE(); + sei();//fix Hubsan dropouts?? + return rx; + } + + void SPI_ENABLE() + { + SPI2_BASE->CR1 |= SPI_CR1_SPE; + } + + void SPI_DISABLE() + { + SPI2_BASE->CR1 &= ~SPI_CR1_SPE; + } + + void SPI_SET_BIDIRECTIONAL() + { + SPI2_BASE->CR1 |= SPI_CR1_BIDIMODE; + SPI2_BASE->CR1 &= ~ SPI_CR1_BIDIOE;//receive only + } + + void SPI_SET_UNIDIRECTIONAL() + { + SPI2_BASE->CR1 &= ~SPI_CR1_BIDIMODE; + } #else - #define XNOP() -#endif + #ifdef ORANGE_TX + #define XNOP() NOP() + #else + #define XNOP() + #endif -void SPI_Write(uint8_t command) -{ - uint8_t n=8; - - SCLK_off;//SCK start low - XNOP(); - SDI_off; - XNOP(); - do + void SPI_Write(uint8_t command) { - if(command&0x80) - SDI_on; - else - SDI_off; - XNOP(); - SCLK_on; - XNOP(); - XNOP(); - command = command << 1; - SCLK_off; - XNOP(); - } - while(--n) ; - SDI_on; -} + uint8_t n=8; -uint8_t SPI_Read(void) -{ - uint8_t result=0,i; - for(i=0;i<8;i++) + SCLK_off;//SCK start low + XNOP(); + SDI_off; + XNOP(); + do + { + if(command&0x80) + SDI_on; + else + SDI_off; + XNOP(); + SCLK_on; + XNOP(); + XNOP(); + command = command << 1; + SCLK_off; + XNOP(); + } + while(--n) ; + SDI_on; + } + + uint8_t SPI_Read(void) { - result=result<<1; - if(SDO_1) - result |= 0x01; - SCLK_on; - XNOP(); - XNOP(); - NOP(); - SCLK_off; - XNOP(); - XNOP(); + uint8_t result=0,i; + for(i=0;i<8;i++) + { + result=result<<1; + if(SDO_1) + result |= 0x01; + SCLK_on; + XNOP(); + XNOP(); + NOP(); + SCLK_off; + XNOP(); + XNOP(); + } + return result; } - return result; -} -#ifdef A7105_INSTALLED -uint8_t SPI_SDIO_Read(void) -{ - uint8_t result=0; - SDI_input; - for(uint8_t i=0;i<8;i++) - { - result=result<<1; - if(SDI_1) ///if SDIO =1 - result |= 0x01; - SCLK_on; - NOP(); - SCLK_off; + #ifdef A7105_INSTALLED + uint8_t SPI_SDI_Read(void) + { + uint8_t result=0; + SDI_input; + for(uint8_t i=0;i<8;i++) + { + result=result<<1; + if(SDI_1) ///if SDIO =1 + result |= 0x01; + SCLK_on; + NOP(); + SCLK_off; + } + SDI_output; + return result; } - SDI_output; - return result; -} -#endif + #endif +#endif//STM32_BOARD \ No newline at end of file diff --git a/Multiprotocol/TX_Def.h b/Multiprotocol/TX_Def.h index 08e131a..ef18d5e 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% @@ -47,203 +56,156 @@ //PPM values used to compare #define PPM_MIN_COMMAND 1250 #define PPM_SWITCH 1550 +#define PPM_SWITCH_B 1450 #define PPM_MAX_COMMAND 1750 //Channel definitions #ifdef AETR -enum { - AILERON =0, - ELEVATOR, - THROTTLE, - RUDDER, -}; + #define AILERON 0 + #define ELEVATOR 1 + #define THROTTLE 2 + #define RUDDER 3 #endif #ifdef AERT -enum { - AILERON =0, - ELEVATOR, - RUDDER, - THROTTLE, -}; + #define AILERON 0 + #define ELEVATOR 1 + #define THROTTLE 3 + #define RUDDER 2 #endif #ifdef ARET -enum { - AILERON =0, - RUDDER, - ELEVATOR, - THROTTLE, -}; + #define AILERON 0 + #define ELEVATOR 2 + #define THROTTLE 3 + #define RUDDER 1 #endif #ifdef ARTE -enum { - AILERON =0, - RUDDER, - THROTTLE, - ELEVATOR, -}; + #define AILERON 0 + #define ELEVATOR 3 + #define THROTTLE 2 + #define RUDDER 1 #endif #ifdef ATRE -enum { - AILERON =0, - THROTTLE, - RUDDER, - ELEVATOR, -}; + #define AILERON 0 + #define ELEVATOR 3 + #define THROTTLE 1 + #define RUDDER 2 #endif #ifdef ATER -enum { - AILERON =0, - THROTTLE, - ELEVATOR, - RUDDER, -}; + #define AILERON 0 + #define ELEVATOR 2 + #define THROTTLE 1 + #define RUDDER 3 #endif #ifdef EATR -enum { - ELEVATOR =0, - AILERON, - THROTTLE, - RUDDER, -}; + #define AILERON 1 + #define ELEVATOR 0 + #define THROTTLE 2 + #define RUDDER 3 #endif #ifdef EART -enum { - ELEVATOR =0, - AILERON, - RUDDER, - THROTTLE, -}; + #define AILERON 1 + #define ELEVATOR 0 + #define THROTTLE 3 + #define RUDDER 2 #endif #ifdef ERAT -enum { - ELEVATOR =0, - RUDDER, - AILERON, - THROTTLE, -}; + #define AILERON 2 + #define ELEVATOR 0 + #define THROTTLE 3 + #define RUDDER 1 #endif #ifdef ERTA -enum { - ELEVATOR =0, - RUDDER, - THROTTLE, - AILERON, -}; + #define AILERON 3 + #define ELEVATOR 0 + #define THROTTLE 2 + #define RUDDER 1 #endif #ifdef ETRA -enum { - ELEVATOR =0, - THROTTLE, - RUDDER, - AILERON, -}; + #define AILERON 3 + #define ELEVATOR 0 + #define THROTTLE 1 + #define RUDDER 2 #endif #ifdef ETAR -enum { - ELEVATOR =0, - THROTTLE, - AILERON, - RUDDER, -}; + #define AILERON 2 + #define ELEVATOR 0 + #define THROTTLE 1 + #define RUDDER 3 #endif #ifdef TEAR -enum { - THROTTLE =0, - ELEVATOR, - AILERON, - RUDDER, -}; + #define AILERON 2 + #define ELEVATOR 1 + #define THROTTLE 0 + #define RUDDER 3 #endif #ifdef TERA -enum { - THROTTLE =0, - ELEVATOR, - RUDDER, - AILERON, -}; + #define AILERON 3 + #define ELEVATOR 1 + #define THROTTLE 0 + #define RUDDER 2 #endif #ifdef TREA -enum { - THROTTLE =0, - RUDDER, - ELEVATOR, - AILERON, -}; + #define AILERON 3 + #define ELEVATOR 2 + #define THROTTLE 0 + #define RUDDER 1 #endif #ifdef TRAE -enum { - THROTTLE =0, - RUDDER, - AILERON, - ELEVATOR, -}; + #define AILERON 2 + #define ELEVATOR 3 + #define THROTTLE 0 + #define RUDDER 1 #endif #ifdef TARE -enum { - THROTTLE =0, - AILERON, - RUDDER, - ELEVATOR, -}; + #define AILERON 1 + #define ELEVATOR 3 + #define THROTTLE 0 + #define RUDDER 2 #endif #ifdef TAER -enum { - THROTTLE =0, - AILERON, - ELEVATOR, - RUDDER, -}; + #define AILERON 1 + #define ELEVATOR 2 + #define THROTTLE 0 + #define RUDDER 3 #endif #ifdef RETA -enum { - RUDDER =0, - ELEVATOR, - THROTTLE, - AILERON, -}; + #define AILERON 3 + #define ELEVATOR 1 + #define THROTTLE 2 + #define RUDDER 0 #endif #ifdef REAT -enum { - RUDDER =0, - ELEVATOR, - AILERON, - THROTTLE, -}; + #define AILERON 2 + #define ELEVATOR 1 + #define THROTTLE 3 + #define RUDDER 0 #endif #ifdef RAET -enum { - RUDDER =0, - AILERON, - ELEVATOR, - THROTTLE, -}; + #define AILERON 1 + #define ELEVATOR 2 + #define THROTTLE 3 + #define RUDDER 0 #endif #ifdef RATE -enum { - RUDDER =0, - AILERON, - THROTTLE, - ELEVATOR, -}; + #define AILERON 1 + #define ELEVATOR 3 + #define THROTTLE 2 + #define RUDDER 0 #endif #ifdef RTAE -enum { - RUDDER =0, - THROTTLE, - AILERON, - ELEVATOR, -}; + #define AILERON 2 + #define ELEVATOR 3 + #define THROTTLE 1 + #define RUDDER 0 #endif #ifdef RTEA -enum { - RUDDER =0, - THROTTLE, - ELEVATOR, - AILERON, -}; + #define AILERON 3 + #define ELEVATOR 2 + #define THROTTLE 1 + #define RUDDER 0 #endif #define AUX1 4 diff --git a/Multiprotocol/Telemetry.ino b/Multiprotocol/Telemetry.ino index ad5e419..de2808e 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> 4 & 0x0f) == 0x08) @@ -304,12 +139,12 @@ void frsky_link_frame() frame[4] = (uint8_t)RSSI_dBm; } else - if (protocol==MODE_HUBSAN) + if (protocol==MODE_HUBSAN||protocol==MODE_AFHDS2A) { 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[3] = protocol==MODE_HUBSAN?0x00:(uint8_t)RSSI_dBm; + frame[4] = TX_RSSI; } frame[5] = frame[6] = frame[7] = frame[8] = 0; frskySendStuffed(); @@ -346,28 +181,28 @@ void frsky_user_frame() pass=1; case 1: - index=indexx; + indx=indexx; prev_index = indexx; - if(index>>>>>> 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 +251,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 +267,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); @@ -635,7 +320,11 @@ void sportSendFrame() { uint8_t i; sport_counter = (sport_counter + 1) %36; - + if(telemetry_lost) + { + sportIdle(); + return; + } if(sport_counter<6) { frame[0] = 0x98; @@ -686,30 +375,30 @@ void proces_sport_data(uint8_t data) case 0: if (data == START_STOP) {//waiting for 0x7e - index = 0; + indx = 0; pass = 1; } break; case 1: if (data == START_STOP) // Happens if missed packet {//waiting for 0x7e - index = 0; + indx = 0; pass = 1; break; } if(data == BYTESTUFF)//if they are stuffed pass=2; else - if (index < MAX_PKTX) - pktx[index++] = data; + if (indx < MAX_PKTX) + pktx[indx++] = data; break; case 2: - if (index < MAX_PKTX) - pktx[index++] = data ^ STUFF_MASK; //unstuff bytes + if (indx < MAX_PKTX) + pktx[indx++] = data ^ STUFF_MASK; //unstuff bytes pass=1; break; } // end switch - if (index >= FRSKY_SPORT_PACKET_SIZE) + if (indx >= FRSKY_SPORT_PACKET_SIZE) {//8 bytes no crc if ( sport ) { @@ -732,93 +421,99 @@ 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; - } - } -#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 ; - } - -#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; - } - #endif - if(telemetry_link && protocol != MODE_FRSKYX ) - { // FrSky + Hubsan - frsky_link_frame(); - telemetry_link=0; - return; - } - #if defined HUB_TELEMETRY - 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) + #ifdef BASH_SERIAL + uint8_t h ; + uint8_t t ; + h = SerialControl.head ; + t = SerialControl.tail ; + if ( h >= t ) { - sportSendFrame(); - last += SPORT_TIME ; + 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 + + #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 ; + if(pktt[6]<=6) + for (uint8_t i=0; i < pktt[6]; i++) + proces_sport_data(pktt[7+i]); + telemetry_link=0; + } + uint32_t now = micros(); + if ((now - last) > SPORT_TIME) + { + sportSendFrame(); + #ifdef STM32_BOARD + last=now; + #else + last += SPORT_TIME ; + #endif + } } - } #endif + + #if defined DSM_TELEMETRY + if(telemetry_link && protocol == MODE_DSM ) + { // DSM + DSM_frame(); + telemetry_link=0; + return; + } + #endif + #if defined AFHDS2A_TELEMETRY + if(telemetry_link == 2 && protocol == MODE_AFHDS2A) + { + AFHDSA_short_frame(); + telemetry_link=0; + } + #endif + if(telemetry_link && protocol != MODE_FRSKYX ) + { // FrSkyD + Hubsan + AFHDS2A + frsky_link_frame(); + telemetry_link=0; + return; + } + #if defined HUB_TELEMETRY + if(!telemetry_link && protocol == MODE_FRSKYD) + { // FrSky + frsky_user_frame(); + return; + } + #endif } @@ -829,94 +524,139 @@ void TelemetryUpdate() /**************************/ #ifndef BASH_SERIAL -// Routines for normal serial output -void Serial_write(uint8_t data) -{ - uint8_t nextHead ; - nextHead = tx_head + 1 ; - if ( nextHead >= TXBUFFER_SIZE ) - nextHead = 0 ; - tx_buff[nextHead]=data; - tx_head = nextHead ; - tx_resume(); -} - -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<=TXBUFFER_SIZE)//head - tx_tail=0; - UDR0=tx_buff[tx_tail]; + uint8_t nextHead ; + nextHead = tx_head + 1 ; + if ( nextHead >= TXBUFFER_SIZE ) + nextHead = 0 ; + tx_buff[nextHead]=data; + tx_head = nextHead ; + tx_resume(); } - if (tx_tail == tx_head) - tx_pause(); // Check if all data is transmitted . if yes disable transmitter UDRE interrupt -} + void initTXSerial( uint8_t speed) + { + #ifdef ENABLE_PPM + if(speed==SPEED_9600) + { // 9600 + #ifdef ORANGE_TX + USARTC0.BAUDCTRLA = 207 ; + USARTC0.BAUDCTRLB = 0 ; + USARTC0.CTRLB = 0x18 ; + USARTC0.CTRLA = (USARTC0.CTRLA & 0xCF) | 0x10 ; + USARTC0.CTRLC = 0x03 ; + #else + #ifdef STM32_BOARD + usart3_begin(9600,SERIAL_8N1); //USART3 + USART3_BASE->CR1 &= ~ USART_CR1_RE; //disable RX leave TX enabled + #else + UBRR0H = 0x00; + UBRR0L = 0x67; + UCSR0A = 0 ; // Clear X2 bit + //Set frame format to 8 data bits, none, 1 stop bit + UCSR0C = (1<CR1 &= ~ USART_CR1_RE; //disable RX leave TX enabled + #else + UBRR0H = 0x00; + UBRR0L = 0x22; + UCSR0A = 0x02 ; // Set X2 bit + //Set frame format to 8 data bits, none, 1 stop bit + UCSR0C = (1<CR1 &= ~ USART_CR1_RE; //disable RX leave TX enabled + #else + UBRR0H = 0x00; + UBRR0L = 0x07; + UCSR0A = 0x00 ; // Clear X2 bit + //Set frame format to 8 data bits, none, 1 stop bit + UCSR0C = (1<SR & USART_SR_TXE) + { + #endif + if(tx_head!=tx_tail) + { + if(++tx_tail>=TXBUFFER_SIZE)//head + tx_tail=0; + #ifdef STM32_BOARD + USART3_BASE->DR=tx_buff[tx_tail];//clears TXE bit + #else + UDR0=tx_buff[tx_tail]; + #endif + } + if (tx_tail == tx_head) + tx_pause(); // Check if all data is transmitted . if yes disable transmitter UDRE interrupt + #ifdef STM32_BOARD + } + #endif + } + #ifdef STM32_BOARD + void usart2_begin(uint32_t baud,uint32_t config ) + { + usart_init(USART2); + usart_config_gpios_async(USART2,GPIOA,PIN_MAP[PA3].gpio_bit,GPIOA,PIN_MAP[PA2].gpio_bit,config); + usart_set_baud_rate(USART2, STM32_PCLK1, baud);// + usart_enable(USART2); + } + void usart3_begin(uint32_t baud,uint32_t config ) + { + usart_init(USART3); + usart_config_gpios_async(USART3,GPIOB,PIN_MAP[PB11].gpio_bit,GPIOB,PIN_MAP[PB10].gpio_bit,config); + usart_set_baud_rate(USART3, STM32_PCLK1, baud); + usart_enable(USART3); + } + #endif #else //BASH_SERIAL // Routines for bit-bashed serial output @@ -1149,4 +889,3 @@ ISR(TIMER0_OVF_vect) #endif // BASH_SERIAL #endif // TELEMETRY ->>>>>>> refs/remotes/pascallanger/master diff --git a/Multiprotocol/V2X2_nrf24l01.ino b/Multiprotocol/V2X2_nrf24l01.ino index 8f88c21..999410f 100644 --- a/Multiprotocol/V2X2_nrf24l01.ino +++ b/Multiprotocol/V2X2_nrf24l01.ino @@ -15,6 +15,8 @@ // compatible with WLToys V2x2, JXD JD38x, JD39x, JJRC H6C, Yizhan Tarantula X6 ... // Last sync with hexfet new_protocols/v202_nrf24l01.c dated 2015-03-15 +// ajout jdx506 : https://github.com/DeviationTX/deviation/compare/master...goebish:protocol_jxd_506 + #if defined(V2X2_NRF24L01_INO) @@ -40,7 +42,12 @@ enum { // flags going to byte 10 V2X2_FLAG_HEADLESS = 0x02, V2X2_FLAG_MAG_CAL_X = 0x08, - V2X2_FLAG_MAG_CAL_Y = 0x20 + V2X2_FLAG_MAG_CAL_Y = 0x20, + // + JXD_FLAG_START_STOP= 0x40, // arm / disarm JXD-506 + JXD_FLAG_EMERGENCY = 0x80, // JXD-506 + JXD_FLAG_CAMERA_UP = 0x01, // JXD-506 + JXD_FLAG_CAMERA_DN = 0x02, // JXD-506 }; // @@ -182,12 +189,26 @@ static void __attribute__((unused)) V2X2_send_packet(uint8_t bind) // Channel 9 if (Servo_AUX5) flags2 = V2X2_FLAG_HEADLESS; - // Channel 10 - if (Servo_AUX6) - flags2 |= V2X2_FLAG_MAG_CAL_X; - // Channel 11 - if (Servo_AUX7) - flags2 |= V2X2_FLAG_MAG_CAL_Y; + + if(sub_protocol == FORMAT_JXD506) { + // Channel 10 + if (Servo_AUX6) flags2 |= JXD_FLAG_START_STOP; + // Channel 11 + if (Servo_AUX7) flags2 |= JXD_FLAG_EMERGENCY; + + // Channel 12 down + if (Servo_data[AUX8] < PPM_SWITCH_B) flags2 |= JXD_FLAG_CAMERA_DN; + // Channel 12 up + if (Servo_data[AUX8] > PPM_SWITCH) flags2 |= JXD_FLAG_CAMERA_UP; + + } else { + // Channel 10 + if (Servo_AUX6) + flags2 |= V2X2_FLAG_MAG_CAL_X; + // Channel 11 + if (Servo_AUX7) + flags2 |= V2X2_FLAG_MAG_CAL_Y; + } } // TX id packet[7] = rx_tx_addr[1]; diff --git a/Multiprotocol/Validate.h b/Multiprotocol/Validate.h new file mode 100644 index 0000000..277d5b1 --- /dev/null +++ b/Multiprotocol/Validate.h @@ -0,0 +1,101 @@ +// Check selected board type +#if defined (STM32_BOARD) && defined (ORANGE_TX) + #error You must comment the board type STM32_BOARD in _Config.h to compile ORANGE_TX +#endif +#if not defined (ORANGE_TX) && not defined (STM32_BOARD) + //Atmega328p + #if not defined(ARDUINO_AVR_PRO) && not defined(ARDUINO_AVR_MINI) && not defined(ARDUINO_AVR_NANO) + #error You must select one of these boards: "Multi 4-in-1", "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)" + #endif +#endif +#if defined (STM32_BOARD) && not defined (ORANGE_TX) + //STM32 + #ifndef ARDUINO_GENERIC_STM32F103C + #error You must select the board type "Generic STM32F103C series" + #endif +#endif + +//Change/Force configuration if OrangeTX +#ifdef ORANGE_TX + #undef ENABLE_PPM // Disable PPM for OrangeTX module + #undef A7105_INSTALLED // Disable A7105 for OrangeTX module + #undef CC2500_INSTALLED // Disable CC2500 for OrangeTX module + #undef NRF24L01_INSTALLED // Disable NRF for OrangeTX module + #define TELEMETRY // Enable telemetry + #define INVERT_TELEMETRY // Enable invert telemetry + #define DSM_TELEMETRY // Enable DSM telemetry +#endif + +//Make sure protocols are selected correctly +#ifndef A7105_INSTALLED + #undef FLYSKY_A7105_INO + #undef HUBSAN_A7105_INO + #undef AFHDS2A_A7105_INO +#endif +#ifndef CYRF6936_INSTALLED + #undef DEVO_CYRF6936_INO + #undef DSM_CYRF6936_INO + #undef J6PRO_CYRF6936_INO +#endif +#ifndef CC2500_INSTALLED + #undef FRSKYD_CC2500_INO + #undef FRSKYV_CC2500_INO + #undef FRSKYX_CC2500_INO + #undef SFHSS_CC2500_INO +#endif +#ifndef NRF24L01_INSTALLED + #undef BAYANG_NRF24L01_INO + #undef CG023_NRF24L01_INO + #undef CX10_NRF24L01_INO + #undef ESKY_NRF24L01_INO + #undef HISKY_NRF24L01_INO + #undef KN_NRF24L01_INO + #undef SLT_NRF24L01_INO + #undef SYMAX_NRF24L01_INO + #undef V2X2_NRF24L01_INO + #undef YD717_NRF24L01_INO + #undef MT99XX_NRF24L01_INO + #undef MJXQ_NRF24L01_INO + #undef SHENQI_NRF24L01_INO + #undef FY326_NRF24L01_INO + #undef FQ777_NRF24L01_INO + #undef ASSAN_NRF24L01_INO + #undef HONTAI_NRF24L01_INO +#endif + +//Make sure telemetry is selected correctly +#ifndef TELEMETRY + #undef INVERT_TELEMETRY + #undef DSM_TELEMETRY + #undef SPORT_TELEMETRY + #undef HUB_TELEMETRY + #undef AFHDS2A_TELEMETRY +#else + #if not defined(DSM_CYRF6936_INO) + #undef DSM_TELEMETRY + #endif + #if not defined(FRSKYD_CC2500_INO) && not defined(HUBSAN_A7105_INO) && not defined(AFHDS2A_A7105_INO) + #undef HUB_TELEMETRY + #endif + #if not defined(FRSKYX_CC2500_INO) + #undef SPORT_TELEMETRY + #endif + #if not defined(AFHDS2A_A7105_INO) + #undef AFHDS2A_TELEMETRY + #endif + #if not defined(DSM_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(SPORT_TELEMETRY) && not defined(AFHDS2A_TELEMETRY) + #undef TELEMETRY + #undef INVERT_TELEMETRY + #endif +#endif + +//Make sure TX is defined correctly +#ifndef AILERON + #error You must select a correct channel order. +#endif +#if not defined(PPM_MAX_100) || not defined(PPM_MIN_100) || not defined(PPM_MAX_125) || not defined(PPM_MIN_125) + #error You must set correct TX end points. +#endif diff --git a/Multiprotocol/WMath.cpp.xmega b/Multiprotocol/WMath.cpp.orangetx similarity index 100% rename from Multiprotocol/WMath.cpp.xmega rename to Multiprotocol/WMath.cpp.orangetx 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..50d574f 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -13,98 +13,32 @@ 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 ***/ /**********************************************/ +/********************/ +/*** BOARD TYPE ***/ +/********************/ +//Uncomment one of the line below if you have a different module not based on the original Multi Atmega328p design which includes the 4-in-1. +//If you don't know then leave them commented. +#ifdef __arm__ + #define STM32_BOARD // Let's automatically select this board if arm is selected since this is the only one for now... +#endif + /*******************/ /*** TX SETTINGS ***/ /*******************/ //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 +//Modify the channel for a software reset modul: AUX...(channel number - 4) +//Default is AUX10 (channel 14). +#define SWITCH_RESET 14 + /**************************/ /*** RF CHIPS INSTALLED ***/ /**************************/ @@ -112,53 +46,70 @@ 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 /****************************/ /*** PROTOCOLS TO INCLUDE ***/ /****************************/ //In this section select the protocols you want to be accessible when using the module. -//All the protocols will not fit in the module so you need to pick and choose. +//All the protocols will not fit in the Atmega328p module so you need to pick and choose. //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 JOYSWAY_A7105_INO + #define FLYSKY_A7105_INO + #define HUBSAN_A7105_INO + #define AFHDS2A_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 // a faire + #define Q303_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,10 +124,10 @@ 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 + #define AFHDS2A_TELEMETRY /****************************/ /*** SERIAL MODE SETTINGS ***/ @@ -200,17 +151,18 @@ 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_DEVO7 //DEVO (1120<->1920µs) -//#define TX_SPEKTRUM //Spektrum (1100<->1900µs) -//#define TX_HISKY //HISKY (1100<->1900µs) -//#define TX_MPX //Multiplex MC2020 (1250<->1950µs) -//#define TX_CUSTOM //Custom +//#define TX_ER9X //ER9X/ERSKY9X/OpenTX ( 988<->2012µs) +#define TX_TARANIS //TARANIS AETR (1100<->1900µs) +//#define TX_DEVO7 //DEVO (1120<->1920µs) +//#define TX_SPEKTRUM //Spektrum (1100<->1900µs) +//#define TX_HISKY //HISKY (1100<->1900µs) +//#define TX_MPX //Multiplex MC2020 (1250<->1950µs) +//#define TX_CUSTOM //Custom // The lines below are used to set the end points in microseconds (µs) if you have selected TX_CUSTOM. -// A few things to considered: +// A few things to consider: // - If you put too big values compared to your TX you won't be able to reach the extremes which is bad for throttle as an example -// - If you put too low values you won't be able to use your full stick range, it will be maxed out before reaching the end +// - If you put too low values you won't be able to use your full stick range, it will be maxed out before reaching the ends // - Centered stick value is usually 1500. It should match the middle between MIN and MAX, ie Center=(MAX-MIN)/2+MIN. If your TX is not centered you can adjust the value MIN or MAX. // - 100% is the value when the model is by default, 125% is the value when you extend the servo travel which is only used by some protocols #if defined(TX_CUSTOM) @@ -225,7 +177,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 +186,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 +193,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 +201,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 +245,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 +279,9 @@ enum chan_orders{ FORMAT_HONTAI FORMAT_JJRCX1 FORMAT_X5C1 + FQ777-951 + MODE_AFHDS2A + NONE */ // 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... @@ -468,8 +292,7 @@ enum chan_orders{ // Auto Bind AUTOBIND or NO_AUTOBIND // For protocols which does not require binding at each power up (like Flysky, FrSky...), you might still want a bind to be initiated each time you power up the TX. -// 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. +// As an example, 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/boards.txt b/Multiprotocol/boards.txt new file mode 100644 index 0000000..70dc5a6 --- /dev/null +++ b/Multiprotocol/boards.txt @@ -0,0 +1,890 @@ +# See: http://code.google.com/p/arduino/wiki/Platforms + +menu.cpu=Processor + +############################################################## + +yun.name=Arduino Yún +yun.upload.via_ssh=true + +yun.vid.0=0x2341 +yun.pid.0=0x0041 +yun.vid.1=0x2341 +yun.pid.1=0x8041 +yun.vid.2=0x2A03 +yun.pid.2=0x0041 +yun.vid.3=0x2A03 +yun.pid.3=0x8041 + +yun.upload.tool=avrdude +yun.upload.protocol=avr109 +yun.upload.maximum_size=28672 +yun.upload.maximum_data_size=2560 +yun.upload.speed=57600 +yun.upload.disable_flushing=true +yun.upload.use_1200bps_touch=true +yun.upload.wait_for_upload_port=true + +yun.bootloader.tool=avrdude +yun.bootloader.low_fuses=0xff +yun.bootloader.high_fuses=0xd8 +yun.bootloader.extended_fuses=0xfb +yun.bootloader.file=caterina/Caterina-Yun.hex +yun.bootloader.unlock_bits=0x3F +yun.bootloader.lock_bits=0x2F + +yun.build.mcu=atmega32u4 +yun.build.f_cpu=16000000L +yun.build.vid=0x2341 +yun.build.pid=0x8041 +yun.build.usb_product="Arduino Yun" +yun.build.board=AVR_YUN +yun.build.core=arduino +yun.build.variant=yun +yun.build.extra_flags={build.usb_flags} + +############################################################## + +uno.name=Arduino/Genuino Uno + +uno.vid.0=0x2341 +uno.pid.0=0x0043 +uno.vid.1=0x2341 +uno.pid.1=0x0001 +uno.vid.2=0x2A03 +uno.pid.2=0x0043 +uno.vid.3=0x2341 +uno.pid.3=0x0243 + +uno.upload.tool=avrdude +uno.upload.protocol=arduino +uno.upload.maximum_size=32256 +uno.upload.maximum_data_size=2048 +uno.upload.speed=115200 + +uno.bootloader.tool=avrdude +uno.bootloader.low_fuses=0xFF +uno.bootloader.high_fuses=0xDE +uno.bootloader.extended_fuses=0x05 +uno.bootloader.unlock_bits=0x3F +uno.bootloader.lock_bits=0x0F +uno.bootloader.file=optiboot/optiboot_atmega328.hex + +uno.build.mcu=atmega328p +uno.build.f_cpu=16000000L +uno.build.board=AVR_UNO +uno.build.core=arduino +uno.build.variant=standard + +############################################################## + +diecimila.name=Arduino Duemilanove or Diecimila + +diecimila.upload.tool=avrdude +diecimila.upload.protocol=arduino + +diecimila.bootloader.tool=avrdude +diecimila.bootloader.low_fuses=0xFF +diecimila.bootloader.unlock_bits=0x3F +diecimila.bootloader.lock_bits=0x0F + +diecimila.build.f_cpu=16000000L +diecimila.build.board=AVR_DUEMILANOVE +diecimila.build.core=arduino +diecimila.build.variant=standard + +## Arduino Duemilanove or Diecimila w/ ATmega328 +## --------------------------------------------- +diecimila.menu.cpu.atmega328=ATmega328 + +diecimila.menu.cpu.atmega328.upload.maximum_size=30720 +diecimila.menu.cpu.atmega328.upload.maximum_data_size=2048 +diecimila.menu.cpu.atmega328.upload.speed=57600 + +diecimila.menu.cpu.atmega328.bootloader.high_fuses=0xDA +diecimila.menu.cpu.atmega328.bootloader.extended_fuses=0x05 +diecimila.menu.cpu.atmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex + +diecimila.menu.cpu.atmega328.build.mcu=atmega328p + +## Arduino Duemilanove or Diecimila w/ ATmega168 +## --------------------------------------------- +diecimila.menu.cpu.atmega168=ATmega168 + +diecimila.menu.cpu.atmega168.upload.maximum_size=14336 +diecimila.menu.cpu.atmega168.upload.maximum_data_size=1024 +diecimila.menu.cpu.atmega168.upload.speed=19200 + +diecimila.menu.cpu.atmega168.bootloader.high_fuses=0xdd +diecimila.menu.cpu.atmega168.bootloader.extended_fuses=0x00 +diecimila.menu.cpu.atmega168.bootloader.file=atmega/ATmegaBOOT_168_diecimila.hex + +diecimila.menu.cpu.atmega168.build.mcu=atmega168 + +############################################################## + +nano.name=Arduino Nano + +nano.upload.tool=avrdude +nano.upload.protocol=arduino + +nano.bootloader.tool=avrdude +nano.bootloader.unlock_bits=0x3F +nano.bootloader.lock_bits=0x0F + +nano.build.f_cpu=16000000L +nano.build.board=AVR_NANO +nano.build.core=arduino +nano.build.variant=eightanaloginputs + +## Arduino Nano w/ ATmega328 +## ------------------------- +nano.menu.cpu.atmega328=ATmega328 + +nano.menu.cpu.atmega328.upload.maximum_size=30720 +nano.menu.cpu.atmega328.upload.maximum_data_size=2048 +nano.menu.cpu.atmega328.upload.speed=57600 + +nano.menu.cpu.atmega328.bootloader.low_fuses=0xFF +nano.menu.cpu.atmega328.bootloader.high_fuses=0xDA +nano.menu.cpu.atmega328.bootloader.extended_fuses=0x05 +nano.menu.cpu.atmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex + +nano.menu.cpu.atmega328.build.mcu=atmega328p + +## Arduino Nano w/ ATmega168 +## ------------------------- +nano.menu.cpu.atmega168=ATmega168 + +nano.menu.cpu.atmega168.upload.maximum_size=14336 +nano.menu.cpu.atmega168.upload.maximum_data_size=1024 +nano.menu.cpu.atmega168.upload.speed=19200 + +nano.menu.cpu.atmega168.bootloader.low_fuses=0xff +nano.menu.cpu.atmega168.bootloader.high_fuses=0xdd +nano.menu.cpu.atmega168.bootloader.extended_fuses=0x00 +nano.menu.cpu.atmega168.bootloader.file=atmega/ATmegaBOOT_168_diecimila.hex + +nano.menu.cpu.atmega168.build.mcu=atmega168 + +############################################################## + +mega.name=Arduino/Genuino Mega or Mega 2560 + +mega.vid.0=0x2341 +mega.pid.0=0x0010 +mega.vid.1=0x2341 +mega.pid.1=0x0042 +mega.vid.2=0x2A03 +mega.pid.2=0x0010 +mega.vid.3=0x2A03 +mega.pid.3=0x0042 +mega.vid.4=0x2341 +mega.pid.4=0x0210 +mega.vid.5=0x2341 +mega.pid.5=0x0242 + +mega.upload.tool=avrdude +mega.upload.maximum_data_size=8192 + +mega.bootloader.tool=avrdude +mega.bootloader.low_fuses=0xFF +mega.bootloader.unlock_bits=0x3F +mega.bootloader.lock_bits=0x0F + +mega.build.f_cpu=16000000L +mega.build.core=arduino +mega.build.variant=mega +# default board may be overridden by the cpu menu +mega.build.board=AVR_MEGA2560 + +## Arduino/Genuino Mega w/ ATmega2560 +## ------------------------- +mega.menu.cpu.atmega2560=ATmega2560 (Mega 2560) + +mega.menu.cpu.atmega2560.upload.protocol=wiring +mega.menu.cpu.atmega2560.upload.maximum_size=253952 +mega.menu.cpu.atmega2560.upload.speed=115200 + +mega.menu.cpu.atmega2560.bootloader.high_fuses=0xD8 +mega.menu.cpu.atmega2560.bootloader.extended_fuses=0xFD +mega.menu.cpu.atmega2560.bootloader.file=stk500v2/stk500boot_v2_mega2560.hex + +mega.menu.cpu.atmega2560.build.mcu=atmega2560 +mega.menu.cpu.atmega2560.build.board=AVR_MEGA2560 + +## Arduino Mega w/ ATmega1280 +## ------------------------- +mega.menu.cpu.atmega1280=ATmega1280 + +mega.menu.cpu.atmega1280.upload.protocol=arduino +mega.menu.cpu.atmega1280.upload.maximum_size=126976 +mega.menu.cpu.atmega1280.upload.speed=57600 + +mega.menu.cpu.atmega1280.bootloader.high_fuses=0xDA +mega.menu.cpu.atmega1280.bootloader.extended_fuses=0xF5 +mega.menu.cpu.atmega1280.bootloader.file=atmega/ATmegaBOOT_168_atmega1280.hex + +mega.menu.cpu.atmega1280.build.mcu=atmega1280 +mega.menu.cpu.atmega1280.build.board=AVR_MEGA + +############################################################## + +megaADK.name=Arduino Mega ADK + +megaADK.vid.0=0x2341 +megaADK.pid.0=0x003f +megaADK.vid.1=0x2341 +megaADK.pid.1=0x0044 +megaADK.vid.2=0x2A03 +megaADK.pid.2=0x003f +megaADK.vid.3=0x2A03 +megaADK.pid.3=0x0044 + +megaADK.upload.tool=avrdude +megaADK.upload.protocol=wiring +megaADK.upload.maximum_size=253952 +megaADK.upload.maximum_data_size=8192 +megaADK.upload.speed=115200 + +megaADK.bootloader.tool=avrdude +megaADK.bootloader.low_fuses=0xFF +megaADK.bootloader.high_fuses=0xD8 +megaADK.bootloader.extended_fuses=0xFD +megaADK.bootloader.file=stk500v2/stk500boot_v2_mega2560.hex +megaADK.bootloader.unlock_bits=0x3F +megaADK.bootloader.lock_bits=0x0F + +megaADK.build.mcu=atmega2560 +megaADK.build.f_cpu=16000000L +megaADK.build.board=AVR_ADK +megaADK.build.core=arduino +megaADK.build.variant=mega + +############################################################## + +leonardo.name=Arduino Leonardo +leonardo.vid.0=0x2341 +leonardo.pid.0=0x0036 +leonardo.vid.1=0x2341 +leonardo.pid.1=0x8036 +leonardo.vid.2=0x2A03 +leonardo.pid.2=0x0036 +leonardo.vid.3=0x2A03 +leonardo.pid.3=0x8036 + +leonardo.upload.tool=avrdude +leonardo.upload.protocol=avr109 +leonardo.upload.maximum_size=28672 +leonardo.upload.maximum_data_size=2560 +leonardo.upload.speed=57600 +leonardo.upload.disable_flushing=true +leonardo.upload.use_1200bps_touch=true +leonardo.upload.wait_for_upload_port=true + +leonardo.bootloader.tool=avrdude +leonardo.bootloader.low_fuses=0xff +leonardo.bootloader.high_fuses=0xd8 +leonardo.bootloader.extended_fuses=0xcb +leonardo.bootloader.file=caterina/Caterina-Leonardo.hex +leonardo.bootloader.unlock_bits=0x3F +leonardo.bootloader.lock_bits=0x2F + +leonardo.build.mcu=atmega32u4 +leonardo.build.f_cpu=16000000L +leonardo.build.vid=0x2341 +leonardo.build.pid=0x8036 +leonardo.build.usb_product="Arduino Leonardo" +leonardo.build.board=AVR_LEONARDO +leonardo.build.core=arduino +leonardo.build.variant=leonardo +leonardo.build.extra_flags={build.usb_flags} + +############################################################## + +micro.name=Arduino/Genuino Micro + +micro.vid.0=0x2341 +micro.pid.0=0x0037 +micro.vid.1=0x2341 +micro.pid.1=0x8037 +micro.vid.2=0x2A03 +micro.pid.2=0x0037 +micro.vid.3=0x2A03 +micro.pid.3=0x8037 + +micro.vid.4=0x2341 +micro.pid.4=0x0237 +# If the board is a 2341:0237 use 2341:8237 for build and set +# other parameters as well +micro.vid.4.build.vid=0x2341 +micro.vid.4.build.pid=0x8237 +micro.vid.4.build.usb_product="Genuino Micro" +micro.vid.4.bootloader.file=caterina/Caterina-Genuino-Micro.hex + +micro.vid.5=0x2341 +micro.pid.5=0x8237 +# If the board is a 2341:8237 use 2341:8237 for build and set +# other paramters as well +micro.vid.5.build.vid=0x2341 +micro.vid.5.build.pid=0x8237 +micro.vid.5.build.usb_product="Genuino Micro" +micro.vid.5.bootloader.file=caterina/Caterina-Genuino-Micro.hex + +micro.upload.tool=avrdude +micro.upload.protocol=avr109 +micro.upload.maximum_size=28672 +micro.upload.maximum_data_size=2560 +micro.upload.speed=57600 +micro.upload.disable_flushing=true +micro.upload.use_1200bps_touch=true +micro.upload.wait_for_upload_port=true + +micro.bootloader.tool=avrdude +micro.bootloader.low_fuses=0xff +micro.bootloader.high_fuses=0xd8 +micro.bootloader.extended_fuses=0xcb +micro.bootloader.file=caterina/Caterina-Micro.hex +micro.bootloader.unlock_bits=0x3F +micro.bootloader.lock_bits=0x2F + +micro.build.mcu=atmega32u4 +micro.build.f_cpu=16000000L +micro.build.vid=0x2341 +micro.build.pid=0x8037 +micro.build.usb_product="Arduino Micro" +micro.build.board=AVR_MICRO +micro.build.core=arduino +micro.build.variant=micro +micro.build.extra_flags={build.usb_flags} + +############################################################## + +esplora.name=Arduino Esplora +esplora.vid.0=0x2341 +esplora.pid.0=0x003C +esplora.vid.1=0x2341 +esplora.pid.1=0x803C +esplora.vid.2=0x2A03 +esplora.pid.2=0x003C +esplora.vid.3=0x2A03 +esplora.pid.3=0x803C + +esplora.upload.tool=avrdude +esplora.upload.protocol=avr109 +esplora.upload.maximum_size=28672 +esplora.upload.maximum_data_size=2560 +esplora.upload.speed=57600 +esplora.upload.disable_flushing=true +esplora.upload.use_1200bps_touch=true +esplora.upload.wait_for_upload_port=true + +esplora.bootloader.tool=avrdude +esplora.bootloader.low_fuses=0xff +esplora.bootloader.high_fuses=0xd8 +esplora.bootloader.extended_fuses=0xcb +esplora.bootloader.file=caterina/Caterina-Esplora.hex +esplora.bootloader.unlock_bits=0x3F +esplora.bootloader.lock_bits=0x2F + +esplora.build.mcu=atmega32u4 +esplora.build.f_cpu=16000000L +esplora.build.vid=0x2341 +esplora.build.pid=0x803c +esplora.build.usb_product="Arduino Esplora" +esplora.build.board=AVR_ESPLORA +esplora.build.core=arduino +esplora.build.variant=leonardo +esplora.build.extra_flags={build.usb_flags} + +############################################################## + +mini.name=Arduino Mini + +mini.upload.tool=avrdude +mini.upload.protocol=arduino + +mini.bootloader.tool=avrdude +mini.bootloader.low_fuses=0xff +mini.bootloader.unlock_bits=0x3F +mini.bootloader.lock_bits=0x0F + +mini.build.f_cpu=16000000L +mini.build.board=AVR_MINI +mini.build.core=arduino +mini.build.variant=eightanaloginputs + +## Arduino Mini w/ ATmega328 +## ------------------------- +mini.menu.cpu.atmega328=ATmega328 + +mini.menu.cpu.atmega328.upload.maximum_size=28672 +mini.menu.cpu.atmega328.upload.maximum_data_size=2048 +mini.menu.cpu.atmega328.upload.speed=115200 + +mini.menu.cpu.atmega328.bootloader.high_fuses=0xd8 +mini.menu.cpu.atmega328.bootloader.extended_fuses=0x05 +mini.menu.cpu.atmega328.bootloader.file=optiboot/optiboot_atmega328-Mini.hex + +mini.menu.cpu.atmega328.build.mcu=atmega328p + +## Arduino Mini w/ ATmega168 +## ------------------------- +mini.menu.cpu.atmega168=ATmega168 + +mini.menu.cpu.atmega168.upload.maximum_size=14336 +mini.menu.cpu.atmega168.upload.maximum_data_size=1024 +mini.menu.cpu.atmega168.upload.speed=19200 + +mini.menu.cpu.atmega168.bootloader.high_fuses=0xdd +mini.menu.cpu.atmega168.bootloader.extended_fuses=0x00 +mini.menu.cpu.atmega168.bootloader.file=atmega/ATmegaBOOT_168_ng.hex + +mini.menu.cpu.atmega168.build.mcu=atmega168 + +############################################################## + +ethernet.name=Arduino Ethernet + +ethernet.upload.tool=avrdude +ethernet.upload.protocol=arduino +ethernet.upload.maximum_size=32256 +ethernet.upload.maximum_data_size=2048 +ethernet.upload.speed=115200 + +ethernet.bootloader.tool=avrdude +ethernet.bootloader.low_fuses=0xff +ethernet.bootloader.high_fuses=0xde +ethernet.bootloader.extended_fuses=0x05 +ethernet.bootloader.file=optiboot/optiboot_atmega328.hex +ethernet.bootloader.unlock_bits=0x3F +ethernet.bootloader.lock_bits=0x0F + +ethernet.build.variant=ethernet +ethernet.build.mcu=atmega328p +ethernet.build.f_cpu=16000000L +ethernet.build.board=AVR_ETHERNET +ethernet.build.core=arduino + +############################################################## + +fio.name=Arduino Fio + +fio.upload.tool=avrdude +fio.upload.protocol=arduino +fio.upload.maximum_size=30720 +fio.upload.maximum_data_size=2048 +fio.upload.speed=57600 + +fio.bootloader.tool=avrdude +fio.bootloader.low_fuses=0xFF +fio.bootloader.high_fuses=0xDA +fio.bootloader.extended_fuses=0x05 +fio.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex +fio.bootloader.unlock_bits=0x3F +fio.bootloader.lock_bits=0x0F + +fio.build.mcu=atmega328p +fio.build.f_cpu=8000000L +fio.build.board=AVR_FIO +fio.build.core=arduino +fio.build.variant=eightanaloginputs + +############################################################## + +bt.name=Arduino BT + +bt.upload.tool=avrdude +bt.upload.protocol=arduino +bt.upload.speed=19200 +bt.upload.disable_flushing=true + +bt.bootloader.tool=avrdude +bt.bootloader.low_fuses=0xff +bt.bootloader.unlock_bits=0x3F +bt.bootloader.lock_bits=0x0F + +bt.build.f_cpu=16000000L +bt.build.board=AVR_BT +bt.build.core=arduino +bt.build.variant=eightanaloginputs + +## Arduino BT w/ ATmega328 +## ----------------------- +bt.menu.cpu.atmega328=ATmega328 +bt.menu.cpu.atmega328.upload.maximum_size=28672 +bt.menu.cpu.atmega328.upload.maximum_data_size=2048 + +bt.menu.cpu.atmega328.bootloader.high_fuses=0xd8 +bt.menu.cpu.atmega328.bootloader.extended_fuses=0x05 +bt.menu.cpu.atmega328.bootloader.file=bt/ATmegaBOOT_168_atmega328_bt.hex + +bt.menu.cpu.atmega328.build.mcu=atmega328p + +## Arduino BT w/ ATmega168 +## ----------------------- +bt.menu.cpu.atmega168=ATmega168 +bt.menu.cpu.atmega168.upload.maximum_size=14336 +bt.menu.cpu.atmega168.upload.maximum_data_size=1024 + +bt.menu.cpu.atmega168.bootloader.high_fuses=0xdd +bt.menu.cpu.atmega168.bootloader.extended_fuses=0x00 +bt.menu.cpu.atmega168.bootloader.file=bt/ATmegaBOOT_168.hex + +bt.menu.cpu.atmega168.build.mcu=atmega168 + +############################################################## + +LilyPadUSB.name=LilyPad Arduino USB +LilyPadUSB.vid.0=0x1B4F +LilyPadUSB.pid.0=0x9207 +LilyPadUSB.vid.1=0x1B4F +LilyPadUSB.pid.1=0x9208 + +LilyPadUSB.upload.tool=avrdude +LilyPadUSB.upload.protocol=avr109 +LilyPadUSB.upload.maximum_size=28672 +LilyPadUSB.upload.maximum_data_size=2560 +LilyPadUSB.upload.speed=57600 +LilyPadUSB.upload.disable_flushing=true +LilyPadUSB.upload.use_1200bps_touch=true +LilyPadUSB.upload.wait_for_upload_port=true + +LilyPadUSB.bootloader.tool=avrdude +LilyPadUSB.bootloader.low_fuses=0xff +LilyPadUSB.bootloader.high_fuses=0xd8 +LilyPadUSB.bootloader.extended_fuses=0xce +LilyPadUSB.bootloader.file=caterina-LilyPadUSB/Caterina-LilyPadUSB.hex +LilyPadUSB.bootloader.unlock_bits=0x3F +LilyPadUSB.bootloader.lock_bits=0x2F + +LilyPadUSB.build.mcu=atmega32u4 +LilyPadUSB.build.f_cpu=8000000L +LilyPadUSB.build.vid=0x1B4F +LilyPadUSB.build.pid=0x9208 +LilyPadUSB.build.usb_product="LilyPad USB" +LilyPadUSB.build.board=AVR_LILYPAD_USB +LilyPadUSB.build.core=arduino +LilyPadUSB.build.variant=leonardo +LilyPadUSB.build.extra_flags={build.usb_flags} + +############################################################## + +lilypad.name=LilyPad Arduino + +lilypad.upload.tool=avrdude +lilypad.upload.protocol=arduino + +lilypad.bootloader.tool=avrdude +lilypad.bootloader.unlock_bits=0x3F +lilypad.bootloader.lock_bits=0x0F + +lilypad.build.f_cpu=8000000L +lilypad.build.board=AVR_LILYPAD +lilypad.build.core=arduino +lilypad.build.variant=standard + +## LilyPad Arduino w/ ATmega328 +## ---------------------------- +lilypad.menu.cpu.atmega328=ATmega328 + +lilypad.menu.cpu.atmega328.upload.maximum_size=30720 +lilypad.menu.cpu.atmega328.upload.maximum_data_size=2048 +lilypad.menu.cpu.atmega328.upload.speed=57600 + +lilypad.menu.cpu.atmega328.bootloader.low_fuses=0xFF +lilypad.menu.cpu.atmega328.bootloader.high_fuses=0xDA +lilypad.menu.cpu.atmega328.bootloader.extended_fuses=0x05 +lilypad.menu.cpu.atmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex + +lilypad.menu.cpu.atmega328.build.mcu=atmega328p + +## LilyPad Arduino w/ ATmega168 +## ---------------------------- +lilypad.menu.cpu.atmega168=ATmega168 + +lilypad.menu.cpu.atmega168.upload.maximum_size=14336 +lilypad.menu.cpu.atmega168.upload.maximum_data_size=1024 +lilypad.menu.cpu.atmega168.upload.speed=19200 + +lilypad.menu.cpu.atmega168.bootloader.low_fuses=0xe2 +lilypad.menu.cpu.atmega168.bootloader.high_fuses=0xdd +lilypad.menu.cpu.atmega168.bootloader.extended_fuses=0x00 +lilypad.menu.cpu.atmega168.bootloader.file=lilypad/LilyPadBOOT_168.hex + +lilypad.menu.cpu.atmega168.build.mcu=atmega168 + +############################################################## + +pro.name=Arduino Pro or Pro Mini + +pro.upload.tool=avrdude +pro.upload.protocol=arduino + +pro.bootloader.tool=avrdude +pro.bootloader.unlock_bits=0x3F +pro.bootloader.lock_bits=0x0F + +pro.build.board=AVR_PRO +pro.build.core=arduino +pro.build.variant=eightanaloginputs + +## Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega328 +## ------------------------------------------------- +pro.menu.cpu.16MHzatmega328=ATmega328 (5V, 16 MHz) + +pro.menu.cpu.16MHzatmega328.upload.maximum_size=30720 +pro.menu.cpu.16MHzatmega328.upload.maximum_data_size=2048 +pro.menu.cpu.16MHzatmega328.upload.speed=57600 + +pro.menu.cpu.16MHzatmega328.bootloader.low_fuses=0xFF +pro.menu.cpu.16MHzatmega328.bootloader.high_fuses=0xDA +pro.menu.cpu.16MHzatmega328.bootloader.extended_fuses=0x05 +pro.menu.cpu.16MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex + +pro.menu.cpu.16MHzatmega328.build.mcu=atmega328p +pro.menu.cpu.16MHzatmega328.build.f_cpu=16000000L + +## Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328 +## -------------------------------------------------- +pro.menu.cpu.8MHzatmega328=ATmega328 (3.3V, 8 MHz) + +pro.menu.cpu.8MHzatmega328.upload.maximum_size=30720 +pro.menu.cpu.8MHzatmega328.upload.maximum_data_size=2048 +pro.menu.cpu.8MHzatmega328.upload.speed=57600 + +pro.menu.cpu.8MHzatmega328.bootloader.low_fuses=0xFF +pro.menu.cpu.8MHzatmega328.bootloader.high_fuses=0xDA +pro.menu.cpu.8MHzatmega328.bootloader.extended_fuses=0x05 +pro.menu.cpu.8MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex + +pro.menu.cpu.8MHzatmega328.build.mcu=atmega328p +pro.menu.cpu.8MHzatmega328.build.f_cpu=8000000L + +## Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega168 +## ------------------------------------------------- +pro.menu.cpu.16MHzatmega168=ATmega168 (5V, 16 MHz) + +pro.menu.cpu.16MHzatmega168.upload.maximum_size=14336 +pro.menu.cpu.16MHzatmega168.upload.maximum_data_size=1024 +pro.menu.cpu.16MHzatmega168.upload.speed=19200 + +pro.menu.cpu.16MHzatmega168.bootloader.low_fuses=0xff +pro.menu.cpu.16MHzatmega168.bootloader.high_fuses=0xdd +pro.menu.cpu.16MHzatmega168.bootloader.extended_fuses=0x00 +pro.menu.cpu.16MHzatmega168.bootloader.file=atmega/ATmegaBOOT_168_diecimila.hex + +pro.menu.cpu.16MHzatmega168.build.mcu=atmega168 +pro.menu.cpu.16MHzatmega168.build.f_cpu=16000000L + +## Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega168 +## -------------------------------------------------- +pro.menu.cpu.8MHzatmega168=ATmega168 (3.3V, 8 MHz) + +pro.menu.cpu.8MHzatmega168.upload.maximum_size=14336 +pro.menu.cpu.8MHzatmega168.upload.maximum_data_size=1024 +pro.menu.cpu.8MHzatmega168.upload.speed=19200 + +pro.menu.cpu.8MHzatmega168.bootloader.low_fuses=0xc6 +pro.menu.cpu.8MHzatmega168.bootloader.high_fuses=0xdd +pro.menu.cpu.8MHzatmega168.bootloader.extended_fuses=0x00 +pro.menu.cpu.8MHzatmega168.bootloader.file=atmega/ATmegaBOOT_168_pro_8MHz.hex + +pro.menu.cpu.8MHzatmega168.build.mcu=atmega168 +pro.menu.cpu.8MHzatmega168.build.f_cpu=8000000L + +############################################################## + +atmegang.name=Arduino NG or older + +atmegang.upload.tool=avrdude +atmegang.upload.protocol=arduino +atmegang.upload.speed=19200 + +atmegang.bootloader.tool=avrdude +atmegang.bootloader.unlock_bits=0x3F +atmegang.bootloader.lock_bits=0x0F + +atmegang.build.mcu=atmegang +atmegang.build.f_cpu=16000000L +atmegang.build.board=AVR_NG +atmegang.build.core=arduino +atmegang.build.variant=standard + +## Arduino NG or older w/ ATmega168 +## -------------------------------- +atmegang.menu.cpu.atmega168=ATmega168 + +atmegang.menu.cpu.atmega168.upload.maximum_size=14336 +atmegang.menu.cpu.atmega168.upload.maximum_data_size=1024 + +atmegang.menu.cpu.atmega168.bootloader.low_fuses=0xff +atmegang.menu.cpu.atmega168.bootloader.high_fuses=0xdd +atmegang.menu.cpu.atmega168.bootloader.extended_fuses=0x00 +atmegang.menu.cpu.atmega168.bootloader.file=atmega/ATmegaBOOT_168_ng.hex + +atmegang.menu.cpu.atmega168.build.mcu=atmega168 + +## Arduino NG or older w/ ATmega8 +## ------------------------------ +atmegang.menu.cpu.atmega8=ATmega8 + +atmegang.menu.cpu.atmega8.upload.maximum_size=7168 +atmegang.menu.cpu.atmega8.upload.maximum_data_size=1024 + +atmegang.menu.cpu.atmega8.bootloader.low_fuses=0xdf +atmegang.menu.cpu.atmega8.bootloader.high_fuses=0xca +atmegang.menu.cpu.atmega8.bootloader.file=atmega8/ATmegaBOOT-prod-firmware-2009-11-07.hex + +atmegang.menu.cpu.atmega8.build.mcu=atmega8 + +############################################################## + +robotControl.name=Arduino Robot Control +robotControl.vid.0=0x2341 +robotControl.pid.0=0x0038 +robotControl.vid.1=0x2341 +robotControl.pid.1=0x8038 +robotControl.vid.2=0x2A03 +robotControl.pid.2=0x0038 +robotControl.vid.3=0x2A03 +robotControl.pid.3=0x8038 + +robotControl.upload.tool=avrdude +robotControl.upload.protocol=avr109 +robotControl.upload.maximum_size=28672 +robotControl.upload.maximum_data_size=2560 +robotControl.upload.speed=57600 +robotControl.upload.disable_flushing=true +robotControl.upload.use_1200bps_touch=true +robotControl.upload.wait_for_upload_port=true + +robotControl.bootloader.tool=avrdude +robotControl.bootloader.low_fuses=0xff +robotControl.bootloader.high_fuses=0xd8 +robotControl.bootloader.extended_fuses=0xcb +robotControl.bootloader.file=caterina-Arduino_Robot/Caterina-Robot-Control.hex +robotControl.bootloader.unlock_bits=0x3F +robotControl.bootloader.lock_bits=0x2F + +robotControl.build.mcu=atmega32u4 +robotControl.build.f_cpu=16000000L +robotControl.build.vid=0x2341 +robotControl.build.pid=0x8038 +robotControl.build.usb_product="Robot Control" +robotControl.build.board=AVR_ROBOT_CONTROL +robotControl.build.core=arduino +robotControl.build.variant=robot_control +robotControl.build.extra_flags={build.usb_flags} + +############################################################## + +robotMotor.name=Arduino Robot Motor +robotMotor.vid.0=0x2341 +robotMotor.pid.0=0x0039 +robotMotor.vid.1=0x2341 +robotMotor.pid.1=0x8039 +robotMotor.vid.2=0x2A03 +robotMotor.pid.2=0x0039 +robotMotor.vid.3=0x2A03 +robotMotor.pid.3=0x8039 + +robotMotor.upload.tool=avrdude +robotMotor.upload.protocol=avr109 +robotMotor.upload.maximum_size=28672 +robotMotor.upload.maximum_data_size=2560 +robotMotor.upload.speed=57600 +robotMotor.upload.disable_flushing=true +robotMotor.upload.use_1200bps_touch=true +robotMotor.upload.wait_for_upload_port=true + +robotMotor.bootloader.tool=avrdude +robotMotor.bootloader.low_fuses=0xff +robotMotor.bootloader.high_fuses=0xd8 +robotMotor.bootloader.extended_fuses=0xcb +robotMotor.bootloader.file=caterina-Arduino_Robot/Caterina-Robot-Motor.hex +robotMotor.bootloader.unlock_bits=0x3F +robotMotor.bootloader.lock_bits=0x2F + +robotMotor.build.mcu=atmega32u4 +robotMotor.build.f_cpu=16000000L +robotMotor.build.vid=0x2341 +robotMotor.build.pid=0x8039 +robotMotor.build.usb_product="Robot Motor" +robotMotor.build.board=AVR_ROBOT_MOTOR +robotMotor.build.core=arduino +robotMotor.build.variant=robot_motor +robotMotor.build.extra_flags={build.usb_flags} + +############################################################## + +gemma.vid.0=0x2341 +gemma.pid.0=0x0c9f + +gemma.name=Arduino Gemma + +gemma.bootloader.low_fuses=0xF1 +gemma.bootloader.high_fuses=0xD5 +gemma.bootloader.extended_fuses=0xFE +gemma.bootloader.tool=avrdude +gemma.bootloader.lock_bits= +gemma.bootloader.unlock_bits= +gemma.bootloader.file=gemma/gemma_v1.hex + +gemma.build.mcu=attiny85 +gemma.build.f_cpu=8000000L +gemma.build.core=arduino +gemma.build.variant=gemma +gemma.build.board=AVR_GEMMA + +gemma.upload.tool=avrdude +gemma.upload.maximum_size=5310 + +############################################################## + +## Multi 4-in-1 (3.3V, 16 MHz) w/ ATmega328 +## -------------------------------------------------- +multi.name=Multi 4-in-1 + +multi.upload.tool=avrdude +multi.upload.protocol=arduino + +multi.bootloader.tool=avrdude +multi.bootloader.unlock_bits=0x3F +multi.bootloader.lock_bits=0x0F + +multi.build.board=AVR_PRO +multi.build.core=arduino +multi.build.variant=eightanaloginputs + +multi.menu.cpu.16MHzatmega328=ATmega328 (3.3V, 16 MHz) + +multi.menu.cpu.16MHzatmega328.upload.maximum_size=32768 +multi.menu.cpu.16MHzatmega328.upload.maximum_data_size=2048 +multi.menu.cpu.16MHzatmega328.upload.speed=57600 +multi.menu.cpu.16MHzatmega328.upload.using=arduino:arduinoisp + +multi.menu.cpu.16MHzatmega328.bootloader.low_fuses=0xFF +multi.menu.cpu.16MHzatmega328.bootloader.high_fuses=0xD2 +multi.menu.cpu.16MHzatmega328.bootloader.extended_fuses=0xFD +multi.menu.cpu.16MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex + +multi.menu.cpu.16MHzatmega328.build.mcu=atmega328p +multi.menu.cpu.16MHzatmega328.build.f_cpu=16000000L +## -------------------------------------------------- +multi.menu.cpu.16MHzatmega328opti=ATmega328 Opti (3.3V, 16 MHz) + +multi.menu.cpu.16MHzatmega328opti.upload.maximum_size=32768 +multi.menu.cpu.16MHzatmega328opti.upload.maximum_data_size=2048 +multi.menu.cpu.16MHzatmega328opti.upload.speed=57600 +multi.menu.cpu.16MHzatmega328opti.upload.using=arduino:arduinoisp + +multi.menu.cpu.16MHzatmega328opti.bootloader.low_fuses=0xFF +multi.menu.cpu.16MHzatmega328opti.bootloader.high_fuses=0xD6 +multi.menu.cpu.16MHzatmega328opti.bootloader.extended_fuses=0xFD +multi.menu.cpu.16MHzatmega328opti.bootloader.file=atmega/optiboot_atmega328_16.hex + +multi.menu.cpu.16MHzatmega328opti.build.mcu=atmega328p +multi.menu.cpu.16MHzatmega328opti.build.f_cpu=16000000L + +############################################################## 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..f04121d 100644 --- a/Multiprotocol/iface_a7105.h +++ b/Multiprotocol/iface_a7105.h @@ -87,9 +87,4 @@ enum A7105_MASK { A7105_MASK_VBCF = 1 << 3, }; -enum { - INIT_FLYSKY, - INIT_HUBSAN -}; - #endif \ No newline at end of file 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..68caa59 100644 --- a/Multiprotocol/multiprotocol.h +++ b/Multiprotocol/multiprotocol.h @@ -13,21 +13,28 @@ along with Multiprotocol. If not, see . */ -// 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" - #endif - #if F_CPU != 16000000L || not defined(__AVR_ATmega328P__) - #error You must select the processor type "ATmega328(5V, 16MHz)" - #endif -#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_INAV = 57, // =>NRF24L01 + MODE_Q303 = 58, // =>NRF24L01 + MODE_SERIAL = 0, // Serial commands MODE_FLYSKY = 1, // =>A7105 MODE_HUBSAN = 2, // =>A7105 @@ -56,19 +63,26 @@ enum PROTOCOLS MODE_FRSKYV = 25, // =>CC2500 MODE_HONTAI = 26, // =>NRF24L01 MODE_OPENLRS = 27, // =>OpenLRS hardware + MODE_AFHDS2A = 28, // =>A7105 }; - enum Flysky { - Flysky = 0, - V9X9 = 1, - V6X6 = 2, - V912 = 3 + Flysky=0, + V9X9=1, + V6X6=2, + V912=3 +}; +enum AFHDS2A +{ + PWM_IBUS = 0, + PPM_IBUS = 1, + PWM_SBUS = 2, + PPM_SBUS = 3, }; enum Hisky { - Hisky = 0, - HK310 = 1 + Hisky=0, + HK310=1 }; enum DSM { @@ -80,38 +94,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 { @@ -126,7 +140,8 @@ enum MJXQ X600 = 1, X800 = 2, H26D = 3, - E010 = 4 + E010 = 4, + H26WH = 5 }; enum FRSKYX { @@ -135,9 +150,44 @@ 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 V2X2 { + FORMAT_V202 = 0, + FORMAT_JXD506 = 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 @@ -159,27 +209,6 @@ struct PPM_Parameters // Macros #define NOP() __asm__ __volatile__("nop") -//******************* -//*** Timer *** -//******************* -#ifdef XMEGA - #define TIFR1 TCC1.INTFLAGS - #define OCF1A_bm TC1_CCAIF_bm - #define OCR1A TCC1.CCA - #define TCNT1 TCC1.CNT - #define UDR0 USARTC0.DATA - #define OCF1B_bm TC1_CCBIF_bm - #define OCR1B TCC1.CCB - #define TIMSK1 TCC1.INTCTRLB - #define SET_TIMSK1_OCIE1B TIMSK1 = (TIMSK1 & 0xF3) | 0x04 - #define CLR_TIMSK1_OCIE1B TIMSK1 &= 0xF3 -#else - #define OCF1A_bm _BV(OCF1A) - #define OCF1B_bm _BV(OCF1B) - #define SET_TIMSK1_OCIE1B TIMSK1 |= _BV(OCIE1B) - #define CLR_TIMSK1_OCIE1B TIMSK1 &=~_BV(OCIE1B) -#endif - //*************** //*** Flags *** //*************** @@ -188,7 +217,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 +235,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 +257,27 @@ 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 ) +//Signal OK +#define INPUT_SIGNAL_off protocol_flags2 &= ~_BV(5) +#define INPUT_SIGNAL_on protocol_flags2 |= _BV(5) +#define IS_INPUT_SIGNAL_on ( ( protocol_flags2 & _BV(5) ) !=0 ) +#define IS_INPUT_SIGNAL_off ( ( protocol_flags2 & _BV(5) ) ==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_PPM_TIME 1000 #define BLINK_BAD_PROTO_TIME_LOW 1000 #define BLINK_BAD_PROTO_TIME_HIGH 50 @@ -409,6 +447,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- FrskyV 25 HONTAI 26 OpenLRS 27 + AFHDS2A 28 BindBit=> 0x80 1=Bind/0=No AutoBindBit=> 0x40 1=Yes /0=No RangeCheck=> 0x20 1=Yes /0=No @@ -416,30 +455,31 @@ 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 + DSM_AUTO 4 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,6 +504,9 @@ 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 @@ -471,7 +514,13 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- FORMAT_HONTAI 0 FORMAT_JJRCX1 1 FORMAT_X5C1 2 - Power value => 0x80 0=High/1=Low + FQ777-521 3 + sub_protocol==AFHDS2A + PWM_IBUS 0 + PPM_IBUS 1 + PWM_SBUS 2 + PPM_SBUS 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 +532,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..ef0ab5b Binary files /dev/null and b/Multiprotocol/sync.ffs_db differ