mirror of
https://github.com/iNavFlight/inav.git
synced 2025-07-24 16:55:29 +03:00
Merge pull request #4235 from iNavFlight/de_timer_fixes
Fixes to timer DMA and DSHOT code
This commit is contained in:
commit
0d0d256073
5 changed files with 30 additions and 9 deletions
|
@ -266,8 +266,11 @@ static uint16_t prepareDshotPacket(const uint16_t value, bool requestTelemetry)
|
|||
return packet;
|
||||
}
|
||||
|
||||
void pwmCompleteDshotUpdate(uint8_t motorCount, timeUs_t currentTimeUs)
|
||||
void pwmCompleteDshotUpdate(uint8_t motorCount)
|
||||
{
|
||||
// Get latest REAL time
|
||||
timeUs_t currentTimeUs = micros();
|
||||
|
||||
// Enforce motor update rate
|
||||
if (!isProtocolDshot || (dshotMotorUpdateIntervalUs == 0) || ((currentTimeUs - dshotMotorLastUpdateUs) <= dshotMotorUpdateIntervalUs)) {
|
||||
return;
|
||||
|
|
|
@ -34,7 +34,7 @@ typedef enum {
|
|||
|
||||
void pwmWriteMotor(uint8_t index, uint16_t value);
|
||||
void pwmShutdownPulsesForAllMotors(uint8_t motorCount);
|
||||
void pwmCompleteDshotUpdate(uint8_t motorCount, timeUs_t currentTimeUs);
|
||||
void pwmCompleteDshotUpdate(uint8_t motorCount);
|
||||
bool isMotorProtocolDshot(void);
|
||||
|
||||
void pwmWriteServo(uint8_t index, uint16_t value);
|
||||
|
|
|
@ -306,7 +306,11 @@ static void impl_timerDMA_IRQHandler(DMA_t descriptor)
|
|||
{
|
||||
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) {
|
||||
TCH_t * tch = (TCH_t *)descriptor->userParam;
|
||||
tch->dmaState = TCH_DMA_IDLE;
|
||||
|
||||
// If it was ACTIVE - switch to IDLE
|
||||
if (tch->dmaState == TCH_DMA_ACTIVE) {
|
||||
tch->dmaState = TCH_DMA_IDLE;
|
||||
}
|
||||
|
||||
LL_DMA_DisableStream(tch->dma->dma, lookupDMALLStreamTable[DMATAG_GET_STREAM(tch->timHw->dmaTag)]);
|
||||
LL_TIM_DisableDMAReq_CCx(tch->timHw->tim, lookupDMASourceTable[tch->timHw->channelIndex]);
|
||||
|
@ -376,15 +380,20 @@ void impl_timerPWMPrepareDMA(TCH_t * tch, uint32_t dmaBufferSize)
|
|||
const uint32_t streamLL = lookupDMALLStreamTable[DMATAG_GET_STREAM(tch->timHw->dmaTag)];
|
||||
DMA_TypeDef * dmaBase = tch->dma->dma;
|
||||
|
||||
tch->dmaState = TCH_DMA_READY;
|
||||
// Make sure we terminate any DMA transaction currently in progress
|
||||
// Clear the flag as well, so even if DMA transfer finishes while within ATOMIC_BLOCK
|
||||
// the resulting IRQ won't mess up the DMA state
|
||||
ATOMIC_BLOCK(NVIC_PRIO_MAX) {
|
||||
LL_TIM_DisableDMAReq_CCx(tch->timHw->tim, lookupDMASourceTable[tch->timHw->channelIndex]);
|
||||
LL_DMA_DisableStream(dmaBase, streamLL);
|
||||
DMA_CLEAR_FLAG(tch->dma, DMA_IT_TCIF);
|
||||
}
|
||||
|
||||
LL_TIM_DisableDMAReq_CCx(tch->timHw->tim, lookupDMASourceTable[tch->timHw->channelIndex]);
|
||||
|
||||
LL_DMA_DisableStream(dmaBase, streamLL);
|
||||
LL_DMA_SetDataLength(dmaBase, streamLL, dmaBufferSize);
|
||||
LL_DMA_ConfigAddresses(dmaBase, streamLL, (uint32_t)tch->dmaBuffer, (uint32_t)impl_timerCCR(tch), LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
|
||||
LL_DMA_EnableIT_TC(dmaBase, streamLL);
|
||||
LL_DMA_EnableStream(dmaBase, streamLL);
|
||||
tch->dmaState = TCH_DMA_READY;
|
||||
}
|
||||
|
||||
void impl_timerPWMStartDMA(TCH_t * tch)
|
||||
|
|
|
@ -347,9 +347,18 @@ bool impl_timerPWMConfigChannelDMA(TCH_t * tch, void * dmaBuffer, uint32_t dmaBu
|
|||
|
||||
void impl_timerPWMPrepareDMA(TCH_t * tch, uint32_t dmaBufferSize)
|
||||
{
|
||||
tch->dmaState = TCH_DMA_READY;
|
||||
// Make sure we terminate any DMA transaction currently in progress
|
||||
// Clear the flag as well, so even if DMA transfer finishes while within ATOMIC_BLOCK
|
||||
// the resulting IRQ won't mess up the DMA state
|
||||
ATOMIC_BLOCK(NVIC_PRIO_MAX) {
|
||||
DMA_Cmd(tch->dma->ref, DISABLE);
|
||||
TIM_DMACmd(tch->timHw->tim, lookupDMASourceTable[tch->timHw->channelIndex], DISABLE);
|
||||
DMA_CLEAR_FLAG(tch->dma, DMA_IT_TCIF);
|
||||
}
|
||||
|
||||
DMA_SetCurrDataCounter(tch->dma->ref, dmaBufferSize);
|
||||
DMA_Cmd(tch->dma->ref, ENABLE);
|
||||
tch->dmaState = TCH_DMA_READY;
|
||||
}
|
||||
|
||||
void impl_timerPWMStartDMA(TCH_t * tch)
|
||||
|
|
|
@ -784,7 +784,7 @@ void taskRunRealtimeCallbacks(timeUs_t currentTimeUs)
|
|||
#endif
|
||||
|
||||
#ifdef USE_DSHOT
|
||||
pwmCompleteDshotUpdate(getMotorCount(), currentTimeUs);
|
||||
pwmCompleteDshotUpdate(getMotorCount());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue