summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2017-02-20 12:12:43 -0800
committerKeith Packard <keithp@keithp.com>2017-02-20 12:34:01 -0800
commit72ea90d28817549c4343d2fea03a4c951f849cbe (patch)
tree58f8c4d06380b4213c1357c7ec1088cfafe95264 /src
parent5dc5e2e238f8c1a8ca35d85ec046124afa9385ad (diff)
altos/stm: Allow DMA channels to be hijacked by other code
This lets code which needs finer control over DMA to use the channel without interference, and leaves the DMA engine running so that it can. Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src')
-rw-r--r--src/stm/ao_dma_stm.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/src/stm/ao_dma_stm.c b/src/stm/ao_dma_stm.c
index 63d6688a..962b3acc 100644
--- a/src/stm/ao_dma_stm.c
+++ b/src/stm/ao_dma_stm.c
@@ -29,7 +29,6 @@ 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;
static void
ao_dma_isr(uint8_t index) {
@@ -49,12 +48,24 @@ ao_dma_isr(uint8_t index) {
void stm_dma1_channel1_isr(void) { ao_dma_isr(STM_DMA_INDEX(1)); }
void stm_dma1_channel2_isr(void) { ao_dma_isr(STM_DMA_INDEX(2)); }
+#ifdef STM_DMA1_3_STOLEN
+#define LEAVE_DMA_ON
+#else
void stm_dma1_channel3_isr(void) { ao_dma_isr(STM_DMA_INDEX(3)); }
+#endif
void stm_dma1_channel4_isr(void) { ao_dma_isr(STM_DMA_INDEX(4)); }
+#ifdef STM_DMA1_5_STOLEN
+#define LEAVE_DMA_ON
+#else
void stm_dma1_channel5_isr(void) { ao_dma_isr(STM_DMA_INDEX(5)); }
+#endif
void stm_dma1_channel6_isr(void) { ao_dma_isr(STM_DMA_INDEX(6)); }
void stm_dma1_channel7_isr(void) { ao_dma_isr(STM_DMA_INDEX(7)); }
+#ifndef LEAVE_DMA_ON
+static uint8_t ao_dma_active;
+#endif
+
void
ao_dma_set_transfer(uint8_t index,
volatile void *peripheral,
@@ -68,10 +79,12 @@ ao_dma_set_transfer(uint8_t index,
ao_dma_mutex[index] = 0xff;
} else
ao_mutex_get(&ao_dma_mutex[index]);
+#ifndef LEAVE_DMA_ON
ao_arch_critical(
if (ao_dma_active++ == 0)
stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_DMA1EN);
);
+#endif
stm_dma.channel[index].ccr = ccr | (1 << STM_DMA_CCR_TCIE);
stm_dma.channel[index].cndtr = count;
stm_dma.channel[index].cpar = peripheral;
@@ -96,10 +109,12 @@ void
ao_dma_done_transfer(uint8_t index)
{
stm_dma.channel[index].ccr &= ~(1 << STM_DMA_CCR_EN);
+#ifndef LEAVE_DMA_ON
ao_arch_critical(
if (--ao_dma_active == 0)
stm_rcc.ahbenr &= ~(1 << STM_RCC_AHBENR_DMA1EN);
);
+#endif
if (ao_dma_allocated[index])
ao_dma_mutex[index] = 0;
else
@@ -120,10 +135,12 @@ ao_dma_dump_cmd(void)
{
int i;
+#ifndef LEAVE_DMA_ON
ao_arch_critical(
if (ao_dma_active++ == 0)
stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_DMA1EN);
);
+#endif
printf ("isr %08x ifcr%08x\n", stm_dma.isr, stm_dma.ifcr);
for (i = 0; i < NUM_DMA; i++)
printf("%d: done %d allocated %d mutex %2d ccr %04x cndtr %04x cpar %08x cmar %08x isr %08x\n",
@@ -136,10 +153,12 @@ ao_dma_dump_cmd(void)
stm_dma.channel[i].cpar,
stm_dma.channel[i].cmar,
ao_dma_config[i].isr);
+#ifndef LEAVE_DMA_ON
ao_arch_critical(
if (--ao_dma_active == 0)
stm_rcc.ahbenr &= ~(1 << STM_RCC_AHBENR_DMA1EN);
);
+#endif
}
static const struct ao_cmds ao_dma_cmds[] = {
@@ -153,7 +172,24 @@ ao_dma_init(void)
{
int index;
+#ifdef LEAVE_DMA_ON
+ stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_DMA1EN);
+#endif
for (index = 0; index < STM_NUM_DMA; index++) {
+#if STM_DMA1_5_STOLEN
+ if (index == STM_DMA_INDEX(5)) {
+ ao_dma_allocated[index] = 1;
+ ao_dma_mutex[index] = 0xff;
+ continue;
+ }
+#endif
+#if STM_DMA1_3_STOLEN
+ if (index == STM_DMA_INDEX(3)) {
+ ao_dma_allocated[index] = 1;
+ ao_dma_mutex[index] = 0xff;
+ continue;
+ }
+#endif
stm_nvic_set_enable(STM_ISR_DMA1_CHANNEL1_POS + index);
stm_nvic_set_priority(STM_ISR_DMA1_CHANNEL1_POS + index,
AO_STM_NVIC_MED_PRIORITY);