Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code refactor #137

Merged
merged 32 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
a3be921
move Controller to Control namespace
rtlopez Oct 30, 2024
cbedb0e
move Fusion to Control namespace
rtlopez Oct 30, 2024
d8bb20b
move Actuator to Control namespace and split
rtlopez Oct 30, 2024
e816b91
AccelSensor split
rtlopez Oct 30, 2024
6abae4a
split baro, mag and voltage sensors
rtlopez Oct 31, 2024
59afc64
split hardware unit
rtlopez Nov 2, 2024
dfc8348
split buzzer
rtlopez Nov 2, 2024
6156bde
remove unittest defines
rtlopez Nov 2, 2024
10dcd76
move filter to utils namespace
rtlopez Nov 2, 2024
eb7f048
move timer to utils, drop timer dependency in escdriver
rtlopez Nov 3, 2024
5c53a61
move stats to utils namespace
rtlopez Nov 3, 2024
7e5f8f9
move msp to connect
rtlopez Nov 4, 2024
3be19d0
move cli to connect ns
rtlopez Nov 4, 2024
6ff81a9
move and split storage
rtlopez Nov 4, 2024
c779041
move logger to utils + remove deprecated Model::isActive()
rtlopez Nov 4, 2024
8a784bc
split telemetry and wireless
rtlopez Nov 5, 2024
f2675d5
cleanup headers
rtlopez Nov 5, 2024
147940f
split and move sma and freq analyzers
rtlopez Nov 7, 2024
7941be5
move Math/Bits.h to Utils
rtlopez Nov 8, 2024
45c26eb
move Crc to Utils
rtlopez Nov 8, 2024
78695cb
move Math to Utils
rtlopez Nov 8, 2024
59f6c85
move buzzer to connect ns
rtlopez Nov 13, 2024
da81079
split msp classes
rtlopez Nov 13, 2024
c33c2e5
msp pragma once
rtlopez Nov 13, 2024
e8c84df
split cli module
rtlopez Nov 14, 2024
cc76de1
loop index type
rtlopez Nov 14, 2024
251d711
move Kalman to AHRS lib
rtlopez Nov 14, 2024
05b675e
split EscDriverBase
rtlopez Nov 22, 2024
1391039
fix esc drivers and pgm imports
rtlopez Nov 23, 2024
6ca59b8
replace typedef with using
rtlopez Jan 14, 2025
9b22cf9
baro tuning
rtlopez Jan 15, 2025
05da2ce
arg type fix
rtlopez Jan 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
File renamed without changes.
6 changes: 3 additions & 3 deletions lib/AHRS/src/helper_3dmath.h
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,6 @@ class RotationMatrix
};
};

typedef VectorBase<float> VectorFloat;
typedef VectorBase<int16_t> VectorInt16;
typedef RotationMatrix<float> RotationMatrixFloat;
using VectorFloat = VectorBase<float>;
using VectorInt16 = VectorBase<int16_t>;
using RotationMatrixFloat = RotationMatrix<float>;
196 changes: 2 additions & 194 deletions lib/EscDriver/src/EscDriver.h
Original file line number Diff line number Diff line change
@@ -1,196 +1,6 @@
#ifndef _ESC_DRIVER_H_
#define _ESC_DRIVER_H_

#include <Arduino.h>

enum EscProtocol {
ESC_PROTOCOL_PWM,
ESC_PROTOCOL_ONESHOT125,
ESC_PROTOCOL_ONESHOT42,
ESC_PROTOCOL_MULTISHOT,
ESC_PROTOCOL_BRUSHED,
ESC_PROTOCOL_DSHOT150,
ESC_PROTOCOL_DSHOT300,
ESC_PROTOCOL_DSHOT600,
ESC_PROTOCOL_PROSHOT,
ESC_PROTOCOL_DISABLED,
ESC_PROTOCOL_COUNT
};

struct EscConfig
{
int timer;
EscProtocol protocol;
int rate;
bool async;
bool dshotTelemetry;
};

#define PWM_TO_DSHOT(v) (((v - 1000) * 2) + 47)
#define ESC_PROTOCOL_SANITIZE(p) (p > ESC_PROTOCOL_DSHOT600 && p != ESC_PROTOCOL_DISABLED ? ESC_PROTOCOL_DSHOT600 : p)

class EscDriverBase
{
public:
#if defined(UNIT_TEST)
int begin(const EscConfig& conf) { return 1; }
void end() {}
int attach(size_t channel, int pin, int pulse) { return 1; }
int write(size_t channel, int pulse) { return 1; }
void apply() {}
int pin(size_t channel) const { return -1; }
uint32_t telemetry(size_t channel) const { return 0; }
#endif
#pragma once

static uint16_t IRAM_ATTR dshotConvert(uint16_t pulse)
{
return pulse > 1000 ? PWM_TO_DSHOT(pulse) : 0;
}

static uint16_t IRAM_ATTR dshotEncode(uint16_t value, bool inverted = false)
{
value <<= 1;

// compute checksum
int csum = 0;
int csum_data = value;
for (int i = 0; i < 3; i++)
{
csum ^= csum_data; // xor
csum_data >>= 4;
}
if(inverted)
{
csum = ~csum;
}
csum &= 0xf;

return (value << 4) | csum;
}

static uint32_t IRAM_ATTR durationToBitLen(uint32_t duration, uint32_t len)
{
return (duration + (len >> 1)) / len;
}

static uint32_t IRAM_ATTR pushBits(uint32_t value, uint32_t bitVal, size_t bitLen)
{
while(bitLen--)
{
value <<= 1;
value |= bitVal;
}
return value;
}

/**
* @param data expected data layout (bits): duration0(15), level0(1), duration(15), level1(1)
* @param len number of data items
* @param bitLen duration of single bit
* @return uint32_t raw gcr value
*/
static uint32_t IRAM_ATTR extractTelemetryGcr(uint32_t* data, size_t len, uint32_t bitLen)
{
int bitCount = 0;
uint32_t value = 0;
for(size_t i = 0; i < len; i++)
{
uint32_t duration0 = data[i] & 0x7fff;
if(!duration0) break;
uint32_t level0 = (data[i] >> 15) & 0x01;
uint32_t len0 = durationToBitLen(duration0, bitLen);
if(len0)
{
value = pushBits(value, level0, len0);
bitCount += len0;
}

uint32_t duration1 = (data[i] >> 16) & 0x7fff;
if(!duration1) break;
uint32_t level1 = (data[i] >> 31) & 0x01;
uint32_t len1 = durationToBitLen(duration1, bitLen);
if(len1)
{
value = pushBits(value, level1, len1);
bitCount += len1;
}
}

// fill missing bits with 1
if(bitCount < 21)
{
value = pushBits(value, 0x1, 21 - bitCount);
}

return value;
}

static constexpr uint32_t INVALID_TELEMETRY_VALUE = 0xffff;
static constexpr int SECONDS_PER_MINUTE = 60;
static constexpr float ERPM_PER_LSB = 100.0f;

static float IRAM_ATTR getErpmToHzRatio(int poles)
{
return ERPM_PER_LSB / SECONDS_PER_MINUTE / (poles / 2.0f);
}

static uint32_t IRAM_ATTR convertToErpm(uint32_t value)
{
if(!value) return 0;

if(!value || value == INVALID_TELEMETRY_VALUE)
{
return INVALID_TELEMETRY_VALUE;
}

// Convert period to erpm * 100
return (1000000 * 60 / 100 + value / 2) / value;
}

static uint32_t IRAM_ATTR convertToValue(uint32_t value)
{
// eRPM range
if(value == 0x0fff)
{
return 0;
}

// Convert value to 16 bit from the GCR telemetry format (eeem mmmm mmmm)
return (value & 0x01ff) << ((value & 0xfe00) >> 9);
}

static uint32_t IRAM_ATTR gcrToRawValue(uint32_t value)
{
value = value ^ (value >> 1); // extract gcr

constexpr uint32_t iv = 0xffffffff; // invalid code
// First bit is start bit so discard it.
value &= 0xfffff;
static const uint32_t decode[32] = {
iv, iv, iv, iv, iv, iv, iv, iv, iv, 9, 10, 11, iv, 13, 14, 15,
iv, iv, 2, 3, iv, 5, 6, 7, iv, 0, 8, 1, iv, 4, 12, iv,
};

uint32_t decodedValue = decode[value & 0x1f];
decodedValue |= decode[(value >> 5) & 0x1f] << 4;
decodedValue |= decode[(value >> 10) & 0x1f] << 8;
decodedValue |= decode[(value >> 15) & 0x1f] << 12;

uint32_t csum = decodedValue;
csum = csum ^ (csum >> 8); // xor bytes
csum = csum ^ (csum >> 4); // xor nibbles

if((csum & 0xf) != 0xf || decodedValue > 0xffff)
{
return INVALID_TELEMETRY_VALUE;
}
value = decodedValue >> 4;

return value;
}

static const size_t DSHOT_BIT_COUNT = 16;
};
#include "EscDriverBase.hpp"

#if defined(ESP8266)

Expand Down Expand Up @@ -250,5 +60,3 @@ class EscDriverBase
#error "Unsupported platform"

#endif

#endif
146 changes: 146 additions & 0 deletions lib/EscDriver/src/EscDriverBase.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#include "EscDriverBase.hpp"
#include <Arduino.h>

uint16_t IRAM_ATTR EscDriverBase::dshotConvert(uint16_t pulse)
{
return pulse > 1000 ? PWM_TO_DSHOT(pulse) : 0;
}

uint16_t IRAM_ATTR EscDriverBase::dshotEncode(uint16_t value, bool inverted)
{
value <<= 1;

// compute checksum
int csum = 0;
int csum_data = value;
for (int i = 0; i < 3; i++)
{
csum ^= csum_data; // xor
csum_data >>= 4;
}
if(inverted)
{
csum = ~csum;
}
csum &= 0xf;

return (value << 4) | csum;
}

uint32_t IRAM_ATTR EscDriverBase::durationToBitLen(uint32_t duration, uint32_t len)
{
return (duration + (len >> 1)) / len;
}

uint32_t IRAM_ATTR EscDriverBase::pushBits(uint32_t value, uint32_t bitVal, size_t bitLen)
{
while(bitLen--)
{
value <<= 1;
value |= bitVal;
}
return value;
}

/**
* @param data expected data layout (bits): duration0(15), level0(1), duration(15), level1(1)
* @param len number of data items
* @param bitLen duration of single bit
* @return uint32_t raw gcr value
*/
uint32_t IRAM_ATTR EscDriverBase::extractTelemetryGcr(uint32_t* data, size_t len, uint32_t bitLen)
{
int bitCount = 0;
uint32_t value = 0;
for(size_t i = 0; i < len; i++)
{
uint32_t duration0 = data[i] & 0x7fff;
if(!duration0) break;
uint32_t level0 = (data[i] >> 15) & 0x01;
uint32_t len0 = durationToBitLen(duration0, bitLen);
if(len0)
{
value = pushBits(value, level0, len0);
bitCount += len0;
}

uint32_t duration1 = (data[i] >> 16) & 0x7fff;
if(!duration1) break;
uint32_t level1 = (data[i] >> 31) & 0x01;
uint32_t len1 = durationToBitLen(duration1, bitLen);
if(len1)
{
value = pushBits(value, level1, len1);
bitCount += len1;
}
}

// fill missing bits with 1
if(bitCount < 21)
{
value = pushBits(value, 0x1, 21 - bitCount);
}

return value;
}

float IRAM_ATTR EscDriverBase::getErpmToHzRatio(int poles)
{
return ERPM_PER_LSB / SECONDS_PER_MINUTE / (poles / 2.0f);
}

uint32_t IRAM_ATTR EscDriverBase::convertToErpm(uint32_t value)
{
if(!value) return 0;

if(!value || value == INVALID_TELEMETRY_VALUE)
{
return INVALID_TELEMETRY_VALUE;
}

// Convert period to erpm * 100
return (1000000 * 60 / 100 + value / 2) / value;
}

uint32_t IRAM_ATTR EscDriverBase::convertToValue(uint32_t value)
{
// eRPM range
if(value == 0x0fff)
{
return 0;
}

// Convert value to 16 bit from the GCR telemetry format (eeem mmmm mmmm)
return (value & 0x01ff) << ((value & 0xfe00) >> 9);
}

uint32_t IRAM_ATTR EscDriverBase::gcrToRawValue(uint32_t value)
{
value = value ^ (value >> 1); // extract gcr

constexpr uint32_t iv = 0xffffffff; // invalid code
// First bit is start bit so discard it.
value &= 0xfffff;
static const uint32_t decode[32] = {
iv, iv, iv, iv, iv, iv, iv, iv, iv, 9, 10, 11, iv, 13, 14, 15,
iv, iv, 2, 3, iv, 5, 6, 7, iv, 0, 8, 1, iv, 4, 12, iv,
};

uint32_t decodedValue = decode[value & 0x1f];
decodedValue |= decode[(value >> 5) & 0x1f] << 4;
decodedValue |= decode[(value >> 10) & 0x1f] << 8;
decodedValue |= decode[(value >> 15) & 0x1f] << 12;

uint32_t csum = decodedValue;
csum = csum ^ (csum >> 8); // xor bytes
csum = csum ^ (csum >> 4); // xor nibbles

if((csum & 0xf) != 0xf || decodedValue > 0xffff)
{
return INVALID_TELEMETRY_VALUE;
}
value = decodedValue >> 4;

return value;
}

Loading