diff --git a/Multiprotocol/DSM_Rx_cyrf6936.ino b/Multiprotocol/DSM_Rx_cyrf6936.ino index 66a546e..7abc453 100644 --- a/Multiprotocol/DSM_Rx_cyrf6936.ino +++ b/Multiprotocol/DSM_Rx_cyrf6936.ino @@ -214,6 +214,15 @@ uint16_t DSM_RX_callback() uint8_t rx_status; static uint8_t read_retry=0; + if(sub_protocol == DSM_ERASE) + { + if(packet_count) + packet_count--; + else + BIND_DONE; + return 10000; // Nothing to do... + } + switch (phase) { case DSM_RX_BIND1: @@ -240,10 +249,14 @@ uint16_t DSM_RX_callback() { // store tx info into eeprom uint16_t temp = DSM_RX_EEPROM_OFFSET; + debug("ID="); for(uint8_t i=0;i<4;i++) { - cyrfmfg_id[i]=packet_in[i]^0xFF; + if (sub_protocol == DSM_CLONE && i == 3) + cyrfmfg_id[i]=(packet_in[i]^RX_num)^0xFF; + else + cyrfmfg_id[i]=packet_in[i]^0xFF; eeprom_write_byte((EE_ADDR)temp++, cyrfmfg_id[i]); debug(" %02X", cyrfmfg_id[i]); } @@ -303,6 +316,14 @@ uint16_t DSM_RX_callback() { BIND_DONE; phase++; // DSM_RX_DATA_PREP + //Copy clone values to EEPROM + if (sub_protocol == DSM_CLONE) + { + uint16_t temp = DSM_CLONE_EEPROM_OFFSET; + for(uint8_t i=0; i<4; i++) + eeprom_write_byte((EE_ADDR)temp++, cyrfmfg_id[i]); + eeprom_write_byte((EE_ADDR)temp, 0xF0); + } } break; case DSM_RX_DATA_PREP: @@ -470,20 +491,34 @@ void DSM_RX_init() if (IS_BIND_IN_PROGRESS) { - packet_count=0; - phase = DSM_RX_BIND1; + if(sub_protocol == DSM_ERASE) + { + // Clear all cloned addresses + uint16_t addr = DSM_CLONE_EEPROM_OFFSET; + for(uint8_t i=0; i<6; i++) + eeprom_write_byte((EE_ADDR)(addr++), 0xFF); + packet_count = 100; + } + else + { + packet_count=0; + phase = DSM_RX_BIND1; + } } else { uint16_t temp = DSM_RX_EEPROM_OFFSET; + if (sub_protocol == DSM_CLONE || sub_protocol == DSM_ERASE ) + temp = DSM_CLONE_EEPROM_OFFSET; debug("ID="); for(uint8_t i=0;i<4;i++) { cyrfmfg_id[i]=eeprom_read_byte((EE_ADDR)temp++); debug(" %02X", cyrfmfg_id[i]); } - DSM_rx_type=eeprom_read_byte((EE_ADDR)temp); + DSM_rx_type=eeprom_read_byte((EE_ADDR)DSM_RX_EEPROM_OFFSET+4); debugln(", type=%02X", DSM_rx_type); + phase = DSM_RX_DATA_PREP; } } diff --git a/Multiprotocol/DSM_cyrf6936.ino b/Multiprotocol/DSM_cyrf6936.ino index 5f2c562..eb1e9c1 100644 --- a/Multiprotocol/DSM_cyrf6936.ino +++ b/Multiprotocol/DSM_cyrf6936.ino @@ -21,6 +21,8 @@ //#define DSM_GR300 +#define CLONE_BIT_MASK 0x20 + #define DSM_BIND_CHANNEL 0x0d //13 This can be any odd channel //During binding we will send BIND_COUNT/2 packets @@ -143,7 +145,13 @@ static void __attribute__((unused)) DSM_update_channels() static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper) { uint8_t bits = 11; - + + // Check if clone flag has changed + if((prev_option&CLONE_BIT_MASK) != (option&CLONE_BIT_MASK)) + { + DSM_init(); + prev_option^=CLONE_BIT_MASK; + } if(prev_option!=option) DSM_update_channels(); @@ -512,27 +520,61 @@ void DSM_init() { if(sub_protocol == DSMR) { - uint8_t row = rx_tx_addr[3]%22; - for(uint8_t i=0; i< 4; i++) - cyrfmfg_id[i] = pgm_read_byte_near(&DSMR_ID_FREQ[row][i]); - for(uint8_t i=0; i< 23; i++) - hopping_frequency[i] = pgm_read_byte_near(&DSMR_ID_FREQ[row][i+4]); + if(option&CLONE_BIT_MASK) + SUB_PROTO_INVALID; + else + { + SUB_PROTO_VALID; + uint8_t row = rx_tx_addr[3]%22; + for(uint8_t i=0; i< 4; i++) + cyrfmfg_id[i] = pgm_read_byte_near(&DSMR_ID_FREQ[row][i]); + for(uint8_t i=0; i< 23; i++) + hopping_frequency[i] = pgm_read_byte_near(&DSMR_ID_FREQ[row][i+4]); + } } else { - CYRF_GetMfgData(cyrfmfg_id); - //Model match - cyrfmfg_id[3]^=RX_num; + if(option&CLONE_BIT_MASK) + { + if(eeprom_read_byte((EE_ADDR)DSM_CLONE_EEPROM_OFFSET+4)==0xF0) + { + //read cloned ID from EEPROM + debugln("Using cloned ID"); + uint16_t temp = DSM_CLONE_EEPROM_OFFSET; + for(uint8_t i=0;i<4;i++) + cyrfmfg_id[i] = eeprom_read_byte((EE_ADDR)temp++); + debug("Clone ID=") + for(uint8_t i=0;i<4;i++) + debug("%02x ", cyrfmfg_id[i]); + debugln(""); + } + else + { + SUB_PROTO_INVALID; + debugln("No valid cloned ID"); + } + } + else + { + SUB_PROTO_VALID; + CYRF_GetMfgData(cyrfmfg_id); + } } + //Model match + cyrfmfg_id[3]^=RX_num; //Calc sop_col sop_col = (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + 2) & 0x07; - //Fix for OrangeRX using wrong DSM_pncodes by preventing access to "Col 8" - if(sop_col==0 && sub_protocol != DSMR) - { - cyrfmfg_id[rx_tx_addr[0]%3]^=0x01; //Change a bit so sop_col will be different from 0 - sop_col = (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + 2) & 0x07; + //We cannot manipulate the ID if we are cloning + if(!(option&CLONE_BIT_MASK)) + { + //Fix for OrangeRX using wrong DSM_pncodes by preventing access to "Col 8" + if(sop_col==0 && sub_protocol != DSMR) + { + cyrfmfg_id[rx_tx_addr[0]%3]^=0x01; //Change a bit so sop_col will be different from 0 + sop_col = (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + 2) & 0x07; + } } //Calc CRC seed diff --git a/Multiprotocol/Multi.txt b/Multiprotocol/Multi.txt index 52854f1..3e0a317 100644 --- a/Multiprotocol/Multi.txt +++ b/Multiprotocol/Multi.txt @@ -67,7 +67,7 @@ 67,LR12,LR12,LR12_6ch 68,Skyartec 69,ESKYv2,150V2 -70,DSM_RX,Multi,CPPM +70,DSM_RX,Multi,CloneTX,EraseTX,CPPM 71,JJRC345,JJRC345,SkyTmblr 72,Q90C 73,Kyosho,FHSS,Hype diff --git a/Multiprotocol/Multi_Protos.ino b/Multiprotocol/Multi_Protos.ino index a61e781..0093d58 100644 --- a/Multiprotocol/Multi_Protos.ino +++ b/Multiprotocol/Multi_Protos.ino @@ -179,12 +179,16 @@ const char STR_SUBTYPE_FX[] = "\x04""816\0""620\0""9630"; #ifdef SEND_CPPM const char STR_SUB_FRSKY_RX[] = "\x07""Multi\0 ""CloneTX""EraseTX""CPPM\0 "; + const char STR_SUB_DSM_RX[] = "\x07""Multi\0 ""CloneTX""EraseTX""CPPM\0 "; #define FRCPPM 4 + #define DSMCPPM 4 const char STR_CPPM[] = "\x05""Multi""CPPM\0"; #define NBR_CPPM 2 #else const char STR_SUB_FRSKY_RX[] = "\x07""Multi\0 ""CloneTX""EraseTX"; + const char STR_SUB_DSM_RX[] = "\x07""Multi\0 ""CloneTX""EraseTX"; #define FRCPPM 3 + #define DSMCPPM 3 #define STR_CPPM NO_SUBTYPE #define NBR_CPPM 0 #endif @@ -249,7 +253,7 @@ const mm_protocol_definition multi_protocols[] = { {PROTO_DSM, STR_DSM, STR_SUBTYPE_DSM, 6, OPTION_MAXTHR, 0, 1, SW_CYRF, DSM_init, DSM_callback }, #endif #if defined(DSM_RX_CYRF6936_INO) - {PROTO_DSM_RX, STR_DSM_RX, STR_CPPM, NBR_CPPM, OPTION_NONE, 0, 1, SW_CYRF, DSM_RX_init, DSM_RX_callback }, + {PROTO_DSM_RX, STR_DSM_RX, STR_SUB_DSM_RX, DSMCPPM, OPTION_NONE, 0, 1, SW_CYRF, DSM_RX_init, DSM_RX_callback }, #endif #if defined(E010R5_CYRF6936_INO) {PROTO_E010R5, STR_E010R5, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_CYRF, E010R5_init, E010R5_callback }, diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index f475310..3fdbebd 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -19,7 +19,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 3 #define VERSION_REVISION 3 -#define VERSION_PATCH_LEVEL 29 +#define VERSION_PATCH_LEVEL 30 #define MODE_SERIAL 0 @@ -170,6 +170,12 @@ enum DSM DSM_AUTO = 4, DSMR = 5, }; +enum DSM_RX +{ + DSM_RX = 0, + DSM_CLONE = 1, + DSM_ERASE = 2, +}; enum YD717 { YD717 = 0, @@ -823,7 +829,8 @@ enum { #define FRSKYX2_CLONE_EEPROM_OFFSET 873 // (1) format + (3) TX ID, 4 bytes, end is 877 #define DSM_RX_EEPROM_OFFSET 877 // (4) TX ID + format, 5 bytes, end is 882 #define MOULDKG_EEPROM_OFFSET 882 // RX ID, 3 bytes per model, end is 882+64*3=1074 -//#define CONFIG_EEPROM_OFFSET 1074 // Current configuration of the multimodule +#define DSM_CLONE_EEPROM_OFFSET 1074 // (4) TX ID, (1) Initialized, end is 1079 +//#define CONFIG_EEPROM_OFFSET 1079 // Current configuration of the multimodule /* STM32 Flash Size */ #ifndef DISABLE_FLASH_SIZE_CHECK @@ -962,6 +969,10 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- DSMX_1F 2 DSMX_2F 3 DSM_AUTO 4 + sub_protocol==DSM_RX + DSM_RX 0 + DSM_CLONE 1 + DSM_ERASE 2 sub_protocol==YD717 YD717 0 SKYWLKR 1 diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index 67394c9..4e1e5b5 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -603,7 +603,9 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= { DSMX_2F DSMR PROTO_DSM_RX - NONE + DSM_RX + DSM_CLONE + DSM_ERASE PROTO_E010R5 NONE PROTO_E016H