diff --git a/Multiprotocol/Multi.txt b/Multiprotocol/Multi.txt index 81596a2..230c17b 100644 --- a/Multiprotocol/Multi.txt +++ b/Multiprotocol/Multi.txt @@ -2,7 +2,7 @@ 2,Hubsan,H107,H301,H501 3,FrskyD,D8,Cloned 4,Hisky,Hisky,HK310 -5,V2x2,V2x2,JXD506 +5,V2x2,V2x2,JXD506,MR101 6,DSM,DSM2_1F,DSM2_2F,DSMX_1F,DSMX_2F,AUTO 7,Devo,8CH,10CH,12CH,6CH,7CH 8,YD717,YD717,SKYWLKR,SYMAX4,XINXUN,NIHUI diff --git a/Multiprotocol/Multi_Names.ino b/Multiprotocol/Multi_Names.ino index 4243f94..c24a6dc 100644 --- a/Multiprotocol/Multi_Names.ino +++ b/Multiprotocol/Multi_Names.ino @@ -93,7 +93,7 @@ const char STR_SUBTYPE_HUBSAN[] = "\x04""H107""H301""H501"; const char STR_SUBTYPE_FRSKYD[] = "\x06""D8\0 ""Cloned"; const char STR_SUBTYPE_FRSKYX[] = "\x07""D16\0 ""D16 8ch""LBT(EU)""LBT 8ch""Cloned\0"; const char STR_SUBTYPE_HISKY[] = "\x05""Std\0 ""HK310"; -const char STR_SUBTYPE_V2X2[] = "\x06""Std\0 ""JXD506"; +const char STR_SUBTYPE_V2X2[] = "\x06""Std\0 ""JXD506""MR101\0"; const char STR_SUBTYPE_DSM[] = "\x04""2 1F""2 2F""X 1F""X 2F""Auto"; const char STR_SUBTYPE_DEVO[] = "\x04""8ch\0""10ch""12ch""6ch\0""7ch\0"; const char STR_SUBTYPE_YD717[] = "\x07""Std\0 ""SkyWlkr""Syma X4""XINXUN\0""NIHUI\0 "; @@ -124,7 +124,7 @@ const char STR_SUBTYPE_POTENSIC[] = "\x03""A20"; const char STR_SUBTYPE_ZSX[] = "\x07""280JJRC"; const char STR_SUBTYPE_FLYZONE[] = "\x05""FZ410"; const char STR_SUBTYPE_FX816[] = "\x03""P38"; -const char STR_SUBTYPE_XN297DUMP[] = "\x07""250Kbps""1Mbps\0 ""2Mbps\0 ""Auto\0 "; +const char STR_SUBTYPE_XN297DUMP[] = "\x07""250Kbps""1Mbps\0 ""2Mbps\0 ""Auto\0 ""NRF\0 "; const char STR_SUBTYPE_ESKY150[] = "\x03""4ch""7ch"; const char STR_SUBTYPE_ESKY150V2[] = "\x05""150V2"; const char STR_SUBTYPE_V911S[] = "\x05""V911S""E119\0"; @@ -343,7 +343,7 @@ const mm_protocol_definition multi_protocols[] = { {PROTO_TRAXXAS, STR_TRAXXAS, 1, STR_SUBTYPE_TRAXXAS, OPTION_NONE }, #endif #if defined(V2X2_NRF24L01_INO) - {PROTO_V2X2, STR_V2X2, 2, STR_SUBTYPE_V2X2, OPTION_NONE }, + {PROTO_V2X2, STR_V2X2, 3, STR_SUBTYPE_V2X2, OPTION_NONE }, #endif #if defined(V761_NRF24L01_INO) {PROTO_V761, STR_V761, 0, NO_SUBTYPE, OPTION_NONE }, @@ -361,7 +361,7 @@ const mm_protocol_definition multi_protocols[] = { {PROTO_XK, STR_XK , 2, STR_SUBTYPE_XK, OPTION_RFTUNE }, #endif #if defined(XN297DUMP_NRF24L01_INO) - {PROTO_XN297DUMP, STR_XN297DUMP, 4, STR_SUBTYPE_XN297DUMP, OPTION_RFCHAN }, + {PROTO_XN297DUMP, STR_XN297DUMP, 5, STR_SUBTYPE_XN297DUMP, OPTION_RFCHAN }, #endif #if defined(YD717_NRF24L01_INO) {PROTO_YD717, STR_YD717, 5, STR_SUBTYPE_YD717, OPTION_NONE }, diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index 8e39964..d6aa3f0 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -19,7 +19,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 3 #define VERSION_REVISION 1 -#define VERSION_PATCH_LEVEL 21 +#define VERSION_PATCH_LEVEL 22 //****************** // Protocols @@ -241,6 +241,7 @@ enum V2X2 { V2X2 = 0, JXD506 = 1, + V2X2_MR101 = 2, }; enum FY326 { @@ -884,6 +885,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- sub_protocol==V2X2 V2X2 0 JXD506 1 + V2X2_MR101 2 sub_protocol==FY326 FY326 0 FY319 1 diff --git a/Multiprotocol/V2X2_nrf24l01.ino b/Multiprotocol/V2X2_nrf24l01.ino index 20774da..591cb28 100644 --- a/Multiprotocol/V2X2_nrf24l01.ino +++ b/Multiprotocol/V2X2_nrf24l01.ino @@ -19,7 +19,7 @@ #include "iface_nrf24l01.h" - +#define V2X2_MR101_FORCE_ID #define V2X2_BIND_COUNT 1000 // Timeout for callback in uSec, 4ms=4000us for V202 @@ -51,14 +51,6 @@ enum { // -enum { - V202_INIT2 = 0, - V202_INIT2_NO_BIND,//1 - V202_BIND1,//2 - V202_BIND2,//3 - V202_DATA//4 -}; - // This is frequency hopping table for V202 protocol // The table is the first 4 rows of 32 frequency hopping // patterns, all other rows are derived from the first 4. @@ -87,39 +79,29 @@ static void __attribute__((unused)) v202_init() NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x3F); // Enable all data pipes NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address - NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0xFF); // 4ms retransmit t/o, 15 tries - NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x08); // Channel 8 - NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps + // NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0xFF); // 4ms retransmit t/o, 15 tries + // NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x08); // Channel 8 + NRF24L01_SetBitrate(sub_protocol==V2X2_MR101?NRF24L01_BR_250K:NRF24L01_BR_1M); NRF24L01_SetPower(); NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit // NRF24L01_WriteReg(NRF24L01_08_OBSERVE_TX, 0x00); // no write bits in this field // NRF24L01_WriteReg(NRF24L01_00_CD, 0x00); // same - NRF24L01_WriteReg(NRF24L01_0C_RX_ADDR_P2, 0xC3); // LSB byte of pipe 2 receive address - NRF24L01_WriteReg(NRF24L01_0D_RX_ADDR_P3, 0xC4); - NRF24L01_WriteReg(NRF24L01_0E_RX_ADDR_P4, 0xC5); - NRF24L01_WriteReg(NRF24L01_0F_RX_ADDR_P5, 0xC6); - NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, V2X2_PAYLOADSIZE); // bytes of data payload for pipe 1 - NRF24L01_WriteReg(NRF24L01_12_RX_PW_P1, V2X2_PAYLOADSIZE); - NRF24L01_WriteReg(NRF24L01_13_RX_PW_P2, V2X2_PAYLOADSIZE); - NRF24L01_WriteReg(NRF24L01_14_RX_PW_P3, V2X2_PAYLOADSIZE); - NRF24L01_WriteReg(NRF24L01_15_RX_PW_P4, V2X2_PAYLOADSIZE); - NRF24L01_WriteReg(NRF24L01_16_RX_PW_P5, V2X2_PAYLOADSIZE); - NRF24L01_WriteReg(NRF24L01_17_FIFO_STATUS, 0x00); // Just in case, no real bits to write here + // NRF24L01_WriteReg(NRF24L01_0C_RX_ADDR_P2, 0xC3); // LSB byte of pipe 2 receive address + // NRF24L01_WriteReg(NRF24L01_0D_RX_ADDR_P3, 0xC4); + // NRF24L01_WriteReg(NRF24L01_0E_RX_ADDR_P4, 0xC5); + // NRF24L01_WriteReg(NRF24L01_0F_RX_ADDR_P5, 0xC6); + // NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, V2X2_PAYLOADSIZE); // bytes of data payload for pipe 1 + // NRF24L01_WriteReg(NRF24L01_12_RX_PW_P1, V2X2_PAYLOADSIZE); + // NRF24L01_WriteReg(NRF24L01_13_RX_PW_P2, V2X2_PAYLOADSIZE); + // NRF24L01_WriteReg(NRF24L01_14_RX_PW_P3, V2X2_PAYLOADSIZE); + // NRF24L01_WriteReg(NRF24L01_15_RX_PW_P4, V2X2_PAYLOADSIZE); + // NRF24L01_WriteReg(NRF24L01_16_RX_PW_P5, V2X2_PAYLOADSIZE); + // NRF24L01_WriteReg(NRF24L01_17_FIFO_STATUS, 0x00); // Just in case, no real bits to write here NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t *)"\x66\x88\x68\x68\x68", 5); - NRF24L01_WriteRegisterMulti(NRF24L01_0B_RX_ADDR_P1, (uint8_t *)"\x88\x66\x86\x86\x86", 5); + // NRF24L01_WriteRegisterMulti(NRF24L01_0B_RX_ADDR_P1, (uint8_t *)"\x88\x66\x86\x86\x86", 5); NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)"\x66\x88\x68\x68\x68", 5); -} - -static void __attribute__((unused)) V202_init2() -{ - NRF24L01_FlushTx(); - packet_sent = 0; - hopping_frequency_no = 0; - - // Turn radio power on NRF24L01_SetTxRxMode(TX_EN); - //Done by TX_EN??? => NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); } static void __attribute__((unused)) V2X2_set_tx_id(void) @@ -135,20 +117,24 @@ static void __attribute__((unused)) V2X2_set_tx_id(void) // Strange avoidance of channels divisible by 16 hopping_frequency[i] = (val & 0x0f) ? val : val - 3; } + #ifdef V2X2_MR101_FORCE_ID + rx_tx_addr[1]=0x83; + rx_tx_addr[2]=0x03; + rx_tx_addr[3]=0xAE; + memcpy(hopping_frequency,"\x05\x12\x08\x0C\x04\x0E\x10",7); + #endif } -static void __attribute__((unused)) V2X2_add_pkt_checksum() +static void __attribute__((unused)) V2X2_send_packet() { - uint8_t sum = 0; - for (uint8_t i = 0; i < 15; ++i) - sum += packet[i]; - packet[15] = sum; -} + uint8_t rf_ch = hopping_frequency[hopping_frequency_no >> 1]; + hopping_frequency_no = (hopping_frequency_no + 1) & 0x1F; + if(sub_protocol==V2X2_MR101 && hopping_frequency_no>13) + hopping_frequency_no=0; + NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_ch); -static void __attribute__((unused)) V2X2_send_packet(uint8_t bind) -{ uint8_t flags2=0; - if (bind) + if (IS_BIND_IN_PROGRESS) { flags = V2X2_FLAG_BIND; packet[0] = 0; @@ -174,31 +160,35 @@ static void __attribute__((unused)) V2X2_send_packet(uint8_t bind) flags=0; // Channel 5 if (CH5_SW) flags = V2X2_FLAG_FLIP; - // Channel 6 - if (CH6_SW) flags |= V2X2_FLAG_LIGHT; - // Channel 7 - if (CH7_SW) flags |= V2X2_FLAG_CAMERA; - // Channel 8 - if (CH8_SW) flags |= V2X2_FLAG_VIDEO; - //Flags2 - // Channel 9 - if (CH9_SW) - flags2 = V2X2_FLAG_HEADLESS; - if(sub_protocol==JXD506) - { - // Channel 11 - if (CH11_SW) - flags2 |= V2X2_FLAG_EMERGENCY; - } - else - { - // Channel 10 - if (CH10_SW) - flags2 |= V2X2_FLAG_MAG_CAL_X; - // Channel 11 - if (CH11_SW) - flags2 |= V2X2_FLAG_MAG_CAL_Y; + if(sub_protocol!=V2X2_MR101) + {//V2X2 & JXD506 + // Channel 6 + if (CH6_SW) flags |= V2X2_FLAG_LIGHT; + // Channel 7 + if (CH7_SW) flags |= V2X2_FLAG_CAMERA; + // Channel 8 + if (CH8_SW) flags |= V2X2_FLAG_VIDEO; + + //Flags2 + // Channel 9 + if (CH9_SW) + flags2 = V2X2_FLAG_HEADLESS; + if(sub_protocol==JXD506) + { + // Channel 11 + if (CH11_SW) + flags2 |= V2X2_FLAG_EMERGENCY; + } + else + {//V2X2 + // Channel 10 + if (CH10_SW) + flags2 |= V2X2_FLAG_MAG_CAL_X; + // Channel 11 + if (CH11_SW) + flags2 |= V2X2_FLAG_MAG_CAL_Y; + } } } // TX id @@ -223,16 +213,26 @@ static void __attribute__((unused)) V2X2_send_packet(uint8_t bind) packet[12] = 0x40; packet[13] = 0x40; } + else if(sub_protocol==V2X2_MR101) + { + + if (CH10_SW) packet[11] = 0x04; // Motors start/stop + if (CH11_SW) packet[11] |= 0x40; // Auto Land=-100% Takeoff=+100% + if (CH7_SW) flags |= 0x02; // Picture + if (CH8_SW) flags |= 0x01; // Video + if(IS_BIND_IN_PROGRESS) + flags = 0x80; + flags |= (hopping_frequency_no & 0x01)<<6; + } packet[14] = flags; - V2X2_add_pkt_checksum(); + uint8_t sum = packet[0]; + for (uint8_t i = 1; i < 15; ++i) + sum += packet[i]; + packet[15] = sum; - packet_sent = 0; - uint8_t rf_ch = hopping_frequency[hopping_frequency_no >> 1]; - hopping_frequency_no = (hopping_frequency_no + 1) & 0x1F; - NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_ch); NRF24L01_FlushTx(); NRF24L01_WritePayload(packet, V2X2_PAYLOADSIZE); - packet_sent = 1; + //packet_sent = 1; if (! hopping_frequency_no) NRF24L01_SetPower(); @@ -240,35 +240,26 @@ static void __attribute__((unused)) V2X2_send_packet(uint8_t bind) uint16_t ReadV2x2() { - switch (phase) { - case V202_INIT2: - V202_init2(); - phase = V202_BIND2; - return 150; - break; - case V202_INIT2_NO_BIND: - V202_init2(); - phase = V202_DATA; - return 150; - break; - case V202_BIND2: - if (packet_sent && NRF24L01_packet_ack() != PKT_ACKED) - return V2X2_PACKET_CHKTIME; - V2X2_send_packet(1); - if (--bind_counter == 0) + //if (packet_sent && NRF24L01_packet_ack() != PKT_ACKED) + // return V2X2_PACKET_CHKTIME; + #ifdef MULTI_SYNC + telemetry_set_input_sync(V2X2_PACKET_PERIOD); + #endif + V2X2_send_packet(); + if(IS_BIND_IN_PROGRESS) + { + if (--bind_counter == 0) + { + BIND_DONE; + if(sub_protocol==V2X2_MR101) { - phase = V202_DATA; - BIND_DONE; + #ifdef V2X2_MR101_FORCE_ID + NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)"\xC9\x59\xD2\x65\x34", 5); + memcpy(hopping_frequency,"\x03\x05\x15\x0D\x06\x14\x0B",7); + #endif } - break; - case V202_DATA: - if (packet_sent && NRF24L01_packet_ack() != PKT_ACKED) - return V2X2_PACKET_CHKTIME; - #ifdef MULTI_SYNC - telemetry_set_input_sync(V2X2_PACKET_PERIOD); - #endif - V2X2_send_packet(0); - break; + hopping_frequency_no = 0; + } } // Packet every 4ms return V2X2_PACKET_PERIOD; @@ -276,15 +267,13 @@ uint16_t ReadV2x2() uint16_t initV2x2() { + if(sub_protocol==V2X2_MR101) + BIND_IN_PROGRESS; + //packet_sent = 0; + hopping_frequency_no = 0; + bind_counter = V2X2_BIND_COUNT; + v202_init(); - // - if (IS_BIND_IN_PROGRESS) - { - bind_counter = V2X2_BIND_COUNT; - phase = V202_INIT2; - } - else - phase = V202_INIT2_NO_BIND; V2X2_set_tx_id(); return 50000; } diff --git a/Multiprotocol/XN297Dump_nrf24l01.ino b/Multiprotocol/XN297Dump_nrf24l01.ino index 54eea85..d10cf89 100644 --- a/Multiprotocol/XN297Dump_nrf24l01.ino +++ b/Multiprotocol/XN297Dump_nrf24l01.ino @@ -278,7 +278,7 @@ static uint16_t XN297Dump_callback() XN297Dump_overflow(); } } - else + else if(sub_protocol==XN297DUMP_AUTO) { switch(phase) { @@ -624,6 +624,79 @@ static uint16_t XN297Dump_callback() break; } } + else + { + if(phase==0) + { + address_length=5; + memcpy(rx_tx_addr, (uint8_t *)"\xC9\x59\xD2\x65\x34", 5); + bitrate=XN297DUMP_250K; + packet_length=16; + hopping_frequency_no=0x03; + + NRF24L01_Initialize(); + NRF24L01_SetTxRxMode(TXRX_OFF); + NRF24L01_SetTxRxMode(RX_EN); + NRF24L01_FlushTx(); + NRF24L01_FlushRx(); + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit + NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgment on all data pipes + NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only + NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, address_length-2); // RX/TX address length + NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, address_length); // set up RX address + NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, packet_length); // Enable rx pipe 0 + NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency_no); + + debug("NRF dump, len=%d, rf=%d, address length=%d, bitrate=",packet_length,hopping_frequency_no,address_length); + switch(bitrate) + { + case XN297DUMP_250K: + NRF24L01_SetBitrate(NRF24L01_BR_250K); + debugln("250K"); + break; + case XN297DUMP_2M: + NRF24L01_SetBitrate(NRF24L01_BR_2M); + debugln("2M"); + break; + default: + NRF24L01_SetBitrate(NRF24L01_BR_1M); + debugln("1M"); + break; + + } + 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_SetPower(); + NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); + phase++; + } + else + { + if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) + { // RX fifo data ready + if(NRF24L01_ReadReg(NRF24L01_09_CD)) + { + NRF24L01_ReadPayload(packet, packet_length); + if(memcmp(packet_in,packet,packet_length)) + { + debug("P:"); + for(uint8_t i=0;i