.. _program_listing_file_src_tap_communication_serial_dji_serial.hpp: Program Listing for File dji_serial.hpp ======================================= |exhale_lsh| :ref:`Return to documentation for file ` (``src/tap/communication/serial/dji_serial.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp /* * Copyright (c) 2020-2021 Advanced Robotics at the University of Washington * * This file is part of Taproot. * * Taproot is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Taproot is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Taproot. If not, see . */ #ifndef TAPROOT_DJI_SERIAL_HPP_ #define TAPROOT_DJI_SERIAL_HPP_ #include #include "tap/algorithms/crc.hpp" #include "tap/communication/serial/uart.hpp" #include "tap/util_macros.hpp" namespace tap { class Drivers; } namespace tap::communication::serial { class DJISerial { public: struct FrameHeader { uint8_t headByte; uint16_t dataLength; uint8_t seq; uint8_t CRC8; } modm_packed; template struct SerialMessage { explicit SerialMessage(uint8_t seq = 0) { header.headByte = 0xa5; header.dataLength = sizeof(data); header.seq = seq; header.CRC8 = tap::algorithms::calculateCRC8( reinterpret_cast(&header), sizeof(header) - 1); } void setCRC16() { CRC16 = tap::algorithms::calculateCRC16( reinterpret_cast(this), sizeof(*this) - 2); } FrameHeader header; uint16_t messageType; uint8_t data[DATA_SIZE]; uint16_t CRC16; } modm_packed; static const uint16_t SERIAL_RX_BUFF_SIZE = 1024; static const uint16_t SERIAL_HEAD_BYTE = 0xA5; using ReceivedSerialMessage = SerialMessage; DJISerial(Drivers *drivers, Uart::UartPort port, bool isRxCRCEnforcementEnabled = true); DISALLOW_COPY_AND_ASSIGN(DJISerial) mockable ~DJISerial() = default; mockable void initialize(); mockable void updateSerial(); virtual void messageReceiveCallback(const ReceivedSerialMessage &completeMessage) = 0; private: enum SerialRxState { SERIAL_HEADER_SEARCH, PROCESS_FRAME_HEADER, PROCESS_FRAME_DATA }; Uart::UartPort port; SerialRxState djiSerialRxState; ReceivedSerialMessage newMessage; ReceivedSerialMessage mostRecentMessage; uint16_t frameCurrReadByte; bool rxCrcEnabled; inline bool verifyCRC8(uint8_t *message, uint32_t messageLength, uint8_t expectedCRC8) { return tap::algorithms::calculateCRC8(message, messageLength) == expectedCRC8; } protected: Drivers *drivers; }; } // namespace tap::communication::serial #endif // TAPROOT_DJI_SERIAL_HPP_