...add package builder

This commit is contained in:
Wastl Kraus 2025-08-05 01:43:19 +02:00
parent 6c1c7e38e0
commit dfccc3c83d
2 changed files with 40 additions and 37 deletions

View File

@ -70,39 +70,31 @@ bool DShotRMT::begin()
//
bool DShotRMT::setThrottle(uint16_t throttle)
{
// DShot Frame Container
dshot_packet_t packet = {};
// Create DShot packet
packet.throttle_value = constrain(throttle, DSHOT_THROTTLE_MIN, DSHOT_THROTTLE_MAX);
packet.telemetric_request = 0;
packet.checksum = _calculateCRC(packet);
if (!_sendDShotFrame(packet))
// Precheck throttle value
if (throttle < DSHOT_THROTTLE_MIN || throttle > DSHOT_THROTTLE_MAX)
{
return DSHOT_ERROR;
}
//
dshot_packet_t packet = _buildDShotPacket(throttle);
return DSHOT_OK;
return (_sendDShotFrame(packet));
}
//
bool DShotRMT::sendDShotCommand(uint16_t command)
{
// DShot Frame Container
dshot_packet_t packet = {};
// Create DShot packet
packet.throttle_value = constrain(command, DSHOT_CMD_MOTOR_STOP, DSHOT_CMD_MAX);
packet.telemetric_request = 0;
packet.checksum = _calculateCRC(packet);
if (!_sendDShotFrame(packet))
// Precheck throttle value
if (command < DSHOT_CMD_MOTOR_STOP || command > DSHOT_CMD_MAX)
{
return DSHOT_ERROR;
}
//
dshot_packet_t packet = _buildDShotPacket(command);
return DSHOT_OK;
return (_sendDShotFrame(packet));
}
//
@ -190,30 +182,30 @@ bool DShotRMT::_initDShotEncoder()
}
// Use RMT to transmit a prepared DShot packet and returns it
uint16_t DShotRMT::_sendDShotFrame(const dshot_packet_t &packet)
bool DShotRMT::_sendDShotFrame(const dshot_packet_t &packet)
{
// Encodes packet directly into RMT Buffer
rmt_symbol_word_t tx_symbols[DSHOT_BITS_PER_FRAME];
_encodeDShotFrame(packet, tx_symbols);
//
if (!_timer_signal())
{
return DSHOT_NULL_PACKET;
return DSHOT_ERROR;
}
// Encodes packet directly into RMT Buffer
rmt_symbol_word_t tx_symbols[DSHOT_BITS_PER_FRAME];
_encodeDShotFrame(packet, tx_symbols);
// Trigger RMT Transmit
if (rmt_transmit(_rmt_tx_channel, _dshot_encoder, tx_symbols, DSHOT_SYMBOLS_SIZE, &_transmit_config) != 0)
{
Serial.println("Failed to transmit DShot packet");
return DSHOT_NULL_PACKET;
return DSHOT_ERROR;
}
// Time Stamp
_timer_reset();
//
return _parseDShotPacket(packet);
return DSHOT_OK;
}
// Calculates checksum for given package
@ -236,23 +228,34 @@ uint16_t DShotRMT::_parseDShotPacket(const dshot_packet_t &packet)
{
// Parses DShot Frame
uint16_t data = (packet.throttle_value << 1) | packet.telemetric_request;
return (data << 4) | packet.checksum;
return (data << 4) | _calculateCRC(packet);
}
dshot_packet_t DShotRMT::_buildDShotPacket(const uint16_t value)
{
// DShot Frame Container
dshot_packet_t packet = {};
// Create DShot packet
packet.throttle_value = value;
packet.telemetric_request = 0;
packet.checksum = _calculateCRC(packet);
//
return packet;
}
//
bool IRAM_ATTR DShotRMT::_encodeDShotFrame(const dshot_packet_t &packet, rmt_symbol_word_t *symbols)
{
// Encoding to "raw" DShot Packet
uint16_t frame_bits = _parseDShotPacket(packet);
// Updates temp buffer with encoded packet
_current_packet = frame_bits;
// Decoding "raw" DShot Packet
_current_packet = _parseDShotPacket(packet);
// Convert the parsed dshot frame to rmt_tx data
for (int i = 0; i < DSHOT_BITS_PER_FRAME; i++)
{
// Encode RMT symbols bitwise (MSB first) - tricky
bool bit = (frame_bits >> (DSHOT_BITS_PER_FRAME - 1 - i)) & 0b0000000000000001;
bool bit = (_current_packet >> (DSHOT_BITS_PER_FRAME - 1 - i)) & 0b0000000000000001;
if (_is_bidirectional)
{
symbols[i].level0 = 0;

View File

@ -90,7 +90,6 @@ 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; }
@ -126,8 +125,9 @@ private:
bool _initRXChannel();
bool _initDShotEncoder();
uint16_t _sendDShotFrame(const dshot_packet_t &packet);
bool _sendDShotFrame(const dshot_packet_t &packet);
uint16_t _calculateCRC(const dshot_packet_t &packet);
dshot_packet_t _buildDShotPacket(const uint16_t value);
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);