From 3537f4f2d88ae025b869acd6f9f75da09ee5e886 Mon Sep 17 00:00:00 2001 From: Wastl Kraus Date: Mon, 29 Sep 2025 16:51:12 +0200 Subject: [PATCH] refractor dshot_result_t --- DShotRMT.code-workspace | 3 +- README.md | 2 +- src/DShotRMT.cpp | 64 ++++++++++++++++++++--------------------- src/dshot_definitions.h | 64 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 97 insertions(+), 36 deletions(-) diff --git a/DShotRMT.code-workspace b/DShotRMT.code-workspace index e535653..3f3afe3 100644 --- a/DShotRMT.code-workspace +++ b/DShotRMT.code-workspace @@ -10,6 +10,7 @@ }, "arduino.logLevel": "verbose", "arduino.path": "/usr/bin/arduino-cli", - "arduino.useArduinoCli": true + "arduino.useArduinoCli": true, + "arduino.disableIntelliSenseAutoGen": true } } \ No newline at end of file diff --git a/README.md b/README.md index 4186cf2..f309cc0 100644 --- a/README.md +++ b/README.md @@ -147,4 +147,4 @@ Contributions are welcome! Please fork the repository, create a feature branch, ## 📄 License -This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. \ No newline at end of file +This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. diff --git a/src/DShotRMT.cpp b/src/DShotRMT.cpp index 08a3e25..46bb833 100644 --- a/src/DShotRMT.cpp +++ b/src/DShotRMT.cpp @@ -18,7 +18,7 @@ DShotRMT::DShotRMT(gpio_num_t gpio, dshot_mode_t mode, bool is_bidirectional, ui _dshot_timing(DSHOT_TIMING_US[static_cast(mode)]), _frame_timer_us(0), _rmt_ticks{0}, - _last_throttle(static_cast(dshotCommands_e::DSHOT_CMD_MOTOR_STOP)), + _last_throttle(dshotCommands_e::DSHOT_CMD_MOTOR_STOP), _last_transmission_time_us(0), _last_command_timestamp(0), _encoded_frame_value(0), @@ -84,7 +84,7 @@ dshot_result_t DShotRMT::begin() { if (!_initTXChannel().success) { - return {false, TX_INIT_FAILED}; + return {false, dshot_msg_code_t::DSHOT_TX_INIT_FAILED}; } if (_is_bidirectional) @@ -95,7 +95,7 @@ dshot_result_t DShotRMT::begin() rmt_disable(_rmt_tx_channel); rmt_del_channel(_rmt_tx_channel); _rmt_tx_channel = nullptr; - return {false, RX_INIT_FAILED}; + return {false, dshot_msg_code_t::DSHOT_RX_INIT_FAILED}; } } @@ -113,10 +113,10 @@ dshot_result_t DShotRMT::begin() _rmt_rx_channel = nullptr; } - return {false, ENCODER_INIT_FAILED}; + return {false, dshot_msg_code_t::DSHOT_ENCODER_INIT_FAILED}; } - return {true, INIT_SUCCESS}; + return {true, dshot_msg_code_t::DSHOT_INIT_SUCCESS}; } // Send throttle value @@ -125,7 +125,7 @@ dshot_result_t DShotRMT::sendThrottle(uint16_t throttle) // A throttle value of 0 is a disarm command if (throttle == 0) { - return sendCommand(static_cast(dshotCommands_e::DSHOT_CMD_MOTOR_STOP)); + return sendCommand(dshotCommands_e::DSHOT_CMD_MOTOR_STOP); } // Constrain throttle to the valid DShot range @@ -140,7 +140,7 @@ dshot_result_t DShotRMT::sendThrottlePercent(float percent) { if (percent < 0.0f || percent > 100.0f) { - return {false, PERCENT_NOT_IN_RANGE}; + return {false, dshot_msg_code_t::DSHOT_PERCENT_NOT_IN_RANGE}; } // Map percent to DShot throttle range @@ -151,9 +151,9 @@ dshot_result_t DShotRMT::sendThrottlePercent(float percent) // Send DShot command to ESC dshot_result_t DShotRMT::sendCommand(uint16_t command) { - if (command > static_cast(dshotCommands_e::DSHOT_CMD_MAX)) + if (command > dshotCommands_e::DSHOT_CMD_MAX) { - return {false, COMMAND_NOT_VALID}; + return {false, dshot_msg_code_t::DSHOT_COMMAND_NOT_VALID}; } _packet = _buildDShotPacket(command); @@ -164,11 +164,11 @@ dshot_result_t DShotRMT::sendCommand(uint16_t command) // This is a blocking function that uses delayMicroseconds for repetitions. dshot_result_t DShotRMT::sendCommand(dshotCommands_e dshot_command, uint16_t repeat_count, uint16_t delay_us) { - dshot_result_t result = {false, UNKNOWN_ERROR}; + dshot_result_t result = {false, dshot_msg_code_t::DSHOT_UNKNOWN, NO_DSHOT_TELEMETRY, NO_DSHOT_TELEMETRY}; if (!_isValidCommand(dshot_command)) { - result.result_code = INVALID_COMMAND; + result.result_code = dshot_msg_code_t::DSHOT_INVALID_COMMAND; return result; } @@ -198,7 +198,7 @@ dshot_result_t DShotRMT::sendCommand(dshotCommands_e dshot_command, uint16_t rep if (result.success) { - result.result_code = COMMAND_SUCCESS; + result.result_code = dshot_msg_code_t::DSHOT_COMMAND_SUCCESS; } return result; @@ -207,11 +207,11 @@ dshot_result_t DShotRMT::sendCommand(dshotCommands_e dshot_command, uint16_t rep // Get telemetry data dshot_result_t DShotRMT::getTelemetry(uint16_t magnet_count) { - dshot_result_t result = {false, TELEMETRY_FAILED, NO_DSHOT_TELEMETRY, NO_DSHOT_TELEMETRY}; + dshot_result_t result = {false, dshot_msg_code_t::DSHOT_TELEMETRY_FAILED, NO_DSHOT_TELEMETRY, NO_DSHOT_TELEMETRY}; if (!_is_bidirectional) { - result.result_code = BIDIR_NOT_ENABLED; + result.result_code = dshot_msg_code_t::DSHOT_BIDIR_NOT_ENABLED; return result; } @@ -233,7 +233,7 @@ dshot_result_t DShotRMT::getTelemetry(uint16_t magnet_count) result.success = true; result.erpm = erpm; result.motor_rpm = motor_rpm; - result.result_code = TELEMETRY_SUCCESS; + result.result_code = dshot_msg_code_t::DSHOT_TELEMETRY_SUCCESS; } } @@ -251,7 +251,7 @@ dshot_result_t DShotRMT::setMotorSpinDirection(bool reversed) dshot_result_t DShotRMT::getESCInfo() { - return sendCommand(static_cast(dshotCommands_e::DSHOT_CMD_ESC_INFO)); + return sendCommand(dshotCommands_e::DSHOT_CMD_ESC_INFO); } // Use with caution @@ -263,7 +263,7 @@ dshot_result_t DShotRMT::saveESCSettings() // Simple check bool DShotRMT::_isValidCommand(dshotCommands_e command) { - return (static_cast(command) >= static_cast(dshotCommands_e::DSHOT_CMD_MOTOR_STOP) && static_cast(command) <= static_cast(dshotCommands_e::DSHOT_CMD_MAX)); + return (command >= dshotCommands_e::DSHOT_CMD_MOTOR_STOP && command <= dshotCommands_e::DSHOT_CMD_MAX); } // @@ -272,7 +272,7 @@ dshot_result_t DShotRMT::_executeCommand(dshotCommands_e command) uint64_t start_time = esp_timer_get_time(); // Execute the command using the DShotRMT instance - dshot_result_t result = sendCommand(static_cast(command)); + dshot_result_t result = sendCommand(command); uint64_t end_time = esp_timer_get_time(); _last_command_timestamp = end_time; @@ -294,15 +294,15 @@ dshot_result_t DShotRMT::_initTXChannel() if (rmt_new_tx_channel(&_tx_channel_config, &_rmt_tx_channel) != DSHOT_OK) { - return {false, TX_INIT_FAILED}; + return {false, dshot_msg_code_t::DSHOT_TX_INIT_FAILED}; } if (rmt_enable(_rmt_tx_channel) != DSHOT_OK) { - return {false, TX_INIT_FAILED}; + return {false, dshot_msg_code_t::DSHOT_TX_INIT_FAILED}; } - return {true, TX_INIT_SUCCESS}; + return {true, dshot_msg_code_t::DSHOT_TX_INIT_SUCCESS}; } dshot_result_t DShotRMT::_initRXChannel() @@ -310,7 +310,7 @@ dshot_result_t DShotRMT::_initRXChannel() // Double check if bidirectional mode is enabled if (!_is_bidirectional) { - return {true, NONE}; + return {true, dshot_msg_code_t::DSHOT_NONE}; } _rx_channel_config.gpio_num = _gpio; @@ -324,19 +324,19 @@ dshot_result_t DShotRMT::_initRXChannel() if (rmt_new_rx_channel(&_rx_channel_config, &_rmt_rx_channel) != DSHOT_OK) { - return {false, RX_INIT_FAILED}; + return {false, dshot_msg_code_t::DSHOT_RX_INIT_FAILED}; } // Register the callback function that will be triggered when a frame is received _rx_event_callbacks.on_recv_done = _on_rx_done; if (rmt_rx_register_event_callbacks(_rmt_rx_channel, &_rx_event_callbacks, this) != DSHOT_OK) { - return {false, CALLBACK_REGISTERING_FAILED}; + return {false, dshot_msg_code_t::DSHOT_CALLBACK_REGISTERING_FAILED}; } if (rmt_enable(_rmt_rx_channel) != DSHOT_OK) { - return {false, RX_INIT_FAILED}; + return {false, dshot_msg_code_t::DSHOT_RX_INIT_FAILED}; } // Start the receiver to wait for incoming telemetry data @@ -344,10 +344,10 @@ dshot_result_t DShotRMT::_initRXChannel() size_t rx_size_bytes = GCR_BITS_PER_FRAME * sizeof(rmt_symbol_word_t); if (rmt_receive(_rmt_rx_channel, rx_symbols, rx_size_bytes, &_rmt_rx_config) != DSHOT_OK) { - return {false, RECEIVER_FAILED}; + return {false, dshot_msg_code_t::DSHOT_RECEIVER_FAILED}; } - return {true, RX_INIT_SUCCESS}; + return {true, dshot_msg_code_t::DSHOT_RX_INIT_SUCCESS}; } dshot_result_t DShotRMT::_initDShotEncoder() @@ -372,10 +372,10 @@ dshot_result_t DShotRMT::_initDShotEncoder() if (rmt_new_bytes_encoder(&encoder_config, &_dshot_encoder) != DSHOT_OK) { - return {false, ENCODER_INIT_FAILED}; + return {false, dshot_msg_code_t::DSHOT_ENCODER_INIT_FAILED}; } - return {true, ENCODER_INIT_SUCCESS}; + return {true, dshot_msg_code_t::DSHOT_ENCODER_INIT_SUCCESS}; } // Private Packet Management Functions @@ -439,7 +439,7 @@ dshot_result_t DShotRMT::_sendDShotFrame(const dshot_packet_t &packet) // Ensure enough time has passed since the last transmission if (!_isFrameIntervalElapsed()) { - return {true, NONE}; + return {true, dshot_msg_code_t::DSHOT_NONE}; } _encoded_frame_value = _buildDShotFrameValue(packet); @@ -452,12 +452,12 @@ dshot_result_t DShotRMT::_sendDShotFrame(const dshot_packet_t &packet) if (rmt_transmit(_rmt_tx_channel, _dshot_encoder, &swapped_value, tx_size_bytes, &_rmt_tx_config) != DSHOT_OK) { - return {false, TRANSMISSION_FAILED}; + return {false, dshot_msg_code_t::DSHOT_TRANSMISSION_FAILED}; } _recordFrameTransmissionTime(); // Reset the timer for the next frame - return {true, TRANSMISSION_SUCCESS}; + return {true, dshot_msg_code_t::DSHOT_TRANSMISSION_SUCCESS}; } // This function needs to be fast, as it generates the RMT symbols just before sending diff --git a/src/dshot_definitions.h b/src/dshot_definitions.h index fd3f55d..702c0af 100644 --- a/src/dshot_definitions.h +++ b/src/dshot_definitions.h @@ -75,7 +75,7 @@ enum class dshot_msg_code_t typedef struct dshot_result { bool success; - char *result_code; // Specific error or success code. + dshot_msg_code_t result_code; // Specific error or success code. uint16_t erpm; // Electrical RPM (eRPM) if telemetry is successful. uint16_t motor_rpm; // Motor RPM if telemetry is successful and magnet count is known. } dshot_result_t; @@ -194,10 +194,70 @@ static constexpr char *CALLBACK_REGISTERING_FAILED = "RMT RX Callback registerin static constexpr char *INVALID_COMMAND = "Invalid command!"; static constexpr char *COMMAND_SUCCESS = "DShot command sent successfully"; +// Helper to get result code string +inline const char* _get_result_code_str(dshot_msg_code_t code) +{ + switch (code) + { + case dshot_msg_code_t::DSHOT_NONE: + return NONE; + case dshot_msg_code_t::DSHOT_UNKNOWN: + return UNKNOWN_ERROR; + case dshot_msg_code_t::DSHOT_TX_INIT_FAILED: + return TX_INIT_FAILED; + case dshot_msg_code_t::DSHOT_RX_INIT_FAILED: + return RX_INIT_FAILED; + case dshot_msg_code_t::DSHOT_ENCODER_INIT_FAILED: + return ENCODER_INIT_FAILED; + case dshot_msg_code_t::DSHOT_CALLBACK_REGISTERING_FAILED: + return CALLBACK_REGISTERING_FAILED; + case dshot_msg_code_t::DSHOT_RECEIVER_FAILED: + return RECEIVER_FAILED; + case dshot_msg_code_t::DSHOT_TRANSMISSION_FAILED: + return TRANSMISSION_FAILED; + case dshot_msg_code_t::DSHOT_THROTTLE_NOT_IN_RANGE: + return THROTTLE_NOT_IN_RANGE; + case dshot_msg_code_t::DSHOT_PERCENT_NOT_IN_RANGE: + return PERCENT_NOT_IN_RANGE; + case dshot_msg_code_t::DSHOT_COMMAND_NOT_VALID: + return COMMAND_NOT_VALID; + case dshot_msg_code_t::DSHOT_BIDIR_NOT_ENABLED: + return BIDIR_NOT_ENABLED; + case dshot_msg_code_t::DSHOT_TELEMETRY_FAILED: + return TELEMETRY_FAILED; + case dshot_msg_code_t::DSHOT_INVALID_MAGNET_COUNT: + return INVALID_MAGNET_COUNT; + case dshot_msg_code_t::DSHOT_INVALID_COMMAND: + return INVALID_COMMAND; + case dshot_msg_code_t::DSHOT_TIMING_CORRECTION: + return TIMING_CORRECTION; + case dshot_msg_code_t::DSHOT_INIT_FAILED: + return INIT_FAILED; + case dshot_msg_code_t::DSHOT_INIT_SUCCESS: + return INIT_SUCCESS; + case dshot_msg_code_t::DSHOT_TX_INIT_SUCCESS: + return TX_INIT_SUCCESS; + case dshot_msg_code_t::DSHOT_RX_INIT_SUCCESS: + return RX_INIT_SUCCESS; + case dshot_msg_code_t::DSHOT_ENCODER_INIT_SUCCESS: + return ENCODER_INIT_SUCCESS; + case dshot_msg_code_t::DSHOT_ENCODING_SUCCESS: + return ENCODING_SUCCESS; + case dshot_msg_code_t::DSHOT_TRANSMISSION_SUCCESS: + return TRANSMISSION_SUCCESS; + case dshot_msg_code_t::DSHOT_TELEMETRY_SUCCESS: + return TELEMETRY_SUCCESS; + case dshot_msg_code_t::DSHOT_COMMAND_SUCCESS: + return COMMAND_SUCCESS; + default: + return UNKNOWN_ERROR; + } +} + // Helpers inline void printDShotResult(dshot_result_t &result, Stream &output = Serial) { - output.printf("Status: %s - %s", result.success ? "SUCCESS" : "FAILED", result.result_code); + output.printf("Status: %s - %s", result.success ? "SUCCESS" : "FAILED", _get_result_code_str(result.result_code)); // Print telemetry data if available if (result.success && (result.erpm > 0 || result.motor_rpm > 0))