arch/arm/src/imxrt: Add framework for eDMA support. Initial port is a rip off from the SAMA5Dx and is little more than the framework for the DMA support.

This commit is contained in:
Gregory Nutt
2018-05-16 14:28:22 -06:00
parent 9bb4a80838
commit ea8d78c9c5
10 changed files with 932 additions and 26 deletions
+6 -6
View File
@@ -60,12 +60,12 @@
#define IMXRT_IRQ_EDMA7_23 (IMXRT_IRQ_EXTINT + 7) /* eDMA Channel 7/23 Transfer Complete */
#define IMXRT_IRQ_EDMA8_24 (IMXRT_IRQ_EXTINT + 8) /* eDMA Channel 8/24 Transfer Complete */
#define IMXRT_IRQ_EDMA9_25 (IMXRT_IRQ_EXTINT + 9) /* eDMA Channel 9/25 Transfer Complete */
#define IMXRT_IRQ_EDMA0_26 (IMXRT_IRQ_EXTINT + 10) /* eDMA Channel 10/26 Transfer Complete */
#define IMXRT_IRQ_EDMA1_27 (IMXRT_IRQ_EXTINT + 11) /* eDMA Channel 11/27 Transfer Complete */
#define IMXRT_IRQ_EDMA2_28 (IMXRT_IRQ_EXTINT + 12) /* eDMA Channel 12/28 Transfer Complete */
#define IMXRT_IRQ_EDMA3_29 (IMXRT_IRQ_EXTINT + 13) /* eDMA Channel 13/29 Transfer Complete */
#define IMXRT_IRQ_EDMA4_30 (IMXRT_IRQ_EXTINT + 14) /* eDMA Channel 14/30 Transfer Complete */
#define IMXRT_IRQ_EDMA5_31 (IMXRT_IRQ_EXTINT + 15) /* eDMA Channel 15/31 Transfer Complete */
#define IMXRT_IRQ_EDMA10_26 (IMXRT_IRQ_EXTINT + 10) /* eDMA Channel 10/26 Transfer Complete */
#define IMXRT_IRQ_EDMA11_27 (IMXRT_IRQ_EXTINT + 11) /* eDMA Channel 11/27 Transfer Complete */
#define IMXRT_IRQ_EDMA12_28 (IMXRT_IRQ_EXTINT + 12) /* eDMA Channel 12/28 Transfer Complete */
#define IMXRT_IRQ_EDMA13_29 (IMXRT_IRQ_EXTINT + 13) /* eDMA Channel 13/29 Transfer Complete */
#define IMXRT_IRQ_EDMA14_30 (IMXRT_IRQ_EXTINT + 14) /* eDMA Channel 14/30 Transfer Complete */
#define IMXRT_IRQ_EDMA15_31 (IMXRT_IRQ_EXTINT + 15) /* eDMA Channel 15/31 Transfer Complete */
#define IMXRT_IRQ_EDMA_ERROR (IMXRT_IRQ_EXTINT + 16) /* Error Interrupt, Channels 0-15 / 16-31 */
#define IMXRT_IRQ_CM70 (IMXRT_IRQ_EXTINT + 17) /* CTI trigger outputs (internal: CTIIRQ[0]) */
#define IMXRT_IRQ_CM71 (IMXRT_IRQ_EXTINT + 18) /* CTI trigger outputs (internal: CTIIRQ[1]) */
+5
View File
@@ -70,6 +70,11 @@ endmenu # FlexIO Peripherals
menu "LPUART Peripherals"
config IMXRT_EDMA
bool "eDMA"
default n
depends on EXPERIMENTAL
config IMXRT_LPUART1
bool "LPUART1"
default n
+4
View File
@@ -119,3 +119,7 @@ ifeq ($(CONFIG_BUILD_PROTECTED),y)
CHIP_CSRCS += imxrt_userspace.c
endif
endif
ifeq ($(CONFIG_IMXRT_EDMA),y)
CHIP_CSRCS += imxrt_edma.c
endif
+14 -12
View File
@@ -47,6 +47,8 @@
* Pre-processor definitions
****************************************************************************************************/
#define IMXRT_EDMA_NCHANNELS 32
/* eDMA Register Offsets ****************************************************************************/
#define IMXRT_EDMA_CR_OFFSET 0x0000 /* Control */
@@ -564,18 +566,18 @@
#define IMXRT_EDMA_DCHPRI29 (IMXRT_EDMA_BASE + IMXRT_EDMA_DCHPRI2_OFFSET)
#define IMXRT_EDMA_DCHPRI28 (IMXRT_EDMA_BASE + IMXRT_EDMA_DCHPRI3_OFFSET)
#define IMXRT_EDMA_TCD(n) (IMXRT_EDMA_BASE + IMXRT_EDMA_TCD_OFFSET(n))
#define IMXRT_EDMA_TCD_SADDR(n) (IMXRT_EDMA_TCD(n) + IMXRT_EDMA_TCD_SADDR_OFFSET)
#define IMXRT_EDMA_TCD_SOFF(n) (IMXRT_EDMA_TCD(n) + IMXRT_EDMA_TCD_SOFF_OFFSET)
#define IMXRT_EDMA_TCD_ATTR(n) (IMXRT_EDMA_TCD(n) + IMXRT_EDMA_TCD_ATTR_OFFSET)
#define IMXRT_EDMA_TCD_NBYTES_ML(n) (IMXRT_EDMA_TCD(n) + IMXRT_EDMA_TCD_NBYTES_ML_OFFSET)
#define IMXRT_EDMA_TCD_SLAST(n) (IMXRT_EDMA_TCD(n) + IMXRT_EDMA_TCD_SLAST_OFFSET)
#define IMXRT_EDMA_TCD_DADDR(n) (IMXRT_EDMA_TCD(n) + IMXRT_EDMA_TCD_DADDR_OFFSET)
#define IMXRT_EDMA_TCD_DOFF(n) (IMXRT_EDMA_TCD(n) + IMXRT_EDMA_TCD_DOFF_OFFSET)
#define IMXRT_EDMA_TCD_CITER_ELINK(n) (IMXRT_EDMA_TCD(n) + IMXRT_EDMA_TCD_CITER_ELINK_OFFSET)
#define IMXRT_EDMA_TCD_DLASTSGA(n) (IMXRT_EDMA_TCD(n) + IMXRT_EDMA_TCD_DLASTSGA_OFFSET)
#define IMXRT_EDMA_TCD_CSR(n) (IMXRT_EDMA_TCD(n) + IMXRT_EDMA_TCD_CSR_OFFSET)
#define IMXRT_EDMA_TCD_BITER_ELINK(n) (IMXRT_EDMA_TCD(n) + IMXRT_EDMA_TCD_BITER_ELINK_OFFSET)
#define IMXRT_EDMA_TCD_BASE(n) (IMXRT_EDMA_BASE + IMXRT_EDMA_TCD_OFFSET(n))
#define IMXRT_EDMA_TCD_SADDR(n) (IMXRT_EDMA_TCD_BASE(n) + IMXRT_EDMA_TCD_SADDR_OFFSET)
#define IMXRT_EDMA_TCD_SOFF(n) (IMXRT_EDMA_TCD_BASE(n) + IMXRT_EDMA_TCD_SOFF_OFFSET)
#define IMXRT_EDMA_TCD_ATTR(n) (IMXRT_EDMA_TCD_BASE(n) + IMXRT_EDMA_TCD_ATTR_OFFSET)
#define IMXRT_EDMA_TCD_NBYTES_ML(n) (IMXRT_EDMA_TCD_BASE(n) + IMXRT_EDMA_TCD_NBYTES_ML_OFFSET)
#define IMXRT_EDMA_TCD_SLAST(n) (IMXRT_EDMA_TCD_BASE(n) + IMXRT_EDMA_TCD_SLAST_OFFSET)
#define IMXRT_EDMA_TCD_DADDR(n) (IMXRT_EDMA_TCD_BASE(n) + IMXRT_EDMA_TCD_DADDR_OFFSET)
#define IMXRT_EDMA_TCD_DOFF(n) (IMXRT_EDMA_TCD_BASE(n) + IMXRT_EDMA_TCD_DOFF_OFFSET)
#define IMXRT_EDMA_TCD_CITER_ELINK(n) (IMXRT_EDMA_TCD_BASE(n) + IMXRT_EDMA_TCD_CITER_ELINK_OFFSET)
#define IMXRT_EDMA_TCD_DLASTSGA(n) (IMXRT_EDMA_TCD_BASE(n) + IMXRT_EDMA_TCD_DLASTSGA_OFFSET)
#define IMXRT_EDMA_TCD_CSR(n) (IMXRT_EDMA_TCD_BASE(n) + IMXRT_EDMA_TCD_CSR_OFFSET)
#define IMXRT_EDMA_TCD_BITER_ELINK(n) (IMXRT_EDMA_TCD_BASE(n) + IMXRT_EDMA_TCD_BITER_ELINK_OFFSET)
#define IMXRT_EDMA_TCD0_SADDR (IMXRT_EDMA_BASE + IMXRT_EDMA_TCD0_SADDR_OFFSET)
#define IMXRT_EDMA_TCD0_SOFF (IMXRT_EDMA_BASE + IMXRT_EDMA_TCD0_SOFF_OFFSET)
File diff suppressed because it is too large Load Diff
+248
View File
@@ -0,0 +1,248 @@
/************************************************************************************
* arch/arm/src/imxrt/imxrt_dmac.h
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
************************************************************************************/
#ifndef __ARCH_ARM_SRC_IMXRT_IMXRT_EDMAC_H
#define __ARCH_ARM_SRC_IMXRT_IMXRT_EDMAC_H
/************************************************************************************
* Included Files
************************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
/* DMA ******************************************************************************/
/* Flags used to characterize the DMA channel. The naming convention is that one
* side is the peripheral and the other is memory (however, the interface could still
* be used if, for example, both sides were memory although the naming would be
* awkward)
*/
#define DMACH_FLAG_
/************************************************************************************
* Public Types
************************************************************************************/
typedef FAR void *DMA_HANDLE;
typedef void (*dma_callback_t)(DMA_HANDLE handle, void *arg, int result);
/* The following is used for sampling DMA registers when CONFIG DEBUG_DMA is selected */
#ifdef CONFIG_DEBUG_DMA
struct imxrt_dmaregs_s
{
/* eDMA Global Registers */
uint32_t cr; /* Control */
uint32_t es; /* Error Status */
uint32_t erq; /* Enable Request */
uint32_t req; /* Interrupt Request */
uint32_t err; /* Error */
uint32_t hrs; /* Hardware Request Status */
uint32_t ears; /* Enable Asynchronous Request in Stop */
/* eDMA Channel registers */
uint8_t dchpri; /* Channel priority */
/* eDMA TCD */
uint32_t saddr; /* TCD Source Address */
uint16_t soff; /* TCD Signed Source Address Offset */
uint16_t attr; /* TCD Transfer Attributes */
uint32_t nbml; /* TCD Signed Minor Loop Offset / Byte Count */
uint32_t slast; /* TCD Last Source Address Adjustment */
uint32_t daddr; /* TCD Destination Address */
uint16_t doff; /* TCD Signed Destination Address Offset */
uint16_t citer; /* TCD Current Minor Loop Link, Major Loop Count */
uint32_t dlastsga; /* TCD Last Destination Address Adjustment/Scatter Gather Address */
uint32_t csr; /* TCD Control and Status */
uint16_t biter; /* TCD Beginning Minor Loop Link, Major Loop Count */
/* DMAMUX registers */
uint32_t dmamux; /* Channel configuration */
};
#endif /* CONFIG_DEBUG_DMA */
/************************************************************************************
* Inline Functions
************************************************************************************/
#ifndef __ASSEMBLY__
/************************************************************************************
* Public Data
************************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/************************************************************************************
* Public Function Prototypes
************************************************************************************/
/************************************************************************************
* Name: imxrt_dmachannel
*
* Description:
* Allocate a DMA channel. This function sets aside a DMA channel then gives the
* caller exclusive access to the DMA channel.
*
* The naming convention in all of the DMA interfaces is that one side is the
* 'peripheral' and the other is 'memory'. However, the interface could still
* be used if, for example, both sides were memory although the naming would be
* awkward.
*
* Returned Value:
* If a DMA channel is available, this function returns a non-NULL, void* DMA
* channel handle. NULL is returned on any failure.
*
************************************************************************************/
DMA_HANDLE imxrt_dmachannel(void);
/************************************************************************************
* Name: imxrt_dmafree
*
* Description:
* Release a DMA channel. NOTE: The 'handle' used in this argument must NEVER be
* used again until imxrt_dmachannel() is called again to re-gain a valid handle.
*
* Returned Value:
* None
*
************************************************************************************/
void imxrt_dmafree(DMA_HANDLE handle);
/************************************************************************************
* Name: imxrt_dmatxsetup
*
* Description:
* Configure DMA for transmit of one buffer (memory to peripheral). This function
* may be called multiple times to handle large and/or discontinuous transfers.
* Calls to imxrt_dmatxsetup() and imxrt_dmarxsetup() must not be intermixed on the
* same transfer, however.
*
************************************************************************************/
int imxrt_dmatxsetup(DMA_HANDLE handle, uint8_t pchan, uint32_t maddr, size_t nbytes,
uint32_t chflags);
/************************************************************************************
* Name: imxrt_dmarxsetup
*
* Description:
* Configure DMA for receipt of one buffer (peripheral to memory). This function
* may be called multiple times to handle large and/or discontinuous transfers.
* Calls to imxrt_dmatxsetup() and imxrt_dmarxsetup() must not be intermixed on the
* same transfer, however.
*
************************************************************************************/
int imxrt_dmarxsetup(DMA_HANDLE handle, uint8_t pchan, uint32_t maddr, size_t nbytes,
uint32_t chflags);
/************************************************************************************
* Name: imxrt_dmastart
*
* Description:
* Start the DMA transfer
*
************************************************************************************/
int imxrt_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg);
/************************************************************************************
* Name: imxrt_dmastop
*
* Description:
* Cancel the DMA. After imxrt_dmastop() is called, the DMA channel is reset and
* imxrt_dmarx/txsetup() must be called before imxrt_dmastart() can be called again
*
************************************************************************************/
void imxrt_dmastop(DMA_HANDLE handle);
/************************************************************************************
* Name: imxrt_dmasample
*
* Description:
* Sample DMA register contents
*
************************************************************************************/
#ifdef CONFIG_DEBUG_DMA
void imxrt_dmasample(DMA_HANDLE handle, struct imxrt_dmaregs_s *regs);
#else
# define imxrt_dmasample(handle,regs)
#endif
/************************************************************************************
* Name: imxrt_dmadump
*
* Description:
* Dump previously sampled DMA register contents
*
************************************************************************************/
#ifdef CONFIG_DEBUG_DMA
void imxrt_dmadump(DMA_HANDLE handle, const struct imxrt_dmaregs_s *regs,
const char *msg);
#else
# define imxrt_dmadump(handle,regs,msg)
#endif
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_IMXRT_IMXRT_EDMAC_H */
+2 -2
View File
@@ -132,8 +132,8 @@ void kinetis_dmafree(DMA_HANDLE handle)
*
****************************************************************************/
int kinetis_dmarxsetup(DMA_HANDLE handle, uint32_t control, uint32_t config,
uint32_t srcaddr, uint32_t destaddr, size_t nbytes)
int kinetis_dmasetup(DMA_HANDLE handle, uint32_t control, uint32_t config,
uint32_t srcaddr, uint32_t destaddr, size_t nbytes)
{
return -1;
}
+2 -2
View File
@@ -156,8 +156,8 @@ void kinetis_dmafree(DMA_HANDLE handle);
*
****************************************************************************/
int kinetis_dmarxsetup(DMA_HANDLE handle, uint32_t control, uint32_t config,
uint32_t srcaddr, uint32_t destaddr, size_t nbytes);
int kinetis_dmasetup(DMA_HANDLE handle, uint32_t control, uint32_t config,
uint32_t srcaddr, uint32_t destaddr, size_t nbytes);
/****************************************************************************
* Name: kinetis_dmastart
+2 -2
View File
@@ -460,8 +460,8 @@ void lpc43_dmafree(DMA_HANDLE handle)
*
****************************************************************************/
int lpc43_dmarxsetup(DMA_HANDLE handle, uint32_t control, uint32_t config,
uint32_t srcaddr, uint32_t destaddr, size_t nbytes)
int lpc43_dmasetup(DMA_HANDLE handle, uint32_t control, uint32_t config,
uint32_t srcaddr, uint32_t destaddr, size_t nbytes)
{
struct lpc43_dmach_s *dmach = (DMA_HANDLE)handle;
uint32_t chbit;
+2 -2
View File
@@ -158,8 +158,8 @@ void lpc43_dmafree(DMA_HANDLE handle);
*
****************************************************************************/
int lpc43_dmarxsetup(DMA_HANDLE handle, uint32_t control, uint32_t config,
uint32_t srcaddr, uint32_t destaddr, size_t nbytes);
int lpc43_dmasetup(DMA_HANDLE handle, uint32_t control, uint32_t config,
uint32_t srcaddr, uint32_t destaddr, size_t nbytes);
/****************************************************************************
* Name: lpc43_dmastart