diff --git a/Multiprotocol/Bayang_Rx_nrf24l01.ino b/Multiprotocol/Bayang_Rx_nrf24l01.ino new file mode 100644 index 0000000..eb8ee01 --- /dev/null +++ b/Multiprotocol/Bayang_Rx_nrf24l01.ino @@ -0,0 +1,188 @@ +/* + 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(BAYANG_RX_NRF24L01_INO) + +#include "iface_nrf24l01.h" + +#define BAYANG_RX_PACKET_SIZE 15 +#define BAYANG_RX_RF_NUM_CHANNELS 4 +#define BAYANG_RX_RF_BIND_CHANNEL 0 +#define BAYANG_RX_ADDRESS_LENGTH 5 + +enum { + BAYANG_RX_BIND = 0, + BAYANG_RX_DATA +}; + +static void __attribute__((unused)) Bayang_Rx_init_nrf24l01() +{ + const uint8_t bind_address[BAYANG_RX_ADDRESS_LENGTH] = { 0,0,0,0,0 }; + NRF24L01_Initialize(); + XN297_SetTXAddr(bind_address, BAYANG_RX_ADDRESS_LENGTH); + XN297_SetRXAddr(bind_address, BAYANG_RX_ADDRESS_LENGTH); + 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_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only + NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, BAYANG_RX_PACKET_SIZE + 2); // 2 extra bytes for xn297 crc + NRF24L01_WriteReg(NRF24L01_05_RF_CH, BAYANG_RX_RF_BIND_CHANNEL); + NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps + NRF24L01_SetPower(); + NRF24L01_Activate(0x73); // Activate feature register + NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes + NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01); + NRF24L01_Activate(0x73); + NRF24L01_SetTxRxMode(TXRX_OFF); + NRF24L01_FlushRx(); + NRF24L01_SetTxRxMode(RX_EN); + XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); +} + +static uint8_t __attribute__((unused)) Bayang_Rx_check_validity() { + uint8_t sum = packet[0]; + for (uint8_t i = 1; i < BAYANG_RX_PACKET_SIZE - 1; i++) + sum += packet[i]; + return sum == packet[14]; +} + +static void __attribute__((unused)) Bayang_Rx_build_telemetry_packet() +{ + uint32_t bits = 0; + uint8_t bitsavailable = 0; + uint8_t idx = 0; + + packet_in[idx++] = RX_LQI; + packet_in[idx++] = 100; // no RSSI + packet_in[idx++] = 0; // start channel + packet_in[idx++] = 8; // number of channels in packet + + // convert & pack channels + for (uint8_t i = 0; i < packet_in[3]; i++) { + uint32_t val = 0; + if (i < 4) { + // AETR + val = (((packet[4 + i * 2] & ~0x7C) << 8) | packet[5 + i * 2]) << 1; + } + else if ((i == 4) && (packet[2] & 0x08) || // flip + (i == 5) && (packet[2] & 0x01) || // rth + (i == 6) && (packet[2] & 0x20) || // picture + (i == 7) && (packet[2] & 0x10)) { // video + // set channel to 100% if feature is enabled + val = 2047; + } + bits |= val << bitsavailable; + bitsavailable += 11; + while (bitsavailable >= 8) { + packet_in[idx++] = bits & 0xff; + bits >>= 8; + bitsavailable -= 8; + } + } +} + +uint16_t initBayang_Rx() +{ + uint8_t i; + Bayang_Rx_init_nrf24l01(); + hopping_frequency_no = 0; + rx_data_started = false; + + if (IS_BIND_IN_PROGRESS) { + phase = BAYANG_RX_BIND; + } + else { + uint16_t temp = BAYANG_RX_EEPROM_OFFSET; + for (i = 0; i < 5; i++) + rx_tx_addr[i] = eeprom_read_byte((EE_ADDR)temp++); + for (i = 0; i < BAYANG_RX_RF_NUM_CHANNELS; i++) + hopping_frequency[i] = eeprom_read_byte((EE_ADDR)temp++); + XN297_SetTXAddr(rx_tx_addr, BAYANG_RX_ADDRESS_LENGTH); + XN297_SetRXAddr(rx_tx_addr, BAYANG_RX_ADDRESS_LENGTH); + phase = BAYANG_RX_DATA; + } + return 1000; +} + +uint16_t Bayang_Rx_callback() +{ + uint8_t i; + static int8_t read_retry; + static uint16_t pps_counter; + static uint32_t pps_timer = 0; + + switch (phase) { + case BAYANG_RX_BIND: + if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) { + // data received from TX + if (XN297_ReadPayload(packet, BAYANG_RX_PACKET_SIZE) && packet[0] == 0xA4 && Bayang_Rx_check_validity()) { + // store tx info into eeprom + uint16_t temp = BAYANG_RX_EEPROM_OFFSET; + for (i = 0; i < 5; i++) { + rx_tx_addr[i] = packet[i + 1]; + eeprom_write_byte((EE_ADDR)temp++, rx_tx_addr[i]); + } + for (i = 0; i < 4; i++) { + hopping_frequency[i] = packet[i + 6]; + eeprom_write_byte((EE_ADDR)temp++, hopping_frequency[i]); + } + XN297_SetTXAddr(rx_tx_addr, BAYANG_RX_ADDRESS_LENGTH); + XN297_SetRXAddr(rx_tx_addr, BAYANG_RX_ADDRESS_LENGTH); + BIND_DONE; + phase = BAYANG_RX_DATA; + } + NRF24L01_FlushRx(); + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); + } + break; + case BAYANG_RX_DATA: + if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) { + if (XN297_ReadPayload(packet, BAYANG_RX_PACKET_SIZE) && packet[0] == 0xA5 && Bayang_Rx_check_validity()) { + if (telemetry_link == 0) { + Bayang_Rx_build_telemetry_packet(); + telemetry_link = 1; + } + rx_data_started = true; + read_retry = 4; + pps_counter++; + } + } + // packets per second + if (millis() - pps_timer >= 1000) { + pps_timer = millis(); + debugln("%d pps", pps_counter); + RX_LQI = pps_counter / 2; + pps_counter = 0; + } + + // frequency hopping + if (read_retry++ >= 4) { + hopping_frequency_no++; + if (hopping_frequency_no >= BAYANG_RX_RF_NUM_CHANNELS) + hopping_frequency_no = 0; + NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]); + NRF24L01_FlushRx(); + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); + if (rx_data_started) + read_retry = 0; + else + read_retry = -16; // retry longer until first packet is caught + } + return 250; + } + return 1000; +} + +#endif diff --git a/Multiprotocol/Multi_Names.ino b/Multiprotocol/Multi_Names.ino index c9ffe7a..802eea2 100644 --- a/Multiprotocol/Multi_Names.ino +++ b/Multiprotocol/Multi_Names.ino @@ -72,6 +72,7 @@ const char STR_FRSKY_RX[] ="FrSkyRX"; const char STR_AFHDS2A_RX[] ="FS2A_RX"; const char STR_HOTT[] ="HoTT"; const char STR_FX816[] ="FX816"; +const char STR_BAYANG_RX[] ="BayanRX"; const char STR_XN297DUMP[] ="XN297DP"; const char STR_SUBTYPE_FLYSKY[] = "\x04""Std\0""V9x9""V6x6""V912""CX20"; @@ -300,6 +301,9 @@ const mm_protocol_definition multi_protocols[] = { #if defined(FX816_NRF24L01_INO) {PROTO_FX816, STR_FX816, 1, STR_SUBTYPE_FX816, OPTION_NONE }, #endif +#if defined(BAYANG_RX_NRF24L01_INO) + {PROTO_BAYANG_RX, STR_BAYANG_RX, 0, NO_SUBTYPE, OPTION_NONE }, +#endif #if defined(XN297DUMP_NRF24L01_INO) {PROTO_XN297DUMP, STR_XN297DUMP, 3, STR_SUBTYPE_XN297DUMP, OPTION_RFCHAN }, #endif diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index d246b7a..5f80408 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -85,6 +85,7 @@ enum PROTOCOLS PROTO_AFHDS2A_RX= 56, // =>A7105 PROTO_HOTT = 57, // =>CC2500 PROTO_FX816 = 58, // =>NRF24L01 + PROTO_BAYANG_RX = 59, // =>NRF24L01 PROTO_XN297DUMP = 63, // =>NRF24L01 }; @@ -601,7 +602,8 @@ enum { #define AFHDS2A_RX_EEPROM_OFFSET 230 // (4) TX ID + (16) channels, 20 bytes, end is 230+20=250 #define AFHDS2A_EEPROM_OFFSET2 250 // RX ID, 4 bytes per model id, end is 250+192=442 #define HOTT_EEPROM_OFFSET 442 // RX ID, 5 bytes per model id, end is 320+442=762 -//#define CONFIG_EEPROM_OFFSET 762 // Current configuration of the multimodule +#define BAYANG_RX_EEPROM_OFFSET 762 // (5) TX ID + (4) channels, 9 bytes, end is 771 +//#define CONFIG_EEPROM_OFFSET 771 // Current configuration of the multimodule //**************************************** //*** MULTI protocol serial definition *** @@ -678,6 +680,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- AFHDS2A_RX 56 HOTT 57 FX816 58 + BAYANG_RX 59 BindBit=> 0x80 1=Bind/0=No AutoBindBit=> 0x40 1=Yes /0=No RangeCheck=> 0x20 1=Yes /0=No diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino index e9ba01c..5aacdce 100644 --- a/Multiprotocol/Multiprotocol.ino +++ b/Multiprotocol/Multiprotocol.ino @@ -227,7 +227,7 @@ uint8_t packet_in[TELEMETRY_BUFFER_SIZE];//telemetry receiving packets #endif //RX protocols - #if defined(AFHDS2A_RX_A7105_INO) || defined(FRSKY_RX_CC2500_INO) + #if defined(AFHDS2A_RX_A7105_INO) || defined(FRSKY_RX_CC2500_INO) || defined(BAYANG_RX_NRF24L01_INO) bool rx_data_started; bool rx_disable_lna; uint16_t rx_rc_chan[16]; @@ -699,7 +699,7 @@ bool Update_All() update_led_status(); #if defined(TELEMETRY) #if ( !( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) ) ) - if( (protocol == PROTO_FRSKY_RX) || (protocol == PROTO_SCANNER) || (protocol==PROTO_FRSKYD) || (protocol==PROTO_BAYANG) || (protocol==PROTO_NCC1701) || (protocol==PROTO_BUGS) || (protocol==PROTO_BUGSMINI) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_FRSKYX) || (protocol==PROTO_DSM) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC) || (protocol==PROTO_HOTT)) + if((protocol == PROTO_BAYANG_RX) || (protocol == PROTO_AFHDS2A_RX) || (protocol == PROTO_FRSKY_RX) || (protocol == PROTO_SCANNER) || (protocol==PROTO_FRSKYD) || (protocol==PROTO_BAYANG) || (protocol==PROTO_NCC1701) || (protocol==PROTO_BUGS) || (protocol==PROTO_BUGSMINI) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_FRSKYX) || (protocol==PROTO_DSM) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC) || (protocol==PROTO_HOTT)) #endif if(IS_DISABLE_TELEM_off) TelemetryUpdate(); @@ -991,7 +991,7 @@ static void protocol_init() TX_RX_PAUSE_off; TX_MAIN_PAUSE_off; tx_resume(); - #if defined(AFHDS2A_RX_A7105_INO) || defined(FRSKY_RX_CC2500_INO) + #if defined(AFHDS2A_RX_A7105_INO) || defined(FRSKY_RX_CC2500_INO) || defined(BAYANG_RX_NRF24L01_INO) for(uint8_t ch=0; ch<16; ch++) rx_rc_chan[ch] = 1024; #endif @@ -1421,6 +1421,12 @@ static void protocol_init() remote_callback = FX816_callback; break; #endif + #if defined(BAYANG_RX_NRF24L01_INO) + case PROTO_BAYANG_RX: + next_callback=initBayang_Rx(); + remote_callback = Bayang_Rx_callback; + break; + #endif #if defined(XN297DUMP_NRF24L01_INO) case PROTO_XN297DUMP: next_callback=initXN297Dump(); diff --git a/Multiprotocol/Telemetry.ino b/Multiprotocol/Telemetry.ino index 1eb60bd..892fcf1 100644 --- a/Multiprotocol/Telemetry.ino +++ b/Multiprotocol/Telemetry.ino @@ -258,7 +258,7 @@ static void multi_send_status() } #endif -#if defined (FRSKY_RX_TELEMETRY) || defined (AFHDS2A_RX_TELEMETRY) +#if defined (FRSKY_RX_TELEMETRY) || defined (AFHDS2A_RX_TELEMETRY) || defined (BAYANG_RX_TELEMETRY) void receiver_channels_frame() { uint16_t len = packet_in[3] * 11; // 11 bit per channel @@ -930,11 +930,11 @@ void TelemetryUpdate() } #endif - #if defined (FRSKY_RX_TELEMETRY) || defined(AFHDS2A_RX_TELEMETRY) - if (telemetry_link && (protocol == PROTO_FRSKY_RX || protocol == PROTO_AFHDS2A_RX)) + #if defined (FRSKY_RX_TELEMETRY) || defined(AFHDS2A_RX_TELEMETRY) || defined (BAYANG_RX_TELEMETRY) + if ((telemetry_link & 1) && (protocol == PROTO_FRSKY_RX || protocol == PROTO_AFHDS2A_RX || protocol == PROTO_BAYANG_RX)) { receiver_channels_frame(); - telemetry_link = 0; + telemetry_link &= ~1; return; } #endif diff --git a/Multiprotocol/Validate.h b/Multiprotocol/Validate.h index 01be5fe..611672d 100644 --- a/Multiprotocol/Validate.h +++ b/Multiprotocol/Validate.h @@ -239,6 +239,7 @@ #undef XN297L_CC2500_EMU #undef POTENSIC_NRF24L01_INO #undef ZSX_NRF24L01_INO + #undef BAYANG_RX_NRF24L01_INO #endif //Make sure telemetry is selected correctly @@ -266,6 +267,8 @@ #undef AFHDS2A_RX_TELEMETRY #undef AFHDS2A_RX_A7105_INO #undef HOTT_FW_TELEMETRY + #undef BAYANG_RX_TELEMETRY + #undef BAYANG_RX_NRF24L01_INO #else #if defined(MULTI_TELEMETRY) && defined(MULTI_STATUS) #error You should choose either MULTI_TELEMETRY or MULTI_STATUS but not both. @@ -282,6 +285,10 @@ #undef AFHDS2A_RX_TELEMETRY #undef AFHDS2A_RX_A7105_INO #endif + #if not defined(BAYANG_RX_NRF24L01_INO) || not defined(BAYANG_RX_TELEMETRY) + #undef BAYANG_RX_TELEMETRY + #undef BAYANG_RX_NRF24L01_INO + #endif #if not defined(BAYANG_NRF24L01_INO) #undef BAYANG_HUB_TELEMETRY #endif @@ -321,7 +328,7 @@ #if not defined(HOTT_CC2500_INO) #undef HOTT_FW_TELEMETRY #endif - #if not defined(HOTT_FW_TELEMETRY) && not defined(DSM_TELEMETRY) && not defined(SPORT_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(HUBSAN_HUB_TELEMETRY) && not defined(BUGS_HUB_TELEMETRY) && not defined(NCC1701_HUB_TELEMETRY) && not defined(BAYANG_HUB_TELEMETRY) && not defined(CABELL_HUB_TELEMETRY) && not defined(AFHDS2A_HUB_TELEMETRY) && not defined(AFHDS2A_FW_TELEMETRY) && not defined(MULTI_TELEMETRY) && not defined(MULTI_STATUS) && not defined(HITEC_HUB_TELEMETRY) && not defined(HITEC_FW_TELEMETRY) && not defined(SCANNER_TELEMETRY) && not defined(FRSKY_RX_TELEMETRY) && not defined(AFHDS2A_RX_TELEMETRY) + #if not defined(HOTT_FW_TELEMETRY) && not defined(DSM_TELEMETRY) && not defined(SPORT_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(HUBSAN_HUB_TELEMETRY) && not defined(BUGS_HUB_TELEMETRY) && not defined(NCC1701_HUB_TELEMETRY) && not defined(BAYANG_HUB_TELEMETRY) && not defined(CABELL_HUB_TELEMETRY) && not defined(AFHDS2A_HUB_TELEMETRY) && not defined(AFHDS2A_FW_TELEMETRY) && not defined(MULTI_TELEMETRY) && not defined(MULTI_STATUS) && not defined(HITEC_HUB_TELEMETRY) && not defined(HITEC_FW_TELEMETRY) && not defined(SCANNER_TELEMETRY) && not defined(FRSKY_RX_TELEMETRY) && not defined(AFHDS2A_RX_TELEMETRY) && not defined(BAYANG_RX_TELEMETRY) #undef TELEMETRY #undef INVERT_TELEMETRY #undef MULTI_TELEMETRY diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index 1d90cd3..717e5be 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -187,6 +187,7 @@ //The protocols below need a NRF24L01 to be installed #define ASSAN_NRF24L01_INO #define BAYANG_NRF24L01_INO +#define BAYANG_RX_NRF24L01_INO #define BUGSMINI_NRF24L01_INO #define CABELL_NRF24L01_INO #define CFLIE_NRF24L01_INO @@ -304,6 +305,7 @@ #define FRSKY_RX_TELEMETRY // Forward channels data to TX #define AFHDS2A_RX_TELEMETRY // Forward channels data to TX #define HOTT_FW_TELEMETRY // Forward received telemetry packets to be decoded by erskyTX and OpenTX +#define BAYANG_RX_TELEMETRY // Forward channels data to TX /****************************/ /*** SERIAL MODE SETTINGS ***/ @@ -501,6 +503,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= { X16_AH IRDRONE DHD_D4 + PROTO_BAYANG_RX + NONE PROTO_BUGS NONE PROTO_BUGSMINI diff --git a/Protocols_Details.md b/Protocols_Details.md index 67e03c3..4390597 100644 --- a/Protocols_Details.md +++ b/Protocols_Details.md @@ -69,6 +69,7 @@ Protocol Name|Protocol Number|Sub_Proto 0|Sub_Proto 1|Sub_Proto 2|Sub_Proto 3|Su ---|---|---|---|---|---|---|---|---|---|---|--- [Assan](Protocols_Details.md#ASSAN---24)|24|ASSAN||||||||NRF24L01| [Bayang](Protocols_Details.md#BAYANG---14)|14|Bayang|H8S3D|X16_AH|IRDRONE|DHD_D4||||NRF24L01|XN297 +[Bayang RX](Protocols_Details.md#BAYANG-RX---59)|59|||||||||NRF24L01|XN297 [Bugs](Protocols_Details.md#BUGS---41)|41|BUGS||||||||A7105| [BugsMini](Protocols_Details.md#BUGSMINI---42)|42|BUGSMINI|BUGS3H|||||||NRF24L01|XN297 [Cabell](Protocols_Details.md#Cabell---34)|34|Cabell_V3|C_TELEM|-|-|-|-|F_SAFE|UNBIND|NRF24L01| @@ -674,6 +675,17 @@ CH12|CH13 ----|---- TAKE_OFF|EMG_STOP +## BAYANG RX - *59* +The Bayang receiver protocol enables master/slave trainning, separate access from 2 different radios to the same model,... + +CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8 +---|---|---|---|---|---|---|--- +A|E|T|R|FLIP|RTH|PICTURE|VIDEO + +Extended limits not supported + +Available in OpenTX 2.3.2, Trainer Mode Master/Multi + ## BUGSMINI - *42* Models: MJX Bugs 3 Mini and 3H