diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_dma.h b/arch/arm/src/stm32l4/chip/stm32l4x6xx_dma.h index c0d136150fa..ab63195d2f2 100644 --- a/arch/arm/src/stm32l4/chip/stm32l4x6xx_dma.h +++ b/arch/arm/src/stm32l4/chip/stm32l4x6xx_dma.h @@ -39,8 +39,7 @@ /************************************************************************************ * Pre-processor Definitions ************************************************************************************/ -/* These definitions apply to both the STM32 F1 and F3 families */ -/* 12 Channels Total: 7 DMA1 Channels(1-7) and 5 DMA2 channels (1-5) */ +/* 14 Channels Total: 7 DMA1 Channels(1-7) and 7 DMA2 channels (1-7) */ #define DMA1 0 #define DMA2 1 @@ -158,6 +157,8 @@ #define STM32L4_DMA2_CCR3 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR3_OFFSET) #define STM32L4_DMA2_CCR4 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR4_OFFSET) #define STM32L4_DMA2_CCR5 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR5_OFFSET) +#define STM32L4_DMA2_CCR6 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR6_OFFSET) +#define STM32L4_DMA2_CCR7 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR7_OFFSET) #define STM32L4_DMA2_CNDTR(n) (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR_OFFSET(n)) #define STM32L4_DMA2_CNDTR1 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR1_OFFSET) @@ -165,6 +166,8 @@ #define STM32L4_DMA2_CNDTR3 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR3_OFFSET) #define STM32L4_DMA2_CNDTR4 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR4_OFFSET) #define STM32L4_DMA2_CNDTR5 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR5_OFFSET) +#define STM32L4_DMA2_CNDTR6 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR6_OFFSET) +#define STM32L4_DMA2_CNDTR7 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR7_OFFSET) #define STM32L4_DMA2_CPAR(n) (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR_OFFSET(n)) #define STM32L4_DMA2_CPAR1 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR1_OFFSET) @@ -172,6 +175,8 @@ #define STM32L4_DMA2_CPAR3 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR3_OFFSET) #define STM32L4_DMA2_CPAR4 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR4_OFFSET) #define STM32L4_DMA2_CPAR5 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR5_OFFSET) +#define STM32L4_DMA2_CPAR6 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR6_OFFSET) +#define STM32L4_DMA2_CPAR7 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR7_OFFSET) #define STM32L4_DMA2_CMAR(n) (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR_OFFSET(n)) #define STM32L4_DMA2_CMAR1 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR1_OFFSET) @@ -179,6 +184,8 @@ #define STM32L4_DMA2_CMAR3 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR3_OFFSET) #define STM32L4_DMA2_CMAR4 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR4_OFFSET) #define STM32L4_DMA2_CMAR5 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR5_OFFSET) +#define STM32L4_DMA2_CMAR6 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR6_OFFSET) +#define STM32L4_DMA2_CMAR7 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR7_OFFSET) /* Register Bitfield Definitions ****************************************************/ diff --git a/arch/arm/src/stm32l4/stm32l4_dma.h b/arch/arm/src/stm32l4/stm32l4_dma.h index 9fd36a63373..ee11f8655c5 100644 --- a/arch/arm/src/stm32l4/stm32l4_dma.h +++ b/arch/arm/src/stm32l4/stm32l4_dma.h @@ -3,6 +3,8 @@ * * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt + * Sebastien Lorquet + * dev@ziggurat29.com * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -57,13 +59,11 @@ * DMA callback function (see dma_callback_t). */ -# define DMA_STATUS_FEIF 0 /* (Not available in F1) */ -# define DMA_STATUS_DMEIF 0 /* (Not available in F1) */ # define DMA_STATUS_TEIF DMA_CHAN_TEIF_BIT /* Channel Transfer Error */ # define DMA_STATUS_HTIF DMA_CHAN_HTIF_BIT /* Channel Half Transfer */ # define DMA_STATUS_TCIF DMA_CHAN_TCIF_BIT /* Channel Transfer Complete */ -#define DMA_STATUS_ERROR (DMA_STATUS_FEIF|DMA_STATUS_DMEIF|DMA_STATUS_TEIF) +#define DMA_STATUS_ERROR (DMA_STATUS_TEIF) #define DMA_STATUS_SUCCESS (DMA_STATUS_TCIF|DMA_STATUS_HTIF) /************************************************************************************ @@ -71,7 +71,7 @@ ************************************************************************************/ /* DMA_HANDLE provides an opaque are reference that can be used to represent a DMA - * channel (F1) or a DMA stream (F4). + * channel. */ typedef FAR void *DMA_HANDLE; @@ -81,7 +81,7 @@ typedef FAR void *DMA_HANDLE; * completion of the DMA. * * Input Parameters: - * handle - Refers tot he DMA channel or stream + * handle - Refers tot he DMA channel * status - A bit encoded value that provides the completion status. See the * DMASTATUS_* definitions above. * arg - A user-provided value that was provided when stm32l4_dmastart() was @@ -93,11 +93,12 @@ typedef void (*dma_callback_t)(DMA_HANDLE handle, uint8_t status, void *arg); #ifdef CONFIG_DEBUG_DMA struct stm32l4_dmaregs_s { - uint32_t isr; - uint32_t ccr; - uint32_t cndtr; - uint32_t cpar; - uint32_t cmar; + uint32_t isr; /* Interrupt Status Register; each channel gets 4 bits */ + uint32_t cselr; /* Channel Selection Register; chooses peripheral bound */ + uint32_t ccr; /* Channel Configuration Register; determines functionality */ + uint32_t cndtr; /* Channel Count Register; determines number of transfers */ + uint32_t cpar; /* Channel Peripheral Address Register; determines start */ + uint32_t cmar; /* Channel Memory Address Register; determines start */ }; #endif @@ -126,7 +127,7 @@ extern "C" * Description: * Allocate a DMA channel. This function gives the caller mutually * exclusive access to the DMA channel specified by the 'chan' argument. - * DMA channels are shared on the STM32: Devices sharing the same DMA + * DMA channels are shared on the STM32L4: Devices sharing the same DMA * channel cannot do DMA concurrently! See the DMACHAN_* definitions in * stm32l4_dma.h. * @@ -142,10 +143,8 @@ extern "C" * * Input parameter: * chan - Identifies the stream/channel resource - * For the STM32 F1, this is simply the channel number as provided by - * the DMACHAN_* definitions in chip/stm32f10xxx_dma.h. - * For the STM32 F4, this is a bit encoded value as provided by the - * the DMAMAP_* definitions in chip/stm32f40xxx_dma.h + * This is a bit encoded value as provided by the DMACHAN_* definitions + * in chip/stm32l4x6xx_dma.h * * Returned Value: * Provided that 'chan' is valid, this function ALWAYS returns a non-NULL, @@ -153,8 +152,8 @@ extern "C" * assert if debug is enabled or do something ignorant otherwise). * * Assumptions: - * - The caller does not hold he DMA channel. - * - The caller can wait for the DMA channel to be freed if it is no + * - The caller does not hold the DMA channel. + * - The caller can wait for the DMA channel to be freed if it is not * available. * ****************************************************************************/ diff --git a/arch/arm/src/stm32l4/stm32l4x6xx_dma.c b/arch/arm/src/stm32l4/stm32l4x6xx_dma.c index 2e6afa2b3b6..a45d33970bf 100644 --- a/arch/arm/src/stm32l4/stm32l4x6xx_dma.c +++ b/arch/arm/src/stm32l4/stm32l4x6xx_dma.c @@ -3,6 +3,8 @@ * * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt + * Sebastien Lorquet + * dev@ziggurat29.com * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -306,16 +308,17 @@ static int stm32l4_dmainterrupt(int irq, void *context) isr = dmabase_getreg(dmach, STM32L4_DMA_ISR_OFFSET) & DMA_ISR_CHAN_MASK(dmach->chan); - /* Clear the interrupts we are handling */ - - dmabase_putreg(dmach, STM32L4_DMA_IFCR_OFFSET, isr); - /* Invoke the callback */ if (dmach->callback) { dmach->callback(dmach, isr >> DMA_ISR_CHAN_SHIFT(dmach->chan), dmach->arg); } + + /* Clear the interrupts we are handling */ + + dmabase_putreg(dmach, STM32L4_DMA_IFCR_OFFSET, isr); + return OK; } @@ -387,9 +390,9 @@ void weak_function up_dmainitialize(void) * version. Feel free to do that if that is what you need. * * Input parameter: - * chndx - Identifies the stream/channel resource. For the STM32 F1, this - * is simply the channel number as provided by the DMACHAN_* definitions - * in chip/stm32f10xxx_dma.h. + * chan - Identifies the stream/channel resource + * This is a bit encoded value as provided by the DMACHAN_* definitions + * in chip/stm32l4x6xx_dma.h * * Returned Value: * Provided that 'chndx' is valid, this function ALWAYS returns a non-NULL, @@ -471,6 +474,9 @@ void stm32l4_dmasetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, struct stm32l4_dma_s *dmach = (struct stm32l4_dma_s *)handle; uint32_t regval; + DEBUGASSERT(handle != NULL); + DEBUGASSERT(ntransfers<65536); + /* Then DMA_CNDTRx register can only be modified if the DMA channel is * disabled. */ @@ -514,7 +520,12 @@ void stm32l4_dmasetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, regval |= ccr; dmachan_putreg(dmach, STM32L4_DMACHAN_CCR_OFFSET, regval); -#warning TODO define peripheral by using dmach->function + /* define peripheral indicated in dmach->function */ + + regval = dmabase_getreg(dmach, STM32L4_DMA_CSELR_OFFSET); + regval &= (0x0f << (dmach->chan << 2)); + regval |= (dmach->function << (dmach->chan << 2)); + dmabase_putreg(dmach, STM32L4_DMA_CSELR_OFFSET, regval); } /**************************************************************************** @@ -641,7 +652,9 @@ bool stm32l4_dmacapable(uint32_t maddr, uint32_t count, uint32_t ccr) * Transfers to/from memory performed by the DMA controller are * required to be aligned to their size. * - * See ST RM0090 rev4, section 9.3.11 + * Datasheet 3.13 claims + * "Access to Flash, SRAM, APB and AHB peripherals as source + * and destination" * * Compute mend inline to avoid a possible non-constant integer * multiply. @@ -682,13 +695,14 @@ bool stm32l4_dmacapable(uint32_t maddr, uint32_t count, uint32_t ccr) switch (maddr & STM32L4_REGION_MASK) { -#if defined(CONFIG_STM32L4_STM32F10XX) + case STM32L4_PERIPH_BASE: + case STM32L4_FSMC_BASE: case STM32L4_FSMC_BANK1: case STM32L4_FSMC_BANK2: case STM32L4_FSMC_BANK3: case STM32L4_FSMC_BANK4: -#endif case STM32L4_SRAM_BASE: + case STM32L4_SRAM2_BASE: case STM32L4_CODE_BASE: /* All RAM and flash is supported */ @@ -719,13 +733,14 @@ void stm32l4_dmasample(DMA_HANDLE handle, struct stm32l4_dmaregs_s *regs) struct stm32l4_dma_s *dmach = (struct stm32l4_dma_s *)handle; irqstate_t flags; - flags = irqsave(); + flags = enter_critical_section(); regs->isr = dmabase_getreg(dmach, STM32L4_DMA_ISR_OFFSET); + regs->cselr = dmabase_getreg(dmach, STM32L4_DMA_CSELR_OFFSET); regs->ccr = dmachan_getreg(dmach, STM32L4_DMACHAN_CCR_OFFSET); regs->cndtr = dmachan_getreg(dmach, STM32L4_DMACHAN_CNDTR_OFFSET); regs->cpar = dmachan_getreg(dmach, STM32L4_DMACHAN_CPAR_OFFSET); regs->cmar = dmachan_getreg(dmach, STM32L4_DMACHAN_CMAR_OFFSET); - irqrestore(flags); + leave_critical_section(flags); } #endif @@ -748,7 +763,8 @@ void stm32l4_dmadump(DMA_HANDLE handle, const struct stm32l4_dmaregs_s *regs, uint32_t dmabase = DMA_BASE(dmach->base); dmadbg("DMA Registers: %s\n", msg); - dmadbg(" ISRC[%08x]: %08x\n", dmabase + STM32L4_DMA_ISR_OFFSET, regs->isr); + dmadbg(" ISR[%08x]: %08x\n", dmabase + STM32L4_DMA_ISR_OFFSET, regs->isr); + dmadbg(" CSELR[%08x]: %08x\n", dmabase + STM32L4_DMA_CSELR_OFFSET, regs->cselr); dmadbg(" CCR[%08x]: %08x\n", dmach->base + STM32L4_DMACHAN_CCR_OFFSET, regs->ccr); dmadbg(" CNDTR[%08x]: %08x\n", dmach->base + STM32L4_DMACHAN_CNDTR_OFFSET, regs->cndtr); dmadbg(" CPAR[%08x]: %08x\n", dmach->base + STM32L4_DMACHAN_CPAR_OFFSET, regs->cpar);