From 36b5481c4716857a0f4a655268c7b5640efceaa7 Mon Sep 17 00:00:00 2001 From: philipp schoenberger Date: Fri, 14 Sep 2018 00:06:53 +0200 Subject: [PATCH] - first try to port frsky from multi protocol --- remote/src/cc2500.cpp | 41 +++-- remote/src/cc2500.h | 109 +++++++------- remote/src/config.h | 69 +++++++++ remote/src/frskyd.cpp | 306 ++++++++++++++++++++++++++++++++++++++ remote/src/frskyd.h | 81 ++++++++++ remote/src/iface_cc2500.h | 16 +- remote/src/io_data.cpp | 27 ++-- remote/src/io_data.h | 31 ++-- remote/src/main.cpp | 110 ++++++++------ remote/src/pins.h | 14 ++ remote/src/spi.cpp | 19 ++- remote/src/spi.h | 15 +- 12 files changed, 681 insertions(+), 157 deletions(-) create mode 100644 remote/src/frskyd.cpp create mode 100644 remote/src/frskyd.h 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