3 #if HAL_RCINPUT_WITH_AP_RADIO 6 #if CONFIG_HAL_BOARD == HAL_BOARD_PX4 7 #include <board_config.h> 26 #if CONFIG_HAL_BOARD == HAL_BOARD_CHIBIOS 28 #define TIMEOUT_PRIORITY 181 29 #define EVT_TIMEOUT EVENT_MASK(0) 30 #define EVT_IRQ EVENT_MASK(1) 33 #ifndef CYRF_SPI_DEVICE 34 # define CYRF_SPI_DEVICE "cypress" 37 #ifndef CYRF_IRQ_INPUT 38 # define CYRF_IRQ_INPUT (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTD|GPIO_PIN15) 41 #ifndef CYRF_RESET_PIN 42 # define CYRF_RESET_PIN (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_EXTI|GPIO_PORTB|GPIO_PIN0) 47 #define Debug(level, fmt, args...) do { if ((level) <= get_debug_level()) { hal.console->printf(fmt, ##args); }} while (0) 49 #define LP_FIFO_SIZE 16 // Physical data FIFO lengths in Radio 54 CYRF_TX_LENGTH = 0x01,
57 CYRF_TX_IRQ_STATUS = 0x04,
60 CYRF_RX_IRQ_STATUS = 0x07,
61 CYRF_RX_STATUS = 0x08,
63 CYRF_RX_LENGTH = 0x0A,
65 CYRF_XTAL_CTRL = 0x0C,
67 CYRF_GPIO_CTRL = 0x0E,
69 CYRF_FRAMING_CFG = 0x10,
70 CYRF_DATA32_THOLD = 0x11,
71 CYRF_DATA64_THOLD = 0x12,
74 CYRF_CRC_SEED_LSB = 0x15,
75 CYRF_CRC_SEED_MSB = 0x16,
76 CYRF_TX_CRC_LSB = 0x17,
77 CYRF_TX_CRC_MSB = 0x18,
78 CYRF_RX_CRC_LSB = 0x19,
79 CYRF_RX_CRC_MSB = 0x1A,
80 CYRF_TX_OFFSET_LSB = 0x1B,
81 CYRF_TX_OFFSET_MSB = 0x1C,
82 CYRF_MODE_OVERRIDE = 0x1D,
83 CYRF_RX_OVERRIDE = 0x1E,
84 CYRF_TX_OVERRIDE = 0x1F,
85 CYRF_TX_BUFFER = 0x20,
86 CYRF_RX_BUFFER = 0x21,
88 CYRF_DATA_CODE = 0x23,
92 CYRF_CLK_OFFSET = 0x27,
95 CYRF_AUTO_CAL_TIME = 0x32,
96 CYRF_AUTO_CAL_OFFSET = 0x35,
97 CYRF_ANALOG_CTRL = 0x39,
99 #define CYRF_DIR (1<<7) 101 // CYRF_MODE_OVERRIDE 102 #define CYRF_RST (1<<0) 105 #define CYRF_RXF (1<<1) 109 CYRF_MODE_SLEEP = (0x0<<2),
110 CYRF_MODE_IDLE = (0x1<<2),
111 CYRF_MODE_SYNTH_TX = (0x2<<2),
112 CYRF_MODE_SYNTH_RX = (0x3<<2),
113 CYRF_MODE_RX = (0x4<<2),
115 #define CYRF_FRC_END (1<<5) 116 #define CYRF_ACK_EN (1<<7) 119 #define CYRF_IRQ_GPIO (1<<0) 120 #define CYRF_SPI_3PIN (1<<1) 121 #define CYRF_PACTL_GPIO (1<<2) 122 #define CYRF_PACTL_OD (1<<3) 123 #define CYRF_XOUT_OD (1<<4) 124 #define CYRF_MISO_OD (1<<5) 125 #define CYRF_IRQ_POL (1<<6) 126 #define CYRF_IRQ_OD (1<<7) 129 #define CYRF_LEN_EN (1<<5) 130 #define CYRF_SOP_LEN (1<<6) 131 #define CYRF_SOP_EN (1<<7) 135 CYRF_RX_DATA_MODE_GFSK = 0x00,
136 CYRF_RX_DATA_MODE_8DR = 0x01,
137 CYRF_RX_DATA_MODE_DDR = 0x10,
138 CYRF_RX_DATA_MODE_NV = 0x11,
140 #define CYRF_RX_CODE (1<<2) 141 #define CYRF_BAD_CRC (1<<3) 142 #define CYRF_CRC0 (1<<4) 143 #define CYRF_EOP_ERR (1<<5) 144 #define CYRF_PKT_ERR (1<<6) 145 #define CYRF_RX_ACK (1<<7) 148 #define CYRF_TXE_IRQ (1<<0) 149 #define CYRF_TXC_IRQ (1<<1) 150 #define CYRF_TXBERR_IRQ (1<<2) 151 #define CYRF_TXB0_IRQ (1<<3) 152 #define CYRF_TXB8_IRQ (1<<4) 153 #define CYRF_TXB15_IRQ (1<<5) 154 #define CYRF_LV_IRQ (1<<6) 155 #define CYRF_OS_IRQ (1<<7) 158 #define CYRF_RXE_IRQ (1<<0) 159 #define CYRF_RXC_IRQ (1<<1) 160 #define CYRF_RXBERR_IRQ (1<<2) 161 #define CYRF_RXB1_IRQ (1<<3) 162 #define CYRF_RXB8_IRQ (1<<4) 163 #define CYRF_RXB16_IRQ (1<<5) 164 #define CYRF_SOPDET_IRQ (1<<6) 165 #define CYRF_RXOW_IRQ (1<<7) 168 #define CYRF_TXE_IRQEN (1<<0) 169 #define CYRF_TXC_IRQEN (1<<1) 170 #define CYRF_TXBERR_IRQEN (1<<2) 171 #define CYRF_TXB0_IRQEN (1<<3) 172 #define CYRF_TXB8_IRQEN (1<<4) 173 #define CYRF_TXB15_IRQEN (1<<5) 174 #define CYRF_TX_CLR (1<<6) 175 #define CYRF_TX_GO (1<<7) 178 #define CYRF_RXE_IRQEN (1<<0) 179 #define CYRF_RXC_IRQEN (1<<1) 180 #define CYRF_RXBERR_IRQEN (1<<2) 181 #define CYRF_RXB1_IRQEN (1<<3) 182 #define CYRF_RXB8_IRQEN (1<<4) 183 #define CYRF_RXB16_IRQEN (1<<5) 184 #define CYRF_RSVD (1<<6) 185 #define CYRF_RX_GO (1<<7) 188 #define CYRF_ACE (1<<1) 189 #define CYRF_DIS_RXCRC (1<<2) 190 #define CYRF_DIS_CRC0 (1<<3) 191 #define CYRF_FRC_RXDR (1<<4) 192 #define CYRF_MAN_RXACK (1<<5) 193 #define CYRF_RXTX_DLY (1<<6) 194 #define CYRF_ACK_RX (1<<7) 197 #define CYRF_TX_INV (1<<0) 198 #define CYRF_DIS_TXCRC (1<<2) 199 #define CYRF_OVRD_ACK (1<<3) 200 #define CYRF_MAN_TXACK (1<<4) 201 #define CYRF_FRC_PRE (1<<6) 202 #define CYRF_ACK_TX (1<<7) 205 #define CYRF_VLD_EN (1<<0) 206 #define CYRF_RXOW_EN (1<<1) 207 #define CYRF_FAST_TURN_EN (1<<3) 208 #define CYRF_HILO (1<<4) 209 #define CYRF_ATT (1<<5) 210 #define CYRF_LNA (1<<6) 211 #define CYRF_AGC_EN (1<<7) 225 CYRF_DATA_MODE_GFSK = (0x0 <<3),
226 CYRF_DATA_MODE_8DR = (0x1 <<3),
227 CYRF_DATA_MODE_DDR = (0x2 <<3),
228 CYRF_DATA_MODE_SDR = (0x3 <<3),
230 #define CYRF_DATA_CODE_LENGTH (1<<5) 233 #define FLAG_WRITE 0x80 234 #define FLAG_AUTO_INC 0x40 236 #define DSM_MAX_CHANNEL 0x4F 238 #define DSM_SCAN_MIN_CH 8 239 #define DSM_SCAN_MID_CH 40 240 #define DSM_SCAN_MAX_CH 70 242 #define FCC_SUPPORT_CW_MODE 0 244 #define AUTOBIND_CHANNEL 12 248 #if CONFIG_HAL_BOARD == HAL_BOARD_CHIBIOS 249 thread_t *AP_Radio_cypress::_irq_handler_ctx;
267 #if CONFIG_HAL_BOARD == HAL_BOARD_CHIBIOS 269 AP_HAL::panic(
"AP_Radio_cypress: double instantiation of irq_handler\n");
273 sizeof(_irq_handler_wa),
297 #if CONFIG_HAL_BOARD == HAL_BOARD_PX4 298 stm32_configgpio(CYRF_RESET_PIN);
299 stm32_gpiowrite(CYRF_RESET_PIN, 1);
301 stm32_gpiowrite(CYRF_RESET_PIN, 0);
304 stm32_configgpio(CYRF_IRQ_INPUT);
305 #elif defined(HAL_GPIO_RADIO_RESET) 306 hal.
gpio->
write(HAL_GPIO_RADIO_RESET, 1);
308 hal.
gpio->
write(HAL_GPIO_RADIO_RESET, 0);
314 if (dsm.protocol == DSM_NONE &&
335 if (dsm.need_bind_save) {
341 return dsm.pwm_channels[
chan];
358 Debug(2,
"recv:%3u bad:%3u to:%3u re:%u N:%2u TXI:%u TX:%u 1:%4u 2:%4u 3:%4u 4:%4u 5:%4u 6:%4u 7:%4u 8:%4u 14:%u\n",
364 unsigned(dsm.send_irq_count),
365 unsigned(dsm.send_count),
366 dsm.pwm_channels[0], dsm.pwm_channels[1], dsm.pwm_channels[2], dsm.pwm_channels[3],
367 dsm.pwm_channels[4], dsm.pwm_channels[5], dsm.pwm_channels[6], dsm.pwm_channels[7],
368 dsm.pwm_channels[13]);
379 dsm.pwm_channels[chan-1] = dsm.rssi;
380 dsm.num_channels =
MAX(dsm.num_channels, chan);
386 dsm.num_channels =
MAX(dsm.num_channels, chan);
391 dsm.pwm_channels[chan-1] = dsm.tx_rssi;
392 dsm.num_channels =
MAX(dsm.num_channels, chan);
397 dsm.pwm_channels[chan-1] = dsm.tx_pps;
398 dsm.num_channels =
MAX(dsm.num_channels, chan);
401 if (now - last_debug_print_ms > 1000) {
402 last_debug_print_ms = now;
412 return dsm.num_channels;
420 Debug(4,
"check need_ack\n");
424 uint8_t data16[16] {};
426 memcpy(&data16[0], &ack_to, 4);
427 mavlink_msg_data16_send(
fwupload.chan, 42, 4, data16);
428 Debug(4,
"sent ack DATA16\n");
439 return dsm.last_parse_us;
454 {0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8},
455 {0x88, 0x17, 0x13, 0x3B, 0x2D, 0xBF, 0x06, 0xD6},
456 {0xF1, 0x94, 0x30, 0x21, 0xA1, 0x1C, 0x88, 0xA9},
457 {0xD0, 0xD2, 0x8E, 0xBC, 0x82, 0x2F, 0xE3, 0xB4},
458 {0x8C, 0xFA, 0x47, 0x9B, 0x83, 0xA5, 0x66, 0xD0},
459 {0x07, 0xBD, 0x9F, 0x26, 0xC8, 0x31, 0x0F, 0xB8},
460 {0xEF, 0x03, 0x95, 0x89, 0xB4, 0x71, 0x61, 0x9D},
461 {0x40, 0xBA, 0x97, 0xD5, 0x86, 0x4F, 0xCC, 0xD1},
462 {0xD7, 0xA1, 0x54, 0xB1, 0x5E, 0x89, 0xAE, 0x86}
465 {0x83, 0xF7, 0xA8, 0x2D, 0x7A, 0x44, 0x64, 0xD3},
466 {0x3F, 0x2C, 0x4E, 0xAA, 0x71, 0x48, 0x7A, 0xC9},
467 {0x17, 0xFF, 0x9E, 0x21, 0x36, 0x90, 0xC7, 0x82},
468 {0xBC, 0x5D, 0x9A, 0x5B, 0xEE, 0x7F, 0x42, 0xEB},
469 {0x24, 0xF5, 0xDD, 0xF8, 0x7A, 0x77, 0x74, 0xE7},
470 {0x3D, 0x70, 0x7C, 0x94, 0xDC, 0x84, 0xAD, 0x95},
471 {0x1E, 0x6A, 0xF0, 0x37, 0x52, 0x7B, 0x11, 0xD4},
472 {0x62, 0xF5, 0x2B, 0xAA, 0xFC, 0x33, 0xBF, 0xAF},
473 {0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97}
476 {0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97},
477 {0x8E, 0x4A, 0xD0, 0xA9, 0xA7, 0xFF, 0x20, 0xCA},
478 {0x4C, 0x97, 0x9D, 0xBF, 0xB8, 0x3D, 0xB5, 0xBE},
479 {0x0C, 0x5D, 0x24, 0x30, 0x9F, 0xCA, 0x6D, 0xBD},
480 {0x50, 0x14, 0x33, 0xDE, 0xF1, 0x78, 0x95, 0xAD},
481 {0x0C, 0x3C, 0xFA, 0xF9, 0xF0, 0xF2, 0x10, 0xC9},
482 {0xF4, 0xDA, 0x06, 0xDB, 0xBF, 0x4E, 0x6F, 0xB3},
483 {0x9E, 0x08, 0xD1, 0xAE, 0x59, 0x5E, 0xE8, 0xF0},
484 {0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E}
487 {0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E},
488 {0x80, 0x69, 0x26, 0x80, 0x08, 0xF8, 0x49, 0xE7},
489 {0x7D, 0x2D, 0x49, 0x54, 0xD0, 0x80, 0x40, 0xC1},
490 {0xB6, 0xF2, 0xE6, 0x1B, 0x80, 0x5A, 0x36, 0xB4},
491 {0x42, 0xAE, 0x9C, 0x1C, 0xDA, 0x67, 0x05, 0xF6},
492 {0x9B, 0x75, 0xF7, 0xE0, 0x14, 0x8D, 0xB5, 0x80},
493 {0xBF, 0x54, 0x98, 0xB9, 0xB7, 0x30, 0x5A, 0x88},
494 {0x35, 0xD1, 0xFC, 0x97, 0x23, 0xD4, 0xC9, 0x88},
495 {0x88, 0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40}
498 {0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40, 0x93},
499 {0xDC, 0x68, 0x08, 0x99, 0x97, 0xAE, 0xAF, 0x8C},
500 {0xC3, 0x0E, 0x01, 0x16, 0x0E, 0x32, 0x06, 0xBA},
501 {0xE0, 0x83, 0x01, 0xFA, 0xAB, 0x3E, 0x8F, 0xAC},
502 {0x5C, 0xD5, 0x9C, 0xB8, 0x46, 0x9C, 0x7D, 0x84},
503 {0xF1, 0xC6, 0xFE, 0x5C, 0x9D, 0xA5, 0x4F, 0xB7},
504 {0x58, 0xB5, 0xB3, 0xDD, 0x0E, 0x28, 0xF1, 0xB0},
505 {0x5F, 0x30, 0x3B, 0x56, 0x96, 0x45, 0xF4, 0xA1},
506 {0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8}
513 {CYRF_MODE_OVERRIDE, CYRF_RST},
514 {CYRF_CLK_EN, CYRF_RXF},
515 {CYRF_AUTO_CAL_TIME, 0x3C},
516 {CYRF_AUTO_CAL_OFFSET, 0x14},
517 {CYRF_RX_CFG, CYRF_LNA | CYRF_FAST_TURN_EN},
518 {CYRF_TX_OFFSET_LSB, 0x55},
519 {CYRF_TX_OFFSET_MSB, 0x05},
520 {CYRF_XACT_CFG, CYRF_MODE_SYNTH_RX | CYRF_FRC_END},
521 {CYRF_TX_CFG, CYRF_DATA_CODE_LENGTH | CYRF_DATA_MODE_SDR | CYRF_PA_4},
522 {CYRF_DATA64_THOLD, 0x0E},
523 {CYRF_XACT_CFG, CYRF_MODE_SYNTH_RX},
524 {CYRF_IO_CFG, CYRF_IRQ_POL},
528 {CYRF_TX_CFG, CYRF_DATA_CODE_LENGTH | CYRF_DATA_MODE_SDR | CYRF_PA_4},
529 {CYRF_FRAMING_CFG, CYRF_SOP_LEN | 0xE},
530 {CYRF_RX_OVERRIDE, CYRF_FRC_RXDR | CYRF_DIS_RXCRC},
531 {CYRF_EOP_CTRL, 0x02},
532 {CYRF_TX_OVERRIDE, CYRF_DIS_TXCRC},
535 {CYRF_TX_CFG, CYRF_DATA_CODE_LENGTH | CYRF_DATA_MODE_8DR | CYRF_PA_4},
536 {CYRF_FRAMING_CFG, CYRF_SOP_EN | CYRF_SOP_LEN | CYRF_LEN_EN | 0xE},
537 {CYRF_TX_OVERRIDE, 0x00},
538 {CYRF_RX_OVERRIDE, 0x00},
549 ret = read_register(adr);
552 if ((ret & (CYRF_RXC_IRQ | CYRF_RXE_IRQ)) != 0
553 && (ret & (CYRF_RXC_IRQ | CYRF_RXE_IRQ)) != (CYRF_RXC_IRQ | CYRF_RXE_IRQ)) {
568 write_register(CYRF_XACT_CFG, CYRF_FRC_END);
571 if ((read_register(CYRF_XACT_CFG) & CYRF_FRC_END) == 0) {
579 write_register(CYRF_XACT_CFG, CYRF_MODE_SLEEP);
588 if (dsm.forced_channel != -1) {
589 channel = dsm.forced_channel;
591 write_register(CYRF_CHANNEL, channel);
597 for (uint8_t i=0; i<size; i++) {
598 write_register(conf[i].reg, conf[i].
value);
607 Debug(1,
"Cypress: radio_init starting\n");
611 for (i=0; i<1000; i++) {
612 uint8_t chan = read_register(CYRF_CHANNEL);
616 write_register(CYRF_CHANNEL, 1);
620 Debug(1,
"Cypress: radio_init failed\n");
625 radio_set_config(cyrf_config,
ARRAY_SIZE(cyrf_config));
628 radio_set_config(cyrf_transfer_config,
ARRAY_SIZE(cyrf_transfer_config));
631 write_register(CYRF_RX_OVERRIDE, CYRF_DIS_RXCRC);
634 dsm_setup_transfer_dsmx();
636 write_register(CYRF_XTAL_CTRL,0x80);
637 force_initial_state();
638 write_register(CYRF_PWR_CTRL,0x20);
643 Debug(1,
"Cypress: radio_init done\n");
648 #if CONFIG_HAL_BOARD == HAL_BOARD_PX4 649 stm32_gpiosetevent(CYRF_IRQ_INPUT,
true,
false,
false, irq_radio_trampoline);
650 #elif CONFIG_HAL_BOARD == HAL_BOARD_CHIBIOS 657 for (uint8_t i=0; i<n; i++) {
658 uint8_t
v = read_register(i);
659 printf(
"%02x:%02x ", i, v);
660 if ((i+1) % 16 == 0) {
686 pkt[0] = reg | FLAG_WRITE;
687 memcpy(&pkt[1], data, n);
708 uint16_t tmp = channels[1];
709 channels[1] = 3000 - channels[2];
710 channels[2] = 3000 - tmp;
716 uint16_t tmp = channels[1];
717 channels[1] = 3000 - channels[2];
718 channels[2] = 3000 - tmp;
720 channels[0] = channels[3];
727 uint16_t tmp = channels[0];
728 channels[0] = channels[3];
745 if (dsm.tx_pps <= dsm.telem_send_count ||
753 Debug(1,
"Double-bind detected\n");
754 memset(dsm.mfg_id, 1,
sizeof(dsm.mfg_id));
755 dsm.last_recv_us = 0;
756 dsm_setup_transfer_dsmx();
764 uint16_t num_values = 0;
776 Debug(2,
"DSM: bad decode\n");
779 if (num_values < 5) {
780 Debug(2,
"DSM: num_values=%u\n", num_values);
787 memcpy(dsm.pwm_channels,
pwm_channels, num_values*
sizeof(uint16_t));
792 dsm.num_channels = num_values==8?7:num_values;
794 if (num_values == 8) {
798 d = data[14] << 8 | data[15];
801 d = data[10] << 8 | data[11];
804 uint8_t chan = d>>11;
805 uint8_t key = (d >> 8) & 0x7;
806 uint8_t v = d & 0xFF;
807 if (chan == 7 && key == 0) {
809 Debug(4,
"ack %u seq=%u acked=%u length=%u len=%u\n",
825 dsm.tx_firmware_year =
v;
828 dsm.tx_firmware_month =
v;
831 dsm.tx_firmware_day =
v;
838 dsm.have_tx_pps =
true;
842 if (v != dsm.tx_bl_version) {
848 dsm.tx_bl_version =
v;
864 bool ok = (len==16 && pkt[0] == pkt[4] && pkt[1] == pkt[5] && pkt[2] == pkt[6] && pkt[3] == pkt[7]);
867 uint16_t bind_sum = 384 - 0x10;
868 for (uint8_t i = 0; i < 8; i++) {
873 if (pkt[8] != bind_sum >> 8 || pkt[9] != (bind_sum & 0xFF)) {
878 for (uint8_t i = 8; i < 14; i++) {
883 if (pkt[14] != bind_sum >> 8 || pkt[15] != (bind_sum & 0xFF)) {
887 if (
state == STATE_AUTOBIND) {
888 uint8_t
rssi = read_register(CYRF_RSSI) & 0x1F;
889 Debug(3,
"bind RSSI %u\n", rssi);
896 uint8_t mfg_id[4] = {uint8_t(~pkt[0]), uint8_t(~pkt[1]), uint8_t(~pkt[2]), uint8_t(~pkt[3])};
897 uint8_t num_chan = pkt[11];
898 uint8_t protocol = pkt[12];
901 memcpy(dsm.mfg_id, mfg_id, 4);
904 radio_set_config(cyrf_transfer_config,
ARRAY_SIZE(cyrf_transfer_config));
907 write_register(CYRF_RX_OVERRIDE, CYRF_DIS_RXCRC);
910 dsm.protocol = (
enum dsm_protocol)protocol;
911 dsm_setup_transfer_dsmx();
913 Debug(1,
"BIND OK: mfg_id={0x%02x, 0x%02x, 0x%02x, 0x%02x} N=%u P=0x%02x DSM2=%u\n",
914 mfg_id[0], mfg_id[1], mfg_id[2], mfg_id[3],
925 dsm.need_bind_save =
true;
935 if (factory_test != 0) {
936 dsm.channels[0] = (factory_test*7) % DSM_MAX_CHANNEL;
937 dsm.channels[1] = (dsm.channels[0] + 5) % DSM_MAX_CHANNEL;
940 Debug(2,
"DSM2 start sync\n");
941 dsm.sync = DSM2_SYNC_A;
950 #if CONFIG_HAL_BOARD == HAL_BOARD_PX4 951 hrt_call_after(&wait_call, timeout_ms*1000, (hrt_callout)irq_timeout_trampoline,
nullptr);
952 #elif CONFIG_HAL_BOARD == HAL_BOARD_CHIBIOS 964 const uint8_t *
id = dsm.mfg_id;
968 ok = (pkt[0] == ((~id[2])&0xFF) && pkt[1] == (~id[3]&0xFF));
970 ok = (pkt[0] ==
id[2] && pkt[1] ==
id[3]);
972 if (ok && is_DSM2() && dsm.sync < DSM2_OK) {
973 if (dsm.sync == DSM2_SYNC_A) {
974 dsm.channels[0] = dsm.current_rf_channel;
975 dsm.sync = DSM2_SYNC_B;
976 Debug(2,
"DSM2 SYNCA chan=%u\n", dsm.channels[0]);
977 dsm.last_recv_us = now;
979 if (dsm.current_rf_channel != dsm.channels[0]) {
980 dsm.channels[1] = dsm.current_rf_channel;
982 Debug(2,
"DSM2 SYNCB chan=%u\n", dsm.channels[1]);
983 dsm.last_recv_us = now;
988 if (ok && (!is_DSM2() || dsm.sync >= DSM2_SYNC_B)) {
989 ok = parse_dsm_channels(pkt);
992 uint32_t packet_dt_us = now - dsm.last_recv_us;
994 dsm.last_recv_chan = dsm.current_channel;
995 dsm.last_recv_us = now;
996 if (dsm.crc_errors > 2) {
1003 uint8_t rssi = read_register(CYRF_RSSI) & 0x1F;
1004 dsm.rssi = 0.95 * dsm.rssi + 0.05 *
rssi;
1006 if (packet_dt_us < 5000) {
1007 dsm.pkt_time1 = packet_dt_us;
1008 }
else if (packet_dt_us < 8000) {
1009 dsm.pkt_time2 = packet_dt_us;
1013 if (packet_dt_us < 5000 &&
1026 state = STATE_SEND_TELEM;
1044 dsm_choose_channel();
1046 write_register(CYRF_RX_IRQ_STATUS, CYRF_RXOW_IRQ);
1047 write_register(CYRF_RX_CTRL, CYRF_RX_GO | CYRF_RXC_IRQEN | CYRF_RXE_IRQEN);
1050 if (
state == STATE_AUTOBIND) {
1051 dsm.receive_timeout_msec = 90;
1053 dsm.receive_timeout_msec = 15;
1055 dsm.receive_timeout_msec = 12;
1057 setup_timeout(dsm.receive_timeout_msec);
1065 if ((rx_status & (CYRF_RXC_IRQ | CYRF_RXE_IRQ)) == 0) {
1071 uint8_t rlen = read_register(CYRF_RX_COUNT);
1079 if (rx_status & CYRF_RXE_IRQ) {
1080 uint8_t reason = read_register(CYRF_RX_STATUS);
1081 if (reason & CYRF_BAD_CRC) {
1083 if (dsm.crc_errors > 20) {
1084 Debug(2,
"Flip CRC\n");
1086 dsm.crc_seed = ~dsm.crc_seed;
1090 write_register(CYRF_XACT_CFG, CYRF_MODE_SYNTH_RX | CYRF_FRC_END);
1091 write_register(CYRF_RX_ABORT, 0);
1093 }
else if (rx_status & CYRF_RXC_IRQ) {
1094 if (
state == STATE_RECV) {
1095 process_packet(pkt, rlen);
1097 process_bind(pkt, rlen);
1101 if (
state == STATE_AUTOBIND) {
1105 if (
state != STATE_SEND_TELEM) {
1116 if ((tx_status & (CYRF_TXC_IRQ | CYRF_TXE_IRQ)) == 0) {
1136 uint8_t rx_status = read_status_debounced(CYRF_RX_IRQ_STATUS);
1137 uint8_t tx_status = read_status_debounced(CYRF_TX_IRQ_STATUS);
1140 case STATE_AUTOBIND:
1144 irq_handler_recv(rx_status);
1147 case STATE_SEND_TELEM:
1148 case STATE_SEND_TELEM_WAIT:
1149 irq_handler_send(tx_status);
1152 case STATE_SEND_FCC:
1154 write_register(CYRF_RX_IRQ_STATUS, CYRF_RXOW_IRQ);
1155 write_register(CYRF_RX_CTRL, CYRF_RX_GO | CYRF_RXC_IRQEN | CYRF_RXE_IRQEN);
1172 setup_timeout(dsm.receive_timeout_msec);
1177 Debug(3,
"Starting FCC test\n");
1178 state = STATE_SEND_FCC;
1180 Debug(3,
"Ending FCC test\n");
1185 case STATE_SEND_TELEM:
1186 send_telem_packet();
1188 case STATE_SEND_FCC:
1189 send_FCC_test_packet();
1191 case STATE_AUTOBIND:
1192 case STATE_SEND_TELEM_WAIT:
1196 write_register(CYRF_XACT_CFG, CYRF_MODE_SYNTH_RX | CYRF_FRC_END);
1197 write_register(CYRF_RX_ABORT, 0);
1209 #if CONFIG_HAL_BOARD == HAL_BOARD_PX4 1220 #if CONFIG_HAL_BOARD == HAL_BOARD_PX4 1226 #elif CONFIG_HAL_BOARD == HAL_BOARD_CHIBIOS 1227 void AP_Radio_cypress::irq_handler_thd(
void *arg)
1232 eventmask_t evt = chEvtWaitAny(ALL_EVENTS);
1233 if (evt & EVT_IRQ) {
1236 if (evt & EVT_TIMEOUT) {
1242 void AP_Radio_cypress::trigger_timeout_event(
void *arg)
1250 chSysUnlockFromISR();
1253 void AP_Radio_cypress::trigger_irq_radio_event()
1260 chSysUnlockFromISR();
1271 pn_row = is_dsm2? channel % 5 : (channel-2) % 5;
1274 write_register(CYRF_CRC_SEED_LSB, crc_seed & 0xff);
1275 write_register(CYRF_CRC_SEED_MSB, crc_seed >> 8);
1278 if (memcmp(dsm.last_sop_code, pn_codes[pn_row][sop_col], 8) != 0) {
1279 write_multiple(CYRF_SOP_CODE, 8, pn_codes[pn_row][sop_col]);
1280 memcpy(dsm.last_sop_code, pn_codes[pn_row][sop_col], 8);
1284 if (memcmp(dsm.last_data_code, pn_codes[pn_row][data_col], 16) != 0) {
1285 write_multiple(CYRF_DATA_CODE, 16, pn_codes[pn_row][data_col]);
1286 memcpy(dsm.last_data_code, pn_codes[pn_row][data_col], 16);
1291 Debug(3,
"Cypress: DISCRC=%u\n", dsm.last_discrc);
1292 write_register(CYRF_RX_OVERRIDE, dsm.last_discrc?CYRF_DIS_RXCRC:0);
1297 Debug(3,
"Cypress: TXPOWER=%u\n", dsm.last_transmit_power);
1298 write_register(CYRF_TX_CFG, CYRF_DATA_CODE_LENGTH | CYRF_DATA_MODE_8DR | dsm.last_transmit_power);
1302 set_channel(channel);
1312 uint32_t
id = ~((mfg_id[0] << 24) | (mfg_id[1] << 16) |
1313 (mfg_id[2] << 8) | (mfg_id[3] << 0));
1314 uint32_t id_tmp = id;
1319 int count_3_27 = 0, count_28_51 = 0, count_52_76 = 0;
1321 id_tmp = id_tmp * 0x0019660D + 0x3C6EF35F;
1322 uint8_t next_ch = ((id_tmp >> 8) % 0x49) + 3;
1323 if (((next_ch ^
id) & 0x01 ) == 0) {
1328 for (i = 0; i < idx; i++) {
1330 if (channels[i] == next_ch) {
1335 if(channels[i] <= 27) {
1337 }
else if (channels[i] <= 51) {
1350 if ((next_ch < 28 && count_3_27 < 8)
1351 || (next_ch >= 28 && next_ch < 52 && count_28_51 < 7)
1352 || (next_ch >= 52 && count_52_76 < 8)) {
1353 channels[idx++] = next_ch;
1357 Debug(2,
"Generated DSMX channels\n");
1365 dsm.current_channel = 0;
1367 dsm.crc_seed = ~((dsm.mfg_id[0] << 8) + dsm.mfg_id[1]);
1368 dsm.sop_col = (dsm.mfg_id[0] + dsm.mfg_id[1] + dsm.mfg_id[2] + 2) & 0x07;
1369 dsm.data_col = 7 - dsm.sop_col;
1371 dsm_generate_channels_dsmx(dsm.mfg_id, dsm.channels);
1380 uint32_t dt = now - dsm.last_recv_us;
1381 const uint32_t cycle_time = dsm.pkt_time1 + dsm.pkt_time2;
1382 uint8_t next_channel;
1386 if (now - dsm.last_chan_change_us > 15000) {
1388 dsm.current_rf_channel |= 1;
1389 dsm.current_rf_channel = (dsm.current_rf_channel+2) % DSM_MAX_CHANNEL;
1390 dsm.last_chan_change_us = now;
1392 set_channel(dsm.current_rf_channel);
1397 dsm.last_recv_us == 0 &&
1398 now - dsm.last_autobind_send > 300*1000UL &&
1401 state == STATE_RECV) {
1403 dsm_set_channel(AUTOBIND_CHANNEL,
true, 0, 0, 0);
1405 state = STATE_AUTOBIND;
1407 Debug(3,
"recv autobind %u\n",
unsigned(now - dsm.last_autobind_send));
1408 dsm.last_autobind_send = now;
1412 if (is_DSM2() && dsm.sync == DSM2_SYNC_A) {
1413 if (now - dsm.last_chan_change_us > 15000) {
1415 dsm.current_rf_channel &= ~1;
1416 dsm.current_rf_channel = (dsm.current_rf_channel+2) % DSM_MAX_CHANNEL;
1417 dsm.last_chan_change_us = now;
1420 dsm_set_channel(dsm.current_rf_channel, is_DSM2(),
1421 dsm.sop_col, dsm.data_col,
1422 dsm.sync==DSM2_SYNC_B?~dsm.crc_seed:dsm.crc_seed);
1428 next_channel = dsm.last_recv_chan + 1;
1429 }
else if (dt > 20*cycle_time) {
1431 next_channel = dsm.last_recv_chan + (dt / (cycle_time*2));
1434 next_channel = dsm.last_recv_chan + 1;
1435 next_channel += (dt / cycle_time) * 2;
1436 if (dt % cycle_time > (
unsigned)(dsm.pkt_time1 + 1000U)) {
1442 dsm.current_channel = next_channel;
1443 if (dsm.current_channel >= chan_count) {
1446 dsm.crc_seed = ~dsm.crc_seed;
1450 if (is_DSM2() && dsm.sync == DSM2_SYNC_B && dsm.current_channel == 1) {
1453 dsm.channels[1] &= ~1;
1454 dsm.channels[1] = (dsm.channels[1]+2) % DSM_MAX_CHANNEL;
1455 }
while (dsm.channels[1] == dsm.channels[0]);
1458 dsm.current_rf_channel = dsm.channels[dsm.current_channel];
1460 uint16_t seed = dsm.crc_seed;
1461 if (dsm.current_channel & 1) {
1466 if (now - dsm.last_recv_us > 5000000) {
1471 dsm_set_channel(dsm.current_rf_channel, is_DSM2(),
1472 dsm.sop_col, dsm.data_col, seed);
1485 Debug(1,
"Cypress: start_recv_bind\n");
1487 write_register(CYRF_XACT_CFG, CYRF_MODE_SYNTH_RX | CYRF_FRC_END);
1488 write_register(CYRF_RX_ABORT, 0);
1492 radio_set_config(cyrf_bind_config,
ARRAY_SIZE(cyrf_bind_config));
1494 write_register(CYRF_CRC_SEED_LSB, 0);
1495 write_register(CYRF_CRC_SEED_MSB, 0);
1497 write_multiple(CYRF_SOP_CODE, 8, pn_codes[0][0]);
1499 uint8_t data_code[16];
1500 memcpy(data_code, pn_codes[0][8], 8);
1501 memcpy(&data_code[8], pn_bind, 8);
1502 write_multiple(CYRF_DATA_CODE, 16, data_code);
1504 dsm.current_rf_channel = 1;
1518 struct bind_info info;
1521 memcpy(info.mfg_id, dsm.mfg_id,
sizeof(info.mfg_id));
1522 info.protocol = dsm.protocol;
1524 if (bind_storage.write_block(0, &info,
sizeof(info))) {
1525 dsm.need_bind_save =
false;
1536 struct bind_info info;
1540 if (factory_test != 0) {
1541 Debug(1,
"In factory test %u\n", factory_test);
1542 memset(dsm.mfg_id, 0,
sizeof(dsm.mfg_id));
1543 dsm.mfg_id[0] = factory_test;
1544 dsm.protocol = DSM_DSM2_2;
1546 }
else if (bind_storage.read_block(&info, 0,
sizeof(info)) && info.magic ==
bind_magic) {
1547 Debug(1,
"Loaded mfg_id %02x:%02x:%02x:%02x\n",
1548 info.mfg_id[0], info.mfg_id[1], info.mfg_id[2], info.mfg_id[3]);
1549 memcpy(dsm.mfg_id, info.mfg_id,
sizeof(info.mfg_id));
1550 dsm.protocol = info.protocol;
1559 return dsm.protocol == DSM_DSM2_1 || dsm.protocol == DSM_DSM2_2;
1568 write_register(CYRF_TX_LENGTH, 16);
1569 write_register(CYRF_TX_CTRL, CYRF_TX_CLR);
1571 write_multiple(CYRF_TX_BUFFER, 16, data);
1572 write_register(CYRF_TX_CTRL, CYRF_TX_GO | CYRF_TXC_IRQEN);
1598 ((
fwupload.counter++ & 0x07) != 0) &&
1601 pkt.payload.fw.seq =
fwupload.sequence;
1603 pkt.payload.fw.len = len<=8?
len:8;
1605 memcpy(&pkt.payload.fw.data[0], &
fwupload.pending_data[
fwupload.acked], pkt.payload.fw.len);
1607 Debug(4,
"sent fw seq=%u offset=%u len=%u type=%u\n",
1609 pkt.payload.fw.offset,
1613 pkt.crc =
crc_crc8((
const uint8_t *)&pkt.type, 15);
1617 pkt.crc =
crc_crc8((
const uint8_t *)&pkt.type, 15);
1618 dsm.telem_send_count++;
1621 write_register(CYRF_XACT_CFG, CYRF_MODE_SYNTH_TX | CYRF_FRC_END);
1622 write_register(CYRF_RX_ABORT, 0);
1623 transmit16((uint8_t*)&pkt);
1625 state = STATE_SEND_TELEM_WAIT;
1634 uint8_t pkt[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
1636 state = STATE_SEND_FCC;
1643 dsm.forced_channel = -1;
1644 send_telem_packet();
1648 channel = DSM_SCAN_MIN_CH;
1652 channel = DSM_SCAN_MID_CH;
1657 channel = DSM_SCAN_MAX_CH;
1661 Debug(5,
"FCC send %u\n", channel);
1663 if (channel != dsm.forced_channel) {
1664 Debug(1,
"FCC channel %u\n", channel);
1665 dsm.forced_channel = channel;
1667 radio_set_config(cyrf_config,
ARRAY_SIZE(cyrf_config));
1668 radio_set_config(cyrf_transfer_config,
ARRAY_SIZE(cyrf_transfer_config));
1670 set_channel(channel);
1673 #if FCC_SUPPORT_CW_MODE 1677 write_register(CYRF_PREAMBLE,0x01);
1678 write_register(CYRF_PREAMBLE,0x00);
1679 write_register(CYRF_PREAMBLE,0x00);
1681 write_register(CYRF_TX_OVERRIDE, CYRF_FRC_PRE);
1682 write_register(CYRF_TX_CTRL, CYRF_TX_GO);
1686 write_register(CYRF_XACT_CFG, CYRF_MODE_SYNTH_TX | CYRF_FRC_END);
1687 write_register(CYRF_RX_ABORT, 0);
1692 write_register(CYRF_XACT_CFG, CYRF_MODE_SYNTH_TX | CYRF_FRC_END);
1693 write_register(CYRF_RX_ABORT, 0);
1703 memcpy(&ofs, &m.data[0], 4);
1704 Debug(4,
"got data96 of len %u from chan %u at offset %u\n", m.len, chan,
unsigned(ofs));
1727 #endif // HAL_RCINPUT_WITH_AP_RADIO void dsm_set_channel(uint8_t channel, bool is_dsm2, uint8_t sop_col, uint8_t data_col, uint16_t crc_seed)
int printf(const char *fmt,...)
bool get_soft_armed() const
static thread_t * _irq_handler_ctx
void start_recv_bind(void) override
uint8_t get_tx_rssi_chan(void) const
void send_telem_packet(void)
static void trigger_timeout_event(void *arg)
#define TELEM_FLAG_POS_OK
uint8_t get_debug_level(void) const
uint16_t pwm_channels[CC2500_MAX_CHANNELS]
uint8_t get_rssi_chan(void) const
void save_bind_info(void)
void send_FCC_test_packet(void)
bool send(const uint8_t *pkt, uint16_t len) override
AP_HAL::OwnPtr< AP_HAL::SPIDevice > dev
void write_multiple(uint8_t reg, uint8_t n, const uint8_t *data)
AP_Radio::stats last_stats
uint8_t get_factory_test(void) const
uint8_t crc_crc8(const uint8_t *p, uint8_t len)
#define HAL_SEMAPHORE_BLOCK_FOREVER
void save_bind_info(void)
virtual bool take(uint32_t timeout_ms) WARN_IF_UNUSED=0
uint8_t num_channels(void) override
AP_Radio_cypress(AP_Radio &radio)
virtual Semaphore * new_semaphore(void)
void dsm_setup_transfer_dsmx(void)
static AP_Radio_cypress * radio_instance
uint8_t read_register(uint8_t reg)
static uint16_t channels[SRXL_MAX_CHANNELS]
virtual void write(uint8_t pin, uint8_t value)=0
void set_channel(uint8_t channel)
static auto MAX(const A &one, const B &two) -> decltype(one > two ? one :two)
void handle_data_packet(mavlink_channel_t chan, const mavlink_data96_t &m) override
struct telem_status t_status
bool get_telem_enable(void) const
static const uint8_t pn_bind[]
void start_recv_bind(void) override
virtual void delay(uint16_t ms)=0
bool parse_dsm_channels(const uint8_t *data)
virtual bool attach_interrupt(uint8_t interrupt_num, AP_HAL::Proc p, uint8_t mode)=0
static const uint8_t pn_codes[5][9][8]
void transmit16(const uint8_t data[16])
virtual bool take_nonblocking() WARN_IF_UNUSED=0
bool reset(void) override
uint8_t get_autobind_rssi(void) const
virtual OwnPtr< SPIDevice > get_device(const char *name)
void irq_handler_send(uint8_t tx_status)
static const config cyrf_transfer_config[]
void process_bind(const uint8_t *pkt, uint8_t len)
void check_double_bind(void)
virtual Semaphore * get_semaphore() override=0
uint8_t num_channels(void) override
static const config cyrf_bind_config[]
#define Debug(fmt, args ...)
void radio_set_config(const struct config *config, uint8_t size)
int8_t get_fcc_test(void) const
uint16_t read(uint8_t chan) override
static const config cyrf_config[]
bool get_disable_crc(void) const
#define HAL_GPIO_INTERRUPT_RISING
void set_tx_max_power_default(uint8_t v)
uint8_t get_stick_mode(void) const
uint32_t failsafe_battery
bool dsm_decode(uint64_t frame_time, const uint8_t dsm_frame[16], uint16_t *values, uint16_t *num_values, uint16_t max_values)
virtual bool set_chip_select(bool set)
void print_debug_info(void)
AP_HAL::SPIDeviceManager * spi
#define TELEM_FLAG_ARM_OK
#define TELEM_FLAG_BATT_OK
void dsm_choose_channel(void)
static virtual_timer_t timeout_vt
static void trigger_irq_radio_event(void)
void update(void) override
static AP_Radio_cc2500 * radio_instance
uint8_t get_tx_buzzer_adjust(void) const
void process_packet(const uint8_t *pkt, uint8_t len)
void setup_timeout(uint32_t timeout_ms)
virtual bool transfer(const uint8_t *send, uint32_t send_len, uint8_t *recv, uint32_t recv_len) override=0
void load_bind_info(void)
static struct notify_flags_and_values_type flags
uint8_t get_transmit_power(void) const
void write_register(uint8_t reg, uint8_t value)
void force_initial_state(void)
uint8_t get_autobind_time(void) const
void dsm_generate_channels_dsmx(uint8_t mfg_id[4], uint8_t channels[23])
uint8_t get_tx_pps_chan(void) const
uint8_t get_tx_max_power(void) const
bool read_registers(uint8_t first_reg, uint8_t *recv, uint32_t recv_len)
uint8_t read_status_debounced(uint8_t adr)
bool read(uint8_t *recv, uint32_t recv_len)
#define TELEM_FLAG_GPS_OK
struct AP_Radio_cc2500::@168 fwupload
static int irq_timeout_trampoline(int irq, void *context)
void panic(const char *errormsg,...) FMT_PRINTF(1
void dsm2_start_sync(void)
static int irq_radio_trampoline(int irq, void *context)
uint8_t get_pps_chan(void) const
bool reset(void) override
void dump_registers(uint8_t n)
bool load_bind_info(void)
uint32_t last_recv_us(void) override
THD_WORKING_AREA(_timer_thread_wa, 2048)
bool write_register(uint8_t reg, uint8_t val, bool checked=false)
const AP_Radio::stats & get_stats(void) override
static void irq_handler_thd(void *arg)
void map_stick_mode(uint16_t *channels)
void irq_handler_recv(uint8_t rx_status)
AP_HAL::Scheduler * scheduler
AP_Radio::ap_radio_protocol get_protocol(void) const
static const uint16_t bind_magic