LCOV - code coverage report
Current view: top level - AP_RCProtocol - AP_RCProtocol_SUMD.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 0 60 0.0 %
Date: 2026-09-09 11:02:08 Functions: 0 3 0.0 %

          Line data    Source code
       1             : /*
       2             :   SUMD decoder, based on PX4Firmware/src/rc/lib/rc/sumd.c from PX4Firmware
       3             :   modified for use in AP_HAL_* by Andrew Tridgell
       4             :  */
       5             : /****************************************************************************
       6             :  *
       7             :  *   Copyright (c) 2015 PX4 Development Team. All rights reserved.
       8             :  *
       9             :  * Redistribution and use in source and binary forms, with or without
      10             :  * modification, are permitted provided that the following conditions
      11             :  * are met:
      12             :  *
      13             :  * 1. Redistributions of source code must retain the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer.
      15             :  * 2. Redistributions in binary form must reproduce the above copyright
      16             :  *    notice, this list of conditions and the following disclaimer in
      17             :  *    the documentation and/or other materials provided with the
      18             :  *    distribution.
      19             :  * 3. Neither the name PX4 nor the names of its contributors may be
      20             :  *    used to endorse or promote products derived from this software
      21             :  *    without specific prior written permission.
      22             :  *
      23             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      24             :  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      25             :  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
      26             :  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
      27             :  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
      28             :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
      29             :  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
      30             :  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
      31             :  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      32             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
      33             :  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      34             :  * POSSIBILITY OF SUCH DAMAGE.
      35             :  *
      36             :  ****************************************************************************/
      37             : 
      38             : /*
      39             :  * @file sumd.h
      40             :  *
      41             :  * RC protocol definition for Graupner HoTT transmitter (SUMD/SUMH Protocol)
      42             :  *
      43             :  * @author Marco Bauer <[email protected]>
      44             :  */
      45             : #include "AP_RCProtocol_config.h"
      46             : 
      47             : #if AP_RCPROTOCOL_SUMD_ENABLED
      48             : 
      49             : #include "AP_RCProtocol_SUMD.h"
      50             : 
      51             : #include <AP_Math/crc.h>
      52             : 
      53             : #define SUMD_HEADER_LENGTH      3
      54             : #define SUMD_HEADER_ID          0xA8
      55             : #define SUMD_ID_SUMH            0x00
      56             : #define SUMD_ID_SUMD            0x01
      57             : #define SUMD_ID_FAILSAFE        0x81
      58             : 
      59             : // #define SUMD_DEBUG
      60             : extern const AP_HAL::HAL& hal;
      61             : 
      62           0 : void AP_RCProtocol_SUMD::process_pulse(uint32_t width_s0, uint32_t width_s1)
      63             : {
      64             :     uint8_t b;
      65           0 :     if (ss.process_pulse(width_s0, width_s1, b)) {
      66           0 :         _process_byte(ss.get_byte_timestamp_us(), b);
      67             :     }
      68           0 : }
      69             : 
      70           0 : void AP_RCProtocol_SUMD::_process_byte(uint32_t timestamp_us, uint8_t byte)
      71             : {
      72           0 :     if (timestamp_us - last_packet_us > 5000U) {
      73           0 :         _decode_state = SUMD_DECODE_STATE_UNSYNCED;
      74             :     }
      75           0 :     switch (_decode_state) {
      76           0 :     case SUMD_DECODE_STATE_UNSYNCED:
      77             : #ifdef SUMD_DEBUG
      78             :         hal.console->printf(" SUMD_DECODE_STATE_UNSYNCED \n") ;
      79             : #endif
      80           0 :         if (byte == SUMD_HEADER_ID) {
      81           0 :             _rxlen = 0;
      82           0 :             _crc16 = crc_xmodem_update(0, byte);
      83           0 :             _decode_state = SUMD_DECODE_STATE_GOT_HEADER;
      84             : 
      85             : #ifdef SUMD_DEBUG
      86             :             hal.console->printf(" SUMD_DECODE_STATE_GOT_HEADER: %x \n", byte) ;
      87             : #endif
      88           0 :             last_packet_us = timestamp_us;
      89             :         }
      90           0 :         break;
      91             : 
      92           0 :     case SUMD_DECODE_STATE_GOT_HEADER:
      93           0 :         if ((byte == SUMD_ID_SUMD) || (byte == SUMD_ID_FAILSAFE)) {
      94           0 :             _rxpacket.status = byte;
      95           0 :             _crc16 = crc_xmodem_update(_crc16, byte);
      96           0 :             _decode_state = SUMD_DECODE_STATE_GOT_STATE;
      97             : #ifdef SUMD_DEBUG
      98             :             hal.console->printf(" SUMD_DECODE_STATE_GOT_STATE: %x \n", byte) ;
      99             : #endif
     100             :         } else {
     101           0 :             _decode_state = SUMD_DECODE_STATE_UNSYNCED;
     102             :         }
     103             : 
     104           0 :         break;
     105             : 
     106           0 :     case SUMD_DECODE_STATE_GOT_STATE:
     107           0 :         if (byte >= 4 && byte <= SUMD_MAX_CHANNELS) { // need at least 4 for reordering
     108           0 :             _rxpacket.length = byte;
     109           0 :             _crc16 = crc_xmodem_update(_crc16, byte);
     110           0 :             _rxlen++;
     111           0 :             _decode_state = SUMD_DECODE_STATE_GOT_LEN;
     112             : 
     113             : #ifdef SUMD_DEBUG
     114             :             hal.console->printf(" SUMD_DECODE_STATE_GOT_LEN: %x (%d) \n", byte, byte) ;
     115             : #endif
     116             :         } else {
     117           0 :             _decode_state = SUMD_DECODE_STATE_UNSYNCED;
     118             :         }
     119             : 
     120           0 :         break;
     121             : 
     122           0 :     case SUMD_DECODE_STATE_GOT_LEN:
     123           0 :         _rxpacket.sumd_data[_rxlen] = byte;
     124           0 :         _crc16 = crc_xmodem_update(_crc16, byte);
     125           0 :         _rxlen++;
     126           0 :         if (_rxlen <= ((_rxpacket.length * 2))) {
     127             : #ifdef SUMD_DEBUG
     128             :             hal.console->printf(" SUMD_DECODE_STATE_GOT_DATA[%d]: %x\n", _rxlen - 2, byte) ;
     129             : #endif
     130             :         } else {
     131           0 :             _decode_state = SUMD_DECODE_STATE_GOT_DATA;
     132             : #ifdef SUMD_DEBUG
     133             :             hal.console->printf(" SUMD_DECODE_STATE_GOT_DATA -- finish --\n") ;
     134             : #endif
     135             :         }
     136             : 
     137           0 :         break;
     138             : 
     139           0 :     case SUMD_DECODE_STATE_GOT_DATA:
     140           0 :         _rxpacket.crc16_high = byte;
     141           0 :         _decode_state = SUMD_DECODE_STATE_GOT_CRC;
     142             : #ifdef SUMD_DEBUG
     143             :         hal.console->printf(" SUMD_DECODE_STATE_GOT_CRC16[1]: %x   [%x]\n", byte, ((_crc16 >> 8) & 0xff)) ;
     144             : #endif
     145           0 :         break;
     146             : 
     147           0 :     case SUMD_DECODE_STATE_GOT_CRC:
     148             : #ifdef SUMD_DEBUG
     149             :         hal.console->printf(" SUMD_DECODE_STATE_GOT_CRC[2]: %x   [%x]\n\n", byte, (_crc16 & 0xff)) ;
     150             : #endif
     151             : 
     152           0 :         log_data(AP_RCProtocol::SUMD, timestamp_us, _rxpacket.sumd_data, _rxlen);
     153             : 
     154           0 :         if (_crc16 == (uint16_t)(_rxpacket.crc16_high << 8) + byte) {
     155             : #ifdef SUMD_DEBUG
     156             :             hal.console->printf(" CRC - OK \n") ;
     157             :             hal.console->printf(" Got valid SUMD Packet\n") ;
     158             :             hal.console->printf(" RXLEN: %d  [Chans: %d] \n\n", _rxlen - 1, (_rxlen - 1) / 2) ;
     159             : #endif
     160             : 
     161             :             uint16_t values[SUMD_MAX_CHANNELS];
     162             : 
     163             :             /* received Channels */
     164           0 :             if ((uint16_t)_rxpacket.length > SUMD_MAX_CHANNELS) {
     165           0 :                 _rxpacket.length = (uint8_t) SUMD_MAX_CHANNELS;
     166             :             }
     167             : 
     168             :             /* decode the actual packet */
     169             :             /* reorder first 4 channels */
     170             : 
     171             :             /* ch1 = roll -> sumd = ch2 */
     172           0 :             values[0] = (uint16_t)((_rxpacket.sumd_data[1 * 2 + 1] << 8) | _rxpacket.sumd_data[1 * 2 + 2]) >> 3;
     173             :             /* ch2 = pitch -> sumd = ch2 */
     174           0 :             values[1] = (uint16_t)((_rxpacket.sumd_data[2 * 2 + 1] << 8) | _rxpacket.sumd_data[2 * 2 + 2]) >> 3;
     175             :             /* ch3 = throttle -> sumd = ch2 */
     176           0 :             values[2] = (uint16_t)((_rxpacket.sumd_data[0 * 2 + 1] << 8) | _rxpacket.sumd_data[0 * 2 + 2]) >> 3;
     177             :             /* ch4 = yaw -> sumd = ch2 */
     178           0 :             values[3] = (uint16_t)((_rxpacket.sumd_data[3 * 2 + 1] << 8) | _rxpacket.sumd_data[3 * 2 + 2]) >> 3;
     179             : 
     180             :             /* we start at channel 5(index 4) */
     181           0 :             for (uint8_t i = 4; i < _rxpacket.length; i++) {
     182             : #ifdef SUMD_DEBUG
     183             :                 hal.console->printf("ch[%u] : %x %x [ %x    %d ]\n", i + 1, _rxpacket.sumd_data[i * 2 + 1], _rxpacket.sumd_data[i * 2 + 2],
     184             :                                     ((_rxpacket.sumd_data[i * 2 + 1] << 8) | _rxpacket.sumd_data[i * 2 + 2]) >> 3,
     185             :                                     ((_rxpacket.sumd_data[i * 2 + 1] << 8) | _rxpacket.sumd_data[i * 2 + 2]) >> 3);
     186             : #endif
     187             : 
     188           0 :                 values[i] = (uint16_t)((_rxpacket.sumd_data[i * 2 + 1] << 8) | _rxpacket.sumd_data[i * 2 + 2]) >> 3;
     189             :             }
     190           0 :             add_input(_rxpacket.length, values, (_rxpacket.status == SUMD_ID_FAILSAFE));
     191             : #ifdef SUMD_DEBUG
     192             :         } else {
     193             :             hal.console->printf(" CRC - fail 0x%X 0x%X\n", _crc16, (uint16_t)(_rxpacket.crc16_high << 8) + byte);
     194             : #endif
     195             :         }
     196             : 
     197           0 :         _decode_state = SUMD_DECODE_STATE_UNSYNCED;
     198           0 :         break;
     199             :     }
     200           0 : }
     201             : 
     202           0 : void AP_RCProtocol_SUMD::process_byte(uint8_t byte, uint32_t baudrate)
     203             : {
     204           0 :     if (baudrate != 115200) {
     205           0 :         return;
     206             :     }
     207           0 :     _process_byte(AP_HAL::micros(), byte);
     208             : }
     209             : 
     210             : #endif  // AP_RCPROTOCOL_SUMD_ENABLED

Generated by: LCOV version 1.14