Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
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"
36
37/* Default SuperbitRF SPI DEV */
38#ifndef SUPERBITRF_SPI_DEV
39#define SUPERBITRF_SPI_DEV spi1
40#endif
42
43/* Default SuperbitRF RST PORT and PIN */
44#ifndef SUPERBITRF_RST_PORT
45#define SUPERBITRF_RST_PORT GPIOC
46#endif
48#ifndef SUPERBITRF_RST_PIN
49#define SUPERBITRF_RST_PIN GPIO12
50#endif
52
53/* Default SuperbitRF DRDY(IRQ) PORT and PIN */
54#ifndef SUPERBITRF_DRDY_PORT
55#define SUPERBITRF_DRDY_PORT GPIOB
56#endif
58#ifndef SUPERBITRF_DRDY_PIN
59#define SUPERBITRF_DRDY_PIN GPIO1
60#endif
62
63/* Default forcing in DSM2 mode is false */
64#ifndef SUPERBITRF_FORCE_DSM2
65#define SUPERBITRF_FORCE_DSM2 TRUE
66#endif
68
69#ifndef SUPERBITRF_UPDATE_DL
70#define SUPERBITRF_UPDATE_DL TRUE
71#endif
72
73/* The superbitRF structure */
75
76/* The pprz transport structure */
78
79/* The internal functions */
80static inline void superbitrf_radio_to_channels(uint8_t *data, uint8_t nb_channels, bool is_11bit, int16_t *channels);
81static inline void superbitrf_receive_packet_cb(bool error, uint8_t status, uint8_t packet[]);
82static inline void superbitrf_send_packet_cb(bool error);
83static inline void superbitrf_gen_dsmx_channels(void);
84
85/* The startup configuration for the cyrf6936 */
86static 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 */
100static 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 */
108static 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 */
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 */
126static 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};
183static const uint8_t pn_bind[] = { 0x98, 0x88, 0x1B, 0xE4, 0x30, 0x79, 0x03, 0x84 };
184
185#if PERIODIC_TELEMETRY
187
208#endif
209
210// Functions for the generic device API
211static 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) {
216 }
217 return space >= len ? space : 0;
218}
219
220static 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
226static 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
234static void superbitrf_send(struct SuperbitRF *p __attribute__((unused)), long fd __attribute__((unused))) { }
235
236static int null_function(struct SuperbitRF *p __attribute__((unused))) { return 0; }
237static uint8_t null_byte_function(struct SuperbitRF *p __attribute__((unused))) { return 0; }
238
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
258
259 // Configure generic device
260 superbitrf.device.periph = (void *)(&superbitrf);
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
289}
290
298
300{
306
307 // Calculate some values based on the bind MFG id
311}
312
314{
315 superbitrf.protocol = protocol;
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
355 }
356
357 /* Check if it has a valid send */
359 // Handle the send packet
362
363 // Reset the packet receiving
365 }
366 }
367
368 // Check the status of the superbitrf
369 switch (superbitrf.status) {
370
371 /* When the superbitrf isn't initialized */
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
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);
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 */
425
426#ifdef RADIO_CONTROL_LED
427 slowLedCpt++;
428 if (slowLedCpt > 100000) {
429
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
441 }
442 break;
443 case 1:
444 // Abort the receive
446
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
461 break;
462 case 4:
463 // Start receiving
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 {
481 }
482#endif
483#ifdef RADIO_TRANSMITTER_CHAN
485 if (superbitrf.num_channels == 0) {
487 }
488#endif
489 if (superbitrf.protocol == 0) {
491 }
492#ifdef RADIO_TRANSMITTER_PROTOCOL
493 else {
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
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
531 }
532 break;
533 case 1:
534 // Abort the receive
537 break;
538 case 2:
539 // Switch channel, sop code, data code and crc
545
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 {
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
577
578 // Update the packet extraction
579 if (!superbitrf.packet_loss) {
581 }
582
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
595 }
596 break;
597 case 7:
598 // When DSMX we don't need to switch
602 break;
603 }
604
605 // Switch channel, sop code, data code and crc
606 superbitrf.channel = (superbitrf.channel + 2) % 0x4F; //TODO fix define
610
615
617 break;
618 case 8:
619 // Start receiving
622 break;
623 default:
624 // Set the timer
626 superbitrf.state = 0;
627 break;
628 }
629 break;
630
631 /* Normal transfer mode */
633
634#ifdef RADIO_CONTROL_LED
636#endif
637
638 /* Switch the different states */
639 switch (superbitrf.state) {
640 case 0:
641 // Fixing timer overflow
644 }
645
646 // When there is a timeout
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
664
665 // Set the timer
669 } else {
671 }
672
673 // Only send on channel 2
675 superbitrf.state = 8;
676 }
677 break;
678 case 2:
679 // Wait before sending (FIXME??)
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 {
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
707
708 // Update the packet extraction
709 if (!superbitrf.packet_loss) {
711 }
712
714 break;
715 case 4:
716 //TODO: check timeout? (Waiting for send)
717 break;
718 case 5:
719 // Start receiving
722 break;
723 case 6:
724 // Fixing timer overflow
727 }
728
729 // Waiting for data receive
732 }
733 break;
734 case 7:
735 // Abort the receive
738 break;
739 case 8:
740 // Switch channel, sop code, data code and crc
747
752
754 break;
755 case 9:
756 // Start receiving
759 break;
760 default:
761 // Set the timer
764 } else {
766 }
769 } else {
771 }
772
773 superbitrf.state = 0;
774 break;
775 }
776 break;
777
778 /* Should not come here */
779 default:
780 break;
781 }
782}
783
787static 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 */
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
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++) {
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 {
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++) {
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;
977 }
978 break;
979
980 /* When we receive a packet during 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)) {
1006
1007 // Parse the packet
1010
1011 // Calculate the timing (seperately for the channel switches)
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
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++) {
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
1058static 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 */
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 */
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
1089static 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
1118static 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
1164 }
1165 }
1166}
1167
1168
1169
#define SPEKTRUM_BIND_PIN_PORT
Definition board.h:402
#define SPEKTRUM_BIND_PIN
Definition board.h:401
static uint8_t status
#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:94
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.
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
@ CYRF_EOP_CTRL
@ CYRF_TX_OFFSET_LSB
@ CYRF_AUTO_CAL_TIME
@ CYRF_RX_OVERRIDE
@ CYRF_FRAMING_CFG
@ CYRF_CHANNEL
@ CYRF_XACT_CFG
@ CYRF_RX_ABORT
@ CYRF_DATA64_THOLD
@ CYRF_CLK_EN
@ CYRF_RX_CTRL
@ CYRF_TX_CFG
@ CYRF_MODE_OVERRIDE
@ CYRF_TX_OFFSET_MSB
@ CYRF_TX_OVERRIDE
@ CYRF_RX_CFG
@ CYRF_AUTO_CAL_OFFSET
@ CYRF_RX_IRQ_STATUS
#define CYRF_RXE_IRQ
#define CYRF_RXE_IRQEN
#define CYRF_RXF
#define CYRF_BAD_CRC
#define CYRF_SOP_LEN
#define CYRF_RX_GO
#define CYRF_DIS_RXCRC
@ CYRF_MODE_SYNTH_RX
#define CYRF_RST
#define CYRF_FRC_RXDR
#define CYRF_RXOW_IRQ
#define CYRF_FAST_TURN_EN
#define CYRF_TXE_IRQ
@ CYRF_PA_4
#define CYRF_FRC_END
@ CYRF_DATA_MODE_SDR
@ CYRF_DATA_MODE_8DR
#define CYRF_RXC_IRQEN
#define CYRF_LNA
#define CYRF_SOP_EN
#define CYRF_TXC_IRQ
#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
uint16_t foo
Definition main_demo5.c:58
#define byte
static uint32_t idx
PRINT_CONFIG_VAR(ONELOOP_ANDI_FILT_CUTOFF)
#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.
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.