From ee10ba29a4f4bb2c30c62602b1197210e06d6b1b Mon Sep 17 00:00:00 2001 From: midelic Date: Sat, 24 Sep 2016 01:04:35 +0300 Subject: [PATCH] update to last multi modification --- Multiprotocol/ASSAN_nrf24l01.ino | 20 +- Multiprotocol/Bayang_nrf24l01.ino | 2 +- Multiprotocol/CC2500_SPI.ino | 8 +- Multiprotocol/CG023_nrf24l01.ino | 2 +- Multiprotocol/CX10_nrf24l01.ino | 8 +- Multiprotocol/CYRF6936_SPI.ino | 67 ++- Multiprotocol/DSM_cyrf6936.ino | 620 ++++++++++++++++++++++++++++ Multiprotocol/Devo_cyrf6936.ino | 26 +- Multiprotocol/ESky_nrf24l01.ino | 4 +- Multiprotocol/FY326_nrf24l01.ino | 4 +- Multiprotocol/FlySky_a7105.ino | 69 ++-- Multiprotocol/FrSkyD_cc2500.ino | 27 +- Multiprotocol/FrSkyV_cc2500.ino | 2 + Multiprotocol/FrSkyX_cc2500.ino | 17 +- Multiprotocol/Hisky_nrf24l01.ino | 3 +- Multiprotocol/Hontai_nrf24l01.ino | 2 +- Multiprotocol/Hubsan_a7105.ino | 2 - Multiprotocol/J6Pro_cyrf6936.ino | 33 +- Multiprotocol/KN_nrf24l01.ino | 4 +- Multiprotocol/MJXQ_nrf24l01.ino | 78 ++-- Multiprotocol/MT99xx_nrf24l01.ino | 81 ++-- Multiprotocol/MultiOrange.cpp.xmega | 354 +--------------- Multiprotocol/NRF24l01_SPI.ino | 81 +++- Multiprotocol/SFHSS_cc2500.ino | 60 ++- Multiprotocol/SHENQI_nrf24l01.ino | 8 +- Multiprotocol/SLT_nrf24l01.ino | 6 +- Multiprotocol/Symax_nrf24l01.ino | 2 +- Multiprotocol/V2X2_nrf24l01.ino | 4 +- Multiprotocol/YD717_nrf24l01.ino | 98 +---- 29 files changed, 980 insertions(+), 712 deletions(-) create mode 100644 Multiprotocol/DSM_cyrf6936.ino diff --git a/Multiprotocol/ASSAN_nrf24l01.ino b/Multiprotocol/ASSAN_nrf24l01.ino index dccbfd4..684f654 100644 --- a/Multiprotocol/ASSAN_nrf24l01.ino +++ b/Multiprotocol/ASSAN_nrf24l01.ino @@ -74,17 +74,17 @@ uint16_t ASSAN_callback() NRF24L01_SetTxRxMode(RX_EN); phase++; case ASSAN_BIND1: - //Wait for RX to send the frames - if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR)) + //Wait for receiver to send the frames + if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) { //Something has been received NRF24L01_ReadPayload(packet, ASSAN_PACKET_SIZE); if(packet[19]==0x13) - { //Last packet received + { //Last frame received phase++; //Switch to TX NRF24L01_SetTxRxMode(TXRX_OFF); NRF24L01_SetTxRxMode(TX_EN); - //Prepare packet + //Prepare bind packet memset(packet,0x05,ASSAN_PACKET_SIZE-5); packet[15]=0x99; for(uint8_t i=0;i<4;i++) @@ -134,7 +134,7 @@ uint16_t ASSAN_callback() static void __attribute__((unused)) ASSAN_initialize_txid() { -/* //Renaud TXID with Freq=36 and alternate freq 67 or 68 or 69 or 70 or 71 or 73 or 74 or 75 or 78 and may be more... +/* //Renaud TXID with Freq=36 and alternate Freq 67 or 68 or 69 or 70 or 71 or 73 or 74 or 75 or 78 and may be more... packet[23]=0x22; packet[22]=0x37; packet[21]=0xFA; @@ -153,19 +153,15 @@ static void __attribute__((unused)) ASSAN_initialize_txid() freq=((freq%25)+2)<<1; if(freq&0x02) freq|=0x01; hopping_frequency[0]=freq; - // Alternate frequency - hopping_frequency[1]=freq*2-6; + // Alternate frequency has some random do { #if defined STM32_board randomSeed((uint32_t)analogRead(PB0) << 10 | analogRead(PB1)); - #else - randomSeed((uint32_t)analogRead(A6) << 10 | analogRead(A7)); - #endif +#endif freq2=random(0xfefefefe)%9; freq2+=freq*2-5; } - while( (freq2>118) || (freq2. + */ + +#if defined(DSM_CYRF6936_INO) + +#include "iface_cyrf6936.h" + +#define DSM_BIND_CHANNEL 0x0d //13 This can be any odd channel + +//During binding we will send BIND_COUNT/2 packets +//One packet each 10msec +#define DSM_BIND_COUNT 300 + +enum { + DSM_BIND_WRITE=0, + DSM_BIND_CHECK, + DSM_BIND_READ, + DSM_CHANSEL, + DSM_CH1_WRITE_A, + DSM_CH1_CHECK_A, + DSM_CH2_WRITE_A, + DSM_CH2_CHECK_A, + DSM_CH2_READ_A, + DSM_CH1_WRITE_B, + DSM_CH1_CHECK_B, + DSM_CH2_WRITE_B, + DSM_CH2_CHECK_B, + DSM_CH2_READ_B, +}; + +// +uint8_t sop_col; +uint8_t DSM_orx=0; +uint8_t DSM_num_ch=0; +uint8_t ch_map[14]; +const uint8_t PROGMEM ch_map_progmem[][12] = { + {0, 1, 2, 3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, //Guess + {0, 1, 2, 3, 4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, //Guess + {1, 5, 2, 3, 0, 4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, //HP6DSM + {1, 5, 2, 4, 3, 6, 0, 0xff, 0xff, 0xff, 0xff, 0xff}, //DX6i + {1, 5, 2, 3, 6, 0xff, 0xff, 4, 0, 7, 0xff, 0xff}, //DX8 + {3, 2, 1, 5, 0, 4, 6, 7, 8, 0xff, 0xff, 0xff}, //DM9 + {3, 2, 1, 5, 0, 4, 6, 7, 8, 9, 0xff, 0xff}, //Guess + {3, 2, 1, 5, 0, 4, 6, 7, 8, 9, 10, 0xff}, //Guess + {3, 2, 1, 5, 0, 4, 6, 7, 8, 9, 10, 11} }; //Guess + +const uint8_t PROGMEM pncodes[5][9][8] = { + /* Note these are in order transmitted (LSB 1st) */ + { /* Row 0 */ + /* Col 0 */ {0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8}, + /* Col 1 */ {0x88, 0x17, 0x13, 0x3B, 0x2D, 0xBF, 0x06, 0xD6}, + /* Col 2 */ {0xF1, 0x94, 0x30, 0x21, 0xA1, 0x1C, 0x88, 0xA9}, + /* Col 3 */ {0xD0, 0xD2, 0x8E, 0xBC, 0x82, 0x2F, 0xE3, 0xB4}, + /* Col 4 */ {0x8C, 0xFA, 0x47, 0x9B, 0x83, 0xA5, 0x66, 0xD0}, + /* Col 5 */ {0x07, 0xBD, 0x9F, 0x26, 0xC8, 0x31, 0x0F, 0xB8}, + /* Col 6 */ {0xEF, 0x03, 0x95, 0x89, 0xB4, 0x71, 0x61, 0x9D}, + /* Col 7 */ {0x40, 0xBA, 0x97, 0xD5, 0x86, 0x4F, 0xCC, 0xD1}, + /* Col 8 */ {0xD7, 0xA1, 0x54, 0xB1, 0x5E, 0x89, 0xAE, 0x86} + }, + { /* Row 1 */ + /* Col 0 */ {0x83, 0xF7, 0xA8, 0x2D, 0x7A, 0x44, 0x64, 0xD3}, + /* Col 1 */ {0x3F, 0x2C, 0x4E, 0xAA, 0x71, 0x48, 0x7A, 0xC9}, + /* Col 2 */ {0x17, 0xFF, 0x9E, 0x21, 0x36, 0x90, 0xC7, 0x82}, + /* Col 3 */ {0xBC, 0x5D, 0x9A, 0x5B, 0xEE, 0x7F, 0x42, 0xEB}, + /* Col 4 */ {0x24, 0xF5, 0xDD, 0xF8, 0x7A, 0x77, 0x74, 0xE7}, + /* Col 5 */ {0x3D, 0x70, 0x7C, 0x94, 0xDC, 0x84, 0xAD, 0x95}, + /* Col 6 */ {0x1E, 0x6A, 0xF0, 0x37, 0x52, 0x7B, 0x11, 0xD4}, + /* Col 7 */ {0x62, 0xF5, 0x2B, 0xAA, 0xFC, 0x33, 0xBF, 0xAF}, + /* Col 8 */ {0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97} + }, + { /* Row 2 */ + /* Col 0 */ {0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97}, + /* Col 1 */ {0x8E, 0x4A, 0xD0, 0xA9, 0xA7, 0xFF, 0x20, 0xCA}, + /* Col 2 */ {0x4C, 0x97, 0x9D, 0xBF, 0xB8, 0x3D, 0xB5, 0xBE}, + /* Col 3 */ {0x0C, 0x5D, 0x24, 0x30, 0x9F, 0xCA, 0x6D, 0xBD}, + /* Col 4 */ {0x50, 0x14, 0x33, 0xDE, 0xF1, 0x78, 0x95, 0xAD}, + /* Col 5 */ {0x0C, 0x3C, 0xFA, 0xF9, 0xF0, 0xF2, 0x10, 0xC9}, + /* Col 6 */ {0xF4, 0xDA, 0x06, 0xDB, 0xBF, 0x4E, 0x6F, 0xB3}, + /* Col 7 */ {0x9E, 0x08, 0xD1, 0xAE, 0x59, 0x5E, 0xE8, 0xF0}, + /* Col 8 */ {0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E} + }, + { /* Row 3 */ + /* Col 0 */ {0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E}, + /* Col 1 */ {0x80, 0x69, 0x26, 0x80, 0x08, 0xF8, 0x49, 0xE7}, + /* Col 2 */ {0x7D, 0x2D, 0x49, 0x54, 0xD0, 0x80, 0x40, 0xC1}, + /* Col 3 */ {0xB6, 0xF2, 0xE6, 0x1B, 0x80, 0x5A, 0x36, 0xB4}, + /* Col 4 */ {0x42, 0xAE, 0x9C, 0x1C, 0xDA, 0x67, 0x05, 0xF6}, + /* Col 5 */ {0x9B, 0x75, 0xF7, 0xE0, 0x14, 0x8D, 0xB5, 0x80}, + /* Col 6 */ {0xBF, 0x54, 0x98, 0xB9, 0xB7, 0x30, 0x5A, 0x88}, + /* Col 7 */ {0x35, 0xD1, 0xFC, 0x97, 0x23, 0xD4, 0xC9, 0x88}, + /* Col 8 */ {0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40, 0x93} +// Wrong values used by Orange TX/RX +// /* Col 8 */ {0x88, 0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40} + }, + { /* Row 4 */ + /* Col 0 */ {0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40, 0x93}, + /* Col 1 */ {0xDC, 0x68, 0x08, 0x99, 0x97, 0xAE, 0xAF, 0x8C}, + /* Col 2 */ {0xC3, 0x0E, 0x01, 0x16, 0x0E, 0x32, 0x06, 0xBA}, + /* Col 3 */ {0xE0, 0x83, 0x01, 0xFA, 0xAB, 0x3E, 0x8F, 0xAC}, + /* Col 4 */ {0x5C, 0xD5, 0x9C, 0xB8, 0x46, 0x9C, 0x7D, 0x84}, + /* Col 5 */ {0xF1, 0xC6, 0xFE, 0x5C, 0x9D, 0xA5, 0x4F, 0xB7}, + /* Col 6 */ {0x58, 0xB5, 0xB3, 0xDD, 0x0E, 0x28, 0xF1, 0xB0}, + /* Col 7 */ {0x5F, 0x30, 0x3B, 0x56, 0x96, 0x45, 0xF4, 0xA1}, + /* Col 8 */ {0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8} + }, +}; + +static void __attribute__((unused)) read_code(uint8_t *buf, uint8_t row, uint8_t col, uint8_t len) +{ + if(DSM_orx==1 && row==3 && col==7 && len==16) + { + uint8_t dec=0; + for(uint8_t i=0;i> 8; + packet[9] = sum & 0xff; + packet[10] = 0x01; //??? + packet[11] = DSM_num_ch; + + if (sub_protocol==DSM2_22) + packet[12]=DSM_num_ch<8?0x01:0x02; // DSM2/1024 1 or 2 packets depending on the number of channels + if(sub_protocol==DSM2_11) + packet[12]=0x12; // DSM2/2048 2 packets + if(sub_protocol==DSMX_22) + #if defined DSM_TELEMETRY + packet[12] = 0xb2; // DSMX/2048 2 packets + #else + packet[12] = DSM_num_ch<8? 0xa2 : 0xb2; // DSMX/2048 1 or 2 packets depending on the number of channels + #endif + if(sub_protocol==DSMX_11 || sub_protocol==DSM_AUTO) // Force DSMX/1024 in mode Auto + packet[12]=0xb2; // DSMX/1024 2 packets + + packet[13] = 0x00; //??? + for(i = 8; i < 14; i++) + sum += packet[i]; + packet[14] = sum >> 8; + packet[15] = sum & 0xff; +} + +static void __attribute__((unused)) initialize_bind_phase() +{ + uint8_t code[32]; + + CYRF_ConfigRFChannel(DSM_BIND_CHANNEL); //This seems to be random? + uint8_t pn_row = get_pn_row(DSM_BIND_CHANNEL); + //printf("Ch: %d Row: %d SOP: %d Data: %d\n", DSM_BIND_CHANNEL, pn_row, sop_col, 7 - sop_col); + CYRF_ConfigCRCSeed(crc); + + read_code(code,pn_row,sop_col,8); + CYRF_ConfigSOPCode(code); + read_code(code,pn_row,7 - sop_col,16); + read_code(code+16,0,8,8); + memcpy(code + 24, (void *)"\xc6\x94\x22\xfe\x48\xe6\x57\x4e", 8); + CYRF_ConfigDataCode(code, 32); + + build_bind_packet(); +} + +const uint8_t PROGMEM data_vals[][2] = { + {CYRF_05_RX_CTRL, 0x83}, //Initialize for reading RSSI + {CYRF_29_RX_ABORT, 0x20}, + {CYRF_0F_XACT_CFG, 0x24}, + {CYRF_29_RX_ABORT, 0x00}, + {CYRF_03_TX_CFG, 0x08 | CYRF_HIGH_POWER}, + {CYRF_10_FRAMING_CFG, 0xea}, + {CYRF_1F_TX_OVERRIDE, 0x00}, + {CYRF_1E_RX_OVERRIDE, 0x00}, + {CYRF_03_TX_CFG, 0x28 | CYRF_HIGH_POWER}, + {CYRF_12_DATA64_THOLD, 0x3f}, + {CYRF_10_FRAMING_CFG, 0xff}, + {CYRF_0F_XACT_CFG, 0x24}, //Switch from reading RSSI to Writing + {CYRF_29_RX_ABORT, 0x00}, + {CYRF_12_DATA64_THOLD, 0x0a}, + {CYRF_10_FRAMING_CFG, 0xea}, +}; + +static void __attribute__((unused)) cyrf_configdata() +{ + for(uint8_t i = 0; i < sizeof(data_vals) / 2; i++) + CYRF_WriteRegister(pgm_read_byte_near(&data_vals[i][0]), pgm_read_byte_near(&data_vals[i][1])); +} + +static void __attribute__((unused)) update_channels() +{ + prev_option=option; + if(sub_protocol==DSM_AUTO) + DSM_num_ch=12; // Force 12 channels in mode Auto + else + if(option&0x80) + { + DSM_num_ch=-option; + DSM_orx=1; // Use orange table + } + else + { + DSM_num_ch=option; + DSM_orx=0; // Use normal table + } + if(DSM_num_ch<4 || DSM_num_ch>12) + DSM_num_ch=6; // Default to 6 channels if invalid choice... + + // Create channel map based on number of channels + for(uint8_t i=0;i<12;i++) + ch_map[i]=pgm_read_byte_near(&ch_map_progmem[DSM_num_ch-4][i]); + ch_map[12]=0xFF; + ch_map[13]=0xFF; + // TODO: if DSM2_11 or DSMX_11 then repeat lower channels to upper channels need to rewrite this part + if(DSM_num_ch<8) + for(uint8_t i=7;i<14;i++) + ch_map[i]=ch_map[i-7]; +} + +static void __attribute__((unused)) build_data_packet(uint8_t upper) +{ + uint16_t max = 2047; + uint8_t bits = 11; + + if(prev_option!=option) + update_channels(); + + if (sub_protocol==DSMX_11 || sub_protocol==DSMX_22 ) + { + packet[0] = cyrfmfg_id[2]; + packet[1] = cyrfmfg_id[3]; + } + else + { + packet[0] = (0xff ^ cyrfmfg_id[2]); + packet[1] = (0xff ^ cyrfmfg_id[3]); + if(sub_protocol==DSM2_22) + { + max=1023; // Only DSM_22 is using a resolution of 1024 + bits=10; + } + } + + for (uint8_t i = 0; i < 7; i++) + { + uint8_t idx = ch_map[(upper?7:0) + i];//1,5,2,3,0,4 + uint16_t value = 0xffff;; + if (idx != 0xff) + { + if (!IS_BIND_DONE_on) + { // Failsafe position during binding + value=max/2; //all channels to middle + if(idx==0) + value=1; //except throttle + } + else + value=map(Servo_data[CH_TAER[idx]],servo_min_125,servo_max_125,0,max); + value |= (upper ? 0x8000 : 0) | (idx << bits); + } + packet[i*2+2] = (value >> 8) & 0xff; + packet[i*2+3] = (value >> 0) & 0xff; + } +} + +static void __attribute__((unused)) set_sop_data_crc() +{ + //The crc for channel '1' is NOT(mfgid[0] << 8 + mfgid[1]) + //The crc for channel '2' is (mfgid[0] << 8 + mfgid[1]) + uint16_t crc = (cyrfmfg_id[0] << 8) + cyrfmfg_id[1]; + if(phase==DSM_CH1_CHECK_A||phase==DSM_CH1_CHECK_B) + CYRF_ConfigCRCSeed(crc); //CH2 + else + CYRF_ConfigCRCSeed(~crc); //CH1 + + uint8_t pn_row = get_pn_row(hopping_frequency[hopping_frequency_no]); + uint8_t code[16]; + read_code(code,pn_row,sop_col,8); + CYRF_ConfigSOPCode(code); + read_code(code,pn_row,7 - sop_col,16); + CYRF_ConfigDataCode(code, 16); + + CYRF_ConfigRFChannel(hopping_frequency[hopping_frequency_no]); + hopping_frequency_no++; + if(sub_protocol == DSMX_11 || sub_protocol == DSMX_22) + hopping_frequency_no %=23; + else + hopping_frequency_no %=2; +} + +static void __attribute__((unused)) calc_dsmx_channel() +{ + uint8_t idx = 0; + uint32_t id = ~(((uint32_t)cyrfmfg_id[0] << 24) | ((uint32_t)cyrfmfg_id[1] << 16) | ((uint32_t)cyrfmfg_id[2] << 8) | (cyrfmfg_id[3] << 0)); + uint32_t id_tmp = id; + while(idx < 23) + { + uint8_t i; + uint8_t count_3_27 = 0, count_28_51 = 0, count_52_76 = 0; + id_tmp = id_tmp * 0x0019660D + 0x3C6EF35F; // Randomization + uint8_t next_ch = ((id_tmp >> 8) % 0x49) + 3; // Use least-significant byte and must be larger than 3 + if ( (next_ch ^ cyrfmfg_id[3]) & 0x01 ) + continue; + for (i = 0; i < idx; i++) + { + if(hopping_frequency[i] == next_ch) + break; + if(hopping_frequency[i] <= 27) + count_3_27++; + else + if (hopping_frequency[i] <= 51) + count_28_51++; + else + count_52_76++; + } + if (i != idx) + continue; + if ((next_ch < 28 && count_3_27 < 8) + ||(next_ch >= 28 && next_ch < 52 && count_28_51 < 7) + ||(next_ch >= 52 && count_52_76 < 8)) + hopping_frequency[idx++] = next_ch; + } +} + +static uint8_t __attribute__((unused)) DSM_Check_RX_packet() +{ + uint8_t result=1; // assume good packet + + uint16_t sum = 384 - 0x10; + for(uint8_t i = 1; i < 9; i++) + { + sum += pkt[i]; + if(i<5) + if(pkt[i] != (0xff ^ cyrfmfg_id[i-1])) + result=0; // bad packet + } + if( pkt[9] != (sum>>8) && pkt[10] != (uint8_t)sum ) + result=0; + return result; +} + +uint16_t ReadDsm() +{ +#define DSM_CH1_CH2_DELAY 4010 // Time between write of channel 1 and channel 2 +#define DSM_WRITE_DELAY 1550 // Time after write to verify write complete +#define DSM_READ_DELAY 600 // Time before write to check read phase, and switch channels. Was 400 but 600 seems what the 328p needs to read a packet + uint16_t start; + #if defined DSM_TELEMETRY + uint8_t rx_phase; + uint8_t len; + #endif + + switch(phase) + { + case DSM_BIND_WRITE: + if(bind_counter--==0) + #if defined DSM_TELEMETRY + phase=DSM_BIND_CHECK; //Check RX answer + #else + phase=DSM_CHANSEL; //Switch to normal mode + #endif + CYRF_WriteDataPacket(packet); + return 10000; + #if defined DSM_TELEMETRY + case DSM_BIND_CHECK: + CYRF_ConfigDataCode((const uint8_t *)"\x98\x88\x1B\xE4\x30\x79\x03\x84\xC9\x2C\x06\x93\x86\xB9\x9E", 16); + CYRF_SetTxRxMode(RX_EN); //Receive mode + CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x83); //Prepare to receive + bind_counter=300; + phase++; // change from BIND_CHECK to BIND_READ + return 2000; + case DSM_BIND_READ: + //Read data from RX + rx_phase = CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS); + if((rx_phase & 0x03) == 0x02) // RXC=1, RXE=0 then 2nd check is required (debouncing) + rx_phase |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS); + if((rx_phase & 0x07) == 0x02) + { // data received + CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // need to set RXOW before data read + len=CYRF_ReadRegister(CYRF_09_RX_COUNT); + if(len>MAX_PKT-2) + len=MAX_PKT-2; + CYRF_ReadDataPacketLen(pkt+1, len); + if(len==10 && DSM_Check_RX_packet()) + { + pkt[0]=0x80; + telemetry_link=1; // send received data on serial + CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20); + CYRF_SetTxRxMode(TX_EN); // Write mode + phase++; + return 2000; + } + } + //Force end read phase + CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x2C); // Force end phase + start=micros(); + while ((uint16_t)micros()-start < 100) // Wait max 100 µs + if((CYRF_ReadRegister(CYRF_0F_XACT_CFG) & 0x20) == 0) + break; + if( --bind_counter == 0 ) + { + phase++; // Exit if no answer has been received for some time + return 7000 ; + } + CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x0C); // Read mode + CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x83); // Prepare to receive + return 7000; + #endif + case DSM_CHANSEL: + BIND_DONE; + cyrf_configdata(); + CYRF_SetTxRxMode(TX_EN); + hopping_frequency_no = 0; + phase = DSM_CH1_WRITE_A; // in fact phase++ + set_sop_data_crc(); + return 10000; + case DSM_CH1_WRITE_A: + case DSM_CH1_WRITE_B: + case DSM_CH2_WRITE_A: + case DSM_CH2_WRITE_B: + build_data_packet(phase == DSM_CH1_WRITE_B||phase == DSM_CH2_WRITE_B); // build lower or upper channels + CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS); // clear IRQ flags + CYRF_WriteDataPacket(packet); + phase++; // change from WRITE to CHECK mode + return DSM_WRITE_DELAY; + case DSM_CH1_CHECK_A: + case DSM_CH1_CHECK_B: + start=micros(); + while ((uint16_t)micros()-start < 500) // Wait max 500µs + if(CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x02) + break; + set_sop_data_crc(); + phase++; // change from CH1_CHECK to CH2_WRITE + return DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY; + case DSM_CH2_CHECK_A: + case DSM_CH2_CHECK_B: + start=micros(); + while ((uint16_t)micros()-start < 500) // Wait max 500µs + if(CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x02) + break; + if (phase == DSM_CH2_CHECK_A) + CYRF_SetPower(0x28); //Keep transmit power in sync +#if defined DSM_TELEMETRY + phase++; // change from CH2_CHECK to CH2_READ + CYRF_SetTxRxMode(RX_EN); //Receive mode + CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //0x80??? //Prepare to receive + return 11000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY - DSM_READ_DELAY; + case DSM_CH2_READ_A: + case DSM_CH2_READ_B: + //Read telemetry + rx_phase = CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS); + if((rx_phase & 0x03) == 0x02) // RXC=1, RXE=0 then 2nd check is required (debouncing) + rx_phase |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS); + if((rx_phase & 0x07) == 0x02) + { // good data (complete with no errors) + CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // need to set RXOW before data read + len=CYRF_ReadRegister(CYRF_09_RX_COUNT); + if(len>MAX_PKT-2) + len=MAX_PKT-2; + CYRF_ReadDataPacketLen(pkt+1, len); + pkt[0]=CYRF_ReadRegister(CYRF_13_RSSI)&0x1F;// store RSSI of the received telemetry signal + telemetry_link=1; + } + if (phase == DSM_CH2_READ_A && (sub_protocol==DSM2_22 || sub_protocol==DSMX_22) && DSM_num_ch < 8) // 22ms mode + { + //Force end read phase + CYRF_WriteRegister(CYRF_0F_XACT_CFG, (CYRF_ReadRegister(CYRF_0F_XACT_CFG) | 0x20)); // Force end phase + start=micros(); + while ((uint16_t)micros()-start < 100) // Wait max 100 µs + if((CYRF_ReadRegister(CYRF_0F_XACT_CFG) & 0x20) == 0) + break; + phase = DSM_CH2_READ_B; + CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //0x80??? //Prepare to receive + return 11000; + } + if (phase == DSM_CH2_READ_A) + phase = DSM_CH1_WRITE_B; //Transmit upper + else + phase = DSM_CH1_WRITE_A; //Transmit lower + CYRF_SetTxRxMode(TX_EN); //Write mode + set_sop_data_crc(); + return DSM_READ_DELAY; +#else + // No telemetry + set_sop_data_crc(); + if (phase == DSM_CH2_CHECK_A) + { + if(DSM_num_ch > 7 || sub_protocol==DSM2_11 || sub_protocol==DSMX_11) + phase = DSM_CH1_WRITE_B; //11ms mode or upper to transmit change from CH2_CHECK_A to CH1_WRITE_A + else + { //Normal mode 22ms + phase = DSM_CH1_WRITE_A; // change from CH2_CHECK_A to CH1_WRITE_A (ie no upper) + return 22000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY ; + } + } + else + phase = DSM_CH1_WRITE_A; // change from CH2_CHECK_B to CH1_WRITE_A (upper already transmitted so transmit lower) + return 11000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY; +#endif + } + return 0; +} + +uint16_t initDsm() +{ + CYRF_GetMfgData(cyrfmfg_id);// + //Model match + cyrfmfg_id[3]+=RX_num; + + cyrf_config(); + + if (sub_protocol == DSMX_11 || sub_protocol == DSMX_22) + calc_dsmx_channel(); + else + { + uint8_t tmpch[10]; + CYRF_FindBestChannels(tmpch, 10, 5, 3, 75); + // + uint8_t idx = random(0xfefefefe) % 10; + hopping_frequency[0] = tmpch[idx]; + while(1) + { + idx = random(0xfefefefe) % 10; + if (tmpch[idx] != hopping_frequency[0]) + break; + } + hopping_frequency[1] = tmpch[idx]; + } + + // + sop_col = (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + 2) & 0x07; + + CYRF_SetTxRxMode(TX_EN); + // + update_channels(); + if(IS_AUTOBIND_FLAG_on ) + { + BIND_IN_PROGRESS; + initialize_bind_phase(); + phase = DSM_BIND_WRITE; + bind_counter=DSM_BIND_COUNT; + } + else + phase = DSM_CHANSEL;// + return 10000; +} + +#endif \ No newline at end of file diff --git a/Multiprotocol/Devo_cyrf6936.ino b/Multiprotocol/Devo_cyrf6936.ino index df8b845..300c251 100644 --- a/Multiprotocol/Devo_cyrf6936.ino +++ b/Multiprotocol/Devo_cyrf6936.ino @@ -43,28 +43,6 @@ enum { DEVO_BOUND_10, }; -const uint8_t PROGMEM DEVO_sopcodes[][8] = { - /* Note these are in order transmitted (LSB 1st) */ - /* 0 */ {0x3C,0x37,0xCC,0x91,0xE2,0xF8,0xCC,0x91}, //0x91CCF8E291CC373C - /* 1 */ {0x9B,0xC5,0xA1,0x0F,0xAD,0x39,0xA2,0x0F}, //0x0FA239AD0FA1C59B - /* 2 */ {0xEF,0x64,0xB0,0x2A,0xD2,0x8F,0xB1,0x2A}, //0x2AB18FD22AB064EF - /* 3 */ {0x66,0xCD,0x7C,0x50,0xDD,0x26,0x7C,0x50}, //0x507C26DD507CCD66 - /* 4 */ {0x5C,0xE1,0xF6,0x44,0xAD,0x16,0xF6,0x44}, //0x44F616AD44F6E15C - /* 5 */ {0x5A,0xCC,0xAE,0x46,0xB6,0x31,0xAE,0x46}, //0x46AE31B646AECC5A - /* 6 */ {0xA1,0x78,0xDC,0x3C,0x9E,0x82,0xDC,0x3C}, //0x3CDC829E3CDC78A1 - /* 7 */ {0xB9,0x8E,0x19,0x74,0x6F,0x65,0x18,0x74}, //0x7418656F74198EB9 - /* 8 */ {0xDF,0xB1,0xC0,0x49,0x62,0xDF,0xC1,0x49}, //0x49C1DF6249C0B1DF - /* 9 */ {0x97,0xE5,0x14,0x72,0x7F,0x1A,0x14,0x72}, //0x72141A7F7214E597 -}; - -static void __attribute__((unused)) DEVO_ConfigSOPCode(uint8_t val) -{ - uint8_t code[8]; - for(uint8_t i=0;i<8;i++) - code[i]=pgm_read_byte_near(&DEVO_sopcodes[val][i]); - CYRF_ConfigSOPCode(code); -} - static void __attribute__((unused)) DEVO_scramble_pkt() { #ifdef NO_SCRAMBLE @@ -185,7 +163,7 @@ static void __attribute__((unused)) DEVO_cyrf_set_bound_sop_code() uint8_t sopidx = (0xff &((cyrfmfg_id[0] << 2) + cyrfmfg_id[1] + cyrfmfg_id[2])) % 10; CYRF_SetTxRxMode(TX_EN); CYRF_ConfigCRCSeed((crc << 8) + crc); - DEVO_ConfigSOPCode(sopidx); + CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[sopidx]); CYRF_SetPower(0x08); } @@ -317,7 +295,7 @@ uint16_t DevoInit() CYRF_GetMfgData(cyrfmfg_id); CYRF_SetTxRxMode(TX_EN); CYRF_ConfigCRCSeed(0x0000); - DEVO_ConfigSOPCode(0); + CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[0]); DEVO_set_radio_channels(); hopping_frequency_ptr = hopping_frequency; diff --git a/Multiprotocol/ESky_nrf24l01.ino b/Multiprotocol/ESky_nrf24l01.ino index 4204fae..80fdd85 100644 --- a/Multiprotocol/ESky_nrf24l01.ino +++ b/Multiprotocol/ESky_nrf24l01.ino @@ -35,7 +35,7 @@ static void __attribute__((unused)) ESKY_init(uint8_t bind) NRF24L01_Initialize(); // 2-bytes CRC, radio off - NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO)); + NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)); NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgement NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 if (bind) @@ -167,4 +167,4 @@ uint16_t initESKY(void) return 50000; } -#endif +#endif \ No newline at end of file diff --git a/Multiprotocol/FY326_nrf24l01.ino b/Multiprotocol/FY326_nrf24l01.ino index ccd640f..41837d8 100644 --- a/Multiprotocol/FY326_nrf24l01.ino +++ b/Multiprotocol/FY326_nrf24l01.ino @@ -105,7 +105,7 @@ uint16_t FY326_callback() switch (phase) { case FY326_BIND1: - if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR)) + if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) { // RX fifo data ready NRF24L01_ReadPayload(packet, FY326_PACKET_SIZE); rxid = packet[13]; @@ -127,7 +127,7 @@ uint16_t FY326_callback() } break; case FY326_BIND2: - if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_TX_DS)) + if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS)) { // TX data sent -> switch to RX mode NRF24L01_SetTxRxMode(TXRX_OFF); NRF24L01_FlushRx(); diff --git a/Multiprotocol/FlySky_a7105.ino b/Multiprotocol/FlySky_a7105.ino index 1601486..fb86783 100644 --- a/Multiprotocol/FlySky_a7105.ino +++ b/Multiprotocol/FlySky_a7105.ino @@ -50,16 +50,11 @@ enum { FLAG_V912_BTMBTN= 0x80, }; -uint8_t chanrow; -uint8_t chancol; -uint8_t chanoffset; - const uint8_t PROGMEM V912_X17_SEQ[10] = { 0x14, 0x31, 0x40, 0x49, 0x49, // sometime first byte is 0x15 ? 0x49, 0x49, 0x49, 0x49, 0x49, }; static void __attribute__((unused)) flysky_apply_extension_flags() { - static uint8_t seq_counter; switch(sub_protocol) { @@ -144,34 +139,14 @@ static void __attribute__((unused)) flysky_build_packet(uint8_t init) packet[2] = rx_tx_addr[2]; packet[3] = rx_tx_addr[1]; packet[4] = rx_tx_addr[0]; - const uint8_t ch[]={AILERON, ELEVATOR, THROTTLE, RUDDER, AUX1, AUX2, AUX3, AUX4}; for(i = 0; i < 8; i++) { - packet[5 + i*2]=Servo_data[ch[i]]&0xFF; //low byte of servo timing(1000-2000us) - packet[6 + i*2]=(Servo_data[ch[i]]>>8)&0xFF; //high byte of servo timing(1000-2000us) + packet[5 + i*2]=Servo_data[CH_AETR[i]]&0xFF; //low byte of servo timing(1000-2000us) + packet[6 + i*2]=(Servo_data[CH_AETR[i]]>>8)&0xFF; //high byte of servo timing(1000-2000us) } flysky_apply_extension_flags(); } -const uint8_t PROGMEM tx_channels[16][16] = { - {0x0a, 0x5a, 0x14, 0x64, 0x1e, 0x6e, 0x28, 0x78, 0x32, 0x82, 0x3c, 0x8c, 0x46, 0x96, 0x50, 0xa0}, - {0xa0, 0x50, 0x96, 0x46, 0x8c, 0x3c, 0x82, 0x32, 0x78, 0x28, 0x6e, 0x1e, 0x64, 0x14, 0x5a, 0x0a}, - {0x0a, 0x5a, 0x50, 0xa0, 0x14, 0x64, 0x46, 0x96, 0x1e, 0x6e, 0x3c, 0x8c, 0x28, 0x78, 0x32, 0x82}, - {0x82, 0x32, 0x78, 0x28, 0x8c, 0x3c, 0x6e, 0x1e, 0x96, 0x46, 0x64, 0x14, 0xa0, 0x50, 0x5a, 0x0a}, - {0x28, 0x78, 0x0a, 0x5a, 0x50, 0xa0, 0x14, 0x64, 0x1e, 0x6e, 0x3c, 0x8c, 0x32, 0x82, 0x46, 0x96}, - {0x96, 0x46, 0x82, 0x32, 0x8c, 0x3c, 0x6e, 0x1e, 0x64, 0x14, 0xa0, 0x50, 0x5a, 0x0a, 0x78, 0x28}, - {0x50, 0xa0, 0x28, 0x78, 0x0a, 0x5a, 0x1e, 0x6e, 0x3c, 0x8c, 0x32, 0x82, 0x46, 0x96, 0x14, 0x64}, - {0x64, 0x14, 0x96, 0x46, 0x82, 0x32, 0x8c, 0x3c, 0x6e, 0x1e, 0x5a, 0x0a, 0x78, 0x28, 0xa0, 0x50}, - {0x50, 0xa0, 0x46, 0x96, 0x3c, 0x8c, 0x28, 0x78, 0x0a, 0x5a, 0x32, 0x82, 0x1e, 0x6e, 0x14, 0x64}, - {0x64, 0x14, 0x6e, 0x1e, 0x82, 0x32, 0x5a, 0x0a, 0x78, 0x28, 0x8c, 0x3c, 0x96, 0x46, 0xa0, 0x50}, - {0x46, 0x96, 0x3c, 0x8c, 0x50, 0xa0, 0x28, 0x78, 0x0a, 0x5a, 0x1e, 0x6e, 0x32, 0x82, 0x14, 0x64}, - {0x64, 0x14, 0x82, 0x32, 0x6e, 0x1e, 0x5a, 0x0a, 0x78, 0x28, 0xa0, 0x50, 0x8c, 0x3c, 0x96, 0x46}, - {0x46, 0x96, 0x0a, 0x5a, 0x3c, 0x8c, 0x14, 0x64, 0x50, 0xa0, 0x28, 0x78, 0x1e, 0x6e, 0x32, 0x82}, - {0x82, 0x32, 0x6e, 0x1e, 0x78, 0x28, 0xa0, 0x50, 0x64, 0x14, 0x8c, 0x3c, 0x5a, 0x0a, 0x96, 0x46}, - {0x46, 0x96, 0x0a, 0x5a, 0x50, 0xa0, 0x3c, 0x8c, 0x28, 0x78, 0x1e, 0x6e, 0x32, 0x82, 0x14, 0x64}, - {0x64, 0x14, 0x82, 0x32, 0x6e, 0x1e, 0x78, 0x28, 0x8c, 0x3c, 0xa0, 0x50, 0x5a, 0x0a, 0x96, 0x46}, -}; - uint16_t ReadFlySky() { if (bind_counter) @@ -185,28 +160,56 @@ uint16_t ReadFlySky() else { flysky_build_packet(0); - A7105_WriteData(21, pgm_read_byte_near(&tx_channels[chanrow][chancol])-chanoffset); - chancol = (chancol + 1) % 16; - if (! chancol) //Keep transmit power updated + A7105_WriteData(21, hopping_frequency[hopping_frequency_no]); + hopping_frequency_no = (hopping_frequency_no + 1) & 0x0F; A7105_SetPower(); } return 1510; //1460 on deviation but not working with the latest V911 bricks... Turnigy 9X v2 is 1533, Flysky TX for 9XR/9XR Pro is 1510, V911 TX is 1490. } -uint16_t initFlySky() { +const uint8_t PROGMEM tx_channels[8][4] = { + { 0x12, 0x34, 0x56, 0x78}, + { 0x18, 0x27, 0x36, 0x45}, + { 0x41, 0x82, 0x36, 0x57}, + { 0x84, 0x13, 0x65, 0x72}, + { 0x87, 0x64, 0x15, 0x32}, + { 0x76, 0x84, 0x13, 0x52}, + { 0x71, 0x62, 0x84, 0x35}, + { 0x71, 0x86, 0x43, 0x52} +}; + +uint16_t initFlySky() +{ + uint8_t chanrow; + uint8_t chanoffset; + uint8_t temp; + A7105_Init(INIT_FLYSKY); //flysky_init(); if ((rx_tx_addr[3]&0xF0) > 0x90) // limit offset to 9 as higher values don't work with some RX (ie V912) rx_tx_addr[3]=rx_tx_addr[3]-0x70; chanrow=rx_tx_addr[3] & 0x0F; - chancol=0; chanoffset=rx_tx_addr[3]/16; + // Build frequency hop table + for(uint8_t i=0;i<16;i++) + { + temp=pgm_read_byte_near(&tx_channels[chanrow>>1][i>>2]); + if(i&0x01) + temp&=0x0F; + else + temp>>=4; + temp*=0x0A; + if(i&0x02) + temp+=0x50; + hopping_frequency[((chanrow&1)?15-i:i)]=temp-chanoffset; + } + hopping_frequency_no=0; + if(IS_AUTOBIND_FLAG_on) bind_counter = FLYSKY_BIND_COUNT; else bind_counter = 0; return 2400; } - #endif diff --git a/Multiprotocol/FrSkyD_cc2500.ino b/Multiprotocol/FrSkyD_cc2500.ino index 740b839..424cda8 100644 --- a/Multiprotocol/FrSkyD_cc2500.ino +++ b/Multiprotocol/FrSkyD_cc2500.ino @@ -13,30 +13,13 @@ along with Multiprotocol. If not, see . */ -#if defined(FRSKY_CC2500_INO) +#if defined(FRSKYD_CC2500_INO) #include "iface_cc2500.h" -//##########Variables######## -//uint32_t state; -//uint8_t len; - -/* -enum { - FRSKY_BIND = 0, - FRSKY_BIND_DONE = 1000, - FRSKY_DATA1, - FRSKY_DATA2, - FRSKY_DATA3, - FRSKY_DATA4, - FRSKY_DATA5 -}; -*/ - static void __attribute__((unused)) frsky2way_init(uint8_t bind) { // Configure cc2500 for tx mode - CC2500_Reset(); // for(uint8_t i=0;i<36;i++) { @@ -51,6 +34,7 @@ static void __attribute__((unused)) frsky2way_init(uint8_t bind) CC2500_WriteReg(reg,val); } prev_option = option ; + CC2500_SetTxRxMode(TX_EN); CC2500_SetPower(); @@ -143,7 +127,7 @@ uint16_t initFrSky_2way() if(IS_AUTOBIND_FLAG_on) { frsky2way_init(1); - state = FRSKY_BIND;// + state = FRSKY_BIND; } else { @@ -206,14 +190,13 @@ uint16_t ReadFrSky_2way() CC2500_SetTxRxMode(TX_EN); CC2500_SetPower(); // Set tx_power } - + CC2500_Strobe(CC2500_SIDLE); + CC2500_WriteReg(CC2500_0A_CHANNR, get_chan_num(counter % 47)); if ( prev_option != option ) { CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack prev_option = option ; } - CC2500_Strobe(CC2500_SIDLE); - CC2500_WriteReg(CC2500_0A_CHANNR, get_chan_num(counter % 47)); CC2500_WriteReg(CC2500_23_FSCAL3, 0x89); CC2500_Strobe(CC2500_SFRX); frsky2way_data_frame(); diff --git a/Multiprotocol/FrSkyV_cc2500.ino b/Multiprotocol/FrSkyV_cc2500.ino index 2c7248e..aaf88a9 100644 --- a/Multiprotocol/FrSkyV_cc2500.ino +++ b/Multiprotocol/FrSkyV_cc2500.ino @@ -3,10 +3,12 @@ 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 . */ diff --git a/Multiprotocol/FrSkyX_cc2500.ino b/Multiprotocol/FrSkyX_cc2500.ino index 3545cf0..471be50 100644 --- a/Multiprotocol/FrSkyX_cc2500.ino +++ b/Multiprotocol/FrSkyX_cc2500.ino @@ -23,7 +23,6 @@ uint8_t chanskip; uint8_t counter_rst; uint8_t ctr; -uint8_t FS_flag=0; uint8_t seq_last_sent; uint8_t seq_last_rcvd; @@ -90,8 +89,6 @@ static void __attribute__((unused)) set_start(uint8_t ch ) static void __attribute__((unused)) frskyX_init() { - CC2500_Reset(); - for(uint8_t i=0;i<36;i++) { uint8_t reg=pgm_read_byte_near(&cc2500_conf[i][0]); @@ -215,10 +212,10 @@ static void __attribute__((unused)) frskyX_data_frame() packet[4] = (ctr<<6)+hopping_frequency_no; packet[5] = counter_rst; packet[6] = RX_num; - //FLAGS 00 - standard packet + //packet[7] = FLAGS 00 - standard packet //10, 12, 14, 16, 18, 1A, 1C, 1E - failsafe packet //20 - range check packet - packet[7] = FS_flag; + packet[7] = 0; packet[8] = 0; // if ( lpass & 1 ) @@ -286,7 +283,7 @@ uint16_t ReadFrSkyX() CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack prev_option = option ; } - LED_ON; + LED_on; CC2500_SetTxRxMode(TX_EN); set_start(hopping_frequency_no); CC2500_SetPower(); @@ -339,10 +336,8 @@ uint16_t initFrSkyX() { while(!chanskip) { - #if defined STM32_board - randomSeed((uint32_t)analogRead(PB0) << 10 | analogRead(PB1)); - #else - randomSeed((uint32_t)analogRead(A6) << 10 | analogRead(A7)); + #if defined STM32_board + randomSeed((uint32_t)analogRead(PB0) << 10 | analogRead(PB1)); #endif chanskip=random(0xfefefefe)%47; } @@ -371,4 +366,4 @@ uint16_t initFrSkyX() seq_last_rcvd = 8; return 10000; } -#endif +#endif diff --git a/Multiprotocol/Hisky_nrf24l01.ino b/Multiprotocol/Hisky_nrf24l01.ino index 6bd1cf8..ddf935b 100644 --- a/Multiprotocol/Hisky_nrf24l01.ino +++ b/Multiprotocol/Hisky_nrf24l01.ino @@ -120,9 +120,8 @@ static void __attribute__((unused)) build_ch_data() { uint16_t temp; uint8_t i,j; - const uint8_t ch[]={AILERON, ELEVATOR, THROTTLE, RUDDER, AUX1, AUX2, AUX3, AUX4}; for (i = 0; i< 8; i++) { - j=ch[i]; + j=CH_AETR[i]; temp=map(limit_channel_100(j),servo_min_100,servo_max_100,0,1000); if (j == THROTTLE) // It is clear that hisky's throttle stick is made reversely, so I adjust it here on purpose temp = 1000 -temp; diff --git a/Multiprotocol/Hontai_nrf24l01.ino b/Multiprotocol/Hontai_nrf24l01.ino index 08ce83a..64f61a9 100644 --- a/Multiprotocol/Hontai_nrf24l01.ino +++ b/Multiprotocol/Hontai_nrf24l01.ino @@ -121,7 +121,7 @@ static void __attribute__((unused)) HONTAI_send_packet(uint8_t bind) if(sub_protocol == FORMAT_JJRCX1) NRF24L01_SetTxRxMode(TX_EN); else - XN297_Configure(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP)); + XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? HONTAI_RF_BIND_CHANNEL : hopping_frequency[hopping_frequency_no++]); hopping_frequency_no %= 3; diff --git a/Multiprotocol/Hubsan_a7105.ino b/Multiprotocol/Hubsan_a7105.ino index 8a06fd4..70d3bf6 100644 --- a/Multiprotocol/Hubsan_a7105.ino +++ b/Multiprotocol/Hubsan_a7105.ino @@ -347,8 +347,6 @@ uint16_t initHubsan() { #if defined STM32_board randomSeed((uint32_t)analogRead(PB0) << 10 | analogRead(PB1)); - #else - randomSeed((uint32_t)analogRead(A6) << 10 | analogRead(A7)); #endif sessionid = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16); channel = allowed_ch[random(0xfefefefe) % sizeof(allowed_ch)]; diff --git a/Multiprotocol/J6Pro_cyrf6936.ino b/Multiprotocol/J6Pro_cyrf6936.ino index f82bb70..acc0971 100644 --- a/Multiprotocol/J6Pro_cyrf6936.ino +++ b/Multiprotocol/J6Pro_cyrf6936.ino @@ -35,30 +35,8 @@ enum PktState { J6PRO_CHAN_4, }; -const uint8_t j6pro_sopcodes[][8] = { - /* Note these are in order transmitted (LSB 1st) */ - {0x3C, 0x37, 0xCC, 0x91, 0xE2, 0xF8, 0xCC, 0x91}, - {0x9B, 0xC5, 0xA1, 0x0F, 0xAD, 0x39, 0xA2, 0x0F}, - {0xEF, 0x64, 0xB0, 0x2A, 0xD2, 0x8F, 0xB1, 0x2A}, - {0x66, 0xCD, 0x7C, 0x50, 0xDD, 0x26, 0x7C, 0x50}, - {0x5C, 0xE1, 0xF6, 0x44, 0xAD, 0x16, 0xF6, 0x44}, - {0x5A, 0xCC, 0xAE, 0x46, 0xB6, 0x31, 0xAE, 0x46}, - {0xA1, 0x78, 0xDC, 0x3C, 0x9E, 0x82, 0xDC, 0x3C}, - {0xB9, 0x8E, 0x19, 0x74, 0x6F, 0x65, 0x18, 0x74}, - {0xDF, 0xB1, 0xC0, 0x49, 0x62, 0xDF, 0xC1, 0x49}, - {0x97, 0xE5, 0x14, 0x72, 0x7F, 0x1A, 0x14, 0x72}, - {0x82, 0xC7, 0x90, 0x36, 0x21, 0x03, 0xFF, 0x17}, - {0xE2, 0xF8, 0xCC, 0x91, 0x3C, 0x37, 0xCC, 0x91}, //Note: the '03' was '9E' in the Cypress recommended table - {0xAD, 0x39, 0xA2, 0x0F, 0x9B, 0xC5, 0xA1, 0x0F}, //The following are the same as the 1st 8 above, - {0xD2, 0x8F, 0xB1, 0x2A, 0xEF, 0x64, 0xB0, 0x2A}, //but with the upper and lower word swapped - {0xDD, 0x26, 0x7C, 0x50, 0x66, 0xCD, 0x7C, 0x50}, - {0xAD, 0x16, 0xF6, 0x44, 0x5C, 0xE1, 0xF6, 0x44}, - {0xB6, 0x31, 0xAE, 0x46, 0x5A, 0xCC, 0xAE, 0x46}, - {0x9E, 0x82, 0xDC, 0x3C, 0xA1, 0x78, 0xDC, 0x3C}, - {0x6F, 0x65, 0x18, 0x74, 0xB9, 0x8E, 0x19, 0x74}, -}; -const uint8_t bind_sop_code[] = {0x62, 0xdf, 0xc1, 0x49, 0xdf, 0xb1, 0xc0, 0x49}; -const uint8_t data_code[] = {0x02, 0xf9, 0x93, 0x97, 0x02, 0xfa, 0x5c, 0xe3, 0x01, 0x2b, 0xf1, 0xdb, 0x01, 0x32, 0xbe, 0x6f}; +const uint8_t PROGMEM j6pro_bind_sop_code[] = {0x62, 0xdf, 0xc1, 0x49, 0xdf, 0xb1, 0xc0, 0x49}; +const uint8_t j6pro_data_code[] = {0x02, 0xf9, 0x93, 0x97, 0x02, 0xfa, 0x5c, 0xe3, 0x01, 0x2b, 0xf1, 0xdb, 0x01, 0x32, 0xbe, 0x6f}; static void __attribute__((unused)) j6pro_build_bind_packet() { @@ -106,7 +84,7 @@ static void __attribute__((unused)) j6pro_cyrf_init() CYRF_WriteRegister(CYRF_10_FRAMING_CFG, 0xee); CYRF_WriteRegister(CYRF_1F_TX_OVERRIDE, 0x00); CYRF_WriteRegister(CYRF_1E_RX_OVERRIDE, 0x00); - CYRF_ConfigDataCode(data_code, 16); + CYRF_ConfigDataCode(j6pro_data_code, 16); CYRF_WritePreamble(0x023333); CYRF_GetMfgData(cyrfmfg_id); @@ -121,7 +99,7 @@ static void __attribute__((unused)) cyrf_bindinit() CYRF_SetPower(0x28); //Deviation using max power, replaced by bind power... CYRF_ConfigRFChannel(0x52); - CYRF_ConfigSOPCode(bind_sop_code); + CYRF_PROGMEM_ConfigSOPCode(j6pro_bind_sop_code); CYRF_ConfigCRCSeed(0x0000); CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a); CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x83); @@ -144,7 +122,7 @@ static void __attribute__((unused)) cyrf_datainit() uint16_t crc = (0xff & (cyrfmfg_id[1] - cyrfmfg_id[4] + cyrfmfg_id[5])) | ((0xff & (cyrfmfg_id[2] + cyrfmfg_id[3] - cyrfmfg_id[4] + cyrfmfg_id[5])) << 8); CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x25); - CYRF_ConfigSOPCode(j6pro_sopcodes[sop_idx]); + CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[sop_idx]); CYRF_ConfigCRCSeed(crc); } @@ -257,7 +235,6 @@ uint16_t ReadJ6Pro() uint16_t initJ6Pro() { - CYRF_Reset(); j6pro_cyrf_init(); if(IS_AUTOBIND_FLAG_on) { diff --git a/Multiprotocol/KN_nrf24l01.ino b/Multiprotocol/KN_nrf24l01.ino index 9e0775b..14e9566 100644 --- a/Multiprotocol/KN_nrf24l01.ino +++ b/Multiprotocol/KN_nrf24l01.ino @@ -246,7 +246,7 @@ static void __attribute__((unused)) kn_init() NRF24L01_Initialize(); - NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO)); + NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)); NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address @@ -259,7 +259,7 @@ static void __attribute__((unused)) kn_init() NRF24L01_Activate(0x73); NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 1); // Dynamic payload for data pipe 0 // Enable: Dynamic Payload Length to enable PCF - NRF24L01_WriteReg(NRF24L01_1D_FEATURE, BV(NRF2401_1D_EN_DPL)); + NRF24L01_WriteReg(NRF24L01_1D_FEATURE, _BV(NRF2401_1D_EN_DPL)); NRF24L01_SetPower(); diff --git a/Multiprotocol/MJXQ_nrf24l01.ino b/Multiprotocol/MJXQ_nrf24l01.ino index 01ea02e..bc291e5 100644 --- a/Multiprotocol/MJXQ_nrf24l01.ino +++ b/Multiprotocol/MJXQ_nrf24l01.ino @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with Multiprotocol. If not, see . */ -// compatible with MJX WLH08, X600, X800, H26D +// compatible with MJX WLH08, X600, X800, H26D, Eachine E010 // Last sync with hexfet new_protocols/mjxq_nrf24l01.c dated 2016-01-17 #if defined(MJXQ_NRF24L01_INO) @@ -26,6 +26,17 @@ #define MJXQ_RF_NUM_CHANNELS 4 #define MJXQ_ADDRESS_LENGTH 5 +// haven't figured out txid<-->rf channel mapping for MJX models +const uint8_t PROGMEM MJXQ_map_rfchan[][4] = { + {0x0A, 0x46, 0x3A, 0x42}, + {0x0A, 0x3C, 0x36, 0x3F}, + {0x0A, 0x43, 0x36, 0x3F} }; +const uint8_t PROGMEM MJXQ_map_txid[][3] = { + {0xF8, 0x4F, 0x1C}, + {0xC8, 0x6E, 0x02}, + {0x48, 0x6A, 0x40} }; + + #define MJXQ_PAN_TILT_COUNT 16 // for H26D - match stock tx timing #define MJXQ_PAN_DOWN 0x08 #define MJXQ_PAN_UP 0x04 @@ -39,14 +50,14 @@ static uint8_t __attribute__((unused)) MJXQ_pan_tilt_value() packet_count++; if(packet_count & MJXQ_PAN_TILT_COUNT) { - if(Servo_AUX8) + if(Servo_data[AUX8]>PPM_MAX_COMMAND) pan=MJXQ_PAN_UP; if(Servo_data[AUX8]PPM_MIN_COMMAND) - pan=MJXQ_TILT_UP; + if(Servo_data[AUX9]>PPM_MAX_COMMAND) + pan+=MJXQ_TILT_UP; if(Servo_data[AUX9]rf channel mapping for MJX models - static const uint8_t rf_map[][4] = { - {0x0A, 0x46, 0x3A, 0x42}, - {0x0A, 0x3C, 0x36, 0x3F}, - {0x0A, 0x43, 0x36, 0x3F} }; if (sub_protocol == H26D) memcpy(hopping_frequency, "\x32\x3e\x42\x4e", MJXQ_RF_NUM_CHANNELS); else - if (sub_protocol == WLH08) - memcpy(hopping_frequency, rf_map[rx_tx_addr[0]%3], MJXQ_RF_NUM_CHANNELS); + if (sub_protocol != WLH08 && sub_protocol != E010) + for(uint8_t i=0;irf channel mapping for MJX models - static const uint8_t tx_map[][3]={ - {0xF8, 0x4F, 0x1C}, - {0xC8, 0x6E, 0x02}, - {0x48, 0x6A, 0x40} }; - if (sub_protocol == WLH08) - rx_tx_addr[0]&=0xF8; // txid must be multiple of 8 + rx_tx_addr[0]&=0xF8; + if (sub_protocol == E010) + { + rx_tx_addr[1]=(rx_tx_addr[1]&0xF0)|0x0C; + rx_tx_addr[2]&=0xF0; + } else - memcpy(rx_tx_addr,tx_map[rx_tx_addr[0]%3],3); + for(uint8_t i=0;i<3;i++) + rx_tx_addr[i]=pgm_read_byte_near( &MJXQ_map_txid[rx_tx_addr[4]%3][i] ); } uint16_t MJXQ_callback() diff --git a/Multiprotocol/MT99xx_nrf24l01.ino b/Multiprotocol/MT99xx_nrf24l01.ino index 88d9a46..a36d12f 100644 --- a/Multiprotocol/MT99xx_nrf24l01.ino +++ b/Multiprotocol/MT99xx_nrf24l01.ino @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with Multiprotocol. If not, see . */ -// compatible with MT99xx, Eachine H7, Yi Zhan i6S +// compatible with MT99xx, Eachine H7, Yi Zhan i6S and LS114/124 // Last sync with Goebish mt99xx_nrf24l01.c dated 2016-01-29 #if defined(MT99XX_NRF24L01_INO) @@ -53,34 +53,54 @@ enum { MT99XX_DATA }; -static void __attribute__((unused)) MT99XX_send_packet() -{ - const uint8_t yz_p4_seq[] = {0xa0, 0x20, 0x60}; - const uint8_t mys_byte[] = { +const uint8_t h7_mys_byte[] = { 0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 0x04, 0x14, 0x05, 0x15, 0x06, 0x16, 0x07, 0x17, 0x00, 0x10 }; + +static const uint8_t ls_mys_byte[] = { + 0x05, 0x15, 0x25, 0x06, 0x16, 0x26, + 0x07, 0x17, 0x27, 0x00, 0x10, 0x20, + 0x01, 0x11, 0x21, 0x02, 0x12, 0x22, + 0x03, 0x13, 0x23, 0x04, 0x14, 0x24 +}; + +static void __attribute__((unused)) MT99XX_send_packet() +{ + const uint8_t yz_p4_seq[] = {0xa0, 0x20, 0x60}; static uint8_t yz_seq_num=0; + static uint8_t ls_counter=0; if(sub_protocol != YZ) - { // MT99XX & H7 - packet[0] = convert_channel_8b_scale(THROTTLE,0x00,0xE1); // throttle + { // MT99XX & H7 & LS + packet[0] = convert_channel_8b_scale(THROTTLE,0xE1,0x00); // throttle packet[1] = convert_channel_8b_scale(RUDDER ,0x00,0xE1); // rudder - packet[2] = convert_channel_8b_scale(AILERON ,0x00,0xE1); // aileron + packet[2] = convert_channel_8b_scale(AILERON ,0xE1,0x00); // aileron packet[3] = convert_channel_8b_scale(ELEVATOR,0x00,0xE1); // elevator packet[4] = 0x20; // pitch trim (0x3f-0x20-0x00) packet[5] = 0x20; // roll trim (0x00-0x20-0x3f) - packet[6] = GET_FLAG( Servo_AUX1, FLAG_MT_FLIP ) - | GET_FLAG( Servo_AUX3, FLAG_MT_SNAPSHOT ) - | GET_FLAG( Servo_AUX4, FLAG_MT_VIDEO ); - if(sub_protocol==MT99) - packet[6] |= 0x40 | FLAG_MT_RATE2; - else + packet[6] = GET_FLAG( Servo_AUX1, FLAG_MT_FLIP ); + packet[7] = h7_mys_byte[hopping_frequency_no]; // next rf channel index ? + + if(sub_protocol==H7) packet[6] |= FLAG_MT_RATE1; // max rate on H7 - // todo: mys_byte = next channel index ? - // low nibble: index in chan list ? - // high nibble: 0->start from start of list, 1->start from end of list ? - packet[7] = mys_byte[hopping_frequency_no]; + else + if(sub_protocol==MT99) + packet[6] |= 0x40 | FLAG_MT_RATE2 + | GET_FLAG( Servo_AUX3, FLAG_MT_SNAPSHOT ) + | GET_FLAG( Servo_AUX4, FLAG_MT_VIDEO ); // max rate on MT99xx + else //LS + { + packet[6] |= FLAG_LS_RATE // max rate + | GET_FLAG( Servo_AUX2, FLAG_LS_INVERT ) //INVERT + | GET_FLAG( Servo_AUX3, FLAG_LS_SNAPSHOT ) //SNAPSHOT + | GET_FLAG( Servo_AUX4, FLAG_LS_VIDEO ) //VIDEO + | GET_FLAG( Servo_AUX5, FLAG_LS_HEADLESS ); //HEADLESS + packet[7] = ls_mys_byte[ls_counter++]; + if(ls_counter >= sizeof(ls_mys_byte)) + ls_counter=0; + } + uint8_t result=checksum_offset; for(uint8_t i=0; i<8; i++) result += packet[i]; @@ -89,9 +109,9 @@ static void __attribute__((unused)) MT99XX_send_packet() else { // YZ packet[0] = convert_channel_8b_scale(THROTTLE,0x00,0x64); // throttle - packet[1] = convert_channel_8b_scale(RUDDER ,0x00,0x64); // rudder + packet[1] = convert_channel_8b_scale(RUDDER ,0x64,0x00); // rudder packet[2] = convert_channel_8b_scale(ELEVATOR,0x00,0x64); // elevator - packet[3] = convert_channel_8b_scale(AILERON ,0x00,0x64); // aileron + packet[3] = convert_channel_8b_scale(AILERON ,0x64,0x00); // aileron if(packet_count++ >= 23) { yz_seq_num ++; @@ -111,6 +131,7 @@ static void __attribute__((unused)) MT99XX_send_packet() packet[7] += packet[idx]; packet[8] = 0xff; } + if(sub_protocol == LS) NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x2D); // LS always transmits on the same channel else @@ -132,8 +153,11 @@ static void __attribute__((unused)) MT99XX_send_packet() static void __attribute__((unused)) MT99XX_init() { NRF24L01_Initialize(); + if(sub_protocol == YZ) + XN297_SetScrambledMode(XN297_UNSCRAMBLED); NRF24L01_SetTxRxMode(TX_EN); NRF24L01_FlushTx(); + XN297_SetTXAddr((uint8_t *)"\xCC\xCC\xCC\xCC\xCC", 5); 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 @@ -145,7 +169,7 @@ static void __attribute__((unused)) MT99XX_init() NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps NRF24L01_SetPower(); - XN297_Configure(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP) ); + XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) ); } @@ -153,13 +177,17 @@ static void __attribute__((unused)) MT99XX_initialize_txid() { rx_tx_addr[3] = 0xCC; rx_tx_addr[4] = 0xCC; - if(sub_protocol == YZ) { rx_tx_addr[0] = 0x53; // test (SB id) rx_tx_addr[1] = 0x00; rx_tx_addr[2] = 0x00; } + else + if(sub_protocol == LS) + rx_tx_addr[0] = 0xCC; + else //MT99 & H7 + rx_tx_addr[2] = 0x00; checksum_offset = rx_tx_addr[0] + rx_tx_addr[1] + rx_tx_addr[2]; channel_offset = (((checksum_offset & 0xf0)>>4) + (checksum_offset & 0x0f)) % 8; } @@ -208,6 +236,7 @@ uint16_t initMT99XX(void) MT99XX_init(); packet[0] = 0x20; + packet_period = MT99XX_PACKET_PERIOD_MT; switch(sub_protocol) { // MT99 & H7 case MT99: @@ -228,12 +257,12 @@ uint16_t initMT99XX(void) packet[3] = 0x11; break; } - packet[4] = rx_tx_addr[0]; // 1st byte for data state tx address - packet[5] = rx_tx_addr[1]; // 2nd byte for data state tx address (always 0x00 on Yi Zhan ?) - packet[6] = 0x00; // 3rd byte for data state tx address (always 0x00 ?) + packet[4] = rx_tx_addr[0]; + packet[5] = rx_tx_addr[1]; + packet[6] = rx_tx_addr[2]; packet[7] = checksum_offset; // checksum offset packet[8] = 0xAA; // fixed packet_count=0; return MT99XX_INITIAL_WAIT+MT99XX_PACKET_PERIOD_MT; } -#endif +#endif diff --git a/Multiprotocol/MultiOrange.cpp.xmega b/Multiprotocol/MultiOrange.cpp.xmega index 0b6305b..d9a916c 100644 --- a/Multiprotocol/MultiOrange.cpp.xmega +++ b/Multiprotocol/MultiOrange.cpp.xmega @@ -3,17 +3,18 @@ #define XMEGA 1 +// For BLUE module use: +//#define DSM_BLUE + #include #include #include static void protocol_init(void) ; static void update_aux_flags(void) ; -static void PPM_Telemetry_serial_init(void) ; static uint32_t random_id(uint16_t adress, uint8_t create_new) ; static void update_serial_data(void) ; static void Mprotocol_serial_init(void) ; -static void module_reset(void) ; static void update_led_status(void) ; static void set_rx_tx_addr(uint32_t id) ; uint16_t limit_channel_100(uint8_t ch) ; @@ -31,6 +32,8 @@ extern uint16_t initDsm2(void) ; extern uint16_t ReadDsm2(void) ; extern uint16_t DevoInit(void) ; extern uint16_t devo_callback(void) ; +extern uint16_t initJ6Pro(void) ; +extern uint16_t ReadJ6Pro(void) ; extern void randomSeed(unsigned int seed) ; extern long random(long howbig) ; @@ -39,20 +42,19 @@ extern long map(long x, long in_min, long in_max, long out_min, long out_max) ; extern uint32_t millis(void) ; extern uint32_t micros(void) ; extern void delayMicroseconds(uint16_t x) ; +extern void delayMilliseconds(unsigned long ms) ; extern void init(void) ; -extern int analogRead(uint8_t pin) ; - -#define A6 20 -#define A7 21 +extern void modules_reset() ; +extern void Update_All() ; +extern void tx_pause() ; +extern void tx_resume() ; +extern void TelemetryUpdate() ; +extern uint16_t initDsm() ; +extern uint16_t ReadDsm() ; #define yield() -//void _delay_us( uint16_t x ) -//{ -// delayMicroseconds( x ) ; -//} - #define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) #define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) @@ -69,219 +71,6 @@ extern int analogRead(uint8_t pin) ; #define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3) #define FRACT_MAX (1000 >> 3) -volatile unsigned long timer0_overflow_count = 0; -volatile unsigned long timer0_millis = 0; -static unsigned char timer0_fract = 0; - - - -//void chipInit() -//{ -// PR.PRGEN = 0 ; // RTC and event system active -// PR.PRPC = 0 ; // No power reduction port C -// PR.PRPD = 0 ; // No power reduction port D -// PMIC.CTRL = 7 ; -// OSC.CTRL = 0xC3 ; // unclear -// OSC.CTRL |= 0x08 ; // Enable external oscillator -// while( ( OSC.STATUS & 0x08 ) == 0 ) ; // Wait for ext osc to be ready -// OSC.PLLCTRL = 0xC2 ; // Ext. Osc times 2 -// OSC.CTRL |= 0x10 ; // Enable PLL -// while( ( OSC.STATUS & 0x10 ) == 0 ) ; // Wait PLL ready -// CPU_CCP = 0xD8 ; // 0x34 -// CLK.CTRL = 0 ; // Select 2MHz internal clock -// CPU_CCP = 0xD8 ; // 0x34 -// CLK.CTRL = 0x04 ; // Select PLL as clock (32MHz) -// PORTD.OUTSET = 0x17 ; -// PORTD.DIRSET = 0xB2 ; -// PORTD.DIRCLR = 0x4D ; -// PORTD.PIN0CTRL = 0x18 ; -// PORTD.PIN2CTRL = 0x18 ; -// PORTE.DIRSET = 0x01 ; -// PORTE.DIRCLR = 0x02 ; -// PORTE.OUTSET = 0x01 ; -// PORTA.DIRCLR = 0xFF ; -// PORTA.PIN0CTRL = 0x18 ; -// PORTA.PIN1CTRL = 0x18 ; -// PORTA.PIN2CTRL = 0x18 ; -// PORTA.PIN3CTRL = 0x18 ; -// PORTA.PIN4CTRL = 0x18 ; -// PORTA.PIN5CTRL = 0x18 ; -// PORTA.PIN6CTRL = 0x18 ; -// PORTA.PIN7CTRL = 0x18 ; -// PORTC.DIRSET = 0x20 ; -// PORTC.OUTCLR = 0x20 ; -// SPID.CTRL = 0x51 ; -// PORTC.OUTSET = 0x08 ; -// PORTC.DIRSET = 0x08 ; -// PORTC.PIN3CTRL = 0x18 ; -// PORTC.PIN2CTRL = 0x18 ; -// USARTC0.BAUDCTRLA = 19 ; -// USARTC0.BAUDCTRLB = 0 ; -// USARTC0.CTRLB = 0x18 ; -// USARTC0.CTRLA = (USARTC0.CTRLA & 0xCF) | 0x10 ; -// USARTC0.CTRLC = 0x03 ; - -// TCC0.CTRLB = 0 ; -// TCC0.CTRLC = 0 ; -// TCC0.CTRLD = 0 ; -// TCC0.CTRLE = 0 ; -// TCC0.INTCTRLA = 0x01 ; -// TCC0.INTCTRLB = 0 ; -// TCC0.PER = 0x00FF ; -// TCC0.CTRLA = 4 ; - -// TCC1.CTRLB = 0 ; -// TCC1.CTRLC = 0 ; -// TCC1.CTRLD = 0 ; -// TCC1.CTRLE = 0 ; -// TCC1.INTCTRLA = 0x03 ; -// TCC1.INTCTRLB = 0 ; -// TCC1.PER = 0xFFFF ; -// TCC1.CNT = 0 ; -// TCC1.CTRLA = 4 ; - -// TCD0.CTRLA = 4 ; -// TCD0.INTCTRLA = 0x03 ; -// TCD0.PER = 0x02ED ; - -//// L0EDB() ; - -// NVM.CTRLB &= 0xF7 ; // No EEPROM mapping -//} - - - -ISR(TCC0_OVF_vect) -{ - // copy these to local variables so they can be stored in registers - // (volatile variables must be read from memory on every access) - unsigned long m = timer0_millis; - unsigned char f = timer0_fract; - - m += MILLIS_INC; - f += FRACT_INC; - if (f >= FRACT_MAX) { - f -= FRACT_MAX; - m += 1; - } - - timer0_fract = f; - timer0_millis = m; - timer0_overflow_count++; -} - -unsigned long millis() -{ - unsigned long m; - uint8_t oldSREG = SREG; - - // disable interrupts while we read timer0_millis or we might get an - // inconsistent value (e.g. in the middle of a write to timer0_millis) - cli(); - m = timer0_millis; - SREG = oldSREG; - - return m; -} - -unsigned long micros() -{ - unsigned long m; - uint8_t oldSREG = SREG, t; - - cli(); - m = timer0_overflow_count; - t = TCC0.CNT ; - - if ((TCC0.INTFLAGS & TC0_OVFIF_bm) && (t < 255)) - m++; - - SREG = oldSREG; - - return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond()); -} - -void delay(unsigned long ms) -{ - uint16_t start = (uint16_t)micros(); - - while (ms > 0) { - yield(); - if (((uint16_t)micros() - start) >= 1000) { - ms--; - start += 1000; - } - } -} - -/* Delay for the given number of microseconds. Assumes a 8 or 16 MHz clock. */ -void delayMicroseconds(unsigned int us) -{ - // calling avrlib's delay_us() function with low values (e.g. 1 or - // 2 microseconds) gives delays longer than desired. - //delay_us(us); -#if F_CPU >= 20000000L - // for the 20 MHz clock on rare Arduino boards - - // for a one-microsecond delay, simply wait 2 cycle and return. The overhead - // of the function call yields a delay of exactly a one microsecond. - __asm__ __volatile__ ( - "nop" "\n\t" - "nop"); //just waiting 2 cycle - if (--us == 0) - return; - - // the following loop takes a 1/5 of a microsecond (4 cycles) - // per iteration, so execute it five times for each microsecond of - // delay requested. - us = (us<<2) + us; // x5 us - - // account for the time taken in the preceeding commands. - us -= 2; - -#elif F_CPU >= 16000000L - // for the 16 MHz clock on most Arduino boards - - // for a one-microsecond delay, simply return. the overhead - // of the function call yields a delay of approximately 1 1/8 us. - if (--us == 0) - return; - - // the following loop takes a quarter of a microsecond (4 cycles) - // per iteration, so execute it four times for each microsecond of - // delay requested. - us <<= 2; - - // account for the time taken in the preceeding commands. - us -= 2; -#else - // for the 8 MHz internal clock on the ATmega168 - - // for a one- or two-microsecond delay, simply return. the overhead of - // the function calls takes more than two microseconds. can't just - // subtract two, since us is unsigned; we'd overflow. - if (--us == 0) - return; - if (--us == 0) - return; - - // the following loop takes half of a microsecond (4 cycles) - // per iteration, so execute it twice for each microsecond of - // delay requested. - us <<= 1; - - // partially compensate for the time taken by the preceeding commands. - // we can't subtract any more than this or we'd overflow w/ small delays. - us--; -#endif - - // busy wait - __asm__ __volatile__ ( - "1: sbiw %0,1" "\n\t" // 2 cycles - "brne 1b" : "=w" (us) : "0" (us) // 2 cycles - ); -} - #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif @@ -314,27 +103,6 @@ void init() PMIC.CTRL = 7 ; // Enable all interrupt levels sei(); - // on the ATmega168, timer 0 is also used for fast hardware pwm - // (using phase-correct PWM would mean that timer 0 overflowed half as often - // resulting in different millis() behavior on the ATmega8 and ATmega168) -//#if defined(TCCR0A) && defined(WGM01) -// sbi(TCCR0A, WGM01); -// sbi(TCCR0A, WGM00); -//#endif - - -// TCC0 counts 0-255 at 4uS clock rate - EVSYS.CH2MUX = 0x80 + 0x07 ; // Prescaler of 128 - TCC0.CTRLB = 0 ; - TCC0.CTRLC = 0 ; - TCC0.CTRLD = 0 ; - TCC0.CTRLE = 0 ; - TCC0.INTCTRLA = 0x01 ; - TCC0.INTCTRLB = 0 ; - TCC0.PER = 0x00FF ; - TCC0.CTRLA = 0x0A ; - - #if defined(ADCSRA) // set a2d prescale factor to 128 // 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range. @@ -357,12 +125,6 @@ void init() UCSR0B = 0; #endif - // PPM interrupt - PORTD.DIRCLR = 0x08 ; // D3 is input - PORTD.PIN3CTRL = 0x01 ; // Rising edge - PORTD.INT0MASK = 0x08 ; - PORTD.INTCTRL = 0x02 ; // Medium level interrupt - // Dip Switch inputs PORTA.DIRCLR = 0xFF ; PORTA.PIN0CTRL = 0x18 ; @@ -375,95 +137,15 @@ void init() PORTA.PIN7CTRL = 0x18 ; } -#define DEFAULT 1 - -uint8_t analog_reference = DEFAULT; - -void analogReference(uint8_t mode) -{ - // can't actually set the register here because the default setting - // will connect AVCC and the AREF pin, which would cause a short if - // there's something connected to AREF. - analog_reference = mode; -} - -int analogRead(uint8_t pin) -{ - uint8_t low, high; - -#if defined(analogPinToChannel) -#if defined(__AVR_ATmega32U4__) - if (pin >= 18) pin -= 18; // allow for channel or pin numbers -#endif - pin = analogPinToChannel(pin); -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) - if (pin >= 54) pin -= 54; // allow for channel or pin numbers -#elif defined(__AVR_ATmega32U4__) - if (pin >= 18) pin -= 18; // allow for channel or pin numbers -#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) - if (pin >= 24) pin -= 24; // allow for channel or pin numbers -#else - if (pin >= 14) pin -= 14; // allow for channel or pin numbers -#endif - -#if defined(ADCSRB) && defined(MUX5) - // the MUX5 bit of ADCSRB selects whether we're reading from channels - // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high). - ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5); -#endif - - // set the analog reference (high two bits of ADMUX) and select the - // channel (low 4 bits). this also sets ADLAR (left-adjust result) - // to 0 (the default). -#if defined(ADMUX) - ADMUX = (analog_reference << 6) | (pin & 0x07); -#endif - - // without a delay, we seem to read from the wrong channel - //delay(1); - -#if defined(ADCSRA) && defined(ADCL) - // start the conversion - sbi(ADCSRA, ADSC); - - // ADSC is cleared when the conversion finishes - while (bit_is_set(ADCSRA, ADSC)); - - // we have to read ADCL first; doing so locks both ADCL - // and ADCH until ADCH is read. reading ADCL second would - // cause the results of each conversion to be discarded, - // as ADCL and ADCH would be locked when it completed. - low = ADCL; - high = ADCH; -#else - // we dont have an ADC, return 0 - low = 0; - high = 0; -#endif - - // combine the two bytes - return (high << 8) | low; -} - - - - -void A7105_Reset() -{ -} -void CC2500_Reset() -{ -} -void NRF24L01_Reset() -{ -} - - #include "Multiprotocol.ino" +#include "SPI.ino" +#include "Convert.ino" +#include "Arduino.ino" #include "cyrf6936_SPI.ino" -#include "DSM2_cyrf6936.ino" +#include "DSM_cyrf6936.ino" #include "Devo_cyrf6936.ino" +#include "J6Pro_cyrf6936.ino" #include "Telemetry.ino" diff --git a/Multiprotocol/NRF24l01_SPI.ino b/Multiprotocol/NRF24l01_SPI.ino index 45f4dc0..bcd7f0a 100644 --- a/Multiprotocol/NRF24l01_SPI.ino +++ b/Multiprotocol/NRF24l01_SPI.ino @@ -19,6 +19,7 @@ //--------------------------- #include "iface_nrf24l01.h" + //--------------------------- // NRF24L01+ SPI Specific Functions //--------------------------- @@ -156,6 +157,42 @@ void NRF24L01_SetPower() } } +void NRF24L01_SetTxRxMode(enum TXRX_State mode) +{ + if(mode == TX_EN) { + NRF_CSN_off; + NRF24L01_WriteReg(NRF24L01_07_STATUS, (1 << NRF24L01_07_RX_DR) //reset the flag(s) + | (1 << NRF24L01_07_TX_DS) + | (1 << NRF24L01_07_MAX_RT)); + NRF24L01_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_EN_CRC) // switch to TX mode + | (1 << NRF24L01_00_CRCO) + | (1 << NRF24L01_00_PWR_UP)); + _delay_us(130); + NRF_CSN_on; + } + else + if (mode == RX_EN) { + NRF_CSN_off; + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // reset the flag(s) + NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x0F); // switch to RX mode + NRF24L01_WriteReg(NRF24L01_07_STATUS, (1 << NRF24L01_07_RX_DR) //reset the flag(s) + | (1 << NRF24L01_07_TX_DS) + | (1 << NRF24L01_07_MAX_RT)); + NRF24L01_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_EN_CRC) // switch to RX mode + | (1 << NRF24L01_00_CRCO) + | (1 << NRF24L01_00_PWR_UP) + | (1 << NRF24L01_00_PRIM_RX)); + _delay_us(130); + NRF_CSN_on; + } + else + { + NRF24L01_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_EN_CRC)); //PowerDown + NRF_CSN_off; + } +} + +/* void NRF24L01_SetTxRxMode(enum TXRX_State mode) { if(mode == TX_EN) { @@ -167,7 +204,7 @@ void NRF24L01_SetTxRxMode(enum TXRX_State mode) | (1 << NRF24L01_00_CRCO) | (1 << NRF24L01_00_PWR_UP)); delayMicroseconds(130); - NRF_CSN_on; + NRF_CE_on; } else if (mode == RX_EN) { @@ -190,7 +227,7 @@ void NRF24L01_SetTxRxMode(enum TXRX_State mode) NRF_CE_off; } } - +*/ void NRF24L01_Reset() { //** not in deviation but needed to hot switch between models @@ -205,24 +242,25 @@ void NRF24L01_Reset() NRF24L01_Strobe(0xff); // NOP NRF24L01_ReadReg(NRF24L01_07_STATUS); NRF24L01_SetTxRxMode(TXRX_OFF); - _delay_us(100); + delayMicroseconds(100); } uint8_t NRF24L01_packet_ack() { - switch (NRF24L01_ReadReg(NRF24L01_07_STATUS) & (BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT))) + switch (NRF24L01_ReadReg(NRF24L01_07_STATUS) & (_BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_MAX_RT))) { - case BV(NRF24L01_07_TX_DS): + case _BV(NRF24L01_07_TX_DS): return PKT_ACKED; - case BV(NRF24L01_07_MAX_RT): + case _BV(NRF24L01_07_MAX_RT): return PKT_TIMEOUT; } return PKT_PENDING; } + /////////////// // XN297 emulation layer -uint8_t xn297_scramble_enabled=1; //enabled by default +uint8_t xn297_scramble_enabled=XN297_SCRAMBLED; //enabled by default uint8_t xn297_addr_len; uint8_t xn297_tx_addr[5]; uint8_t xn297_rx_addr[5]; @@ -235,13 +273,6 @@ static const uint8_t xn297_scramble[] = { 0x1b, 0x5d, 0x19, 0x10, 0x24, 0xd3, 0xdc, 0x3f, 0x8e, 0xc5, 0x2f}; -const uint16_t PROGMEM xn297_crc_xorout[] = { - 0x0000, 0x3d5f, 0xa6f1, 0x3a23, 0xaa16, 0x1caf, - 0x62b2, 0xe0eb, 0x0821, 0xbe07, 0x5f1a, 0xaf15, - 0x4f0a, 0xad24, 0x5e48, 0xed34, 0x068c, 0xf2c9, - 0x1852, 0xdf36, 0x129d, 0xb17c, 0xd5f5, 0x70d7, - 0xb798, 0x5133, 0x67db, 0xd94e}; - const uint16_t PROGMEM xn297_crc_xorout_scrambled[] = { 0x0000, 0x3448, 0x9BA7, 0x8BBB, 0x85E1, 0x3E8C, 0x451E, 0x18E6, 0x6B24, 0xE7AB, 0x3828, 0x814B, @@ -249,6 +280,13 @@ const uint16_t PROGMEM xn297_crc_xorout_scrambled[] = { 0x8B17, 0x2920, 0x8B5F, 0x61B1, 0xD391, 0x7401, 0x2138, 0x129F, 0xB3A0, 0x2988}; +const uint16_t PROGMEM xn297_crc_xorout[] = { + 0x0000, 0x3d5f, 0xa6f1, 0x3a23, 0xaa16, 0x1caf, + 0x62b2, 0xe0eb, 0x0821, 0xbe07, 0x5f1a, 0xaf15, + 0x4f0a, 0xad24, 0x5e48, 0xed34, 0x068c, 0xf2c9, + 0x1852, 0xdf36, 0x129d, 0xb17c, 0xd5f5, 0x70d7, + 0xb798, 0x5133, 0x67db, 0xd94e}; + static uint8_t bit_reverse(uint8_t b_in) { uint8_t b_out = 0; @@ -260,10 +298,9 @@ static uint8_t bit_reverse(uint8_t b_in) return b_out; } +static const uint16_t polynomial = 0x1021; static uint16_t crc16_update(uint16_t crc, uint8_t a) { - static const uint16_t polynomial = 0x1021; - crc ^= a << 8; for (uint8_t i = 0; i < 8; ++i) if (crc & 0x8000) @@ -309,14 +346,18 @@ void XN297_SetRXAddr(const uint8_t* addr, uint8_t len) NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, buf, 5); } -void XN297_Configure(uint16_t flags) +void XN297_Configure(uint8_t flags) { - xn297_scramble_enabled = !(flags & BV(XN297_UNSCRAMBLED)); - xn297_crc = !!(flags & BV(NRF24L01_00_EN_CRC)); - flags &= ~(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO)); + xn297_crc = !!(flags & _BV(NRF24L01_00_EN_CRC)); + flags &= ~(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)); NRF24L01_WriteReg(NRF24L01_00_CONFIG, flags & 0xFF); } +void XN297_SetScrambledMode(const uint8_t mode) +{ + xn297_scramble_enabled = mode; +} + void XN297_WritePayload(uint8_t* msg, uint8_t len) { uint8_t buf[32]; diff --git a/Multiprotocol/SFHSS_cc2500.ino b/Multiprotocol/SFHSS_cc2500.ino index 85a9afe..00ef2fe 100644 --- a/Multiprotocol/SFHSS_cc2500.ino +++ b/Multiprotocol/SFHSS_cc2500.ino @@ -18,7 +18,6 @@ #include "iface_cc2500.h" - #define SFHSS_COARSE 0 #define SFHSS_PACKET_LEN 13 @@ -27,11 +26,11 @@ uint8_t fhss_code; // 0-27 enum { - SFHSS_START = 0x101, - SFHSS_CAL = 0x102, - SFHSS_TUNE = 0x103, - SFHSS_DATA1 = 0x02, - SFHSS_DATA2 = 0x0b + SFHSS_START = 0x00, + SFHSS_CAL = 0x01, + SFHSS_DATA1 = 0x02, // do not change this value + SFHSS_DATA2 = 0x0B, // do not change this value + SFHSS_TUNE = 0x0F }; #define SFHSS_FREQ0_VAL 0xC4 @@ -75,12 +74,11 @@ const PROGMEM uint8_t SFHSS_init_values[] = { static void __attribute__((unused)) SFHSS_rf_init() { - CC2500_Reset(); CC2500_Strobe(CC2500_SIDLE); for (uint8_t i = 0; i < 39; ++i) CC2500_WriteReg(i, pgm_read_byte_near(&SFHSS_init_values[i])); - //CC2500_WriteRegisterMulti(CC2500_00_IOCFG2, init_values, sizeof(init_values)); + prev_option = option; CC2500_WriteReg(CC2500_0C_FSCTRL0, option); @@ -102,16 +100,14 @@ static void __attribute__((unused)) SFHSS_tune_chan_fast() CC2500_WriteReg(CC2500_25_FSCAL1, calData[rf_ch_num]); } - -static void __attribute__((unused)) SFHSS_tune_freq() { -// May be we'll need this tuning routine - some receivers are more sensitive to -// frequency impreciseness, and though CC2500 has a procedure to handle it it -// may not be applied in receivers, so we need to compensate for it on TX +static void __attribute__((unused)) SFHSS_tune_freq() +{ if ( prev_option != option ) { CC2500_WriteReg(CC2500_0C_FSCTRL0, option); CC2500_WriteReg(CC2500_0F_FREQ0, SFHSS_FREQ0_VAL + SFHSS_COARSE); prev_option = option ; + phase = SFHSS_START; // Restart the tune process if option is changed to get good tuned values } } @@ -130,23 +126,20 @@ static void __attribute__((unused)) SFHSS_calc_next_chan() // Values grow down and to the right, so we just revert every channel. static uint16_t __attribute__((unused)) SFHSS_convert_channel(uint8_t num) { - return (uint16_t) (map(limit_channel_100(num),PPM_MIN_100,PPM_MAX_100,906,86)); + return (uint16_t) (map(limit_channel_100(num),servo_min_100,servo_max_100,906,86)); } - static void __attribute__((unused)) SFHSS_build_data_packet() { #define spacer1 0x02 //0b10 #define spacer2 (spacer1 << 4) - uint8_t ch_offset = state == SFHSS_DATA1 ? 0 : 4; - const uint8_t ch[]={AILERON, ELEVATOR, THROTTLE, RUDDER, AUX1, AUX2, AUX3, AUX4}; - - uint16_t ch1 = SFHSS_convert_channel(ch[ch_offset+0]); - uint16_t ch2 = SFHSS_convert_channel(ch[ch_offset+1]); - uint16_t ch3 = SFHSS_convert_channel(ch[ch_offset+2]); - uint16_t ch4 = SFHSS_convert_channel(ch[ch_offset+3]); + uint8_t ch_offset = phase == SFHSS_DATA1 ? 0 : 4; + uint16_t ch1 = SFHSS_convert_channel(CH_AETR[ch_offset+0]); + uint16_t ch2 = SFHSS_convert_channel(CH_AETR[ch_offset+1]); + uint16_t ch3 = SFHSS_convert_channel(CH_AETR[ch_offset+2]); + uint16_t ch4 = SFHSS_convert_channel(CH_AETR[ch_offset+3]); - packet[0] = 0x81; // can be 80, 81, 81 for Orange, only 81 for XK + packet[0] = 0x81; // can be 80 or 81 for Orange, only 81 for XK packet[1] = rx_tx_addr[0]; packet[2] = rx_tx_addr[1]; packet[3] = 0; @@ -158,23 +151,22 @@ static void __attribute__((unused)) SFHSS_build_data_packet() packet[9] = (ch3 >> 1); packet[10] = (ch3 << 7) | spacer2 | ((ch4 >> 5) & 0x1F /*0b11111*/); packet[11] = (ch4 << 3) | ((fhss_code >> 2) & 0x07 /*0b111 */); - packet[12] = (fhss_code << 6) | state; + packet[12] = (fhss_code << 6) | phase; } static void __attribute__((unused)) SFHSS_send_packet() { - //SFHSS_tune_chan_fast(); CC2500_WriteData(packet, SFHSS_PACKET_LEN); } uint16_t ReadSFHSS() { - switch(state) + switch(phase) { case SFHSS_START: rf_ch_num = 0; SFHSS_tune_chan(); - state = SFHSS_CAL; + phase = SFHSS_CAL; return 2000; case SFHSS_CAL: calData[rf_ch_num]=CC2500_ReadReg(CC2500_25_FSCAL1); @@ -183,7 +175,7 @@ uint16_t ReadSFHSS() else { rf_ch_num = 0; - state = SFHSS_DATA1; + phase = SFHSS_DATA1; } return 2000; @@ -191,16 +183,16 @@ uint16_t ReadSFHSS() case SFHSS_DATA1: SFHSS_build_data_packet(); SFHSS_send_packet(); - state = SFHSS_DATA2; + phase = SFHSS_DATA2; return 1650; case SFHSS_DATA2: SFHSS_build_data_packet(); SFHSS_send_packet(); SFHSS_calc_next_chan(); - state = SFHSS_TUNE; + phase = SFHSS_TUNE; return 2000; case SFHSS_TUNE: - state = SFHSS_DATA1; + phase = SFHSS_DATA1; SFHSS_tune_freq(); SFHSS_tune_chan_fast(); CC2500_SetPower(); @@ -241,15 +233,15 @@ static void __attribute__((unused)) SFHSS_get_tx_id() uint16_t initSFHSS() { - BIND_DONE; // No bind protocol + BIND_DONE; // Not a TX bind protocol SFHSS_get_tx_id(); fhss_code=rx_tx_addr[2]%28; // Initialize it to random 0-27 inclusive SFHSS_rf_init(); - state = SFHSS_START; + phase = SFHSS_START; return 10000; } -#endif +#endif \ No newline at end of file diff --git a/Multiprotocol/SHENQI_nrf24l01.ino b/Multiprotocol/SHENQI_nrf24l01.ino index 2d6b020..bbfe774 100644 --- a/Multiprotocol/SHENQI_nrf24l01.ino +++ b/Multiprotocol/SHENQI_nrf24l01.ino @@ -4,10 +4,12 @@ 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 . */ @@ -93,7 +95,7 @@ uint16_t SHENQI_callback() SHENQI_send_packet(); else { - if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR)) + if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) { if(LT8900_ReadPayload(packet, 3)) { @@ -115,8 +117,8 @@ uint16_t initSHENQI() SHENQI_init(); hopping_frequency_no = 0; packet_count=0; - packet_period=100; + packet_period=500; return 1000; } -#endif +#endif \ No newline at end of file diff --git a/Multiprotocol/SLT_nrf24l01.ino b/Multiprotocol/SLT_nrf24l01.ino index 0622b55..8d4e486 100644 --- a/Multiprotocol/SLT_nrf24l01.ino +++ b/Multiprotocol/SLT_nrf24l01.ino @@ -34,7 +34,7 @@ enum { static void __attribute__((unused)) SLT_init() { NRF24L01_Initialize(); - NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO)); // 2-bytes CRC, radio off + NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)); // 2-bytes CRC, radio off NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x02); // 4-byte RX/TX address @@ -93,7 +93,7 @@ static void __attribute__((unused)) SLT_set_tx_id(void) static void __attribute__((unused)) SLT_wait_radio() { if (packet_sent) - while (!(NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_TX_DS))) ; + while (!(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS))) ; packet_sent = 0; } @@ -101,7 +101,7 @@ static void __attribute__((unused)) SLT_send_data(uint8_t *data, uint8_t len) { SLT_wait_radio(); NRF24L01_FlushTx(); - NRF24L01_WriteReg(NRF24L01_07_STATUS, BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_RX_DR) | BV(NRF24L01_07_MAX_RT)); + NRF24L01_WriteReg(NRF24L01_07_STATUS, _BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_RX_DR) | _BV(NRF24L01_07_MAX_RT)); NRF24L01_WritePayload(data, len); //NRF24L01_PulseCE(); packet_sent = 1; diff --git a/Multiprotocol/Symax_nrf24l01.ino b/Multiprotocol/Symax_nrf24l01.ino index 4a03990..c8b7a03 100644 --- a/Multiprotocol/Symax_nrf24l01.ino +++ b/Multiprotocol/Symax_nrf24l01.ino @@ -174,7 +174,7 @@ static void __attribute__((unused)) symax_init() NRF24L01_SetTxRxMode(TX_EN); // NRF24L01_ReadReg(NRF24L01_07_STATUS); - NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO)); + NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)); NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x3F); // Enable all data pipes (even though not used?) NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address diff --git a/Multiprotocol/V2X2_nrf24l01.ino b/Multiprotocol/V2X2_nrf24l01.ino index 887e60e..8f88c21 100644 --- a/Multiprotocol/V2X2_nrf24l01.ino +++ b/Multiprotocol/V2X2_nrf24l01.ino @@ -80,7 +80,7 @@ static void __attribute__((unused)) v202_init() NRF24L01_Initialize(); // 2-bytes CRC, radio off - NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO)); + NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)); 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 @@ -116,7 +116,7 @@ static void __attribute__((unused)) V202_init2() // 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)); + //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) diff --git a/Multiprotocol/YD717_nrf24l01.ino b/Multiprotocol/YD717_nrf24l01.ino index 1d9ffbe..50d0fa7 100644 --- a/Multiprotocol/YD717_nrf24l01.ino +++ b/Multiprotocol/YD717_nrf24l01.ino @@ -34,13 +34,6 @@ #define YD717_PAYLOADSIZE 8 // receive data pipes set to this size, but unused -enum { - YD717_INIT1 = 0, - YD717_BIND2, - YD717_BIND3, - YD717_DATA -}; - static void __attribute__((unused)) yd717_send_packet(uint8_t bind) { uint8_t rudder_trim, elevator_trim, aileron_trim; @@ -108,7 +101,7 @@ static void __attribute__((unused)) yd717_send_packet(uint8_t bind) } // clear packet status bits and TX FIFO - NRF24L01_WriteReg(NRF24L01_07_STATUS, (BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT))); + NRF24L01_WriteReg(NRF24L01_07_STATUS, (_BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_MAX_RT))); NRF24L01_FlushTx(); if( sub_protocol == YD717 ) @@ -131,120 +124,65 @@ static void __attribute__((unused)) yd717_init() // CRC, radio on NRF24L01_SetTxRxMode(TX_EN); - NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_PWR_UP)); - NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x3F); // Auto Acknoledgement on all data pipes - NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x3F); // Enable all data pipes + NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_PWR_UP)); + NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // Disable Acknoledgement on all data pipes + NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x00); // Disable all data pipes NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address - NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x1A); // 500uS retransmit t/o, 10 tries + NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // No retransmit NRF24L01_WriteReg(NRF24L01_05_RF_CH, YD717_RF_CHANNEL); // Channel 3C NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps NRF24L01_SetPower(); NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit - 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, YD717_PAYLOADSIZE); // bytes of data payload for pipe 1 - NRF24L01_WriteReg(NRF24L01_12_RX_PW_P1, YD717_PAYLOADSIZE); - NRF24L01_WriteReg(NRF24L01_13_RX_PW_P2, YD717_PAYLOADSIZE); - NRF24L01_WriteReg(NRF24L01_14_RX_PW_P3, YD717_PAYLOADSIZE); - NRF24L01_WriteReg(NRF24L01_15_RX_PW_P4, YD717_PAYLOADSIZE); - NRF24L01_WriteReg(NRF24L01_16_RX_PW_P5, YD717_PAYLOADSIZE); - NRF24L01_WriteReg(NRF24L01_17_FIFO_STATUS, 0x00); // Just in case, no real bits to write here NRF24L01_Activate(0x73); // Activate feature register NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3F); // Enable dynamic payload length on all pipes NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07); // Set feature bits on NRF24L01_Activate(0x73); - // set tx id - NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, 5); - NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5); -} - -static void __attribute__((unused)) YD717_init1() -{ // for bind packets set address to prearranged value known to receiver uint8_t bind_rx_tx_addr[] = {0x65, 0x65, 0x65, 0x65, 0x65}; - uint8_t i; + if( sub_protocol==SYMAX4 ) - for(i=0; i < 5; i++) + for(uint8_t i=0; i < 5; i++) bind_rx_tx_addr[i] = 0x60; else if( sub_protocol==NIHUI ) - for(i=0; i < 5; i++) + for(uint8_t i=0; i < 5; i++) bind_rx_tx_addr[i] = 0x64; - NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, bind_rx_tx_addr, 5); NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, bind_rx_tx_addr, 5); } -static void __attribute__((unused)) YD717_init2() -{ - // set rx/tx address for data phase - NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, 5); - NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5); -} - uint16_t yd717_callback() { - switch (phase) + if(IS_BIND_DONE_on) + yd717_send_packet(0); + else { - case YD717_INIT1: - yd717_send_packet(0); // receiver doesn't re-enter bind mode if connection lost...check if already bound - phase = YD717_BIND3; - break; - case YD717_BIND2: - if (counter == 0) + if (bind_counter == 0) { - if (NRF24L01_packet_ack() == PKT_PENDING) - return YD717_PACKET_CHKTIME; // packet send not yet complete - YD717_init2(); // change to data phase rx/tx address + NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5); // set address yd717_send_packet(0); - phase = YD717_BIND3; + BIND_DONE; // bind complete } else { - if (NRF24L01_packet_ack() == PKT_PENDING) - return YD717_PACKET_CHKTIME; // packet send not yet complete; yd717_send_packet(1); - counter--; + bind_counter--; } - break; - case YD717_BIND3: - switch (NRF24L01_packet_ack()) - { - case PKT_PENDING: - return YD717_PACKET_CHKTIME; // packet send not yet complete - case PKT_ACKED: - phase = YD717_DATA; - BIND_DONE; // bind complete - break; - case PKT_TIMEOUT: - YD717_init1(); // change to bind rx/tx address - counter = YD717_BIND_COUNT; - phase = YD717_BIND2; - yd717_send_packet(1); - } - break; - case YD717_DATA: - if (NRF24L01_packet_ack() == PKT_PENDING) - return YD717_PACKET_CHKTIME; // packet send not yet complete - yd717_send_packet(0); - break; } return YD717_PACKET_PERIOD; // Packet every 8ms } uint16_t initYD717() { + BIND_IN_PROGRESS; // autobind protocol rx_tx_addr[4] = 0xC1; // always uses first data port yd717_init(); - phase = YD717_INIT1; - BIND_IN_PROGRESS; // autobind protocol + bind_counter = YD717_BIND_COUNT; // Call callback in 50ms return YD717_INITIAL_WAIT; } -#endif +#endif \ No newline at end of file