123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- #include "AP_RCProtocol_SRXL.h"
- #include <AP_Math/crc.h>
- #include <AP_Math/AP_Math.h>
- extern const AP_HAL::HAL& hal;
- void AP_RCProtocol_SRXL::process_pulse(uint32_t width_s0, uint32_t width_s1)
- {
- uint8_t b;
- if (ss.process_pulse(width_s0, width_s1, b)) {
- _process_byte(ss.get_byte_timestamp_us(), b);
- }
- }
- int AP_RCProtocol_SRXL::srxl_channels_get_v1v2(uint16_t max_values, uint8_t *num_values, uint16_t *values, bool *failsafe_state)
- {
- uint8_t loop;
- uint32_t channel_raw_value;
- *num_values = (uint8_t)((frame_len_full - 3U)/2U);
- *failsafe_state = 0U;
-
- for (loop=0U; loop < *num_values; loop++) {
- channel_raw_value = ((((uint32_t)buffer[loop*2U+1U])& 0x0000000FU) << 8U) | ((uint32_t)(buffer[loop*2U+2U]));
- channels[loop] = (uint16_t)(((channel_raw_value * (uint32_t)1400U) >> 12U) + (uint32_t)800U);
- }
-
- if ((uint16_t)*num_values > max_values) {
- *num_values = (uint8_t)max_values;
- }
- memcpy(values, channels, (*num_values)*2);
- return 0;
- }
- int AP_RCProtocol_SRXL::srxl_channels_get_v5(uint16_t max_values, uint8_t *num_values, uint16_t *values, bool *failsafe_state)
- {
-
-
-
- for (uint8_t i=0; i<7; i++) {
- uint16_t b = buffer[i*2+2] << 8 | buffer[i*2+3];
- uint16_t c = b >> 11;
- int32_t v = b & 0x7FF;
- if (b & 0x8000) {
- continue;
- }
- if (c == 12) {
-
-
-
- v = (b & 0x1FF) << 2;
- c = 10 + ((b >> 9) & 0x7);
- if (buffer[1] & 1) {
- c += 4;
- }
- } else if (c > 12) {
-
- v = 0;
- }
-
-
-
-
- if (c < SRXL_MAX_CHANNELS) {
- v = (((v - 0x400) * 500) / 876) + 1500;
- channels[c] = v;
- if (c >= max_channels) {
- max_channels = c+1;
- }
- }
-
- }
-
- *num_values = max_channels;
- if (*num_values > max_values) {
- *num_values = max_values;
- }
- memcpy(values, channels, (*num_values)*2);
-
-
- *failsafe_state = ((buffer[1] & 2) == 0);
-
- return 0;
- }
- void AP_RCProtocol_SRXL::_process_byte(uint32_t timestamp_us, uint8_t byte)
- {
-
-
- if ((timestamp_us - last_data_us) >= SRXL_MIN_FRAMESPACE_US) {
-
- switch (byte) {
- case SRXL_HEADER_V1:
- frame_len_full = SRXL_FRAMELEN_V1;
- frame_header = SRXL_HEADER_V1;
- decode_state = STATE_NEW;
- break;
- case SRXL_HEADER_V2:
- frame_len_full = SRXL_FRAMELEN_V2;
- frame_header = SRXL_HEADER_V2;
- decode_state = STATE_NEW;
- break;
- case SRXL_HEADER_V5:
- frame_len_full = SRXL_FRAMELEN_V5;
- frame_header = SRXL_HEADER_V5;
- decode_state = STATE_NEW;
- break;
- default:
- frame_len_full = 0U;
- frame_header = SRXL_HEADER_NOT_IMPL;
- decode_state = STATE_IDLE;
- buflen = 0;
- return;
- }
- }
-
- switch (decode_state) {
- case STATE_NEW:
- buffer[0U]=byte;
- crc_fmu = crc_xmodem_update(0U,byte);
- buflen = 1U;
- decode_state_next = STATE_COLLECT;
- break;
- case STATE_COLLECT:
- if (buflen >= frame_len_full) {
-
- decode_state = STATE_IDLE;
- buflen = 0;
- frame_len_full = 0;
- frame_header = SRXL_HEADER_NOT_IMPL;
- return;
- }
- buffer[buflen] = byte;
- buflen++;
-
- if (buflen <= (frame_len_full-2)) {
- crc_fmu = crc_xmodem_update(crc_fmu,byte);
- }
- if (buflen == frame_len_full) {
-
- crc_receiver = ((uint16_t)buffer[buflen-2] << 8U) | ((uint16_t)buffer[buflen-1]);
- if (crc_receiver == crc_fmu) {
-
- const uint8_t max_values = MIN((unsigned)SRXL_MAX_CHANNELS,(unsigned)MAX_RCIN_CHANNELS);
- uint16_t values[max_values];
- uint8_t num_values;
- bool failsafe_state;
- switch (frame_header) {
- case SRXL_HEADER_V1:
- srxl_channels_get_v1v2(max_values, &num_values, values, &failsafe_state);
- add_input(num_values, values, failsafe_state);
- break;
- case SRXL_HEADER_V2:
- srxl_channels_get_v1v2(max_values, &num_values, values, &failsafe_state);
- add_input(num_values, values, failsafe_state);
- break;
- case SRXL_HEADER_V5:
- srxl_channels_get_v5(max_values, &num_values, values, &failsafe_state);
- add_input(num_values, values, failsafe_state);
- break;
- default:
- break;
- }
- }
- decode_state_next = STATE_IDLE;
- } else {
-
- decode_state_next = STATE_COLLECT;
- }
- break;
- default:
- break;
- }
- decode_state = decode_state_next;
- last_data_us = timestamp_us;
- }
- void AP_RCProtocol_SRXL::process_byte(uint8_t byte, uint32_t baudrate)
- {
- if (baudrate != 115200) {
- return;
- }
- _process_byte(AP_HAL::micros(), byte);
- }
|