Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
superbitrf.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2013 Freek van Tienen <freek.v.tienen@gmail.com>
3  *
4  * This file is part of paparazzi.
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21 
27 #include "modules/datalink/superbitrf.h"
28 
29 #include <string.h>
30 #include "paparazzi.h"
31 #include "led.h"
32 #include "mcu_periph/spi.h"
33 #include "mcu_periph/sys_time.h"
34 #include "mcu_periph/gpio.h"
35 #include "modules/core/settings.h"
36 
37 /* Default SuperbitRF SPI DEV */
38 #ifndef SUPERBITRF_SPI_DEV
39 #define SUPERBITRF_SPI_DEV spi1
40 #endif
41 PRINT_CONFIG_VAR(SUPERBITRF_SPI_DEV)
42 
43 /* Default SuperbitRF RST PORT and PIN */
44 #ifndef SUPERBITRF_RST_PORT
45 #define SUPERBITRF_RST_PORT GPIOC
46 #endif
47 PRINT_CONFIG_VAR(SUPERBITRF_RST_PORT)
48 #ifndef SUPERBITRF_RST_PIN
49 #define SUPERBITRF_RST_PIN GPIO12
50 #endif
51 PRINT_CONFIG_VAR(SUPERBITRF_RST_PIN)
52 
53 /* Default SuperbitRF DRDY(IRQ) PORT and PIN */
54 #ifndef SUPERBITRF_DRDY_PORT
55 #define SUPERBITRF_DRDY_PORT GPIOB
56 #endif
57 PRINT_CONFIG_VAR(SUPERBITRF_DRDY_PORT)
58 #ifndef SUPERBITRF_DRDY_PIN
59 #define SUPERBITRF_DRDY_PIN GPIO1
60 #endif
61 PRINT_CONFIG_VAR(SUPERBITRF_DRDY_PIN)
62 
63 /* Default forcing in DSM2 mode is false */
64 #ifndef SUPERBITRF_FORCE_DSM2
65 #define SUPERBITRF_FORCE_DSM2 TRUE
66 #endif
67 PRINT_CONFIG_VAR(SUPERBITRF_FORCE_DSM2)
68 
69 #ifndef SUPERBITRF_UPDATE_DL
70 #define SUPERBITRF_UPDATE_DL TRUE
71 #endif
72 
73 /* The superbitRF structure */
74 struct SuperbitRF superbitrf;
75 
76 /* The pprz transport structure */
77 struct pprz_transport pprz_srf_tp;
78 
79 /* The internal functions */
80 static inline void superbitrf_radio_to_channels(uint8_t *data, uint8_t nb_channels, bool is_11bit, int16_t *channels);
81 static inline void superbitrf_receive_packet_cb(bool error, uint8_t status, uint8_t packet[]);
82 static inline void superbitrf_send_packet_cb(bool error);
83 static inline void superbitrf_gen_dsmx_channels(void);
84 
85 /* The startup configuration for the cyrf6936 */
86 static const uint8_t cyrf_stratup_config[][2] = {
87  {CYRF_MODE_OVERRIDE, CYRF_RST}, // Reset the device
88  {CYRF_CLK_EN, CYRF_RXF}, // Enable the clock
89  {CYRF_AUTO_CAL_TIME, 0x3C}, // From manual, needed for initialization
90  {CYRF_AUTO_CAL_OFFSET, 0x14}, // From manual, needed for initialization
91  {CYRF_RX_CFG, CYRF_LNA | CYRF_FAST_TURN_EN}, // Enable low noise amplifier and fast turning
92  {CYRF_TX_OFFSET_LSB, 0x55}, // From manual, typical configuration
93  {CYRF_TX_OFFSET_MSB, 0x05}, // From manual, typical configuration
94  {CYRF_XACT_CFG, CYRF_MODE_SYNTH_RX | CYRF_FRC_END}, // Force in Synth RX mode
95  {CYRF_TX_CFG, CYRF_DATA_CODE_LENGTH | CYRF_DATA_MODE_SDR | CYRF_PA_4}, // Enable 64 chip codes, SDR mode and amplifier +4dBm
96  {CYRF_DATA64_THOLD, 0x0E}, // From manual, typical configuration
97  {CYRF_XACT_CFG, CYRF_MODE_SYNTH_RX}, // Set in Synth RX mode (again, really needed?)
98 };
99 /* The binding configuration for the cyrf6936 */
100 static const uint8_t cyrf_bind_config[][2] = {
101  {CYRF_TX_CFG, CYRF_DATA_CODE_LENGTH | CYRF_DATA_MODE_SDR | CYRF_PA_4}, // Enable 64 chip codes, SDR mode and amplifier +4dBm
102  {CYRF_FRAMING_CFG, CYRF_SOP_LEN | 0xE}, // Set SOP CODE to 64 chips and SOP Correlator Threshold to 0xE
103  {CYRF_RX_OVERRIDE, CYRF_FRC_RXDR | CYRF_DIS_RXCRC}, // Force receive data rate and disable receive CRC checker
104  {CYRF_EOP_CTRL, 0x02}, // Only enable EOP symbol count of 2
105  {CYRF_TX_OVERRIDE, CYRF_DIS_TXCRC}, // Disable transmit CRC generate
106 };
107 /* The transfer configuration for the cyrf6936 */
108 static const uint8_t cyrf_transfer_config[][2] = {
109  {CYRF_TX_CFG, CYRF_DATA_CODE_LENGTH | CYRF_DATA_MODE_8DR | CYRF_PA_4}, // Enable 64 chip codes, 8DR mode and amplifier +4dBm
110  {CYRF_FRAMING_CFG, CYRF_SOP_EN | CYRF_SOP_LEN | CYRF_LEN_EN | 0xE}, // Set SOP CODE enable, SOP CODE to 64 chips, Packet length enable, and SOP Correlator Threshold to 0xE
111  {CYRF_TX_OVERRIDE, 0x00}, // Reset TX overrides
112  {CYRF_RX_OVERRIDE, 0x00}, // Reset RX overrides
113 };
114 /* Abort the receive of the cyrf6936 */
117  {CYRF_RX_ABORT, 0x00}
118 };
119 /* Start the receive of the cyrf6936 */
121  {CYRF_RX_IRQ_STATUS, CYRF_RXOW_IRQ}, // Clear the IRQ
122  {CYRF_RX_CTRL, CYRF_RX_GO | CYRF_RXC_IRQEN | CYRF_RXE_IRQEN} // Start receiving and set the IRQ
123 };
124 
125 /* The PN codes used for DSM2 and DSMX channel hopping */
126 static const uint8_t pn_codes[5][9][8] = {
127  { /* Row 0 */
128  /* Col 0 */ {0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8},
129  /* Col 1 */ {0x88, 0x17, 0x13, 0x3B, 0x2D, 0xBF, 0x06, 0xD6},
130  /* Col 2 */ {0xF1, 0x94, 0x30, 0x21, 0xA1, 0x1C, 0x88, 0xA9},
131  /* Col 3 */ {0xD0, 0xD2, 0x8E, 0xBC, 0x82, 0x2F, 0xE3, 0xB4},
132  /* Col 4 */ {0x8C, 0xFA, 0x47, 0x9B, 0x83, 0xA5, 0x66, 0xD0},
133  /* Col 5 */ {0x07, 0xBD, 0x9F, 0x26, 0xC8, 0x31, 0x0F, 0xB8},
134  /* Col 6 */ {0xEF, 0x03, 0x95, 0x89, 0xB4, 0x71, 0x61, 0x9D},
135  /* Col 7 */ {0x40, 0xBA, 0x97, 0xD5, 0x86, 0x4F, 0xCC, 0xD1},
136  /* Col 8 */ {0xD7, 0xA1, 0x54, 0xB1, 0x5E, 0x89, 0xAE, 0x86}
137  },
138  { /* Row 1 */
139  /* Col 0 */ {0x83, 0xF7, 0xA8, 0x2D, 0x7A, 0x44, 0x64, 0xD3},
140  /* Col 1 */ {0x3F, 0x2C, 0x4E, 0xAA, 0x71, 0x48, 0x7A, 0xC9},
141  /* Col 2 */ {0x17, 0xFF, 0x9E, 0x21, 0x36, 0x90, 0xC7, 0x82},
142  /* Col 3 */ {0xBC, 0x5D, 0x9A, 0x5B, 0xEE, 0x7F, 0x42, 0xEB},
143  /* Col 4 */ {0x24, 0xF5, 0xDD, 0xF8, 0x7A, 0x77, 0x74, 0xE7},
144  /* Col 5 */ {0x3D, 0x70, 0x7C, 0x94, 0xDC, 0x84, 0xAD, 0x95},
145  /* Col 6 */ {0x1E, 0x6A, 0xF0, 0x37, 0x52, 0x7B, 0x11, 0xD4},
146  /* Col 7 */ {0x62, 0xF5, 0x2B, 0xAA, 0xFC, 0x33, 0xBF, 0xAF},
147  /* Col 8 */ {0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97}
148  },
149  { /* Row 2 */
150  /* Col 0 */ {0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97},
151  /* Col 1 */ {0x8E, 0x4A, 0xD0, 0xA9, 0xA7, 0xFF, 0x20, 0xCA},
152  /* Col 2 */ {0x4C, 0x97, 0x9D, 0xBF, 0xB8, 0x3D, 0xB5, 0xBE},
153  /* Col 3 */ {0x0C, 0x5D, 0x24, 0x30, 0x9F, 0xCA, 0x6D, 0xBD},
154  /* Col 4 */ {0x50, 0x14, 0x33, 0xDE, 0xF1, 0x78, 0x95, 0xAD},
155  /* Col 5 */ {0x0C, 0x3C, 0xFA, 0xF9, 0xF0, 0xF2, 0x10, 0xC9},
156  /* Col 6 */ {0xF4, 0xDA, 0x06, 0xDB, 0xBF, 0x4E, 0x6F, 0xB3},
157  /* Col 7 */ {0x9E, 0x08, 0xD1, 0xAE, 0x59, 0x5E, 0xE8, 0xF0},
158  /* Col 8 */ {0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E}
159  },
160  { /* Row 3 */
161  /* Col 0 */ {0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E},
162  /* Col 1 */ {0x80, 0x69, 0x26, 0x80, 0x08, 0xF8, 0x49, 0xE7},
163  /* Col 2 */ {0x7D, 0x2D, 0x49, 0x54, 0xD0, 0x80, 0x40, 0xC1},
164  /* Col 3 */ {0xB6, 0xF2, 0xE6, 0x1B, 0x80, 0x5A, 0x36, 0xB4},
165  /* Col 4 */ {0x42, 0xAE, 0x9C, 0x1C, 0xDA, 0x67, 0x05, 0xF6},
166  /* Col 5 */ {0x9B, 0x75, 0xF7, 0xE0, 0x14, 0x8D, 0xB5, 0x80},
167  /* Col 6 */ {0xBF, 0x54, 0x98, 0xB9, 0xB7, 0x30, 0x5A, 0x88},
168  /* Col 7 */ {0x35, 0xD1, 0xFC, 0x97, 0x23, 0xD4, 0xC9, 0x88},
169  /* Col 8 */ {0x88, 0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40}
170  },
171  { /* Row 4 */
172  /* Col 0 */ {0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40, 0x93},
173  /* Col 1 */ {0xDC, 0x68, 0x08, 0x99, 0x97, 0xAE, 0xAF, 0x8C},
174  /* Col 2 */ {0xC3, 0x0E, 0x01, 0x16, 0x0E, 0x32, 0x06, 0xBA},
175  /* Col 3 */ {0xE0, 0x83, 0x01, 0xFA, 0xAB, 0x3E, 0x8F, 0xAC},
176  /* Col 4 */ {0x5C, 0xD5, 0x9C, 0xB8, 0x46, 0x9C, 0x7D, 0x84},
177  /* Col 5 */ {0xF1, 0xC6, 0xFE, 0x5C, 0x9D, 0xA5, 0x4F, 0xB7},
178  /* Col 6 */ {0x58, 0xB5, 0xB3, 0xDD, 0x0E, 0x28, 0xF1, 0xB0},
179  /* Col 7 */ {0x5F, 0x30, 0x3B, 0x56, 0x96, 0x45, 0xF4, 0xA1},
180  /* Col 8 */ {0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8}
181  },
182 };
183 static const uint8_t pn_bind[] = { 0x98, 0x88, 0x1B, 0xE4, 0x30, 0x79, 0x03, 0x84 };
184 
185 #if PERIODIC_TELEMETRY
187 
188 static void send_superbit(struct transport_tx *trans, struct link_device *dev)
189 {
191  uint8_t cyrf6936_status = superbitrf.cyrf6936.status;
192  pprz_msg_send_SUPERBITRF(trans, dev, AC_ID,
193  &status,
194  &cyrf6936_status,
205  6,
207 }
208 #endif
209 
210 // Functions for the generic device API
211 static int superbitrf_check_free_space(struct SuperbitRF *p, long *fd __attribute__((unused)), uint16_t len)
212 {
213  int space = p->tx_extract_idx - p->tx_insert_idx - 1;
214  if (space < 0) {
215  space += SUPERBITRF_TX_BUFFER_SIZE;
216  }
217  return space >= len ? space : 0;
218 }
219 
220 static void superbitrf_transmit(struct SuperbitRF *p, long fd __attribute__((unused)), uint8_t byte)
221 {
222  p->tx_buffer[p->tx_insert_idx] = byte;
223  p->tx_insert_idx = (p->tx_insert_idx + 1) % SUPERBITRF_TX_BUFFER_SIZE;
224 }
225 
226 static void superbitrf_transmit_buffer(struct SuperbitRF *p, long fd, uint8_t *data, uint16_t len)
227 {
228  int i;
229  for (i = 0; i < len; i++) {
230  superbitrf_transmit(p, fd, data[i]);
231  }
232 }
233 
234 static void superbitrf_send(struct SuperbitRF *p __attribute__((unused)), long fd __attribute__((unused))) { }
235 
236 static int null_function(struct SuperbitRF *p __attribute__((unused))) { return 0; }
237 static uint8_t null_byte_function(struct SuperbitRF *p __attribute__((unused))) { return 0; }
238 
242 void superbitrf_init(void)
243 {
244  // Set the status to uninitialized and set the timer to 0
246  superbitrf.state = 0;
247  superbitrf.timer = 0;
250 
251  // Setup the transmit buffer
254 
257  superbitrf.protocol = 0;
258 
259  // Configure generic device
260  superbitrf.device.periph = (void *)(&superbitrf);
261  superbitrf.device.check_free_space = (check_free_space_t) superbitrf_check_free_space;
262  superbitrf.device.put_byte = (put_byte_t) superbitrf_transmit;
263  superbitrf.device.put_buffer = (put_buffer_t) superbitrf_transmit_buffer;
264  superbitrf.device.send_message = (send_message_t) superbitrf_send;
265  superbitrf.device.char_available = (char_available_t) null_function; // not needed
266  superbitrf.device.get_byte = (get_byte_t) null_byte_function; // not needed
267 
268  // Initialize the binding pin
270 
271  // Initialize the IRQ/DRDY pin
273 
274  // Initialize the cyrf6936 chip
276 
277 #if PERIODIC_TELEMETRY
279 #endif
280 }
281 
286 {
287  // Init pprz transport
288  pprz_transport_init(&pprz_srf_tp);
289 }
290 
295 {
297 }
298 
300 {
303  superbitrf.bind_mfg_id[1] = (superbitrf.bind_mfg_id32 >> 8 & 0xFF);
304  superbitrf.bind_mfg_id[2] = (superbitrf.bind_mfg_id32 >> 16 & 0xFF);
305  superbitrf.bind_mfg_id[3] = (superbitrf.bind_mfg_id32 >> 24 & 0xFF);
306 
307  // Calculate some values based on the bind MFG id
311 }
312 
314 {
315  superbitrf.protocol = protocol;
316  superbitrf.resolution = (superbitrf.protocol & 0x10) >> 4;
317 }
318 
323 {
324  uint8_t i, pn_row, data_code[16];
325  static uint8_t packet_size, tx_packet[16];
326  static bool start_transfer = true;
327 
328 #ifdef RADIO_CONTROL_LED
329  static uint32_t slowLedCpt = 0;
330 #endif
331 
332  // Check if the cyrf6936 isn't busy and the uperbitrf is initialized
334  return;
335  }
336 
337  // When the device is initialized handle the IRQ
339  // First handle the IRQ
341  // Receive the packet
344  }
345 
346  /* Check if it is a valid receive */
348  // Handle the packet received
352 
353  // Reset the packet receiving
354  superbitrf.cyrf6936.has_irq = false;
355  }
356 
357  /* Check if it has a valid send */
359  // Handle the send packet
362 
363  // Reset the packet receiving
364  superbitrf.cyrf6936.has_irq = false;
365  }
366  }
367 
368  // Check the status of the superbitrf
369  switch (superbitrf.status) {
370 
371  /* When the superbitrf isn't initialized */
372  case SUPERBITRF_UNINIT:
373  // Try to write the startup config
375  // Check if need to go to bind or transfer
377  start_transfer = false;
378  }
379 
381  }
382  break;
383 
384  /* When the superbitrf is initializing binding */
386  /* Switch the different states */
387  switch (superbitrf.state) {
388  case 0:
389  // Try to write the binding config
391  superbitrf.state++;
392  break;
393  case 1:
394  // Set the data code and channel
395  memcpy(data_code, pn_codes[0][8], 8);
396  memcpy(data_code + 8, pn_bind, 8);
397  cyrf6936_write_chan_sop_data_crc(&superbitrf.cyrf6936, 1, pn_codes[0][0], data_code, 0x0000);
398 
400  break;
401  default:
402  // Should not happen
403  superbitrf.state = 0;
404  break;
405  }
406  break;
407 
408  /* When the superbitrf is initializing transfer */
410  // Generate the DSMX channels
412 
413  // Try to write the transfer config
416  superbitrf.packet_loss = false;
419  superbitrf.state = 1;
420  }
421  break;
422 
423  /* When the superbitrf is in binding mode */
424  case SUPERBITRF_BINDING:
425 
426 #ifdef RADIO_CONTROL_LED
427  slowLedCpt++;
428  if (slowLedCpt > 100000) {
429 
430  LED_TOGGLE(RADIO_CONTROL_LED);
431  slowLedCpt = 0;
432  }
433 #endif
434 
435  /* Switch the different states */
436  switch (superbitrf.state) {
437  case 0:
438  // When there is a timeout
440  superbitrf.state++;
441  }
442  break;
443  case 1:
444  // Abort the receive
446 
447  superbitrf.state++;
448  break;
449  case 2:
450  // Switch channel
451  superbitrf.channel = (superbitrf.channel + 2) % 0x4F; //TODO fix define
453 
454  superbitrf.state += 2; // Already aborted
455  break;
456  case 3:
457  // Abort the receive
459 
460  superbitrf.state++;
461  break;
462  case 4:
463  // Start receiving
465  superbitrf.state++;
466  break;
467  default:
468  // Check if need to go to transfer
469  if (start_transfer) {
470  // Initialize the binding values
471  // set values based on mfg id
472  // if bind_mfg_id32 is loaded from persistent settings use that,
475  }
476 #ifdef RADIO_TRANSMITTER_ID
477  // otherwise load airframe file value
478  else {
479  PRINT_CONFIG_VAR(RADIO_TRANSMITTER_ID)
480  superbitrf_set_mfg_id(RADIO_TRANSMITTER_ID);
481  }
482 #endif
483 #ifdef RADIO_TRANSMITTER_CHAN
484  PRINT_CONFIG_VAR(RADIO_TRANSMITTER_CHAN)
485  if (superbitrf.num_channels == 0) {
486  superbitrf.num_channels = RADIO_TRANSMITTER_CHAN;
487  }
488 #endif
489  if (superbitrf.protocol == 0) {
491  }
492 #ifdef RADIO_TRANSMITTER_PROTOCOL
493  else {
494  PRINT_CONFIG_VAR(RADIO_TRANSMITTER_PROTOCOL)
495  superbitrf_set_protocol(RADIO_TRANSMITTER_PROTOCOL);
496  }
497 #endif
498 
499  // Start transfer
500  superbitrf.state = 0;
502  break;
503  }
504 
505  // Set the timer
507  superbitrf.state = 0;
508  break;
509  }
510  break;
511 
512  /* When the receiver is synchronizing with the transmitter */
515 
516 #ifdef RADIO_CONTROL_LED
517  slowLedCpt++;
518  if (slowLedCpt > 5000) {
519 
520  LED_TOGGLE(RADIO_CONTROL_LED);
521  slowLedCpt = 0;
522  }
523 #endif
524 
525  /* Switch the different states */
526  switch (superbitrf.state) {
527  case 0:
528  // When there is a timeout
530  superbitrf.state++;
531  }
532  break;
533  case 1:
534  // Abort the receive
536  superbitrf.state++;
537  break;
538  case 2:
539  // Switch channel, sop code, data code and crc
542  pn_row = (IS_DSM2(superbitrf.protocol)
545 
547  pn_codes[pn_row][superbitrf.sop_col],
548  pn_codes[pn_row][superbitrf.data_col],
550  superbitrf.state++;
551  break;
552  case 3:
553  // Create a new packet when no packet loss
554  if (!superbitrf.packet_loss) {
557  tx_packet[0] = ~superbitrf.bind_mfg_id[2];
558  tx_packet[1] = (~superbitrf.bind_mfg_id[3]) + 1 + superbitrf.packet_loss_bit;
559  } else {
560  tx_packet[0] = superbitrf.bind_mfg_id[2];
561  tx_packet[1] = (superbitrf.bind_mfg_id[3]) + 1 + superbitrf.packet_loss_bit;
562  }
563 
566  if (packet_size > 14) {
567  packet_size = 14;
568  }
569 
570  for (i = 0; i < packet_size; i++) {
572  }
573  }
574 
575  // Send a packet
576  cyrf6936_send(&superbitrf.cyrf6936, tx_packet, packet_size + 2);
577 
578  // Update the packet extraction
579  if (!superbitrf.packet_loss) {
581  }
582 
583  superbitrf.state++;
584  break;
585  case 4:
586  //TODO: check timeout? (Waiting for send)
587  break;
588  case 5:
589  superbitrf.state = 7;
590  break;
591  case 6:
592  // Wait for telemetry data
594  superbitrf.state++;
595  }
596  break;
597  case 7:
598  // When DSMX we don't need to switch
600  superbitrf.state++;
602  break;
603  }
604 
605  // Switch channel, sop code, data code and crc
606  superbitrf.channel = (superbitrf.channel + 2) % 0x4F; //TODO fix define
608  pn_row = (IS_DSM2(superbitrf.protocol)
610 
612  pn_codes[pn_row][superbitrf.sop_col],
613  pn_codes[pn_row][superbitrf.data_col],
615 
616  superbitrf.state++;
617  break;
618  case 8:
619  // Start receiving
621  superbitrf.state++;
622  break;
623  default:
624  // Set the timer
626  superbitrf.state = 0;
627  break;
628  }
629  break;
630 
631  /* Normal transfer mode */
632  case SUPERBITRF_TRANSFER:
633 
634 #ifdef RADIO_CONTROL_LED
635  LED_ON(RADIO_CONTROL_LED);
636 #endif
637 
638  /* Switch the different states */
639  switch (superbitrf.state) {
640  case 0:
641  // Fixing timer overflow
643  superbitrf.timer_overflow = false;
644  }
645 
646  // When there is a timeout
650  superbitrf.state++;
651  }
652 
653  // We really lost the communication
654  if (superbitrf.timeouts > 100) {
655  superbitrf.state = 0;
658  }
659  break;
660  case 1:
661  // Abort the receive
663  superbitrf.state++;
664 
665  // Set the timer
668  superbitrf.timer_overflow = true;
669  } else {
670  superbitrf.timer_overflow = false;
671  }
672 
673  // Only send on channel 2
675  superbitrf.state = 8;
676  }
677  break;
678  case 2:
679  // Wait before sending (FIXME??)
680  superbitrf.state++;
681  break;
682  case 3:
683  // Create a new packet when no packet loss
684  if (!superbitrf.packet_loss) {
687  tx_packet[0] = ~superbitrf.bind_mfg_id[2];
688  tx_packet[1] = ((~superbitrf.bind_mfg_id[3]) + 1 + superbitrf.packet_loss_bit) % 0xFF;
689  } else {
690  tx_packet[0] = superbitrf.bind_mfg_id[2];
691  tx_packet[1] = ((superbitrf.bind_mfg_id[3]) + 1 + superbitrf.packet_loss_bit) % 0xFF;
692  }
693 
696  if (packet_size > 14) {
697  packet_size = 14;
698  }
699 
700  for (i = 0; i < packet_size; i++) {
702  }
703  }
704 
705  // Send a packet
706  cyrf6936_send(&superbitrf.cyrf6936, tx_packet, packet_size + 2);
707 
708  // Update the packet extraction
709  if (!superbitrf.packet_loss) {
711  }
712 
713  superbitrf.state++;
714  break;
715  case 4:
716  //TODO: check timeout? (Waiting for send)
717  break;
718  case 5:
719  // Start receiving
721  superbitrf.state++;
722  break;
723  case 6:
724  // Fixing timer overflow
726  superbitrf.timer_overflow = false;
727  }
728 
729  // Waiting for data receive
731  superbitrf.state++;
732  }
733  break;
734  case 7:
735  // Abort the receive
737  superbitrf.state++;
738  break;
739  case 8:
740  // Switch channel, sop code, data code and crc
745  pn_row = (IS_DSM2(superbitrf.protocol)
747 
749  pn_codes[pn_row][superbitrf.sop_col],
750  pn_codes[pn_row][superbitrf.data_col],
752 
753  superbitrf.state++;
754  break;
755  case 9:
756  // Start receiving
758  superbitrf.state++;
759  break;
760  default:
761  // Set the timer
764  } else {
766  }
768  superbitrf.timer_overflow = true;
769  } else {
770  superbitrf.timer_overflow = false;
771  }
772 
773  superbitrf.state = 0;
774  break;
775  }
776  break;
777 
778  /* Should not come here */
779  default:
780  break;
781  }
782 }
783 
787 static inline void superbitrf_receive_packet_cb(bool error, uint8_t status, uint8_t packet[])
788 {
789  int i;
790  uint16_t sum;
791 
792  /* Switch on the status of the superbitRF */
793  switch (superbitrf.status) {
794 
795  /* When we are in binding mode */
796  case SUPERBITRF_BINDING:
797  // Check if the MFG id is exactly the same
798  if (packet[0] != packet[4] || packet[1] != packet[5] || packet[2] != packet[6] || packet[3] != packet[7]) {
799  // Start receiving without changing channel
800  superbitrf.state = 3;
801  break;
802  }
803 
804  // Calculate the first sum
805  sum = 384 - 0x10;
806  for (i = 0; i < 8; i++) {
807  sum += packet[i];
808  }
809 
810  // Check the first sum
811  if (packet[8] != sum >> 8 || packet[9] != (sum & 0xFF)) {
812  // Start receiving without changing channel
813  superbitrf.state = 3;
814  break;
815  }
816 
817  // Calculate second sum
818  for (i = 8; i < 14; i++) {
819  sum += packet[i];
820  }
821 
822  // Check the second sum
823  if (packet[14] != sum >> 8 || packet[15] != (sum & 0xFF)) {
824  // Start receiving without changing channel
825  superbitrf.state = 3;
826  break;
827  }
828 
829  // Update the mfg id, number of channels and protocol
830  uint32_t mfg_id = ((~packet[3] & 0xFF) << 24 | (~packet[2] & 0xFF) << 16 |
831  (~packet[1] & 0xFF) << 8 | (~packet[0] & 0xFF));
832  superbitrf_set_mfg_id(mfg_id);
833 
834  superbitrf.num_channels = packet[11];
835  superbitrf_set_protocol(packet[12]);
836 
837  // Store all the persistent settings.
838  // In case we have the superbit setting file loaded and persistent settings
839  // enabled in the airframe file this will store our binding information and
840  // survive a reboot.
842 
843  // Update the status of the receiver
844  superbitrf.state = 0;
846  break;
847 
848  /* When we receive a packet during syncing first channel A */
850  // Check the MFG id
851  if (error && !(status & CYRF_BAD_CRC)) {
852  // Start receiving TODO: Fix nicely
854  break;
855  }
857  (packet[0] != (~superbitrf.bind_mfg_id[2] & 0xFF) || (packet[1] != (~superbitrf.bind_mfg_id[3] & 0xFF) &&
858  packet[1] != (~superbitrf.bind_mfg_id[3] & 0xFF) + 1))) {
859  // Start receiving TODO: Fix nicely
861  break;
862  }
864  (packet[0] != (superbitrf.bind_mfg_id[2] & 0xFF) || (packet[1] != (superbitrf.bind_mfg_id[3] & 0xFF) &&
865  packet[1] != (superbitrf.bind_mfg_id[3] & 0xFF) + 1))) {
866  // Start receiving TODO: Fix nicely
868  break;
869  }
870 
871  // If the CRC is wrong invert
872  if (error && (status & CYRF_BAD_CRC)) {
874  }
875 
876  // When we receive a data packet
877  if (packet[1] != (~superbitrf.bind_mfg_id[3] & 0xFF) && packet[1] != (superbitrf.bind_mfg_id[3] & 0xFF)) {
879 
880  // Check if it is a data loss packet
881  if (packet[1] != (~superbitrf.bind_mfg_id[3] + 1 + superbitrf.packet_loss_bit) % 0xFF
882  && packet[1] != (superbitrf.bind_mfg_id[3] + 1 + superbitrf.packet_loss_bit) % 0xFF) {
883  superbitrf.packet_loss = true;
884  } else {
885  superbitrf.packet_loss = false;
886  }
887 
888  // When it is a data packet, parse the packet if not busy already
890  for (i = 2; i < superbitrf.cyrf6936.rx_count; i++) {
891  parse_pprz(&superbitrf.rx_transport, packet[i]);
892 
893  // When we have a full message
894  if (superbitrf.rx_transport.trans_rx.msg_received) {
895  DatalinkFillDlBuffer(superbitrf.rx_transport.trans_rx.payload, superbitrf.rx_transport.trans_rx.payload_len);
896  superbitrf.rx_transport.trans_rx.msg_received = false;
897  }
898  }
899  }
900  break;
901  }
902 
906 
907  superbitrf.state = 1;
909  } else {
910  superbitrf.timeouts = 0;
911  superbitrf.state = 1;
913  }
914  break;
915 
916  /* When we receive a packet during syncing second channel B */
918  // Check the MFG id
919  if (error && !(status & CYRF_BAD_CRC)) {
920  // Start receiving TODO: Fix nicely
922  break;
923  }
925  (packet[0] != (~superbitrf.bind_mfg_id[2] & 0xFF) || (packet[1] != (~superbitrf.bind_mfg_id[3] & 0xFF) &&
926  packet[1] != (~superbitrf.bind_mfg_id[3] & 0xFF) + 1 && packet[1] != (~superbitrf.bind_mfg_id[3] & 0xFF) + 2))) {
927  // Start receiving TODO: Fix nicely
929  break;
930  }
932  (packet[0] != (superbitrf.bind_mfg_id[2] & 0xFF) || (packet[1] != (superbitrf.bind_mfg_id[3] & 0xFF) &&
933  packet[1] != (superbitrf.bind_mfg_id[3] & 0xFF) + 1 && packet[1] != (superbitrf.bind_mfg_id[3] & 0xFF) + 2))) {
934  // Start receiving TODO: Fix nicely
936  break;
937  }
938 
939  // If the CRC is wrong invert
940  if (error && (status & CYRF_BAD_CRC)) {
942  }
943 
944  // When we receive a data packet
945  if (packet[1] != (~superbitrf.bind_mfg_id[3] & 0xFF) && packet[1] != (superbitrf.bind_mfg_id[3] & 0xFF)) {
947 
948  // When it is a data packet, parse the packet if not busy already
949  if (!dl_msg_available) {
950  for (i = 2; i < superbitrf.cyrf6936.rx_count; i++) {
951  parse_pprz(&superbitrf.rx_transport, packet[i]);
952 
953  // When we have a full message
954  if (superbitrf.rx_transport.trans_rx.msg_received) {
955  DatalinkFillDlBuffer(superbitrf.rx_transport.trans_rx.payload, superbitrf.rx_transport.trans_rx.payload_len);
956  superbitrf.rx_transport.trans_rx.msg_received = false;
957  }
958  }
959  }
960  break;
961  }
962 
963  // Set the channel
967  } else {
970  }
971 
972  // When the channels aren't the same go to transfer mode
973  if (superbitrf.channels[1] != superbitrf.channels[0]) {
974  superbitrf.state = 1;
976  superbitrf.timeouts = 0;
977  }
978  break;
979 
980  /* When we receive a packet during transfer */
981  case SUPERBITRF_TRANSFER:
982  // Check the MFG id
983  if (error) {
984  // Start receiving TODO: Fix nicely
986  break;
987  }
989  (packet[0] != (~superbitrf.bind_mfg_id[2] & 0xFF) || (packet[1] != (~superbitrf.bind_mfg_id[3] & 0xFF) &&
990  packet[1] != (~superbitrf.bind_mfg_id[3] & 0xFF) + 1 && packet[1] != (~superbitrf.bind_mfg_id[3] & 0xFF) + 2))) {
991  // Start receiving TODO: Fix nicely
993  break;
994  }
996  (packet[0] != (superbitrf.bind_mfg_id[2] & 0xFF) || (packet[1] != (superbitrf.bind_mfg_id[3] & 0xFF) &&
997  packet[1] != (superbitrf.bind_mfg_id[3] & 0xFF) + 1 && packet[1] != (superbitrf.bind_mfg_id[3] & 0xFF) + 2))) {
998  // Start receiving TODO: Fix nicely
1000  break;
1001  }
1002 
1003  // Check if it is a RC packet
1004  if (packet[1] == (~superbitrf.bind_mfg_id[3] & 0xFF) || packet[1] == (superbitrf.bind_mfg_id[3] & 0xFF)) {
1005  superbitrf.rc_count++;
1006 
1007  // Parse the packet
1010 
1011  // Calculate the timing (seperately for the channel switches)
1012  if (superbitrf.crc_seed != ((superbitrf.bind_mfg_id[0] << 8) + superbitrf.bind_mfg_id[1])) {
1014  } else {
1016  }
1017 
1018  // Go to next receive
1019  superbitrf.state = 1;
1020  superbitrf.timeouts = 0;
1021  } else {
1023 
1024  // Check if it is a data loss packet
1025  if (packet[1] != (~superbitrf.bind_mfg_id[3] + 1 + superbitrf.packet_loss_bit)
1026  && packet[1] != (superbitrf.bind_mfg_id[3] + 1 + superbitrf.packet_loss_bit)) {
1027  superbitrf.packet_loss = true;
1028  } else {
1029  superbitrf.packet_loss = false;
1030  }
1031 
1032  superbitrf.packet_loss = false;
1033 
1034  // When it is a data packet, parse the packet if not busy already
1036  for (i = 2; i < superbitrf.cyrf6936.rx_count; i++) {
1037  parse_pprz(&superbitrf.rx_transport, packet[i]);
1038 
1039  // When we have a full message
1040  if (superbitrf.rx_transport.trans_rx.msg_received) {
1041  DatalinkFillDlBuffer(superbitrf.rx_transport.trans_rx.payload, superbitrf.rx_transport.trans_rx.payload_len);
1042  superbitrf.rx_transport.trans_rx.msg_received = false;
1043  }
1044  }
1045  }
1046 
1047  // Update the state
1048  superbitrf.state = 7;
1049  }
1050  break;
1051 
1052  /* Should not come here */
1053  default:
1054  break;
1055  }
1056 }
1057 
1058 static inline void superbitrf_send_packet_cb(bool error __attribute__((unused)))
1059 {
1060  /* Switch on the status of the superbitRF */
1061  switch (superbitrf.status) {
1062 
1063  /* When we are synchronizing */
1064  case SUPERBITRF_SYNCING_A:
1065  case SUPERBITRF_SYNCING_B:
1066  // When we successfully or unsuccessfully send a data packet
1067  if (superbitrf.state == 4) {
1068  superbitrf.state++;
1069  }
1070  break;
1071 
1072  /* When we are in transfer mode */
1073  case SUPERBITRF_TRANSFER:
1074  // When we successfully or unsuccessfully send a packet
1075  if (superbitrf.state == 4) {
1076  superbitrf.state++;
1077  }
1078  break;
1079 
1080  /* Should not come here */
1081  default:
1082  break;
1083  }
1084 }
1085 
1089 static inline void superbitrf_radio_to_channels(uint8_t *data, uint8_t nb_channels, bool is_11bit, int16_t *channels)
1090 {
1091  int i;
1092  uint8_t bit_shift = (is_11bit) ? 11 : 10;
1093  int16_t value_max = (is_11bit) ? 0x07FF : 0x03FF;
1094 
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;
1098  const int16_t val = (tmp & value_max);
1099 
1100  if (chan < nb_channels) {
1101  channels[chan] = val;
1102 
1103  // Scale the channel
1104  if (is_11bit) {
1105  channels[chan] -= 0x400;
1106  channels[chan] *= MAX_PPRZ / 0x2AC;
1107  } else {
1108  channels[chan] -= 0x200;
1109  channels[chan] *= MAX_PPRZ / 0x156;
1110  }
1111  }
1112  }
1113 }
1114 
1118 static inline void superbitrf_gen_dsmx_channels(void)
1119 {
1120  // Calculate the DSMX channels
1121  int idx = 0;
1122  uint32_t id = ~((superbitrf.bind_mfg_id[0] << 24) | (superbitrf.bind_mfg_id[1] << 16) |
1123  (superbitrf.bind_mfg_id[2] << 8) | (superbitrf.bind_mfg_id[3] << 0));
1124  uint32_t id_tmp = id;
1125 
1126  // While not all channels are set
1127  while (idx < 23) {
1128  int i;
1129  int count_3_27 = 0, count_28_51 = 0, count_52_76 = 0;
1130 
1131  id_tmp = id_tmp * 0x0019660D + 0x3C6EF35F; // Randomization
1132  uint8_t next_ch = ((id_tmp >> 8) % 0x49) + 3; // Use least-significant byte and must be larger than 3
1133  if (((next_ch ^ id) & 0x01) == 0) {
1134  continue;
1135  }
1136 
1137  // Go trough all already set channels
1138  for (i = 0; i < idx; i++) {
1139  // Channel is already used
1140  if (superbitrf.channels[i] == next_ch) {
1141  break;
1142  }
1143 
1144  // Count the channel groups
1145  if (superbitrf.channels[i] <= 27) {
1146  count_3_27++;
1147  } else if (superbitrf.channels[i] <= 51) {
1148  count_28_51++;
1149  } else {
1150  count_52_76++;
1151  }
1152  }
1153 
1154  // When channel is already used continue
1155  if (i != idx) {
1156  continue;
1157  }
1158 
1159  // Set the channel when channel groups aren't full
1160  if ((next_ch < 28 && count_3_27 < 8) // Channels 3-27: max 8
1161  || (next_ch >= 28 && next_ch < 52 && count_28_51 < 7) // Channels 28-52: max 7
1162  || (next_ch >= 52 && count_52_76 < 8)) { // Channels 52-76: max 8
1163  superbitrf.channels[idx++] = next_ch;
1164  }
1165  }
1166 }
1167 
1168 
1169 
#define SPEKTRUM_BIND_PIN_PORT
Definition: board.h:402
#define SPEKTRUM_BIND_PIN
Definition: board.h:401
#define LED_ON(i)
Definition: led_hw.h:51
#define LED_TOGGLE(i)
Definition: led_hw.h:53
void gpio_setup_input(ioportid_t port, uint16_t gpios)
Setup one or more pins of the given GPIO port as inputs.
Definition: gpio_arch.c:40
static uint8_t gpio_get(ioportid_t port, uint16_t pin)
Get level of a gpio.
Definition: gpio_arch.h:88
uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
Definition: sys_time_arch.c:71
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.
Definition: cyrf6936.c:47
bool cyrf6936_multi_write(struct Cyrf6936 *cyrf, const uint8_t data[][2], const uint8_t length)
Write to multiple registers one byte.
Definition: cyrf6936.c:341
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.
Definition: cyrf6936.c:373
bool cyrf6936_write(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t data)
Write to one register.
Definition: cyrf6936.c:330
bool cyrf6936_read_rx_irq_status_packet(struct Cyrf6936 *cyrf)
Read the RX IRQ status register, the rx status register and the rx packet.
Definition: cyrf6936.c:412
bool cyrf6936_send(struct Cyrf6936 *cyrf, const uint8_t data[], const uint8_t length)
Send a packet with a certain length.
Definition: cyrf6936.c:432
@ CYRF6936_IDLE
The chip is idle and can be used.
Definition: cyrf6936.h:38
uint8_t rx_status
The last receive status.
Definition: cyrf6936.h:63
uint8_t rx_count
The length of the received packet.
Definition: cyrf6936.h:64
enum Cyrf6936Status status
The status of the CYRF6936 chip.
Definition: cyrf6936.h:51
bool has_irq
When the CYRF6936 is done reading the irq.
Definition: cyrf6936.h:59
uint8_t tx_irq_status
The last send interrupt status.
Definition: cyrf6936.h:61
uint8_t mfg_id[6]
The manufacturer id of the CYRF6936 chip.
Definition: cyrf6936.h:60
uint8_t rx_packet[16]
The last received packet.
Definition: cyrf6936.h:65
uint8_t rx_irq_status
The last receive interrupt status.
Definition: cyrf6936.h:62
#define CYRF_RXE_IRQ
#define CYRF_RXE_IRQEN
#define CYRF_RXF
Definition: cyrf6936_regs.h:84
#define CYRF_BAD_CRC
@ CYRF_DATA_MODE_SDR
@ CYRF_DATA_MODE_8DR
#define CYRF_SOP_LEN
#define CYRF_RX_GO
#define CYRF_DIS_RXCRC
@ CYRF_EOP_CTRL
Definition: cyrf6936_regs.h:52
@ CYRF_TX_OFFSET_LSB
Definition: cyrf6936_regs.h:59
@ CYRF_AUTO_CAL_TIME
Definition: cyrf6936_regs.h:74
@ CYRF_RX_OVERRIDE
Definition: cyrf6936_regs.h:62
@ CYRF_FRAMING_CFG
Definition: cyrf6936_regs.h:48
@ CYRF_CHANNEL
Definition: cyrf6936_regs.h:32
@ CYRF_XACT_CFG
Definition: cyrf6936_regs.h:47
@ CYRF_RX_ABORT
Definition: cyrf6936_regs.h:73
@ CYRF_DATA64_THOLD
Definition: cyrf6936_regs.h:50
@ CYRF_CLK_EN
Definition: cyrf6936_regs.h:72
@ CYRF_RX_CTRL
Definition: cyrf6936_regs.h:37
@ CYRF_TX_CFG
Definition: cyrf6936_regs.h:35
@ CYRF_MODE_OVERRIDE
Definition: cyrf6936_regs.h:61
@ CYRF_TX_OFFSET_MSB
Definition: cyrf6936_regs.h:60
@ CYRF_TX_OVERRIDE
Definition: cyrf6936_regs.h:63
@ CYRF_RX_CFG
Definition: cyrf6936_regs.h:38
@ CYRF_AUTO_CAL_OFFSET
Definition: cyrf6936_regs.h:75
@ CYRF_RX_IRQ_STATUS
Definition: cyrf6936_regs.h:39
#define CYRF_RST
Definition: cyrf6936_regs.h:81
#define CYRF_FRC_RXDR
#define CYRF_RXOW_IRQ
#define CYRF_FAST_TURN_EN
#define CYRF_TXE_IRQ
@ CYRF_MODE_SYNTH_RX
Definition: cyrf6936_regs.h:91
#define CYRF_FRC_END
Definition: cyrf6936_regs.h:94
#define CYRF_RXC_IRQEN
#define CYRF_LNA
#define CYRF_SOP_EN
#define CYRF_TXC_IRQ
@ CYRF_PA_4
#define CYRF_RXC_IRQ
#define CYRF_LEN_EN
#define CYRF_DATA_CODE_LENGTH
#define CYRF_DIS_TXCRC
Some architecture independent helper functions for GPIOs.
static float p[2][2]
arch independent LED (Light Emitting Diodes) API
uint8_t dl_buffer[MSG_SIZE]
Definition: main_demo5.c:63
bool dl_msg_available
Flag provided to control calls to dl_parse_msg.
Definition: main_demo5.c:60
#define byte
static uint32_t idx
uint8_t status
#define MAX_PPRZ
Definition: paparazzi.h:8
int fd
Definition: serial.c:26
Persistent settings interface.
#define settings_StoreSettings(_v)
Definition: settings.h:44
Architecture independent SPI (Serial Peripheral Interface) API.
#define DOWNLINK_DEVICE
static const struct usb_device_descriptor dev
Definition: usb_ser_hw.c:74
Architecture independent timing functions.
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Definition: telemetry.c:51
Periodic telemetry system header (includes downlink utility and generated code).
#define DefaultPeriodic
Set default periodic telemetry.
Definition: telemetry.h:66
uint16_t val[TCOUPLE_NB]
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
Definition: vl53l1_types.h:88
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
Definition: vl53l1_types.h:78
short int16_t
Typedef defining 16 bit short type.
Definition: vl53l1_types.h:93
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98