...cosmetics
This commit is contained in:
parent
295d5e6571
commit
85814f39be
|
|
@ -10,3 +10,6 @@
|
|||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
# Caching ESP32 Builds
|
||||
buildCache/*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {}
|
||||
}
|
||||
|
|
@ -14,7 +14,8 @@ DShotRMT dshot_01(GPIO_NUM_4, RMT_CHANNEL_0);
|
|||
volatile uint16_t throttle_value = 0x30; // ...sending "48", the first throttle value
|
||||
constexpr auto FAILSAVE_THROTTLE = 0x3E7;
|
||||
|
||||
void setup() {
|
||||
void setup()
|
||||
{
|
||||
// ...always start the onboard usb support
|
||||
USB_Serial.begin(USB_SERIAL_BAUD);
|
||||
|
||||
|
|
@ -22,7 +23,8 @@ void setup() {
|
|||
dshot_01.begin(DSHOT300);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
void loop()
|
||||
{
|
||||
read_SerialThrottle();
|
||||
|
||||
dshot_01.send_dshot_value(throttle_value);
|
||||
|
|
@ -33,11 +35,15 @@ void loop() {
|
|||
|
||||
//
|
||||
//
|
||||
uint16_t read_SerialThrottle() {
|
||||
if (USB_Serial.available() > 0) {
|
||||
uint16_t read_SerialThrottle()
|
||||
{
|
||||
if (USB_Serial.available() > 0)
|
||||
{
|
||||
auto throttle_input = (USB_Serial.readStringUntil('\n')).toInt();
|
||||
return throttle_input;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return FAILSAVE_THROTTLE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
name=DShotRMT
|
||||
version=0.2.0
|
||||
version=0.2.1
|
||||
author=derdoktor667
|
||||
maintainer=derdoktor667
|
||||
sentence=DShotRMT Library supporting all DShot Types and speeds. Tested with BlHeli_S.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@
|
|||
// Source: https://github.com/bitdump/BLHeli/blob/master/BLHeli_S%20SiLabs/Dshotprog%20spec%20BLHeli_S.txt
|
||||
// Date: 04.07.2021
|
||||
|
||||
enum dshot_cmd_t {
|
||||
enum dshot_cmd_t
|
||||
{
|
||||
DSHOT_CMD_MOTOR_STOP, // Currently not implemented - STOP Motors
|
||||
DSHOT_CMD_BEEP1, // Wait at least length of beep (380ms) before next command
|
||||
DSHOT_CMD_BEEP2, // Wait at least length of beep (380ms) before next command
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@
|
|||
|
||||
#include "DShotRMT.h"
|
||||
|
||||
DShotRMT::DShotRMT(gpio_num_t gpio, rmt_channel_t rmtChannel) {
|
||||
DShotRMT::DShotRMT(gpio_num_t gpio, rmt_channel_t rmtChannel)
|
||||
{
|
||||
dshot_config.gpio_num = gpio;
|
||||
dshot_config.pin_num = uint8_t(gpio);
|
||||
dshot_config.rmt_channel = rmtChannel;
|
||||
|
|
@ -16,7 +17,8 @@ DShotRMT::DShotRMT(gpio_num_t gpio, rmt_channel_t rmtChannel) {
|
|||
encode_dshot_to_rmt(DSHOT_NULL_PACKET);
|
||||
}
|
||||
|
||||
DShotRMT::DShotRMT(uint8_t pin, uint8_t channel) {
|
||||
DShotRMT::DShotRMT(uint8_t pin, uint8_t channel)
|
||||
{
|
||||
dshot_config.gpio_num = gpio_num_t(pin);
|
||||
dshot_config.pin_num = pin;
|
||||
dshot_config.rmt_channel = rmt_channel_t(channel);
|
||||
|
|
@ -26,21 +28,25 @@ DShotRMT::DShotRMT(uint8_t pin, uint8_t channel) {
|
|||
encode_dshot_to_rmt(DSHOT_NULL_PACKET);
|
||||
}
|
||||
|
||||
DShotRMT::~DShotRMT() {
|
||||
DShotRMT::~DShotRMT()
|
||||
{
|
||||
rmt_driver_uninstall(dshot_config.rmt_channel);
|
||||
}
|
||||
|
||||
DShotRMT::DShotRMT(DShotRMT const&) {
|
||||
DShotRMT::DShotRMT(DShotRMT const &)
|
||||
{
|
||||
// ...write me
|
||||
}
|
||||
|
||||
bool DShotRMT::begin(dshot_mode_t dshot_mode, bool is_bidirectional) {
|
||||
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) {
|
||||
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
|
||||
|
|
@ -87,9 +93,12 @@ bool DShotRMT::begin(dshot_mode_t dshot_mode, bool is_bidirectional) {
|
|||
dshot_tx_rmt_config.tx_config.carrier_en = false;
|
||||
dshot_tx_rmt_config.tx_config.idle_output_en = true;
|
||||
|
||||
if (dshot_config.bidirectional) {
|
||||
if (dshot_config.bidirectional)
|
||||
{
|
||||
dshot_tx_rmt_config.tx_config.idle_level = RMT_IDLE_LEVEL_HIGH;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dshot_tx_rmt_config.tx_config.idle_level = RMT_IDLE_LEVEL_LOW;
|
||||
}
|
||||
|
||||
|
|
@ -101,14 +110,17 @@ bool DShotRMT::begin(dshot_mode_t dshot_mode, bool is_bidirectional) {
|
|||
}
|
||||
|
||||
// ...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) {
|
||||
dshot_packet_t dshot_rmt_packet = { };
|
||||
void DShotRMT::send_dshot_value(uint16_t throttle_value, telemetric_request_t telemetric_request)
|
||||
{
|
||||
dshot_packet_t dshot_rmt_packet = {};
|
||||
|
||||
if (throttle_value < DSHOT_THROTTLE_MIN) {
|
||||
if (throttle_value < DSHOT_THROTTLE_MIN)
|
||||
{
|
||||
throttle_value = DSHOT_THROTTLE_MIN;
|
||||
}
|
||||
|
||||
if (throttle_value > DSHOT_THROTTLE_MAX) {
|
||||
if (throttle_value > DSHOT_THROTTLE_MAX)
|
||||
{
|
||||
throttle_value = DSHOT_THROTTLE_MAX;
|
||||
}
|
||||
|
||||
|
|
@ -121,26 +133,33 @@ void DShotRMT::send_dshot_value(uint16_t throttle_value, telemetric_request_t te
|
|||
}
|
||||
|
||||
// ...get all setup data about current mode
|
||||
dshot_config_t* DShotRMT::get_dshot_info() {
|
||||
dshot_config_t *DShotRMT::get_dshot_info()
|
||||
{
|
||||
return &dshot_config;
|
||||
}
|
||||
|
||||
// ...get the ABP_Clock Divider for further calculations
|
||||
uint8_t* DShotRMT::get_dshot_clock_div() {
|
||||
uint8_t *DShotRMT::get_dshot_clock_div()
|
||||
{
|
||||
return &dshot_config.clk_div;
|
||||
}
|
||||
|
||||
rmt_item32_t* DShotRMT::encode_dshot_to_rmt(uint16_t parsed_packet) {
|
||||
rmt_item32_t *DShotRMT::encode_dshot_to_rmt(uint16_t parsed_packet)
|
||||
{
|
||||
// ...is bidirecional mode activated
|
||||
if (dshot_config.bidirectional) {
|
||||
if (dshot_config.bidirectional)
|
||||
{
|
||||
// ..."invert" the signal duration
|
||||
for (int i = 0; i < DSHOT_PAUSE_BIT; i++, parsed_packet <<= 1) {
|
||||
if (parsed_packet & 0b1000000000000000) {
|
||||
for (int i = 0; i < DSHOT_PAUSE_BIT; i++, parsed_packet <<= 1)
|
||||
{
|
||||
if (parsed_packet & 0b1000000000000000)
|
||||
{
|
||||
// set one
|
||||
dshot_tx_rmt_item[i].duration0 = dshot_config.ticks_one_low;
|
||||
dshot_tx_rmt_item[i].duration1 = dshot_config.ticks_one_high;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// set zero
|
||||
dshot_tx_rmt_item[i].duration0 = dshot_config.ticks_zero_low;
|
||||
dshot_tx_rmt_item[i].duration1 = dshot_config.ticks_zero_high;
|
||||
|
|
@ -152,14 +171,18 @@ rmt_item32_t* DShotRMT::encode_dshot_to_rmt(uint16_t parsed_packet) {
|
|||
}
|
||||
|
||||
// ..."normal" DShot mode / "bidirectional" mode OFF
|
||||
else {
|
||||
for (int i = 0; i < DSHOT_PAUSE_BIT; i++, parsed_packet <<= 1) {
|
||||
if (parsed_packet & 0b1000000000000000) {
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < DSHOT_PAUSE_BIT; i++, parsed_packet <<= 1)
|
||||
{
|
||||
if (parsed_packet & 0b1000000000000000)
|
||||
{
|
||||
// set one
|
||||
dshot_tx_rmt_item[i].duration0 = dshot_config.ticks_one_high;
|
||||
dshot_tx_rmt_item[i].duration1 = dshot_config.ticks_one_low;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// set zero
|
||||
dshot_tx_rmt_item[i].duration0 = dshot_config.ticks_zero_high;
|
||||
dshot_tx_rmt_item[i].duration1 = dshot_config.ticks_zero_low;
|
||||
|
|
@ -170,10 +193,13 @@ rmt_item32_t* DShotRMT::encode_dshot_to_rmt(uint16_t parsed_packet) {
|
|||
}
|
||||
}
|
||||
|
||||
if (dshot_config.bidirectional) {
|
||||
if (dshot_config.bidirectional)
|
||||
{
|
||||
dshot_tx_rmt_item[DSHOT_PAUSE_BIT].level0 = 1;
|
||||
dshot_tx_rmt_item[DSHOT_PAUSE_BIT].level1 = 0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dshot_tx_rmt_item[DSHOT_PAUSE_BIT].level0 = 0;
|
||||
dshot_tx_rmt_item[DSHOT_PAUSE_BIT].level1 = 1;
|
||||
}
|
||||
|
|
@ -186,7 +212,8 @@ rmt_item32_t* DShotRMT::encode_dshot_to_rmt(uint16_t parsed_packet) {
|
|||
|
||||
// ...just returns the checksum
|
||||
// DOES NOT APPEND CHECKSUM!!!
|
||||
uint16_t DShotRMT::calc_dshot_chksum(const dshot_packet_t& dshot_packet) {
|
||||
uint16_t DShotRMT::calc_dshot_chksum(const dshot_packet_t &dshot_packet)
|
||||
{
|
||||
// ...start with two emprty "container"
|
||||
uint16_t packet = DSHOT_NULL_PACKET;
|
||||
uint16_t chksum = DSHOT_NULL_PACKET;
|
||||
|
|
@ -194,10 +221,13 @@ uint16_t DShotRMT::calc_dshot_chksum(const dshot_packet_t& dshot_packet) {
|
|||
// ...same initial 12bit data for bidirectional or "normal" mode
|
||||
packet = (dshot_packet.throttle_value << 1) | dshot_packet.telemetric_request;
|
||||
|
||||
if (dshot_config.bidirectional) {
|
||||
if (dshot_config.bidirectional)
|
||||
{
|
||||
// ...calc the checksum "inverted" / bidirectional mode
|
||||
chksum = (~(packet ^ (packet >> 4) ^ (packet >> 8))) & 0x0F;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// ...calc the checksum "normal" mode
|
||||
chksum = (packet ^ (packet >> 4) ^ (packet >> 8)) & 0x0F;
|
||||
}
|
||||
|
|
@ -205,7 +235,8 @@ uint16_t DShotRMT::calc_dshot_chksum(const dshot_packet_t& dshot_packet) {
|
|||
return chksum;
|
||||
}
|
||||
|
||||
uint16_t DShotRMT::prepare_rmt_data(const dshot_packet_t &dshot_packet) {
|
||||
uint16_t DShotRMT::prepare_rmt_data(const dshot_packet_t &dshot_packet)
|
||||
{
|
||||
uint16_t prepared_to_encode = DSHOT_NULL_PACKET;
|
||||
uint16_t chksum = calc_dshot_chksum(dshot_packet);
|
||||
|
||||
|
|
@ -217,7 +248,8 @@ uint16_t DShotRMT::prepare_rmt_data(const dshot_packet_t &dshot_packet) {
|
|||
}
|
||||
|
||||
// ...finally output using ESP32 RMT
|
||||
void DShotRMT::output_rmt_data(const dshot_packet_t &dshot_packet) {
|
||||
void DShotRMT::output_rmt_data(const dshot_packet_t &dshot_packet)
|
||||
{
|
||||
encode_dshot_to_rmt(prepare_rmt_data(dshot_packet));
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "BlheliCmdMap.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
// ...utilizing the IR Module library for generating the DShot signal
|
||||
#include <driver/rmt.h>
|
||||
|
|
@ -26,7 +26,8 @@ constexpr auto F_CPU_RMT = APB_CLK_FREQ;
|
|||
constexpr auto RMT_CYCLES_PER_SEC = (F_CPU_RMT / DSHOT_CLK_DIVIDER);
|
||||
constexpr auto RMT_CYCLES_PER_ESP_CYCLE = (F_CPU / RMT_CYCLES_PER_SEC);
|
||||
|
||||
typedef enum dshot_mode_e {
|
||||
typedef enum dshot_mode_e
|
||||
{
|
||||
DSHOT_OFF,
|
||||
DSHOT150,
|
||||
DSHOT300,
|
||||
|
|
@ -35,36 +36,39 @@ typedef enum dshot_mode_e {
|
|||
} dshot_mode_t;
|
||||
|
||||
// ...to get human readable DShot Mode
|
||||
static const char* const dshot_mode_name[] = {
|
||||
static const char *const dshot_mode_name[] = {
|
||||
"DSHOT_OFF",
|
||||
"DSHOT150",
|
||||
"DSHOT300",
|
||||
"DSHOT600",
|
||||
"DSHOT1200"
|
||||
};
|
||||
"DSHOT1200"};
|
||||
|
||||
typedef String dshot_name_t;
|
||||
|
||||
typedef enum telemetric_request_e {
|
||||
typedef enum telemetric_request_e
|
||||
{
|
||||
NO_TELEMETRIC,
|
||||
ENABLE_TELEMETRIC,
|
||||
} telemetric_request_t;
|
||||
|
||||
// ...set bitcount for DShot packet
|
||||
typedef struct dshot_packet_s {
|
||||
typedef struct dshot_packet_s
|
||||
{
|
||||
uint16_t throttle_value : 11;
|
||||
telemetric_request_t telemetric_request : 1;
|
||||
uint16_t checksum : 4;
|
||||
} dshot_packet_t;
|
||||
|
||||
// ...set bitcount for eRPM packet
|
||||
typedef struct eRPM_packet_s {
|
||||
typedef struct eRPM_packet_s
|
||||
{
|
||||
uint16_t eRPM_data : 12;
|
||||
uint8_t checksum : 4;
|
||||
} eRPM_packet_t;
|
||||
|
||||
// ...all settings for the dshot mode
|
||||
typedef struct dshot_config_s {
|
||||
typedef struct dshot_config_s
|
||||
{
|
||||
dshot_mode_t mode;
|
||||
dshot_name_t name_str;
|
||||
bool bidirectional;
|
||||
|
|
@ -80,12 +84,13 @@ typedef struct dshot_config_s {
|
|||
uint16_t ticks_one_low;
|
||||
} dshot_config_t;
|
||||
|
||||
class DShotRMT {
|
||||
public:
|
||||
class DShotRMT
|
||||
{
|
||||
public:
|
||||
DShotRMT(gpio_num_t gpio, rmt_channel_t rmtChannel);
|
||||
DShotRMT(uint8_t pin, uint8_t channel);
|
||||
~DShotRMT();
|
||||
DShotRMT(DShotRMT const&);
|
||||
DShotRMT(DShotRMT const &);
|
||||
|
||||
// ...safety first ...no parameters, no DShot
|
||||
bool begin(dshot_mode_t dshot_mode = DSHOT_OFF, bool is_bidirectional = false);
|
||||
|
|
@ -94,7 +99,7 @@ class DShotRMT {
|
|||
dshot_config_t *get_dshot_info();
|
||||
uint8_t *get_dshot_clock_div();
|
||||
|
||||
private:
|
||||
private:
|
||||
rmt_item32_t dshot_tx_rmt_item[DSHOT_PACKET_LENGTH];
|
||||
rmt_config_t dshot_tx_rmt_config;
|
||||
dshot_config_t dshot_config;
|
||||
|
|
|
|||
Loading…
Reference in New Issue