1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-14 20:10:18 +03:00

F4 Dshot-DMAR initial working version

This commit is contained in:
jflyper 2017-12-23 02:52:01 +09:00
parent 5594a5c5b9
commit 759e03c47e
8 changed files with 220 additions and 52 deletions

View file

@ -109,9 +109,14 @@ typedef enum {
typedef struct { typedef struct {
TIM_TypeDef *timer; TIM_TypeDef *timer;
uint16_t timerDmaSources; #if defined(USE_DSHOT_DMAR)
#ifdef USE_DSHOT_DMAR #if !defined(USE_HAL_DRIVER)
DMA_Stream_TypeDef *dmaBurstRef;
uint16_t dmaBurstLength;
#endif
uint32_t dmaBurstBuffer[DSHOT_DMA_BUFFER_SIZE * 4]; uint32_t dmaBurstBuffer[DSHOT_DMA_BUFFER_SIZE * 4];
#else
uint16_t timerDmaSources;
#endif #endif
} motorDmaTimer_t; } motorDmaTimer_t;
@ -119,7 +124,9 @@ typedef struct {
ioTag_t ioTag; ioTag_t ioTag;
const timerHardware_t *timerHardware; const timerHardware_t *timerHardware;
uint16_t value; uint16_t value;
#if !defined(USE_DSHOT_DMAR)
uint16_t timerDmaSource; uint16_t timerDmaSource;
#endif
motorDmaTimer_t *timer; motorDmaTimer_t *timer;
volatile bool requestTelemetry; volatile bool requestTelemetry;
#if defined(STM32F3) || defined(STM32F4) || defined(STM32F7) #if defined(STM32F3) || defined(STM32F4) || defined(STM32F7)
@ -127,11 +134,10 @@ typedef struct {
#else #else
uint8_t dmaBuffer[DSHOT_DMA_BUFFER_SIZE]; uint8_t dmaBuffer[DSHOT_DMA_BUFFER_SIZE];
#endif #endif
#if defined(STM32F7) #if defined(USE_HAL_DRIVER)
TIM_HandleTypeDef TimHandle; TIM_HandleTypeDef TimHandle;
DMA_HandleTypeDef hdma_tim; DMA_HandleTypeDef hdma_tim;
uint16_t timerDmaIndex; uint16_t timerDmaIndex;
uint8_t timerIndex;
#endif #endif
} motorDmaOutput_t; } motorDmaOutput_t;

View file

@ -22,6 +22,8 @@
#ifdef USE_DSHOT #ifdef USE_DSHOT
#include "build/debug.h"
#include "drivers/io.h" #include "drivers/io.h"
#include "timer.h" #include "timer.h"
#if defined(STM32F4) #if defined(STM32F4)
@ -58,17 +60,34 @@ void pwmWriteDshotInt(uint8_t index, uint16_t value)
{ {
motorDmaOutput_t *const motor = &dmaMotors[index]; motorDmaOutput_t *const motor = &dmaMotors[index];
#ifdef USE_DSHOT_DMAR
if (!motor->timerHardware || !motor->timerHardware->dmaTimUPRef) {
return;
}
#else
if (!motor->timerHardware || !motor->timerHardware->dmaRef) { if (!motor->timerHardware || !motor->timerHardware->dmaRef) {
return; return;
} }
#endif
uint16_t packet = prepareDshotPacket(motor, value); uint16_t packet = prepareDshotPacket(motor, value);
// XXX Replace this with striding loader in the next refactor
uint8_t bufferSize = loadDmaBuffer(motor, packet); uint8_t bufferSize = loadDmaBuffer(motor, packet);
#ifdef USE_DSHOT_DMAR
// Load channel data into burst buffer
uint8_t channelIndex = timerLookupChannelIndex(motor->timerHardware->channel);
// XXX This copy will be deleted once the striding loader is available
for (int i = 0; i < bufferSize; i++) {
motor->timer->dmaBurstBuffer[channelIndex + i * 4] = motor->dmaBuffer[i];
}
motor->timer->dmaBurstLength = bufferSize * 4;
#else
motor->timer->timerDmaSources |= motor->timerDmaSource; motor->timer->timerDmaSources |= motor->timerDmaSource;
DMA_SetCurrDataCounter(motor->timerHardware->dmaRef, bufferSize); DMA_SetCurrDataCounter(motor->timerHardware->dmaRef, bufferSize);
DMA_Cmd(motor->timerHardware->dmaRef, ENABLE); DMA_Cmd(motor->timerHardware->dmaRef, ENABLE);
#endif
} }
void pwmCompleteDshotMotorUpdate(uint8_t motorCount) void pwmCompleteDshotMotorUpdate(uint8_t motorCount)
@ -76,9 +95,16 @@ void pwmCompleteDshotMotorUpdate(uint8_t motorCount)
UNUSED(motorCount); UNUSED(motorCount);
for (int i = 0; i < dmaMotorTimerCount; i++) { for (int i = 0; i < dmaMotorTimerCount; i++) {
#ifdef USE_DSHOT_DMAR
DMA_SetCurrDataCounter(dmaMotorTimers[i].dmaBurstRef, dmaMotorTimers[i].dmaBurstLength);
DMA_Cmd(dmaMotorTimers[i].dmaBurstRef, ENABLE);
TIM_DMAConfig(dmaMotorTimers[i].timer, TIM_DMABase_CCR1, TIM_DMABurstLength_4Transfers);
TIM_DMACmd(dmaMotorTimers[i].timer, TIM_DMA_Update, ENABLE);
#else
TIM_SetCounter(dmaMotorTimers[i].timer, 0); TIM_SetCounter(dmaMotorTimers[i].timer, 0);
TIM_DMACmd(dmaMotorTimers[i].timer, dmaMotorTimers[i].timerDmaSources, ENABLE); TIM_DMACmd(dmaMotorTimers[i].timer, dmaMotorTimers[i].timerDmaSources, ENABLE);
dmaMotorTimers[i].timerDmaSources = 0; dmaMotorTimers[i].timerDmaSources = 0;
#endif
} }
} }
@ -86,14 +112,35 @@ static void motor_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor)
{ {
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) { if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) {
motorDmaOutput_t * const motor = &dmaMotors[descriptor->userParam]; motorDmaOutput_t * const motor = &dmaMotors[descriptor->userParam];
#ifdef USE_DSHOT_DMAR
DMA_Cmd(motor->timerHardware->dmaTimUPRef, DISABLE);
TIM_DMACmd(motor->timerHardware->tim, TIM_DMA_Update, DISABLE);
#else
DMA_Cmd(motor->timerHardware->dmaRef, DISABLE); DMA_Cmd(motor->timerHardware->dmaRef, DISABLE);
TIM_DMACmd(motor->timerHardware->tim, motor->timerDmaSource, DISABLE); TIM_DMACmd(motor->timerHardware->tim, motor->timerDmaSource, DISABLE);
#endif
DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF); DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
} }
} }
void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t motorIndex, motorPwmProtocolTypes_e pwmProtocolType, uint8_t output) void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t motorIndex, motorPwmProtocolTypes_e pwmProtocolType, uint8_t output)
{ {
#if defined(STM32F3)
DMA_Channel_TypeDef *dmaRef = timerHardware->dmaRef;
#elif defined(STM32F4)
#ifdef USE_DSHOT_DMAR
DMA_Stream_TypeDef *dmaRef = timerHardware->dmaTimUPRef;
#else
DMA_Stream_TypeDef *dmaRef = timerHardware->dmaRef;
#endif
#else
#error "No MCU specified in DSHOT"
#endif
if (dmaRef == NULL) {
return;
}
TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure;
DMA_InitTypeDef DMA_InitStructure; DMA_InitTypeDef DMA_InitStructure;
@ -138,9 +185,6 @@ void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t m
timerOCInit(timer, timerHardware->channel, &TIM_OCInitStructure); timerOCInit(timer, timerHardware->channel, &TIM_OCInitStructure);
timerOCPreloadConfig(timer, timerHardware->channel, TIM_OCPreload_Enable); timerOCPreloadConfig(timer, timerHardware->channel, TIM_OCPreload_Enable);
motor->timerDmaSource = timerDmaSource(timerHardware->channel);
motor->timer = &dmaMotorTimers[timerIndex];
motor->timer->timerDmaSources &= ~motor->timerDmaSource;
if (output & TIMER_OUTPUT_N_CHANNEL) { if (output & TIMER_OUTPUT_N_CHANNEL) {
TIM_CCxNCmd(timer, timerHardware->channel, TIM_CCxN_Enable); TIM_CCxNCmd(timer, timerHardware->channel, TIM_CCxN_Enable);
@ -154,25 +198,47 @@ void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t m
TIM_Cmd(timer, ENABLE); TIM_Cmd(timer, ENABLE);
} }
#if defined(STM32F3) motor->timer = &dmaMotorTimers[timerIndex];
DMA_Channel_TypeDef *dmaRef = timerHardware->dmaRef;
#elif defined(STM32F4)
DMA_Stream_TypeDef *dmaRef = timerHardware->dmaRef;
#else
#error "No MCU specified in DSHOT"
#endif
if (dmaRef == NULL) { #ifdef USE_DSHOT_DMAR
motor->timer->dmaBurstRef = dmaRef;
if (!configureTimer) {
return; return;
} }
#else
dmaInit(timerHardware->dmaIrqHandler, OWNER_MOTOR, RESOURCE_INDEX(motorIndex)); motor->timerDmaSource = timerDmaSource(timerHardware->channel);
dmaSetHandler(timerHardware->dmaIrqHandler, motor_DMA_IRQHandler, NVIC_BUILD_PRIORITY(1, 2), motorIndex); motor->timer->timerDmaSources &= ~motor->timerDmaSource;
#endif
DMA_Cmd(dmaRef, DISABLE); DMA_Cmd(dmaRef, DISABLE);
DMA_DeInit(dmaRef); DMA_DeInit(dmaRef);
DMA_StructInit(&DMA_InitStructure); DMA_StructInit(&DMA_InitStructure);
#ifdef USE_DSHOT_DMAR
dmaInit(timerHardware->dmaTimUPIrqHandler, OWNER_TIMUP, timerGetTIMNumber(timerHardware->tim));
dmaSetHandler(timerHardware->dmaTimUPIrqHandler, motor_DMA_IRQHandler, NVIC_BUILD_PRIORITY(1, 2), motorIndex);
DMA_InitStructure.DMA_Channel = timerHardware->dmaTimUPChannel;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)motor->timer->dmaBurstBuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&timerHardware->tim->DMAR;
DMA_InitStructure.DMA_BufferSize = (pwmProtocolType == PWM_TYPE_PROSHOT1000) ? PROSHOT_DMA_BUFFER_SIZE : DSHOT_DMA_BUFFER_SIZE; // XXX
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
#else // !USE_DSHOT_DMAR
dmaInit(timerHardware->dmaIrqHandler, OWNER_MOTOR, RESOURCE_INDEX(motorIndex));
dmaSetHandler(timerHardware->dmaIrqHandler, motor_DMA_IRQHandler, NVIC_BUILD_PRIORITY(1, 2), motorIndex);
#if defined(STM32F3) #if defined(STM32F3)
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)motor->dmaBuffer; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)motor->dmaBuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
@ -194,6 +260,9 @@ void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t m
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_Priority = DMA_Priority_High;
#endif // USE_DSHOT_DMAR
// XXX Consolidate common settings in the next refactor
DMA_Init(dmaRef, &DMA_InitStructure); DMA_Init(dmaRef, &DMA_InitStructure);
DMA_ITConfig(dmaRef, DMA_IT_TC, ENABLE); DMA_ITConfig(dmaRef, DMA_IT_TC, ENABLE);

View file

@ -71,10 +71,10 @@ void pwmWriteDshotInt(uint8_t index, uint16_t value)
uint8_t channel_index = motor->timerHardware->channel / TIM_CHANNEL_2; uint8_t channel_index = motor->timerHardware->channel / TIM_CHANNEL_2;
// load channel data into burst buffer // load channel data into burst buffer
for(int i = 0; i < bufferSize; i++) { for(int i = 0; i < bufferSize; i++) {
dmaMotorTimers[motor->timerIndex].dmaBurstBuffer[channel_index + i * 4] = motor->dmaBuffer[i]; motor->timer->dmaBurstBuffer[channel_index + i * 4] = motor->dmaBuffer[i];
} }
if(HAL_DMA_STATE_READY == motor->TimHandle.hdma[motor->timerDmaIndex]->State) { if(HAL_DMA_STATE_READY == motor->TimHandle.hdma[motor->timerDmaIndex]->State) {
HAL_DMA_Start_IT(motor->TimHandle.hdma[motor->timerDmaIndex], (uint32_t)dmaMotorTimers[motor->timerIndex].dmaBurstBuffer, (uint32_t)&motor->TimHandle.Instance->DMAR, bufferSize * 4); HAL_DMA_Start_IT(motor->TimHandle.hdma[motor->timerDmaIndex], (uint32_t)motor->timer->dmaBurstBuffer, (uint32_t)&motor->TimHandle.Instance->DMAR, bufferSize * 4);
} }
#else #else
if (DMA_SetCurrDataCounter(&motor->TimHandle, motor->timerHardware->channel, motor->dmaBuffer, bufferSize) != HAL_OK) { if (DMA_SetCurrDataCounter(&motor->TimHandle, motor->timerHardware->channel, motor->dmaBuffer, bufferSize) != HAL_OK) {
@ -125,14 +125,22 @@ static void motor_DMA_IRQHandler(dmaChannelDescriptor_t* descriptor)
void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t motorIndex, motorPwmProtocolTypes_e pwmProtocolType, uint8_t output) void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t motorIndex, motorPwmProtocolTypes_e pwmProtocolType, uint8_t output)
{ {
#ifdef USE_DSHOT_DMAR
if (timerHardware->dmaTimUPRef == NULL) {
return;
}
#else
if (timerHardware->dmaRef == NULL) {
return;
}
#endif
motorDmaOutput_t * const motor = &dmaMotors[motorIndex]; motorDmaOutput_t * const motor = &dmaMotors[motorIndex];
motor->timerHardware = timerHardware; motor->timerHardware = timerHardware;
TIM_TypeDef *timer = timerHardware->tim; TIM_TypeDef *timer = timerHardware->tim;
const IO_t motorIO = IOGetByTag(timerHardware->tag); const IO_t motorIO = IOGetByTag(timerHardware->tag);
const uint8_t timerIndex = getTimerIndex(timer);
IOConfigGPIOAF(motorIO, IO_CONFIG(GPIO_MODE_AF_PP, GPIO_SPEED_FREQ_VERY_HIGH, GPIO_PULLDOWN), timerHardware->alternateFunction); IOConfigGPIOAF(motorIO, IO_CONFIG(GPIO_MODE_AF_PP, GPIO_SPEED_FREQ_VERY_HIGH, GPIO_PULLDOWN), timerHardware->alternateFunction);
__DMA1_CLK_ENABLE(); __DMA1_CLK_ENABLE();
@ -146,15 +154,15 @@ void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t m
motor->TimHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; motor->TimHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
motor->TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; motor->TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
motor->TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; motor->TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_PWM_Init(&motor->TimHandle) != HAL_OK) { if (HAL_TIM_PWM_Init(&motor->TimHandle) != HAL_OK) {
/* Initialization Error */ /* Initialization Error */
return; return;
} }
#ifdef USE_DSHOT_DMAR motor->timer = &dmaMotorTimers[getTimerIndex(timer)];
motor->timerDmaIndex = TIM_DMA_ID_UPDATE;
/* Set the parameters to be configured */ /* Set the common dma handle parameters to be configured */
motor->hdma_tim.Init.Channel = timerHardware->dmaTimUPChannel;
motor->hdma_tim.Init.Direction = DMA_MEMORY_TO_PERIPH; motor->hdma_tim.Init.Direction = DMA_MEMORY_TO_PERIPH;
motor->hdma_tim.Init.PeriphInc = DMA_PINC_DISABLE; motor->hdma_tim.Init.PeriphInc = DMA_PINC_DISABLE;
motor->hdma_tim.Init.MemInc = DMA_MINC_ENABLE; motor->hdma_tim.Init.MemInc = DMA_MINC_ENABLE;
@ -162,17 +170,19 @@ void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t m
motor->hdma_tim.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; motor->hdma_tim.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
motor->hdma_tim.Init.Mode = DMA_NORMAL; motor->hdma_tim.Init.Mode = DMA_NORMAL;
motor->hdma_tim.Init.Priority = DMA_PRIORITY_HIGH; motor->hdma_tim.Init.Priority = DMA_PRIORITY_HIGH;
motor->hdma_tim.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
motor->hdma_tim.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; motor->hdma_tim.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
motor->hdma_tim.Init.MemBurst = DMA_MBURST_SINGLE; motor->hdma_tim.Init.MemBurst = DMA_MBURST_SINGLE;
motor->hdma_tim.Init.PeriphBurst = DMA_PBURST_SINGLE; motor->hdma_tim.Init.PeriphBurst = DMA_PBURST_SINGLE;
#ifdef USE_DSHOT_DMAR
motor->timerDmaIndex = TIM_DMA_ID_UPDATE;
/* Set the DMAR specific dma handle parameters to be configured */
motor->hdma_tim.Init.Channel = timerHardware->dmaTimUPChannel;
motor->hdma_tim.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
/* Set hdma_tim instance */ /* Set hdma_tim instance */
if (timerHardware->dmaTimUPRef == NULL) {
/* Initialization Error */
return;
}
motor->hdma_tim.Instance = timerHardware->dmaTimUPRef; motor->hdma_tim.Instance = timerHardware->dmaTimUPRef;
/* Link hdma_tim to hdma[x] (channelx) */ /* Link hdma_tim to hdma[x] (channelx) */
__HAL_LINKDMA(&motor->TimHandle, hdma[motor->timerDmaIndex], motor->hdma_tim); __HAL_LINKDMA(&motor->TimHandle, hdma[motor->timerDmaIndex], motor->hdma_tim);
@ -180,29 +190,15 @@ void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t m
dmaSetHandler(timerHardware->dmaTimUPIrqHandler, motor_DMA_IRQHandler, NVIC_BUILD_PRIORITY(1, 2), motorIndex); dmaSetHandler(timerHardware->dmaTimUPIrqHandler, motor_DMA_IRQHandler, NVIC_BUILD_PRIORITY(1, 2), motorIndex);
#else #else
motor->timerDmaIndex = timerDmaIndex(timerHardware->channel); motor->timerDmaIndex = timerDmaIndex(timerHardware->channel);
motor->timer = &dmaMotorTimers[timerIndex]; motor->timer->timerDmaSources |= timerDmaSource(timerHardware->channel);
dmaMotorTimers[timerIndex].timerDmaSources |= timerDmaSource(timerHardware->channel);
/* Set the parameters to be configured */ /* Set the non-DMAR specific dma handle parameters to be configured */
motor->hdma_tim.Init.Channel = timerHardware->dmaChannel; motor->hdma_tim.Init.Channel = timerHardware->dmaChannel;
motor->hdma_tim.Init.Direction = DMA_MEMORY_TO_PERIPH;
motor->hdma_tim.Init.PeriphInc = DMA_PINC_DISABLE;
motor->hdma_tim.Init.MemInc = DMA_MINC_ENABLE;
motor->hdma_tim.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
motor->hdma_tim.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
motor->hdma_tim.Init.Mode = DMA_NORMAL;
motor->hdma_tim.Init.Priority = DMA_PRIORITY_HIGH;
motor->hdma_tim.Init.FIFOMode = DMA_FIFOMODE_DISABLE; motor->hdma_tim.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
motor->hdma_tim.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
motor->hdma_tim.Init.MemBurst = DMA_MBURST_SINGLE;
motor->hdma_tim.Init.PeriphBurst = DMA_PBURST_SINGLE;
/* Set hdma_tim instance */ /* Set hdma_tim instance */
if (timerHardware->dmaRef == NULL) {
/* Initialization Error */
return;
}
motor->hdma_tim.Instance = timerHardware->dmaRef; motor->hdma_tim.Instance = timerHardware->dmaRef;
/* Link hdma_tim to hdma[x] (channelx) */ /* Link hdma_tim to hdma[x] (channelx) */
__HAL_LINKDMA(&motor->TimHandle, hdma[motor->timerDmaIndex], motor->hdma_tim); __HAL_LINKDMA(&motor->TimHandle, hdma[motor->timerDmaIndex], motor->hdma_tim);
@ -262,7 +258,7 @@ void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t m
break; break;
} }
} }
motor->timerIndex = timerIndex;
LL_TIM_CC_EnableChannel(motor->timerHardware->tim, channels); LL_TIM_CC_EnableChannel(motor->timerHardware->tim, channels);
#else #else
if (output & TIMER_OUTPUT_N_CHANNEL) { if (output & TIMER_OUTPUT_N_CHANNEL) {

View file

@ -193,11 +193,85 @@ TIM_TypeDef * const usedTimers[USED_TIMER_COUNT] = {
#undef _DEF #undef _DEF
}; };
// Map timer index to timer number (Straight copy of usedTimers array)
const int8_t timerNumbers[USED_TIMER_COUNT] = {
#define _DEF(i) i
#if USED_TIMERS & TIM_N(1)
_DEF(1),
#endif
#if USED_TIMERS & TIM_N(2)
_DEF(2),
#endif
#if USED_TIMERS & TIM_N(3)
_DEF(3),
#endif
#if USED_TIMERS & TIM_N(4)
_DEF(4),
#endif
#if USED_TIMERS & TIM_N(5)
_DEF(5),
#endif
#if USED_TIMERS & TIM_N(6)
_DEF(6),
#endif
#if USED_TIMERS & TIM_N(7)
_DEF(7),
#endif
#if USED_TIMERS & TIM_N(8)
_DEF(8),
#endif
#if USED_TIMERS & TIM_N(9)
_DEF(9),
#endif
#if USED_TIMERS & TIM_N(10)
_DEF(10),
#endif
#if USED_TIMERS & TIM_N(11)
_DEF(11),
#endif
#if USED_TIMERS & TIM_N(12)
_DEF(12),
#endif
#if USED_TIMERS & TIM_N(13)
_DEF(13),
#endif
#if USED_TIMERS & TIM_N(14)
_DEF(14),
#endif
#if USED_TIMERS & TIM_N(15)
_DEF(15),
#endif
#if USED_TIMERS & TIM_N(16)
_DEF(16),
#endif
#if USED_TIMERS & TIM_N(17)
_DEF(17),
#endif
#undef _DEF
};
int8_t timerGetTIMNumber(const TIM_TypeDef *tim)
{
uint8_t index = lookupTimerIndex(tim);
if (index < USED_TIMER_COUNT) {
return timerNumbers[index];
} else {
return 0;
}
}
static inline uint8_t lookupChannelIndex(const uint16_t channel) static inline uint8_t lookupChannelIndex(const uint16_t channel)
{ {
return channel >> 2; return channel >> 2;
} }
uint8_t timerLookupChannelIndex(const uint16_t channel)
{
return lookupChannelIndex(channel);
}
rccPeriphTag_t timerRCC(TIM_TypeDef *tim) rccPeriphTag_t timerRCC(TIM_TypeDef *tim)
{ {
for (int i = 0; i < HARDWARE_TIMER_DEFINITION_COUNT; i++) { for (int i = 0; i < HARDWARE_TIMER_DEFINITION_COUNT; i++) {

View file

@ -104,7 +104,7 @@ typedef struct timerHardware_s {
DMA_Channel_TypeDef *dmaRef; DMA_Channel_TypeDef *dmaRef;
#endif #endif
uint8_t dmaIrqHandler; uint8_t dmaIrqHandler;
#if defined(STM32F7) #if defined(STM32F4) || defined(STM32F7)
// TIMUP // TIMUP
DMA_Stream_TypeDef *dmaTimUPRef; DMA_Stream_TypeDef *dmaTimUPRef;
uint32_t dmaTimUPChannel; uint32_t dmaTimUPChannel;
@ -212,3 +212,4 @@ uint16_t timerGetPrescalerByDesiredMhz(TIM_TypeDef *tim, uint16_t mhz);
uint16_t timerGetPeriodByPrescaler(TIM_TypeDef *tim, uint16_t prescaler, uint32_t hz); uint16_t timerGetPeriodByPrescaler(TIM_TypeDef *tim, uint16_t prescaler, uint32_t hz);
int8_t timerGetTIMNumber(const TIM_TypeDef *tim); int8_t timerGetTIMNumber(const TIM_TypeDef *tim);
uint8_t timerLookupChannelIndex(const uint16_t channel);

View file

@ -374,6 +374,11 @@
DEF_TIM_DMA_STREAM(dmaopt, TCH_## tim ## _ ## chan), \ DEF_TIM_DMA_STREAM(dmaopt, TCH_## tim ## _ ## chan), \
DEF_TIM_DMA_CHANNEL(dmaopt, TCH_## tim ## _ ## chan), \ DEF_TIM_DMA_CHANNEL(dmaopt, TCH_## tim ## _ ## chan), \
DEF_TIM_DMA_HANDLER(dmaopt, TCH_## tim ## _ ## chan) \ DEF_TIM_DMA_HANDLER(dmaopt, TCH_## tim ## _ ## chan) \
), \
DEF_TIM_DMA_COND( \
DEF_TIM_DMA_STREAM(0, TCH_## tim ## _UP), \
DEF_TIM_DMA_CHANNEL(0, TCH_## tim ## _UP), \
DEF_TIM_DMA_HANDLER(0, TCH_## tim ## _UP) \
) \ ) \
} \ } \
/**/ /**/
@ -447,6 +452,22 @@
#define DEF_TIM_DMA__BTCH_TIM14_CH1 NONE #define DEF_TIM_DMA__BTCH_TIM14_CH1 NONE
// TIM_UP table
#define DEF_TIM_DMA__BTCH_TIM1_UP D(2, 5, 6)
#define DEF_TIM_DMA__BTCH_TIM2_UP D(1, 7, 3)
#define DEF_TIM_DMA__BTCH_TIM3_UP D(1, 2, 5)
#define DEF_TIM_DMA__BTCH_TIM4_UP D(1, 6, 2)
#define DEF_TIM_DMA__BTCH_TIM5_UP D(1, 0, 6)
#define DEF_TIM_DMA__BTCH_TIM6_UP D(1, 1, 7)
#define DEF_TIM_DMA__BTCH_TIM7_UP D(1, 4, 1)
#define DEF_TIM_DMA__BTCH_TIM8_UP D(2, 1, 7)
#define DEF_TIM_DMA__BTCH_TIM9_UP NONE
#define DEF_TIM_DMA__BTCH_TIM10_UP NONE
#define DEF_TIM_DMA__BTCH_TIM11_UP NONE
#define DEF_TIM_DMA__BTCH_TIM12_UP NONE
#define DEF_TIM_DMA__BTCH_TIM13_UP NONE
#define DEF_TIM_DMA__BTCH_TIM14_UP NONE
#elif defined(STM32F7) #elif defined(STM32F7)
#define DEF_TIM(tim, chan, pin, flags, out, dmaopt) { \ #define DEF_TIM(tim, chan, pin, flags, out, dmaopt) { \
tim, \ tim, \

View file

@ -46,6 +46,7 @@
#ifdef STM32F4 #ifdef STM32F4
#define USE_DSHOT #define USE_DSHOT
#define USE_DSHOT_DMAR
#define USE_ESC_SENSOR #define USE_ESC_SENSOR
#define I2C3_OVERCLOCK true #define I2C3_OVERCLOCK true
#define USE_TELEMETRY_IBUS #define USE_TELEMETRY_IBUS