123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- /*
- This program 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.
- This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #pragma once
- /*
- AP_Radio implementation for CC2500 2.4GHz radio.
- With thanks to cleanflight and betaflight projects
- */
- #include "AP_Radio_backend.h"
- #if CONFIG_HAL_BOARD == HAL_BOARD_CHIBIOS
- #include "hal.h"
- #include "telem_structure.h"
- #include "driver_cc2500.h"
- #define CC2500_MAX_PWM_CHANNELS 16
- class AP_Radio_cc2500 : public AP_Radio_backend
- {
- public:
- AP_Radio_cc2500(AP_Radio &radio);
- // init - initialise radio
- bool init(void) override;
- // rest radio
- bool reset(void) override;
- // send a packet
- bool send(const uint8_t *pkt, uint16_t len) override;
- // start bind process as a receiver
- void start_recv_bind(void) override;
- // return time in microseconds of last received R/C packet
- uint32_t last_recv_us(void) override;
- // return number of input channels
- uint8_t num_channels(void) override;
- // return current PWM of a channel
- uint16_t read(uint8_t chan) override;
- // handle a data96 mavlink packet for fw upload
- void handle_data_packet(mavlink_channel_t chan, const mavlink_data96_t &m) override;
- // update status
- void update(void) override;
- // get TX fw version
- uint32_t get_tx_version(void) override
- {
- // pack date into 16 bits for vendor_id in AUTOPILOT_VERSION
- return (uint16_t(tx_date.firmware_year)<<12) + (uint16_t(tx_date.firmware_month)<<8) + tx_date.firmware_day;
- }
- // get radio statistics structure
- const AP_Radio::stats &get_stats(void) override;
- // set the 2.4GHz wifi channel used by companion computer, so it can be avoided
- void set_wifi_channel(uint8_t channel) override
- {
- t_status.wifi_chan = channel;
- }
- // static probe function for device detection
- static bool probe(void);
- private:
- AP_HAL::OwnPtr<AP_HAL::SPIDevice> dev;
- static AP_Radio_cc2500 *radio_singleton;
- static thread_t *_irq_handler_ctx;
- static virtual_timer_t timeout_vt;
- static void irq_handler_thd(void* arg);
- static void trigger_irq_radio_event(void);
- static void trigger_timeout_event(void *arg);
- void radio_init(void);
- // semaphore between ISR and main thread
- HAL_Semaphore sem;
- AP_Radio::stats stats;
- AP_Radio::stats last_stats;
- uint16_t pwm_channels[CC2500_MAX_PWM_CHANNELS];
- Radio_CC2500 cc2500;
- uint8_t bindTxId[2];
- int8_t bindOffset;
- uint8_t bindHopData[47];
- uint8_t rxNum;
- uint8_t listLength;
- uint8_t channr;
- uint8_t chanskip;
- int8_t fcc_chan;
- uint32_t packet_timer;
- static uint32_t irq_time_us;
- uint8_t chan_count;
- uint32_t lost;
- uint32_t timeouts;
- bool have_bind_info;
- uint8_t packet3;
- bool telem_send_rssi;
- float rssi_filtered;
- uint64_t bind_mask;
- uint8_t best_lqi;
- int8_t best_bindOffset;
- int8_t auto_bindOffset;
- uint8_t search_count;
- uint8_t last_wifi_channel;
- uint32_t timeTunedMs;
- uint32_t autobind_start_recv_ms;
- void initTuneRx(void);
- void initialiseData(uint8_t adr);
- void initGetBind(void);
- bool tuneRx(uint8_t ccLen, uint8_t *packet);
- bool getBindData(uint8_t ccLen, uint8_t *packet);
- bool check_best_LQI(void);
- void setChannel(uint8_t channel);
- void setChannelRX(uint8_t channel);
- void nextChannel(uint8_t skip);
- void parse_frSkyX(const uint8_t *packet);
- uint16_t calc_crc(const uint8_t *data, uint8_t len);
- bool check_crc(uint8_t ccLen, uint8_t *packet);
- void send_D16_telemetry(void);
- void send_SRT_telemetry(void);
- void irq_handler(void);
- void irq_timeout(void);
- // bind structure saved to storage
- static const uint16_t bind_magic = 0x120c;
- struct PACKED bind_info {
- uint16_t magic;
- uint8_t bindTxId[2];
- int8_t bindOffset;
- uint8_t wifi_chan;
- uint8_t bindHopData[47];
- };
- void save_bind_info(void);
- bool load_bind_info(void);
- enum {
- STATE_INIT = 0,
- STATE_BIND,
- STATE_BIND_TUNING,
- STATE_BIND_BINDING,
- STATE_BIND_COMPLETE,
- STATE_STARTING,
- STATE_DATA,
- STATE_TELEMETRY,
- STATE_RESUME,
- STATE_FCCTEST,
- STATE_SEARCH,
- } protocolState;
- struct config {
- uint8_t reg;
- uint8_t value;
- };
- static const config radio_config_GFSK[];
- static const config radio_config[];
- struct {
- mavlink_channel_t chan;
- bool need_ack;
- uint8_t counter;
- uint8_t sequence;
- uint32_t offset;
- uint32_t length;
- uint32_t acked;
- uint8_t len;
- enum telem_type fw_type;
- uint8_t pending_data[92];
- } fwupload;
- struct {
- uint8_t firmware_year;
- uint8_t firmware_month;
- uint8_t firmware_day;
- } tx_date;
- struct telem_status_cc2500 t_status;
- uint32_t last_pps_ms;
- uint8_t tx_rssi;
- uint8_t tx_pps;
- bool have_tx_pps;
- uint8_t last_fcc_chan;
- uint32_t telem_send_count;
- bool handle_D16_packet(const uint8_t *packet);
- bool handle_SRT_packet(const uint8_t *packet);
- bool handle_autobind_packet(const uint8_t *packet, uint8_t lqi);
- bool have_channel(uint8_t channel, uint8_t count, uint8_t loop);
- void setup_hopping_table_SRT(void);
- uint8_t map_RSSI_to_dBm(uint8_t rssi_raw);
- // check sending of fw upload ack
- void check_fw_ack(void);
- void map_stick_mode(uint16_t *channels);
- void set_fcc_channel(void);
- // check for double binding
- void check_double_bind(void);
- };
- #endif // CONFIG_HAL_BOARD == HAL_BOARD_CHIBIOS
|