diff --git a/Multiprotocol/CYRF6936_SPI.ino b/Multiprotocol/CYRF6936_SPI.ino
index bcc0d6c..20136b8 100644
--- a/Multiprotocol/CYRF6936_SPI.ino
+++ b/Multiprotocol/CYRF6936_SPI.ino
@@ -98,13 +98,15 @@ void CYRF_SetTxRxMode(uint8_t mode)
{
if(mode==TXRX_OFF)
{
- CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24); // 4=IDLE, 8=TX, C=RX
+ if(protocol!=PROTO_WFLY)
+ CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24); // 4=IDLE, 8=TX, C=RX
CYRF_WriteRegister(CYRF_0E_GPIO_CTRL,0x00); // XOUT=0 PACTL=0
}
else
{
//Set the post tx/rx state
- CYRF_WriteRegister(CYRF_0F_XACT_CFG, mode == TX_EN ? 0x28 : 0x2C); // 4=IDLE, 8=TX, C=RX
+ if(protocol!=PROTO_WFLY)
+ CYRF_WriteRegister(CYRF_0F_XACT_CFG, mode == TX_EN ? 0x28 : 0x2C); // 4=IDLE, 8=TX, C=RX
if(mode == TX_EN)
#ifdef ORANGE_TX_BLUE
CYRF_WriteRegister(CYRF_0E_GPIO_CTRL,0x20); // XOUT=1, PACTL=0
@@ -203,9 +205,9 @@ void CYRF_ReadDataPacketLen(uint8_t dpbuffer[], uint8_t length)
static void CYRF_WriteDataPacketLen(const uint8_t dpbuffer[], uint8_t len)
{
CYRF_WriteRegister(CYRF_01_TX_LENGTH, len);
- CYRF_WriteRegister(CYRF_02_TX_CTRL, 0x40);
+ CYRF_WriteRegister(CYRF_02_TX_CTRL, 0x43); // 0x40
CYRF_WriteRegisterMulti(CYRF_20_TX_BUFFER, dpbuffer, len);
- CYRF_WriteRegister(CYRF_02_TX_CTRL, 0xBF);
+ CYRF_WriteRegister(CYRF_02_TX_CTRL, 0x83); // 0xBF
}
void CYRF_WriteDataPacket(const uint8_t dpbuffer[])
diff --git a/Multiprotocol/DSM_cyrf6936.ino b/Multiprotocol/DSM_cyrf6936.ino
index 98fc67f..5586227 100644
--- a/Multiprotocol/DSM_cyrf6936.ino
+++ b/Multiprotocol/DSM_cyrf6936.ino
@@ -448,9 +448,9 @@ uint16_t ReadDsm()
case DSM_CH1_CHECK_B:
case DSM_CH2_CHECK_A:
case DSM_CH2_CHECK_B:
- start=micros();
- while ((uint8_t)micros()-start < 100) // Wait max 100µs, max I've seen is 50µs
- if(CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x02)
+ start=(uint8_t)micros();
+ while ((uint8_t)((uint8_t)micros()-(uint8_t)start) < 100) // Wait max 100µs, max I've seen is 50µs
+ if((CYRF_ReadRegister(CYRF_02_TX_CTRL) & 0x80) == 0x00)
break;
if(phase==DSM_CH1_CHECK_A || phase==DSM_CH1_CHECK_B)
{
diff --git a/Multiprotocol/Hitec_cc2500.ino b/Multiprotocol/Hitec_cc2500.ino
index cdcc3ee..2f57628 100644
--- a/Multiprotocol/Hitec_cc2500.ino
+++ b/Multiprotocol/Hitec_cc2500.ino
@@ -39,13 +39,11 @@ enum {
HITEC_RX2 = 0x08,
};
-#define HITEC_FREQ0_VAL 0xE8
-
const PROGMEM uint8_t HITEC_init_values[] = {
/* 00 */ 0x2F, 0x2E, 0x2F, 0x07, 0xD3, 0x91, 0xFF, 0x04,
- /* 08 */ 0x45, 0x00, 0x00, 0x12, 0x00, 0x5C, 0x85, HITEC_FREQ0_VAL + HITEC_COARSE,
+ /* 08 */ 0x45, 0x00, 0x00, 0x12, 0x00, 0x5C, 0x85, 0xE8 + HITEC_COARSE,
/* 10 */ 0x3D, 0x3B, 0x73, 0x73, 0x7A, 0x01, 0x07, 0x30,
- /* 18 */ 0x08, 0x1D, 0x1C, 0xC7, 0x00, 0xB0, 0x87, 0x6B,
+ /* 18 */ 0x08, 0x1D, 0x1C, 0xC7, 0x40, 0xB0, 0x87, 0x6B,
/* 20 */ 0xF8, 0xB6, 0x10, 0xEA, 0x0A, 0x00, 0x11
};
@@ -325,7 +323,7 @@ uint16_t ReadHITEC()
// 0C,1C,A1,2B,00,16,00,00,00,00,00,16,00,2C,8E
// 0C,1C,A1,2B,00,17,00,00,00,42,44,17,00,48,8D -> 42=>temperature3 0x42-0x28=26°C,44=>temperature4 0x44-0x28=28°C
// 0C,1C,A1,2B,00,18,00,00,00,00,00,18,00,50,92
- debug(",telem");
+ debug(",telem,%02x",pkt[14]&0x7F);
#if defined(HITEC_FW_TELEMETRY)
if(sub_protocol==OPT_FW)
{
diff --git a/Multiprotocol/J6Pro_cyrf6936.ino b/Multiprotocol/J6Pro_cyrf6936.ino
index ff8b43f..454739a 100644
--- a/Multiprotocol/J6Pro_cyrf6936.ino
+++ b/Multiprotocol/J6Pro_cyrf6936.ino
@@ -128,7 +128,7 @@ static void __attribute__((unused)) j6pro_set_radio_channels()
uint16_t ReadJ6Pro()
{
- uint32_t start;
+ uint16_t start;
switch(phase)
{
@@ -144,11 +144,11 @@ uint16_t ReadJ6Pro()
phase = J6PRO_BIND_03_START;
return 3000; //3msec
case J6PRO_BIND_03_START:
- start=micros();
- while (micros()-start < 500) // Wait max 500µs
- if(CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x06)
- break;
- CYRF_ConfigRFChannel(0x53);
+ start=(uint16_t)micros();
+ while ((uint16_t)((uint16_t)micros()-(uint16_t)start) < 500) // Wait max 500µs
+ if((CYRF_ReadRegister(CYRF_02_TX_CTRL) & 0x80) == 0x00)
+ break; // Packet transmission complete
+ CYRF_ConfigRFChannel(0x53);
CYRF_SetTxRxMode(RX_EN);
//CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a);
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80);
diff --git a/Multiprotocol/Multi.txt b/Multiprotocol/Multi.txt
index 577f81d..c0741c2 100644
--- a/Multiprotocol/Multi.txt
+++ b/Multiprotocol/Multi.txt
@@ -37,3 +37,4 @@
37,CORONA,COR_V1,COR_V2,FD_V3
38,CFlie
39,Hitec,OPT_FW,OPT_HUB,MINIMA
+40,WFLY
diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h
index c39ffbb..b0eb649 100644
--- a/Multiprotocol/Multiprotocol.h
+++ b/Multiprotocol/Multiprotocol.h
@@ -19,7 +19,7 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 2
#define VERSION_REVISION 0
-#define VERSION_PATCH_LEVEL 31
+#define VERSION_PATCH_LEVEL 32
//******************
// Protocols
@@ -66,6 +66,7 @@ enum PROTOCOLS
PROTO_CORONA = 37, // =>CC2500
PROTO_CFLIE = 38, // =>NRF24L01
PROTO_HITEC = 39, // =>CC2500
+ PROTO_WFLY = 40, // =>CYRF6936
};
enum Flysky
@@ -569,6 +570,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
CORONA 37
CFlie 38
Hitec 39
+ WFLY 40
BindBit=> 0x80 1=Bind/0=No
AutoBindBit=> 0x40 1=Yes /0=No
RangeCheck=> 0x20 1=Yes /0=No
diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino
index 6c1ae97..daa6541 100644
--- a/Multiprotocol/Multiprotocol.ino
+++ b/Multiprotocol/Multiprotocol.ino
@@ -108,10 +108,8 @@ uint16_t crc;
uint8_t crc8;
uint16_t seed;
uint16_t failsafe_count;
-//
uint16_t state;
uint8_t len;
-uint8_t RX_num;
#if defined(FRSKYX_CC2500_INO) || defined(SFHSS_CC2500_INO)
uint8_t calData[48];
@@ -157,6 +155,7 @@ uint8_t option;
uint8_t cur_protocol[3];
uint8_t prev_option;
uint8_t prev_power=0xFD; // unused power value
+uint8_t RX_num;
//Serial RX variables
#define BAUD 100000
@@ -975,6 +974,13 @@ static void protocol_init()
remote_callback = ReadDsm;
break;
#endif
+ #if defined(WFLY_CYRF6936_INO)
+ case PROTO_WFLY:
+ PE2_on; //antenna RF4
+ next_callback = initWFLY();
+ remote_callback = ReadWFLY;
+ break;
+ #endif
#if defined(DEVO_CYRF6936_INO)
case PROTO_DEVO:
#ifdef ENABLE_PPM
diff --git a/Multiprotocol/Validate.h b/Multiprotocol/Validate.h
index 9308fa0..aec20da 100644
--- a/Multiprotocol/Validate.h
+++ b/Multiprotocol/Validate.h
@@ -143,6 +143,7 @@
#undef DEVO_CYRF6936_INO
#undef DSM_CYRF6936_INO
#undef J6PRO_CYRF6936_INO
+ #undef WFLY_CYRF6936_INO
#undef WK2x01_CYRF6936_INO
#endif
#ifndef CC2500_INSTALLED
diff --git a/Multiprotocol/WFLY_cyrf6936.ino b/Multiprotocol/WFLY_cyrf6936.ino
new file mode 100644
index 0000000..c4bf9e6
--- /dev/null
+++ b/Multiprotocol/WFLY_cyrf6936.ino
@@ -0,0 +1,294 @@
+/*
+ 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 .
+ */
+
+#if defined(WFLY_CYRF6936_INO)
+
+#include "iface_cyrf6936.h"
+
+//#define WFLY_FORCE_ID
+#define WFLY_BIND_COUNT 1500 // around 15s
+#define WFLY_NUM_FREQUENCE 4
+#define WFLY_BIND_CHANNEL 0x09
+
+enum {
+ WFLY_BIND_TX=0,
+ WFLY_BIND_PREP_RX,
+ WFLY_BIND_RX,
+ WFLY_PREP_DATA,
+ WFLY_DATA,
+};
+
+const uint8_t PROGMEM WFLY_sop_bind[]={ 0x5A, 0xCC, 0xAE, 0x46, 0xB6, 0x31, 0xAE, 0x46 };
+const uint8_t PROGMEM WFLY_sop_data[]={ 0xEF, 0x64, 0xB0, 0x2A, 0xD2, 0x8F, 0xB1, 0x2A };
+
+//Most of the bytes are unknown... 1C A7 looks to be the bind ID, BF 13 is the TX ID, 15 is the channel used to send the hopping frequencies.
+const uint8_t PROGMEM WFLY_bind_packet[]={ 0x1C, 0xA7, 0x60, 0x04, 0x04, 0xBF, 0x13, 0x15, 0xC5, 0x40, 0x8A, 0x37, 0xE0, 0xE8, 0x03, 0xA3 };
+
+
+const uint8_t PROGMEM WFLY_init_vals[][2] = {
+ //Init from dump
+ {CYRF_1D_MODE_OVERRIDE, 0x19}, // Reset
+ {CYRF_32_AUTO_CAL_TIME, 0x3C}, // Default init value
+ {CYRF_35_AUTOCAL_OFFSET, 0x14}, // Default init value
+ {CYRF_1B_TX_OFFSET_LSB, 0x55}, // Default init value
+ {CYRF_1C_TX_OFFSET_MSB, 0x05}, // Default init value
+ {CYRF_06_RX_CFG, 0x48 | 0x02}, // LNA enabled, Fast Turn Mode enabled, adding overwrite enable to not lockup RX
+ {CYRF_10_FRAMING_CFG, 0xE8}, // SOP enable
+ {CYRF_03_TX_CFG, 0x08 | CYRF_BIND_POWER}, // Original=0x0F, 8DR Mode, 32 chip codes
+ {CYRF_0C_XTAL_CTRL, 0xC4}, // Enable XOUT as GPIO
+ {CYRF_0D_IO_CFG, 0x04}, // Enable PACTL as GPIO
+ {CYRF_0F_XACT_CFG, 0x21}, // Abort current operation
+ {CYRF_1E_RX_OVERRIDE, 0x00}, // Accept packets with 0 seed for bind
+ {CYRF_15_CRC_SEED_LSB, 0x00}, // CRC seed for bind
+ {CYRF_16_CRC_SEED_MSB, 0x00}, // CRC seed for bind
+};
+
+static void __attribute__((unused)) WFLY_cyrf_bind_config()
+{
+ for(uint8_t i = 0; i < sizeof(init_vals) / 2; i++)
+ CYRF_WriteRegister(pgm_read_byte_near(&WFLY_init_vals[i][0]), pgm_read_byte_near(&WFLY_init_vals[i][1]));
+
+ CYRF_PROGMEM_ConfigSOPCode(WFLY_sop_bind);
+ CYRF_ConfigRFChannel(WFLY_BIND_CHANNEL);
+ CYRF_SetTxRxMode(TX_EN);
+}
+
+static void __attribute__((unused)) WFLY_cyrf_data_config()
+{
+ for(uint8_t i = 0; i < (sizeof(init_vals) / 2)-3; i++)
+ CYRF_WriteRegister(pgm_read_byte_near(&WFLY_init_vals[i][0]), pgm_read_byte_near(&WFLY_init_vals[i][1]));
+
+ //CYRF_WriteRegister(CYRF_1E_RX_OVERRIDE, 0x08); // Do not accept CRC with 0 seed but not needed since the RX is not sending any data...
+ CYRF_WriteRegister(CYRF_15_CRC_SEED_LSB, rx_tx_addr[2]);
+ CYRF_WriteRegister(CYRF_16_CRC_SEED_MSB, rx_tx_addr[3]);
+
+ CYRF_PROGMEM_ConfigSOPCode(WFLY_sop_data);
+ CYRF_SetTxRxMode(TX_EN);
+}
+
+static uint16_t __attribute__((unused)) WFLY_send_data_packet()
+{
+ packet_count++;
+ packet[0] = rx_tx_addr[2];
+ packet[1] = rx_tx_addr[3];
+ if(packet_count%4==3)
+ { // Send the hopping frequencies
+ packet[2]=0x70; // packet type
+ packet[3]=0x04; // unknown
+ packet[4]=0x00; // unknown
+ packet[5]=0x04; // unknown
+ packet[6]=hopping_frequency[0];
+ packet[7]=hopping_frequency[0];
+ packet[8]=hopping_frequency[1];
+ packet[9]=hopping_frequency[2];
+ len=10; // packet[10] contains the checksum
+ }
+ else
+ { // Send sticks packet
+ uint8_t nbr_ch=option;
+ if(nbr_ch<4) nbr_ch=9; // 4 channels min can be sent, default to 9
+ if(nbr_ch>9) nbr_ch=9; // 9 channels max can be sent
+ packet[2]=nbr_ch-3; // nbr of channels to follow
+ packet[3]=packet_count>>2; // packet counter 0x00..0x3F
+ len=4;
+ for(uint8_t i=0;i<3;i++)
+ { // Channels
+ uint16_t ch = convert_channel_16b_nolimit(i*4+0,151,847);
+ uint8_t offset=i*5;
+ packet[3+offset]|=ch<<6;
+ packet[4+offset]=ch>>2;
+ len++;
+ if(--nbr_ch==0) break;
+ ch = convert_channel_16b_nolimit(i*4+1,151,847);
+ packet[5+offset]=ch;
+ packet[6+offset]=ch>>8;
+ len+=2;
+ if(--nbr_ch==0) break;
+ ch = convert_channel_16b_nolimit(i*4+2,151,847);
+ packet[6+offset]|=ch<<2;
+ packet[7+offset]=ch>>6;
+ len++;
+ if(--nbr_ch==0) break;
+ ch = convert_channel_16b_nolimit(i*4+3,151,847);
+ packet[7+offset]|=ch<<4;
+ packet[8+offset]=ch>>4;
+ len++;
+ if(--nbr_ch==0) break;
+ }
+ }
+
+ uint8_t sum=0;
+ for(uint8_t i = 0; i < len; i++)
+ sum += packet[i];
+ packet[len] = sum;
+
+ CYRF_ConfigRFChannel(hopping_frequency[(packet_count)%4]);
+ CYRF_SetPower(0x08);
+ CYRF_WriteDataPacketLen(packet, len+1);
+
+ switch(packet_count%4)
+ {
+ case 0:
+ return 1393;
+ case 1:
+ return 1330;
+ case 2:
+ return 1555;
+ }
+ return 1093; // case 3
+}
+
+uint16_t ReadWFLY()
+{
+ uint8_t status,len,sum=0,check=0;
+ uint8_t start;
+ static uint8_t retry;
+
+ switch(phase)
+ {
+ case WFLY_BIND_TX:
+ CYRF_SetTxRxMode(TX_EN);
+ CYRF_WriteDataPacketLen(packet, sizeof(WFLY_bind_packet));
+ debug("P=");
+ for(uint8_t i=0;i=10)
+ { // Good packet received
+ if(pkt[2]==0x64)
+ { // Switch to normal mode
+ BIND_DONE;
+ phase=WFLY_PREP_DATA;
+ return 10000;
+ }
+ memcpy((void *)packet,(void *)pkt,0x10); // Send back to the RX what we've just received with no modifications
+ }
+ phase=WFLY_BIND_TX;
+ return 200;
+ }
+ }
+ if(status & 0x85 || --retry == 0)
+ { // RX error or no answer
+ debugln("Abort");
+ CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20); // Enable RX abort
+ CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x21); // Force end state
+ CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00); // Disable RX abort
+ phase=WFLY_BIND_TX; // Retry sending bind packet
+ }
+ return 700;
+ case WFLY_PREP_DATA:
+ WFLY_cyrf_data_config();
+ packet_count=0;
+ phase++;
+ case WFLY_DATA:
+ start=micros();
+ while ((uint8_t)((uint8_t)micros()-(uint8_t)start) < 200)
+ if((CYRF_ReadRegister(CYRF_02_TX_CTRL) & 0x80) == 0x00)
+ break; // Packet transmission complete
+ return WFLY_send_data_packet();
+ }
+ return 1000;
+}
+
+uint16_t initWFLY()
+{
+ //Random start channel
+ uint8_t ch=0x0A+random(0xfefefefe)%0x0E;
+ if(ch%3==0)
+ ch++; // remove these channels as they seem to not be working...
+ rf_ch_num=0x0C+(rx_tx_addr[1]%4)*3; // use the start channels which do not seem to work to send the hopping table instead
+
+ #ifdef WFLY_FORCE_ID // data taken from TX dump
+ rx_tx_addr[2]=0xBF; // ID
+ rx_tx_addr[3]=0x13; // ID
+ ch=0x16; // value seen between 0x0A and 0x17
+ rc_ch_num=0x15 // RF channel to send the current hopping table
+ #endif
+
+ debug("ID:")
+ for(uint8_t i=0;i<2;i++)
+ debug(" %02X", rx_tx_addr[2+i]);
+ debugln("");
+
+ hopping_frequency[0]=ch;
+ hopping_frequency[1]=ch+0x1E;
+ hopping_frequency[2]=ch+0x2D;
+ hopping_frequency[3]=rf_ch_num; // RF channel used to send the current hopping table
+
+ debug("RF Channels:")
+ for(uint8_t i=0;i