TO REPROGRAM 3DR RADIO IF BAD SOFTWARE: look at hm-trp pinout: https://github.com/Dronecode/SiK/blob/master/Firmware/include/board_hm_trp.h connect c2d/c2ck/gnd from si usb debug adapter to hm-trp board power 3dr radio from usb, NOT usb debug adapter use windows si ide to connect to adapter -> hm-trp download object file click go -- done! si1000 internal pkt structure: [preamble 1-255] [sync 1-4] [tx header 0-4] [packet length 0-1] [data] [crc 0-2] our packet structure: [preamble 2] [sync 2] [tx header 0] [len 1] [data ?] [crc 0] [5555] [2DD4] [] [??] [*] [] data = [ fo = 0 sbsel = 1 hbsel = 1 fb = 21 fc = 49002 (we had something else?) fhs = 25 fhch = 26 (changes) trclk = 0 dtmod = 2 eninv = 0 modtyp = 3 fd = 102 txdr = 4194 Fcarrier = Fnom + fhs(25) * (fhch * 10kHz) 915129375 + 25 + (25*10000) Fnom??? = fTX = 915129375 = 10MHz * (hbsel+1) * (fb + 24 + (fc/64000)) = 10000000 * (1+1) * (21 + 24 + (48414/64000)) Ftx = 10000000 * (1+1) * (21+24+(49002/64000)) = 915313125 (device instead of expected) Fcarrier = Fnom + fhs * (fhch * 10000) Fcarrier = 915313125 + 25 * (25 * 10000) = 921563125 Fcarrier = 915313125 + 25 * (26 * 10000) = 921813125 so freq_min is actually 915313381 -- why? weird rand()? // evil mavlink example fe = start of frame 0c = length of payload 12 = packet sequence (random guess) 00 = system id (?) 00 = component id (?) 4c = message id (command_long) 000001900001000000000000 = payload 35d3 = crc(0c1200004c000001900001000000000000) len=19 golay(fe0c1200004c00000190000100000000000035d3) = e4f7672c9500000000646502000000750c005e8004750c00000000000000000000000000 si1000 whitening algo: 0f70b36f439848aebc97381dd3d4a0557d68376d60bbe3cd35c68bfa58a630199593f6926fcb50a2765ec354e4310804464756c712a367cf16e52099d1f783fe1ee166de8730915d792e703ba7a940aafad06edac177c79a6b8d17f4b14c60332b27ed24df96a144ecbd86a9c86210088c8ead8e2546cf9e2dca4133a3ef07fc3dc2cdbd0e6122baf25ce0774f528155f5a0ddb582ef8f34d71a2fe96298c066564fda49bf2d4289d97b0d5390c42011191d5b1c4a8d9f3c5b94826747de0ff87b859b7a1cc24575e4b9c0ee9ea502abeb41bb6b05df1e69ae345fd2c53180ccac9fb4937e5a8513b2f61aa721884022323ab638951b3e78b72904ce8f194b # frequency deviation (for data rate+freq) = 102 * 625 = 63750 # whitening is on len+data /* UNTESTED */ () [EZRADIOPRO_DATA_ACCESS_CONTROL] () [reg_index[i]] 0x05 0 [EZRADIOPRO_INTERRUPT_ENABLE_1] 0x05 0x00 [EZRADIOPRO_INTERRUPT_ENABLE_1] 0x05 RADIO_RX_INTERRUPTS [EZRADIOPRO_INTERRUPT_ENABLE_1] 0x06 0 [EZRADIOPRO_INTERRUPT_ENABLE_2] 0x06 0x00 [EZRADIOPRO_INTERRUPT_ENABLE_2] 0x06 EZRADIOPRO_ENCHIPRDY (0x02) [EZRADIOPRO_INTERRUPT_ENABLE_2] 0x06 EZRADIOPRO_ENPREAVAL (0x40) [EZRADIOPRO_INTERRUPT_ENABLE_2] 0x07 (EZRADIOPRO_SWRES | EZRADIOPRO_XTON [EZRADIOPRO_OPERATING_AND_FUNCTION_CONTROL_1] 0x07 EZRADIOPRO_PLLON (0x02) [EZRADIOPRO_OPERATING_AND_FUNCTION_CONTROL_1] 0x07 EZRADIOPRO_RXON | EZRADIOPRO_XTON [EZRADIOPRO_OPERATING_AND_FUNCTION_CONTROL_1] 0x07 EZRADIOPRO_TXON | EZRADIOPRO_XTON [EZRADIOPRO_OPERATING_AND_FUNCTION_CONTROL_1] 0x08 (register_read(EZRADIOPRO_OPERATING_AND_FUNCTION_CONTROL_2 [EZRADIOPRO_OPERATING_AND_FUNCTION_CONTROL_2] 0x08 control & ~EZRADIOPRO_FFCLRRX [EZRADIOPRO_OPERATING_AND_FUNCTION_CONTROL_2] 0x08 control & ~EZRADIOPRO_FFCLRTX [EZRADIOPRO_OPERATING_AND_FUNCTION_CONTROL_2] 0x08 control | EZRADIOPRO_FFCLRRX [EZRADIOPRO_OPERATING_AND_FUNCTION_CONTROL_2] 0x08 control | EZRADIOPRO_FFCLRTX [EZRADIOPRO_OPERATING_AND_FUNCTION_CONTROL_2] 0x09 EZRADIOPRO_OSC_CAP_VALUE (0xB6) [EZRADIOPRO_CRYSTAL_OSCILLATOR_LOAD_CAPACITANCE] 0x0B 0x14 [EZRADIOPRO_GPIO0_CONFIGURATION] 0x0B 0x15 [EZRADIOPRO_GPIO0_CONFIGURATION] 0x0C 0x12 [EZRADIOPRO_GPIO1_CONFIGURATION] 0x0C 0x14 [EZRADIOPRO_GPIO1_CONFIGURATION] 0x0D 0x0A [EZRADIOPRO_GPIO2_CONFIGURATION] 0x0D 0x14 [EZRADIOPRO_GPIO2_CONFIGURATION] 0x0D 0x15 [EZRADIOPRO_GPIO2_CONFIGURATION] 0x0D 0x18 [EZRADIOPRO_GPIO2_CONFIGURATION] 0x0E 0x04 [EZRADIOPRO_IO_PORT_CONFIGURATION] 0x1D 0x44 [EZRADIOPRO_AFC_LOOP_GEARSHIFT_OVERRIDE] 0x1E 0x02 [EZRADIOPRO_AFC_TIMING_CONTROL] 0x1E 0x0A [EZRADIOPRO_AFC_TIMING_CONTROL] if (feature_golay) 0x30 1000 1000 0x88 (136) EZRADIOPRO_ENPACTX | EZRADIOPRO_ENPACRX [EZRADIOPRO_DATA_ACCESS_CONTROL] 0x32 0x00 [EZRADIOPRO_HEADER_CONTROL_1] 0x33 EZRADIOPRO_HDLEN_0BYTE | EZRADIOPRO_SYNCLEN_2BYTE (2) [EZRADIOPRO_HEADER_CONTROL_2] else 0x30 EZRADIOPRO_ENPACTX | EZRADIOPRO_ENPACRX | EZRADIOPRO_ENCRC | EZRADIOPRO_CRC_16 [EZRADIOPRO_DATA_ACCESS_CONTROL] 0x32 0x0C [EZRADIOPRO_HEADER_CONTROL_1] 0x33 EZRADIOPRO_HDLEN_2BYTE | EZRADIOPRO_SYNCLEN_2BYTE [EZRADIOPRO_HEADER_CONTROL_2] 0x34 00010000 0x10 16 - settings.preamble_length [EZRADIOPRO_PREAMBLE_LENGTH] 0x35 5<<3 [EZRADIOPRO_PREAMBLE_DETECTION_CONTROL] 0x36 00101101 2D - sync word 3 (DEFAULT) 0x37 11010100 D4 - sync word 2 (DEFAULT) if (feature_golay) 0x3A 0 (DEFAULT) 0x3B 0 (DEFAULT) else 0x3A id >> 8 [EZRADIOPRO_TRANSMIT_HEADER_3] id=networkId (25 by default) 0x3B id & 0xFF [EZRADIOPRO_TRANSMIT_HEADER_2] id=networkId (25 by default) 0x3E length [EZRADIOPRO_TRANSMIT_PACKET_LENGTH] if (feature_golay) 0x3F 0 (DEFAULT) 0x40 0 (DEFAULT) else 0x3F id >> 8 [EZRADIOPRO_CHECK_HEADER_3] id=networkId (25 by default) 0x40 id & 0xFF [EZRADIOPRO_CHECK_HEADER_2] id=networkId (25 by default) 0x43 0xFF [EZRADIOPRO_HEADER_ENABLE_3] 0x44 0xFF [EZRADIOPRO_HEADER_ENABLE_2] 0x58 0xC0 [EZRADIOPRO_CHARGEPUMP_CURRENT_TRIMMING_OVERRIDE] 0x6D 6 [EZRADIOPRO_TX_POWER] 0x6D i [EZRADIOPRO_TX_POWER] 0x70 0000 1101 (control is probably 0x0D) [EZRADIOPRO_MODULATION_MODE_CONTROL_1] 0x71 0010 0011 0x23 [EZRADIOPRO_MODULATION_MODE_CONTROL_2] 0x75 band [EZRADIOPRO_FREQUENCY_BAND_SELECT] 0x76 carrier >> 8 [EZRADIOPRO_NOMINAL_CARRIER_FREQUENCY_1] 0x77 carrier & 0xFF [EZRADIOPRO_NOMINAL_CARRIER_FREQUENCY_0] 0x79 channel [EZRADIOPRO_FREQUENCY_HOPPING_CHANNEL_SELECT] 0x7A settings.channel_spacing [EZRADIOPRO_FREQUENCY_HOPPING_STEP_SIZE] 0x7A value [EZRADIOPRO_FREQUENCY_HOPPING_STEP_SIZE] 0x7C TX_FIFO_THRESHOLD_HIGH [EZRADIOPRO_TX_FIFO_CONTROL_1] 0x7D TX_FIFO_THRESHOLD_LOW [EZRADIOPRO_TX_FIFO_CONTROL_2] 0x7E RX_FIFO_THRESHOLD_HIGH [EZRADIOPRO_RX_FIFO_CONTROL] reg_index[i] ... S0:FORMAT=25 S1:SERIAL_SPEED=57 S2:AIR_SPEED=64 S3:NETID=25 S4:TXPOWER=20 S5:ECC=1 S6:MAVLINK=1 S7:OPPRESEND=1 S8:MIN_FREQ=915000 S9:MAX_FREQ=928000 S10:NUM_CHANNELS=50 S11:DUTY_CYCLE=100 S12:LBT_RSSI=0 S13:MANCHESTER=0 S14:RTSCTS=0 S15:MAX_WINDOW=131 # serial, baudrate 57600 dsrdtr=0 rtscts=0 xonxoff=0 # there is a preamble # there is no hardware header # hardware CRC is off (software CRC is implemented) # there is a 2-byte DEFAULT sync word synclen[1:0] = 01—Expected/Transmitted Synchronization Word 3 first, followed by sync word 2. # default sync word: 0x2DD4 # golay = ECC (yes by default) 1445130108.421) Received: 06b465f55b23589f3e87 | ..e.[#X.>. (1445130246.321) Received: 63b465f530287a0a71ef | c.e.0(z.q. (1445130257.795) Received: 58b460f5bf7259db3c86 | X.`..rY.<. (1445130269.306) Received: 62b464f531297c8bdcef | b.d.1)|... (1445130298.035) Received: 62b467f5113bea13c287 | b.g..;.... 2dd4 77 557a6fdd3f49d74c9528bbe2f9 2dd4 a7 55786f52f56a85f1bd5372b 2dd4 b3 55786f242a68f508b578a8b3 // example rx: 55555f55 2dd4 9b f7786ff1ffea7fc9f732bff8a0 // unwhitened 64 1665f51c7ad95b238de0868837 // length = 0x64 (100) #d.setFreq(915129375) # Fnom = 10000000 * (1+1) * (21 + 24 + (48414/64000)) # [preamble = 0x5555] // 20 bits? 5 * 4 # [syncword = 0x2DD4] // 16 bits # data = PN9 whitened { # [length (1 byte)] // 8 bits (whitened) # [data (for `length`) = # golay (ECC'd) { // # netid = 0x1900 // 16 bits (whitened + ECC) # length = ?? // 8 bits (whitened + ECC) # } // 24 bits (rest of ECC) # golay (ECC'd) { // # crc = ?? // 16 bits (whitened + ECC) # length = ?? // 8 bits (whitened + ECC) # } // 24 bits (rest of ECC) # golay (ECC'd) { // # rest of data // `length` bytes from previous golay # } // `length` bytes (rest of ECC) # trailer.window // 13 bits (whitened) # trailer.command // 1 bit (whitened) # trailer.bonus // 1 bit (whitened) # trailer.resend // 1 bit (whitened) # ] # } # # packet size is 12 (header) + data*2 (golay) # packet structure (if ECC enabled) packet_length (whitened) [golay'd 0 netid[0] 1 netid[1] 2 length_of_pkt 3 golay 4 golay 5 golay 6 crc(buf)[0] 7 crc(buf)[1] 8 length_of_pkt (again) 9 golay 10 golay 11 golay 12-end rest of packet+golay ] b6 25db00 f22f22 # with whitening OFF: # Prem Sync LL(Net Ln golay) # Received: 55 5555 2dd4 b6 25db00 f22f22 acff5c462852ecf7 # 25cb00 f22f02 # golay 25db00f22f22 = 190045 [1900 = netid 25, 45 = len 69] # # 97.855 in hackrf = 98.7 IRL # subtract real freq by 0.845 # rfcat d.lowball() d.setMdmDRate(63995) # (4194 * 1000000) / (2 ** (16 + 5 * 0)) d.setMdmDeviatn(63750) d.setMdmChanBW(187500) # (63750 * 2) / 187500 = 68% filter bw d.setEnablePktCRC(0) d.setMdmSyncWord(0x2DD4) # 0x5555 0x2DD4 d.setMdmSyncMode(SYNCM_16_of_16) d.setMdmSyncMode(SYNCM_CARRIER_16_of_16) d.setPktPQT(3) d.setPktPQT(7) d.setEnablePktDataWhitening(0) # FIGURE OUT WHITENING d.setEnableMdmManchester(0) d.setMdmModulation(MOD_FORMAT_GFSK) d.setFreq(921813125) # see sik_map d.setFreq(916063125) # sik_map - first channel, ch3 d.makePktFLEN(19) # 1 length + 6 netid + 6 crc + 6 first data d.RFlisten() # end rfcat # rfcat TESTING d.lowball() d.setMdmDeviatn(63750) d.setMdmDRate(63995) # (4194 * 1000000) / (2 ** (16 + 5 * 0)) d.setMdmChanBW(187500) # (63750 * 2) / 187500 = 68% filter bw d.setEnablePktCRC(0) d.setPktPQT(3) d.setPktPQT(7) d.setMdmSyncWord(0x5555) # 0x5555 0x2DD4 d.setMdmSyncWord(0x2dd4) # 0x5555 0x2DD4 d.setMdmSyncMode(SYNCM_16_of_16) d.setMdmSyncMode(SYNCM_CARRIER_16_of_16) d.setEnablePktDataWhitening(0) # XXX figure out whitening d.setEnableMdmManchester(0) d.setMdmModulation(MOD_FORMAT_GFSK) d.setFreq(915379400) # see sik_map (chan=25) d.setFreq(921813125) d.makePktFLEN(20) d.RFlisten() # end rfcat # rfcat TX d.lowball() d.setEnablePktCRC(0) d.setMdmDeviatn(63750) d.setPktPQT(3) d.setMdmSyncWord(0x5555) # 0x5555 0x2DD4 d.setMdmSyncWord(0x2dd4) # 0x5555 0x2DD4 d.setMdmModulation(MOD_FORMAT_GFSK) d.setMdmSyncMode(SYNCM_16_of_16) d.setEnablePktDataWhitening(0) d.setEnableMdmManchester(0) d.setMdmDRate(63995) # (4194 * 1000000) / (2 ** (16 + 5 * 0)) d.setFreq(915379400) # see sik_map (chan=25) d.setFreq(921813125) d.makePktVLEN() d.setMaxPower() d.RFlisten() # end rfcat // guesses (for 900MHz) air_rate = 64 air_data_rate = rate_selection = 8 (air_data_rates[8] = 64) control = 0x0D manchester = yes (< 128kbps) duty_cycle = 100 // said 11 before...why? freq_min = 915M (changes below to 915125000) freq_max = 928M num_fh_channels = 50 channel_spacing = (freq_max - freq_min) / (num_fh_channels+2) channel_spacing = (928000000 - 915000000) / (50+2) = 250000 freq_min += channel_spacing / 2 freq_min = 915125000 srand(netid [25 by default]) freq_min += (sdcc_rand() * 625) % channel_spacing freq_min += 98125 = 915223125 // this is the list of registers that we will use the register tables for __code static const uint8_t reg_index[NUM_RADIO_REGISTERS] = { EZRADIOPRO_IF_FILTER_BANDWIDTH, // 0x1C EZRADIOPRO_CLOCK_RECOVERY_GEARSHIFT_OVERRIDE, // 0x1F EZRADIOPRO_CLOCK_RECOVERY_OVERSAMPLING_RATIO, // 0x20 EZRADIOPRO_CLOCK_RECOVERY_OFFSET_2, // 0x21 EZRADIOPRO_CLOCK_RECOVERY_OFFSET_1, // 0x22 EZRADIOPRO_CLOCK_RECOVERY_OFFSET_0, // 0x23 EZRADIOPRO_CLOCK_RECOVERY_TIMING_LOOP_GAIN_1, // 0x24 EZRADIOPRO_CLOCK_RECOVERY_TIMING_LOOP_GAIN_0, // 0x25 EZRADIOPRO_AFC_LIMITER, // 0x2A EZRADIOPRO_TX_DATA_RATE_1, // 0x6E EZRADIOPRO_TX_DATA_RATE_0, // 0x6F EZRADIOPRO_FREQUENCY_DEVIATION, // 0x72 }; // register table for 915MHz radios __code static const uint8_t reg_table_915[NUM_RADIO_REGISTERS][NUM_DATA_RATES] = { 0 1 2 3 4 5 6 7 8_YES 9 10 11 12 EZRADIOPRO_IF_FILTER_BANDWIDTH, // 0x1C {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x0B, 0x9A, 0x88, 0x8A, 0x8C, 0x8D}, EZRADIOPRO_CLOCK_RECOVERY_GEARSHIFT_OVERRIDE, // 0x1F {0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}, EZRADIOPRO_CLOCK_RECOVERY_OVERSAMPLING_RATIO, // 0x20 {0xD0, 0xE8, 0xF4, 0xFA, 0xD3, 0xA7, 0x7D, 0x53, 0x5E, 0x7D, 0x5E, 0x3F, 0x30}, EZRADIOPRO_CLOCK_RECOVERY_OFFSET_2, // 0x21 {0xE0, 0x60, 0x20, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02}, EZRADIOPRO_CLOCK_RECOVERY_OFFSET_1, // 0x22 {0x10, 0x20, 0x41, 0x83, 0x9B, 0xC4, 0x06, 0x89, 0x5D, 0x06, 0x5D, 0x0C, 0xAA}, EZRADIOPRO_CLOCK_RECOVERY_OFFSET_0, // 0x23 {0x62, 0xC5, 0x89, 0x12, 0xA6, 0x9C, 0x25, 0x37, 0x86, 0x25, 0x86, 0x4A, 0xAB}, EZRADIOPRO_CLOCK_RECOVERY_TIMING_LOOP_GAIN_1, // 0x24 {0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x03, 0x02, 0x02, 0x02, 0x04, 0x07}, EZRADIOPRO_CLOCK_RECOVERY_TIMING_LOOP_GAIN_0, // 0x25 {0x23, 0x44, 0x85, 0x08, 0x39, 0x8A, 0x0E, 0x18, 0xBB, 0x0E, 0xBB, 0xEA, EZRADIOPRO_AFC_LIMITER, // 0x2A {0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x20, 0x30, 0x41, 0x50, 0x50, 0x50, EZRADIOPRO_TX_DATA_RATE_1, // 0x6E {0x10, 0x20, 0x41, 0x83, 0x9B, 0xC4, 0x08, 0x0C, 0x10, 0x18, 0x20, 0x31, 0x40}, EZRADIOPRO_TX_DATA_RATE_0, // 0x6F {0x62, 0xC5, 0x89, 0x12, 0xA6, 0x9C, 0x31, 0x4A, 0x62, 0x93, 0xC5, 0x27, 0x00}, EZRADIOPRO_FREQUENCY_DEVIATION, // 0x72 {0x03, 0x06, 0x0D, 0x1A, 0x1E, 0x26, 0x33, 0x4D, 0x66, 0x9A, 0xCD, 0xFE, 0xFE} }; /* DATA RATES */ 0x1062 = 4194 = 1999 0x20C5 = 8389 = 4000 0x4189 = 16777 = 7999 0x8312 = 33554 = 15999 0x9BA6 = 39846 = 19000 0xC49C = 50332 = 24000 0x0831 = 2097 = 999 0x0C4A = 3146 = 1500 0x1062 = 4194 = 1999 0x1893 = 6291 = 2999 0x20C5 = 8389 = 4000 0x3127 = 12583 = 6000 0x4000 = 16384 = 7812 /* END DATA RATES */ data rate = 4194 or 25104 00010000 01100010 0x1062 = 4 txdr=0100011000001000 > (4194 * 1000000) / (2**(16+5)) = 1999.85504150390625 PARAM_NET_ID = 25; MAX_FREQ_CHANNELS = 50; freq_min = 915000000UL; freq_max = 928000000UL; txpower = 20; num_fh_channels = MAX_FREQ_CHANNELS; if (frequency > 480000000UL) { frequency -= 480000000UL; // frequency = 435000000 band = frequency / 20000000UL; // band = 21 //21.75 frequency -= (uint32_t)band * 20000000UL; // frequency = 15000000 frequency = scale_uint32(frequency, 625); // (value + (scale >> 1)) / scale; // (15000000 + (625 >> 1)) / 625 // frequency = 24000 //24000.4992 frequency <<= 1; // frequency = 48000 band |= EZRADIOPRO_HBSEL; } EZRADIOPRO_MODULATION_MODE_CONTROL_2 (0x71) = 0x23 0x23 = 00100011 modtyp[0,1] = 11 (GFSK (enable TX Data CLK when direct mode is used)) fd[8] = 0 eninv = 0 dtmod[0,1] = 01 trclk[0,1] = 00 /* sdcc rand functions -- SiK is compiled with sdcc */ #include static unsigned long int next = 1; int sdcc_rand(void) { next = next * 1103515245UL + 12345; return (unsigned int)(next/65536) % (RAND_MAX + 1U); } void sdcc_srand(unsigned int seed) { next = seed; } /* end of sdcc rand functions */ ////////////////////////// channel_spacing = (freq_max - freq_min) / (num_fh_channels+2); // add half of the channel spacing, to ensure that we are well // away from the edges of the allowed range freq_min += channel_spacing/2; // add another offset based on network ID. This means that // with different network IDs we will have much lower // interference srand(param_get(PARAM_NETID)); if (num_fh_channels > 5) { freq_min += ((unsigned long)(rand()*625)) % channel_spacing; } // set the frequency and channel spacing // change base freq based on netid radio_set_frequency(freq_min); // set channel spacing radio_set_channel_spacing(channel_spacing); // start on a channel chosen by network ID radio_set_channel(param_get(PARAM_NETID) % num_fh_channels); // And intilise the radio with them. if (!radio_configure(param_get(PARAM_AIR_SPEED)) && !radio_configure(param_get(PARAM_AIR_SPEED)) && !radio_configure(param_get(PARAM_AIR_SPEED))) { panic("radio_configure failed"); } // report the real air data rate in parameters param_set(PARAM_AIR_SPEED, radio_air_rate()); // setup network ID radio_set_network_id(param_get(PARAM_NETID)); // setup transmit power radio_set_transmit_power(txpower); // report the real transmit power in settings param_set(PARAM_TXPOWER, radio_get_transmit_power()); #ifdef USE_RTC // initialise real time clock rtc_init(); #endif // initialise frequency hopping system fhop_init(param_get(PARAM_NETID));