/* 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 . Works with Traxxas 6519 receivers https://traxxas.com/sites/default/files/24CompGuide-2016.jpg . */ #if defined(TRAXXAS_CYRF6936_INO) #include "iface_cyrf6936.h" #define TRAXXAS_TQ1_FORCE_ID //#define TRAXXAS_TQ2_FORCE_ID #define TRAXXAS_DEBUG #define TRAXXAS_BIND_CHANNEL 0x2B #define TRAXXAS_CHECK_CHANNEL 0x22 #define TRAXXAS_PACKET_SIZE 16 #define TRAXXAS_TQ1_BIND_CHANNEL 0x04 #define TRAXXAS_TQ1_CHECK_CHANNEL 0x34 enum { TRAXXAS_BIND_PREP_RX=0, TRAXXAS_BIND_RX, TRAXXAS_BIND_TX1, TRAXXAS_PREP_RX, TRAXXAS_RX, TRAXXAS_PREP_DATA, TRAXXAS_DATA, TRAXXAS_TQ1_BIND, TRAXXAS_TQ1_DATA1, TRAXXAS_TQ1_DATA2, }; const uint8_t PROGMEM TRAXXAS_init_vals[][2] = { //Init from dump {CYRF_32_AUTO_CAL_TIME, 0x3C}, // Default init value {CYRF_35_AUTOCAL_OFFSET, 0x14}, // Default init value {CYRF_1B_TX_OFFSET_LSB, 0x55}, // Default init value {CYRF_1C_TX_OFFSET_MSB, 0x05}, // Default init value {CYRF_28_CLK_EN, 0x02}, // Force Receive Clock Enable {CYRF_03_TX_CFG, 0x08 | CYRF_BIND_POWER}, // 8DR Mode, 32 chip codes {CYRF_0B_PWR_CTRL, 0x00}, // PMU {CYRF_06_RX_CFG, 0x88 | 0x02}, // AGC enabled, Fast Turn Mode enabled, adding overwrite enable to not lockup RX {CYRF_1E_RX_OVERRIDE, 0x08}, // Reject packets with 0 seed }; static void __attribute__((unused)) TRAXXAS_cyrf_bind_config() { CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[0]); CYRF_WriteRegister(CYRF_15_CRC_SEED_LSB, 0x5A); CYRF_WriteRegister(CYRF_16_CRC_SEED_MSB, 0x5A); CYRF_ConfigRFChannel(TRAXXAS_BIND_CHANNEL); } static void __attribute__((unused)) TRAXXAS_cyrf_check_config() { CYRF_ConfigRFChannel(TRAXXAS_CHECK_CHANNEL); CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[9]); CYRF_WriteRegister(CYRF_15_CRC_SEED_LSB, 0xA5); CYRF_WriteRegister(CYRF_16_CRC_SEED_MSB, 0xA5); } static void __attribute__((unused)) TRAXXAS_cyrf_data_config() { CYRF_ConfigRFChannel(hopping_frequency[0]); #ifdef TRAXXAS_FORCE_ID // data taken from TX dump CYRF_WriteRegister(CYRF_15_CRC_SEED_LSB, 0x1B); CYRF_WriteRegister(CYRF_16_CRC_SEED_MSB, 0x3F); CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[6]); #else uint16_t addr=TRAXXAS_EEPROM_OFFSET+RX_num*3; CYRF_WriteRegister(CYRF_15_CRC_SEED_LSB, cyrfmfg_id[0] - eeprom_read_byte((EE_ADDR)(addr + 0))); CYRF_WriteRegister(CYRF_16_CRC_SEED_MSB, cyrfmfg_id[1] - eeprom_read_byte((EE_ADDR)(addr + 1))); CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[eeprom_read_byte((EE_ADDR)(addr + 2)) % 20]); #endif CYRF_SetTxRxMode(TX_EN); } static void __attribute__((unused)) TRAXXAS_send_data_packet() { packet[0] = 0x01; memset(&packet[1],0x00,TRAXXAS_PACKET_SIZE-1); //Next RF channel ? 0x00 -> keep current, 0x0E change to F=15 //packet[1] = hopping_frequency[0] - 1; //6 channels uint16_t ch; for(uint8_t i=0; i<6; i++) { ch = convert_channel_16b_nolimit(i,500,1000,false); packet[2+i*2]=ch>>8; packet[3+i*2]=ch; } CYRF_SetPower(0x08); CYRF_WriteDataPacket(packet); } static void __attribute__((unused)) TRAXXAS_TQ1_send_data_packet() { memcpy(&packet[1], cyrfmfg_id, 4); if(IS_BIND_IN_PROGRESS) { packet_length = 8; packet[0] = 0x2A; // Bind packet packet[5] = 0xA0; // Bind phase 0 packet[6] = TRAXXAS_TQ1_BIND_CHANNEL-1; // Not sure... } else { packet_length = 16; packet[0] = 0x02; // Normal packet packet[5] = 0xA2; // Bind phase 2 = completed? //4 channels uint16_t ch; for(uint8_t i=0; i<4; i++) { ch = convert_channel_ppm(i); packet[6+i*2]=ch; packet[7+i*2]=ch>>8; } packet[14] = hopping_frequency[0]-1; // Not sure... } uint8_t xor_value=0; for(uint8_t i=0; i doesn't care?? - P[8] RF channel - 1 (on packets type 0x03) - P[9] 0x00 unchanged?? - P[10] needs to be set to 0x01 to complete the bind -> normal packet P[0]?? - P[11] unchanged ?? -> no bind if set to 0x00 or 0x81 - P[12] unchanged ?? -> no bind if set to 0x05 or 0x86 - P[13] changes from 0x06 to 0x05 but not needed to complete the bind -> doesn't care?? - P[14..15]=0x00 unchanged?? Packets 0x03: Which RF channel CHANNEL: 0x22 SOP_CODE: 0x97 0xE5 0x14 0x72 0x7F 0x1A 0x14 0x72 CRC_SEED_LSB: 0xA5 CRC_SEED_MSB: 0xA5 RX: 0x03 0x4A 0xA3 0x2D 0x1A 0x49 0xFE 0x06 0x00 0x00 0x02 0x01 0x06 0x06 0x00 0x00 TX: 0x03 0x65 0xE2 0x5E 0x55 0x4D 0xFE 0xEE 0x0E 0x00 0x01 0x01 0x06 0x05 0x00 0x00 - P[8] RF channel - 1 Packets 0x04: unknown RX: 0x04 0x4A 0xA3 0x2D 0x1A 0x49 0xFE 0x06 0x00 0x00 0x02 0x01 0x06 0x06 0x00 0x00 Packets 0x01: Normal mode CHANNEL: 0x05 SOP_CODE: 0xA1 0x78 0xDC 0x3C 0x9E 0x82 0xDC 0x3C CRC_SEED_LSB: 0x1B CRC_SEED_MSB: 0x3F TX3: 0x01 0x00 0x02 0xA8 0x03 0xE7 0x02 0x08 0x00 0x00 0x01 0x01 0x02 0xEE 0x00 0x00 CRC_SEED: TX ID: \x65\xE2\x5E\x55\x4D\xFE RX ID: \x4A\xA3\x2D\x1A\x49\xFE CRC 0x1B 0x3F => CRC: 65-4A=1B E2-A3=3F RX ID: \x4B\xA3\x2D\x1A\x49\xFE CRC 0x1A 0x3F => CRC: 65-4B=1A E2-A3=3F RX ID: \x00\x00\x2D\x1A\x49\xFE CRC 0x65 0xE2 => CRC: 65-00=65 E2-00=E2 RX ID: \x00\xFF\x2D\x1A\x49\xFE CRC 0x65 0xE3 => CRC: 65-00=65 E2-FF=E3 RX ID: \xFF\x00\x2D\x1A\x49\xFE CRC 0x66 0xE2 => CRC: 65-FF=66 E2-00=E2 SOP Codes: RX1: 02 4A A3 2D 1A 49 FE 06 00 00 02 01 06 06 00 00 SOP: A1 78 DC 3C 9E 82 DC 3C RX2: 02 49 AC 4F 55 4D FE 05 00 00 02 01 06 06 00 00 SOP: 5A CC AE 46 B6 31 AE 46 RX3: 02 CA F3 62 55 4D FE 03 00 00 02 01 06 06 00 00 SOP: 66 CD 7C 50 DD 26 7C 50 Dump of SOP Codes: 00: 3C 37 CC 91 E2 F8 CC 91 => bind 01: 9B C5 A1 0F AD 39 A2 0F 02: EF 64 B0 2A D2 8F B1 2A 03: 66 CD 7C 50 DD 26 7C 50 04: 5C E1 F6 44 AD 16 F6 44 05: 5A CC AE 46 B6 31 AE 46 06: A1 78 DC 3C 9E 82 DC 3C 07: B9 8E 19 74 6F 65 18 74 08: DF B1 C0 49 62 DF C1 49 09: 97 E5 14 72 7F 1A 14 72 => check 10: 82 C7 90 36 21 03 FF 17 11: E2 F8 CC 91 3C 37 CC 91 => bind 4 bytes group swapped 12: AD 39 A2 0F 9B C5 A1 0F => 01 4 bytes group swapped 13: D2 8F B1 2A EF 64 B0 2A => 02 4 bytes group swapped 14: DD 26 7C 50 66 CD 7C 50 => 03 4 bytes group swapped ... 19: 62 DF C1 49 DF B1 C0 49 => 08 4 bytes group swapped 20: 00 00 00 33 DE AD BA BE ??over?? */ /* Traxxas TQ 1st generation ------------------------- https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/issues/967#issuecomment-2079038576 */ /* Traxxas TQi ------------------------- Unknown 3 first packets: CHANNEL: 0x2B SOP_CODE: 0x3C 0x37 0xCC 0x91 0xE2 0xF8 0xCC 0x91 CRC_SEED_LSB: 0x5A CRC_SEED_MSB: 0x5A RX: 0xA0 0x1F 0x60 0x58 0x34 0x44 0x1C 0x11 0xA5 0x72 0x8D 0x9D 0xEA 0x49 0x2B 0xE2 RX: 0xD3 0x53 0xD4 0x45 0x1B 0x6F 0x75 0x42 0xEF 0x8A 0xD2 0x24 0x8E 0xF0 0x05 0x6C RX: 0xAA 0xD7 0xD7 0x43 0x0F 0x2F 0x02 0x8F 0x06 0x54 0x3A 0x35 0xF5 0xCF 0x0F 0x82 Packets 0x02: Bind learn TX/RX addresses same as TQ 2nd: CHANNEL: 0x2B SOP_CODE: 0x3C 0x37 0xCC 0x91 0xE2 0xF8 0xCC 0x91 CRC_SEED_LSB: 0x5A CRC_SEED_MSB: 0x5A RX: 0x02 0x5B 0xE9 0x7E 0x14 0xF1 0xFE 0x0D 0x00 0x00 0x02 0x02 0x00 0x26 0x00 0x00 TX: 0x02 0xE0 0xAC 0x7F 0x14 0xF1 0xFE 0x00 0x00 0x00 0x01 0x02 0x00 0x51 0x00 0x00 Notes: - P[1..6] = RX cyrfmfg_id is 0x5B,0xE9,0x7E,0x14,0xF1,0xFE and TX cyrfmfg_id is 0xE0,0xAC,0x7F,0x14,0xF1,0xFE - P[7] RX SOP code index, changes from 0x0D to 0x00 (but not needed to complete the bind -> doesn't care??) - P[8] RF channel - 1 (on packets type 0x03) - P[9] 0x00 unchanged?? - P[10] needs to be set to 0x01 to complete the bind -> normal packet P[0]?? - P[11] unchanged ?? (-> no bind if set to 0x00 or 0x81) - P[12] unchanged ?? (-> no bind if set to 0x05 or 0x86) - P[13] changes from 0x26 to 0x51 (but not needed to complete the bind -> doesn't care??) - P[14..15]=0x00 unchanged?? Next steps: Packets 0x08: ??? TX: 0x08 0x00 0x03 0x14 0xFD 0x3E 0x28 0xB9 0xCA 0x48 0x76 0x4E 0x00 0x51 0x00 0x00 TX: 0x08 0x00 0x02 0x14 0xFD 0x3E 0x28 0xB9 0xCA 0x48 0x76 0x4E 0x00 0x51 0x00 0x00 TX: 0x08 0x00 0x01 0x14 0xFD 0x3E 0x28 0xB9 0xCA 0x48 0x76 0x4E 0x00 0x51 0x00 0x00 RX: 0x08 0x00 0x03 0x14 0xFD 0x24 0x20 0xB8 0xCA 0x48 0x76 0x4E 0x00 0x26 0x00 0x00 RX: 0x08 0x00 0x01 0x14 0xFD 0x24 0x20 0xB8 0xCA 0x48 0x76 0x4E 0x00 0x26 0x00 0x00 P[1] index P[2] sequence number Packets 0x09: ??? TX: 0x09 0x00 0x03 0xEE 0x12 0x49 0x57 0x1F 0x4B 0x60 0x6B 0x4D 0x14 0xEF 0x69 0xC4 TX: 0x09 0x00 0x02 0xEE 0x12 0x49 0x57 0x1F 0x4B 0x60 0x6B 0x4D 0x14 0xEF 0x69 0xC4 TX: 0x09 0x00 0x01 0xEE 0x12 0x49 0x57 0x1F 0x4B 0x60 0x6B 0x4D 0x14 0xEF 0x69 0xC4 TX: 0x09 0x01 0x03 0xB2 0x63 0x43 0x25 0x22 0x4D 0xA1 0x15 0xFE 0xBA 0x7D 0x67 0x3E TX: 0x09 0x01 0x02 0xB2 0x63 0x43 0x25 0x22 0x4D 0xA1 0x15 0xFE 0xBA 0x7D 0x67 0x3E TX: 0x09 0x01 0x01 0xB2 0x63 0x43 0x25 0x22 0x4D 0xA1 0x15 0xFE 0xBA 0x7D 0x67 0x3E TX: 0x09 0x02 0x03 0xCB 0xBE 0xA6 0xD1 0xCD 0x23 0xA1 0x15 0xFE 0xBA 0x7D 0x67 0x3E TX: 0x09 0x02 0x02 0xCB 0xBE 0xA6 0xD1 0xCD 0x23 0xA1 0x15 0xFE 0xBA 0x7D 0x67 0x3E TX: 0x09 0x02 0x01 0xCB 0xBE 0xA6 0xD1 0xCD 0x23 0xA1 0x15 0xFE 0xBA 0x7D 0x67 0x3E RX: 0x09 0x00 0x03 0x90 0x24 0x93 0x08 0x41 0xC7 0x7F 0x59 0xB4 0xE3 0x25 0x77 0xB5 RX: 0x09 0x00 0x01 0x90 0x24 0x93 0x08 0x41 0xC7 0x7F 0x59 0xB4 0xE3 0x25 0x77 0xB5 RX: 0x09 0x01 0x02 0x88 0xFA 0x4D 0xFB 0x33 0xD4 0xFE 0x5F 0x1C 0xA9 0x0B 0x7A 0xE6 RX: 0x09 0x02 0x03 0x86 0xAF 0xD0 0x91 0xF6 0xDD 0xFE 0x5F 0x1C 0xA9 0x0B 0x7A 0xE6 RX: 0x09 0x02 0x01 0x86 0xAF 0xD0 0x91 0xF6 0xDD 0xFE 0x5F 0x1C 0xA9 0x0B 0x7A 0xE6 P[1] index P[2] sequence number Switch to normal mode: SOP_CODE: 0xD2 0x8F 0xB1 0x2A 0xEF 0x64 0xB0 0x2A CRC_SEED_LSB: 0x85 CRC_SEED_MSB: 0xC3 CHANNEL: 0x05 TX: 0x01 0x00 0x02 0xF5 0x02 0x9E 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x99 0x67 0x3E Normal content except P[14]&P[15] = 0x67&0x3E from previous packet sent SOP_CODE: 0x97 0xE5 0x14 0x72 0x7F 0x1A 0x14 0x72 CRC_SEED_LSB: 0xA5 CRC_SEED_MSB: 0xA5 CHANNEL: 0x22 RX: 0x04 0x5B 0xE9 0x7E 0x14 0xF1 0xFE 0x0D 0xDD 0xFE 0x02 0x02 0x00 0x26 0x7A 0xE6 RX packets 0x04: RX identity ? P[1..6] = RX cyrfmfg_id 0x5B,0xE9,0x7E,0x14,0xF1,0xFE P[7] = SOP index P[8] = unknown P[9] = unknown P[10] = same value as bind 0x02 P[11] = same value as bind 0x02 P[12] = same value as bind 0x00 P[13] = same value as bind 0x26 P[14] = unknown P[15] = unknown SOP_CODE: 0xD2 0x8F 0xB1 0x2A 0xEF 0x64 0xB0 0x2A CRC_SEED_LSB: 0x85 CRC_SEED_MSB: 0xC3 CHANNEL: 0x05 TX: 0x14 0x00 0x03 0xF5 0x02 0x9E 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x99 0x67 0x3E TX: 0x14 0x00 0x02 0xF5 0x02 0x9E 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x99 0x67 0x3E TX: 0x14 0x00 0x01 0xF5 0x02 0x9E 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x99 0x67 0x3E RX: 0x14 0x00 0x03 0x22 0xEC 0x42 0x9B 0xD7 0x99 0x3B 0xBB 0x85 0x17 0x41 0x67 0xA0 RX: 0x14 0x00 0x01 0x22 0xEC 0x42 0x9B 0xD7 0x99 0x3B 0xBB 0x85 0x17 0x41 0x67 0xA0 RX: 0x14 0x01 0x02 0x22 0xEF 0x42 0x9C 0xCA 0xFB 0x39 0xBB 0x85 0x17 0x41 0x67 0xA0 TX packets 0x14 same as packets 0x01 with a sequence number on P[2] RX packets 0x14 unknown content Packets 0x01 & 0x07: normal and telemetry request/answer TX: 0x01 0x00 0x02 0xF5 0x02 0x9E 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x99 0x00 0x00 TX: 0x07 0x00 0x02 0xF5 0x02 0x9E 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x99 0x00 0x00 RX: 0x07 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0xFB 0x00 0x00 0x85 0x17 0x41 0x67 0xA0 TX: 0x01 0x00 0x02 0xF5 0x02 0x9E 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x99 0x00 0x00 TX: 0x07 0x00 0x02 0xF5 0x02 0x9E 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x99 0x00 0x00 RX: 0x07 0x01 0x00 0x00 0x00 0x11 0x49 0xC8 0xFB 0x00 0x00 0x85 0x17 0x41 0x67 0xA0 TX: 0x01 0x00 0x02 0xF5 0x02 0x9E 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x99 0x00 0x00 TX: 0x07 0x00 0x02 0xF5 0x02 0x9E 0x00 0x00 0x00 0x00 0x00 0x00 0x02 0x99 0x00 0x00 RX: 0x07 0x01 0x00 0x00 0x00 0x12 0xDC 0x20 0xFB 0x00 0x00 0x85 0x17 0x41 0x67 0xA0 TX packets 0x07: request for telemetry RX packets 0x07: unknown CRC calc same as TQ 2nd: TX ID: 0xE0,0xAC,0x7F,0x14,0xF1,0xFE RX ID: 0x5B,0xE9,0x7E,0x14,0xF1,0xFE CRC 0x85 0xC3 => CRC: E0-5B=85 AC-E9=C3 SOP index same as TQ 2nd: SOP index=0x0D, SOP code= 0xD2, 0x8F, 0xB1, 0x2A, 0xEF, 0x64, 0xB0, 0x2A */ #endif