8 #error dynamic dshot speed is not yet implemented in DSHOT BIDIR
12 static const float TIM_FREQ_MHZ = (STM32_TIMCLK1 / 1e6d);
27 #define SWTICH_TO_CAPTURE_BASE_TIMOUT 38U
28 #elif defined STM32F7XX
29 #define SWTICH_TO_CAPTURE_BASE_TIMOUT 32U
31 #define SWTICH_TO_CAPTURE_BASE_TIMOUT 28U
41 static void gptCb(GPTDriver *gptd);
45 static volatile uint32_t dmaErrs = 0;
48 #if !defined __GNUC__ || __GNUC__ < 13
59 TIM_DIER_CC1DE | TIM_DIER_TDE},
61 TIM_DIER_CC1DE | TIM_DIER_CC2DE | TIM_DIER_TDE},
63 TIM_DIER_CC1DE | TIM_DIER_CC2DE | TIM_DIER_CC3DE | TIM_DIER_TDE},
65 TIM_DIER_CC1DE | TIM_DIER_CC2DE | TIM_DIER_CC3DE | TIM_DIER_CC4DE | TIM_DIER_TDE}
85 #ifndef GPT_DRIVER_EXT_FIELDS
86 #error dshot rpmcapture driver involve defining #define GPT_DRIVER_EXT_FIELDS void *user_data; in halconf.h
89 #define GPT_DRIVER_EXT_FIELDS void *user_data;
93 .frequency = 1000U * 1000U,
111 memset(drcp, 0,
sizeof(*drcp));
152 static systime_t ts = 0;
154 ts = chVTGetSystemTimeX();
172 chThdSuspendS(&drcp->
dmads[0].thread);
184 const rtcnt_t tstart = chSysGetRealtimeCounterX();
189 if (drcp->
config->dcache_memory_in_use ==
true) {
199 const rtcnt_t tstop = chSysGetRealtimeCounterX();
201 drcp->accumDecodeTime += (tstop - tstart);
204 #if defined(DFREQ) && (DFREQ < 10) && (DFREQ != 0)
205 DebugTrace(
"dma out on %s",
msg == MSG_OK ?
"completion" :
"timeout");
220 if ((index != 0xff) && (index != i))
254 #if STM32_DMA_SUPPORTS_DMAMUX
259 .inc_peripheral_addr =
false,
260 .inc_memory_addr =
true,
265 #if STM32_DMA_USE_ASYNC_TIMOUT
266 .timeout = TIME_MS2I(100),
276 .periph_inc_size_4 =
false,
277 .transfert_end_ctrl_by_periph =
false
283 #if STM32_DMA_SUPPORTS_DMAMUX
302 cfg->
gptd->user_data = drcp;
349 static const size_t frameLen = 20U;
351 uint_fast8_t bit = 0x0;
352 uint_fast8_t bitIndex = 0;
353 uint_fast16_t prec = capture[0];
355 for (
size_t i = 1U; i < dmaLen; i++) {
356 const uint_fast16_t len = capture[i] - prec;
363 switch(nbConsecutives) {
364 case 1U: erpsVal |= (0b001 << (frameLen - bitIndex));
break;
365 case 2U: erpsVal |= (0b011 << (frameLen - bitIndex - 1U));
break;
366 default: erpsVal |= (0b111 << (frameLen - bitIndex - 2U));
break;
370 bitIndex += nbConsecutives;
373 for (
size_t j=bitIndex; j <= frameLen; j++)
374 erpsVal |= (1U << (frameLen - j));
418 chThdResumeI(&drcd->
dmads[0].thread, MSG_TIMEOUT);
419 chSysUnlockFromISR();
static const uint32_t ERPS_BIT1_DUTY
static uint32_t processErpsDmaBuffer(const uint16_t *capture, size_t dmaLen)
convert DMA buffer full of pulse length into raw ERPS frame
static const uint32_t TIM_PRESCALER
static void buildDmaConfig(DshotRpmCapture *drcp)
build dma configuration structure
static void gptCb(GPTDriver *gptd)
dma timeout ISR :
void dshotRpmCaptureStart(DshotRpmCapture *drcp, const DshotRpmCaptureConfig *cfg, stm32_tim_t *timer)
Configures and activates the DSHOT ERPS CAPTURE driver.
static void dmaErrCb(DMADriver *dmad, dmaerrormask_t em)
dma error ISR :
static const GPTConfig gptCfg
static void startCapture(DshotRpmCapture *drcp)
start the DMA capture
static const struct @5 activeDier[4]
static const float bit1t_us
void dshotRpmCatchErps(DshotRpmCapture *drcp)
capture the DSHOT ERPS frame(s) : one frame for each DSHOT_CHANNELS
static const TimICConfig timicCfgSkel
static const float TIM_FREQ_MHZ
void dshotRpmCaptureStop(DshotRpmCapture *drcp)
stop the the DSHOT ERPS CAPTURE driver.
static void initCache(DshotRpmCapture *drcp)
build dma and timer registers cache
#define SWTICH_TO_CAPTURE_BASE_TIMOUT
static void stopCapture(DshotRpmCapture *drcp)
stop the DMA capture
static const float speed_factor
DshotDmaStreamChan dma_streams[DSHOT_CHANNELS]
: array of DMA stream for each capture channel
TimICDriver icd
: input capture timer driver
DMADriver dmads[DSHOT_CHANNELS]
: dma input capture drivers
#define DSHOT_DMA_EXTRADATA_LEN
TimICConfig icCfg
: input capture timer configuration
const DshotRpmCaptureConfig * config
: pointer to configuration structure
TimerDmaCache cache
: cache for timer and dma configuration
uint32_t rpms[DSHOT_CHANNELS]
: array of rpms
DshotRpmCaptureOneChannelDmaBuffer dma_buf[DSHOT_CHANNELS]
DshotRpmCaptureDmaBuffer * dma_capture
: pointer to the input capture DMA buffer
uint16_t buf[DSHOT_DMA_DATA_LEN+DSHOT_DMA_EXTRADATA_LEN]
DMAConfig dmaCfgs[DSHOT_CHANNELS]
: dma input capture configuration
#define DSHOT_DMA_DATA_LEN
GPTDriver * gptd
: GPT Driver to manage microseconds timeout
: DSHOT Rpm Capture Driver configuration structure.
#define DSHOT_SPEED
Base freq of DSHOT signal (in kHz) Possible values are: 150, 300, 600.
void chprintf(BaseSequentialStream *lchp, const char *fmt,...)
void dmaObjectInit(DMADriver *dmap)
bool dmaStartTransfert(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size)
Starts a DMA transaction.
void dmaStopTransfertI(DMADriver *dmap)
Stops an ongoing transaction.
bool dmaStart(DMADriver *dmap, const DMAConfig *cfg)
Configures and activates the DMA peripheral.
@ DMA_ONESHOT
One transert then stop
@ DMA_DIR_P2M
PERIPHERAL to MEMORY
static size_t dmaGetTransactionCounter(DMADriver *dmap)
dmaerrormask_t
Possible DMA failure causes.
uint32_t stream
stream associated with transaction
DMA stream configuration structure.
Structure representing a DMA driver.
uint8_t msg[10]
Buffer used for general comunication over SPI (out buffer)
void timerDmaCache_restore(const TimerDmaCache *tdcp, DMADriver *toDma, stm32_tim_t *toTim)
void timerDmaCache_cache(TimerDmaCache *tdcp, const DMADriver *fromDma, const stm32_tim_t *fromTim)
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.