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