stmhal: On SysTick IRQ, only process one DMA channel at a time.
This can be generalised if/when more processing is needed by SysTick. Thanks to @chuckbook for the idea.
This commit is contained in:
parent
9936aa3f87
commit
22bd23114a
10
stmhal/dma.c
10
stmhal/dma.c
@ -220,14 +220,16 @@ void dma_invalidate_channel(DMA_Stream_TypeDef *dma_stream, uint32_t dma_channel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from the SysTick handler (once per millisecond)
|
// Called from the SysTick handler
|
||||||
void dma_idle_handler() {
|
// We use LSB of tick to select which controller to process
|
||||||
|
void dma_idle_handler(int tick) {
|
||||||
static const uint32_t controller_mask[] = {
|
static const uint32_t controller_mask[] = {
|
||||||
DMA1_ENABLE_MASK, DMA2_ENABLE_MASK
|
DMA1_ENABLE_MASK, DMA2_ENABLE_MASK
|
||||||
};
|
};
|
||||||
for (int controller = 0; controller < NCONTROLLERS; controller++) {
|
{
|
||||||
|
int controller = tick & 1;
|
||||||
if (dma_idle.counter[controller] == 0) {
|
if (dma_idle.counter[controller] == 0) {
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
if (++dma_idle.counter[controller] > DMA_IDLE_TICK_MAX) {
|
if (++dma_idle.counter[controller] > DMA_IDLE_TICK_MAX) {
|
||||||
if ((dma_enable_mask & controller_mask[controller]) == 0) {
|
if ((dma_enable_mask & controller_mask[controller]) == 0) {
|
||||||
|
@ -38,7 +38,7 @@ typedef union {
|
|||||||
extern volatile dma_idle_count_t dma_idle;
|
extern volatile dma_idle_count_t dma_idle;
|
||||||
#define DMA_IDLE_ENABLED() (dma_idle.enabled != 0)
|
#define DMA_IDLE_ENABLED() (dma_idle.enabled != 0)
|
||||||
|
|
||||||
#define DMA_SYSTICK_MASK 0x0F
|
#define DMA_SYSTICK_MASK 0x0e
|
||||||
#define DMA_MSECS_PER_SYSTICK (DMA_SYSTICK_MASK + 1)
|
#define DMA_MSECS_PER_SYSTICK (DMA_SYSTICK_MASK + 1)
|
||||||
#define DMA_IDLE_TICK_MAX (8) // 128 msec
|
#define DMA_IDLE_TICK_MAX (8) // 128 msec
|
||||||
#define DMA_IDLE_TICK(tick) (((tick) & DMA_SYSTICK_MASK) == 0)
|
#define DMA_IDLE_TICK(tick) (((tick) & DMA_SYSTICK_MASK) == 0)
|
||||||
@ -48,4 +48,4 @@ extern const DMA_InitTypeDef dma_init_struct_spi_i2c;
|
|||||||
void dma_init(DMA_HandleTypeDef *dma, DMA_Stream_TypeDef *dma_stream, const DMA_InitTypeDef *dma_init, uint32_t dma_channel, uint32_t direction, void *data);
|
void dma_init(DMA_HandleTypeDef *dma, DMA_Stream_TypeDef *dma_stream, const DMA_InitTypeDef *dma_init, uint32_t dma_channel, uint32_t direction, void *data);
|
||||||
void dma_deinit(DMA_HandleTypeDef *dma);
|
void dma_deinit(DMA_HandleTypeDef *dma);
|
||||||
void dma_invalidate_channel(DMA_Stream_TypeDef *dma_stream, uint32_t dma_channel);
|
void dma_invalidate_channel(DMA_Stream_TypeDef *dma_stream, uint32_t dma_channel);
|
||||||
void dma_idle_handler();
|
void dma_idle_handler(int controller);
|
||||||
|
@ -269,8 +269,12 @@ void SysTick_Handler(void) {
|
|||||||
// work properly.
|
// work properly.
|
||||||
SysTick->CTRL;
|
SysTick->CTRL;
|
||||||
|
|
||||||
|
// Right now we just have the DMA controllers to process during this
|
||||||
|
// interrupt and we use a custom dispatch handler. If this needs to
|
||||||
|
// be generalised in the future then a dispatch table can be used as
|
||||||
|
// follows: ((void(*)(void))(systick_dispatch[uwTick & 0xf]))();
|
||||||
if (DMA_IDLE_ENABLED() && DMA_IDLE_TICK(uwTick)) {
|
if (DMA_IDLE_ENABLED() && DMA_IDLE_TICK(uwTick)) {
|
||||||
dma_idle_handler();
|
dma_idle_handler(uwTick);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user