From 059f09dbca4703c25b42389b54c6510331c39485 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 9 Apr 2012 00:05:18 -0700 Subject: [PATCH] altos: Allow STM DMA channels to be reserved for one use This allows a single user of a DMA channel to reserve it for use without needing to lock the mutex; this is required for DMA from the ADC to work on megametrum as it wants to start DMA from an interrupt handler, which cannot block on a mutex. Signed-off-by: Keith Packard --- src/stm/ao_adc_stm.c | 2 ++ src/stm/ao_arch_funcs.h | 3 +++ src/stm/ao_dma_stm.c | 23 +++++++++++++++++++++-- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/stm/ao_adc_stm.c b/src/stm/ao_adc_stm.c index d758e629..729551c4 100644 --- a/src/stm/ao_adc_stm.c +++ b/src/stm/ao_adc_stm.c @@ -221,5 +221,7 @@ ao_adc_init(void) /* Clear any stale status bits */ stm_adc.sr = 0; ao_adc_ready = 1; + + ao_dma_alloc(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC1)); ao_cmd_register(&ao_adc_cmds[0]); } diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index a42fe10f..7dc576d1 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -61,6 +61,9 @@ ao_dma_done_transfer(uint8_t index); void ao_dma_abort(uint8_t index); +void +ao_dma_alloc(uint8_t index); + void ao_dma_init(void); diff --git a/src/stm/ao_dma_stm.c b/src/stm/ao_dma_stm.c index 785235a8..21390748 100644 --- a/src/stm/ao_dma_stm.c +++ b/src/stm/ao_dma_stm.c @@ -26,6 +26,7 @@ struct ao_dma_config { uint8_t ao_dma_done[NUM_DMA]; static struct ao_dma_config ao_dma_config[NUM_DMA]; +static uint8_t ao_dma_allocated[NUM_DMA]; static uint8_t ao_dma_mutex[NUM_DMA]; static uint8_t ao_dma_active; @@ -60,7 +61,12 @@ ao_dma_set_transfer(uint8_t index, uint16_t count, uint32_t ccr) { - ao_mutex_get(&ao_dma_mutex[index]); + if (ao_dma_allocated[index]) { + if (ao_dma_mutex[index]) + ao_panic(AO_PANIC_DMA); + ao_dma_mutex[index] = 1; + } else + ao_mutex_get(&ao_dma_mutex[index]); ao_arch_critical( if (ao_dma_active++ == 0) stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_DMA1EN); @@ -93,7 +99,10 @@ ao_dma_done_transfer(uint8_t index) if (--ao_dma_active == 0) stm_rcc.ahbenr &= ~(1 << STM_RCC_AHBENR_DMA1EN); ); - ao_mutex_put(&ao_dma_mutex[index]); + if (ao_dma_allocated[index]) + ao_dma_mutex[index] = 0; + else + ao_mutex_put(&ao_dma_mutex[index]); } void @@ -102,6 +111,14 @@ ao_dma_abort(uint8_t index) stm_dma.channel[index].ccr &= ~(1 << STM_DMA_CCR_EN); } +void +ao_dma_alloc(uint8_t index) +{ + if (ao_dma_allocated[index]) + ao_panic(AO_PANIC_DMA); + ao_dma_allocated[index] = 1; +} + void ao_dma_init(void) { @@ -110,6 +127,8 @@ ao_dma_init(void) for (index = 0; index < STM_NUM_DMA; index++) { stm_nvic_set_enable(STM_ISR_DMA1_CHANNEL1_POS + index); stm_nvic_set_priority(STM_ISR_DMA1_CHANNEL1_POS + index, 4); + ao_dma_allocated[index] = 0; + ao_dma_mutex[index] = 0; } } -- 2.30.2