1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-16 21:05:35 +03:00

Re-design DMA driver

This commit is contained in:
Evgeny Sychov 2016-07-01 01:53:45 -07:00
parent 1c1dff4b12
commit 2d070a3507
16 changed files with 299 additions and 394 deletions

View file

@ -23,61 +23,66 @@
#include "build_config.h" #include "build_config.h"
#include "drivers/nvic.h"
#include "drivers/dma.h" #include "drivers/dma.h"
/* /*
* DMA handlers for DMA resources that are shared between different features depending on run-time configuration. * DMA descriptors.
*/ */
static dmaHandlers_t dmaHandlers; static dmaChannelDescriptor_t dmaDescriptors[] = {
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel1, 0, DMA1_Channel1_IRQn, RCC_AHBPeriph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel2, 4, DMA1_Channel2_IRQn, RCC_AHBPeriph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel3, 8, DMA1_Channel3_IRQn, RCC_AHBPeriph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel4, 12, DMA1_Channel4_IRQn, RCC_AHBPeriph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel5, 16, DMA1_Channel5_IRQn, RCC_AHBPeriph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel6, 20, DMA1_Channel6_IRQn, RCC_AHBPeriph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel7, 24, DMA1_Channel7_IRQn, RCC_AHBPeriph_DMA1),
#if defined(STM32F3) || defined(STM32F10X_CL)
DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel1, 0, DMA2_Channel1_IRQn, RCC_AHBPeriph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel2, 4, DMA2_Channel2_IRQn, RCC_AHBPeriph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel3, 8, DMA2_Channel3_IRQn, RCC_AHBPeriph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel4, 12, DMA2_Channel4_IRQn, RCC_AHBPeriph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel5, 16, DMA2_Channel5_IRQn, RCC_AHBPeriph_DMA2),
#endif
};
void dmaNoOpHandler(DMA_Channel_TypeDef *channel) /*
{ * DMA IRQ Handlers
UNUSED(channel); */
} DEFINE_DMA_IRQ_HANDLER(1, 1, DMA1_CH1_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 2, DMA1_CH2_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 3, DMA1_CH3_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 4, DMA1_CH4_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 5, DMA1_CH5_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 6, DMA1_CH6_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 7, DMA1_CH7_HANDLER)
void DMA1_Channel2_IRQHandler(void) #if defined(STM32F3) || defined(STM32F10X_CL)
{ DEFINE_DMA_IRQ_HANDLER(2, 1, DMA2_CH1_HANDLER)
dmaHandlers.dma1Channel2IRQHandler(DMA1_Channel2); DEFINE_DMA_IRQ_HANDLER(2, 2, DMA2_CH2_HANDLER)
} DEFINE_DMA_IRQ_HANDLER(2, 3, DMA2_CH3_HANDLER)
DEFINE_DMA_IRQ_HANDLER(2, 4, DMA2_CH4_HANDLER)
DEFINE_DMA_IRQ_HANDLER(2, 5, DMA2_CH5_HANDLER)
#endif
void DMA1_Channel3_IRQHandler(void)
{
dmaHandlers.dma1Channel3IRQHandler(DMA1_Channel3);
}
void DMA1_Channel6_IRQHandler(void)
{
dmaHandlers.dma1Channel6IRQHandler(DMA1_Channel6);
}
void DMA1_Channel7_IRQHandler(void)
{
dmaHandlers.dma1Channel7IRQHandler(DMA1_Channel7);
}
void dmaInit(void) void dmaInit(void)
{ {
memset(&dmaHandlers, 0, sizeof(dmaHandlers)); // TODO: Do we need this?
dmaHandlers.dma1Channel2IRQHandler = dmaNoOpHandler;
dmaHandlers.dma1Channel3IRQHandler = dmaNoOpHandler;
dmaHandlers.dma1Channel6IRQHandler = dmaNoOpHandler;
dmaHandlers.dma1Channel7IRQHandler = dmaNoOpHandler;
} }
void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback) void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam)
{ {
switch (identifier) { NVIC_InitTypeDef NVIC_InitStructure;
case DMA1_CH2_HANDLER:
dmaHandlers.dma1Channel2IRQHandler = callback; RCC_AHBPeriphClockCmd(dmaDescriptors[identifier].rrc, ENABLE);
break; dmaDescriptors[identifier].irqHandlerCallback = callback;
case DMA1_CH3_HANDLER: dmaDescriptors[identifier].userParam = userParam;
dmaHandlers.dma1Channel3IRQHandler = callback;
break; NVIC_InitStructure.NVIC_IRQChannel = dmaDescriptors[identifier].irqN;
case DMA1_CH6_HANDLER: NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(priority);
dmaHandlers.dma1Channel6IRQHandler = callback; NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(priority);
break; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
case DMA1_CH7_HANDLER: NVIC_Init(&NVIC_InitStructure);
dmaHandlers.dma1Channel7IRQHandler = callback;
break;
}
} }

View file

@ -15,37 +15,98 @@
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>. * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
*/ */
struct dmaChannelDescriptor_s;
typedef void (*dmaCallbackHandlerFuncPtr)(struct dmaChannelDescriptor_s *channelDescriptor);
#ifdef STM32F4 #ifdef STM32F4
typedef void(*dmaCallbackHandlerFuncPtr)(DMA_Stream_TypeDef *stream); typedef void(*dmaCallbackHandlerFuncPtr)(DMA_Stream_TypeDef *stream);
typedef enum { typedef enum {
DMA1_ST2_HANDLER = 0, DMA1_ST1_HANDLER = 0,
DMA1_ST2_HANDLER,
DMA1_ST3_HANDLER,
DMA1_ST4_HANDLER,
DMA1_ST5_HANDLER,
DMA1_ST6_HANDLER,
DMA1_ST7_HANDLER, DMA1_ST7_HANDLER,
DMA2_ST1_HANDLER,
DMA2_ST2_HANDLER,
DMA2_ST3_HANDLER,
DMA2_ST4_HANDLER,
DMA2_ST5_HANDLER,
DMA2_ST6_HANDLER,
DMA2_ST7_HANDLER,
} dmaHandlerIdentifier_e; } dmaHandlerIdentifier_e;
typedef struct dmaHandlers_s { typedef struct dmaChannelDescriptor_s {
dmaCallbackHandlerFuncPtr dma1Stream2IRQHandler; DMA_TypeDef* dma;
dmaCallbackHandlerFuncPtr dma1Stream7IRQHandler; DMA_Stream_TypeDef* stream;
} dmaHandlers_t; dmaCallbackHandlerFuncPtr irqHandlerCallback;
uint8_t flagsShift;
IRQn_Type irqN;
uint32_t rrc;
uint32_t userParam;
} dmaChannelDescriptor_t;
#define DEFINE_DMA_CHANNEL(d, s, f, i, r) {.dma = d, .stream = s, .irqHandlerCallback = NULL, .flagsShift = f, .irqN = i, .rrc = r, .userParam = 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]);\
}
#define DMA_CLEAR_FLAG(d, flag) d->flagsShift > 31 ? d->dma->HIFCR = (flag << (d->flagsShift - 32)) : d->dma->LIFCR = (flag << d->flagsShift)
#define DMA_GET_FLAG_STATUS(d, flag) (d->flagsShift > 31 ? d->dma->HISR & (flag << (d->flagsShift - 32)): d->dma->LISR & (flag << d->flagsShift))
#define DMA_IT_TCIF ((uint32_t)0x00000020)
#define DMA_IT_HTIF ((uint32_t)0x00000010)
#define DMA_IT_TEIF ((uint32_t)0x00000008)
#define DMA_IT_DMEIF ((uint32_t)0x00000004)
#define DMA_IT_FEIF ((uint32_t)0x00000001)
#else #else
typedef void (*dmaCallbackHandlerFuncPtr)(DMA_Channel_TypeDef *channel);
typedef enum { typedef enum {
DMA1_CH2_HANDLER = 0, DMA1_CH1_HANDLER = 0,
DMA1_CH2_HANDLER,
DMA1_CH3_HANDLER, DMA1_CH3_HANDLER,
DMA1_CH4_HANDLER,
DMA1_CH5_HANDLER,
DMA1_CH6_HANDLER, DMA1_CH6_HANDLER,
DMA1_CH7_HANDLER, DMA1_CH7_HANDLER,
DMA2_CH1_HANDLER,
DMA2_CH2_HANDLER,
DMA2_CH3_HANDLER,
DMA2_CH4_HANDLER,
DMA2_CH5_HANDLER,
} dmaHandlerIdentifier_e; } dmaHandlerIdentifier_e;
typedef struct dmaHandlers_s { typedef struct dmaChannelDescriptor_s {
dmaCallbackHandlerFuncPtr dma1Channel2IRQHandler; DMA_TypeDef* dma;
dmaCallbackHandlerFuncPtr dma1Channel3IRQHandler; DMA_Channel_TypeDef* channel;
dmaCallbackHandlerFuncPtr dma1Channel6IRQHandler; dmaCallbackHandlerFuncPtr irqHandlerCallback;
dmaCallbackHandlerFuncPtr dma1Channel7IRQHandler; uint8_t flagsShift;
} dmaHandlers_t; IRQn_Type irqN;
uint32_t rrc;
uint32_t userParam;
} dmaChannelDescriptor_t;
#define DEFINE_DMA_CHANNEL(d, c, f, i, r) {.dma = d, .channel = c, .irqHandlerCallback = NULL, .flagsShift = f, .irqN = i, .rrc = r, .userParam = 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]);\
}
#define DMA_CLEAR_FLAG(d, flag) d->dma->IFCR = (flag << d->flagsShift)
#define DMA_GET_FLAG_STATUS(d, flag) (d->dma->ISR & (flag << d->flagsShift))
#define DMA_IT_TCIF ((uint32_t)0x00000002)
#define DMA_IT_HTIF ((uint32_t)0x00000004)
#define DMA_IT_TEIF ((uint32_t)0x00000008)
#endif #endif
void dmaInit(void); void dmaInit(void);
void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback); void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam);

View file

@ -23,43 +23,66 @@
#include "build_config.h" #include "build_config.h"
#include "drivers/nvic.h"
#include "drivers/dma.h" #include "drivers/dma.h"
/* /*
* DMA handlers for DMA resources that are shared between different features depending on run-time configuration. * DMA descriptors.
*/ */
static dmaHandlers_t dmaHandlers; static dmaChannelDescriptor_t dmaDescriptors[] = {
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream0, 0, DMA1_Stream0_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream1, 6, DMA1_Stream1_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream2, 16, DMA1_Stream2_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream3, 22, DMA1_Stream3_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream4, 32, DMA1_Stream4_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream5, 38, DMA1_Stream5_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream6, 48, DMA1_Stream6_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream7, 54, DMA1_Stream7_IRQn, RCC_AHB1Periph_DMA1),
void dmaNoOpHandler(DMA_Stream_TypeDef *stream) DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream0, 0, DMA2_Stream0_IRQn, RCC_AHB1Periph_DMA2),
{ DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream1, 6, DMA2_Stream1_IRQn, RCC_AHB1Periph_DMA2),
UNUSED(stream); DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream2, 16, DMA2_Stream2_IRQn, RCC_AHB1Periph_DMA2),
} DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream3, 22, DMA2_Stream3_IRQn, RCC_AHB1Periph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream4, 32, DMA2_Stream4_IRQn, RCC_AHB1Periph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream5, 38, DMA2_Stream5_IRQn, RCC_AHB1Periph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream6, 48, DMA2_Stream6_IRQn, RCC_AHB1Periph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream7, 54, DMA2_Stream7_IRQn, RCC_AHB1Periph_DMA2),
void DMA1_Stream2_IRQHandler(void) };
{
dmaHandlers.dma1Stream2IRQHandler(DMA1_Stream2); /*
} * DMA IRQ Handlers
*/
DEFINE_DMA_IRQ_HANDLER(1, 1, DMA1_CH1_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 2, DMA1_CH2_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 3, DMA1_CH3_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 4, DMA1_CH4_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 5, DMA1_CH5_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 6, DMA1_CH6_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 7, DMA1_CH7_HANDLER)
DEFINE_DMA_IRQ_HANDLER(2, 1, DMA2_CH1_HANDLER)
DEFINE_DMA_IRQ_HANDLER(2, 2, DMA2_CH2_HANDLER)
DEFINE_DMA_IRQ_HANDLER(2, 3, DMA2_CH3_HANDLER)
DEFINE_DMA_IRQ_HANDLER(2, 4, DMA2_CH4_HANDLER)
DEFINE_DMA_IRQ_HANDLER(2, 5, DMA2_CH5_HANDLER)
void DMA1_Stream7_IRQHandler(void)
{
dmaHandlers.dma1Stream7IRQHandler(DMA1_Stream7);
}
void dmaInit(void) void dmaInit(void)
{ {
memset(&dmaHandlers, 0, sizeof(dmaHandlers)); // TODO: Do we need this?
dmaHandlers.dma1Stream2IRQHandler = dmaNoOpHandler;
dmaHandlers.dma1Stream7IRQHandler = dmaNoOpHandler;
} }
void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback) void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority)
{ {
switch (identifier) { NVIC_InitTypeDef NVIC_InitStructure;
case DMA1_ST2_HANDLER:
dmaHandlers.dma1Stream2IRQHandler = callback; RCC_AHB1PeriphClockCmd(dmaDescriptors[identifier].periphClk, ENABLE);
break; dmaDescriptors[identifier].irqHandlerCallback = callback;
case DMA1_ST7_HANDLER:
dmaHandlers.dma1Stream7IRQHandler = callback; NVIC_InitStructure.NVIC_IRQChannel = dmaDescriptors[identifier].irqN;
break; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(priority);
} NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(priority);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
} }

View file

@ -80,18 +80,9 @@ void setStripColors(const hsvColor_t *colors)
} }
} }
void ws2811DMAHandler(DMA_Channel_TypeDef *channel) {
if (DMA_GetFlagStatus(WS2811_DMA_TC_FLAG)) {
ws2811LedDataTransferInProgress = 0;
DMA_Cmd(channel, DISABLE);
DMA_ClearFlag(WS2811_DMA_TC_FLAG);
}
}
void ws2811LedStripInit(void) void ws2811LedStripInit(void)
{ {
memset(&ledStripDMABuffer, 0, WS2811_DMA_BUFFER_SIZE); memset(&ledStripDMABuffer, 0, WS2811_DMA_BUFFER_SIZE);
dmaSetHandler(WS2811_DMA_HANDLER_IDENTIFER, ws2811DMAHandler);
ws2811LedStripHardwareInit(); ws2811LedStripHardwareInit();
ws2811UpdateStrip(); ws2811UpdateStrip();
} }

View file

@ -23,6 +23,15 @@
#include "common/color.h" #include "common/color.h"
#include "drivers/light_ws2811strip.h" #include "drivers/light_ws2811strip.h"
#include "nvic.h" #include "nvic.h"
#include "dma.h"
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(void) void ws2811LedStripHardwareInit(void)
{ {
@ -100,13 +109,7 @@ void ws2811LedStripHardwareInit(void)
DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE); DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure; dmaSetHandler(DMA1_CH6_HANDLER, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_WS2811_DMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_WS2811_DMA);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
setStripColor(&hsv_white); setStripColor(&hsv_white);
ws2811UpdateStrip(); ws2811UpdateStrip();

View file

@ -22,6 +22,7 @@
#include "gpio.h" #include "gpio.h"
#include "nvic.h" #include "nvic.h"
#include "dma.h"
#include "common/color.h" #include "common/color.h"
#include "drivers/light_ws2811strip.h" #include "drivers/light_ws2811strip.h"
@ -41,6 +42,14 @@
#endif #endif
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(void) void ws2811LedStripHardwareInit(void)
{ {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
@ -114,13 +123,7 @@ void ws2811LedStripHardwareInit(void)
DMA_ITConfig(WS2811_DMA_CHANNEL, DMA_IT_TC, ENABLE); DMA_ITConfig(WS2811_DMA_CHANNEL, DMA_IT_TC, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure; dmaSetHandler(WS2811_DMA_HANDLER_IDENTIFER, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0);
NVIC_InitStructure.NVIC_IRQChannel = WS2811_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_WS2811_DMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_WS2811_DMA);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
setStripColor(&hsv_white); setStripColor(&hsv_white);
ws2811UpdateStrip(); ws2811UpdateStrip();

View file

@ -23,8 +23,20 @@
#include "common/color.h" #include "common/color.h"
#include "light_ws2811strip.h" #include "light_ws2811strip.h"
#include "nvic.h" #include "nvic.h"
#include "dma.h"
#ifdef LED_STRIP #ifdef LED_STRIP
static void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor)
{
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) {
ws2811LedDataTransferInProgress = 0;
DMA_Cmd(descriptor->stream, DISABLE);
TIM_DMACmd(TIM5, TIM_DMA_CC1, DISABLE);
DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
}
}
void ws2811LedStripHardwareInit(void) void ws2811LedStripHardwareInit(void)
{ {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
@ -98,28 +110,11 @@ void ws2811LedStripHardwareInit(void)
DMA_ITConfig(DMA1_Stream2, DMA_IT_TC, ENABLE); DMA_ITConfig(DMA1_Stream2, DMA_IT_TC, ENABLE);
DMA_ClearITPendingBit(DMA1_Stream2, DMA_IT_TCIF2); // clear DMA1 Channel 6 transfer complete flag DMA_ClearITPendingBit(DMA1_Stream2, DMA_IT_TCIF2); // clear DMA1 Channel 6 transfer complete flag
NVIC_InitTypeDef NVIC_InitStructure; dmaSetHandler(DMA1_ST2_HANDLER, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_WS2811_DMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_WS2811_DMA);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
setStripColor(&hsv_white); setStripColor(&hsv_white);
ws2811UpdateStrip(); ws2811UpdateStrip();
} }
void DMA1_Stream2_IRQHandler(void)
{
if (DMA_GetFlagStatus(DMA1_Stream2, DMA_FLAG_TCIF2)) {
ws2811LedDataTransferInProgress = 0;
DMA_Cmd(DMA1_Stream2, DISABLE);
TIM_DMACmd(TIM5, TIM_DMA_CC1, DISABLE);
DMA_ClearITPendingBit(DMA1_Stream2, DMA_IT_TCIF2);
}
}
void ws2811LedStripDMAEnable(void) void ws2811LedStripDMAEnable(void)
{ {
DMA_SetCurrDataCounter(DMA1_Stream2, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred DMA_SetCurrDataCounter(DMA1_Stream2, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred

View file

@ -30,6 +30,7 @@
#include "drivers/light_led.h" #include "drivers/light_led.h"
#include "drivers/system.h" #include "drivers/system.h"
#include "drivers/nvic.h" #include "drivers/nvic.h"
#include "drivers/dma.h"
#include "max7456.h" #include "max7456.h"
#include "max7456_symbols.h" #include "max7456_symbols.h"
@ -119,8 +120,8 @@ static void max7456_send_dma(void* tx_buffer, void* rx_buffer, uint16_t buffer_s
SPI_I2S_DMAReq_Tx, ENABLE); SPI_I2S_DMAReq_Tx, ENABLE);
} }
void MAX7456_DMA_IRQ_HANDLER_FUNCTION (void) { void max7456_dma_irq_handler(dmaChannelDescriptor_t* descriptor) {
if (DMA_GetFlagStatus(MAX7456_DMA_TC_FLAG)) { if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) {
#ifdef MAX7456_DMA_CHANNEL_RX #ifdef MAX7456_DMA_CHANNEL_RX
DMA_Cmd(MAX7456_DMA_CHANNEL_RX, DISABLE); DMA_Cmd(MAX7456_DMA_CHANNEL_RX, DISABLE);
#else #else
@ -131,7 +132,7 @@ void MAX7456_DMA_IRQ_HANDLER_FUNCTION (void) {
#endif #endif
DMA_Cmd(MAX7456_DMA_CHANNEL_TX, DISABLE); DMA_Cmd(MAX7456_DMA_CHANNEL_TX, DISABLE);
DMA_ClearFlag(MAX7456_DMA_TC_FLAG); DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
SPI_I2S_DMACmd(MAX7456_SPI_INSTANCE, SPI_I2S_DMACmd(MAX7456_SPI_INSTANCE,
#ifdef MAX7456_DMA_CHANNEL_RX #ifdef MAX7456_DMA_CHANNEL_RX
@ -141,7 +142,7 @@ void MAX7456_DMA_IRQ_HANDLER_FUNCTION (void) {
DISABLE_MAX7456; DISABLE_MAX7456;
for (uint16_t x = 0; x < max_screen_size; x++) for (uint16_t x = 0; x < max_screen_size; x++)
max7456_screen[x + 3] = MAX7456ADD_DMDI; max7456_screen[x + 3] = MAX7456_CHAR(' ');
dma_transaction_in_progress = 0; dma_transaction_in_progress = 0;
} }
} }
@ -206,7 +207,7 @@ void max7456_init(uint8_t video_system)
delay(100); delay(100);
for (x = 0; x < max_screen_size; x++) for (x = 0; x < max_screen_size; x++)
SCREEN_BUFFER[x] = MAX7456_CHAR(0); SCREEN_BUFFER[x] = MAX7456_CHAR(' ');
#ifdef MAX7456_DMA_CHANNEL_TX #ifdef MAX7456_DMA_CHANNEL_TX
max7456_screen[0] = (uint16_t)(MAX7456ADD_DMAH | (0 << 8)); max7456_screen[0] = (uint16_t)(MAX7456ADD_DMAH | (0 << 8));
@ -215,14 +216,7 @@ void max7456_init(uint8_t video_system)
max7456_screen[max_screen_size + 3] = (uint16_t)(MAX7456ADD_DMDI | (0xFF << 8)); max7456_screen[max_screen_size + 3] = (uint16_t)(MAX7456ADD_DMDI | (0xFF << 8));
max7456_screen[max_screen_size + 4] = (uint16_t)(MAX7456ADD_DMM | (0 << 8)); max7456_screen[max_screen_size + 4] = (uint16_t)(MAX7456ADD_DMM | (0 << 8));
RCC_AHBPeriphClockCmd(MAX7456_DMA_PERIPH_CLOCK, ENABLE); dmaSetHandler(MAX7456_DMA_IRQ_HANDLER_ID, max7456_dma_irq_handler, NVIC_PRIO_MAX7456_DMA, 0);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = MAX7456_DMA_IRQ_HANDLER_ID;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_MAX7456_DMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_MAX7456_DMA);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif #endif
} }

View file

@ -176,7 +176,7 @@
#define SYM_FT 0x0F #define SYM_FT 0x0F
// Voltage and amperage // Voltage and amperage
#define SYM_VOLT 0x00 #define SYM_VOLT 0x06
#define SYM_AMP 0x9A #define SYM_AMP 0x9A
#define SYM_MAH 0xA4 #define SYM_MAH 0xA4
#define SYM_WATT 0x57 #define SYM_WATT 0x57

View file

@ -31,6 +31,7 @@
#include "system.h" #include "system.h"
#include "gpio.h" #include "gpio.h"
#include "nvic.h" #include "nvic.h"
#include "dma.h"
#include "serial.h" #include "serial.h"
#include "serial_uart.h" #include "serial_uart.h"
@ -83,6 +84,22 @@ void usartIrqCallback(uartPort_t *s)
} }
#ifdef USE_USART1 #ifdef USE_USART1
// USART1 Tx DMA Handler
void USART1_DMA_IRQHandler(dmaChannelDescriptor_t* descriptor)
{
uartPort_t *s = &uartPort1;
DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
DMA_Cmd(descriptor->channel, DISABLE);
if (s->port.txBufferHead != s->port.txBufferTail)
uartStartTxDMA(s);
else
s->txDMAEmpty = true;
}
// USART1 - Telemetry (RX/TX by DMA) // USART1 - Telemetry (RX/TX by DMA)
uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t options) uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t options)
{ {
@ -90,7 +107,6 @@ uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t optio
static volatile uint8_t rx1Buffer[UART1_RX_BUFFER_SIZE]; static volatile uint8_t rx1Buffer[UART1_RX_BUFFER_SIZE];
static volatile uint8_t tx1Buffer[UART1_TX_BUFFER_SIZE]; static volatile uint8_t tx1Buffer[UART1_TX_BUFFER_SIZE];
gpio_config_t gpio; gpio_config_t gpio;
NVIC_InitTypeDef NVIC_InitStructure;
s = &uartPort1; s = &uartPort1;
s->port.vTable = uartVTable; s->port.vTable = uartVTable;
@ -137,14 +153,12 @@ uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t optio
} }
// DMA TX Interrupt // DMA TX Interrupt
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn; dmaSetHandler(DMA1_CH4_HANDLER, USART1_DMA_IRQHandler, NVIC_PRIO_SERIALUART1_TXDMA, 0);
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART1_TXDMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART1_TXDMA);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#ifndef USE_USART1_RX_DMA #ifndef USE_USART1_RX_DMA
// RX/TX Interrupt // RX/TX Interrupt
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART1); NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART1);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART1); NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART1);
@ -156,19 +170,6 @@ uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t optio
} }
// USART1 Tx DMA Handler
void DMA1_Channel4_IRQHandler(void)
{
uartPort_t *s = &uartPort1;
DMA_ClearITPendingBit(DMA1_IT_TC4);
DMA_Cmd(s->txDMAChannel, DISABLE);
if (s->port.txBufferHead != s->port.txBufferTail)
uartStartTxDMA(s);
else
s->txDMAEmpty = true;
}
// USART1 Rx/Tx IRQ Handler // USART1 Rx/Tx IRQ Handler
void USART1_IRQHandler(void) void USART1_IRQHandler(void)
{ {

View file

@ -32,6 +32,7 @@
#include "system.h" #include "system.h"
#include "gpio.h" #include "gpio.h"
#include "nvic.h" #include "nvic.h"
#include "dma.h"
#include "serial.h" #include "serial.h"
#include "serial_uart.h" #include "serial_uart.h"
@ -81,13 +82,24 @@ static uartPort_t uartPort2;
static uartPort_t uartPort3; static uartPort_t uartPort3;
#endif #endif
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);
if (s->port.txBufferHead != s->port.txBufferTail)
uartStartTxDMA(s);
else
s->txDMAEmpty = true;
}
#ifdef USE_USART1 #ifdef USE_USART1
uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t options) uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t options)
{ {
uartPort_t *s; uartPort_t *s;
static volatile uint8_t rx1Buffer[UART1_RX_BUFFER_SIZE]; static volatile uint8_t rx1Buffer[UART1_RX_BUFFER_SIZE];
static volatile uint8_t tx1Buffer[UART1_TX_BUFFER_SIZE]; static volatile uint8_t tx1Buffer[UART1_TX_BUFFER_SIZE];
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
s = &uartPort1; s = &uartPort1;
@ -139,14 +151,12 @@ uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t optio
} }
} }
// DMA TX Interrupt dmaSetHandler(DMA1_CH4_HANDLER, handleUsartTxDma, NVIC_PRIO_SERIALUART1_TXDMA, 0);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART1_TXDMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART1_TXDMA);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#ifndef USE_USART1_RX_DMA #ifndef USE_USART1_RX_DMA
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART1_RXDMA); NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART1_RXDMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART1_RXDMA); NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART1_RXDMA);
@ -164,7 +174,6 @@ uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode, portOptions_t optio
uartPort_t *s; uartPort_t *s;
static volatile uint8_t rx2Buffer[UART2_RX_BUFFER_SIZE]; static volatile uint8_t rx2Buffer[UART2_RX_BUFFER_SIZE];
static volatile uint8_t tx2Buffer[UART2_TX_BUFFER_SIZE]; static volatile uint8_t tx2Buffer[UART2_TX_BUFFER_SIZE];
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
s = &uartPort2; s = &uartPort2;
@ -222,14 +231,12 @@ uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode, portOptions_t optio
#ifdef USE_USART2_TX_DMA #ifdef USE_USART2_TX_DMA
// DMA TX Interrupt // DMA TX Interrupt
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn; dmaSetHandler(DMA1_CH7_HANDLER, handleUsartTxDma, NVIC_PRIO_SERIALUART2_TXDMA, 0);
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART2_TXDMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART2_TXDMA);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif #endif
#ifndef USE_USART2_RX_DMA #ifndef USE_USART2_RX_DMA
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART2_RXDMA); NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART2_RXDMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART2_RXDMA); NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART2_RXDMA);
@ -247,7 +254,6 @@ uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t optio
uartPort_t *s; uartPort_t *s;
static volatile uint8_t rx3Buffer[UART3_RX_BUFFER_SIZE]; static volatile uint8_t rx3Buffer[UART3_RX_BUFFER_SIZE];
static volatile uint8_t tx3Buffer[UART3_TX_BUFFER_SIZE]; static volatile uint8_t tx3Buffer[UART3_TX_BUFFER_SIZE];
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
s = &uartPort3; s = &uartPort3;
@ -305,14 +311,12 @@ uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t optio
#ifdef USE_USART3_TX_DMA #ifdef USE_USART3_TX_DMA
// DMA TX Interrupt // DMA TX Interrupt
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn; dmaSetHandler(DMA1_CH2_HANDLER, handleUsartTxDma, NVIC_PRIO_SERIALUART3_TXDMA, 0);
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART3_TXDMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART3_TXDMA);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif #endif
#ifndef USE_USART3_RX_DMA #ifndef USE_USART3_RX_DMA
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART3_RXDMA); NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART3_RXDMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART3_RXDMA); NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART3_RXDMA);
@ -324,48 +328,6 @@ uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t optio
} }
#endif #endif
static void handleUsartTxDma(uartPort_t *s)
{
DMA_Cmd(s->txDMAChannel, DISABLE);
if (s->port.txBufferHead != s->port.txBufferTail)
uartStartTxDMA(s);
else
s->txDMAEmpty = true;
}
// USART1 Tx DMA Handler
void DMA1_Channel4_IRQHandler(void)
{
uartPort_t *s = &uartPort1;
DMA_ClearITPendingBit(DMA1_IT_TC4);
DMA_Cmd(DMA1_Channel4, DISABLE);
handleUsartTxDma(s);
}
#ifdef USE_USART2_TX_DMA
// USART2 Tx DMA Handler
void DMA1_Channel7_IRQHandler(void)
{
uartPort_t *s = &uartPort2;
DMA_ClearITPendingBit(DMA1_IT_TC7);
DMA_Cmd(DMA1_Channel7, DISABLE);
handleUsartTxDma(s);
}
#endif
// USART3 Tx DMA Handler
#ifdef USE_USART3_TX_DMA
void DMA1_Channel2_IRQHandler(void)
{
uartPort_t *s = &uartPort3;
DMA_ClearITPendingBit(DMA1_IT_TC2);
DMA_Cmd(DMA1_Channel2, DISABLE);
handleUsartTxDma(s);
}
#endif
void usartIrqHandler(uartPort_t *s) void usartIrqHandler(uartPort_t *s)
{ {
uint32_t ISR = s->USARTx->ISR; uint32_t ISR = s->USARTx->ISR;

View file

@ -87,7 +87,7 @@ static uartDevice_t uart1 =
.rcc_ahb1 = USART1_AHB1_PERIPHERALS, .rcc_ahb1 = USART1_AHB1_PERIPHERALS,
#endif #endif
.rcc_apb2 = RCC_APB2(USART1), .rcc_apb2 = RCC_APB2(USART1),
.txIrq = DMA2_Stream7_IRQn, .txIrq = DMA2_ST7_HANDLER,
.rxIrq = USART1_IRQn, .rxIrq = USART1_IRQn,
.txPriority = NVIC_PRIO_SERIALUART1_TXDMA, .txPriority = NVIC_PRIO_SERIALUART1_TXDMA,
.rxPriority = NVIC_PRIO_SERIALUART1 .rxPriority = NVIC_PRIO_SERIALUART1
@ -110,7 +110,7 @@ static uartDevice_t uart2 =
.rcc_ahb1 = USART2_AHB1_PERIPHERALS, .rcc_ahb1 = USART2_AHB1_PERIPHERALS,
#endif #endif
.rcc_apb1 = RCC_APB1(USART2), .rcc_apb1 = RCC_APB1(USART2),
.txIrq = DMA1_Stream6_IRQn, .txIrq = DMA1_ST6_HANDLER,
.rxIrq = USART2_IRQn, .rxIrq = USART2_IRQn,
.txPriority = NVIC_PRIO_SERIALUART2_TXDMA, .txPriority = NVIC_PRIO_SERIALUART2_TXDMA,
.rxPriority = NVIC_PRIO_SERIALUART2 .rxPriority = NVIC_PRIO_SERIALUART2
@ -133,7 +133,7 @@ static uartDevice_t uart3 =
.rcc_ahb1 = USART3_AHB1_PERIPHERALS, .rcc_ahb1 = USART3_AHB1_PERIPHERALS,
#endif #endif
.rcc_apb1 = RCC_APB1(USART3), .rcc_apb1 = RCC_APB1(USART3),
.txIrq = DMA1_Stream3_IRQn, .txIrq = DMA1_ST3_HANDLER,
.rxIrq = USART3_IRQn, .rxIrq = USART3_IRQn,
.txPriority = NVIC_PRIO_SERIALUART3_TXDMA, .txPriority = NVIC_PRIO_SERIALUART3_TXDMA,
.rxPriority = NVIC_PRIO_SERIALUART3 .rxPriority = NVIC_PRIO_SERIALUART3
@ -156,7 +156,7 @@ static uartDevice_t uart4 =
.rcc_ahb1 = USART4_AHB1_PERIPHERALS, .rcc_ahb1 = USART4_AHB1_PERIPHERALS,
#endif #endif
.rcc_apb1 = RCC_APB1(UART4), .rcc_apb1 = RCC_APB1(UART4),
.txIrq = DMA1_Stream4_IRQn, .txIrq = DMA1_ST4_HANDLER,
.rxIrq = UART4_IRQn, .rxIrq = UART4_IRQn,
.txPriority = NVIC_PRIO_SERIALUART4_TXDMA, .txPriority = NVIC_PRIO_SERIALUART4_TXDMA,
.rxPriority = NVIC_PRIO_SERIALUART4 .rxPriority = NVIC_PRIO_SERIALUART4
@ -179,7 +179,7 @@ static uartDevice_t uart5 =
.rcc_ahb1 = USART5_AHB1_PERIPHERALS, .rcc_ahb1 = USART5_AHB1_PERIPHERALS,
#endif #endif
.rcc_apb1 = RCC_APB1(UART5), .rcc_apb1 = RCC_APB1(UART5),
.txIrq = DMA2_Stream7_IRQn, .txIrq = DMA2_ST7_HANDLER,
.rxIrq = UART5_IRQn, .rxIrq = UART5_IRQn,
.txPriority = NVIC_PRIO_SERIALUART5_TXDMA, .txPriority = NVIC_PRIO_SERIALUART5_TXDMA,
.rxPriority = NVIC_PRIO_SERIALUART5 .rxPriority = NVIC_PRIO_SERIALUART5
@ -202,7 +202,7 @@ static uartDevice_t uart6 =
.rcc_ahb1 = USART6_AHB1_PERIPHERALS, .rcc_ahb1 = USART6_AHB1_PERIPHERALS,
#endif #endif
.rcc_apb2 = RCC_APB2(USART6), .rcc_apb2 = RCC_APB2(USART6),
.txIrq = DMA2_Stream6_IRQn, .txIrq = DMA2_ST6_HANDLER,
.rxIrq = USART6_IRQn, .rxIrq = USART6_IRQn,
.txPriority = NVIC_PRIO_SERIALUART6_TXDMA, .txPriority = NVIC_PRIO_SERIALUART6_TXDMA,
.rxPriority = NVIC_PRIO_SERIALUART6 .rxPriority = NVIC_PRIO_SERIALUART6
@ -278,6 +278,29 @@ static void handleUsartTxDma(uartPort_t *s)
s->txDMAEmpty = true; s->txDMAEmpty = true;
} }
void dmaIRQHandler(dmaChannelDescriptor_t descriptor)
{
uartPort_t *s = &((uartDevice_t*)(descriptor->userParam)->port);
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF))
{
DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
DMA_CLEAR_FLAG(descriptor, DMA_IT_HTIF);
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_FEIF))
{
DMA_CLEAR_FLAG(descriptor, DMA_IT_FEIF);
}
handleUsartTxDma(s);
}
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TEIF))
{
DMA_CLEAR_FLAG(descriptor, DMA_IT_TEIF);
}
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_DMEIF))
{
DMA_CLEAR_FLAG(descriptor, DMA_IT_DMEIF);
}
}
uartPort_t *serialUSART(UARTDevice device, uint32_t baudRate, portMode_t mode, portOptions_t options) uartPort_t *serialUSART(UARTDevice device, uint32_t baudRate, portMode_t mode, portOptions_t options)
{ {
uartPort_t *s; uartPort_t *s;
@ -336,11 +359,7 @@ uartPort_t *serialUSART(UARTDevice device, uint32_t baudRate, portMode_t mode, p
} }
// DMA TX Interrupt // DMA TX Interrupt
NVIC_InitStructure.NVIC_IRQChannel = uart->txIrq; dmaSetHandler(uart->txIrq, dmaIRQHandler, uart->txPriority, (uint32_t)uart);
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(uart->txPriority);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(uart->txPriority);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
if (!(s->rxDMAChannel)) { if (!(s->rxDMAChannel)) {
NVIC_InitStructure.NVIC_IRQChannel = uart->rxIrq; NVIC_InitStructure.NVIC_IRQChannel = uart->rxIrq;
@ -359,30 +378,6 @@ uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t optio
return serialUSART(UARTDEV_1, baudRate, mode, options); return serialUSART(UARTDEV_1, baudRate, mode, options);
} }
// USART1 Tx DMA Handler
void DMA2_Stream7_IRQHandler(void)
{
uartPort_t *s = &(uartHardwareMap[UARTDEV_1]->port);
if(DMA_GetITStatus(s->txDMAStream,DMA_IT_TCIF7))
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TCIF7);
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_HTIF7);
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_FEIF7)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_FEIF7);
}
handleUsartTxDma(s);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_TEIF7)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TEIF7);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_DMEIF7)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_DMEIF7);
}
}
// USART1 Rx/Tx IRQ Handler // USART1 Rx/Tx IRQ Handler
void USART1_IRQHandler(void) void USART1_IRQHandler(void)
{ {
@ -398,30 +393,6 @@ uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode, portOptions_t optio
return serialUSART(UARTDEV_2, baudRate, mode, options); return serialUSART(UARTDEV_2, baudRate, mode, options);
} }
// USART2 Tx DMA Handler
void DMA1_Stream6_IRQHandler(void)
{
uartPort_t *s = &(uartHardwareMap[UARTDEV_2]->port);
if(DMA_GetITStatus(s->txDMAStream,DMA_IT_TCIF6))
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TCIF6);
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_HTIF6);
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_FEIF6)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_FEIF6);
}
handleUsartTxDma(s);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_TEIF6)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TEIF6);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_DMEIF6)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_DMEIF6);
}
}
void USART2_IRQHandler(void) void USART2_IRQHandler(void)
{ {
uartPort_t *s = &(uartHardwareMap[UARTDEV_2]->port); uartPort_t *s = &(uartHardwareMap[UARTDEV_2]->port);
@ -436,30 +407,6 @@ uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t optio
return serialUSART(UARTDEV_3, baudRate, mode, options); return serialUSART(UARTDEV_3, baudRate, mode, options);
} }
// USART3 Tx DMA Handler
void DMA1_Stream3_IRQHandler(void)
{
uartPort_t *s = &(uartHardwareMap[UARTDEV_3]->port);
if(DMA_GetITStatus(s->txDMAStream,DMA_IT_TCIF3))
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TCIF3);
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_HTIF3);
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_FEIF3)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_FEIF3);
}
handleUsartTxDma(s);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_TEIF3)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TEIF3);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_DMEIF3)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_DMEIF3);
}
}
void USART3_IRQHandler(void) void USART3_IRQHandler(void)
{ {
uartPort_t *s = &(uartHardwareMap[UARTDEV_3]->port); uartPort_t *s = &(uartHardwareMap[UARTDEV_3]->port);
@ -474,30 +421,6 @@ uartPort_t *serialUSART4(uint32_t baudRate, portMode_t mode, portOptions_t optio
return serialUSART(UARTDEV_4, baudRate, mode, options); return serialUSART(UARTDEV_4, baudRate, mode, options);
} }
// USART4 Tx DMA Handler
void DMA1_Stream4_IRQHandler(void)
{
uartPort_t *s = &(uartHardwareMap[UARTDEV_4]->port);
if(DMA_GetITStatus(s->txDMAStream,DMA_IT_TCIF4))
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TCIF4);
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_HTIF4);
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_FEIF4)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_FEIF4);
}
handleUsartTxDma(s);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_TEIF4)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TEIF4);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_DMEIF4)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_DMEIF4);
}
}
void UART4_IRQHandler(void) void UART4_IRQHandler(void)
{ {
uartPort_t *s = &(uartHardwareMap[UARTDEV_4]->port); uartPort_t *s = &(uartHardwareMap[UARTDEV_4]->port);
@ -512,30 +435,6 @@ uartPort_t *serialUSART5(uint32_t baudRate, portMode_t mode, portOptions_t optio
return serialUSART(UARTDEV_5, baudRate, mode, options); return serialUSART(UARTDEV_5, baudRate, mode, options);
} }
// USART5 Tx DMA Handler
void DMA1_Stream7_IRQHandler(void)
{
uartPort_t *s = &(uartHardwareMap[UARTDEV_5]->port);
if(DMA_GetITStatus(s->txDMAStream,DMA_IT_TCIF7))
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TCIF7);
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_HTIF7);
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_FEIF7)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_FEIF7);
}
handleUsartTxDma(s);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_TEIF7)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TEIF7);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_DMEIF7)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_DMEIF7);
}
}
void UART5_IRQHandler(void) void UART5_IRQHandler(void)
{ {
uartPort_t *s = &(uartHardwareMap[UARTDEV_5]->port); uartPort_t *s = &(uartHardwareMap[UARTDEV_5]->port);
@ -550,30 +449,6 @@ uartPort_t *serialUSART6(uint32_t baudRate, portMode_t mode, portOptions_t optio
return serialUSART(UARTDEV_6, baudRate, mode, options); return serialUSART(UARTDEV_6, baudRate, mode, options);
} }
// USART6 Tx DMA Handler
void DMA2_Stream6_IRQHandler(void)
{
uartPort_t *s = &(uartHardwareMap[UARTDEV_6]->port);
if(DMA_GetITStatus(s->txDMAStream,DMA_IT_TCIF6))
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TCIF6);
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_HTIF6);
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_FEIF6)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_FEIF6);
}
handleUsartTxDma(s);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_TEIF6)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TEIF6);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_DMEIF6)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_DMEIF6);
}
}
void USART6_IRQHandler(void) void USART6_IRQHandler(void)
{ {
uartPort_t *s = &(uartHardwareMap[UARTDEV_6]->port); uartPort_t *s = &(uartHardwareMap[UARTDEV_6]->port);

View file

@ -38,19 +38,19 @@ uint8_t transponderIrDMABuffer[TRANSPONDER_DMA_BUFFER_SIZE];
volatile uint8_t transponderIrDataTransferInProgress = 0; volatile uint8_t transponderIrDataTransferInProgress = 0;
void transponderDMAHandler(DMA_Channel_TypeDef *channel) void transponderDMAHandler(dmaChannelDescriptor_t* descriptor)
{ {
if (DMA_GetFlagStatus(TRANSPONDER_DMA_TC_FLAG)) { if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) {
transponderIrDataTransferInProgress = 0; transponderIrDataTransferInProgress = 0;
DMA_Cmd(channel, DISABLE); DMA_Cmd(descriptor->channel, DISABLE);
DMA_ClearFlag(TRANSPONDER_DMA_TC_FLAG); DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
} }
} }
void transponderIrInit(void) void transponderIrInit(void)
{ {
memset(&transponderIrDMABuffer, 0, TRANSPONDER_DMA_BUFFER_SIZE); memset(&transponderIrDMABuffer, 0, TRANSPONDER_DMA_BUFFER_SIZE);
dmaSetHandler(TRANSPONDER_DMA_HANDLER_IDENTIFER, transponderDMAHandler); dmaSetHandler(TRANSPONDER_DMA_HANDLER_IDENTIFER, transponderDMAHandler, NVIC_PRIO_TRANSPONDER_DMA, 0);
transponderIrHardwareInit(); transponderIrHardwareInit();
} }

View file

@ -86,7 +86,7 @@ void transponderIrHardwareInit(void)
/* configure DMA */ /* configure DMA */
/* DMA clock enable */ /* DMA clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* DMA1 Channel6 Config */ /* DMA1 Channel6 Config */
DMA_DeInit(TRANSPONDER_DMA_CHANNEL); DMA_DeInit(TRANSPONDER_DMA_CHANNEL);
@ -110,13 +110,6 @@ void transponderIrHardwareInit(void)
DMA_ITConfig(TRANSPONDER_DMA_CHANNEL, DMA_IT_TC, ENABLE); DMA_ITConfig(TRANSPONDER_DMA_CHANNEL, DMA_IT_TC, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TRANSPONDER_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_TRANSPONDER_DMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_TRANSPONDER_DMA);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
} }
void transponderIrDMAEnable(void) void transponderIrDMAEnable(void)

View file

@ -125,7 +125,9 @@
#define USE_MAX7456 #define USE_MAX7456
#define MAX7456_SPI_INSTANCE SPI1 #define MAX7456_SPI_INSTANCE SPI1
#define MAX7456_SPI_CS_PIN SPI1_NSS_PIN #define MAX7456_SPI_CS_PIN SPI1_NSS_PIN
#define MAX7456_DMA_CHANNEL_TX DMA1_Channel3
//#define MAX7456_DMA_CHANNEL_RX DMA1_Channel2 // <- Conflicts with WS2811 DMA
#define MAX7456_DMA_IRQ_HANDLER_ID DMA1_CH3_HANDLER
#define USE_SPI #define USE_SPI
#define USE_SPI_DEVICE_2 // PB12,13,14,15 on AF5 #define USE_SPI_DEVICE_2 // PB12,13,14,15 on AF5

View file

@ -114,10 +114,7 @@
#define MAX7456_DMA_CHANNEL_TX DMA2_Channel2 #define MAX7456_DMA_CHANNEL_TX DMA2_Channel2
#define MAX7456_DMA_CHANNEL_RX DMA2_Channel1 #define MAX7456_DMA_CHANNEL_RX DMA2_Channel1
#define MAX7456_DMA_TC_FLAG DMA2_FLAG_TC1 #define MAX7456_DMA_IRQ_HANDLER_ID DMA2_CH1_HANDLER
#define MAX7456_DMA_PERIPH_CLOCK RCC_AHBPeriph_DMA2
#define MAX7456_DMA_IRQ_HANDLER_FUNCTION DMA2_Channel1_IRQHandler
#define MAX7456_DMA_IRQ_HANDLER_ID DMA2_Channel1_IRQn
#define USE_RTC6705 #define USE_RTC6705
#define RTC6705_SPIDATA_PIN PC15 #define RTC6705_SPIDATA_PIN PC15