...fix telemetric bit

...also added some helper
This commit is contained in:
Wastl Kraus 2025-08-04 23:29:49 +02:00
parent 08c3a50423
commit 6c1c7e38e0
3 changed files with 67 additions and 26 deletions

View File

@ -19,25 +19,25 @@ constexpr dshot_timing_t DSHOT_TIMINGS[] = {
}; };
// //
DShotRMT::DShotRMT(gpio_num_t gpio, dshot_mode_t mode, bool is_bidirectional): DShotRMT::DShotRMT(gpio_num_t gpio, dshot_mode_t mode, bool is_bidirectional) : _gpio(gpio),
_gpio(gpio), _mode(mode),
_mode(mode), _is_bidirectional(is_bidirectional),
_is_bidirectional(is_bidirectional), _timing_config(DSHOT_TIMINGS[mode]),
_timing_config(DSHOT_TIMINGS[mode]), _rmt_tx_channel(nullptr),
_rmt_tx_channel(nullptr), _rmt_rx_channel(nullptr),
_rmt_rx_channel(nullptr), _dshot_encoder(nullptr),
_dshot_encoder(nullptr), _last_erpm(0),
_last_erpm(0), _last_transmission_time(0),
_last_transmission_time(0) _current_packet(0)
{ {
// Calculate frame time including switch time
_frame_time_us = _timing_config.frame_length_us + DSHOT_SWITCH_TIME;
// Double up frame time for bidirectional mode // Double up frame time for bidirectional mode
if (_is_bidirectional) if (_is_bidirectional)
{ {
_frame_time_us += _frame_time_us; _frame_time_us = (_timing_config.frame_length_us << 1) + DSHOT_SWITCH_TIME;
} }
// Calculate frame time including switch time
_frame_time_us = _timing_config.frame_length_us + DSHOT_SWITCH_TIME;
} }
// Init DShotRMT // Init DShotRMT
@ -75,7 +75,7 @@ bool DShotRMT::setThrottle(uint16_t throttle)
// Create DShot packet // Create DShot packet
packet.throttle_value = constrain(throttle, DSHOT_THROTTLE_MIN, DSHOT_THROTTLE_MAX); packet.throttle_value = constrain(throttle, DSHOT_THROTTLE_MIN, DSHOT_THROTTLE_MAX);
packet.telemetric_request = _is_bidirectional; packet.telemetric_request = 0;
packet.checksum = _calculateCRC(packet); packet.checksum = _calculateCRC(packet);
if (!_sendDShotFrame(packet)) if (!_sendDShotFrame(packet))
@ -94,13 +94,14 @@ bool DShotRMT::sendDShotCommand(uint16_t command)
// Create DShot packet // Create DShot packet
packet.throttle_value = constrain(command, DSHOT_CMD_MOTOR_STOP, DSHOT_CMD_MAX); packet.throttle_value = constrain(command, DSHOT_CMD_MOTOR_STOP, DSHOT_CMD_MAX);
packet.telemetric_request = _is_bidirectional; packet.telemetric_request = 0;
packet.checksum = _calculateCRC(packet); packet.checksum = _calculateCRC(packet);
if (!_sendDShotFrame(packet)) if (!_sendDShotFrame(packet))
{ {
return DSHOT_ERROR; return DSHOT_ERROR;
} }
return DSHOT_OK; return DSHOT_OK;
} }
@ -156,7 +157,7 @@ bool DShotRMT::_initTXChannel()
return DSHOT_ERROR; return DSHOT_ERROR;
} }
return rmt_enable(_rmt_tx_channel) == 0; return (rmt_enable(_rmt_tx_channel) == 0);
} }
// //
@ -177,7 +178,7 @@ bool DShotRMT::_initRXChannel()
return DSHOT_ERROR; return DSHOT_ERROR;
} }
return rmt_enable(_rmt_rx_channel) == 0; return (rmt_enable(_rmt_rx_channel) == 0);
} }
// //
@ -211,17 +212,18 @@ uint16_t DShotRMT::_sendDShotFrame(const dshot_packet_t &packet)
// Time Stamp // Time Stamp
_timer_reset(); _timer_reset();
return _assembleDShotFrame(packet); //
return _parseDShotPacket(packet);
} }
// // Calculates checksum for given package
uint16_t DShotRMT::_calculateCRC(const dshot_packet_t &packet) uint16_t DShotRMT::_calculateCRC(const dshot_packet_t &packet)
{ {
uint16_t data = (packet.throttle_value << 1) | packet.telemetric_request; uint16_t data = (packet.throttle_value << 1) | packet.telemetric_request;
uint16_t crc = (data ^ (data >> 4) ^ (data >> 8)) & 0b0000000000001111; uint16_t crc = (data ^ (data >> 4) ^ (data >> 8)) & 0b0000000000001111;
// Invert CRC for bidirectional DShot // Invert CRC for bidirectional DShot
if (packet.telemetric_request) if (_is_bidirectional)
{ {
crc = (~crc) & 0b0000000000001111; crc = (~crc) & 0b0000000000001111;
} }
@ -230,7 +232,7 @@ uint16_t DShotRMT::_calculateCRC(const dshot_packet_t &packet)
} }
// //
uint16_t DShotRMT::_assembleDShotFrame(const dshot_packet_t &packet) uint16_t DShotRMT::_parseDShotPacket(const dshot_packet_t &packet)
{ {
// Parses DShot Frame // Parses DShot Frame
uint16_t data = (packet.throttle_value << 1) | packet.telemetric_request; uint16_t data = (packet.throttle_value << 1) | packet.telemetric_request;
@ -238,10 +240,13 @@ uint16_t DShotRMT::_assembleDShotFrame(const dshot_packet_t &packet)
} }
// //
bool DShotRMT::_encodeDShotFrame(const dshot_packet_t& packet, rmt_symbol_word_t* symbols) bool IRAM_ATTR DShotRMT::_encodeDShotFrame(const dshot_packet_t &packet, rmt_symbol_word_t *symbols)
{ {
// Encoding to "raw" DShot Packet // Encoding to "raw" DShot Packet
uint16_t frame_bits = _assembleDShotFrame(packet); uint16_t frame_bits = _parseDShotPacket(packet);
// Updates temp buffer with encoded packet
_current_packet = frame_bits;
// Convert the parsed dshot frame to rmt_tx data // Convert the parsed dshot frame to rmt_tx data
for (int i = 0; i < DSHOT_BITS_PER_FRAME; i++) for (int i = 0; i < DSHOT_BITS_PER_FRAME; i++)
@ -303,6 +308,7 @@ uint16_t DShotRMT::_decodeDShotFrame(const rmt_symbol_word_t *symbols, size_t sy
// //
bool DShotRMT::_timer_signal() bool DShotRMT::_timer_signal()
{ {
// Timer triggered
return (micros() - _last_transmission_time) >= _frame_time_us; return (micros() - _last_transmission_time) >= _frame_time_us;
} }

View File

@ -91,6 +91,7 @@ public:
// //
gpio_num_t getGPIO() const { return _gpio; } gpio_num_t getGPIO() const { return _gpio; }
dshot_mode_t getDShotMode() const { return _mode; } dshot_mode_t getDShotMode() const { return _mode; }
uint16_t getDShotPacket() { return _current_packet; }
bool is_bidirectional() const { return _is_bidirectional; } bool is_bidirectional() const { return _is_bidirectional; }
private: private:
@ -118,6 +119,7 @@ private:
rmt_symbol_word_t _rx_symbols[RX_BUFFER_SIZE]; rmt_symbol_word_t _rx_symbols[RX_BUFFER_SIZE];
uint16_t _last_erpm; uint16_t _last_erpm;
unsigned long _last_transmission_time; unsigned long _last_transmission_time;
uint16_t _current_packet;
// //
bool _initTXChannel(); bool _initTXChannel();
@ -126,8 +128,8 @@ private:
uint16_t _sendDShotFrame(const dshot_packet_t &packet); uint16_t _sendDShotFrame(const dshot_packet_t &packet);
uint16_t _calculateCRC(const dshot_packet_t &packet); uint16_t _calculateCRC(const dshot_packet_t &packet);
uint16_t _assembleDShotFrame(const dshot_packet_t &packet); uint16_t _parseDShotPacket(const dshot_packet_t &packet);
bool _encodeDShotFrame(const dshot_packet_t &packet, rmt_symbol_word_t *symbols); bool IRAM_ATTR _encodeDShotFrame(const dshot_packet_t &packet, rmt_symbol_word_t *symbols);
uint16_t _decodeDShotFrame(const rmt_symbol_word_t *symbols, size_t symbol_count); uint16_t _decodeDShotFrame(const rmt_symbol_word_t *symbols, size_t symbol_count);
bool _timer_signal(); bool _timer_signal();

View File

@ -32,6 +32,9 @@ void printRPMPeriodically(uint16_t throttle);
// Reads throttle value from serial input // Reads throttle value from serial input
uint16_t readSerialThrottle(); uint16_t readSerialThrottle();
// Prints out the dshot packet bitwise (Debug)
void printPacket();
// //
void setup() void setup()
{ {
@ -63,6 +66,9 @@ void loop()
{ {
printRPMPeriodically(throttle_input); printRPMPeriodically(throttle_input);
} }
// Prints out "raw" DShot packet
// printPacket();
} }
// Reads throttle value from serial input // Reads throttle value from serial input
@ -111,3 +117,30 @@ void printRPMPeriodically(uint16_t throttle)
last_print_time = millis(); last_print_time = millis();
} }
} }
//
void printPacket()
{
static unsigned long last_print_time = 0;
if (millis() - last_print_time >= 2000)
{
// Prints out actual DShot Packet bitwise
uint16_t packet = motor01.getDShotPacket();
for (int i = 15; i >= 0; --i)
{
if ((packet >> i) & 1)
{
USB_SERIAL.print("1");
}
else
{
USB_SERIAL.print("0");
}
}
USB_SERIAL.println("");
last_print_time = millis();
}
}