...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,8 +19,7 @@ constexpr dshot_timing_t DSHOT_TIMINGS[] = {
};
//
DShotRMT::DShotRMT(gpio_num_t gpio, dshot_mode_t mode, bool is_bidirectional):
_gpio(gpio),
DShotRMT::DShotRMT(gpio_num_t gpio, dshot_mode_t mode, bool is_bidirectional) : _gpio(gpio),
_mode(mode),
_is_bidirectional(is_bidirectional),
_timing_config(DSHOT_TIMINGS[mode]),
@ -28,16 +27,17 @@ DShotRMT::DShotRMT(gpio_num_t gpio, dshot_mode_t mode, bool is_bidirectional):
_rmt_rx_channel(nullptr),
_dshot_encoder(nullptr),
_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
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
@ -75,7 +75,7 @@ bool DShotRMT::setThrottle(uint16_t throttle)
// Create DShot packet
packet.throttle_value = constrain(throttle, DSHOT_THROTTLE_MIN, DSHOT_THROTTLE_MAX);
packet.telemetric_request = _is_bidirectional;
packet.telemetric_request = 0;
packet.checksum = _calculateCRC(packet);
if (!_sendDShotFrame(packet))
@ -94,13 +94,14 @@ bool DShotRMT::sendDShotCommand(uint16_t command)
// Create DShot packet
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);
if (!_sendDShotFrame(packet))
{
return DSHOT_ERROR;
}
return DSHOT_OK;
}
@ -156,7 +157,7 @@ bool DShotRMT::_initTXChannel()
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 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
_timer_reset();
return _assembleDShotFrame(packet);
//
return _parseDShotPacket(packet);
}
//
// Calculates checksum for given package
uint16_t DShotRMT::_calculateCRC(const dshot_packet_t &packet)
{
uint16_t data = (packet.throttle_value << 1) | packet.telemetric_request;
uint16_t crc = (data ^ (data >> 4) ^ (data >> 8)) & 0b0000000000001111;
// Invert CRC for bidirectional DShot
if (packet.telemetric_request)
if (_is_bidirectional)
{
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
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
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
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()
{
// Timer triggered
return (micros() - _last_transmission_time) >= _frame_time_us;
}

View File

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

View File

@ -32,6 +32,9 @@ void printRPMPeriodically(uint16_t throttle);
// Reads throttle value from serial input
uint16_t readSerialThrottle();
// Prints out the dshot packet bitwise (Debug)
void printPacket();
//
void setup()
{
@ -63,6 +66,9 @@ void loop()
{
printRPMPeriodically(throttle_input);
}
// Prints out "raw" DShot packet
// printPacket();
}
// Reads throttle value from serial input
@ -111,3 +117,30 @@ void printRPMPeriodically(uint16_t throttle)
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();
}
}