diff --git a/Makefile b/Makefile index 266889dada..6df2240046 100644 --- a/Makefile +++ b/Makefile @@ -663,6 +663,7 @@ COMMON_SRC = \ drivers/serial_escserial.c \ drivers/sonar_hcsr04.c \ drivers/vtx_common.c \ + drivers/transponder_ir.c \ flight/navigation.c \ io/dashboard.c \ io/displayport_max7456.c \ @@ -671,6 +672,7 @@ COMMON_SRC = \ io/gps.c \ io/ledstrip.c \ io/osd.c \ + io/transponder_ir.c \ sensors/sonar.c \ sensors/barometer.c \ telemetry/telemetry.c \ @@ -815,7 +817,7 @@ STM32F10x_COMMON_SRC = \ drivers/dma.c \ drivers/gpio_stm32f10x.c \ drivers/inverter.c \ - drivers/light_ws2811strip_stm32f10x.c \ + drivers/light_ws2811strip_stdperiph.c \ drivers/serial_uart_stm32f10x.c \ drivers/system_stm32f10x.c \ drivers/timer_stm32f10x.c @@ -826,8 +828,8 @@ STM32F30x_COMMON_SRC = \ drivers/bus_i2c_stm32f30x.c \ drivers/dma.c \ drivers/gpio_stm32f30x.c \ - drivers/light_ws2811strip_stm32f30x.c \ - drivers/pwm_output_stm32f3xx.c \ + drivers/light_ws2811strip_stdperiph.c \ + drivers/pwm_output_dshot.c \ drivers/serial_uart_stm32f30x.c \ drivers/system_stm32f30x.c \ drivers/timer_stm32f30x.c @@ -840,8 +842,8 @@ STM32F4xx_COMMON_SRC = \ drivers/dma_stm32f4xx.c \ drivers/gpio_stm32f4xx.c \ drivers/inverter.c \ - drivers/light_ws2811strip_stm32f4xx.c \ - drivers/pwm_output_stm32f4xx.c \ + drivers/light_ws2811strip_stdperiph.c \ + drivers/pwm_output_dshot.c \ drivers/serial_uart_stm32f4xx.c \ drivers/system_stm32f4xx.c \ drivers/timer_stm32f4xx.c diff --git a/src/main/drivers/dma.c b/src/main/drivers/dma.c index 672e73a20b..6a544915ea 100644 --- a/src/main/drivers/dma.c +++ b/src/main/drivers/dma.c @@ -99,7 +99,7 @@ uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier) dmaIdentifier_e dmaGetIdentifier(const DMA_Channel_TypeDef* channel) { for (int i = 0; i < DMA_MAX_DESCRIPTORS; i++) { - if (dmaDescriptors[i].channel == channel) { + if (dmaDescriptors[i].ref == channel) { return i; } } @@ -109,7 +109,7 @@ dmaIdentifier_e dmaGetIdentifier(const DMA_Channel_TypeDef* channel) dmaChannelDescriptor_t* getDmaDescriptor(const DMA_Channel_TypeDef* channel) { for (int i = 0; i < DMA_MAX_DESCRIPTORS; i++) { - if (dmaDescriptors[i].channel == channel) { + if (dmaDescriptors[i].ref == channel) { return &dmaDescriptors[i]; } } diff --git a/src/main/drivers/dma.h b/src/main/drivers/dma.h index 771aa58567..29910bc025 100644 --- a/src/main/drivers/dma.h +++ b/src/main/drivers/dma.h @@ -25,9 +25,9 @@ typedef void (*dmaCallbackHandlerFuncPtr)(struct dmaChannelDescriptor_s *channel typedef struct dmaChannelDescriptor_s { DMA_TypeDef* dma; #if defined(STM32F4) || defined(STM32F7) - DMA_Stream_TypeDef* stream; + DMA_Stream_TypeDef* ref; #else - DMA_Channel_TypeDef* channel; + DMA_Channel_TypeDef* ref; #endif dmaCallbackHandlerFuncPtr irqHandlerCallback; uint8_t flagsShift; @@ -71,7 +71,7 @@ typedef enum { #define DMA_OUTPUT_INDEX 0 #define DMA_OUTPUT_STRING "DMA%d Stream %d:" -#define DEFINE_DMA_CHANNEL(d, s, f, i, r) {.dma = d, .stream = s, .irqHandlerCallback = NULL, .flagsShift = f, .irqN = i, .rcc = r, .userParam = 0, .owner = 0, .resourceIndex = 0 } +#define DEFINE_DMA_CHANNEL(d, s, f, i, r) {.dma = d, .ref = s, .irqHandlerCallback = NULL, .flagsShift = f, .irqN = i, .rcc = r, .userParam = 0, .owner = 0, .resourceIndex = 0 } #define DEFINE_DMA_IRQ_HANDLER(d, s, i) void DMA ## d ## _Stream ## s ## _IRQHandler(void) {\ if (dmaDescriptors[i].irqHandlerCallback)\ dmaDescriptors[i].irqHandlerCallback(&dmaDescriptors[i]);\ @@ -115,7 +115,7 @@ typedef enum { #define DMA_OUTPUT_INDEX 0 #define DMA_OUTPUT_STRING "DMA%d Channel %d:" -#define DEFINE_DMA_CHANNEL(d, c, f, i, r) {.dma = d, .channel = c, .irqHandlerCallback = NULL, .flagsShift = f, .irqN = i, .rcc = r, .userParam = 0, .owner = 0, .resourceIndex = 0 } +#define DEFINE_DMA_CHANNEL(d, c, f, i, r) {.dma = d, .ref = c, .irqHandlerCallback = NULL, .flagsShift = f, .irqN = i, .rcc = r, .userParam = 0, .owner = 0, .resourceIndex = 0 } #define DEFINE_DMA_IRQ_HANDLER(d, c, i) void DMA ## d ## _Channel ## c ## _IRQHandler(void) {\ if (dmaDescriptors[i].irqHandlerCallback)\ dmaDescriptors[i].irqHandlerCallback(&dmaDescriptors[i]);\ diff --git a/src/main/drivers/dma_stm32f4xx.c b/src/main/drivers/dma_stm32f4xx.c index 24258e820a..b0c428564d 100644 --- a/src/main/drivers/dma_stm32f4xx.c +++ b/src/main/drivers/dma_stm32f4xx.c @@ -118,7 +118,7 @@ uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier) dmaIdentifier_e dmaGetIdentifier(const DMA_Stream_TypeDef* stream) { for (int i = 0; i < DMA_MAX_DESCRIPTORS; i++) { - if (dmaDescriptors[i].stream == stream) { + if (dmaDescriptors[i].ref == stream) { return i; } } @@ -128,7 +128,7 @@ dmaIdentifier_e dmaGetIdentifier(const DMA_Stream_TypeDef* stream) dmaChannelDescriptor_t* getDmaDescriptor(const DMA_Stream_TypeDef* stream) { for (int i = 0; i < DMA_MAX_DESCRIPTORS; i++) { - if (dmaDescriptors[i].stream == stream) { + if (dmaDescriptors[i].ref == stream) { return &dmaDescriptors[i]; } } diff --git a/src/main/drivers/dma_stm32f7xx.c b/src/main/drivers/dma_stm32f7xx.c index 2ff6bfc2f1..0cc4b8b419 100644 --- a/src/main/drivers/dma_stm32f7xx.c +++ b/src/main/drivers/dma_stm32f7xx.c @@ -110,7 +110,7 @@ uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier) dmaIdentifier_e dmaGetIdentifier(const DMA_Stream_TypeDef* stream) { for (int i = 0; i < DMA_MAX_DESCRIPTORS; i++) { - if (dmaDescriptors[i].stream == stream) { + if (dmaDescriptors[i].ref == stream) { return i; } } diff --git a/src/main/drivers/light_ws2811strip.c b/src/main/drivers/light_ws2811strip.c index ccee17a4ed..593a563e91 100644 --- a/src/main/drivers/light_ws2811strip.c +++ b/src/main/drivers/light_ws2811strip.c @@ -47,6 +47,9 @@ uint32_t ledStripDMABuffer[WS2811_DMA_BUFFER_SIZE]; #endif volatile uint8_t ws2811LedDataTransferInProgress = 0; +uint16_t BIT_COMPARE_1 = 0; +uint16_t BIT_COMPARE_0 = 0; + static hsvColor_t ledColorBuffer[WS2811_LED_STRIP_LENGTH]; void setLedHsv(uint16_t index, const hsvColor_t *color) @@ -90,7 +93,7 @@ void ws2811LedStripInit(ioTag_t ioTag) memset(ledStripDMABuffer, 0, sizeof(ledStripDMABuffer)); ws2811LedStripHardwareInit(ioTag); - const hsvColor_t hsv_white = { 0, 255, 255}; + const hsvColor_t hsv_white = { 0, 255, 255 }; setStripColor(&hsv_white); ws2811UpdateStrip(); } diff --git a/src/main/drivers/light_ws2811strip.h b/src/main/drivers/light_ws2811strip.h index 034d02a172..370021e3b3 100644 --- a/src/main/drivers/light_ws2811strip.h +++ b/src/main/drivers/light_ws2811strip.h @@ -24,30 +24,12 @@ // for 50us delay #define WS2811_DELAY_BUFFER_LENGTH 42 -#define WS2811_DATA_BUFFER_SIZE (WS2811_BITS_PER_LED * WS2811_LED_STRIP_LENGTH) +#define WS2811_DATA_BUFFER_SIZE (WS2811_BITS_PER_LED * WS2811_LED_STRIP_LENGTH) // number of bytes needed is #LEDs * 24 bytes + 42 trailing bytes) -#define WS2811_DMA_BUFFER_SIZE (WS2811_DATA_BUFFER_SIZE + WS2811_DELAY_BUFFER_LENGTH) +#define WS2811_DMA_BUFFER_SIZE (WS2811_DATA_BUFFER_SIZE + WS2811_DELAY_BUFFER_LENGTH) -#if defined(STM32F40_41xxx) -#define WS2811_TIMER_HZ 84000000 -#define WS2811_TIMER_PERIOD 104 -// timer compare value for logical 1 -#define BIT_COMPARE_1 67 -// timer compare value for logical 0 -#define BIT_COMPARE_0 33 -#elif defined(STM32F7) -// timer compare value for logical 1 -#define BIT_COMPARE_1 76 -// timer compare value for logical 0 -#define BIT_COMPARE_0 38 -#else -#define WS2811_TIMER_HZ 24000000 -#define WS2811_TIMER_PERIOD 29 -// timer compare value for logical 1 -#define BIT_COMPARE_1 17 -// timer compare value for logical 0 -#define BIT_COMPARE_0 9 -#endif +#define WS2811_TIMER_MHZ 24 +#define WS2811_CARRIER_HZ 800000 void ws2811LedStripInit(ioTag_t ioTag); @@ -73,3 +55,6 @@ extern uint8_t ledStripDMABuffer[WS2811_DMA_BUFFER_SIZE]; extern uint32_t ledStripDMABuffer[WS2811_DMA_BUFFER_SIZE]; #endif extern volatile uint8_t ws2811LedDataTransferInProgress; + +extern uint16_t BIT_COMPARE_1; +extern uint16_t BIT_COMPARE_0; \ No newline at end of file diff --git a/src/main/drivers/light_ws2811strip_hal.c b/src/main/drivers/light_ws2811strip_hal.c index 838f67522b..93698f649f 100644 --- a/src/main/drivers/light_ws2811strip_hal.c +++ b/src/main/drivers/light_ws2811strip_hal.c @@ -61,13 +61,20 @@ void ws2811LedStripHardwareInit(ioTag_t ioTag) TIM_TypeDef *timer = timerHardware->tim; timerChannel = timerHardware->channel; - if (timerHardware->dmaStream == NULL) { + if (timerHardware->dmaRef == NULL) { return; } TimHandle.Instance = timer; - TimHandle.Init.Prescaler = 1; - TimHandle.Init.Period = 135; // 800kHz + /* Compute the prescaler value */ + uint16_t prescaler = timerGetPrescalerByDesiredMhz(timer, WS2811_TIMER_MHZ); + uint16_t period = timerGetPeriodByPrescaler(timer, prescaler, WS2811_CARRIER_HZ); + + BIT_COMPARE_1 = period / 3 * 2; + BIT_COMPARE_0 = period / 3; + + TimHandle.Init.Prescaler = prescaler; + TimHandle.Init.Period = period; // 800kHz TimHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; if(HAL_TIM_PWM_Init(&TimHandle) != HAL_OK) @@ -99,7 +106,7 @@ void ws2811LedStripHardwareInit(ioTag_t ioTag) hdma_tim.Init.PeriphBurst = DMA_PBURST_SINGLE; /* Set hdma_tim instance */ - hdma_tim.Instance = timerHardware->dmaStream; + hdma_tim.Instance = timerHardware->dmaRef; uint16_t dmaSource = timerDmaSource(timerChannel); diff --git a/src/main/drivers/light_ws2811strip_stm32f4xx.c b/src/main/drivers/light_ws2811strip_stdperiph.c similarity index 73% rename from src/main/drivers/light_ws2811strip_stm32f4xx.c rename to src/main/drivers/light_ws2811strip_stdperiph.c index c2ab867971..36cd7aaae5 100644 --- a/src/main/drivers/light_ws2811strip_stm32f4xx.c +++ b/src/main/drivers/light_ws2811strip_stdperiph.c @@ -22,27 +22,32 @@ #ifdef LED_STRIP +#include "io.h" +#include "nvic.h" + #include "common/color.h" #include "light_ws2811strip.h" -#include "nvic.h" #include "dma.h" -#include "io.h" #include "system.h" #include "rcc.h" #include "timer.h" -#include "timer_stm32f4xx.h" -#include "io.h" static IO_t ws2811IO = IO_NONE; bool ws2811Initialised = false; -static DMA_Stream_TypeDef *stream = NULL; +#if defined(STM32F4) +static DMA_Stream_TypeDef *dmaRef = NULL; +#elif defined(STM32F3) || defined(STM32F1) +static DMA_Channel_TypeDef *dmaRef = NULL; +#else +#error "No MCU definition in light_ws2811strip_stdperiph.c" +#endif static TIM_TypeDef *timer = NULL; static void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor) { if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) { ws2811LedDataTransferInProgress = 0; - DMA_Cmd(descriptor->stream, DISABLE); + DMA_Cmd(descriptor->ref, DISABLE); DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF); } } @@ -60,32 +65,39 @@ void ws2811LedStripHardwareInit(ioTag_t ioTag) const timerHardware_t *timerHardware = timerGetByTag(ioTag, TIM_USE_ANY); timer = timerHardware->tim; - if (timerHardware->dmaStream == NULL) { + if (timerHardware->dmaRef == NULL) { return; } - RCC_ClockCmd(timerRCC(timer), ENABLE); - ws2811IO = IOGetByTag(ioTag); - /* GPIOA Configuration: TIM5 Channel 1 as alternate function push-pull */ IOInit(ws2811IO, OWNER_LED_STRIP, 0); +#ifdef STM32F1 + IOConfigGPIO(ws2811IO, IO_CONFIG(GPIO_Speed_50MHz, GPIO_Mode_AF_PP)); +#else IOConfigGPIOAF(ws2811IO, IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP), timerHardware->alternateFunction); +#endif + + RCC_ClockCmd(timerRCC(timer), ENABLE); // Stop timer TIM_Cmd(timer, DISABLE); /* Compute the prescaler value */ - uint16_t prescalerValue = (uint16_t)(SystemCoreClock / timerClockDivisor(timer) / WS2811_TIMER_HZ) - 1; + uint16_t prescaler = timerGetPrescalerByDesiredMhz(timer, WS2811_TIMER_MHZ); + uint16_t period = timerGetPeriodByPrescaler(timer, prescaler, WS2811_CARRIER_HZ); + + BIT_COMPARE_1 = period / 3 * 2; + BIT_COMPARE_0 = period / 3; /* Time base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); - TIM_TimeBaseStructure.TIM_Period = WS2811_TIMER_PERIOD; // 800kHz - TIM_TimeBaseStructure.TIM_Prescaler = prescalerValue; + TIM_TimeBaseStructure.TIM_Period = period; // 800kHz + TIM_TimeBaseStructure.TIM_Prescaler = prescaler; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(timer, &TIM_TimeBaseStructure); - /* PWM1 Mode configuration: Channel1 */ + /* PWM1 Mode configuration */ TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; if (timerHardware->output & TIMER_OUTPUT_N_CHANNEL) { @@ -109,30 +121,43 @@ void ws2811LedStripHardwareInit(ioTag_t ioTag) dmaInit(timerHardware->dmaIrqHandler, OWNER_LED_STRIP, 0); dmaSetHandler(timerHardware->dmaIrqHandler, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0); + + dmaRef = timerHardware->dmaRef; + DMA_DeInit(dmaRef); - stream = timerHardware->dmaStream; /* configure DMA */ - DMA_Cmd(stream, DISABLE); - DMA_DeInit(stream); + DMA_Cmd(dmaRef, DISABLE); + DMA_DeInit(dmaRef); DMA_StructInit(&DMA_InitStructure); - DMA_InitStructure.DMA_Channel = timerHardware->dmaChannel; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)timerCCR(timer, timerHardware->channel); - DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ledStripDMABuffer; - DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_BufferSize = WS2811_DMA_BUFFER_SIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + +#if defined(STM32F4) + DMA_InitStructure.DMA_Channel = timerHardware->dmaChannel; + DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ledStripDMABuffer; + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; 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_VeryHigh; +#elif defined(STM32F3) || defined(STM32F1) + DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ledStripDMABuffer; + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; +#endif + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; - DMA_Init(stream, &DMA_InitStructure); + DMA_Init(dmaRef, &DMA_InitStructure); TIM_DMACmd(timer, timerDmaSource(timerHardware->channel), ENABLE); - DMA_ITConfig(stream, DMA_IT_TC, ENABLE); - DMA_ClearITPendingBit(stream, dmaFlag_IT_TCIF(stream)); - + DMA_ITConfig(dmaRef, DMA_IT_TC, ENABLE); +#ifdef STM32F4 + DMA_ClearITPendingBit(dmaRef, dmaFlag_IT_TCIF(dmaRef)); +#endif ws2811Initialised = true; } @@ -141,10 +166,10 @@ void ws2811LedStripDMAEnable(void) if (!ws2811Initialised) return; - DMA_SetCurrDataCounter(stream, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred + DMA_SetCurrDataCounter(dmaRef, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred TIM_SetCounter(timer, 0); TIM_Cmd(timer, ENABLE); - DMA_Cmd(stream, ENABLE); + DMA_Cmd(dmaRef, ENABLE); } #endif diff --git a/src/main/drivers/light_ws2811strip_stm32f10x.c b/src/main/drivers/light_ws2811strip_stm32f10x.c deleted file mode 100644 index e458b866b3..0000000000 --- a/src/main/drivers/light_ws2811strip_stm32f10x.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * This file is part of Cleanflight. - * - * Cleanflight is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Cleanflight is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Cleanflight. If not, see . - */ - -#include -#include - -#include - -#ifdef LED_STRIP - -#include "common/color.h" -#include "light_ws2811strip.h" -#include "nvic.h" -#include "io.h" -#include "dma.h" -#include "rcc.h" -#include "timer.h" - -static IO_t ws2811IO = IO_NONE; -bool ws2811Initialised = false; -static DMA_Channel_TypeDef *dmaChannel = NULL; -static TIM_TypeDef *timer = NULL; - -static void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor) -{ - if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) { - ws2811LedDataTransferInProgress = 0; - DMA_Cmd(descriptor->channel, DISABLE); - DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF); - } -} - -void ws2811LedStripHardwareInit(ioTag_t ioTag) -{ - if (!ioTag) { - return; - } - - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; - TIM_OCInitTypeDef TIM_OCInitStructure; - DMA_InitTypeDef DMA_InitStructure; - - const timerHardware_t *timerHardware = timerGetByTag(ioTag, TIM_USE_ANY); - timer = timerHardware->tim; - - if (timerHardware->dmaChannel == NULL) { - return; - } - - ws2811IO = IOGetByTag(ioTag); - IOInit(ws2811IO, OWNER_LED_STRIP, 0); - IOConfigGPIO(ws2811IO, IO_CONFIG(GPIO_Speed_50MHz, GPIO_Mode_AF_PP)); - - RCC_ClockCmd(timerRCC(timer), ENABLE); - - /* Compute the prescaler value */ - uint16_t prescalerValue = (uint16_t) (SystemCoreClock / WS2811_TIMER_HZ) - 1; - /* Time base configuration */ - TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); - TIM_TimeBaseStructure.TIM_Period = WS2811_TIMER_PERIOD; // 800kHz - TIM_TimeBaseStructure.TIM_Prescaler = prescalerValue; - TIM_TimeBaseStructure.TIM_ClockDivision = 0; - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; - TIM_TimeBaseInit(timer, &TIM_TimeBaseStructure); - - /* PWM1 Mode configuration: Channel1 */ - TIM_OCStructInit(&TIM_OCInitStructure); - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; - TIM_OCInitStructure.TIM_Pulse = 0; - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; - TIM_OC1Init(timer, &TIM_OCInitStructure); - TIM_OC1PreloadConfig(timer, TIM_OCPreload_Enable); - - TIM_CtrlPWMOutputs(timer, ENABLE); - - /* configure DMA */ - dmaInit(timerHardware->dmaIrqHandler, OWNER_LED_STRIP, 0); - dmaSetHandler(timerHardware->dmaIrqHandler, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0); - - dmaChannel = timerHardware->dmaChannel; - DMA_DeInit(dmaChannel); - - DMA_StructInit(&DMA_InitStructure); - DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)timerCCR(timer, timerHardware->channel); - DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ledStripDMABuffer; - DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; - DMA_InitStructure.DMA_BufferSize = WS2811_DMA_BUFFER_SIZE; - DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; - DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; - DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; - DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; - DMA_InitStructure.DMA_Priority = DMA_Priority_High; - DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; - - DMA_Init(dmaChannel, &DMA_InitStructure); - - /* TIM3 CC1 DMA Request enable */ - TIM_DMACmd(timer, timerDmaSource(timerHardware->channel), ENABLE); - - DMA_ITConfig(dmaChannel, DMA_IT_TC, ENABLE); - - ws2811Initialised = true; -} - -void ws2811LedStripDMAEnable(void) -{ - if (!ws2811Initialised) - return; - - DMA_SetCurrDataCounter(dmaChannel, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred - TIM_SetCounter(timer, 0); - TIM_Cmd(timer, ENABLE); - DMA_Cmd(dmaChannel, ENABLE); -} - -#endif diff --git a/src/main/drivers/light_ws2811strip_stm32f30x.c b/src/main/drivers/light_ws2811strip_stm32f30x.c deleted file mode 100644 index 204d415e71..0000000000 --- a/src/main/drivers/light_ws2811strip_stm32f30x.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * This file is part of Cleanflight. - * - * Cleanflight is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Cleanflight is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Cleanflight. If not, see . - */ - -#include -#include - -#include - -#ifdef LED_STRIP - -#include "io.h" -#include "nvic.h" - -#include "common/color.h" -#include "light_ws2811strip.h" -#include "dma.h" -#include "rcc.h" -#include "timer.h" - -static IO_t ws2811IO = IO_NONE; -bool ws2811Initialised = false; -static DMA_Channel_TypeDef *dmaChannel = NULL; -static TIM_TypeDef *timer = NULL; - -static void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor) -{ - if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) { - ws2811LedDataTransferInProgress = 0; - DMA_Cmd(descriptor->channel, DISABLE); - DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF); - } -} - -void ws2811LedStripHardwareInit(ioTag_t ioTag) -{ - if (!ioTag) { - return; - } - - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; - TIM_OCInitTypeDef TIM_OCInitStructure; - DMA_InitTypeDef DMA_InitStructure; - - const timerHardware_t *timerHardware = timerGetByTag(ioTag, TIM_USE_ANY); - timer = timerHardware->tim; - - if (timerHardware->dmaChannel == NULL) { - return; - } - - ws2811IO = IOGetByTag(ioTag); - IOInit(ws2811IO, OWNER_LED_STRIP, 0); - IOConfigGPIOAF(ws2811IO, IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP), timerHardware->alternateFunction); - - dmaInit(timerHardware->dmaIrqHandler, OWNER_LED_STRIP, 0); - dmaSetHandler(timerHardware->dmaIrqHandler, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0); - RCC_ClockCmd(timerRCC(timer), ENABLE); - - /* Compute the prescaler value */ - uint16_t prescalerValue = (uint16_t) (SystemCoreClock / WS2811_TIMER_HZ) - 1; - - /* Time base configuration */ - TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); - TIM_TimeBaseStructure.TIM_Period = WS2811_TIMER_PERIOD; // 800kHz - TIM_TimeBaseStructure.TIM_Prescaler = prescalerValue; - TIM_TimeBaseStructure.TIM_ClockDivision = 0; - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; - TIM_TimeBaseInit(timer, &TIM_TimeBaseStructure); - - /* PWM1 Mode configuration */ - TIM_OCStructInit(&TIM_OCInitStructure); - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; - if (timerHardware->output & TIMER_OUTPUT_N_CHANNEL) { - TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; - TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset; - } else { - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; - TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; - } - TIM_OCInitStructure.TIM_OCPolarity = (timerHardware->output & TIMER_OUTPUT_INVERTED) ? TIM_OCPolarity_Low : TIM_OCPolarity_High; - TIM_OCInitStructure.TIM_Pulse = 0; - TIM_OC1Init(timer, &TIM_OCInitStructure); - TIM_OC1PreloadConfig(timer, TIM_OCPreload_Enable); - - TIM_CtrlPWMOutputs(timer, ENABLE); - - /* configure DMA */ - /* DMA1 Channel Config */ - dmaChannel = timerHardware->dmaChannel; - DMA_DeInit(dmaChannel); - - DMA_StructInit(&DMA_InitStructure); - DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)timerCCR(timer, timerHardware->channel); - DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ledStripDMABuffer; - DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; - DMA_InitStructure.DMA_BufferSize = WS2811_DMA_BUFFER_SIZE; - 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_Byte; - DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; - DMA_InitStructure.DMA_Priority = DMA_Priority_High; - DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; - - DMA_Init(dmaChannel, &DMA_InitStructure); - - TIM_DMACmd(timer, timerDmaSource(timerHardware->channel), ENABLE); - - DMA_ITConfig(dmaChannel, DMA_IT_TC, ENABLE); - - ws2811Initialised = true; -} - -void ws2811LedStripDMAEnable(void) -{ - if (!ws2811Initialised) - return; - - DMA_SetCurrDataCounter(dmaChannel, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred - TIM_SetCounter(timer, 0); - TIM_Cmd(timer, ENABLE); - DMA_Cmd(dmaChannel, ENABLE); -} - -#endif diff --git a/src/main/drivers/pwm_output_stm32f3xx.c b/src/main/drivers/pwm_output_dshot.c similarity index 84% rename from src/main/drivers/pwm_output_stm32f3xx.c rename to src/main/drivers/pwm_output_dshot.c index fc5a8ff5f4..66ac9fd5c8 100644 --- a/src/main/drivers/pwm_output_stm32f3xx.c +++ b/src/main/drivers/pwm_output_dshot.c @@ -22,10 +22,11 @@ #ifdef USE_DSHOT -#include "build/debug.h" - #include "io.h" #include "timer.h" +#ifdef STM32F4 +#include "timer_stm32f4xx.h" +#endif #include "pwm_output.h" #include "nvic.h" #include "dma.h" @@ -61,7 +62,7 @@ void pwmWriteDigital(uint8_t index, uint16_t value) motorDmaOutput_t * const motor = &dmaMotors[index]; - if (!motor->timerHardware || !motor->timerHardware->dmaChannel) { + if (!motor->timerHardware || !motor->timerHardware->dmaRef) { return; } @@ -84,11 +85,11 @@ void pwmWriteDigital(uint8_t index, uint16_t value) packet <<= 1; } - DMA_Cmd(motor->timerHardware->dmaChannel, DISABLE); + DMA_Cmd(motor->timerHardware->dmaRef, DISABLE); TIM_DMACmd(motor->timerHardware->tim, motor->timerDmaSource, DISABLE); - DMA_SetCurrDataCounter(motor->timerHardware->dmaChannel, MOTOR_DMA_BUFFER_SIZE); + DMA_SetCurrDataCounter(motor->timerHardware->dmaRef, MOTOR_DMA_BUFFER_SIZE); DMA_CLEAR_FLAG(motor->dmaDescriptor, DMA_IT_TCIF); - DMA_Cmd(motor->timerHardware->dmaChannel, ENABLE); + DMA_Cmd(motor->timerHardware->dmaRef, ENABLE); } void pwmCompleteDigitalMotorUpdate(uint8_t motorCount) @@ -163,21 +164,39 @@ void pwmDigitalMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t TIM_Cmd(timer, ENABLE); } - DMA_Channel_TypeDef *channel = timerHardware->dmaChannel; +#if defined(STM32F3) + DMA_Channel_TypeDef *dmaRef = timerHardware->dmaRef; +#elif defined(STM32F4) + DMA_Stream_TypeDef *dmaRef = timerHardware->dmaRef; +#else +#error "No MCU specified in DSHOT" +#endif - if (channel == NULL) { - /* trying to use a non valid channel */ + if (dmaRef == NULL) { return; } dmaInit(timerHardware->dmaIrqHandler, OWNER_MOTOR, RESOURCE_INDEX(motorIndex)); - motor->dmaDescriptor = getDmaDescriptor(channel); + motor->dmaDescriptor = getDmaDescriptor(dmaRef); + + DMA_Cmd(dmaRef, DISABLE); + DMA_DeInit(dmaRef); - DMA_DeInit(channel); DMA_StructInit(&DMA_InitStructure); - DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)timerChCCR(timerHardware); +#if defined(STM32F3) DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)motor->dmaBuffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; + DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; +#elif defined(STM32F4) + DMA_InitStructure.DMA_Channel = timerHardware->channel; + DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)motor->dmaBuffer; + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; +#endif + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)timerChCCR(timerHardware); DMA_InitStructure.DMA_BufferSize = MOTOR_DMA_BUFFER_SIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; @@ -185,9 +204,8 @@ void pwmDigitalMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; - DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; - DMA_Init(channel, &DMA_InitStructure); + DMA_Init(dmaRef, &DMA_InitStructure); } #endif diff --git a/src/main/drivers/pwm_output_stm32f4xx.c b/src/main/drivers/pwm_output_stm32f4xx.c deleted file mode 100644 index 0ce3ec006e..0000000000 --- a/src/main/drivers/pwm_output_stm32f4xx.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * This file is part of Betaflight. - * - * Betaflight is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Betaflight is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Betaflight. If not, see . - */ -#include -#include -#include - -#include "platform.h" - -#ifdef USE_DSHOT - -#include "io.h" -#include "timer.h" -#include "timer_stm32f4xx.h" -#include "pwm_output.h" -#include "nvic.h" -#include "dma.h" -#include "system.h" -#include "rcc.h" - -static uint8_t dmaMotorTimerCount = 0; -static motorDmaTimer_t dmaMotorTimers[MAX_DMA_TIMERS]; -static motorDmaOutput_t dmaMotors[MAX_SUPPORTED_MOTORS]; - -motorDmaOutput_t *getMotorDmaOutput(uint8_t index) -{ - return &dmaMotors[index]; -} - -uint8_t getTimerIndex(TIM_TypeDef *timer) -{ - for (int i = 0; i < dmaMotorTimerCount; i++) { - if (dmaMotorTimers[i].timer == timer) { - return i; - } - } - dmaMotorTimers[dmaMotorTimerCount++].timer = timer; - return dmaMotorTimerCount-1; -} - -void pwmWriteDigital(uint8_t index, uint16_t value) -{ - if (!pwmMotorsEnabled) { - return; - } - - motorDmaOutput_t * const motor = &dmaMotors[index]; - - if (!motor->timerHardware || !motor->timerHardware->dmaStream) { - return; - } - - uint16_t packet = (value << 1) | (motor->requestTelemetry ? 1 : 0); - motor->requestTelemetry = false; // reset telemetry request to make sure it's triggered only once in a row - - // compute checksum - int csum = 0; - int csum_data = packet; - for (int i = 0; i < 3; i++) { - csum ^= csum_data; // xor data by nibbles - csum_data >>= 4; - } - csum &= 0xf; - // append checksum - packet = (packet << 4) | csum; - // generate pulses for whole packet - for (int i = 0; i < 16; i++) { - motor->dmaBuffer[i] = (packet & 0x8000) ? MOTOR_BIT_1 : MOTOR_BIT_0; // MSB first - packet <<= 1; - } - - TIM_DMACmd(motor->timerHardware->tim, motor->timerDmaSource, DISABLE); - DMA_SetCurrDataCounter(motor->timerHardware->dmaStream, MOTOR_DMA_BUFFER_SIZE); - DMA_CLEAR_FLAG(motor->dmaDescriptor, DMA_IT_TCIF); - DMA_Cmd(motor->timerHardware->dmaStream, ENABLE); -} - -void pwmCompleteDigitalMotorUpdate(uint8_t motorCount) -{ - UNUSED(motorCount); - - if (!pwmMotorsEnabled) { - return; - } - - for (int i = 0; i < dmaMotorTimerCount; i++) { - TIM_SetCounter(dmaMotorTimers[i].timer, 0); - TIM_DMACmd(dmaMotorTimers[i].timer, dmaMotorTimers[i].timerDmaSources, ENABLE); - } -} - -void pwmDigitalMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t motorIndex, motorPwmProtocolTypes_e pwmProtocolType, uint8_t output) -{ - TIM_OCInitTypeDef TIM_OCInitStructure; - DMA_InitTypeDef DMA_InitStructure; - - motorDmaOutput_t * const motor = &dmaMotors[motorIndex]; - motor->timerHardware = timerHardware; - - TIM_TypeDef *timer = timerHardware->tim; - const IO_t motorIO = IOGetByTag(timerHardware->tag); - - const uint8_t timerIndex = getTimerIndex(timer); - const bool configureTimer = (timerIndex == dmaMotorTimerCount-1); - - IOInit(motorIO, OWNER_MOTOR, RESOURCE_INDEX(motorIndex)); - IOConfigGPIOAF(motorIO, IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP), timerHardware->alternateFunction); - - if (configureTimer) { - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; - TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); - - RCC_ClockCmd(timerRCC(timer), ENABLE); - TIM_Cmd(timer, DISABLE); - - TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock / timerClockDivisor(timer) / getDshotHz(pwmProtocolType)) - 1; - TIM_TimeBaseStructure.TIM_Period = MOTOR_BITLENGTH; - TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; - TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; - TIM_TimeBaseInit(timer, &TIM_TimeBaseStructure); - } - - TIM_OCStructInit(&TIM_OCInitStructure); - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; - if (output & TIMER_OUTPUT_N_CHANNEL) { - TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; - TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset; - TIM_OCInitStructure.TIM_OCNPolarity = (output & TIMER_OUTPUT_INVERTED) ? TIM_OCNPolarity_Low : TIM_OCNPolarity_High; - } else { - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; - TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; - TIM_OCInitStructure.TIM_OCPolarity = (output & TIMER_OUTPUT_INVERTED) ? TIM_OCPolarity_Low : TIM_OCPolarity_High; - } - TIM_OCInitStructure.TIM_Pulse = 0; - - 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); - - if (configureTimer) { - TIM_CtrlPWMOutputs(timer, ENABLE); - TIM_ARRPreloadConfig(timer, ENABLE); - TIM_Cmd(timer, ENABLE); - } - - DMA_Stream_TypeDef *stream = timerHardware->dmaStream; - - if (stream == NULL) { - /* trying to use a non valid stream */ - return; - } - - dmaInit(timerHardware->dmaIrqHandler, OWNER_MOTOR, RESOURCE_INDEX(motorIndex)); - motor->dmaDescriptor = getDmaDescriptor(stream); - - DMA_Cmd(stream, DISABLE); - DMA_DeInit(stream); - - DMA_StructInit(&DMA_InitStructure); - DMA_InitStructure.DMA_Channel = timerHardware->dmaChannel; - 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; - 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_VeryHigh; - DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; - DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; - DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; - DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; - - DMA_Init(stream, &DMA_InitStructure); -} - -#endif diff --git a/src/main/drivers/pwm_output_stm32f7xx.c b/src/main/drivers/pwm_output_stm32f7xx.c index 72a02d6660..66df5c1228 100644 --- a/src/main/drivers/pwm_output_stm32f7xx.c +++ b/src/main/drivers/pwm_output_stm32f7xx.c @@ -58,7 +58,7 @@ void pwmWriteDigital(uint8_t index, uint16_t value) motorDmaOutput_t * const motor = &dmaMotors[index]; - if (!motor->timerHardware || !motor->timerHardware->dmaStream) { + if (!motor->timerHardware || !motor->timerHardware->dmaRef) { return; } @@ -151,12 +151,12 @@ void pwmDigitalMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t motor->hdma_tim.Init.PeriphBurst = DMA_PBURST_SINGLE; /* Set hdma_tim instance */ - if(timerHardware->dmaStream == NULL) + if(timerHardware->dmaRef == NULL) { /* Initialization Error */ return; } - motor->hdma_tim.Instance = timerHardware->dmaStream; + motor->hdma_tim.Instance = timerHardware->dmaRef; /* Link hdma_tim to hdma[x] (channelx) */ __HAL_LINKDMA(&motor->TimHandle, hdma[motor->timerDmaSource], motor->hdma_tim); diff --git a/src/main/drivers/serial_uart_stm32f10x.c b/src/main/drivers/serial_uart_stm32f10x.c index 493146644e..1407b9ea0f 100644 --- a/src/main/drivers/serial_uart_stm32f10x.c +++ b/src/main/drivers/serial_uart_stm32f10x.c @@ -81,7 +81,7 @@ void uart_tx_dma_IRQHandler(dmaChannelDescriptor_t* descriptor) { uartPort_t *s = (uartPort_t*)(descriptor->userParam); DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF); - DMA_Cmd(descriptor->channel, DISABLE); + DMA_Cmd(descriptor->ref, DISABLE); if (s->port.txBufferHead != s->port.txBufferTail) uartStartTxDMA(s); diff --git a/src/main/drivers/serial_uart_stm32f30x.c b/src/main/drivers/serial_uart_stm32f30x.c index 51f256038a..a65d28aa8d 100644 --- a/src/main/drivers/serial_uart_stm32f30x.c +++ b/src/main/drivers/serial_uart_stm32f30x.c @@ -104,7 +104,7 @@ static void handleUsartTxDma(dmaChannelDescriptor_t* descriptor) { uartPort_t *s = (uartPort_t*)(descriptor->userParam); DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF); - DMA_Cmd(descriptor->channel, DISABLE); + DMA_Cmd(descriptor->ref, DISABLE); if (s->port.txBufferHead != s->port.txBufferTail) uartStartTxDMA(s); diff --git a/src/main/drivers/timer.c b/src/main/drivers/timer.c index 562993f2a1..f77e54a057 100755 --- a/src/main/drivers/timer.c +++ b/src/main/drivers/timer.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "platform.h" @@ -842,3 +843,17 @@ uint16_t timerDmaSource(uint8_t channel) return 0; } #endif + +uint16_t timerGetPrescalerByDesiredMhz(TIM_TypeDef *tim, uint16_t mhz) +{ + // protection here for desired MHZ > SystemCoreClock??? + if ((uint32_t)(mhz * 1000000) > (SystemCoreClock / timerClockDivisor(tim))) { + return 0; + } + return (uint16_t)(round((SystemCoreClock / timerClockDivisor(tim) / (mhz * 1000000)) - 1)); +} + +uint16_t timerGetPeriodByPrescaler(TIM_TypeDef *tim, uint16_t prescaler, uint32_t hertz) +{ + return ((uint16_t)((SystemCoreClock / timerClockDivisor(tim) / (prescaler + 1)) / hertz)); +} \ No newline at end of file diff --git a/src/main/drivers/timer.h b/src/main/drivers/timer.h index 9e002b86fb..d3c34f5c1c 100644 --- a/src/main/drivers/timer.h +++ b/src/main/drivers/timer.h @@ -97,10 +97,10 @@ typedef struct timerHardware_s { #endif #if defined(USE_DSHOT) || defined(LED_STRIP) #if defined(STM32F4) || defined(STM32F7) - DMA_Stream_TypeDef *dmaStream; + DMA_Stream_TypeDef *dmaRef; uint32_t dmaChannel; #elif defined(STM32F3) || defined(STM32F1) - DMA_Channel_TypeDef *dmaChannel; + DMA_Channel_TypeDef *dmaRef; #endif uint8_t dmaIrqHandler; #endif @@ -197,3 +197,6 @@ void timerOCPreloadConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t preload); volatile timCCR_t *timerCCR(TIM_TypeDef *tim, uint8_t channel); uint16_t timerDmaSource(uint8_t channel); + +uint16_t timerGetPrescalerByDesiredMhz(TIM_TypeDef *tim, uint16_t mhz); +uint16_t timerGetPeriodByPrescaler(TIM_TypeDef *tim, uint16_t prescaler, uint32_t hertz); diff --git a/src/main/drivers/timer_hal.c b/src/main/drivers/timer_hal.c index 127e2a1d52..34f742c4c2 100644 --- a/src/main/drivers/timer_hal.c +++ b/src/main/drivers/timer_hal.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "platform.h" @@ -894,3 +895,17 @@ uint16_t timerDmaSource(uint8_t channel) } return 0; } + +uint16_t timerGetPrescalerByDesiredMhz(TIM_TypeDef *tim, uint16_t mhz) +{ + // protection here for desired MHZ > SystemCoreClock??? + if (mhz * 1000000 > (SystemCoreClock / timerClockDivisor(tim))) { + return 0; + } + return (uint16_t)(round((SystemCoreClock / timerClockDivisor(tim) / (mhz * 1000000)) - 1)); +} + +uint16_t timerGetPeriodByPrescaler(TIM_TypeDef *tim, uint16_t prescaler, uint32_t hertz) +{ + return ((uint16_t)((SystemCoreClock / timerClockDivisor(tim) / (prescaler + 1)) / hertz)); +} \ No newline at end of file diff --git a/src/main/drivers/transponder_ir.c b/src/main/drivers/transponder_ir.c index 1b2ff16781..590f68e123 100644 --- a/src/main/drivers/transponder_ir.c +++ b/src/main/drivers/transponder_ir.c @@ -21,17 +21,19 @@ #include +#ifdef TRANSPONDER + #include "dma.h" #include "nvic.h" #include "io.h" #include "rcc.h" #include "timer.h" -#if defined(STM32F4) -#include "timer_stm32f4xx.h" -#endif #include "transponder_ir.h" +#define TRANSPONDER_TIMER_MHZ 24 +#define TRANSPONDER_CARRIER_HZ 460750 + /* * Implementation note: * Using around over 700 bytes for a transponder DMA buffer is a little excessive, likely an alternative implementation that uses a fast @@ -44,12 +46,15 @@ uint8_t transponderIrDMABuffer[TRANSPONDER_DMA_BUFFER_SIZE]; volatile uint8_t transponderIrDataTransferInProgress = 0; +static uint8_t bitToggleOne = 0; +#define BIT_TOGGLE_0 0 + static IO_t transponderIO = IO_NONE; static TIM_TypeDef *timer = NULL; #if defined(STM32F3) -static DMA_Channel_TypeDef *dmaChannel = NULL; +static DMA_Channel_TypeDef *dmaRef = NULL; #elif defined(STM32F4) -static DMA_Stream_TypeDef *stream = NULL; +static DMA_Stream_TypeDef *dmaRef = NULL; #else #error "Transponder not supported on this MCU." #endif @@ -58,11 +63,8 @@ static void TRANSPONDER_DMA_IRQHandler(dmaChannelDescriptor_t* descriptor) { if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) { transponderIrDataTransferInProgress = 0; -#if defined(STM32F3) - DMA_Cmd(descriptor->channel, DISABLE); -#elif defined(STM32F4) - DMA_Cmd(descriptor->stream, DISABLE); -#endif + + DMA_Cmd(descriptor->ref, DISABLE); DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF); } } @@ -80,15 +82,9 @@ void transponderIrHardwareInit(ioTag_t ioTag) const timerHardware_t *timerHardware = timerGetByTag(ioTag, TIM_USE_ANY); timer = timerHardware->tim; -#if defined(STM32F3) - if (timerHardware->dmaChannel == NULL) { + if (timerHardware->dmaRef == NULL) { return; } -#elif defined(STM32F4) - if (timerHardware->dmaStream == NULL) { - return; - } -#endif transponderIO = IOGetByTag(ioTag); IOInit(transponderIO, OWNER_TRANSPONDER, 0); @@ -99,10 +95,15 @@ void transponderIrHardwareInit(ioTag_t ioTag) RCC_ClockCmd(timerRCC(timer), ENABLE); + uint16_t prescaler = timerGetPrescalerByDesiredMhz(timer, TRANSPONDER_TIMER_MHZ); + uint16_t period = timerGetPeriodByPrescaler(timer, prescaler, TRANSPONDER_CARRIER_HZ); + + bitToggleOne = period / 2; + /* Time base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); - TIM_TimeBaseStructure.TIM_Period = 156; - TIM_TimeBaseStructure.TIM_Prescaler = 0; + TIM_TimeBaseStructure.TIM_Period = period; + TIM_TimeBaseStructure.TIM_Prescaler = prescaler; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(timer, &TIM_TimeBaseStructure); @@ -120,31 +121,26 @@ void transponderIrHardwareInit(ioTag_t ioTag) TIM_OCInitStructure.TIM_OCPolarity = (timerHardware->output & TIMER_OUTPUT_INVERTED) ? TIM_OCPolarity_Low : TIM_OCPolarity_High; TIM_OCInitStructure.TIM_Pulse = 0; -#if defined(STM32F3) - TIM_OC1Init(timer, &TIM_OCInitStructure); - TIM_OC1PreloadConfig(timer, TIM_OCPreload_Enable); -#elif defined(STM32F4) + timerOCInit(timer, timerHardware->channel, &TIM_OCInitStructure); timerOCPreloadConfig(timer, timerHardware->channel, TIM_OCPreload_Enable); -#endif TIM_CtrlPWMOutputs(timer, ENABLE); /* configure DMA */ -#if defined(STM32F3) - dmaChannel = timerHardware->dmaChannel; - DMA_DeInit(dmaChannel); -#elif defined(STM32F4) - stream = timerHardware->dmaStream; - DMA_Cmd(stream, DISABLE); - DMA_DeInit(stream); -#endif + dmaRef = timerHardware->dmaRef; + DMA_Cmd(dmaRef, DISABLE); + DMA_DeInit(dmaRef); DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)timerCCR(timer, timerHardware->channel); #if defined(STM32F3) DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)transponderIrDMABuffer; + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; + DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; #elif defined(STM32F4) + DMA_InitStructure.DMA_Channel = timerHardware->dmaChannel; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)transponderIrDMABuffer; + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; #endif DMA_InitStructure.DMA_BufferSize = TRANSPONDER_DMA_BUFFER_SIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; @@ -153,24 +149,12 @@ void transponderIrHardwareInit(ioTag_t ioTag) DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; -#if defined(STM32F3) - DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; - DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; - DMA_Init(dmaChannel, &DMA_InitStructure); -#elif defined(STM32F4) - DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; - - DMA_Init(stream, &DMA_InitStructure); -#endif + DMA_Init(dmaRef, &DMA_InitStructure); TIM_DMACmd(timer, timerDmaSource(timerHardware->channel), ENABLE); -#if defined(STM32F3) - DMA_ITConfig(dmaChannel, DMA_IT_TC, ENABLE); -#elif defined(STM32F4) - DMA_ITConfig(stream, DMA_IT_TC, ENABLE); -#endif + DMA_ITConfig(dmaRef, DMA_IT_TC, ENABLE); } bool transponderIrInit(void) @@ -226,7 +210,7 @@ void updateTransponderDMABuffer(const uint8_t* transponderData) for (toggleIndex = 0; toggleIndex < TRANSPONDER_TOGGLES_PER_BIT; toggleIndex++) { if (doToggles) { - transponderIrDMABuffer[dmaBufferOffset] = BIT_TOGGLE_1; + transponderIrDMABuffer[dmaBufferOffset] = bitToggleOne; } else { transponderIrDMABuffer[dmaBufferOffset] = BIT_TOGGLE_0; } @@ -256,27 +240,15 @@ void transponderIrUpdateData(const uint8_t* transponderData) void transponderIrDMAEnable(void) { -#if defined(STM32F3) - DMA_SetCurrDataCounter(dmaChannel, TRANSPONDER_DMA_BUFFER_SIZE); // load number of bytes to be transferred -#elif defined(STM32F4) - DMA_SetCurrDataCounter(stream, TRANSPONDER_DMA_BUFFER_SIZE); // load number of bytes to be transferred -#endif + DMA_SetCurrDataCounter(dmaRef, TRANSPONDER_DMA_BUFFER_SIZE); // load number of bytes to be transferred TIM_SetCounter(timer, 0); TIM_Cmd(timer, ENABLE); -#if defined(STM32F3) - DMA_Cmd(dmaChannel, ENABLE); -#elif defined(STM32F4) - DMA_Cmd(stream, ENABLE); -#endif + DMA_Cmd(dmaRef, ENABLE); } void transponderIrDisable(void) { -#if defined(STM32F3) - DMA_Cmd(dmaChannel, DISABLE); -#elif defined(STM32F4) - DMA_Cmd(stream, DISABLE); -#endif + DMA_Cmd(dmaRef, DISABLE); TIM_Cmd(timer, DISABLE); IOInit(transponderIO, OWNER_TRANSPONDER, 0); @@ -298,3 +270,4 @@ void transponderIrTransmit(void) transponderIrDataTransferInProgress = 1; transponderIrDMAEnable(); } +#endif \ No newline at end of file diff --git a/src/main/drivers/transponder_ir.h b/src/main/drivers/transponder_ir.h index a3e76d4443..0defc55cbd 100644 --- a/src/main/drivers/transponder_ir.h +++ b/src/main/drivers/transponder_ir.h @@ -27,9 +27,6 @@ #define TRANSPONDER_DMA_BUFFER_SIZE ((TRANSPONDER_TOGGLES_PER_BIT + 1) * TRANSPONDER_BITS_PER_BYTE * TRANSPONDER_DATA_LENGTH) -#define BIT_TOGGLE_1 78 // (156 / 2) -#define BIT_TOGGLE_0 0 - bool transponderIrInit(); void transponderIrDisable(void); diff --git a/src/main/target/FURYF3/target.mk b/src/main/target/FURYF3/target.mk index b7049e3469..1cbb887de4 100644 --- a/src/main/target/FURYF3/target.mk +++ b/src/main/target/FURYF3/target.mk @@ -8,6 +8,5 @@ TARGET_SRC = \ drivers/accgyro_spi_mpu6000.c \ drivers/accgyro_mpu6500.c \ drivers/accgyro_spi_mpu6500.c \ - drivers/accgyro_spi_icm20689.c \ - drivers/pwm_output_stm32f3xx.c + drivers/accgyro_spi_icm20689.c diff --git a/src/main/target/FURYF4/target.mk b/src/main/target/FURYF4/target.mk index e1fb3c41bf..b35c30a577 100644 --- a/src/main/target/FURYF4/target.mk +++ b/src/main/target/FURYF4/target.mk @@ -6,6 +6,5 @@ TARGET_SRC = \ drivers/accgyro_spi_mpu6500.c \ drivers/accgyro_mpu6500.c \ drivers/accgyro_spi_icm20689.c \ - drivers/barometer_ms5611.c \ - drivers/pwm_output_stm32f4xx.c + drivers/barometer_ms5611.c diff --git a/src/main/target/KIWIF4/target.mk b/src/main/target/KIWIF4/target.mk index 97eca5e62b..d5bd1d71ea 100644 --- a/src/main/target/KIWIF4/target.mk +++ b/src/main/target/KIWIF4/target.mk @@ -3,8 +3,6 @@ FEATURES += VCP ONBOARDFLASH TARGET_SRC = \ drivers/accgyro_spi_mpu6000.c \ - drivers/light_ws2811strip.c \ - drivers/light_ws2811strip_stm32f4xx.c\ drivers/max7456.c \ io/osd.c diff --git a/src/main/target/OMNIBUS/target.mk b/src/main/target/OMNIBUS/target.mk index 39f1a27259..c71d5c570f 100644 --- a/src/main/target/OMNIBUS/target.mk +++ b/src/main/target/OMNIBUS/target.mk @@ -9,7 +9,4 @@ TARGET_SRC = \ drivers/compass_ak8963.c \ drivers/compass_ak8975.c \ drivers/compass_hmc5883l.c \ - drivers/max7456.c \ - drivers/serial_usb_vcp.c \ - drivers/transponder_ir.c \ - io/transponder_ir.c + drivers/max7456.c diff --git a/src/main/target/PIKOBLX/target.mk b/src/main/target/PIKOBLX/target.mk index fe40d79e32..3c5cd8c420 100644 --- a/src/main/target/PIKOBLX/target.mk +++ b/src/main/target/PIKOBLX/target.mk @@ -3,7 +3,4 @@ FEATURES = VCP TARGET_SRC = \ drivers/accgyro_mpu.c \ - drivers/accgyro_spi_mpu6000.c \ - drivers/transponder_ir.c \ - io/transponder_ir.c - + drivers/accgyro_spi_mpu6000.c diff --git a/src/main/target/RG_SSD_F3/target.mk b/src/main/target/RG_SSD_F3/target.mk index 9634576e0f..39be156069 100644 --- a/src/main/target/RG_SSD_F3/target.mk +++ b/src/main/target/RG_SSD_F3/target.mk @@ -3,12 +3,7 @@ FEATURES = VCP SDCARD TARGET_SRC = \ drivers/accgyro_mpu.c \ - drivers/accgyro_spi_mpu6000.c \ - drivers/light_ws2811strip.c \ - drivers/light_ws2811strip_stm32f30x.c \ - drivers/serial_usb_vcp.c \ - drivers/transponder_ir.c \ - io/transponder_ir.c + drivers/accgyro_spi_mpu6000.c HSE_VALUE = 12000000 diff --git a/src/main/target/SPRACINGF3EVO/target.mk b/src/main/target/SPRACINGF3EVO/target.mk index 527c06f149..58c2ba63de 100644 --- a/src/main/target/SPRACINGF3EVO/target.mk +++ b/src/main/target/SPRACINGF3EVO/target.mk @@ -6,8 +6,5 @@ TARGET_SRC = \ drivers/accgyro_mpu6500.c \ drivers/accgyro_spi_mpu6500.c \ drivers/barometer_bmp280.c \ - drivers/compass_ak8963.c \ - drivers/serial_usb_vcp.c \ - drivers/transponder_ir.c \ - io/transponder_ir.c + drivers/compass_ak8963.c diff --git a/src/main/target/SPRACINGF3MINI/target.mk b/src/main/target/SPRACINGF3MINI/target.mk index 45713aeaaa..1ed60a29c1 100644 --- a/src/main/target/SPRACINGF3MINI/target.mk +++ b/src/main/target/SPRACINGF3MINI/target.mk @@ -8,9 +8,7 @@ TARGET_SRC = \ drivers/compass_ak8975.c \ drivers/compass_hmc5883l.c \ drivers/compass_ak8963.c \ - drivers/flash_m25p16.c \ - drivers/transponder_ir.c \ - io/transponder_ir.c + drivers/flash_m25p16.c ifeq ($(TARGET), TINYBEEF3) TARGET_SRC += \ diff --git a/src/main/target/SPRACINGF3NEO/target.mk b/src/main/target/SPRACINGF3NEO/target.mk index 5d664fa285..675bbda209 100755 --- a/src/main/target/SPRACINGF3NEO/target.mk +++ b/src/main/target/SPRACINGF3NEO/target.mk @@ -9,12 +9,7 @@ TARGET_SRC = \ drivers/barometer_ms5611.c \ drivers/compass_ak8975.c \ drivers/compass_hmc5883l.c \ - drivers/light_ws2811strip.c \ - drivers/light_ws2811strip_stm32f30x.c \ - drivers/serial_usb_vcp.c \ - drivers/transponder_ir.c \ drivers/max7456.c \ drivers/vtx_rtc6705.c \ io/osd.c \ - io/transponder_ir.c \ io/vtx.c