diff options
| author | Keith Packard <keithp@keithp.com> | 2017-02-20 12:12:43 -0800 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2017-02-20 12:34:01 -0800 | 
| commit | 72ea90d28817549c4343d2fea03a4c951f849cbe (patch) | |
| tree | 58f8c4d06380b4213c1357c7ec1088cfafe95264 /src | |
| parent | 5dc5e2e238f8c1a8ca35d85ec046124afa9385ad (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.c | 38 | 
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); | 
