mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-11-12 19:41:36 +08:00
dshot: breakout driver header file, use static_casts, add const specifiers (#15908)
* Break out dshot.h from dshot.cpp and rename files to reflect the class name. Move DShot class specific #defines from drv_pwm_output.h to dshot.h. Replace c-style casts with static_casts, standardize method naming, single line comment styles, and formatting. Rename update_dshot_out_state() to enable_dshot_outputs().
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2019 PX4 Development Team. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <drivers/drv_hrt.h>
|
||||
|
||||
class DShotTelemetry
|
||||
{
|
||||
public:
|
||||
struct EscData {
|
||||
hrt_abstime time;
|
||||
int8_t temperature; ///< [deg C]
|
||||
int16_t voltage; ///< [0.01V]
|
||||
int16_t current; ///< [0.01A]
|
||||
int16_t consumption; ///< [mAh]
|
||||
int16_t erpm; ///< [100ERPM]
|
||||
};
|
||||
|
||||
static constexpr int esc_info_size_blheli32 = 64;
|
||||
static constexpr int esc_info_size_kiss_v1 = 15;
|
||||
static constexpr int esc_info_size_kiss_v2 = 21;
|
||||
static constexpr int max_esc_info_size = esc_info_size_blheli32;
|
||||
|
||||
struct OutputBuffer {
|
||||
uint8_t buffer[max_esc_info_size];
|
||||
int buf_pos{0};
|
||||
int motor_index;
|
||||
};
|
||||
|
||||
~DShotTelemetry();
|
||||
|
||||
int init(const char *uart_device);
|
||||
|
||||
void deinit();
|
||||
|
||||
void setNumMotors(int num_motors) { _num_motors = num_motors; }
|
||||
int numMotors() const { return _num_motors; }
|
||||
|
||||
/**
|
||||
* Read telemetry from the UART (non-blocking) and handle timeouts.
|
||||
* @return -1 if no update, -2 timeout, >= 0 for the motor index. Use @latestESCData() to get the data.
|
||||
*/
|
||||
int update();
|
||||
|
||||
/**
|
||||
* Redirect everything that is read into a different buffer.
|
||||
* Future calls to @update will write to that instead of an internal buffer, until @update returns
|
||||
* a value different from -1. No decoding is done.
|
||||
* The caller must ensure the buffer exists until that point.
|
||||
* @param buffer
|
||||
* @return 0 on success <0 on error
|
||||
*/
|
||||
int redirectOutput(OutputBuffer &buffer);
|
||||
|
||||
bool redirectActive() const { return _redirect_output != nullptr; }
|
||||
|
||||
/**
|
||||
* Get the motor index for which telemetry should be requested.
|
||||
* @return -1 if no request should be made, motor index otherwise
|
||||
*/
|
||||
int getRequestMotorIndex();
|
||||
|
||||
const EscData &latestESCData() const { return _latest_data; }
|
||||
|
||||
/**
|
||||
* Check whether we are currently expecting to read new data from an ESC
|
||||
*/
|
||||
bool expectingData() const { return _current_request_start != 0; }
|
||||
|
||||
void printStatus() const;
|
||||
|
||||
static void decodeAndPrintEscInfoPacket(const OutputBuffer &buffer);
|
||||
|
||||
private:
|
||||
static constexpr int ESC_FRAME_SIZE = 10;
|
||||
|
||||
/**
|
||||
* set the Baudrate
|
||||
* @param baud
|
||||
* @return 0 on success, <0 on error
|
||||
*/
|
||||
int setBaudrate(unsigned baud);
|
||||
|
||||
void requestNextMotor();
|
||||
|
||||
/**
|
||||
* Decode a single byte from an ESC feedback frame
|
||||
* @param byte
|
||||
* @param successful_decoding set to true if checksum matches
|
||||
* @return true if received the expected amount of bytes and the next motor can be requested
|
||||
*/
|
||||
bool decodeByte(uint8_t byte, bool &successful_decoding);
|
||||
|
||||
static inline uint8_t updateCrc8(uint8_t crc, uint8_t crc_seed);
|
||||
static uint8_t crc8(const uint8_t *buf, uint8_t len);
|
||||
|
||||
int _uart_fd{-1};
|
||||
int _num_motors{0};
|
||||
uint8_t _frame_buffer[ESC_FRAME_SIZE];
|
||||
int _frame_position{0};
|
||||
|
||||
EscData _latest_data;
|
||||
|
||||
int _current_motor_index_request{-1};
|
||||
hrt_abstime _current_request_start{0};
|
||||
|
||||
OutputBuffer *_redirect_output{nullptr}; ///< if set, all read bytes are stored here instead of the internal buffer
|
||||
|
||||
// statistics
|
||||
int _num_timeouts{0};
|
||||
int _num_successful_responses{0};
|
||||
};
|
||||
Reference in New Issue
Block a user