mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-02-04 21:08:12 +00:00
New DSM RX protocol
This commit is contained in:
parent
4cfde0a80a
commit
cc6be6027d
@ -313,6 +313,7 @@ const uint8_t PROGMEM DEVO_j6pro_sopcodes[][8] = {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void __attribute__((unused)) CYRF_PROGMEM_ConfigSOPCode(const uint8_t *data)
|
static void __attribute__((unused)) CYRF_PROGMEM_ConfigSOPCode(const uint8_t *data)
|
||||||
{
|
{
|
||||||
uint8_t code[8];
|
uint8_t code[8];
|
||||||
|
181
Multiprotocol/DSM.ino
Normal file
181
Multiprotocol/DSM.ino
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
#if defined(DSM_CYRF6936_INO) || defined(DSM_RX_CYRF6936_INO)
|
||||||
|
|
||||||
|
#include "iface_cyrf6936.h"
|
||||||
|
|
||||||
|
uint8_t sop_col;
|
||||||
|
|
||||||
|
const uint8_t PROGMEM DSM_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)) DSM_read_code(uint8_t *buf, uint8_t row, uint8_t col, uint8_t len)
|
||||||
|
{
|
||||||
|
for(uint8_t i=0;i<len;i++)
|
||||||
|
buf[i]=pgm_read_byte_near( &DSM_pncodes[row][col][i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t PROGMEM DSM_init_vals[][2] = {
|
||||||
|
{CYRF_02_TX_CTRL, 0x00}, // All TX interrupt disabled
|
||||||
|
{CYRF_05_RX_CTRL, 0x00}, // All RX interrupt disabled
|
||||||
|
{CYRF_28_CLK_EN, 0x02}, // Force receive clock enable
|
||||||
|
{CYRF_32_AUTO_CAL_TIME, 0x3c}, // Default init value
|
||||||
|
{CYRF_35_AUTOCAL_OFFSET, 0x14}, // Default init value
|
||||||
|
{CYRF_06_RX_CFG, 0x4A}, // LNA enabled, RX override enabled, Fast turn mode enabled, RX is 1MHz below TX
|
||||||
|
{CYRF_1B_TX_OFFSET_LSB, 0x55}, // Default init value
|
||||||
|
{CYRF_1C_TX_OFFSET_MSB, 0x05}, // Default init value
|
||||||
|
{CYRF_39_ANALOG_CTRL, 0x01}, // All slow for synth setting time
|
||||||
|
{CYRF_01_TX_LENGTH, 0x10}, // 16 bytes packet
|
||||||
|
{CYRF_14_EOP_CTRL, 0x02}, // Set EOP Symbol Count to 2
|
||||||
|
{CYRF_12_DATA64_THOLD, 0x0a}, // 64 Chip Data PN corelator threshold, default datasheet value is 0x0E
|
||||||
|
//Below is for bind only
|
||||||
|
{CYRF_03_TX_CFG, 0x38 | CYRF_BIND_POWER}, //64 chip codes, SDR mode
|
||||||
|
{CYRF_10_FRAMING_CFG, 0x4a}, // SOP disabled, no LEN field and SOP correlator of 0x0a but since SOP is disabled...
|
||||||
|
{CYRF_1F_TX_OVERRIDE, 0x04}, // Disable TX CRC, no ACK, use TX synthesizer
|
||||||
|
{CYRF_1E_RX_OVERRIDE, 0x14}, // Disable RX CRC, Force receive data rate, use RX synthesizer
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t PROGMEM DSM_data_vals[][2] = {
|
||||||
|
{CYRF_29_RX_ABORT, 0x20}, // Abort RX operation in case we are coming from bind
|
||||||
|
{CYRF_0F_XACT_CFG, 0x24}, // Force Idle
|
||||||
|
{CYRF_29_RX_ABORT, 0x00}, // Clear abort RX
|
||||||
|
{CYRF_03_TX_CFG, 0x28 | CYRF_HIGH_POWER}, // 64 chip codes, 8DR mode
|
||||||
|
{CYRF_10_FRAMING_CFG, 0xea}, // SOP enabled, SOP_CODE_ADR 64 chips, Packet len enabled, SOP correlator 0x0A
|
||||||
|
{CYRF_1F_TX_OVERRIDE, 0x00}, // CRC16 enabled, no ACK
|
||||||
|
{CYRF_1E_RX_OVERRIDE, 0x00}, // CRC16 enabled, no ACK
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __attribute__((unused)) DSM_cyrf_config()
|
||||||
|
{
|
||||||
|
for(uint8_t i = 0; i < sizeof(DSM_init_vals) / 2; i++)
|
||||||
|
CYRF_WriteRegister(pgm_read_byte_near(&DSM_init_vals[i][0]), pgm_read_byte_near(&DSM_init_vals[i][1]));
|
||||||
|
CYRF_WritePreamble(0x333304);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) DSM_cyrf_configdata()
|
||||||
|
{
|
||||||
|
for(uint8_t i = 0; i < sizeof(DSM_data_vals) / 2; i++)
|
||||||
|
CYRF_WriteRegister(pgm_read_byte_near(&DSM_data_vals[i][0]), pgm_read_byte_near(&DSM_data_vals[i][1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t __attribute__((unused)) DSM_get_pn_row(uint8_t channel, bool dsmx)
|
||||||
|
{
|
||||||
|
return (dsmx ? (channel - 2) % 5 : channel % 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) DSM_set_sop_data_crc(bool ch2, bool dsmx)
|
||||||
|
{
|
||||||
|
//The crc for channel '1' is NOT(mfgid[0] << 8 + mfgid[1])
|
||||||
|
//The crc for channel '2' is (mfgid[0] << 8 + mfgid[1])
|
||||||
|
if(ch2)
|
||||||
|
CYRF_ConfigCRCSeed(seed); //CH2
|
||||||
|
else
|
||||||
|
CYRF_ConfigCRCSeed(~seed); //CH1
|
||||||
|
|
||||||
|
uint8_t pn_row = DSM_get_pn_row(hopping_frequency[hopping_frequency_no], dsmx);
|
||||||
|
uint8_t code[16];
|
||||||
|
DSM_read_code(code,pn_row,sop_col,8); // pn_row between 0 and 4, sop_col between 1 and 7
|
||||||
|
CYRF_ConfigSOPCode(code);
|
||||||
|
DSM_read_code(code,pn_row,7 - sop_col,8); // 7-sop_col between 0 and 6
|
||||||
|
DSM_read_code(code+8,pn_row,7 - sop_col + 1,8); // 7-sop_col+1 between 1 and 7
|
||||||
|
CYRF_ConfigDataCode(code, 16);
|
||||||
|
|
||||||
|
CYRF_ConfigRFChannel(hopping_frequency[hopping_frequency_no]);
|
||||||
|
hopping_frequency_no++;
|
||||||
|
if(dsmx)
|
||||||
|
hopping_frequency_no %=23;
|
||||||
|
else
|
||||||
|
hopping_frequency_no %=2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) DSM_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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
466
Multiprotocol/DSM_Rx_cyrf6936.ino
Normal file
466
Multiprotocol/DSM_Rx_cyrf6936.ino
Normal file
@ -0,0 +1,466 @@
|
|||||||
|
/*
|
||||||
|
This project is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Multiprotocol is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(DSM_RX_CYRF6936_INO)
|
||||||
|
|
||||||
|
#include "iface_cyrf6936.h"
|
||||||
|
|
||||||
|
//#define DSM_DEBUG_RF
|
||||||
|
|
||||||
|
uint8_t DSM_rx_type;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
DSM_RX_BIND1 = 0,
|
||||||
|
DSM_RX_BIND2,
|
||||||
|
DSM_RX_DATA_PREP,
|
||||||
|
DSM2_RX_SCAN,
|
||||||
|
DSM_RX_DATA_CH1,
|
||||||
|
DSM_RX_DATA_CH2,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __attribute__((unused)) DSM_Rx_init()
|
||||||
|
{
|
||||||
|
DSM_cyrf_config();
|
||||||
|
if(IS_BIND_IN_PROGRESS)
|
||||||
|
{
|
||||||
|
//64 SDR Mode is configured so only the 8 first values are needed but need to write 16 values...
|
||||||
|
uint8_t code[16];
|
||||||
|
DSM_read_code(code,0,8,8);
|
||||||
|
CYRF_ConfigDataCode(code, 16);
|
||||||
|
CYRF_ConfigRFChannel(1);
|
||||||
|
CYRF_SetTxRxMode(RX_EN); // Force end state read
|
||||||
|
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x83); // Prepare to receive
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DSM_cyrf_configdata();
|
||||||
|
rx_disable_lna = IS_POWER_FLAG_on;
|
||||||
|
CYRF_WriteRegister(CYRF_06_RX_CFG, rx_disable_lna ? 0x0A:0xCA); // AGC enabled/disabled, LNA enabled/disabled, Attenuator disabled, RX override enabled, Fast turn mode enabled, RX is 1MHz below TX
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t convert_channel_DSM_nolimit(int32_t val)
|
||||||
|
{
|
||||||
|
val=(val-0x150)*(CHANNEL_MAX_100-CHANNEL_MIN_100)/(0x6B0-0x150)+CHANNEL_MIN_100;
|
||||||
|
if(val<0)
|
||||||
|
val=0;
|
||||||
|
else
|
||||||
|
if(val>2047)
|
||||||
|
val=2047;
|
||||||
|
return (uint16_t)val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t __attribute__((unused)) DSM_Rx_check_packet()
|
||||||
|
{
|
||||||
|
uint8_t rx_status=CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
|
||||||
|
if((rx_status & 0x03) == 0x02) // RXC=1, RXE=0 then 2nd check is required (debouncing)
|
||||||
|
rx_status |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
|
||||||
|
if((rx_status & 0x07) == 0x02)
|
||||||
|
{ // data received with no errors
|
||||||
|
if(CYRF_ReadRegister(CYRF_09_RX_COUNT)==16)
|
||||||
|
{// 16 bytes
|
||||||
|
// Read packet
|
||||||
|
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // Need to set RXOW before data read
|
||||||
|
CYRF_ReadDataPacketLen(packet, 16);
|
||||||
|
|
||||||
|
// Check packet ID
|
||||||
|
if ((DSM_rx_type&0x80) == 0)
|
||||||
|
{//DSM2
|
||||||
|
packet[0] ^= 0xff;
|
||||||
|
packet[1] ^= 0xff;
|
||||||
|
}
|
||||||
|
if(packet[0] == cyrfmfg_id[2] && packet[1] == cyrfmfg_id[3])
|
||||||
|
return 0x02; // Packet ok
|
||||||
|
}
|
||||||
|
return 0x00; // Wrong size or ID -> nothing received
|
||||||
|
}
|
||||||
|
return rx_status; // Return error code
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) DSM_Rx_build_telemetry_packet()
|
||||||
|
{
|
||||||
|
uint8_t nbr_bits = 11;
|
||||||
|
if((DSM_rx_type&0xF0) == 0x00)
|
||||||
|
nbr_bits=10; // Only DSM_22 is using a resolution of 1024
|
||||||
|
|
||||||
|
// Extract channels
|
||||||
|
uint8_t idx;
|
||||||
|
for (uint8_t i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
uint16_t value=(packet[i*2+2]<<8) | packet[i*2+3];
|
||||||
|
if(value!=0xFFFF)
|
||||||
|
{
|
||||||
|
idx=(value&0x7FFF)>>nbr_bits; // retrieve channel index 0..12
|
||||||
|
if(idx<13)
|
||||||
|
{
|
||||||
|
if(nbr_bits==10) value <<= 1; // switch to 11 bits
|
||||||
|
value &= 0x7FF;
|
||||||
|
rx_rc_chan[CH_TAER[idx]]=convert_channel_DSM_nolimit(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buid telemetry packet
|
||||||
|
idx=0;
|
||||||
|
packet_in[idx++] = RX_LQI;
|
||||||
|
packet_in[idx++] = RX_LQI;
|
||||||
|
packet_in[idx++] = 0; // start channel
|
||||||
|
packet_in[idx++] = 12; // number of channels in packet
|
||||||
|
|
||||||
|
// Pack channels
|
||||||
|
uint32_t bits = 0;
|
||||||
|
uint8_t bitsavailable = 0;
|
||||||
|
for (uint8_t i = 0; i < 12; i++)
|
||||||
|
{
|
||||||
|
bits |= ((uint32_t)rx_rc_chan[i]) << bitsavailable;
|
||||||
|
bitsavailable += 11;
|
||||||
|
while (bitsavailable >= 8)
|
||||||
|
{
|
||||||
|
packet_in[idx++] = bits & 0xff;
|
||||||
|
bits >>= 8;
|
||||||
|
bitsavailable -= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(bitsavailable)
|
||||||
|
packet_in[idx++] = bits & 0xff;
|
||||||
|
// Send telemetry
|
||||||
|
telemetry_link = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool __attribute__((unused)) DSM_Rx_bind_check_validity()
|
||||||
|
{
|
||||||
|
uint16_t sum = 384 - 0x10;//
|
||||||
|
for(uint8_t i = 0; i < 8; i++)
|
||||||
|
sum += packet_in[i];
|
||||||
|
if( packet_in[8] != (sum>>8) || packet_in[9] != (sum&0xFF)) //Checksum
|
||||||
|
return false;
|
||||||
|
for(uint8_t i = 8; i < 14; i++)
|
||||||
|
sum += packet_in[i];
|
||||||
|
if( packet_in[14] != (sum>>8) || packet_in[15] != (sum&0xFF)) //Checksum
|
||||||
|
return false;
|
||||||
|
if(memcmp(packet_in,packet_in+4,4)) //Check ID
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) DSM_Rx_build_bind_packet()
|
||||||
|
{
|
||||||
|
uint16_t sum = 384 - 0x10;//
|
||||||
|
packet[0] = 0xff ^ cyrfmfg_id[0]; // ID
|
||||||
|
packet[1] = 0xff ^ cyrfmfg_id[1];
|
||||||
|
packet[2] = 0xff ^ cyrfmfg_id[2];
|
||||||
|
packet[3] = 0xff ^ cyrfmfg_id[3];
|
||||||
|
packet[4] = 0x01; // RX version
|
||||||
|
packet[5] = num_ch; // Number of channels
|
||||||
|
packet[6] = DSM_rx_type; // DSM type, let's just send back whatever the TX gave us...
|
||||||
|
packet[7] = 0x00; // Unknown
|
||||||
|
for(uint8_t i = 0; i < 8; i++)
|
||||||
|
sum += packet[i];
|
||||||
|
packet[8] = sum >> 8;
|
||||||
|
packet[9] = sum & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) DSM_abort_channel_rx(uint8_t ch)
|
||||||
|
{
|
||||||
|
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20); // Abort RX operation
|
||||||
|
CYRF_SetTxRxMode(IS_POWER_FLAG_on ? TXRX_OFF:RX_EN); // Force end state read
|
||||||
|
if (rx_disable_lna != IS_POWER_FLAG_on)
|
||||||
|
{
|
||||||
|
rx_disable_lna = IS_POWER_FLAG_on;
|
||||||
|
CYRF_WriteRegister(CYRF_06_RX_CFG, rx_disable_lna ? 0x0A:0xCA); // AGC enabled/disabled, LNA enabled/disabled, Attenuator disabled, RX override enabled, Fast turn mode enabled, RX is 1MHz below TX
|
||||||
|
}
|
||||||
|
if(ch&0x02) DSM_set_sop_data_crc(true ,DSM_rx_type&0x80); // Set sop data,crc seed and rf channel using CH1, DSM2/X
|
||||||
|
if(ch&0x01) DSM_set_sop_data_crc(false,DSM_rx_type&0x80); // Set sop data,crc seed and rf channel using CH1, DSM2/X
|
||||||
|
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00); // Clear abort RX operation
|
||||||
|
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x83); // Prepare to receive
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t DSM_Rx_callback()
|
||||||
|
{
|
||||||
|
uint8_t rx_status;
|
||||||
|
static uint8_t read_retry=10;
|
||||||
|
static uint16_t pps_counter;
|
||||||
|
static uint32_t pps_timer = 0;
|
||||||
|
|
||||||
|
switch (phase)
|
||||||
|
{
|
||||||
|
case DSM_RX_BIND1:
|
||||||
|
//Check received data
|
||||||
|
rx_status = CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
|
||||||
|
if((rx_status & 0x03) == 0x02) // RXC=1, RXE=0 then 2nd check is required (debouncing)
|
||||||
|
rx_status |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
|
||||||
|
if((rx_status & 0x07) == 0x02 && read_retry)
|
||||||
|
{ // data received with no errors
|
||||||
|
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // Need to set RXOW before data read
|
||||||
|
rx_status=CYRF_ReadRegister(CYRF_09_RX_COUNT);
|
||||||
|
debugln("RX:%d",rx_status);
|
||||||
|
if(rx_status==16)
|
||||||
|
{
|
||||||
|
CYRF_ReadDataPacketLen(packet_in, 16);
|
||||||
|
if(DSM_Rx_bind_check_validity())
|
||||||
|
{
|
||||||
|
// store tx info into eeprom
|
||||||
|
uint16_t temp = DSM_RX_EEPROM_OFFSET;
|
||||||
|
debug("ID=");
|
||||||
|
for(uint8_t i=0;i<4;i++)
|
||||||
|
{
|
||||||
|
cyrfmfg_id[i]=packet_in[i]^0xFF;
|
||||||
|
//eeprom_write_byte((EE_ADDR)temp++, cyrfmfg_id[i]);
|
||||||
|
debug(" %02X", cyrfmfg_id[i]);
|
||||||
|
}
|
||||||
|
// check num_ch
|
||||||
|
num_ch=packet_in[11];
|
||||||
|
if(num_ch>12) num_ch=12;
|
||||||
|
//check DSM_rx_type
|
||||||
|
/*packet[12] 1 byte -> max DSM type allowed:
|
||||||
|
0x01 => 22ms 1024 DSM2 1 packet => number of channels is <8 and no telemetry
|
||||||
|
0x02 => 22ms 1024 DSM2 2 packets => either a number of channel >7 or telemetry enable RX
|
||||||
|
0x12 => 11ms 2048 DSM2 2 packets => can be any number of channels with/without telemetry
|
||||||
|
0xA2 => 22ms 2048 DSMX 1 packet => number of channels is <8 and no telemetry
|
||||||
|
0xB2 => 11ms 2048 DSMX => can be any number of channels with/without telemetry
|
||||||
|
(0x01 or 0xA2) and num_ch < 7 => 22ms else 11ms
|
||||||
|
&0x80 => false=DSM2, true=DSMX
|
||||||
|
&0xF0 => false=1024, true=2048 */
|
||||||
|
DSM_rx_type=packet_in[12];
|
||||||
|
switch(DSM_rx_type)
|
||||||
|
{
|
||||||
|
case 0x01:
|
||||||
|
if(num_ch>7) DSM_rx_type = 0x02; // Can't be 0x01 with this number of channels
|
||||||
|
break;
|
||||||
|
case 0xA2:
|
||||||
|
if(num_ch>7) DSM_rx_type = 0xB2; // Can't be 0xA2 with this number of channels
|
||||||
|
break;
|
||||||
|
case 0x02:
|
||||||
|
case 0x12:
|
||||||
|
case 0xB2:
|
||||||
|
break;
|
||||||
|
default: // Unknown type, default to DSMX 11ms
|
||||||
|
DSM_rx_type = 0xB2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// eeprom_write_byte((EE_ADDR)temp, DSM_rx_type);
|
||||||
|
debugln(", num_ch=%d, type=%02X",num_ch, DSM_rx_type);
|
||||||
|
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20); // Abort RX operation
|
||||||
|
CYRF_SetTxRxMode(TX_EN); // Force end state TX
|
||||||
|
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00); // Clear abort RX
|
||||||
|
DSM_Rx_build_bind_packet();
|
||||||
|
bind_counter=500;
|
||||||
|
phase++; // DSM_RX_BIND2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(read_retry)
|
||||||
|
read_retry--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hopping_frequency_no++; // Change channel
|
||||||
|
hopping_frequency_no %= 0x50;
|
||||||
|
hopping_frequency_no |= 0x01; // Odd channels only
|
||||||
|
CYRF_ConfigRFChannel(hopping_frequency_no);
|
||||||
|
//debugln("ch:%d",hopping_frequency_no);
|
||||||
|
read_retry = 10;
|
||||||
|
DSM_abort_channel_rx(0); // Abort RX operation and receive
|
||||||
|
}
|
||||||
|
return 12500;
|
||||||
|
case DSM_RX_BIND2:
|
||||||
|
//Transmit settings back
|
||||||
|
CYRF_WriteDataPacketLen(packet,10); // Does not work ?!?!?
|
||||||
|
if(bind_counter--==0)
|
||||||
|
{
|
||||||
|
BIND_DONE;
|
||||||
|
phase++; // DSM_RX_DATA_PREP
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DSM_RX_DATA_PREP:
|
||||||
|
hopping_frequency_no = 0;
|
||||||
|
read_retry=0;
|
||||||
|
rx_data_started = false;
|
||||||
|
read_retry=0;
|
||||||
|
pps_counter = 0;
|
||||||
|
RX_LQI = 100;
|
||||||
|
DSM_cyrf_configdata();
|
||||||
|
pps_timer=millis();
|
||||||
|
sop_col = (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + 2) & 0x07;
|
||||||
|
seed = (cyrfmfg_id[0] << 8) + cyrfmfg_id[1];
|
||||||
|
if(DSM_rx_type&0x80)
|
||||||
|
{ // DSMX
|
||||||
|
DSM_calc_dsmx_channel(); // Build hop table
|
||||||
|
DSM_abort_channel_rx(1); // Abort RX operation, set sop&data&seed&rf using CH1, DSM2/X and receive
|
||||||
|
phase=DSM_RX_DATA_CH1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // DSM2
|
||||||
|
rf_ch_num=0;
|
||||||
|
hopping_frequency_no = 0;
|
||||||
|
hopping_frequency[0] = 3;
|
||||||
|
hopping_frequency[1] = 0;
|
||||||
|
DSM_abort_channel_rx(1); // Abort RX operation, set sop&data&seed&rf using CH1, DSM2/X and receive
|
||||||
|
phase=DSM2_RX_SCAN;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DSM2_RX_SCAN: // Scan for DSM2 frequencies
|
||||||
|
//Received something ?
|
||||||
|
rx_status = DSM_Rx_check_packet();
|
||||||
|
if(rx_status == 0x02)
|
||||||
|
{ // data received with no errors
|
||||||
|
debugln("CH%d:Found %d",rf_ch_num+1,hopping_frequency[rf_ch_num]);
|
||||||
|
read_retry=0;
|
||||||
|
if(rf_ch_num)
|
||||||
|
{ // Both CH1 and CH2 found
|
||||||
|
read_retry=0;
|
||||||
|
hopping_frequency_no=0;
|
||||||
|
DSM_abort_channel_rx(1); // Abort RX operation, set sop&data&seed&rf using CH1, DSM2/X and receive
|
||||||
|
pps_timer=millis();
|
||||||
|
phase++; // DSM_RX_DATA_CH1
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rf_ch_num++; // CH1 found, scan for CH2
|
||||||
|
hopping_frequency_no = 1;
|
||||||
|
if(hopping_frequency[1] < 3) // If no CH2 keep then restart from current
|
||||||
|
hopping_frequency[1]=hopping_frequency[0]+1;
|
||||||
|
DSM_abort_channel_rx(2); // Abort RX operation, set sop&data&seed&rf using CH2, DSM2/X and receive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
read_retry++;
|
||||||
|
if(read_retry>50) // After 50ms
|
||||||
|
{ // Try next channel
|
||||||
|
debugln("CH%d:Next channel",rf_ch_num+1);
|
||||||
|
read_retry=0;
|
||||||
|
hopping_frequency_no = rf_ch_num;
|
||||||
|
hopping_frequency[rf_ch_num]++;
|
||||||
|
if(hopping_frequency[rf_ch_num] > 73) hopping_frequency[rf_ch_num] = 3;
|
||||||
|
DSM_abort_channel_rx(rf_ch_num+1); // Abort RX operation, set sop&data&seed&rf using CH1/2, DSM2/X and receive
|
||||||
|
}
|
||||||
|
else if(rx_status & 0x02)
|
||||||
|
{ // data received with errors
|
||||||
|
if((rx_status & 0x01) && rf_ch_num==0)
|
||||||
|
hopping_frequency[1] = hopping_frequency[0];// Might be CH2 since it's a CRC error so keep it
|
||||||
|
debugln("CH%d:RX error",rf_ch_num+1);
|
||||||
|
DSM_abort_channel_rx(0); // Abort RX operation and receive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1000;
|
||||||
|
case DSM_RX_DATA_CH1:
|
||||||
|
//Packets per second
|
||||||
|
if (millis() - pps_timer >= 1000)
|
||||||
|
{//182pps @11ms, 91pps @22ms
|
||||||
|
pps_timer = millis();
|
||||||
|
if(DSM_rx_type!=0xA2 && DSM_rx_type!=0x01) // if 11ms
|
||||||
|
pps_counter >>=1; // then /2
|
||||||
|
debugln("%d pps", pps_counter);
|
||||||
|
RX_LQI = pps_counter; // max=91pps
|
||||||
|
pps_counter = 0;
|
||||||
|
}
|
||||||
|
//Received something ?
|
||||||
|
rx_status = DSM_Rx_check_packet();
|
||||||
|
if(rx_status == 0x02)
|
||||||
|
{ // data received with no errors
|
||||||
|
#ifdef DSM_DEBUG_RF
|
||||||
|
debugln("CH1:RX");
|
||||||
|
#endif
|
||||||
|
DSM_Rx_build_telemetry_packet();
|
||||||
|
rx_data_started = true;
|
||||||
|
pps_counter++;
|
||||||
|
DSM_abort_channel_rx(2); // Abort RX operation, set sop&data&seed&rf using CH2, DSM2/X and receive
|
||||||
|
phase++;
|
||||||
|
return 5000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
read_retry++;
|
||||||
|
if(rx_data_started && read_retry>6) // After 6*500=3ms
|
||||||
|
{ // skip to CH2
|
||||||
|
#ifdef DSM_DEBUG_RF
|
||||||
|
debugln("CH1:Skip to CH2");
|
||||||
|
#endif
|
||||||
|
DSM_abort_channel_rx(2); // Abort RX operation, set sop&data&seed&rf using CH2, DSM2/X and receive
|
||||||
|
phase++;
|
||||||
|
return 4000;
|
||||||
|
}
|
||||||
|
if(rx_data_started && RX_LQI==0)
|
||||||
|
{ // communication lost
|
||||||
|
#ifdef DSM_DEBUG_RF
|
||||||
|
debugln("CH1:Restart...");
|
||||||
|
#endif
|
||||||
|
phase=DSM_RX_DATA_PREP;
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
if(read_retry>250)
|
||||||
|
{ // move to next RF channel
|
||||||
|
#ifdef DSM_DEBUG_RF
|
||||||
|
debugln("CH1:Scan");
|
||||||
|
#endif
|
||||||
|
DSM_abort_channel_rx(3); // Abort RX operation, set sop&data&seed&rf using CH2 then CH1, DSM2/X and receive
|
||||||
|
read_retry=0;
|
||||||
|
}
|
||||||
|
else if(rx_status & 0x02)
|
||||||
|
{ // data received with errors
|
||||||
|
#ifdef DSM_DEBUG_RF
|
||||||
|
debugln("CH1:RX error %02X",rx_status);
|
||||||
|
#endif
|
||||||
|
DSM_abort_channel_rx(0); // Abort RX operation and receive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 500;
|
||||||
|
case DSM_RX_DATA_CH2:
|
||||||
|
rx_status = DSM_Rx_check_packet();
|
||||||
|
if(rx_status == 0x02)
|
||||||
|
{ // data received with no errors
|
||||||
|
#ifdef DSM_DEBUG_RF
|
||||||
|
debugln("CH2:RX");
|
||||||
|
#endif
|
||||||
|
DSM_Rx_build_telemetry_packet();
|
||||||
|
pps_counter++;
|
||||||
|
}
|
||||||
|
#ifdef DSM_DEBUG_RF
|
||||||
|
else
|
||||||
|
debugln("CH2:No RX");
|
||||||
|
#endif
|
||||||
|
DSM_abort_channel_rx(1); // Abort RX operation, set sop&data&seed&rf using CH1, DSM2/X and receive
|
||||||
|
read_retry=0;
|
||||||
|
phase=DSM_RX_DATA_CH1;
|
||||||
|
if(DSM_rx_type==0xA2) //|| DSM_rx_type==0x01 -> not needed for DSM2 since we are ok to listen even if there will be nothing
|
||||||
|
return 15000; //22ms
|
||||||
|
else
|
||||||
|
return 4000; //11ms
|
||||||
|
}
|
||||||
|
return 10000;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t initDSM_Rx()
|
||||||
|
{
|
||||||
|
DSM_Rx_init();
|
||||||
|
hopping_frequency_no = 0;
|
||||||
|
|
||||||
|
if (IS_BIND_IN_PROGRESS)
|
||||||
|
phase = DSM_RX_BIND1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint16_t temp = DSM_RX_EEPROM_OFFSET;
|
||||||
|
debug("ID=");
|
||||||
|
for(uint8_t i=0;i<4;i++)
|
||||||
|
{
|
||||||
|
cyrfmfg_id[i]=eeprom_read_byte((EE_ADDR)temp++);
|
||||||
|
debug(" %02X", cyrfmfg_id[i]);
|
||||||
|
}
|
||||||
|
DSM_rx_type=0xB2; //eeprom_read_byte((EE_ADDR)temp);
|
||||||
|
debugln(", type=%02X", DSM_rx_type);
|
||||||
|
phase = DSM_RX_DATA_PREP;
|
||||||
|
}
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -41,7 +41,6 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
uint8_t sop_col;
|
|
||||||
uint8_t ch_map[14];
|
uint8_t ch_map[14];
|
||||||
const uint8_t PROGMEM DSM_ch_map_progmem[][14] = {
|
const uint8_t PROGMEM DSM_ch_map_progmem[][14] = {
|
||||||
//22+11ms for 4..7 channels
|
//22+11ms for 4..7 channels
|
||||||
@ -61,116 +60,6 @@ const uint8_t PROGMEM DSM_ch_map_progmem[][14] = {
|
|||||||
{1, 5, 2, 3, 4, 8, 9, 1, 5, 2, 3, 0, 7, 6 }, //10ch - DX18
|
{1, 5, 2, 3, 4, 8, 9, 1, 5, 2, 3, 0, 7, 6 }, //10ch - DX18
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t PROGMEM DSM_pncodes[5][8][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)) DSM_read_code(uint8_t *buf, uint8_t row, uint8_t col, uint8_t len)
|
|
||||||
{
|
|
||||||
for(uint8_t i=0;i<len;i++)
|
|
||||||
buf[i]=pgm_read_byte_near( &DSM_pncodes[row][col][i] );
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t __attribute__((unused)) DSM_get_pn_row(uint8_t channel)
|
|
||||||
{
|
|
||||||
return ((sub_protocol == DSMX_11 || sub_protocol == DSMX_22 )? (channel - 2) % 5 : channel % 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t PROGMEM DSM_init_vals[][2] = {
|
|
||||||
{CYRF_02_TX_CTRL, 0x00}, // All TX interrupt disabled
|
|
||||||
{CYRF_05_RX_CTRL, 0x00}, // All RX interrupt disabled
|
|
||||||
{CYRF_28_CLK_EN, 0x02}, // Force receive clock enable
|
|
||||||
{CYRF_32_AUTO_CAL_TIME, 0x3c}, // Default init value
|
|
||||||
{CYRF_35_AUTOCAL_OFFSET, 0x14}, // Default init value
|
|
||||||
{CYRF_06_RX_CFG, 0x4A}, // LNA enabled, RX override enabled, Fast turn mode enabled, RX is 1MHz below TX
|
|
||||||
{CYRF_1B_TX_OFFSET_LSB, 0x55}, // Default init value
|
|
||||||
{CYRF_1C_TX_OFFSET_MSB, 0x05}, // Default init value
|
|
||||||
{CYRF_39_ANALOG_CTRL, 0x01}, // All slow for synth setting time
|
|
||||||
{CYRF_01_TX_LENGTH, 0x10}, // 16 bytes packet
|
|
||||||
{CYRF_14_EOP_CTRL, 0x02}, // Set EOP Symbol Count to 2
|
|
||||||
{CYRF_12_DATA64_THOLD, 0x0a}, // 64 Chip Data PN corelator threshold, default datasheet value is 0x0E
|
|
||||||
//Below is for bind only
|
|
||||||
{CYRF_03_TX_CFG, 0x38 | CYRF_BIND_POWER}, //64 chip codes, SDR mode
|
|
||||||
{CYRF_10_FRAMING_CFG, 0x4a}, // SOP disabled, no LEN field and SOP correlator of 0x0a but since SOP is disabled...
|
|
||||||
{CYRF_1F_TX_OVERRIDE, 0x04}, // Disable TX CRC, no ACK, use TX synthesizer
|
|
||||||
{CYRF_1E_RX_OVERRIDE, 0x14}, // Disable RX CRC, Force receive data rate, use RX synthesizer
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint8_t PROGMEM DSM_data_vals[][2] = {
|
|
||||||
{CYRF_29_RX_ABORT, 0x20}, // Abort RX operation in case we are coming from bind
|
|
||||||
{CYRF_0F_XACT_CFG, 0x24}, // Force Idle
|
|
||||||
{CYRF_29_RX_ABORT, 0x00}, // Clear abort RX
|
|
||||||
{CYRF_03_TX_CFG, 0x28 | CYRF_HIGH_POWER}, // 64 chip codes, 8DR mode
|
|
||||||
{CYRF_10_FRAMING_CFG, 0xea}, // SOP enabled, SOP_CODE_ADR 64 chips, Packet len enabled, SOP correlator 0x0A
|
|
||||||
{CYRF_1F_TX_OVERRIDE, 0x00}, // CRC16 enabled, no ACK
|
|
||||||
{CYRF_1E_RX_OVERRIDE, 0x00}, // CRC16 enabled, no ACK
|
|
||||||
};
|
|
||||||
|
|
||||||
static void __attribute__((unused)) DSM_cyrf_config()
|
|
||||||
{
|
|
||||||
for(uint8_t i = 0; i < sizeof(DSM_init_vals) / 2; i++)
|
|
||||||
CYRF_WriteRegister(pgm_read_byte_near(&DSM_init_vals[i][0]), pgm_read_byte_near(&DSM_init_vals[i][1]));
|
|
||||||
CYRF_WritePreamble(0x333304);
|
|
||||||
CYRF_ConfigRFChannel(0x61);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) DSM_build_bind_packet()
|
static void __attribute__((unused)) DSM_build_bind_packet()
|
||||||
{
|
{
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
@ -214,16 +103,12 @@ static void __attribute__((unused)) DSM_initialize_bind_phase()
|
|||||||
{
|
{
|
||||||
CYRF_ConfigRFChannel(DSM_BIND_CHANNEL); //This seems to be random?
|
CYRF_ConfigRFChannel(DSM_BIND_CHANNEL); //This seems to be random?
|
||||||
//64 SDR Mode is configured so only the 8 first values are needed but need to write 16 values...
|
//64 SDR Mode is configured so only the 8 first values are needed but need to write 16 values...
|
||||||
CYRF_ConfigDataCode((const uint8_t*)"\xD7\xA1\x54\xB1\x5E\x89\xAE\x86\xc6\x94\x22\xfe\x48\xe6\x57\x4e", 16);
|
uint8_t code[16];
|
||||||
|
DSM_read_code(code,0,8,8);
|
||||||
|
CYRF_ConfigDataCode(code, 16);
|
||||||
DSM_build_bind_packet();
|
DSM_build_bind_packet();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((unused)) DSM_cyrf_configdata()
|
|
||||||
{
|
|
||||||
for(uint8_t i = 0; i < sizeof(DSM_data_vals) / 2; i++)
|
|
||||||
CYRF_WriteRegister(pgm_read_byte_near(&DSM_data_vals[i][0]), pgm_read_byte_near(&DSM_data_vals[i][1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) DSM_update_channels()
|
static void __attribute__((unused)) DSM_update_channels()
|
||||||
{
|
{
|
||||||
prev_option=option;
|
prev_option=option;
|
||||||
@ -259,7 +144,7 @@ static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
|
|||||||
packet[0] = (0xff ^ cyrfmfg_id[2]);
|
packet[0] = (0xff ^ cyrfmfg_id[2]);
|
||||||
packet[1] = (0xff ^ cyrfmfg_id[3]);
|
packet[1] = (0xff ^ cyrfmfg_id[3]);
|
||||||
if(sub_protocol==DSM2_22)
|
if(sub_protocol==DSM2_22)
|
||||||
bits=10; // Only DSM_22 is using a resolution of 1024
|
bits=10; // Only DSM2_22 is using a resolution of 1024
|
||||||
}
|
}
|
||||||
#ifdef DSM_THROTTLE_KILL_CH
|
#ifdef DSM_THROTTLE_KILL_CH
|
||||||
uint16_t kill_ch=Channel_data[DSM_THROTTLE_KILL_CH-1];
|
uint16_t kill_ch=Channel_data[DSM_THROTTLE_KILL_CH-1];
|
||||||
@ -284,7 +169,7 @@ static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
#ifdef DSM_MAX_THROW
|
#ifdef DSM_MAX_THROW
|
||||||
value=Channel_data[CH_TAER[idx]]; // -100%..+100% => 1024..1976us and -125%..+125% => 904..2096us based on Redcon 6 channel DSM2 RX
|
value=Channel_data[CH_TAER[idx]]; // -100%..+100% => 1024..1976us and -125%..+125% => 904..2096us based on Redcon 6 channel DSM2 RX
|
||||||
#else
|
#else
|
||||||
if(option & 0x80)
|
if(option & 0x80)
|
||||||
value=Channel_data[CH_TAER[idx]]; // -100%..+100% => 1024..1976us and -125%..+125% => 904..2096us based on Redcon 6 channel DSM2 RX
|
value=Channel_data[CH_TAER[idx]]; // -100%..+100% => 1024..1976us and -125%..+125% => 904..2096us based on Redcon 6 channel DSM2 RX
|
||||||
@ -299,66 +184,6 @@ static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((unused)) DSM_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 = DSM_get_pn_row(hopping_frequency[hopping_frequency_no]);
|
|
||||||
uint8_t code[16];
|
|
||||||
DSM_read_code(code,pn_row,sop_col,8); // pn_row between 0 and 4, sop_col between 1 and 7
|
|
||||||
CYRF_ConfigSOPCode(code);
|
|
||||||
DSM_read_code(code,pn_row,7 - sop_col,8); // 7-sop_col between 0 and 6
|
|
||||||
DSM_read_code(code+8,pn_row,7 - sop_col + 1,8); // 7-sop_col+1 between 1 and 7
|
|
||||||
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)) DSM_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()
|
static uint8_t __attribute__((unused)) DSM_Check_RX_packet()
|
||||||
{
|
{
|
||||||
uint8_t result=1; // assume good packet
|
uint8_t result=1; // assume good packet
|
||||||
@ -418,17 +243,17 @@ uint16_t ReadDsm()
|
|||||||
rx_phase |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
|
rx_phase |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
|
||||||
if((rx_phase & 0x07) == 0x02)
|
if((rx_phase & 0x07) == 0x02)
|
||||||
{ // data received with no errors
|
{ // data received with no errors
|
||||||
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // need to set RXOW before data read
|
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // Need to set RXOW before data read
|
||||||
len=CYRF_ReadRegister(CYRF_09_RX_COUNT);
|
if(CYRF_ReadRegister(CYRF_09_RX_COUNT)==10) // Len
|
||||||
if(len>TELEMETRY_BUFFER_SIZE-2)
|
|
||||||
len=TELEMETRY_BUFFER_SIZE-2;
|
|
||||||
CYRF_ReadDataPacketLen(packet_in+1, len);
|
|
||||||
if(len==10 && DSM_Check_RX_packet())
|
|
||||||
{
|
{
|
||||||
packet_in[0]=0x80;
|
CYRF_ReadDataPacketLen(packet_in+1, 10);
|
||||||
telemetry_link=1; // send received data on serial
|
if(DSM_Check_RX_packet())
|
||||||
phase++;
|
{
|
||||||
return 2000;
|
packet_in[0]=0x80;
|
||||||
|
telemetry_link=1; // Send received data on serial
|
||||||
|
phase++;
|
||||||
|
return 2000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -441,7 +266,7 @@ uint16_t ReadDsm()
|
|||||||
}
|
}
|
||||||
if( --bind_counter == 0 )
|
if( --bind_counter == 0 )
|
||||||
{ // Exit if no answer has been received for some time
|
{ // Exit if no answer has been received for some time
|
||||||
phase++; // DSM_CHANSEL
|
phase++; // DSM_CHANSEL
|
||||||
return 7000 ;
|
return 7000 ;
|
||||||
}
|
}
|
||||||
return 7000;
|
return 7000;
|
||||||
@ -452,7 +277,7 @@ uint16_t ReadDsm()
|
|||||||
CYRF_SetTxRxMode(TX_EN);
|
CYRF_SetTxRxMode(TX_EN);
|
||||||
hopping_frequency_no = 0;
|
hopping_frequency_no = 0;
|
||||||
phase = DSM_CH1_WRITE_A; // in fact phase++
|
phase = DSM_CH1_WRITE_A; // in fact phase++
|
||||||
DSM_set_sop_data_crc();
|
DSM_set_sop_data_crc(phase==DSM_CH1_CHECK_A||phase==DSM_CH1_CHECK_B, sub_protocol==DSMX_11||sub_protocol==DSMX_22);
|
||||||
return 10000;
|
return 10000;
|
||||||
case DSM_CH1_WRITE_A:
|
case DSM_CH1_WRITE_A:
|
||||||
#ifdef MULTI_SYNC
|
#ifdef MULTI_SYNC
|
||||||
@ -487,7 +312,7 @@ uint16_t ReadDsm()
|
|||||||
CYRF_SetTxRxMode(TX_EN);
|
CYRF_SetTxRxMode(TX_EN);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
DSM_set_sop_data_crc();
|
DSM_set_sop_data_crc(phase==DSM_CH1_CHECK_A||phase==DSM_CH1_CHECK_B, sub_protocol==DSMX_11 || sub_protocol==DSMX_22);
|
||||||
phase++; // change from CH1_CHECK to CH2_WRITE
|
phase++; // change from CH1_CHECK to CH2_WRITE
|
||||||
return DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY;
|
return DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY;
|
||||||
}
|
}
|
||||||
@ -529,11 +354,11 @@ uint16_t ReadDsm()
|
|||||||
phase = DSM_CH1_WRITE_A; //Transmit lower
|
phase = DSM_CH1_WRITE_A; //Transmit lower
|
||||||
CYRF_SetTxRxMode(TX_EN); //TX mode
|
CYRF_SetTxRxMode(TX_EN); //TX mode
|
||||||
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00); //Clear abort RX operation
|
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00); //Clear abort RX operation
|
||||||
DSM_set_sop_data_crc();
|
DSM_set_sop_data_crc(phase==DSM_CH1_CHECK_A||phase==DSM_CH1_CHECK_B, sub_protocol==DSMX_11||sub_protocol==DSMX_22);
|
||||||
return DSM_READ_DELAY;
|
return DSM_READ_DELAY;
|
||||||
#else
|
#else
|
||||||
// No telemetry
|
// No telemetry
|
||||||
DSM_set_sop_data_crc();
|
DSM_set_sop_data_crc(phase==DSM_CH1_CHECK_A||phase==DSM_CH1_CHECK_B, sub_protocol==DSMX_11||sub_protocol==DSMX_22);
|
||||||
if (phase == DSM_CH2_CHECK_A)
|
if (phase == DSM_CH2_CHECK_A)
|
||||||
{
|
{
|
||||||
if(num_ch > 7 || sub_protocol==DSM2_11 || sub_protocol==DSMX_11)
|
if(num_ch > 7 || sub_protocol==DSM2_11 || sub_protocol==DSMX_11)
|
||||||
@ -565,6 +390,8 @@ uint16_t initDsm()
|
|||||||
cyrfmfg_id[rx_tx_addr[0]%3]^=0x01; //Change a bit so sop_col will be different from 0
|
cyrfmfg_id[rx_tx_addr[0]%3]^=0x01; //Change a bit so sop_col will be different from 0
|
||||||
sop_col = (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + 2) & 0x07;
|
sop_col = (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + 2) & 0x07;
|
||||||
}
|
}
|
||||||
|
//Calc CRC seed
|
||||||
|
seed = (cyrfmfg_id[0] << 8) + cyrfmfg_id[1];
|
||||||
//Hopping frequencies
|
//Hopping frequencies
|
||||||
if (sub_protocol == DSMX_11 || sub_protocol == DSMX_22)
|
if (sub_protocol == DSMX_11 || sub_protocol == DSMX_22)
|
||||||
DSM_calc_dsmx_channel();
|
DSM_calc_dsmx_channel();
|
||||||
|
@ -67,3 +67,4 @@
|
|||||||
67,LR12,LR12,LR12_6ch
|
67,LR12,LR12,LR12_6ch
|
||||||
68,Skyartec
|
68,Skyartec
|
||||||
69,ESKYv2,150V2
|
69,ESKYv2,150V2
|
||||||
|
70,DSM_RX
|
@ -21,6 +21,7 @@ const char STR_FRSKYD[] ="FrSky D";
|
|||||||
const char STR_HISKY[] ="Hisky";
|
const char STR_HISKY[] ="Hisky";
|
||||||
const char STR_V2X2[] ="V2x2";
|
const char STR_V2X2[] ="V2x2";
|
||||||
const char STR_DSM[] ="DSM";
|
const char STR_DSM[] ="DSM";
|
||||||
|
const char STR_DSM_RX[] ="DSM_RX";
|
||||||
const char STR_DEVO[] ="Devo";
|
const char STR_DEVO[] ="Devo";
|
||||||
const char STR_YD717[] ="YD717";
|
const char STR_YD717[] ="YD717";
|
||||||
const char STR_KN[] ="KN";
|
const char STR_KN[] ="KN";
|
||||||
@ -191,6 +192,9 @@ const mm_protocol_definition multi_protocols[] = {
|
|||||||
#if defined(DSM_CYRF6936_INO)
|
#if defined(DSM_CYRF6936_INO)
|
||||||
{PROTO_DSM, STR_DSM, 4, STR_SUBTYPE_DSM, OPTION_MAXTHR },
|
{PROTO_DSM, STR_DSM, 4, STR_SUBTYPE_DSM, OPTION_MAXTHR },
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(DSM_RX_CYRF6936_INO)
|
||||||
|
{PROTO_DSM_RX, STR_DSM_RX, 0, NO_SUBTYPE, OPTION_NONE },
|
||||||
|
#endif
|
||||||
#if defined(ESKY_NRF24L01_INO)
|
#if defined(ESKY_NRF24L01_INO)
|
||||||
{PROTO_ESKY, STR_ESKY, 2, STR_SUBTYPE_ESKY, OPTION_NONE },
|
{PROTO_ESKY, STR_ESKY, 2, STR_SUBTYPE_ESKY, OPTION_NONE },
|
||||||
#endif
|
#endif
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#define VERSION_MAJOR 1
|
#define VERSION_MAJOR 1
|
||||||
#define VERSION_MINOR 3
|
#define VERSION_MINOR 3
|
||||||
#define VERSION_REVISION 0
|
#define VERSION_REVISION 0
|
||||||
#define VERSION_PATCH_LEVEL 96
|
#define VERSION_PATCH_LEVEL 98
|
||||||
|
|
||||||
//******************
|
//******************
|
||||||
// Protocols
|
// Protocols
|
||||||
@ -96,6 +96,7 @@ enum PROTOCOLS
|
|||||||
PROTO_FRSKYL = 67, // =>CC2500
|
PROTO_FRSKYL = 67, // =>CC2500
|
||||||
PROTO_SKYARTEC = 68, // =>CC2500
|
PROTO_SKYARTEC = 68, // =>CC2500
|
||||||
PROTO_ESKY150V2 = 69, // =>CC2500+NRF24L01
|
PROTO_ESKY150V2 = 69, // =>CC2500+NRF24L01
|
||||||
|
PROTO_DSM_RX = 70, // =>CYRF6936
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Flysky
|
enum Flysky
|
||||||
@ -397,8 +398,8 @@ enum MultiPacketTypes
|
|||||||
//***************
|
//***************
|
||||||
//*** Tests ***
|
//*** Tests ***
|
||||||
//***************
|
//***************
|
||||||
#define IS_FAILSAFE_PROTOCOL ( (protocol==PROTO_HISKY && sub_protocol==HK310) || protocol==PROTO_AFHDS2A || protocol==PROTO_DEVO || protocol==PROTO_SFHSS || protocol==PROTO_WK2x01 || protocol== PROTO_HOTT || protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYX2 )
|
#define IS_FAILSAFE_PROTOCOL ( (protocol==PROTO_HISKY && sub_protocol==HK310) || protocol==PROTO_AFHDS2A || protocol==PROTO_DEVO || protocol==PROTO_SFHSS || protocol==PROTO_WK2x01 || protocol== PROTO_HOTT || protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYX2 || protocol==PROTO_FRSKY_R9)
|
||||||
#define IS_CHMAP_PROTOCOL ( (protocol==PROTO_HISKY && sub_protocol==HK310) || protocol==PROTO_AFHDS2A || protocol==PROTO_DEVO || protocol==PROTO_SFHSS || protocol==PROTO_WK2x01 || protocol== PROTO_DSM || protocol==PROTO_SLT || protocol==PROTO_FLYSKY || protocol==PROTO_ESKY || protocol==PROTO_J6PRO || protocol==PROTO_PELIKAN || protocol==PROTO_SKYARTEC || protocol==PROTO_ESKY150V2 )
|
#define IS_CHMAP_PROTOCOL ( (protocol==PROTO_HISKY && sub_protocol==HK310) || protocol==PROTO_AFHDS2A || protocol==PROTO_DEVO || protocol==PROTO_SFHSS || protocol==PROTO_WK2x01 || protocol== PROTO_DSM || protocol==PROTO_SLT || protocol==PROTO_FLYSKY || protocol==PROTO_ESKY || protocol==PROTO_J6PRO || protocol==PROTO_PELIKAN || protocol==PROTO_SKYARTEC || protocol==PROTO_ESKY150V2 || protocol==PROTO_DSM_RX)
|
||||||
|
|
||||||
//***************
|
//***************
|
||||||
//*** Flags ***
|
//*** Flags ***
|
||||||
@ -674,7 +675,8 @@ enum {
|
|||||||
#define FRSKYD_CLONE_EEPROM_OFFSET 771 // (1) format + (3) TX ID + (47) channels, 51 bytes, end is 822
|
#define FRSKYD_CLONE_EEPROM_OFFSET 771 // (1) format + (3) TX ID + (47) channels, 51 bytes, end is 822
|
||||||
#define FRSKYX_CLONE_EEPROM_OFFSET 822 // (1) format + (3) TX ID + (47) channels, 51 bytes, end is 873
|
#define FRSKYX_CLONE_EEPROM_OFFSET 822 // (1) format + (3) TX ID + (47) channels, 51 bytes, end is 873
|
||||||
#define FRSKYX2_CLONE_EEPROM_OFFSET 873 // (1) format + (3) TX ID, 4 bytes, end is 877
|
#define FRSKYX2_CLONE_EEPROM_OFFSET 873 // (1) format + (3) TX ID, 4 bytes, end is 877
|
||||||
//#define CONFIG_EEPROM_OFFSET 877 // Current configuration of the multimodule
|
#define DSM_RX_EEPROM_OFFSET 877 // (4) TX ID + format, 5 bytes, end is 882
|
||||||
|
//#define CONFIG_EEPROM_OFFSET 882 // Current configuration of the multimodule
|
||||||
|
|
||||||
//****************************************
|
//****************************************
|
||||||
//*** MULTI protocol serial definition ***
|
//*** MULTI protocol serial definition ***
|
||||||
|
@ -751,7 +751,7 @@ bool Update_All()
|
|||||||
update_led_status();
|
update_led_status();
|
||||||
#if defined(TELEMETRY)
|
#if defined(TELEMETRY)
|
||||||
#if ( !( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) ) )
|
#if ( !( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) ) )
|
||||||
if((protocol == PROTO_BAYANG_RX) || (protocol == PROTO_AFHDS2A_RX) || (protocol == PROTO_FRSKY_RX) || (protocol == PROTO_SCANNER) || (protocol==PROTO_FRSKYD) || (protocol==PROTO_BAYANG) || (protocol==PROTO_NCC1701) || (protocol==PROTO_BUGS) || (protocol==PROTO_BUGSMINI) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_FRSKYX) || (protocol==PROTO_DSM) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC) || (protocol==PROTO_HOTT) || (protocol==PROTO_FRSKYX2) || (protocol==PROTO_PROPEL) || (protocol==PROTO_DEVO))
|
if((protocol == PROTO_BAYANG_RX) || (protocol == PROTO_AFHDS2A_RX) || (protocol == PROTO_FRSKY_RX) || (protocol == PROTO_SCANNER) || (protocol==PROTO_FRSKYD) || (protocol==PROTO_BAYANG) || (protocol==PROTO_NCC1701) || (protocol==PROTO_BUGS) || (protocol==PROTO_BUGSMINI) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_FRSKYX) || (protocol==PROTO_DSM) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC) || (protocol==PROTO_HOTT) || (protocol==PROTO_FRSKYX2) || (protocol==PROTO_PROPEL) || (protocol==PROTO_DEVO) || (protocol==PROTO_DSM_RX))
|
||||||
#endif
|
#endif
|
||||||
if(IS_DISABLE_TELEM_off)
|
if(IS_DISABLE_TELEM_off)
|
||||||
TelemetryUpdate();
|
TelemetryUpdate();
|
||||||
@ -1232,6 +1232,13 @@ static void protocol_init()
|
|||||||
remote_callback = ReadDsm;
|
remote_callback = ReadDsm;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(DSM_RX_CYRF6936_INO)
|
||||||
|
case PROTO_DSM_RX:
|
||||||
|
PE2_on; //antenna RF4
|
||||||
|
next_callback = initDSM_Rx();
|
||||||
|
remote_callback = DSM_Rx_callback;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
#if defined(WFLY_CYRF6936_INO)
|
#if defined(WFLY_CYRF6936_INO)
|
||||||
case PROTO_WFLY:
|
case PROTO_WFLY:
|
||||||
PE2_on; //antenna RF4
|
PE2_on; //antenna RF4
|
||||||
|
@ -267,7 +267,7 @@ static void multi_send_status()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined (FRSKY_RX_TELEMETRY) || defined (AFHDS2A_RX_TELEMETRY) || defined (BAYANG_RX_TELEMETRY)
|
#if defined (FRSKY_RX_TELEMETRY) || defined (AFHDS2A_RX_TELEMETRY) || defined (BAYANG_RX_TELEMETRY) || defined (DSM_RX_CYRF6936_INO)
|
||||||
void receiver_channels_frame()
|
void receiver_channels_frame()
|
||||||
{
|
{
|
||||||
uint16_t len = packet_in[3] * 11; // 11 bit per channel
|
uint16_t len = packet_in[3] * 11; // 11 bit per channel
|
||||||
@ -939,8 +939,8 @@ void TelemetryUpdate()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined (FRSKY_RX_TELEMETRY) || defined(AFHDS2A_RX_TELEMETRY) || defined (BAYANG_RX_TELEMETRY)
|
#if defined (FRSKY_RX_TELEMETRY) || defined(AFHDS2A_RX_TELEMETRY) || defined (BAYANG_RX_TELEMETRY) || defined (DSM_RX_CYRF6936_INO)
|
||||||
if ((telemetry_link & 1) && (protocol == PROTO_FRSKY_RX || protocol == PROTO_AFHDS2A_RX || protocol == PROTO_BAYANG_RX))
|
if ((telemetry_link & 1) && (protocol == PROTO_FRSKY_RX || protocol == PROTO_AFHDS2A_RX || protocol == PROTO_BAYANG_RX || protocol == PROTO_DSM_RX) )
|
||||||
{
|
{
|
||||||
receiver_channels_frame();
|
receiver_channels_frame();
|
||||||
telemetry_link &= ~1;
|
telemetry_link &= ~1;
|
||||||
|
@ -204,6 +204,7 @@
|
|||||||
#ifndef CYRF6936_INSTALLED
|
#ifndef CYRF6936_INSTALLED
|
||||||
#undef DEVO_CYRF6936_INO
|
#undef DEVO_CYRF6936_INO
|
||||||
#undef DSM_CYRF6936_INO
|
#undef DSM_CYRF6936_INO
|
||||||
|
#undef DSM_RX_CYRF6936_INO
|
||||||
#undef HOTT_CC2500_INO
|
#undef HOTT_CC2500_INO
|
||||||
#undef J6PRO_CYRF6936_INO
|
#undef J6PRO_CYRF6936_INO
|
||||||
#undef TRAXXAS_CYRF6936_INO
|
#undef TRAXXAS_CYRF6936_INO
|
||||||
@ -307,6 +308,7 @@
|
|||||||
#undef BAYANG_RX_TELEMETRY
|
#undef BAYANG_RX_TELEMETRY
|
||||||
#undef BAYANG_RX_NRF24L01_INO
|
#undef BAYANG_RX_NRF24L01_INO
|
||||||
#undef DEVO_HUB_TELEMETRY
|
#undef DEVO_HUB_TELEMETRY
|
||||||
|
#undef DSM_RX_CYRF6936_INO
|
||||||
#else
|
#else
|
||||||
#if defined(MULTI_TELEMETRY) && defined(MULTI_STATUS)
|
#if defined(MULTI_TELEMETRY) && defined(MULTI_STATUS)
|
||||||
#error You should choose either MULTI_TELEMETRY or MULTI_STATUS but not both.
|
#error You should choose either MULTI_TELEMETRY or MULTI_STATUS but not both.
|
||||||
|
@ -170,6 +170,7 @@
|
|||||||
//The protocols below need a CYRF6936 to be installed
|
//The protocols below need a CYRF6936 to be installed
|
||||||
#define DEVO_CYRF6936_INO
|
#define DEVO_CYRF6936_INO
|
||||||
#define DSM_CYRF6936_INO
|
#define DSM_CYRF6936_INO
|
||||||
|
#define DSM_RX_CYRF6936_INO
|
||||||
#define J6PRO_CYRF6936_INO
|
#define J6PRO_CYRF6936_INO
|
||||||
#define TRAXXAS_CYRF6936_INO
|
#define TRAXXAS_CYRF6936_INO
|
||||||
#define WFLY_CYRF6936_INO
|
#define WFLY_CYRF6936_INO
|
||||||
@ -231,7 +232,7 @@
|
|||||||
#define ZSX_NRF24L01_INO
|
#define ZSX_NRF24L01_INO
|
||||||
|
|
||||||
//The protocols below need a SX1276 to be installed
|
//The protocols below need a SX1276 to be installed
|
||||||
//#define FRSKYR9_SX1276_INO
|
#define FRSKYR9_SX1276_INO
|
||||||
|
|
||||||
/***************************/
|
/***************************/
|
||||||
/*** PROTOCOLS SETTINGS ***/
|
/*** PROTOCOLS SETTINGS ***/
|
||||||
@ -544,6 +545,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
|||||||
DSM2_11
|
DSM2_11
|
||||||
DSMX_22
|
DSMX_22
|
||||||
DSMX_11
|
DSMX_11
|
||||||
|
PROTO_DSM_RX
|
||||||
|
NONE
|
||||||
PROTO_E01X
|
PROTO_E01X
|
||||||
E012
|
E012
|
||||||
E015
|
E015
|
||||||
|
@ -79,6 +79,7 @@ CFlie|38|CFlie||||||||NRF24L01|
|
|||||||
[Devo](Protocols_Details.md#DEVO---7)|7|Devo|8CH|10CH|12CH|6CH|7CH|||CYRF6936|
|
[Devo](Protocols_Details.md#DEVO---7)|7|Devo|8CH|10CH|12CH|6CH|7CH|||CYRF6936|
|
||||||
[DM002](Protocols_Details.md#DM002---33)|33|DM002||||||||NRF24L01|XN297
|
[DM002](Protocols_Details.md#DM002---33)|33|DM002||||||||NRF24L01|XN297
|
||||||
[DSM](Protocols_Details.md#DSM---6)|6|DSM2-22|DSM2-11|DSMX-22|DSMX-11|AUTO||||CYRF6936|
|
[DSM](Protocols_Details.md#DSM---6)|6|DSM2-22|DSM2-11|DSMX-22|DSMX-11|AUTO||||CYRF6936|
|
||||||
|
[DSM_RX](Protocols_Details.md#DSM_RX---70)|70|||||||||CYRF6936|
|
||||||
[E01X](Protocols_Details.md#E01X---45)|45|E012|E015|E016H||||||NRF24L01|XN297/HS6200
|
[E01X](Protocols_Details.md#E01X---45)|45|E012|E015|E016H||||||NRF24L01|XN297/HS6200
|
||||||
[ESky](Protocols_Details.md#ESKY---16)|16|ESky|Std|ET4||||||NRF24L01|
|
[ESky](Protocols_Details.md#ESKY---16)|16|ESky|Std|ET4||||||NRF24L01|
|
||||||
[ESky150](Protocols_Details.md#ESKY150---35)|35|ESKY150||||||||NRF24L01|
|
[ESky150](Protocols_Details.md#ESKY150---35)|35|ESKY150||||||||NRF24L01|
|
||||||
@ -669,6 +670,20 @@ The current radio firmware which are able to use the "AUTO" feature are erskyTX
|
|||||||
For these firmwares, you must have a telemetry enabled TX and you have to make sure you set the Telemetry "Usr proto" to "DSMx".
|
For these firmwares, you must have a telemetry enabled TX and you have to make sure you set the Telemetry "Usr proto" to "DSMx".
|
||||||
Also on er9x you will need to be sure to match the polarity of the telemetry serial (normal or inverted by bitbashing), while on erskyTX you can set "Invert COM1" accordinlgy.
|
Also on er9x you will need to be sure to match the polarity of the telemetry serial (normal or inverted by bitbashing), while on erskyTX you can set "Invert COM1" accordinlgy.
|
||||||
|
|
||||||
|
## DSM_RX - *70*
|
||||||
|
The DSM receiver protocol enables master/slave trainning, separate access from 2 different radios to the same model,...
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- Automatically support DSM 2/X 11/22 1024/2048
|
||||||
|
- Currently the bind response does not work which means that the TX doesn't know what the DSM RX protocol has selected. **You must manually select the right protocol on the TX**. By default the RX will select DSMX/11ms.
|
||||||
|
- Available in OpenTX 2.3.3, Trainer Mode Master/Multi
|
||||||
|
- Channels 1..4 are remapped to the module default
|
||||||
|
- Extended limits supported
|
||||||
|
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||||
|
---|---|---|---|---|---|---|---|---|----|----|----
|
||||||
|
A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||||
|
|
||||||
## J6Pro - *22*
|
## J6Pro - *22*
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||||
|
Loading…
x
Reference in New Issue
Block a user