mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-02-04 18:48:11 +00:00
initial working version of R9M, 8 CH and BINDING support only
This commit is contained in:
parent
7281c0b5bf
commit
77bf17967d
@ -17,7 +17,7 @@
|
||||
/** FrSky D and X routines **/
|
||||
/******************************/
|
||||
|
||||
#if defined(FRSKYX_CC2500_INO) || defined(FRSKY_RX_CC2500_INO)
|
||||
#if defined(FRSKYX_CC2500_INO) || defined(FRSKY_RX_CC2500_INO) || defined(FRSKYR9_SX1276_INO)
|
||||
//**CRC**
|
||||
const uint16_t PROGMEM FrSkyX_CRC_Short[]={
|
||||
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
|
||||
|
238
Multiprotocol/FrSkyR9_sx1276.ino
Normal file
238
Multiprotocol/FrSkyR9_sx1276.ino
Normal file
@ -0,0 +1,238 @@
|
||||
#if defined(FRSKYR9_SX1276_INO)
|
||||
|
||||
#define REG_IRQ_FLAGS_MASK 0x11
|
||||
|
||||
#define REG_PAYLOAD_LENGTH 0x22
|
||||
|
||||
|
||||
#define REG_FIFO_ADDR_PTR 0x0D
|
||||
#define REG_FIFO_TX_BASE_ADDR 0x0E
|
||||
|
||||
#define REG_OP_MODE 0x01
|
||||
#define REG_DETECT_OPTIMIZE 0x31
|
||||
#define REG_DIO_MAPPING1 0x40
|
||||
#define REG_VERSION 0x42
|
||||
|
||||
|
||||
#define REG_MODEM_CONFIG1 0x1D
|
||||
#define REG_MODEM_CONFIG2 0x1E
|
||||
#define REG_MODEM_CONFIG3 0x26
|
||||
|
||||
#define REG_PREAMBLE_LSB 0x21
|
||||
#define REG_DETECTION_THRESHOLD 0x37
|
||||
|
||||
#define REG_LNA 0x0C
|
||||
|
||||
#define REG_HOP_PERIOD 0x24
|
||||
|
||||
#define REG_PA_DAC 0x4D
|
||||
|
||||
#define REG_PA_CONFIG 0x09
|
||||
|
||||
#define REG_FRF_MSB 0x06
|
||||
|
||||
#define REG_FIFO 0x00
|
||||
|
||||
#define REG_OCP 0x0B
|
||||
|
||||
static uint32_t _freq_map[] =
|
||||
{
|
||||
914472960,
|
||||
914972672,
|
||||
915472384,
|
||||
915972096,
|
||||
916471808,
|
||||
916971520,
|
||||
917471232,
|
||||
917970944,
|
||||
918470656,
|
||||
918970368,
|
||||
919470080,
|
||||
919969792,
|
||||
920469504,
|
||||
920969216,
|
||||
921468928,
|
||||
921968640,
|
||||
922468352,
|
||||
922968064,
|
||||
923467776,
|
||||
923967488,
|
||||
924467200,
|
||||
924966912,
|
||||
925466624,
|
||||
925966336,
|
||||
926466048,
|
||||
926965760,
|
||||
927465472,
|
||||
|
||||
// last two determined by _step
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
static uint8_t _step = 1;
|
||||
|
||||
static uint16_t __attribute__((unused)) FrSkyX_scaleForPXX_temp( uint8_t i )
|
||||
{ //mapped 860,2140(125%) range to 64,1984(PXX values);
|
||||
uint16_t chan_val=convert_channel_frsky(i)-1226;
|
||||
if(i>7) chan_val|=2048; // upper channels offset
|
||||
return chan_val;
|
||||
}
|
||||
|
||||
uint16_t initFrSkyR9()
|
||||
{
|
||||
set_rx_tx_addr(MProtocol_id_master);
|
||||
|
||||
_step = 1 + (random(0xfefefefe) % 24);
|
||||
_freq_map[27] = _freq_map[_step];
|
||||
_freq_map[28] = _freq_map[_step+1];
|
||||
|
||||
SX1276_WriteReg(REG_OP_MODE, 0x80); // sleep
|
||||
SX1276_WriteReg(REG_OP_MODE, 0x81); // standby
|
||||
|
||||
uint8_t buffer[2];
|
||||
buffer[0] = 0x00;
|
||||
buffer[1] = 0x00;
|
||||
SX1276_WriteRegisterMulti(REG_DIO_MAPPING1, buffer, 2);
|
||||
|
||||
uint8_t val = SX1276_ReadReg(REG_DETECT_OPTIMIZE);
|
||||
val = (val & 0b11111000) | 0b00000101;
|
||||
SX1276_WriteReg(REG_DETECT_OPTIMIZE, val);
|
||||
|
||||
// val = SX1276_ReadReg(REG_MODEM_CONFIG2);
|
||||
// val = (val & 0b00011111) | 0b11000000;
|
||||
// writeRegister(REG_MODEM_CONFIG2, val);
|
||||
|
||||
SX1276_WriteReg(REG_MODEM_CONFIG1, 0x93);
|
||||
|
||||
SX1276_WriteReg(REG_MODEM_CONFIG2, 0x60);
|
||||
|
||||
val = SX1276_ReadReg(REG_MODEM_CONFIG3);
|
||||
val = (val & 0b11110011);
|
||||
SX1276_WriteReg(REG_MODEM_CONFIG3, val);
|
||||
|
||||
SX1276_WriteReg(REG_PREAMBLE_LSB, 9);
|
||||
|
||||
SX1276_WriteReg(REG_DETECTION_THRESHOLD, 0x0C);
|
||||
|
||||
SX1276_WriteReg(REG_LNA, 0x23);
|
||||
|
||||
SX1276_WriteReg(REG_HOP_PERIOD, 0x00);
|
||||
|
||||
val = SX1276_ReadReg(REG_PA_DAC);
|
||||
val = (val & 0b11111000) | 0b00000111;
|
||||
SX1276_WriteReg(REG_PA_DAC, val);
|
||||
|
||||
// TODO this can probably be shorter
|
||||
return 20000; // start calling FrSkyR9_callback in 20 milliseconds
|
||||
}
|
||||
|
||||
uint16_t FrSkyR9_callback()
|
||||
{
|
||||
static uint16_t index = 0;
|
||||
uint8_t buffer[3];
|
||||
|
||||
SX1276_WriteReg(REG_OP_MODE, 0x81); // STDBY
|
||||
SX1276_WriteReg(REG_IRQ_FLAGS_MASK, 0xbf); // use only RxDone interrupt
|
||||
|
||||
buffer[0] = 0x00;
|
||||
buffer[1] = 0x00;
|
||||
SX1276_WriteRegisterMulti(REG_DIO_MAPPING1, buffer, 2); // RxDone interrupt mapped to DIO0 (the rest are not used because of the REG_IRQ_FLAGS_MASK)
|
||||
|
||||
// SX1276_WriteReg(REG_PAYLOAD_LENGTH, 13);
|
||||
|
||||
// SX1276_WriteReg(REG_FIFO_ADDR_PTR, 0x00);
|
||||
|
||||
// SX1276_WriteReg(REG_OP_MODE, 0x85); // RXCONTINUOUS
|
||||
// delay(10); // 10 ms
|
||||
|
||||
// SX1276_WriteReg(REG_OP_MODE, 0x81); // STDBY
|
||||
|
||||
SX1276_WriteReg(REG_PA_CONFIG, 0xF0);
|
||||
|
||||
uint32_t freq = _freq_map[index] / 61;
|
||||
|
||||
buffer[0] = (freq & (0xFF << 16)) >> 16;
|
||||
buffer[1] = (freq & (0xFF << 8)) >> 8;
|
||||
buffer[2] = freq & 0xFF;
|
||||
|
||||
SX1276_WriteRegisterMulti(REG_FRF_MSB, buffer, 3); // set current center frequency
|
||||
|
||||
delayMicroseconds(500);
|
||||
|
||||
SX1276_WriteReg(REG_PAYLOAD_LENGTH, 26);
|
||||
SX1276_WriteReg(REG_FIFO_TX_BASE_ADDR, 0x00);
|
||||
SX1276_WriteReg(REG_FIFO_ADDR_PTR, 0x00);
|
||||
|
||||
uint8_t payload[26];
|
||||
|
||||
payload[0] = 0x3C; // ????
|
||||
payload[1] = rx_tx_addr[3]; // unique radio id
|
||||
payload[2] = rx_tx_addr[2]; // unique radio id
|
||||
payload[3] = index; // current channel index
|
||||
payload[4] = _step; // step size and last 2 channels start index
|
||||
payload[5] = RX_num; // receiver number from OpenTX
|
||||
|
||||
// binding mode: 0x00 regular / 0x41 bind?
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
payload[6] = 0x41;
|
||||
else
|
||||
payload[6] = 0x00;
|
||||
|
||||
// TODO
|
||||
payload[7] = 0x00; // fail safe related (looks like the same sequence of numbers as FrskyX protocol)
|
||||
|
||||
// two channel are spread over 3 bytes.
|
||||
// each channel is 11 bit + 1 bit (msb) that states whether
|
||||
// it's part of the upper channels (9-16) or lower (1-8) (0 - lower 1 - upper)
|
||||
|
||||
const int payload_offset = 8;
|
||||
const bool is_upper = false;
|
||||
|
||||
int chan_index = 0;
|
||||
|
||||
for(int i = 0; i < 8; i += 3)
|
||||
{
|
||||
// map channel values (0-2047) to (64-1984)
|
||||
uint16_t ch1 = 64 + (uint16_t)((1920.0f / 2047.0f) * Channel_data[chan_index]);
|
||||
uint16_t ch2 = 64 + (uint16_t)((1920.0f / 2047.0f) * Channel_data[chan_index + 1]);
|
||||
|
||||
chan_index += 2;
|
||||
|
||||
payload[payload_offset + i] = ch1;
|
||||
|
||||
if(is_upper)
|
||||
{
|
||||
payload[payload_offset + i + 1] = ((ch1 >> 8) | 0b1000) | (ch2 << 4);
|
||||
payload[payload_offset + i + 2] = (ch2 >> 4) | 0b10000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
payload[payload_offset + i + 1] = ((ch1 >> 8) & 0b0111) | (ch2 << 4);
|
||||
payload[payload_offset + i + 2] = (ch2 >> 4) & 0b01111111;
|
||||
}
|
||||
}
|
||||
|
||||
payload[20] = 0x08; // ????
|
||||
payload[21] = 0x00; // ????
|
||||
payload[22] = 0x00; // ????
|
||||
payload[23] = 0x00; // ????
|
||||
|
||||
uint16_t crc = FrSkyX_crc(payload, 24);
|
||||
|
||||
payload[24] = crc; // low byte
|
||||
payload[25] = crc >> 8; // high byte
|
||||
|
||||
// write payload to fifo
|
||||
SX1276_WriteRegisterMulti(REG_FIFO, payload, 26);
|
||||
|
||||
index = (index + _step) % 29;
|
||||
|
||||
SX1276_WriteReg(REG_OP_MODE, 0x83); // TX
|
||||
|
||||
// need to clear RegIrqFlags?
|
||||
|
||||
return 19400;
|
||||
}
|
||||
|
||||
#endif
|
@ -78,6 +78,7 @@ const char STR_PELIKAN[] ="Pelikan";
|
||||
const char STR_TIGER[] ="Tiger";
|
||||
const char STR_XK[] ="XK";
|
||||
const char STR_XN297DUMP[] ="XN297DP";
|
||||
const char STR_FRSKYR9[] ="FrSkyR9";
|
||||
|
||||
const char STR_SUBTYPE_FLYSKY[] = "\x04""Std\0""V9x9""V6x6""V912""CX20";
|
||||
const char STR_SUBTYPE_HUBSAN[] = "\x04""H107""H301""H501";
|
||||
@ -118,6 +119,7 @@ const char STR_SUBTYPE_XN297DUMP[] = "\x07""250Kbps""1Mbps\0 ""2Mbps\0 ""Auto\0
|
||||
const char STR_SUBTYPE_ESKY150[] = "\x03""4CH""7CH";
|
||||
const char STR_SUBTYPE_V911S[] = "\x04""Std\0""E119";
|
||||
const char STR_SUBTYPE_XK[] = "\x04""X450""X420";
|
||||
const char STR_SUBTYPE_FRSKYR9[] = "\x07""915MHz\0""868MHz";
|
||||
|
||||
enum
|
||||
{
|
||||
@ -324,6 +326,9 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
#endif
|
||||
#if defined(XN297DUMP_NRF24L01_INO)
|
||||
{PROTO_XN297DUMP, STR_XN297DUMP, 4, STR_SUBTYPE_XN297DUMP, OPTION_RFCHAN },
|
||||
#endif
|
||||
#if defined(FRSKYR9_SX1276_INO)
|
||||
{PROTO_FRSKY_R9, STR_FRSKYR9, 2, STR_SUBTYPE_FRSKYR9, OPTION_NONE },
|
||||
#endif
|
||||
{0x00, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
@ -91,6 +91,7 @@ enum PROTOCOLS
|
||||
PROTO_XK = 62, // =>NRF24L01
|
||||
PROTO_XN297DUMP = 63, // =>NRF24L01
|
||||
PROTO_FRSKYX2 = 64, // =>CC2500
|
||||
PROTO_FRSKY_R9 = 65 // =>SX1276
|
||||
};
|
||||
|
||||
enum Flysky
|
||||
|
@ -1504,6 +1504,14 @@ static void protocol_init()
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef SX1276_INSTALLED
|
||||
#if defined(FRSKYR9_SX1276_INO)
|
||||
case PROTO_FRSKY_R9:
|
||||
next_callback = initFrSkyR9();
|
||||
remote_callback = FrSkyR9_callback;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
debugln("Protocol selected: %d, sub proto %d, rxnum %d, option %d", protocol, sub_protocol, RX_num, option);
|
||||
#ifdef MULTI_NAMES
|
||||
@ -1723,8 +1731,8 @@ void update_serial_data()
|
||||
else
|
||||
if( ((rx_ok_buff[1]&0x80)==0) && ((cur_protocol[1]&0x80)!=0) ) // Bind flag has been reset
|
||||
{ // Request protocol to end bind
|
||||
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO) || defined(FRSKYV_CC2500_INO) || defined(AFHDS2A_A7105_INO)
|
||||
if(protocol==PROTO_FRSKYD || protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYV || protocol==PROTO_AFHDS2A )
|
||||
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO) || defined(FRSKYV_CC2500_INO) || defined(AFHDS2A_A7105_INO) || defined(FRSKYR9_SX1276_INO)
|
||||
if(protocol==PROTO_FRSKYD || protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYV || protocol==PROTO_AFHDS2A || protocol==PROTO_FRSKY_R9 )
|
||||
BIND_DONE;
|
||||
else
|
||||
#endif
|
||||
@ -1871,6 +1879,9 @@ void modules_reset()
|
||||
#ifdef NRF24L01_INSTALLED
|
||||
NRF24L01_Reset();
|
||||
#endif
|
||||
#ifdef SX1276_INSTALLED
|
||||
SX1276_Reset();
|
||||
#endif
|
||||
|
||||
//Wait for every component to reset
|
||||
delayMilliseconds(100);
|
||||
|
38
Multiprotocol/SX1276_SPI.ino
Normal file
38
Multiprotocol/SX1276_SPI.ino
Normal file
@ -0,0 +1,38 @@
|
||||
#ifdef SX1276_INSTALLED
|
||||
|
||||
void SX1276_WriteReg(uint8_t address, uint8_t data)
|
||||
{
|
||||
SPI_CSN_off;
|
||||
SPI_Write(address | 0x80); // MSB 1 = write
|
||||
NOP();
|
||||
SPI_Write(data);
|
||||
SPI_CSN_on;
|
||||
}
|
||||
|
||||
uint8_t SX1276_ReadReg(uint8_t address)
|
||||
{
|
||||
SPI_CSN_off;
|
||||
SPI_Write(address & 0b01111111);
|
||||
uint8_t result = SPI_Read();
|
||||
SPI_CSN_on;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void SX1276_WriteRegisterMulti(uint8_t address, const uint8_t data[], uint8_t length)
|
||||
{
|
||||
SPI_CSN_off;
|
||||
SPI_Write(address | 0x80); // MSB 1 = write
|
||||
for(uint8_t i = 0; i < length; i++)
|
||||
SPI_Write(data[i]);
|
||||
SPI_CSN_on;
|
||||
}
|
||||
|
||||
uint8_t SX1276_Reset()
|
||||
{
|
||||
//TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
@ -77,6 +77,7 @@
|
||||
#define CYRF6936_INSTALLED
|
||||
#define CC2500_INSTALLED
|
||||
#define NRF24L01_INSTALLED
|
||||
//#define SX1276_INSTALLED
|
||||
|
||||
/** OrangeRX TX **/
|
||||
//If you compile for the OrangeRX TX module you need to select the correct board type.
|
||||
@ -223,6 +224,8 @@
|
||||
#define YD717_NRF24L01_INO
|
||||
#define ZSX_NRF24L01_INO
|
||||
|
||||
//The protocols below need a SX1276 to be installed
|
||||
//#define FRSKYR9_SX1276_INO
|
||||
|
||||
/***************************/
|
||||
/*** PROTOCOLS SETTINGS ***/
|
||||
|
Loading…
x
Reference in New Issue
Block a user