...updated class to optimize configuration

This commit is contained in:
Wastl Kraus 2023-03-26 16:19:54 +02:00
parent d7e8386129
commit 34c6f66256
6 changed files with 90 additions and 93 deletions

1
.gitignore vendored
View File

@ -18,3 +18,4 @@ buildCache
examples/dshot300/debug.cfg
examples/dshot300/esp32.svd
examples/dshot300/debug_custom.json
examples/dshot300/debug.svd

View File

@ -9,7 +9,7 @@
constexpr auto USB_SERIAL_BAUD = 115200;
#endif // SERIAL
DShotRMT dshot_01(GPIO_NUM_4, RMT_CHANNEL_0);
DShotRMT motor01(GPIO_NUM_4, RMT_CHANNEL_0, DSHOT300, false);
volatile uint16_t throttle_value = 0x30; // ...sending "48", the first throttle value
constexpr auto FAILSAVE_THROTTLE = 0x3E7;
@ -18,16 +18,13 @@ void setup()
{
// ...always start the onboard usb support
USB_Serial.begin(USB_SERIAL_BAUD);
// ...start the dshot generation
dshot_01.begin(DSHOT300);
}
void loop()
{
read_SerialThrottle();
dshot_01.send_dshot_value(throttle_value);
motor01.send_dshot_value(throttle_value);
// ...print to console
USB_Serial.println(throttle_value);

View File

@ -15,7 +15,7 @@ dshot_config_t KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
install_dshot_driver KEYWORD2
send_dshot_value KEYWORD2
get_dshot_info KEYWORD2
get_dshot_clock_div KEYWORD2

View File

@ -1,5 +1,5 @@
name=DShotRMT
version=0.2.2
version=0.2.3
author=derdoktor667
maintainer=derdoktor667
sentence=DShotRMT Library supporting all DShot Types and speeds. Tested with BlHeli_S.

View File

@ -4,9 +4,9 @@
// Author: derdoktor667
//
#include "DShotRMT.h"
#include <DShotRMT.h>
DShotRMT::DShotRMT(gpio_num_t gpio, rmt_channel_t rmtChannel)
DShotRMT::DShotRMT(gpio_num_t gpio, rmt_channel_t rmtChannel, dshot_mode_t dshot_mode, bool is_bidirectional)
{
dshot_config.gpio_num = gpio;
dshot_config.pin_num = uint8_t(gpio);
@ -15,9 +15,12 @@ DShotRMT::DShotRMT(gpio_num_t gpio, rmt_channel_t rmtChannel)
// ...create empty packet
encode_dshot_to_rmt(DSHOT_NULL_PACKET);
// install the RMT driver with dshot values
install_dshot_driver(dshot_mode, is_bidirectional);
}
DShotRMT::DShotRMT(uint8_t pin, uint8_t channel)
DShotRMT::DShotRMT(uint8_t pin, uint8_t channel, dshot_mode_t dshot_mode, bool is_bidirectional)
{
dshot_config.gpio_num = gpio_num_t(pin);
dshot_config.pin_num = pin;
@ -26,6 +29,9 @@ DShotRMT::DShotRMT(uint8_t pin, uint8_t channel)
// ...create empty packet
encode_dshot_to_rmt(DSHOT_NULL_PACKET);
// install the RMT driver with dshot values
install_dshot_driver(dshot_mode, is_bidirectional);
}
DShotRMT::~DShotRMT()
@ -38,77 +44,6 @@ DShotRMT::DShotRMT(DShotRMT const &)
// ...write me
}
bool DShotRMT::begin(dshot_mode_t dshot_mode, bool is_bidirectional)
{
dshot_config.mode = dshot_mode;
dshot_config.clk_div = DSHOT_CLK_DIVIDER;
dshot_config.name_str = dshot_mode_name[dshot_mode];
dshot_config.bidirectional = is_bidirectional;
switch (dshot_config.mode)
{
case DSHOT150:
dshot_config.ticks_per_bit = 64; // ...Bit Period Time 6.67 us
dshot_config.ticks_zero_high = 24; // ...zero time 2.50 us
dshot_config.ticks_one_high = 48; // ...one time 5.00 us
break;
case DSHOT300:
dshot_config.ticks_per_bit = 32; // ...Bit Period Time 3.33 us
dshot_config.ticks_zero_high = 12; // ...zero time 1.25 us
dshot_config.ticks_one_high = 24; // ...one time 2.50 us
break;
case DSHOT600:
dshot_config.ticks_per_bit = 16; // ...Bit Period Time 1.67 us
dshot_config.ticks_zero_high = 6; // ...zero time 0.625 us
dshot_config.ticks_one_high = 12; // ...one time 1.25 us
break;
case DSHOT1200:
dshot_config.ticks_per_bit = 8; // ...Bit Period Time 0.83 us
dshot_config.ticks_zero_high = 3; // ...zero time 0.313 us
dshot_config.ticks_one_high = 6; // ...one time 0.625 us
break;
// ...because having a default is "good style"
default:
dshot_config.ticks_per_bit = 0; // ...Bit Period Time endless
dshot_config.ticks_zero_high = 0; // ...no bits, no time
dshot_config.ticks_one_high = 0; // ......no bits, no time
break;
}
// ...calc low signal timing
dshot_config.ticks_zero_low = (dshot_config.ticks_per_bit - dshot_config.ticks_zero_high);
dshot_config.ticks_one_low = (dshot_config.ticks_per_bit - dshot_config.ticks_one_high);
dshot_tx_rmt_config.rmt_mode = RMT_MODE_TX;
dshot_tx_rmt_config.channel = dshot_config.rmt_channel;
dshot_tx_rmt_config.gpio_num = dshot_config.gpio_num;
dshot_tx_rmt_config.mem_block_num = dshot_config.mem_block_num;
dshot_tx_rmt_config.clk_div = dshot_config.clk_div;
dshot_tx_rmt_config.tx_config.loop_en = false;
dshot_tx_rmt_config.tx_config.carrier_en = false;
dshot_tx_rmt_config.tx_config.idle_output_en = true;
if (dshot_config.bidirectional)
{
dshot_tx_rmt_config.tx_config.idle_level = RMT_IDLE_LEVEL_HIGH;
}
else
{
dshot_tx_rmt_config.tx_config.idle_level = RMT_IDLE_LEVEL_LOW;
}
// ...setup selected dshot mode
rmt_config(&dshot_tx_rmt_config);
// ...essential step, return the result
return rmt_driver_install(dshot_tx_rmt_config.channel, 0, 0);
}
// ...the config part is done, now the calculating and sending part
void DShotRMT::send_dshot_value(uint16_t throttle_value, telemetric_request_t telemetric_request)
{
@ -247,6 +182,77 @@ uint16_t DShotRMT::prepare_rmt_data(const dshot_packet_t &dshot_packet)
return prepared_to_encode;
}
void DShotRMT::install_dshot_driver(dshot_mode_t dshot_mode, bool is_bidirectional)
{
dshot_config.mode = dshot_mode;
dshot_config.clk_div = DSHOT_CLK_DIVIDER;
dshot_config.name_str = dshot_mode_name[dshot_mode];
dshot_config.bidirectional = is_bidirectional;
switch (dshot_config.mode)
{
case DSHOT150:
dshot_config.ticks_per_bit = 64; // ...Bit Period Time 6.67 us
dshot_config.ticks_zero_high = 24; // ...zero time 2.50 us
dshot_config.ticks_one_high = 48; // ...one time 5.00 us
break;
case DSHOT300:
dshot_config.ticks_per_bit = 32; // ...Bit Period Time 3.33 us
dshot_config.ticks_zero_high = 12; // ...zero time 1.25 us
dshot_config.ticks_one_high = 24; // ...one time 2.50 us
break;
case DSHOT600:
dshot_config.ticks_per_bit = 16; // ...Bit Period Time 1.67 us
dshot_config.ticks_zero_high = 6; // ...zero time 0.625 us
dshot_config.ticks_one_high = 12; // ...one time 1.25 us
break;
case DSHOT1200:
dshot_config.ticks_per_bit = 8; // ...Bit Period Time 0.83 us
dshot_config.ticks_zero_high = 3; // ...zero time 0.313 us
dshot_config.ticks_one_high = 6; // ...one time 0.625 us
break;
// ...because having a default is "good style"
default:
dshot_config.ticks_per_bit = 0; // ...Bit Period Time endless
dshot_config.ticks_zero_high = 0; // ...no bits, no time
dshot_config.ticks_one_high = 0; // ......no bits, no time
break;
}
// ...calc low signal timing
dshot_config.ticks_zero_low = (dshot_config.ticks_per_bit - dshot_config.ticks_zero_high);
dshot_config.ticks_one_low = (dshot_config.ticks_per_bit - dshot_config.ticks_one_high);
dshot_tx_rmt_config.rmt_mode = RMT_MODE_TX;
dshot_tx_rmt_config.channel = dshot_config.rmt_channel;
dshot_tx_rmt_config.gpio_num = dshot_config.gpio_num;
dshot_tx_rmt_config.mem_block_num = dshot_config.mem_block_num;
dshot_tx_rmt_config.clk_div = dshot_config.clk_div;
dshot_tx_rmt_config.tx_config.loop_en = false;
dshot_tx_rmt_config.tx_config.carrier_en = false;
dshot_tx_rmt_config.tx_config.idle_output_en = true;
if (dshot_config.bidirectional)
{
dshot_tx_rmt_config.tx_config.idle_level = RMT_IDLE_LEVEL_HIGH;
}
else
{
dshot_tx_rmt_config.tx_config.idle_level = RMT_IDLE_LEVEL_LOW;
}
// ...setup selected dshot mode
rmt_config(&dshot_tx_rmt_config);
// ...essential step, install rmt driver
rmt_driver_install(dshot_tx_rmt_config.channel, 0, 0);
}
// ...finally output using ESP32 RMT
void DShotRMT::output_rmt_data(const dshot_packet_t &dshot_packet)
{

View File

@ -4,20 +4,15 @@
// Author: derdoktor667
//
#ifndef _DSHOTRMT_h
#define _DSHOTRMT_h
#pragma once
#if defined(ARDUINO) && ARDUINO >= 100
#include <Arduino.h>
#else
#include "WProgram.h"
#endif
// ...utilizing the RMT Module library for generating the DShot signal
#include <driver/rmt.h>
// ...unify versioning
constexpr auto DSHOT_LIB_VERSION = "0.2.2";
constexpr auto DSHOT_LIB_VERSION = "0.2.3";
constexpr auto DSHOT_CLK_DIVIDER = 8; // ...slow down RMT clock to 0.1 microseconds / 100 nanoseconds per cycle
constexpr auto DSHOT_PACKET_LENGTH = 17; // ...last pack is the pause
@ -94,13 +89,12 @@ typedef struct dshot_config_s
class DShotRMT
{
public:
DShotRMT(gpio_num_t gpio, rmt_channel_t rmtChannel);
DShotRMT(uint8_t pin, uint8_t channel);
DShotRMT(gpio_num_t gpio, rmt_channel_t rmtChannel, dshot_mode_t dshot_mode, bool is_bidirectional);
DShotRMT(uint8_t pin, uint8_t channel, dshot_mode_t dshot_mode, bool is_bidirectional);
~DShotRMT();
DShotRMT(DShotRMT const &);
// ...safety first ...no parameters, no DShot
bool begin(dshot_mode_t dshot_mode = DSHOT_OFF, bool is_bidirectional = false);
void send_dshot_value(uint16_t throttle_value, telemetric_request_t telemetric_request = NO_TELEMETRIC);
dshot_config_t *get_dshot_info();
@ -115,7 +109,6 @@ private:
uint16_t calc_dshot_chksum(const dshot_packet_t &dshot_packet);
uint16_t prepare_rmt_data(const dshot_packet_t &dshot_packet);
void install_dshot_driver(dshot_mode_t dshot_mode, bool is_bidirectional);
void output_rmt_data(const dshot_packet_t &dshot_packet);
};
#endif