Skip to content

Commit

Permalink
dshot: check for bad pulses and handle wrap correctly
Browse files Browse the repository at this point in the history
this ensures we handle timer wrap correctly, fixing bad dshot frames
with ArduPilot, and also checks for much too narrow or wide pulses

by making variables static this also saves flash and ram. Using
REF_F031 as the benchmark we get:

current REF_F031:

Memory region         Used Size  Region Size  %age Used
            SRAM:          0 GB        192 B      0.00%
             RAM:        3760 B       3904 B     96.31%
    FLASH_VECTAB:         192 B        192 B    100.00%
   FLASH_VERSION:          16 B         16 B    100.00%
           FLASH:       23260 B      27408 B     84.87%
       FILE_NAME:          32 B         32 B    100.00%
          EEPROM:          0 GB         1 KB      0.00%

with this PR:

Memory region         Used Size  Region Size  %age Used
            SRAM:          0 GB        192 B      0.00%
             RAM:        3704 B       3904 B     94.88%
    FLASH_VECTAB:         192 B        192 B    100.00%
   FLASH_VERSION:          16 B         16 B    100.00%
           FLASH:       23244 B      27408 B     84.81%
       FILE_NAME:          32 B         32 B    100.00%
          EEPROM:          0 GB         1 KB      0.00%

so we save 54 bytes of ram and 16 bytes of flash, while fixing the
wrap issue and adding pulse width checks
  • Loading branch information
tridge committed Sep 28, 2024
1 parent 97f0d66 commit 51320bd
Showing 1 changed file with 25 additions and 23 deletions.
48 changes: 25 additions & 23 deletions Src/dshot.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,45 +12,47 @@
#include "sounds.h"
#include "targets.h"

int dpulse[16] = { 0 };
static uint8_t dpulse[16];

const char gcr_encode_table[16] = {
static const uint8_t gcr_encode_table[16] = {
0b11001, 0b11011, 0b10010, 0b10011, 0b11101, 0b10101, 0b10110, 0b10111,
0b11010, 0b01001, 0b01010, 0b01011, 0b11110, 0b01101, 0b01110, 0b01111
};

char EDT_ARM_ENABLE = 0;
char EDT_ARMED = 0;
int shift_amount = 0;
uint32_t gcrnumber;
char EDT_ARM_ENABLE;
char EDT_ARMED;
static int shift_amount;
static uint32_t gcrnumber;
extern int zero_crosses;
extern char send_telemetry;
extern uint8_t max_duty_cycle_change;
int dshot_full_number;
static uint32_t dshot_full_number;
extern char play_tone_flag;
uint8_t command_count = 0;
uint8_t last_command = 0;
uint8_t high_pin_count = 0;
uint32_t gcr[37] = { 0 };
uint16_t dshot_frametime;
uint16_t dshot_goodcounts;
uint16_t dshot_badcounts;
char dshot_extended_telemetry = 0;
uint16_t send_extended_dshot = 0;
uint16_t processtime = 0;
uint16_t halfpulsetime = 0;
static uint8_t command_count;
static uint8_t last_command;
static uint8_t high_pin_count;
uint32_t gcr[37];
static uint16_t dshot_frametime;
static uint16_t dshot_goodcounts;
static uint16_t dshot_badcounts;
char dshot_extended_telemetry;
uint16_t send_extended_dshot;
static uint16_t halfpulsetime;

void computeDshotDMA()
{
dshot_frametime = dma_buffer[31] - dma_buffer[0];
halfpulsetime = dshot_frametime >> 5;
if ((dshot_frametime > dshot_frametime_low) && (dshot_frametime < dshot_frametime_high)) {
signaltimeout = 0;
signaltimeout = 0;
for (int i = 0; i < 16; i++) {
// note that dma_buffer[] is uint32_t, we cast the difference to uint16_t to handle
// timer wrap correctly
const uint16_t pdiff = dma_buffer[(i << 1) + 1] - dma_buffer[(i << 1)];
dpulse[i] = (pdiff > halfpulsetime);
const uint16_t pwidth = dma_buffer[(i << 1) + 1] - dma_buffer[(i << 1)];
if (pwidth < (halfpulsetime>>1) || pwidth > (halfpulsetime<<1)) {
// pulse width way off, bad frame
dshot_badcounts++;
return;
}
dpulse[i] = (pwidth > halfpulsetime);
}
uint8_t calcCRC = ((dpulse[0] ^ dpulse[4] ^ dpulse[8]) << 3 | (dpulse[1] ^ dpulse[5] ^ dpulse[9]) << 2 | (dpulse[2] ^ dpulse[6] ^ dpulse[10]) << 1 | (dpulse[3] ^ dpulse[7] ^ dpulse[11]));
uint8_t checkCRC = (dpulse[12] << 3 | dpulse[13] << 2 | dpulse[14] << 1 | dpulse[15]);
Expand Down

0 comments on commit 51320bd

Please sign in to comment.