Merge pull request #1374 from blckmn/minor_dshot_updates

Timer code simplification in preparation of led strip being assignable.
This commit is contained in:
Martin Budden 2016-10-23 08:07:43 +01:00 committed by GitHub
commit 82730f0e26
14 changed files with 103 additions and 136 deletions

View File

@ -21,6 +21,8 @@ typedef void (*dmaCallbackHandlerFuncPtr)(struct dmaChannelDescriptor_s *channel
#if defined(STM32F4) || defined(STM32F7)
uint32_t dmaFlag_IT_TCIF(const DMA_Stream_TypeDef *stream);
typedef enum {
DMA1_ST0_HANDLER = 0,
DMA1_ST1_HANDLER,

View File

@ -87,3 +87,16 @@ void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr
NVIC_Init(&NVIC_InitStructure);
}
#define RETURN_TCIF_FLAG(s, n) if (s == DMA1_Stream ## n || s == DMA2_Stream ## n) return DMA_IT_TCIF ## n
uint32_t dmaFlag_IT_TCIF(const DMA_Stream_TypeDef *stream)
{
RETURN_TCIF_FLAG(stream, 0);
RETURN_TCIF_FLAG(stream, 1);
RETURN_TCIF_FLAG(stream, 2);
RETURN_TCIF_FLAG(stream, 3);
RETURN_TCIF_FLAG(stream, 4);
RETURN_TCIF_FLAG(stream, 5);
RETURN_TCIF_FLAG(stream, 6);
RETURN_TCIF_FLAG(stream, 7);
}

View File

@ -30,13 +30,13 @@
#include "system.h"
#include "rcc.h"
#include "timer.h"
#include "timer_stm32f4xx.h"
#if !defined(WS2811_PIN)
#define WS2811_PIN PA0
#define WS2811_TIMER TIM5
#define WS2811_DMA_HANDLER_IDENTIFER DMA1_ST2_HANDLER
#define WS2811_DMA_STREAM DMA1_Stream2
#define WS2811_DMA_IT DMA_IT_TCIF2
#define WS2811_DMA_CHANNEL DMA_Channel_6
#define WS2811_TIMER_CHANNEL TIM_Channel_1
#define WS2811_TIMER_GPIO_AF GPIO_AF_TIM5
@ -94,33 +94,9 @@ void ws2811LedStripHardwareInit(void)
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStructure.TIM_Pulse = 0;
uint32_t channelAddress = 0;
switch (WS2811_TIMER_CHANNEL) {
case TIM_Channel_1:
TIM_OC1Init(WS2811_TIMER, &TIM_OCInitStructure);
timDMASource = TIM_DMA_CC1;
channelAddress = (uint32_t)(&WS2811_TIMER->CCR1);
TIM_OC1PreloadConfig(WS2811_TIMER, TIM_OCPreload_Enable);
break;
case TIM_Channel_2:
TIM_OC2Init(WS2811_TIMER, &TIM_OCInitStructure);
timDMASource = TIM_DMA_CC2;
channelAddress = (uint32_t)(&WS2811_TIMER->CCR2);
TIM_OC2PreloadConfig(WS2811_TIMER, TIM_OCPreload_Enable);
break;
case TIM_Channel_3:
TIM_OC3Init(WS2811_TIMER, &TIM_OCInitStructure);
timDMASource = TIM_DMA_CC3;
channelAddress = (uint32_t)(&WS2811_TIMER->CCR3);
TIM_OC3PreloadConfig(WS2811_TIMER, TIM_OCPreload_Enable);
break;
case TIM_Channel_4:
TIM_OC4Init(WS2811_TIMER, &TIM_OCInitStructure);
timDMASource = TIM_DMA_CC4;
channelAddress = (uint32_t)(&WS2811_TIMER->CCR4);
TIM_OC4PreloadConfig(WS2811_TIMER, TIM_OCPreload_Enable);
break;
}
timerOCInit(WS2811_TIMER, WS2811_TIMER_CHANNEL, &TIM_OCInitStructure);
timerOCPreloadConfig(WS2811_TIMER, WS2811_TIMER_CHANNEL, TIM_OCPreload_Enable);
timDMASource = timerDmaSource(WS2811_TIMER_CHANNEL);
TIM_CtrlPWMOutputs(WS2811_TIMER, ENABLE);
TIM_ARRPreloadConfig(WS2811_TIMER, ENABLE);
@ -133,7 +109,7 @@ void ws2811LedStripHardwareInit(void)
DMA_DeInit(WS2811_DMA_STREAM);
DMA_StructInit(&DMA_InitStructure);
DMA_InitStructure.DMA_Channel = WS2811_DMA_CHANNEL;
DMA_InitStructure.DMA_PeripheralBaseAddr = channelAddress;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)timerCCR(WS2811_TIMER, WS2811_TIMER_CHANNEL);
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ledStripDMABuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_BufferSize = WS2811_DMA_BUFFER_SIZE;
@ -151,7 +127,7 @@ void ws2811LedStripHardwareInit(void)
DMA_Init(WS2811_DMA_STREAM, &DMA_InitStructure);
DMA_ITConfig(WS2811_DMA_STREAM, DMA_IT_TC, ENABLE);
DMA_ClearITPendingBit(WS2811_DMA_STREAM, WS2811_DMA_IT);
DMA_ClearITPendingBit(WS2811_DMA_STREAM, dmaFlag_IT_TCIF(WS2811_DMA_STREAM));
dmaSetHandler(WS2811_DMA_HANDLER_IDENTIFER, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0);

View File

@ -54,24 +54,8 @@ static void pwmOCConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t value, uint8
TIM_OCInitStructure.TIM_OCPolarity = (output & TIMER_OUTPUT_INVERTED) ? TIM_OCPolarity_High : TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
switch (channel) {
case TIM_Channel_1:
TIM_OC1Init(tim, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(tim, TIM_OCPreload_Enable);
break;
case TIM_Channel_2:
TIM_OC2Init(tim, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(tim, TIM_OCPreload_Enable);
break;
case TIM_Channel_3:
TIM_OC3Init(tim, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(tim, TIM_OCPreload_Enable);
break;
case TIM_Channel_4:
TIM_OC4Init(tim, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(tim, TIM_OCPreload_Enable);
break;
}
timerOCInit(tim, channel, &TIM_OCInitStructure);
timerOCPreloadConfig(tim, channel, TIM_OCPreload_Enable);
}
static void pwmOutConfig(pwmOutputPort_t *port, const timerHardware_t *timerHardware, uint8_t mhz, uint16_t period, uint16_t value)
@ -84,20 +68,7 @@ static void pwmOutConfig(pwmOutputPort_t *port, const timerHardware_t *timerHard
}
TIM_Cmd(timerHardware->tim, ENABLE);
switch (timerHardware->channel) {
case TIM_Channel_1:
port->ccr = &timerHardware->tim->CCR1;
break;
case TIM_Channel_2:
port->ccr = &timerHardware->tim->CCR2;
break;
case TIM_Channel_3:
port->ccr = &timerHardware->tim->CCR3;
break;
case TIM_Channel_4:
port->ccr = &timerHardware->tim->CCR4;
break;
}
port->ccr = timerChCCR(timerHardware);
port->period = period;
port->tim = timerHardware->tim;
@ -140,7 +111,9 @@ void pwmShutdownPulsesForAllMotors(uint8_t motorCount)
{
for (int index = 0; index < motorCount; index++) {
// Set the compare register to 0, which stops the output pulsing if the timer overflows
*motors[index].ccr = 0;
if (motors[index].ccr) {
*motors[index].ccr = 0;
}
}
}

View File

@ -149,36 +149,12 @@ void pwmDigitalMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t
}
TIM_OCInitStructure.TIM_Pulse = 0;
uint32_t timerChannelAddress = 0;
switch (timerHardware->channel) {
case TIM_Channel_1:
TIM_OC1Init(timer, &TIM_OCInitStructure);
motor->timerDmaSource = TIM_DMA_CC1;
timerChannelAddress = (uint32_t)(&timer->CCR1);
TIM_OC1PreloadConfig(timer, TIM_OCPreload_Enable);
break;
case TIM_Channel_2:
TIM_OC2Init(timer, &TIM_OCInitStructure);
motor->timerDmaSource = TIM_DMA_CC2;
timerChannelAddress = (uint32_t)(&timer->CCR2);
TIM_OC2PreloadConfig(timer, TIM_OCPreload_Enable);
break;
case TIM_Channel_3:
TIM_OC3Init(timer, &TIM_OCInitStructure);
motor->timerDmaSource = TIM_DMA_CC3;
timerChannelAddress = (uint32_t)(&timer->CCR3);
TIM_OC3PreloadConfig(timer, TIM_OCPreload_Enable);
break;
case TIM_Channel_4:
TIM_OC4Init(timer, &TIM_OCInitStructure);
motor->timerDmaSource = TIM_DMA_CC4;
timerChannelAddress = (uint32_t)(&timer->CCR4);
TIM_OC4PreloadConfig(timer, TIM_OCPreload_Enable);
break;
}
timerOCInit(timer, timerHardware->channel, &TIM_OCInitStructure);
timerOCPreloadConfig(timer, timerHardware->channel, TIM_OCPreload_Enable);
motor->timerDmaSource = timerDmaSource(timerHardware->channel);
dmaMotorTimers[timerIndex].timerDmaSources |= motor->timerDmaSource;
TIM_CCxCmd(timer, motor->timerHardware->channel, TIM_CCx_Enable);
TIM_CCxCmd(timer, timerHardware->channel, TIM_CCx_Enable);
if (configureTimer) {
TIM_CtrlPWMOutputs(timer, ENABLE);
@ -193,7 +169,7 @@ void pwmDigitalMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t
DMA_Cmd(channel, DISABLE);
DMA_DeInit(channel);
DMA_StructInit(&DMA_InitStructure);
DMA_InitStructure.DMA_PeripheralBaseAddr = timerChannelAddress;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)timerChCCR(timerHardware);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)motor->dmaBuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = MOTOR_DMA_BUFFER_SIZE;

View File

@ -22,6 +22,7 @@
#include "io.h"
#include "timer.h"
#include "timer_stm32f4xx.h"
#include "pwm_output.h"
#include "nvic.h"
#include "dma.h"
@ -139,38 +140,9 @@ void pwmDigitalMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStructure.TIM_Pulse = 0;
uint32_t timerChannelAddress = 0;
uint32_t dmaItFlag = 0;
switch (timerHardware->channel) {
case TIM_Channel_1:
TIM_OC1Init(timer, &TIM_OCInitStructure);
motor->timerDmaSource = TIM_DMA_CC1;
timerChannelAddress = (uint32_t)(&timer->CCR1);
TIM_OC1PreloadConfig(timer, TIM_OCPreload_Enable);
dmaItFlag = DMA_IT_TCIF1;
break;
case TIM_Channel_2:
TIM_OC2Init(timer, &TIM_OCInitStructure);
motor->timerDmaSource = TIM_DMA_CC2;
timerChannelAddress = (uint32_t)(&timer->CCR2);
TIM_OC2PreloadConfig(timer, TIM_OCPreload_Enable);
dmaItFlag = DMA_IT_TCIF2;
break;
case TIM_Channel_3:
TIM_OC3Init(timer, &TIM_OCInitStructure);
motor->timerDmaSource = TIM_DMA_CC3;
timerChannelAddress = (uint32_t)(&timer->CCR3);
TIM_OC3PreloadConfig(timer, TIM_OCPreload_Enable);
dmaItFlag = DMA_IT_TCIF3;
break;
case TIM_Channel_4:
TIM_OC4Init(timer, &TIM_OCInitStructure);
motor->timerDmaSource = TIM_DMA_CC4;
timerChannelAddress = (uint32_t)(&timer->CCR4);
TIM_OC4PreloadConfig(timer, TIM_OCPreload_Enable);
dmaItFlag = DMA_IT_TCIF4;
break;
}
timerOCInit(timer, timerHardware->channel, &TIM_OCInitStructure);
timerOCPreloadConfig(timer, timerHardware->channel, TIM_OCPreload_Enable);
motor->timerDmaSource = timerDmaSource(timerHardware->channel);
dmaMotorTimers[timerIndex].timerDmaSources |= motor->timerDmaSource;
TIM_CCxCmd(timer, motor->timerHardware->channel, TIM_CCx_Enable);
@ -187,7 +159,7 @@ void pwmDigitalMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t
DMA_DeInit(stream);
DMA_StructInit(&DMA_InitStructure);
DMA_InitStructure.DMA_Channel = timerHardware->dmaChannel;
DMA_InitStructure.DMA_PeripheralBaseAddr = timerChannelAddress;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)timerChCCR(timerHardware);
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)motor->dmaBuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_BufferSize = MOTOR_DMA_BUFFER_SIZE;
@ -205,7 +177,7 @@ void pwmDigitalMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t
DMA_Init(stream, &DMA_InitStructure);
DMA_ITConfig(stream, DMA_IT_TC, ENABLE);
DMA_ClearITPendingBit(stream, dmaItFlag);
DMA_ClearITPendingBit(stream, dmaFlag_IT_TCIF(timerHardware->dmaStream));
dmaSetHandler(timerHardware->dmaIrqHandler, motor_DMA_IRQHandler, NVIC_BUILD_PRIORITY(1, 2), motorIndex);
}

View File

@ -481,8 +481,6 @@ volatile timCCR_t* timerChCCRLo(const timerHardware_t *timHw)
return (volatile timCCR_t*)((volatile char*)&timHw->tim->CCR1 + (timHw->channel & ~TIM_Channel_2));
}
volatile timCCR_t* timerChCCR(const timerHardware_t *timHw)
{
return (volatile timCCR_t*)((volatile char*)&timHw->tim->CCR1 + timHw->channel);
@ -770,4 +768,62 @@ const timerHardware_t *timerGetByTag(ioTag_t tag, timerFlag_e flag)
}
}
return NULL;
}
#if !defined(USE_HAL_DRIVER)
void timerOCInit(TIM_TypeDef *tim, uint8_t channel, TIM_OCInitTypeDef *init)
{
switch (channel) {
case TIM_Channel_1:
TIM_OC1Init(tim, init);
break;
case TIM_Channel_2:
TIM_OC2Init(tim, init);
break;
case TIM_Channel_3:
TIM_OC3Init(tim, init);
break;
case TIM_Channel_4:
TIM_OC4Init(tim, init);
break;
}
}
void timerOCPreloadConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t preload)
{
switch (channel) {
case TIM_Channel_1:
TIM_OC1PreloadConfig(tim, preload);
break;
case TIM_Channel_2:
TIM_OC2PreloadConfig(tim, preload);
break;
case TIM_Channel_3:
TIM_OC3PreloadConfig(tim, preload);
break;
case TIM_Channel_4:
TIM_OC4PreloadConfig(tim, preload);
break;
}
}
#endif
volatile timCCR_t* timerCCR(TIM_TypeDef *tim, uint8_t channel)
{
return (volatile timCCR_t*)((volatile char*)&tim->CCR1 + channel);
}
uint16_t timerDmaSource(uint8_t channel)
{
switch (channel) {
case TIM_Channel_1:
return TIM_DMA_CC1;
case TIM_Channel_2:
return TIM_DMA_CC2;
case TIM_Channel_3:
return TIM_DMA_CC3;
case TIM_Channel_4:
return TIM_DMA_CC4;
}
return 0;
}

View File

@ -175,4 +175,10 @@ const timerHardware_t *timerGetByTag(ioTag_t tag, timerFlag_e flag);
#if defined(USE_HAL_DRIVER)
TIM_HandleTypeDef* timerFindTimerHandle(TIM_TypeDef *tim);
#else
void timerOCInit(TIM_TypeDef *tim, uint8_t channel, TIM_OCInitTypeDef *init);
void timerOCPreloadConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t preload);
#endif
volatile timCCR_t *timerCCR(TIM_TypeDef *tim, uint8_t channel);
uint16_t timerDmaSource(uint8_t channel);

View File

@ -136,4 +136,3 @@ void TIM_SelectOCxM_NoDisable(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t
*(__IO uint32_t *) tmp |= (uint16_t)(TIM_OCMode << 8);
}
}

View File

@ -3,4 +3,4 @@
#include "stm32f4xx.h"
void TIM_SelectOCxM_NoDisable(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);
void TIM_SelectOCxM_NoDisable(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);

View File

@ -148,7 +148,6 @@
#define WS2811_TIMER_CHANNEL TIM_Channel_4
#define WS2811_DMA_HANDLER_IDENTIFER DMA1_ST2_HANDLER
#define WS2811_DMA_STREAM DMA1_Stream2
#define WS2811_DMA_IT DMA_IT_TCIF2
#define WS2811_TIMER_GPIO_AF GPIO_AF_TIM3
#define WS2811_DMA_CHANNEL DMA_Channel_5
#define WS2811_DMA_IRQ DMA1_Stream2_IRQn

View File

@ -127,8 +127,6 @@
#define WS2811_DMA_STREAM DMA1_Stream4
#define WS2811_DMA_CHANNEL DMA_Channel_6
#define WS2811_DMA_IRQ DMA1_Stream4_IRQn
#define WS2811_DMA_FLAG DMA_FLAG_TCIF4
#define WS2811_DMA_IT DMA_IT_TCIF4
#define WS2811_TIMER_GPIO_AF GPIO_AF_TIM5
#define SENSORS_SET (SENSOR_ACC)

View File

@ -105,7 +105,6 @@
#define WS2811_TIMER TIM5
#define WS2811_DMA_HANDLER_IDENTIFER DMA1_ST2_HANDLER
#define WS2811_DMA_STREAM DMA1_Stream2
#define WS2811_DMA_IT DMA_IT_TCIF2
#define WS2811_DMA_CHANNEL DMA_Channel_6
#define WS2811_TIMER_CHANNEL TIM_Channel_1
#define WS2811_TIMER_GPIO_AF GPIO_AF_TIM5

View File

@ -131,8 +131,6 @@
#define WS2811_TIMER_CHANNEL TIM_Channel_4
#define WS2811_DMA_HANDLER_IDENTIFER DMA1_ST2_HANDLER
#define WS2811_DMA_STREAM DMA1_Stream2
#define WS2811_DMA_FLAG DMA_FLAG_TCIF2
#define WS2811_DMA_IT DMA_IT_TCIF2
#define WS2811_DMA_CHANNEL DMA_Channel_5
#define WS2811_DMA_IRQ DMA1_Stream2_IRQn
#define WS2811_TIMER_GPIO_AF GPIO_AF_TIM3