27 #include "modules/datalink/superbitrf.h"
38 #ifndef SUPERBITRF_SPI_DEV
39 #define SUPERBITRF_SPI_DEV spi1
44 #ifndef SUPERBITRF_RST_PORT
45 #define SUPERBITRF_RST_PORT GPIOC
48 #ifndef SUPERBITRF_RST_PIN
49 #define SUPERBITRF_RST_PIN GPIO12
54 #ifndef SUPERBITRF_DRDY_PORT
55 #define SUPERBITRF_DRDY_PORT GPIOB
58 #ifndef SUPERBITRF_DRDY_PIN
59 #define SUPERBITRF_DRDY_PIN GPIO1
64 #ifndef SUPERBITRF_FORCE_DSM2
65 #define SUPERBITRF_FORCE_DSM2 TRUE
69 #ifndef SUPERBITRF_UPDATE_DL
70 #define SUPERBITRF_UPDATE_DL TRUE
128 {0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8},
129 {0x88, 0x17, 0x13, 0x3B, 0x2D, 0xBF, 0x06, 0xD6},
130 {0xF1, 0x94, 0x30, 0x21, 0xA1, 0x1C, 0x88, 0xA9},
131 {0xD0, 0xD2, 0x8E, 0xBC, 0x82, 0x2F, 0xE3, 0xB4},
132 {0x8C, 0xFA, 0x47, 0x9B, 0x83, 0xA5, 0x66, 0xD0},
133 {0x07, 0xBD, 0x9F, 0x26, 0xC8, 0x31, 0x0F, 0xB8},
134 {0xEF, 0x03, 0x95, 0x89, 0xB4, 0x71, 0x61, 0x9D},
135 {0x40, 0xBA, 0x97, 0xD5, 0x86, 0x4F, 0xCC, 0xD1},
136 {0xD7, 0xA1, 0x54, 0xB1, 0x5E, 0x89, 0xAE, 0x86}
139 {0x83, 0xF7, 0xA8, 0x2D, 0x7A, 0x44, 0x64, 0xD3},
140 {0x3F, 0x2C, 0x4E, 0xAA, 0x71, 0x48, 0x7A, 0xC9},
141 {0x17, 0xFF, 0x9E, 0x21, 0x36, 0x90, 0xC7, 0x82},
142 {0xBC, 0x5D, 0x9A, 0x5B, 0xEE, 0x7F, 0x42, 0xEB},
143 {0x24, 0xF5, 0xDD, 0xF8, 0x7A, 0x77, 0x74, 0xE7},
144 {0x3D, 0x70, 0x7C, 0x94, 0xDC, 0x84, 0xAD, 0x95},
145 {0x1E, 0x6A, 0xF0, 0x37, 0x52, 0x7B, 0x11, 0xD4},
146 {0x62, 0xF5, 0x2B, 0xAA, 0xFC, 0x33, 0xBF, 0xAF},
147 {0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97}
150 {0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97},
151 {0x8E, 0x4A, 0xD0, 0xA9, 0xA7, 0xFF, 0x20, 0xCA},
152 {0x4C, 0x97, 0x9D, 0xBF, 0xB8, 0x3D, 0xB5, 0xBE},
153 {0x0C, 0x5D, 0x24, 0x30, 0x9F, 0xCA, 0x6D, 0xBD},
154 {0x50, 0x14, 0x33, 0xDE, 0xF1, 0x78, 0x95, 0xAD},
155 {0x0C, 0x3C, 0xFA, 0xF9, 0xF0, 0xF2, 0x10, 0xC9},
156 {0xF4, 0xDA, 0x06, 0xDB, 0xBF, 0x4E, 0x6F, 0xB3},
157 {0x9E, 0x08, 0xD1, 0xAE, 0x59, 0x5E, 0xE8, 0xF0},
158 {0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E}
161 {0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E},
162 {0x80, 0x69, 0x26, 0x80, 0x08, 0xF8, 0x49, 0xE7},
163 {0x7D, 0x2D, 0x49, 0x54, 0xD0, 0x80, 0x40, 0xC1},
164 {0xB6, 0xF2, 0xE6, 0x1B, 0x80, 0x5A, 0x36, 0xB4},
165 {0x42, 0xAE, 0x9C, 0x1C, 0xDA, 0x67, 0x05, 0xF6},
166 {0x9B, 0x75, 0xF7, 0xE0, 0x14, 0x8D, 0xB5, 0x80},
167 {0xBF, 0x54, 0x98, 0xB9, 0xB7, 0x30, 0x5A, 0x88},
168 {0x35, 0xD1, 0xFC, 0x97, 0x23, 0xD4, 0xC9, 0x88},
169 {0x88, 0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40}
172 {0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40, 0x93},
173 {0xDC, 0x68, 0x08, 0x99, 0x97, 0xAE, 0xAF, 0x8C},
174 {0xC3, 0x0E, 0x01, 0x16, 0x0E, 0x32, 0x06, 0xBA},
175 {0xE0, 0x83, 0x01, 0xFA, 0xAB, 0x3E, 0x8F, 0xAC},
176 {0x5C, 0xD5, 0x9C, 0xB8, 0x46, 0x9C, 0x7D, 0x84},
177 {0xF1, 0xC6, 0xFE, 0x5C, 0x9D, 0xA5, 0x4F, 0xB7},
178 {0x58, 0xB5, 0xB3, 0xDD, 0x0E, 0x28, 0xF1, 0xB0},
179 {0x5F, 0x30, 0x3B, 0x56, 0x96, 0x45, 0xF4, 0xA1},
180 {0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8}
183 static const uint8_t pn_bind[] = { 0x98, 0x88, 0x1B, 0xE4, 0x30, 0x79, 0x03, 0x84 };
185 #if PERIODIC_TELEMETRY
192 pprz_msg_send_SUPERBITRF(trans,
dev, AC_ID,
213 int space =
p->tx_extract_idx -
p->tx_insert_idx - 1;
217 return space >= len ? space : 0;
222 p->tx_buffer[
p->tx_insert_idx] =
byte;
229 for (i = 0; i < len; i++) {
277 #if PERIODIC_TELEMETRY
324 uint8_t i, pn_row, data_code[16];
325 static uint8_t packet_size, tx_packet[16];
326 static bool start_transfer =
true;
328 #ifdef RADIO_CONTROL_LED
377 start_transfer =
false;
395 memcpy(data_code,
pn_codes[0][8], 8);
396 memcpy(data_code + 8,
pn_bind, 8);
426 #ifdef RADIO_CONTROL_LED
428 if (slowLedCpt > 100000) {
469 if (start_transfer) {
476 #ifdef RADIO_TRANSMITTER_ID
483 #ifdef RADIO_TRANSMITTER_CHAN
492 #ifdef RADIO_TRANSMITTER_PROTOCOL
516 #ifdef RADIO_CONTROL_LED
518 if (slowLedCpt > 5000) {
566 if (packet_size > 14) {
570 for (i = 0; i < packet_size; i++) {
634 #ifdef RADIO_CONTROL_LED
635 LED_ON(RADIO_CONTROL_LED);
696 if (packet_size > 14) {
700 for (i = 0; i < packet_size; i++) {
798 if (packet[0] != packet[4] || packet[1] != packet[5] || packet[2] != packet[6] || packet[3] != packet[7]) {
806 for (i = 0; i < 8; i++) {
811 if (packet[8] != sum >> 8 || packet[9] != (sum & 0xFF)) {
818 for (i = 8; i < 14; i++) {
823 if (packet[14] != sum >> 8 || packet[15] != (sum & 0xFF)) {
830 uint32_t mfg_id = ((~packet[3] & 0xFF) << 24 | (~packet[2] & 0xFF) << 16 |
831 (~packet[1] & 0xFF) << 8 | (~packet[0] & 0xFF));
1092 uint8_t bit_shift = (is_11bit) ? 11 : 10;
1093 int16_t value_max = (is_11bit) ? 0x07FF : 0x03FF;
1095 for (i = 0; i < 7; i++) {
1096 const int16_t tmp = ((data[2 * i] << 8) + data[2 * i + 1]) & 0x7FFF;
1097 const uint8_t chan = (tmp >> bit_shift) & 0x0F;
1100 if (chan < nb_channels) {
1101 channels[chan] =
val;
1105 channels[chan] -= 0x400;
1106 channels[chan] *=
MAX_PPRZ / 0x2AC;
1108 channels[chan] -= 0x200;
1109 channels[chan] *=
MAX_PPRZ / 0x156;
1129 int count_3_27 = 0, count_28_51 = 0, count_52_76 = 0;
1131 id_tmp = id_tmp * 0x0019660D + 0x3C6EF35F;
1132 uint8_t next_ch = ((id_tmp >> 8) % 0x49) + 3;
1133 if (((next_ch ^
id) & 0x01) == 0) {
1138 for (i = 0; i <
idx; i++) {
1160 if ((next_ch < 28 && count_3_27 < 8)
1161 || (next_ch >= 28 && next_ch < 52 && count_28_51 < 7)
1162 || (next_ch >= 52 && count_52_76 < 8)) {
#define SPEKTRUM_BIND_PIN_PORT
#define SPEKTRUM_BIND_PIN
struct SuperbitRF superbitrf
void superbitrf_set_protocol(uint8_t protocol)
void superbitrf_set_mfg_id(uint32_t id)
void gpio_setup_input(ioportid_t port, uint16_t gpios)
Setup one or more pins of the given GPIO port as inputs.
static uint8_t gpio_get(ioportid_t port, uint16_t pin)
Get level of a gpio.
uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
void cyrf6936_init(struct Cyrf6936 *cyrf, struct spi_periph *spi_p, const uint8_t slave_idx, const uint32_t rst_port, const uint16_t rst_pin)
Initializing the cyrf chip.
bool cyrf6936_multi_write(struct Cyrf6936 *cyrf, const uint8_t data[][2], const uint8_t length)
Write to multiple registers one byte.
bool cyrf6936_write_chan_sop_data_crc(struct Cyrf6936 *cyrf, const uint8_t chan, const uint8_t sop_code[], const uint8_t data_code[], const uint16_t crc_seed)
Set the channel, SOP code, DATA code and the CRC seed.
bool cyrf6936_write(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t data)
Write to one register.
bool cyrf6936_read_rx_irq_status_packet(struct Cyrf6936 *cyrf)
Read the RX IRQ status register, the rx status register and the rx packet.
bool cyrf6936_send(struct Cyrf6936 *cyrf, const uint8_t data[], const uint8_t length)
Send a packet with a certain length.
@ CYRF6936_IDLE
The chip is idle and can be used.
uint8_t rx_status
The last receive status.
uint8_t rx_count
The length of the received packet.
enum Cyrf6936Status status
The status of the CYRF6936 chip.
bool has_irq
When the CYRF6936 is done reading the irq.
uint8_t tx_irq_status
The last send interrupt status.
uint8_t mfg_id[6]
The manufacturer id of the CYRF6936 chip.
uint8_t rx_packet[16]
The last received packet.
uint8_t rx_irq_status
The last receive interrupt status.
#define CYRF_FAST_TURN_EN
#define CYRF_DATA_CODE_LENGTH
#define DatalinkFillDlBuffer(_buf, _len)
Convenience macro to fill dl_buffer.
static void DlCheckAndParse(struct link_device *dev, struct transport_tx *trans, uint8_t *buf, bool *msg_available, bool update_dl)
Check for new message and parse.
Some architecture independent helper functions for GPIOs.
arch independent LED (Light Emitting Diodes) API
uint8_t dl_buffer[MSG_SIZE]
bool dl_msg_available
Flag provided to control calls to dl_parse_msg.
static void superbitrf_transmit_buffer(struct SuperbitRF *p, long fd, uint8_t *data, uint16_t len)
void superbitrf_dl_event(void)
The superbitrf datalink event call.
#define SUPERBITRF_DRDY_PORT
static void superbitrf_radio_to_channels(uint8_t *data, uint8_t nb_channels, bool is_11bit, int16_t *channels)
Parse a radio channel packet.
#define SUPERBITRF_FORCE_DSM2
void superbitrf_event(void)
The superbitrf on event call.
static const uint8_t cyrf_bind_config[][2]
#define SUPERBITRF_UPDATE_DL
static void superbitrf_send(struct SuperbitRF *p, long fd)
static const uint8_t pn_bind[]
void superbitrf_dl_init(void)
Initialize datalink part.
const uint8_t cyrf_start_receive[][2]
static void superbitrf_gen_dsmx_channels(void)
Generate the channels.
#define SUPERBITRF_SPI_DEV
void superbitrf_init(void)
Initialize the superbitrf.
static uint8_t null_byte_function(struct SuperbitRF *p)
struct pprz_transport pprz_srf_tp
static int null_function(struct SuperbitRF *p)
#define SUPERBITRF_RST_PIN
const uint8_t cyrf_abort_receive[][2]
static const uint8_t cyrf_stratup_config[][2]
static const uint8_t pn_codes[5][9][8]
static const uint8_t cyrf_transfer_config[][2]
static int superbitrf_check_free_space(struct SuperbitRF *p, long *fd, uint16_t len)
static void send_superbit(struct transport_tx *trans, struct link_device *dev)
#define SUPERBITRF_RST_PORT
static void superbitrf_send_packet_cb(bool error)
static void superbitrf_transmit(struct SuperbitRF *p, long fd, uint8_t byte)
#define SUPERBITRF_DRDY_PIN
static void superbitrf_receive_packet_cb(bool error, uint8_t status, uint8_t packet[])
When we receive a packet this callback is called.
uint32_t bind_mfg_id32
The MFG id where the receiver is bound to in uint32.
uint32_t uplink_count
How many valid uplink packages are received.
uint8_t channels[23]
The channels used for DSM2/DSMX.
uint8_t timeouts
The amount of timeouts.
bool packet_loss
When we have packet loss last packet.
uint32_t rc_count
How many valid RC packages are received.
uint32_t tx_packet_count
How many packets are send(also the invalid)
uint8_t channel_idx
The current channel index.
bool timer_overflow
When the timer overflows.
#define SUPERBITRF_TX_BUFFER_SIZE
struct link_device device
Generic device interface.
#define SUPERBITRF_RECV_SHORT_TIME
The time to wait for a transfer packet short on a channel in microseconds.
uint8_t tx_extract_idx
The transmit buffer extract index.
enum dsm_protocol protocol
The protocol the transmitter uses.
uint32_t resync_count
The amount of resyncs needed during transfer.
uint32_t timer
The timer in microseconds.
uint8_t data_col
The data code column number calculated with the bind MFG id.
uint32_t transfer_timeouts
The amount of timeouts during transfer.
#define SUPERBITRF_BIND_RECV_TIME
The time to wait for a bind packet on a channel in microseconds.
uint8_t tx_buffer[SUPERBITRF_TX_BUFFER_SIZE]
The transmit buffer.
enum SuperbitRFStatus status
The status of the superbitRF.
#define SUPERBITRF_RECV_TIME
The time to wait for a transfer packet on a channel in microseconds.
uint8_t packet_loss_bit
The packet loss indicating bit.
uint16_t crc_seed
The CRC seed that is calculated with the bind MFG id.
uint8_t bind_mfg_id[4]
The MFG id where the receiver is bound to.
enum dsm_resolution resolution
The resolution that the transmitter has.
uint8_t state
The states each status can be in.
uint32_t irq_count
How many interrupts are made.
uint8_t channel
The current channel number.
uint32_t timing2
Time between second last receive in microseconds.
uint8_t num_channels
The number of channels the transmitter has.
uint32_t rx_packet_count
How many packets are received(also the invalid)
struct pprz_transport rx_transport
The receive transport.
#define SUPERBITRF_DATARECV_TIME
The time to wait for a data packet on a channel in microseconds.
uint32_t timing1
Time between last receive in microseconds.
uint8_t sop_col
The sop code column number calculated with the bind MFG id.
#define SUPERBITRF_SYNC_RECV_TIME
The time to wait for a sync packet on a channel in microseconds.
struct Cyrf6936 cyrf6936
The cyrf chip used.
uint8_t tx_insert_idx
The transmit buffer insert index.
bool rc_frame_available
When a RC frame is available.
int16_t rc_values[14]
The rc values from the packet.
@ SUPERBITRF_BINDING
The chip is in binding mode.
@ SUPERBITRF_SYNCING_A
The chip is in synchronizing mode for channel A.
@ SUPERBITRF_TRANSFER
The chip is in transfer mode.
@ SUPERBITRF_UNINIT
The chip isn't initialized.
@ SUPERBITRF_INIT_BINDING
The chip is initializing binding mode.
@ SUPERBITRF_INIT_TRANSFER
The chip is initializing transfer mode.
@ SUPERBITRF_SYNCING_B
The chip is in synchronizing mode for channel B.
PRINT_CONFIG_VAR(ONELOOP_ANDI_FILT_CUTOFF)
Persistent settings interface.
#define settings_StoreSettings(_v)
Architecture independent SPI (Serial Peripheral Interface) API.
static const struct usb_device_descriptor dev
Architecture independent timing functions.
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Periodic telemetry system header (includes downlink utility and generated code).
#define DefaultPeriodic
Set default periodic telemetry.
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
short int16_t
Typedef defining 16 bit short type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.