diff --git a/remote/src/cc2500.cpp b/remote/src/cc2500.cpp
index dc17b1a..6b05652 100644
--- a/remote/src/cc2500.cpp
+++ b/remote/src/cc2500.cpp
@@ -3,10 +3,16 @@
#include "pins.h"
#include "Arduino.h"
-CC2500::CC2500(SPI* spi)
+CC2500::CC2500(SPI *spi)
{
this->spi = spi;
this->bind_done = false;
+
+ CC2500_CS_OUTPUT;
+ CC2500_CS_ON;
+
+ LOW_NOISE_AMP_OUTPUT;
+ LOW_NOISE_AMP_OFF;
}
void CC2500::write_register(uint8_t address, uint8_t data)
@@ -28,7 +34,7 @@ void CC2500::write_register_multi(uint8_t address, const uint8_t data[], uint8_t
spi->write(CC2500_WRITE_BURST | address);
- for(uint8_t i = 0; i < length; i++) {
+ for (uint8_t i = 0; i < length; i++) {
spi->write(data[i]);
}
@@ -50,7 +56,7 @@ void CC2500::read_register_multi(uint8_t address, uint8_t data[], uint8_t length
spi->write(CC2500_READ_BURST | address);
- for(uint8_t i = 0; i < length; i++) {
+ for (uint8_t i = 0; i < length; i++) {
data[i] = spi->read();
}
@@ -71,7 +77,7 @@ uint8_t CC2500::read_register(uint8_t address)
// deselect chip
CC2500_CS_ON;
- return(result);
+ return (result);
}
void CC2500::read_data(uint8_t *dpbuffer, uint8_t len)
@@ -86,17 +92,19 @@ void CC2500::strobe(uint8_t state)
CC2500_CS_ON;
}
-void CC2500::set_wireless_mode(enum wireless_mode mode )
+void CC2500::set_wireless_mode(enum wireless_mode mode)
{
switch (mode) {
case wireless_tx:
this->write_register(CC2500_00_IOCFG2, 0x2F);
this->write_register(CC2500_02_IOCFG0, 0x2F | 0x40);
break;
+
case wireless_rx:
this->write_register(CC2500_02_IOCFG0, 0x2F);
this->write_register(CC2500_00_IOCFG2, 0x2F | 0x40);
break;
+
case wireless_off:
this->write_register(CC2500_02_IOCFG0, 0x2F);
this->write_register(CC2500_00_IOCFG2, 0x2F);
@@ -108,19 +116,19 @@ void CC2500::set_power(void)
{
uint8_t power = CC2500_BIND_POWER;
- if(this->bind_done) {
- #ifdef CC2500_ENABLE_LOW_POWER
- power=IS_POWER_FLAG_on?CC2500_HIGH_POWER:CC2500_LOW_POWER;
- #else
- power=CC2500_HIGH_POWER;
- #endif
+ if (this->bind_done) {
+#ifdef CC2500_ENABLE_LOW_POWER
+ power = IS_POWER_FLAG_on ? CC2500_HIGH_POWER : CC2500_LOW_POWER;
+#else
+ power = CC2500_HIGH_POWER;
+#endif
}
- if(IS_RANGE_FLAG_on) {
- power=CC2500_RANGE_POWER;
+ if (IS_RANGE_FLAG_on) {
+ power = CC2500_RANGE_POWER;
}
- if(this->prev_power != power) {
+ if (this->prev_power != power) {
this->write_register(CC2500_3E_PATABLE, power);
this->prev_power = power;
}
@@ -148,11 +156,13 @@ void CC2500::resetChip(void)
this->strobe(CC2500_SRES);
_delay_ms(100);
+
+ this->prev_power = 0xfd;
}
void CC2500::set_power_value(uint8_t power)
{
- const unsigned char patable[8]= {
+ const unsigned char patable[8] = {
0xC5, // -12dbm
0x97, // -10dbm
0x6E, // -8dbm
@@ -162,6 +172,7 @@ void CC2500::set_power_value(uint8_t power)
0xFE, // 0dbm
0xFF // 1.5dbm
};
+
if (power > 7)
power = 7;
diff --git a/remote/src/cc2500.h b/remote/src/cc2500.h
index ead2bdf..5849d5a 100644
--- a/remote/src/cc2500.h
+++ b/remote/src/cc2500.h
@@ -14,71 +14,72 @@
*/
#ifndef CC2500_H
+#define CC2500_H
#include "Arduino.h"
#include "spi.h"
#include "iface_cc2500.h"
-class CC2500 {
- private:
- SPI* spi;
- bool bind_done;
- uint8_t prev_power;
- public:
- //TODO IS_RANGE_FLAG_on
-#define IS_RANGE_FLAG_on false
- enum wireless_mode {
- wireless_off,
- wireless_tx,
- wireless_rx,
- };
- // CC2500 power output from the chip itself
- // The numbers do not take into account any outside amplifier
- enum CC2500_POWER
- {
- CC2500_POWER_0 = 0x00, // -55dbm or less
- CC2500_POWER_1 = 0x50, // -30dbm
- CC2500_POWER_2 = 0x44, // -28dbm
- CC2500_POWER_3 = 0xC0, // -26dbm
- CC2500_POWER_4 = 0x84, // -24dbm
- CC2500_POWER_5 = 0x81, // -22dbm
- CC2500_POWER_6 = 0x46, // -20dbm
- CC2500_POWER_7 = 0x93, // -18dbm
- CC2500_POWER_8 = 0x55, // -16dbm
- CC2500_POWER_9 = 0x8D, // -14dbm
- CC2500_POWER_10 = 0xC6, // -12dbm
- CC2500_POWER_11 = 0x97, // -10dbm
- CC2500_POWER_12 = 0x6E, // -8dbm
- CC2500_POWER_13 = 0x7F, // -6dbm
- CC2500_POWER_14 = 0xA9, // -4dbm
- CC2500_POWER_15 = 0xBB, // -2dbm
- CC2500_POWER_16 = 0xFE, // 0dbm
- CC2500_POWER_17 = 0xFF, // +1dbm
+class CC2500
+{
+private:
+ SPI *spi;
+ bool bind_done;
+ uint8_t prev_power;
+public:
+ //TODO IS_RANGE_FLAG_on
+ #define IS_RANGE_FLAG_on false
+ enum wireless_mode {
+ wireless_off,
+ wireless_tx,
+ wireless_rx,
+ };
+ // CC2500 power output from the chip itself
+ // The numbers do not take into account any outside amplifier
+ enum CC2500_POWER {
+ CC2500_POWER_0 = 0x00, // -55dbm or less
+ CC2500_POWER_1 = 0x50, // -30dbm
+ CC2500_POWER_2 = 0x44, // -28dbm
+ CC2500_POWER_3 = 0xC0, // -26dbm
+ CC2500_POWER_4 = 0x84, // -24dbm
+ CC2500_POWER_5 = 0x81, // -22dbm
+ CC2500_POWER_6 = 0x46, // -20dbm
+ CC2500_POWER_7 = 0x93, // -18dbm
+ CC2500_POWER_8 = 0x55, // -16dbm
+ CC2500_POWER_9 = 0x8D, // -14dbm
+ CC2500_POWER_10 = 0xC6, // -12dbm
+ CC2500_POWER_11 = 0x97, // -10dbm
+ CC2500_POWER_12 = 0x6E, // -8dbm
+ CC2500_POWER_13 = 0x7F, // -6dbm
+ CC2500_POWER_14 = 0xA9, // -4dbm
+ CC2500_POWER_15 = 0xBB, // -2dbm
+ CC2500_POWER_16 = 0xFE, // 0dbm
+ CC2500_POWER_17 = 0xFF, // +1dbm
- CC2500_HIGH_POWER = CC2500_POWER_17,
- CC2500_LOW_POWER = CC2500_POWER_13,
- CC2500_RANGE_POWER = CC2500_POWER_1,
- CC2500_BIND_POWER = CC2500_POWER_1,
- };
+ CC2500_HIGH_POWER = CC2500_POWER_17,
+ CC2500_LOW_POWER = CC2500_POWER_13,
+ CC2500_RANGE_POWER = CC2500_POWER_1,
+ CC2500_BIND_POWER = CC2500_POWER_1,
+ };
- CC2500(SPI *spi);
- void write_register(uint8_t address, uint8_t data);
- void write_register_multi(uint8_t address, const uint8_t data[], uint8_t length);
- void write_data(uint8_t *dpbuffer, uint8_t len);
+ CC2500(SPI *spi);
+ void write_register(uint8_t address, uint8_t data);
+ void write_register_multi(uint8_t address, const uint8_t data[], uint8_t length);
+ void write_data(uint8_t *dpbuffer, uint8_t len);
- void read_register_multi(uint8_t address, uint8_t data[], uint8_t length);
- uint8_t read_register(uint8_t address);
- void read_data(uint8_t *dpbuffer, uint8_t len);
+ void read_register_multi(uint8_t address, uint8_t data[], uint8_t length);
+ uint8_t read_register(uint8_t address);
+ void read_data(uint8_t *dpbuffer, uint8_t len);
- void strobe(uint8_t state);
+ void strobe(uint8_t state);
- void set_wireless_mode(enum wireless_mode mode );
- void set_power(void);
+ void set_wireless_mode(enum wireless_mode mode);
+ void set_power(void);
- uint8_t reset(void);
- void set_power_value(uint8_t power);
- void resetChip(void);
+ uint8_t reset(void);
+ void set_power_value(uint8_t power);
+ void resetChip(void);
};
-#endif
+#endif /* CC2500_H */
diff --git a/remote/src/config.h b/remote/src/config.h
index 184290d..583b79d 100644
--- a/remote/src/config.h
+++ b/remote/src/config.h
@@ -1,4 +1,73 @@
#ifndef CONFIG_H
#define CONFIG_H
+const uint8_t FRSKYD_cc2500_conf[] = {
+ /*02_IOCFG0*/ 0x06,
+ /*00_IOCFG2*/ 0x06,
+ /*17_MCSM1*/ 0x0c,
+ /*18_MCSM0*/ 0x18,
+ /*06_PKTLEN*/ 0x19,
+ /*07_PKTCTRL1*/ 0x04,
+ /*08_PKTCTRL0*/ 0x05,
+ /*3E_PATABLE*/ 0xff,
+ /*0B_FSCTRL1*/ 0x08,
+ /*0C_FSCTRL0*/ 0x00,
+ /*0D_FREQ2*/ 0x5c,
+ /*0E_FREQ1*/ 0x76,
+ /*0F_FREQ0*/ 0x27,
+ /*10_MDMCFG4*/ 0xAA,
+ /*11_MDMCFG3*/ 0x39,
+ /*12_MDMCFG2*/ 0x11,
+ /*13_MDMCFG1*/ 0x23,
+ /*14_MDMCFG0*/ 0x7a,
+ /*15_DEVIATN*/ 0x42
+};
+
+const uint8_t FRSKY_common_end_cc2500_conf[][2] = {
+ { CC2500_19_FOCCFG, 0x16 },
+ { CC2500_1A_BSCFG, 0x6c },
+ { CC2500_1B_AGCCTRL2, 0x43 },
+ { CC2500_1C_AGCCTRL1, 0x40 },
+ { CC2500_1D_AGCCTRL0, 0x91 },
+ { CC2500_21_FREND1, 0x56 },
+ { CC2500_22_FREND0, 0x10 },
+ { CC2500_23_FSCAL3, 0xa9 },
+ { CC2500_24_FSCAL2, 0x0A },
+ { CC2500_25_FSCAL1, 0x00 },
+ { CC2500_26_FSCAL0, 0x11 },
+ { CC2500_29_FSTEST, 0x59 },
+ { CC2500_2C_TEST2, 0x88 },
+ { CC2500_2D_TEST1, 0x31 },
+ { CC2500_2E_TEST0, 0x0B },
+ { CC2500_03_FIFOTHR, 0x07 },
+ { CC2500_09_ADDR, 0x00 }
+};
+
+const uint8_t FRSKY_common_startreg_cc2500_conf[] = {
+ CC2500_02_IOCFG0,
+ CC2500_00_IOCFG2,
+ CC2500_17_MCSM1,
+ CC2500_18_MCSM0,
+ CC2500_06_PKTLEN,
+ CC2500_07_PKTCTRL1,
+ CC2500_08_PKTCTRL0,
+ CC2500_3E_PATABLE,
+ CC2500_0B_FSCTRL1,
+ CC2500_0C_FSCTRL0, // replaced by option value
+ CC2500_0D_FREQ2,
+ CC2500_0E_FREQ1,
+ CC2500_0F_FREQ0,
+ CC2500_10_MDMCFG4,
+ CC2500_11_MDMCFG3,
+ CC2500_12_MDMCFG2,
+ CC2500_13_MDMCFG1,
+ CC2500_14_MDMCFG0,
+ CC2500_15_DEVIATN
+};
+//AETR
+ #define AILERON 0
+ #define ELEVATOR 1
+ #define THROTTLE 2
+ #define RUDDER 3
+
#endif
diff --git a/remote/src/frskyd.cpp b/remote/src/frskyd.cpp
new file mode 100644
index 0000000..f9a9bd6
--- /dev/null
+++ b/remote/src/frskyd.cpp
@@ -0,0 +1,306 @@
+/*
+ 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 .
+ */
+
+//#include "iface_cc2500.h"
+#include "frskyd.h"
+#include "config.h"
+#include "Arduino.h"
+
+
+Frsky_d::Frsky_d(CC2500 *cc2500)
+{
+ this->calibration = 0x89;
+ this->state = FRSKY_BIND;
+ this->cc2500 = cc2500;
+ this->packet_count = 0;
+
+ // TODO real random randomSeed(analogRead(0));
+ randomSeed(42);
+
+ this->MProtocol_id_master = random(10);
+ this->MProtocol_id = this->MProtocol_id_master;
+
+ this->init_channel();
+ this->init_failsafe();
+
+ Serial.print(" multiprotocl id : ");
+ Serial.print(this->MProtocol_id);
+ Serial.print("\n");
+}
+void Frsky_d::init(bool bind)
+{
+ this->init_cc2500(FRSKYD_cc2500_conf);
+
+ cc2500->write_register(CC2500_09_ADDR, bind ? 0x03 : rx_tx_addr[3]);
+ cc2500->write_register(CC2500_07_PKTCTRL1, 0x05);
+ cc2500->strobe(CC2500_SIDLE); // Go to idle...
+ //
+ cc2500->write_register(CC2500_0A_CHANNR, 0x00);
+ cc2500->write_register(CC2500_23_FSCAL3, 0x89);
+ cc2500->strobe(CC2500_SFRX);
+ //#######END INIT########
+}
+void Frsky_d::init_cc2500(const uint8_t *ptr)
+{
+ for (uint8_t i = 0; i < 19; i++) {
+ uint8_t reg = FRSKY_common_startreg_cc2500_conf[i];
+ uint8_t val = ptr[i];
+
+ if (reg == CC2500_0C_FSCTRL0)
+ val = option;
+
+ cc2500->write_register(reg, val);
+ }
+
+ prev_option = option ; // Save option to monitor FSCTRL0 change
+
+ for (uint8_t i = 0; i < 17; i++) {
+ uint8_t reg = FRSKY_common_end_cc2500_conf[i][0];
+ uint8_t val = FRSKY_common_end_cc2500_conf[i][1];
+ cc2500->write_register(reg, val);
+ }
+
+ cc2500->set_wireless_mode(CC2500::wireless_tx);
+ cc2500->set_power();
+ cc2500->strobe(CC2500_SIDLE); // Go to idle...
+}
+
+void Frsky_d::build_bind_packet(void)
+{
+ //11 03 01 d7 2d 00 00 1e 3c 5b 78 00 00 00 00 00 00 01
+ //11 03 01 19 3e 00 02 8e 2f bb 5c 00 00 00 00 00 00 01
+ packet[0] = 0x11;
+ packet[1] = 0x03;
+ packet[2] = 0x01;
+ packet[3] = rx_tx_addr[3];
+ packet[4] = rx_tx_addr[2];
+ uint16_t idx = ((state - FRSKY_BIND) % 10) * 5;
+ packet[5] = idx;
+ packet[6] = hopping_frequency[idx++];
+ packet[7] = hopping_frequency[idx++];
+ packet[8] = hopping_frequency[idx++];
+ packet[9] = hopping_frequency[idx++];
+ packet[10] = hopping_frequency[idx++];
+ packet[11] = 0x00;
+ packet[12] = 0x00;
+ packet[13] = 0x00;
+ packet[14] = 0x00;
+ packet[15] = 0x00;
+ packet[16] = 0x00;
+ packet[17] = 0x01;
+}
+
+void Frsky_d::frsky2way_data_frame()
+{
+ //pachet[4] is telemetry user frame counter(hub)
+ //11 d7 2d 22 00 01 c9 c9 ca ca 88 88 ca ca c9 ca 88 88
+ //11 57 12 00 00 01 f2 f2 f2 f2 06 06 ca ca ca ca 18 18
+ packet[0] = 0x11; //Length
+ packet[1] = rx_tx_addr[3];
+ packet[2] = rx_tx_addr[2];
+ packet[3] = counter;//
+#if defined TELEMETRY
+ packet[4] = telemetry_counter;
+#else
+ packet[4] = 0x00;
+#endif
+
+ packet[5] = 0x01;
+ //
+ packet[10] = 0;
+ packet[11] = 0;
+ packet[16] = 0;
+ packet[17] = 0;
+
+ for (uint8_t i = 0; i < 8; i++) {
+ uint16_t value;
+ value = convert_channel_frsky(i);
+
+ if (i < 4) {
+ packet[6 + i] = value & 0xff;
+ packet[10 + (i >> 1)] |= ((value >> 8) & 0x0f) << (4 * (i & 0x01));
+ } else {
+ packet[8 + i] = value & 0xff;
+ packet[16 + ((i - 4) >> 1)] |= ((value >> 8) & 0x0f) << (4 * ((i - 4) & 0x01));
+ }
+ }
+}
+
+uint16_t Frsky_d::init_frsky_2way(void)
+{
+ Serial.print("init hop");
+ init_hop();
+ packet_count = 0;
+#if defined TELEMETRY
+ init_frskyd_link_telemetry();
+#endif
+
+ if (IS_BIND_IN_PROGRESS) {
+ init(true);
+ state = FRSKY_BIND;
+ } else {
+ state = FRSKY_BIND_DONE;
+ }
+
+ return 10000;
+}
+
+uint16_t Frsky_d::read_frsky_2way(void)
+{
+ if (state < FRSKY_BIND_DONE) {
+ Serial.print("bind mode\n");
+ build_bind_packet();
+ cc2500->strobe(CC2500_SIDLE);
+ cc2500->write_register(CC2500_0A_CHANNR, 0x00);
+ cc2500->write_register(CC2500_23_FSCAL3, 0x89);
+ cc2500->strobe(CC2500_SFRX);//0x3A
+ cc2500->write_data(packet, packet[0] + 1);
+
+ if (IS_BIND_DONE) {
+ Serial.print("bind finished \n");
+ state = FRSKY_BIND_DONE;
+ } else {
+ //state += 1;
+ Serial.print("bind not done\n");
+ Serial.print("state :");
+ Serial.print(state);
+ Serial.print("\n");
+ }
+
+ return 9000;
+ }
+
+ if (state == FRSKY_BIND_DONE) {
+ Serial.print("bind done \n");
+ state = FRSKY_DATA2;
+ init(false);
+ counter = 0;
+ BIND_DONE;
+ } else if (state == FRSKY_DATA5) {
+ Serial.print("data 5 \n");
+ cc2500->strobe(CC2500_SRX);//0x34 RX enable
+ state = FRSKY_DATA1;
+ return 9200;
+ }
+
+ counter = (counter + 1) % 188;
+
+ if (state == FRSKY_DATA4) {
+ Serial.print("data 4 \n");
+ //telemetry receive
+ cc2500->set_wireless_mode(CC2500::wireless_rx);
+ cc2500->strobe(CC2500_SIDLE);
+ cc2500->write_register(CC2500_0A_CHANNR, hopping_frequency[counter % 47]);
+ cc2500->write_register(CC2500_23_FSCAL3, 0x89);
+ state++;
+ return 1300;
+ } else {
+ if (state == FRSKY_DATA1) {
+ Serial.print("data 1 \n");
+ len = cc2500->read_register(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
+
+ if (len && len <= (0x11 + 3)) { // 20bytes
+ cc2500->read_data(pkt, len); //received telemetry packets
+#if defined(TELEMETRY)
+
+ if (pkt[len - 1] & 0x80) {
+ //with valid crc
+ packet_count = 0;
+ frsky_check_telemetry(pkt, len); //check if valid telemetry packets and buffer them.
+ }
+
+#endif
+ } else {
+ packet_count++;
+
+ // restart sequence on missed packet - might need count or timeout instead of one missed
+ if (packet_count > 100) {
+ //~1sec
+ packet_count = 0;
+#if defined TELEMETRY
+ telemetry_link = 0; //no link frames
+ pkt[6] = 0; //no user frames.
+#endif
+ }
+ }
+
+ cc2500->set_wireless_mode(CC2500::wireless_tx);
+ cc2500->set_power(); // Set tx_power
+ }
+
+ cc2500->strobe(CC2500_SIDLE);
+ cc2500->write_register(CC2500_0A_CHANNR, hopping_frequency[counter % 47]);
+
+ if (prev_option != option) {
+ cc2500->write_register(CC2500_0C_FSCTRL0, option); // Frequency offset hack
+ prev_option = option ;
+ }
+
+ cc2500->write_register(CC2500_23_FSCAL3, 0x89);
+ cc2500->strobe(CC2500_SFRX);
+ frsky2way_data_frame();
+ cc2500->write_data(packet, packet[0] + 1);
+ state++;
+ }
+
+ return state == FRSKY_DATA4 ? 7500 : 9000;
+}
+
+uint16_t Frsky_d::convert_channel_frsky(uint8_t num)
+{
+ // Channel value for FrSky (PPM is multiplied by 1.5)
+ uint16_t val = Channel_data[num];
+ return ((val*15)>>4)+1290;
+}
+
+void Frsky_d::init_hop(void)
+{
+ uint8_t val;
+ uint8_t channel = rx_tx_addr[0]&0x07;
+ uint8_t channel_spacing = rx_tx_addr[1];
+ //Filter bad tables
+ if(channel_spacing<0x02)
+ channel_spacing+=0x02;
+ if(channel_spacing>0xE9)
+ channel_spacing-=0xE7;
+ if(channel_spacing%0x2F==0)
+ channel_spacing++;
+
+ hopping_frequency[0]=channel;
+ for(uint8_t i=1;i<50;i++) {
+ channel=(channel+channel_spacing) % 0xEB;
+ val=channel;
+ if((val==0x00) || (val==0x5A) || (val==0xDC))
+ val++;
+ hopping_frequency[i]=i>46?0:val;
+ }
+}
+
+void Frsky_d::init_channel(void)
+{
+ for(uint8_t i=0;i
+
+#ifndef FRSKYD_H
+#define FRSKYD_H
+#include
+
+ #define BIND_IN_PROGRESS protocol_flags &= ~_BV(7)
+ #define BIND_DONE protocol_flags |= _BV(7)
+ #define IS_BIND_DONE ( ( protocol_flags & _BV(7) ) !=0 )
+ #define IS_BIND_IN_PROGRESS ( ( protocol_flags & _BV(7) ) ==0 )
+
+class Frsky_d
+{
+private:
+ uint8_t hopping_frequency[50];
+ uint8_t calibration;
+ enum frsky_d_state {
+ FRSKY_BIND = 0,
+ FRSKY_BIND_DONE = 1000,
+ FRSKY_DATA1,
+ FRSKY_DATA2,
+ FRSKY_DATA3,
+ FRSKY_DATA4,
+ FRSKY_DATA5
+ };
+ int state;
+
+ CC2500 * cc2500;
+
+ uint16_t packet_count;
+ uint8_t packet[40];
+ uint8_t len;
+
+ uint8_t rx_tx_addr[5];
+ uint8_t option;
+ uint8_t prev_option;
+ uint16_t counter;
+
+ uint8_t pkt[29];
+
+ #define NUM_CHN 16
+ // Servo data
+ uint8_t Channel_AUX;
+
+ uint16_t Channel_data[NUM_CHN];
+ uint16_t failsafe_data[NUM_CHN];
+
+ uint8_t protocol_flags=0,protocol_flags2=0;
+
+ volatile uint32_t gWDT_entropy = 0;
+ uint32_t MProtocol_id_master;
+ uint32_t MProtocol_id;
+
+ bool fail_save = false;
+
+public:
+ Frsky_d(CC2500 *cc2500);
+ void init(bool bind);
+ void build_bind_packet(void);
+ uint16_t init_frsky_2way(void);
+
+ uint16_t read_frsky_2way(void);
+ void frsky2way_init(bool bind);
+ void frsky_init_hop(void);
+
+ void init_cc2500(const uint8_t *ptr);
+ void frsky2way_data_frame();
+
+ uint16_t convert_channel_frsky(uint8_t num);
+
+ void init_hop(void);
+
+ void init_channel(void);
+ void init_failsafe(void);
+
+
+};
+
+
+
+#endif /*FRSKYD_H*/
diff --git a/remote/src/iface_cc2500.h b/remote/src/iface_cc2500.h
index 81b101b..2c49190 100644
--- a/remote/src/iface_cc2500.h
+++ b/remote/src/iface_cc2500.h
@@ -94,18 +94,18 @@ enum {
// Strobe commands
#define CC2500_SRES 0x30 // Reset chip.
#define CC2500_SFSTXON 0x31 // Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1).
- // If in RX/TX: Go to a wait state where only the synthesizer is
- // running (for quick RX / TX turnaround).
+// If in RX/TX: Go to a wait state where only the synthesizer is
+// running (for quick RX / TX turnaround).
#define CC2500_SXOFF 0x32 // Turn off crystal oscillator.
#define CC2500_SCAL 0x33 // Calibrate frequency synthesizer and turn it off
- // (enables quick start).
+// (enables quick start).
#define CC2500_SRX 0x34 // Enable RX. Perform calibration first if coming from IDLE and
- // MCSM0.FS_AUTOCAL=1.
+// MCSM0.FS_AUTOCAL=1.
#define CC2500_STX 0x35 // In IDLE state: Enable TX. Perform calibration first if
- // MCSM0.FS_AUTOCAL=1. If in RX state and CCA is enabled:
- // Only go to TX if channel is clear.
+// MCSM0.FS_AUTOCAL=1. If in RX state and CCA is enabled:
+// Only go to TX if channel is clear.
#define CC2500_SIDLE 0x36 // Exit RX / TX, turn off frequency synthesizer and exit
- // Wake-On-Radio mode if applicable.
+// Wake-On-Radio mode if applicable.
#define CC2500_SAFC 0x37 // Perform AFC adjustment of the frequency synthesizer
#define CC2500_SWOR 0x38 // Start automatic RX polling sequence (Wake-on-Radio)
#define CC2500_SPWD 0x39 // Enter power down mode when CSn goes high.
@@ -113,7 +113,7 @@ enum {
#define CC2500_SFTX 0x3B // Flush the TX FIFO buffer.
#define CC2500_SWORRST 0x3C // Reset real time clock.
#define CC2500_SNOP 0x3D // No operation. May be used to pad strobe commands to two
- // bytes for simpler software.
+// bytes for simpler software.
//----------------------------------------------------------------------------------
// Chip Status Byte
//----------------------------------------------------------------------------------
diff --git a/remote/src/io_data.cpp b/remote/src/io_data.cpp
index 9cbdf04..78ac876 100644
--- a/remote/src/io_data.cpp
+++ b/remote/src/io_data.cpp
@@ -8,7 +8,7 @@ IO_DATA::IO_DATA()
void IO_DATA::adc_init(void)
{
// AREF = AVcc
- ADMUX = (0<= 0x08 ) {
- /* Set Mux5 */
- ADCSRB |= _BV(MUX5);
- ch &= ~0x08;
- } else {
- /* Clear Mux5 */
- ADCSRB &= ~_BV(MUX5);
- }
+ if (ch >= 0x08) {
+ /* Set Mux5 */
+ ADCSRB |= _BV(MUX5);
+ ch &= ~0x08;
+ } else {
+ /* Clear Mux5 */
+ ADCSRB &= ~_BV(MUX5);
+ }
+
ch = ch & 0b00000111;
Serial.print("ch");
Serial.print(ch);
ADMUX |= ch;
// start single convertion
- ADCSRA |= (1<init();
+ Serial.begin(115200);
- cc2500 = new CC2500(spi);
+ spi = new SPI();
+ spi->init();
- io_data = new IO_DATA();
- io_data->init();
+ cc2500 = new CC2500(spi);
- Serial.println("Remote ON!");
+ frskyd = new Frsky_d(cc2500);
+
+ io_data = new IO_DATA();
+ io_data->init();
+
+ Serial.println("Remote ON!");
+
+ delay (500);
+ cc2500->reset();
+ Serial.print(" init\n");
+ frskyd->init(false);
+
+ delay (500);
+ Serial.print(" init 2way\n");
+ frskyd->init_frsky_2way();
}
-void loop() {
- Serial.println("loop!");
-
- io_data->update();
-
- Serial.print(" akku= ");
- Serial.print(io_data->akku_power);
- Serial.print(" arm= ");
- Serial.print(io_data->arm_sw);
- Serial.print(" mode= ");
- Serial.print(io_data->flight_mode_sw);
-
- Serial.print("l x= ");
- Serial.print(io_data->r_x);
- Serial.print(" y= ");
- Serial.print(io_data->r_y);
- Serial.print(" sw= ");
- Serial.print(io_data->r_sw);
-
- Serial.print("r x= ");
- Serial.print(io_data->l_x);
- Serial.print(" y= ");
- Serial.print(io_data->l_y);
- Serial.print(" sw= ");
- Serial.print(io_data->l_sw);
- Serial.print("\n");
-
- delay(500);
+void loop()
+{
+ Serial.println("loop!");
+
+ io_data->update();
+
+ Serial.print(" akku= ");
+ Serial.print(io_data->akku_power);
+ Serial.print(" arm= ");
+ Serial.print(io_data->arm_sw);
+ Serial.print(" mode= ");
+ Serial.print(io_data->flight_mode_sw);
+
+ Serial.print("l x= ");
+ Serial.print(io_data->r_x);
+ Serial.print(" y= ");
+ Serial.print(io_data->r_y);
+ Serial.print(" sw= ");
+ Serial.print(io_data->r_sw);
+
+ Serial.print("r x= ");
+ Serial.print(io_data->l_x);
+ Serial.print(" y= ");
+ Serial.print(io_data->l_y);
+ Serial.print(" sw= ");
+ Serial.print(io_data->l_sw);
+ Serial.print("\n");
+
+ //TODO needed ? PE1_off;
+ //TODO needed ? PE2_on;
+
+ Serial.print(" read 2 way\n");
+ int rt = frskyd->read_frsky_2way();
+
+ Serial.print(" read :");
+ Serial.print(rt);
+ Serial.print("\n");
+
+ delayMicroseconds(rt);
}
diff --git a/remote/src/pins.h b/remote/src/pins.h
index 77e7574..f0e89a1 100644
--- a/remote/src/pins.h
+++ b/remote/src/pins.h
@@ -248,3 +248,17 @@
#define SPI_MOSI_IS_LOW ((SPI_MOSI_IPR & _BV(SPI_MOSI_PIN) == 0x00)
#define NOP __asm__("nop");
+
+#define PE1_pin 1 //A1 = PC1
+#define PE1_port PORTC
+#define PE1_ddr DDRC
+#define PE1_output PE1_ddr |= _BV(PE1_pin)
+#define PE1_on PE1_port |= _BV(PE1_pin)
+#define PE1_off PE1_port &= ~_BV(PE1_pin)
+
+#define PE2_pin 2 //A2 = PC2
+#define PE2_port PORTC
+#define PE2_ddr DDRC
+#define PE2_output PE2_ddr |= _BV(PE2_pin)
+#define PE2_on PE2_port |= _BV(PE2_pin)
+#define PE2_off PE2_port &= ~_BV(PE2_pin)
diff --git a/remote/src/spi.cpp b/remote/src/spi.cpp
index 2d56ffa..329470f 100644
--- a/remote/src/spi.cpp
+++ b/remote/src/spi.cpp
@@ -17,6 +17,8 @@
/********************/
#include "spi.h"
#include "pins.h"
+#include "Arduino.h"
+
SPI::SPI()
{
}
@@ -25,6 +27,12 @@ void SPI::init(void)
SPI_SCLK_OUTPUT;
SPI_MOSI_OUTPUT;
SPI_MISO_INPUT;
+
+ SPI_MOSI_ON;
+ SPI_SCLK_OFF;
+
+ // wait for the components
+ delay(100);
}
void SPI::write(const uint8_t command)
@@ -35,9 +43,9 @@ void SPI::write(const uint8_t command)
SPI_SCLK_OFF;
SPI_MOSI_OFF;
- for (uint8_t i = 0; i< 8; ++i) {
+ for (uint8_t i = 0; i < 8; ++i) {
// check if bit is set
- if(tmp & 0x80) {
+ if (tmp & 0x80) {
SPI_MOSI_ON;
} else {
SPI_MOSI_OFF;
@@ -50,6 +58,7 @@ void SPI::write(const uint8_t command)
// reset clock
SPI_SCLK_OFF;
}
+
SPI_MOSI_ON;
}
@@ -57,10 +66,11 @@ uint8_t SPI::read(void)
{
uint8_t result = 0;
- for(uint8_t i = 0; i < 8; i++) {
+ for (uint8_t i = 0; i < 8; i++) {
result = result << 1;
- if(SPI_MISO_IS_HIGH) {
+
+ if (SPI_MISO_IS_HIGH) {
result |= 0x01;
}
@@ -71,5 +81,6 @@ uint8_t SPI::read(void)
// reset clock
SPI_SCLK_OFF;
}
+
return result;
}
diff --git a/remote/src/spi.h b/remote/src/spi.h
index 545c152..bbab4ae 100644
--- a/remote/src/spi.h
+++ b/remote/src/spi.h
@@ -15,14 +15,15 @@
#ifndef SPI_H
#define SPI_H
#include
-class SPI {
- private:
+class SPI
+{
+private:
- public:
- SPI();
- void init(void);
- void write(uint8_t command);
- uint8_t read(void);
+public:
+ SPI();
+ void init(void);
+ void write(uint8_t command);
+ uint8_t read(void);
};
#endif