arch/arm/src/lpc54xx: Add DMA register definition file and skeletal DMA driver. The initial commit of the DMA driver is simply the LPC43xx GPDMA driver with name changes and all all register access removed.

This commit is contained in:
Gregory Nutt 2017-12-24 10:55:46 -06:00
parent 7ce881051a
commit 321c524c5f
9 changed files with 1007 additions and 176 deletions

View File

@ -628,7 +628,7 @@ void lpc43_dmastop(DMA_HANDLE handle)
DEBUGASSERT(dmach && dmach->inuse);
/* Disable this channel and mask any further interrupts from the channel.
* this channel. The channel is disabled by clearning the channel
* this channel. The channel is disabled by clearing the channel
* enable bit. Any outstanding data in the FIFOs is lost.
*/

View File

@ -177,6 +177,12 @@ config LPC54_HAVE_USART
menu "LPC54xx Peripheral Selection"
config LPC54_DMA
bool "DMA"
default n
select ARCH_DMA
depends on EXPERIMENTAL
menu "Flexcomm Peripherals"
config LPC54_I2C0_MASTER

View File

@ -93,6 +93,10 @@ ifeq ($(CONFIG_BUILD_PROTECTED),y)
CHIP_CSRCS += lpc54_userspace.c lpc54_mpuinit.c
endif
ifeq ($(CONFIG_LPC54_DMA),y)
CHIP_CSRCS += lpc54_dma.c
endif
ifneq ($(CONFIG_ARCH_IDLE_CUSTOM),y)
CHIP_CSRCS += lpc54_idle.c
endif

View File

@ -1,4 +1,4 @@
/****************************************************************************************************
/********************************************************************************************
* arch/arm/src/lpc54xx/lpc54_dma.h
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
@ -31,29 +31,30 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************************************/
********************************************************************************************/
#ifndef __ARCH_ARM_SRC_LPC54XX_CHIP_LPC54_DMA_H
#define __ARCH_ARM_SRC_LPC54XX_CHIP_LPC54_DMA_H
/****************************************************************************************************
/********************************************************************************************
* Included Files
****************************************************************************************************/
********************************************************************************************/
#include <nuttx/config.h>
#include "chip/lpc54_memorymap.h"
/****************************************************************************************************
/********************************************************************************************
* Pre-processor Definitions
****************************************************************************************************/
********************************************************************************************/
#define LPC54_DMA_NCHANNELS 29 /* 29 DMA channels, 0..28 */
#define LPC54_DMA_NCHANNELS 30 /* Channels 0..29 */
/* Register offsets *************************************************************************/
/* Register offsets *********************************************************************************/
/* Global control and status registers */
#define LPC54_DMA_CTRL_OFFSET 0x0000 /* DMA control */
#define LPC54_DMA_INTSTA_OFFSET 0x0004 /* Interrupt status */
#define LPC54_DMA_INTSTAT_OFFSET 0x0004 /* Interrupt status */
#define LPC54_DMA_SRAMBASE_OFFSET 0x0008 /* SRAM address of the channel configuration table */
/* Shared registers */
@ -71,30 +72,19 @@
#define LPC54_DMA_SETTRIG0_OFFSET 0x0070 /* Set trigger control bits for all DMA channels */
#define LPC54_DMA_ABORT0_OFFSET 0x0078 /* Channel abort control for all DMA channels */
/* Channel registers
*
/* Channel registers */
* CFGn Configuration register for DMA channel n
* CTLSTATn Control and status register for DMA channel n
* XFERCFGn Transfer configuration register for DMA channel n
*/
#define LPC54_DMA_CHAN_OFFSET(n) (0x0400 + ((n) << 4))
#define LPC54_DMA_CFG_OFFSET 0x0000 /* Configuration register for DMA channel n */
#define LPC54_DMA_CTLSTAT_OFFSET 0x0004 /* Control and status register for DMA channel n */
#define LPC54_DMA_XFERCFG_OFFSET 0x0008 /* Transfer configuration register for DMA channel n */
#define LPC54_DMA_CHAN_OFFSET(n) ((n) << 4)
#define LPC54_DMA_CHAN_BASE_OFFSET 0x0400
/* Register addresses ***********************************************************************/
#define LPC54_DMA_CFG_OFFSET 0x0000
#define LPC54_DMA_CTLSTAT_OFFSET 0x0004
#define LPC54_DMA_XFERCFG_OFFSET 0x0008
#define LPC54_DMA_CFGn_OFFSET(n) (LPC54_DMA_CHAN_BASE_OFFSET + LPC54_DMA_CHAN_OFFSET(n) + LPC54_DMA_CFG_OFFSET)
#define LPC54_DMA_CTLSTATn_OFFSET(n) (LPC54_DMA_CHAN_BASE_OFFSET + LPC54_DMA_CHAN_OFFSET(n) + LPC54_DMA_CTLSTAT_OFFSET)
#define LPC54_DMA_XFERCFGn_OFFSET(n) (LPC54_DMA_CHAN_BASE_OFFSET + LPC54_DMA_CHAN_OFFSET(n) + LPC54_DMA_CTLSTAT_OFFSET)
/* Register addresses *******************************************************************************/
/* Global control and status registers */
#define LPC54_DMA_CTRL (LPC54_DMA_BASE + LPC54_DMA_CTRL_OFFSET)
#define LPC54_DMA_INTSTA (LPC54_DMA_BASE + LPC54_DMA_INTSTA_OFFSET)
#define LPC54_DMA_INTSTAT (LPC54_DMA_BASE + LPC54_DMA_INTSTAT_OFFSET)
#define LPC54_DMA_SRAMBASE (LPC54_DMA_BASE + LPC54_DMA_SRAMBASE_OFFSET)
/* Shared registers */
@ -114,11 +104,12 @@
/* Channel registers */
#define LPC54_DMA_CFG(n) (LPC54_DMA_BASE + LPC54_DMA_CFGn_OFFSET(n))
#define LPC54_DMA_CTLSTAT(n) (LPC54_DMA_BASE + LPC54_DMA_CTLSTATn_OFFSET(n))
#define LPC54_DMA_XFERCFG(n) (LPC54_DMA_BASE + LPC54_DMA_XFERCFGn_OFFSET(n))
#define LPC54_DMA_CHAN_BASE(n) (LPC54_DMA_BASE + LPC54_DMA_CHAN_OFFSET(n))
#define LPC54_DMA_CFG(n) (LPC54_DMA_CHAN_BASE(n) + LPC54_DMA_CFG_OFFSET)
#define LPC54_DMA_CTLSTAT(n) (LPC54_DMA_CHAN_BASE(n) + LPC54_DMA_CTLSTAT_OFFSET)
#define LPC54_DMA_XFERCFG(n) (LPC54_DMA_CHAN_BASE(n) + LPC54_DMA_XFERCFG_OFFSET)
/* Register bit definitions *************************************************************************/
/* Register bit definitions *****************************************************************/
/* DMA control */
@ -126,121 +117,88 @@
/* Interrupt status */
#define DMA_INTSTA_ACTIVEINT (1 << 1) /* Bit 1: Interrupt pending */
#define DMA_INTSTA_ACTIVEERRINTT (1 << 2) /* Bit 2: error interruptpending */
#define DMA_INTSTAT_ACTIVEINT (1 << 1) /* Bit 1: Summarizes pending enabled interrupts */
#define DMA_INTSTAT_ACTIVEERRINT (1 << 2) /* Bit 2: Summarizes pending error interrupts */
/* SRAM address of the channel configuration table (Bits 9-31) */
/* SRAM address of the channel configuration table */
/* Channel enable read and Set for all DMA channels */
#define DMA_SRAMBASE_MASK 0xfffffe00
#define DMA_ENABLESET0(n) (1 << (n)) /* Bit n: Enable/disable DMA channel n */
/* The remaining shared registers are all 32 bit encoded fieldss with bit n corresponding to
* Channel n.
*/
/* Channel enable clear for all DMA channels */
#define DMA_CHANNEL(n) (1 << (n))
#define DMA_ALL_CHANNELS 0x3fffffff
#define DMA_ENABLECLR0(n) (1 << (n)) /* Bit n: Disable DMA channel n */
/* Channel registers */
/* Channel active status for all DMA channels */
#define DMA_ACTIVE0(n) (1 << (n)) /* Bit n: Channel n active */
/* Channel busy status for all DMA channels */
#define DMA_BUSY0(n) (1 << (n)) /* Bit n: Channel n busy */
/* Error interrupt status for all DMA channels */
#define DMA_ERRINT0 (1 << (n)) /* Bit n: Error interrupt active*/
/* Interrupt enable read and Set for all DMA channels */
#define DMA_INTENSET0 (1 << (n)) /* Bit n: Enable channel n interrupt */
/* Interrupt enable clear for all DMA channels */
#define DMA_INTENCLR0 (1 << (n)) /* Bit n: Disable channel n interrupt */
/* Interrupt A status for all DMA channels */
#define DMA_INTA0 (1 << (n)) /* Bit n: DMA channel n interrupt A active */
/* Interrupt B status for all DMA channels */
#define DMA_INTB0 (1 << (n)) /* Bit n: DMA channel n interrupt B active */
/* Set ValidPending control bits for all DMA channels */
#define DMA_SETVALID0 (1 << (n)) /* Bit n: SETVALID control for DMA channel n */
/* Set trigger control bits for all DMA channels */
#define DMA_SETTRIG0 (1 << (n)) /* Bit n: Set Trigger control bit for DMA channel n */
/* Channel abort control for all DMA channels */
#define DMA_ABORT0 (1 << (n)) /* Bit n: Abort control for DMA channel n */
/* Configuration register for DMA channel n=0..28 */
/* Configuration register for DMA channel n */
#define DMA_CFG_PERIPHREQEN (1 << 0) /* Bit 0: Peripheral request Enable */
#define DMA_CFG_HWTRIGEN (1 << 1) /* Bit 1: Hardware Triggering Enable for this channel */
#define DMA_CFG_HWTRIGEN (1 << 1) /* Bit 1: Hardware Triggering Enable */
#define DMA_CFG_TRIGPOL (1 << 4) /* Bit 4: Trigger Polarity */
# define DMA_CFG_ACTIVE_LOW (0)
# define DMA_CFG_FALLING_EDGE (0)
# define DMA_CFG_ACTIVE_HIGH DMA_CFG_TRIGPOL
# define DMA_CFG_RISING_EDGE DMA_CFG_TRIGPOL
#define DMA_CFG_TRIGTYPE (1 << 5) /* Bit 5: Trigger Type */
# define DMA_CFG_TRIGTYPE_EDGE (0)
# define DMA_CFG_TRIGTYPE_LEVEL DMA_CFG_TRIGTYPE
# define DMA_CFG_EDGE_TRIGGER (0)
# define DMA_CFG_LEVEL_TRIGGER DMA_CFG_TRIGTYPE
#define DMA_CFG_TRIGBURST (1 << 6) /* Bit 6: Trigger Burst */
#define DMA_CFG_BURSTPOWER_SHIFT (8) /* Bits 8-11: Burst Power */
#define DMA_CFG_BURSTPOWER_MASK (15 << DMA_CFG_BURSTPOWER_SHIFT)
# define DMA_CFG_BURSTPOWER_SIZE1 (0 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 1 */
# define DMA_CFG_BURSTPOWER_SIZE2 (1 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 2) */
# define DMA_CFG_BURSTPOWER_SIZE4 (2 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 4) */
# define DMA_CFG_BURSTPOWER_SIZE8 (3 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 8) */
# define DMA_CFG_BURSTPOWER_SIZE16 (4 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 16 */
# define DMA_CFG_BURSTPOWER_SIZE32 (5 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 32 */
# define DMA_CFG_BURSTPOWER_SIZE64 (6 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 64 */
# define DMA_CFG_BURSTPOWER_SIZE128 (7 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 128 */
# define DMA_CFG_BURSTPOWER_SIZE256 (8 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 256 */
# define DMA_CFG_BURSTPOWER_SIZE512 (9 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 512 */
# define DMA_CFG_BURSTPOWER_SIZE1024 (10 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 1024 */
# define DMA_CFG_BURSTPOWER_1 (0 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 1 (2^0) */
# define DMA_CFG_BURSTPOWER_2 (1 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 2 (2^1) */
# define DMA_CFG_BURSTPOWER_3 (2 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 4 (2^2) */
# define DMA_CFG_BURSTPOWER_8 (3 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 8 (2^2) */
# define DMA_CFG_BURSTPOWER_16 (4 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 16 (2^2) */
# define DMA_CFG_BURSTPOWER_32 (5 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 32 (2^2) */
# define DMA_CFG_BURSTPOWER_64 (6 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 64 (2^2) */
# define DMA_CFG_BURSTPOWER_128 (7 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 128 (2^2) */
# define DMA_CFG_BURSTPOWER_256 (8 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 256 (2^2) */
# define DMA_CFG_BURSTPOWER_512 (9 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 256 (2^2) */
# define DMA_CFG_BURSTPOWER_1024 (10 << DMA_CFG_BURSTPOWER_SHIFT) /* Burst size = 1024 (2^10) */
#define DMA_CFG_SRCBURSTWRAP (1 << 14) /* Bit 14: Source Burst Wrap */
#define DMA_CFG_DSTBURSTWRAP (1 << 15) /* Bit 15: Destination Burst Wrap */
#define DMA_CFG_CHPRIORITY_SHIFT (16) /* Bits 16-18: Priority of this channel */
#define DMA_CFG_CHPRIORITY_MASK (7 << DMA_CFG_CHPRIORITY_MASK)
# define DMA_CFG_CHPRIORITY(n) ((uint32_t)(n) << DMA_CFG_CHPRIORITY_MASK)
# define DMA_CFG_CHPRIORITY_MAX (0 << DMA_CFG_CHPRIORITY_MASK) /* highest priority */
# define DMA_CFG_CHPRIORITY_MIn (7 << DMA_CFG_CHPRIORITY_MASK) /* lowest priority */
#define DMA_CFG_CHPRIORITY_MASK (7 << DMA_CFG_CHPRIORITY_SHIFT)
# define DMA_CFG_CHPRIORITY(n) ((uint32_t)(n) << DMA_CFG_CHPRIORITY_SHIFT)
# define DMA_CFG_CHPRIORITY_HIGH (0 << DMA_CFG_CHPRIORITY_SHIFT) /* Highest priority */
# define DMA_CFG_CHPRIORITY_LOW (7 << DMA_CFG_CHPRIORITY_SHIFT) /* Lowest priority */
/* Control and status register for DMA channel n=0..28 */
/* Control and status register for DMA channel n */
#define DMA_CTLSTAT_VALIDPENDING (1 << 0) /* Bit 0: Valid pending flag for this channel */
#define DMA_CTLSTAT_VALIDPENDING (1 << 0) /* Bit 0: Valid pending flag */
#define DMA_CTLSTAT_TRIG (1 << 2) /* Bit 2: Trigger flag */
/* Transfer configuration register for DMA channel n=0..28 */
/* Transfer configuration register for DMA channel n */
#define DMA_XFERCFG_CFGVALID (1 << 0) /* Bit 0: Configuration Valid flag */
#define DMA_XFERCFG_RELOAD (1 << 1) /* Bit 1: Channel control structure will be reloaded */
#define DMA_XFERCFG_SWTRIG (1 << 2 /* Bit 2: Software Trigger */
#define DMA_XFERCFG_CLRTRIG (1 << 3) /* Bit 3: Clear Trigger. 0 */
#define DMA_XFERCFG_SETINTA (1 << 4) /* Bit 4: Set Interrupt flag A for this channel */
#define DMA_XFERCFG_SETINTB (1 << 5) /* Bit 5: Set Interrupt flag B for this channel */
#define DMA_XFERCFG_WIDTH_SHIFT (8) /* Bits 8-9: Transfer width used for this DMA channel */
#define DMA_XFERCFG_RELOAD (1 << 1) /* Bit 1: Reload channels control structure */
#define DMA_XFERCFG_SWTRIG (1 << 2) /* Bit 2: Software Trigger */
#define DMA_XFERCFG_CLRTRIG (1 << 3) /* Bit 3: Clear Trigger */
#define DMA_XFERCFG_SETINTA (1 << 4) /* Bit 4: Set Interrupt flag A */
#define DMA_XFERCFG_SETINTB (1 << 5) /* Bit 5: Set Interrupt flag B */
#define DMA_XFERCFG_WIDTH_SHIFT (8) /* Bits 8-9: Transfer width */
#define DMA_XFERCFG_WIDTH_MASK (3 << DMA_XFERCFG_WIDTH_SHIFT)
# define DMA_XFERCFG_WIDTH _MASK (0 << DMA_XFERCFG_WIDTH_SHIFT) /* 8-bit */
# define DMA_XFERCFG_WIDTH _MASK (1 << DMA_XFERCFG_WIDTH_SHIFT) /* 16-bit */
# define DMA_XFERCFG_WIDTH _MASK (2 << DMA_XFERCFG_WIDTH_SHIFT) /* 32-bit */
#define DMA_XFERCFG_SRCINC_SHIFT (12) /* Bits 12-13: Source address increment control */
# define DMA_XFERCFG_WIDTH_8BIT (0 << DMA_XFERCFG_WIDTH_SHIFT) /* 8-bit transfers */
# define DMA_XFERCFG_WIDTH_16BIT (1 << DMA_XFERCFG_WIDTH_SHIFT) /* 16-bit transfers */
# define DMA_XFERCFG_WIDTH_32BIT (2 << DMA_XFERCFG_WIDTH_SHIFT) /* 32-bit transfers */
#define DMA_XFERCFG_SRCINC_SHIFT (12) /* Bits 12-13: Source address increment */
#define DMA_XFERCFG_SRCINC_MASK (3 << DMA_XFERCFG_SRCINC_SHIFT)
# define DMA_XFERCFG_SRCINC_NONE (0 << DMA_XFERCFG_SRCINC_SHIFT) /* None */
# define DMA_XFERCFG_SRCINC_WIDTH (1 << DMA_XFERCFG_SRCINC_SHIFT) /* 1 x width */
# define DMA_XFERCFG_SRCINC_2xWIDTH (2 << DMA_XFERCFG_SRCINC_SHIFT) /* 2 x width */
# define DMA_XFERCFG_SRCINC_4xWIDTH (3 << DMA_XFERCFG_SRCINC_SHIFT) /* 4 x width */
#define DMA_XFERCFG_DSTINC_SHIFT (14) /* Bits 14:15: Destination address increment control */
# define DMA_XFERCFG_SRCINC_NONE (0 << DMA_XFERCFG_SRCINC_SHIFT) /* No increment */
# define DMA_XFERCFG_SRCINC_1X (1 << DMA_XFERCFG_SRCINC_SHIFT) /* 1 x width */
# define DMA_XFERCFG_SRCINC_2X (2 << DMA_XFERCFG_SRCINC_SHIFT) /* 2 x width */
# define DMA_XFERCFG_SRCINC_4X (3 << DMA_XFERCFG_SRCINC_SHIFT) /* 4 x width */
#define DMA_XFERCFG_DSTINC_SHIFT (14) /* Bits 14-15: Destination address increment */
#define DMA_XFERCFG_DSTINC_MASK (3 << DMA_XFERCFG_DSTINC_SHIFT)
# define DMA_XFERCFG_SRCINC_NONE (0 << DMA_XFERCFG_DSTINC_SHIFT) /* None */
# define DMA_XFERCFG_DSTINC_WIDTH (1 << DMA_XFERCFG_DSTINC_SHIFT) /* 1 x width */
# define DMA_XFERCFG_DSTINC_2xWIDTH (2 << DMA_XFERCFG_DSTINC_SHIFT) /* 2 x width */
# define DMA_XFERCFG_DSTINC_4xWIDTH (3 << DMA_XFERCFG_DSTINC_SHIFT) /* 4 x width */
#define DMA_XFERCFGXFERCOUNT_SHIFT (16) /* Bits 16:25: Total number of transfers to be performed -1 */
#define DMA_XFERCFGXFERCOUNT_MASK (0x3ff << DMA_XFERCFGXFERCOUNT_SHIFT)
# define DMA_XFERCFGXFERCOUNT(n) ((uint32_t)((n)-1) << DMA_XFERCFGXFERCOUNT_SHIFT)
# define DMA_XFERCFG_DSTINC_NONE (0 << DMA_XFERCFG_DSTINC_SHIFT) /* No increment */
# define DMA_XFERCFG_DSTINC_1X (1 << DMA_XFERCFG_DSTINC_SHIFT) /* 1 x width */
# define DMA_XFERCFG_DSTINC_2X (2 << DMA_XFERCFG_DSTINC_SHIFT) /* 2 x width */
# define DMA_XFERCFG_DSTINC_4X (3 << DMA_XFERCFG_DSTINC_SHIFT) /* 4 x width */
#define DMA_XFERCFG_XFERCOUNT_SHIFT (16) /* Bits 16-25: Total number of transfers to be performed */
#define DMA_XFERCFG_XFERCOUNT_MASK (0x3ff << DMA_XFERCFG_XFERCOUNT_SHIFT)
# define DMA_XFERCFG_XFERCOUNT(n) ((uint32_t)((n)-1) << DMA_XFERCFG_XFERCOUNT_SHIFT)
#endif /* __ARCH_ARM_SRC_LPC54XX_CHIP_LPC54_DMA_H */

View File

@ -41,7 +41,9 @@
****************************************************************************/
#include <nuttx/config.h>
#include "up_arch.h"
#include <chip/lpc54_syscon.h>
/****************************************************************************
* Pre-processor Definitions

View File

@ -41,6 +41,7 @@
****************************************************************************/
#include <nuttx/config.h>
#include <chip/lpc54_syscon.h>
/****************************************************************************
* Pre-processor Definitions

View File

@ -0,0 +1,642 @@
/****************************************************************************
* arch/arm/src/lpc54xx/lpc54_dma.c
*
* Copyright (C) 2017 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/arch.h>
#include "up_internal.h"
#include "up_arch.h"
#include "chip/lpc54_dma.h"
#include "lpc54_enableclk.h"
#include "lpc54_reset.h"
#include "lpc54_dma.h"
#ifdef CONFIG_LPC54_DMA
/****************************************************************************
* Private Types
****************************************************************************/
/* This structure represents the state of one DMA channel */
struct lpc54_dmach_s
{
uint8_t chn; /* The DMA channel number */
bool inuse; /* True: The channel is in use */
bool inprogress; /* True: DMA is in progress on this channel */
uint16_t nxfrs; /* Number of bytes to transfers */
dma_callback_t callback; /* DMA completion callback function */
void *arg; /* Argument to pass to the callback function */
};
/* This structure represents the state of the LPC54 DMA block */
struct lpc54_dma_s
{
sem_t exclsem; /* For exclusive access to the DMA channel list */
/* This is the state of each DMA channel */
struct lpc54_dmach_s dmach[LPC54_DMA_NCHANNELS];
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/* The state of the LPC54 DMA block */
static struct lpc54_dma_s g_dma;
/****************************************************************************
* Public Data
****************************************************************************/
/* If the following value is zero, then there is no DMA in progress. This
* value is needed in the IDLE loop to determine if the IDLE loop should
* go into lower power power consumption modes. According to the LPC54xx
* User Manual: "The DMA controller can continue to work in Sleep mode, and
* has access to the peripheral SRAMs and all peripheral registers. The
* flash memory and the Main SRAM are not available in Sleep mode, they are
* disabled in order to save power."
*/
volatile uint8_t g_dma_inprogress;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: lpc54_dma_inprogress
*
* Description:
* Another DMA has started. Increment the g_dma_inprogress counter.
*
* Returned Value:
* None
*
****************************************************************************/
static void lpc54_dma_inprogress(struct lpc54_dmach_s *dmach)
{
irqstate_t flags;
/* Increment the DMA in progress counter */
flags = enter_critical_section();
DEBUGASSERT(!dmach->inprogress && g_dma_inprogress < LPC54_DMA_NCHANNELS);
g_dma_inprogress++;
dmach->inprogress = true;
leave_critical_section(flags);
}
/****************************************************************************
* Name: lpc54_dma_done
*
* Description:
* A DMA has completed. Decrement the g_dma_inprogress counter.
*
* This function is called only from lpc54_dmastop which, in turn, will be
* called either by the user directly, by the user indirectly via
* lpc54_dmafree(), or from lpc54_dma_interrupt when the transfer completes.
*
* NOTE: In the first two cases, we must be able to handle the case where
* there is no DMA in progress and gracefully ignore the call.
*
* Returned Value:
* None
*
****************************************************************************/
static void lpc54_dma_done(struct lpc54_dmach_s *dmach)
{
irqstate_t flags;
/* Increment the DMA in progress counter */
flags = enter_critical_section();
if (dmach->inprogress)
{
DEBUGASSERT(g_dma_inprogress > 0);
dmach->inprogress = false;
g_dma_inprogress--;
}
leave_critical_section(flags);
}
/****************************************************************************
* Name: lpc54_dma_dispatch
*
* Description:
* Dispatch a DMA interrupt.
*
* Returned Value:
* None
*
****************************************************************************/
static void lpc54_dma_dispatch(int ch, int result)
{
struct lpc54_dmach_s *dmach;
/* Yes.. Is this channel assigned? Is there a callback function? */
dmach = &g_dma.dmach[ch];
if (dmach->inuse && dmach->callback != NULL)
{
/* Perform the callback */
dmach->callback((DMA_HANDLE)dmach, dmach->arg, result);
}
/* Disable this channel, mask any further interrupts for this channel, and
* clear any pending interrupts.
*/
lpc54_dmastop((DMA_HANDLE)dmach);
}
/****************************************************************************
* Name: lpc54_dma_interrupt
*
* Description:
* The common DMA interrupt handler.
*
* Returned Value:
* None
*
****************************************************************************/
static int lpc54_dma_interrupt(int irq, FAR void *context, FAR void *arg)
{
uint32_t pending;
uint32_t bitmask;
int ch;
/* Check for pending DMA channel error interrupts */
pending = getreg32(LPC54_DMA_ERRINT0);
putreg32(pending, LPC54_DMA_ERRINT0);
for (ch = 0; pending != 0 && ch < LPC54_DMA_NCHANNELS; ch++)
{
/* Check if there is a pending error on this channel */
bitmask = DMA_CHANNEL((uint32_t)ch);
if ((pending & bitmask) != 0)
{
/* Dispatch the DMA channel error event */
lpc54_dma_dispatch(ch, -EIO);
pending &= ~bitmask;
}
}
/* Check for pending DMA interrupt A events */
pending = getreg32(LPC54_DMA_INTA0);
putreg32(pending, LPC54_DMA_INTA0);
for (ch = 0; pending != 0 && ch < LPC54_DMA_NCHANNELS; ch++)
{
/* Check if there is a pending interrupt A on this channel */
bitmask = DMA_CHANNEL((uint32_t)ch);
if ((pending & bitmask) != 0)
{
/* Dispatch DMA channel interrupt A event */
lpc54_dma_dispatch(ch, OK);
pending &= ~bitmask;
}
}
#if 0 /* interrupt B is not used */
/* Check for pending DMA interrupt B events */
pending = getreg32(LPC54_DMA_INTB0);
putreg32(pending, LPC54_DMA_INTB0);
for (ch = 0; pending != 0 && ch < LPC54_DMA_NCHANNELS; ch++)
{
/* Check if there is a pending interrupt A on this channel */
bitmask = DMA_CHANNEL((uint32_t)ch);
if ((pending & bitmask) != 0)
{
/* Dispatch DMA channel interrupt B event */
lpc54_dma_dispatch(ch, OK);
pending &= ~bitmask;
}
}
#endif
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_dmainitialize
*
* Description:
* Initialize the DMA subsystem.
*
* Returned Value:
* Zero on success; A negated errno value on failure.
*
****************************************************************************/
void weak_function up_dmainitialize(void)
{
uint32_t regval;
int ret;
int ch;
/* Enable clocking to the DMA block */
lpc54_dma_enableclk();
/* Reset the DMA peripheral */
lpc54_reset_dma();
/* Reset all channel configurations */
for (ch = 0; ch < LPC54_DMA_NCHANNELS; ch++)
{
#warning Missing logic
}
/* Disable and clear all DMA interrupts */
putreg32(DMA_ALL_CHANNELS, LPC54_DMA_INTENCLR0);
putreg32(DMA_ALL_CHANNELS, LPC54_DMA_ERRINT0);
putreg32(DMA_ALL_CHANNELS, LPC54_DMA_INTA0);
putreg32(DMA_ALL_CHANNELS, LPC54_DMA_INTB0);
/* Initialize the DMA state structure */
nxsem_init(&g_dma.exclsem, 0, 1);
for (ch = 0; ch < LPC54_DMA_NCHANNELS; ch++)
{
g_dma.dmach[ch].chn = ch; /* Channel number */
g_dma.dmach[ch].inuse = false; /* Channel is not in-use */
}
/* Attach and enable the DMA interrupt handler */
ret = irq_attach(LPC54_IRQ_DMA, lpc54_dma_interrupt, NULL);
if (ret == OK)
{
up_enable_irq(LPC54_IRQ_DMA);
}
/* Enable the DMA controller */
putreg32(DMA_CTRL_ENABLE, LPC54_DMA_CTRL);
}
/****************************************************************************
* Name: lpc54_dmachannel
*
* Description:
* Allocate a DMA channel. This function sets aside a DMA channel and
* gives the caller exclusive access to the DMA channel.
*
* Returned Value:
* One success, this function returns a non-NULL, void* DMA channel
* handle. NULL is returned on any failure. This function can fail only
* if no DMA channel is available.
*
****************************************************************************/
DMA_HANDLE lpc54_dmachannel(void)
{
struct lpc54_dmach_s *dmach = NULL;
int ret;
int ch;
/* Get exclusive access to the DMA state structure */
do
{
ret = nxsem_wait(&g_dma.exclsem);
DEBUGASSERT(ret == OK || ret == -EINTR);
}
while (ret < 0);
/* Find an available DMA channel */
for (ch = 0; ch < LPC54_DMA_NCHANNELS; ch++)
{
if (!g_dma.dmach[ch].inuse)
{
/* Found one! */
dmach = &g_dma.dmach[ch];
g_dma.dmach[ch].inuse = true;
break;
}
}
/* Return what we found (or not) */
nxsem_post(&g_dma.exclsem);
return (DMA_HANDLE)dmach;
}
/****************************************************************************
* Name: lpc54_dmafree
*
* Description:
* Release a DMA channel. NOTE: The 'handle' used in this argument must
* NEVER be used again until lpc54_dmachannel() is called again to re-gain
* a valid handle.
*
* Returned Value:
* None
*
****************************************************************************/
void lpc54_dmafree(DMA_HANDLE handle)
{
struct lpc54_dmach_s *dmach = (DMA_HANDLE)handle;
DEBUGASSERT(dmach && dmach->inuse);
/* Make sure that the DMA channel was properly stopped */
lpc54_dmastop(handle);
/* Mark the channel available. This is an atomic operation and needs no
* special protection.
*/
dmach->inuse = false;
}
/****************************************************************************
* Name: lpc54_dmasetup
*
* Description:
* Configure DMA for one transfer.
*
****************************************************************************/
int lpc54_dmarxsetup(DMA_HANDLE handle, uint32_t control, uint32_t config,
uint32_t srcaddr, uint32_t destaddr, size_t nbytes)
{
struct lpc54_dmach_s *dmach = (DMA_HANDLE)handle;
uint32_t bitmask;
uint32_t regval;
uintptr_t base;
DEBUGASSERT(dmach && dmach->inuse && nbytes < 4096);
bitmask = DMA_CHANNEL((uint32_t)dmach->chn);
base = LPC54_DMA_CHAN_BASE((uint32_t)dmach->chn);
/* Put the channel in a known state. */
#warning Missing logic
/* Program the DMA channel */
#warning Missing logic
return OK;
}
/****************************************************************************
* Name: lpc54_dmastart
*
* Description:
* Start the DMA transfer
*
****************************************************************************/
int lpc54_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg)
{
struct lpc54_dmach_s *dmach = (DMA_HANDLE)handle;
uint32_t regval;
uint32_t bitmask;
uintptr_t base;
DEBUGASSERT(dmach && dmach->inuse && callback);
/* Save the callback information */
dmach->callback = callback;
dmach->arg = arg;
/* Increment the count of DMAs in-progress. This count will be
* decremented when lpc54_dmastop() is called, either by the user,
* indirectly via lpc54_dmafree(), or from lpc54_dma_interrupt when the
* transfer completes.
*/
lpc54_dma_inprogress(dmach);
/* Clear any pending DMA interrupts */
bitmask = DMA_CHANNEL((uint32_t)dmach->chn);
putreg32(bitmask, LPC54_DMA_ERRINT0);
putreg32(bitmask, LPC54_DMA_INTA0);
putreg32(bitmask, LPC54_DMA_INTB0);
/* Enable terminal count interrupt. */
#warning Missing logic
/* Enable the channel and unmask terminal count and error interrupts. */
#warning Missing logic
return OK;
}
/****************************************************************************
* Name: lpc54_dmastop
*
* Description:
* Cancel the DMA. After lpc54_dmastop() is called, the DMA channel is
* reset and lpc54_dmasetup() must be called before lpc54_dmastart() can be
* called again
*
* This function will be called either by the user directly, by the user
* indirectly via lpc54_dmafree(), or from lpc54_dma_interrupt when the
* transfer completes.
*
****************************************************************************/
void lpc54_dmastop(DMA_HANDLE handle)
{
struct lpc54_dmach_s *dmach = (DMA_HANDLE)handle;
uintptr_t regaddr;
uint32_t regval;
uint32_t bitmask;
DEBUGASSERT(dmach && dmach->inuse);
/* Disable this channel and mask any further interrupts from the channel.
* this channel.
*/
#warning Missing logic
/* Clear any pending interrupts for this channel */
bitmask = DMA_CHANNEL((uint32_t)dmach->chn);
putreg32(bitmask, LPC54_DMA_ERRINT0);
putreg32(bitmask, LPC54_DMA_INTA0);
putreg32(bitmask, LPC54_DMA_INTB0);
/* Decrement the count of DMAs in progress */
lpc54_dma_done(dmach);
}
/****************************************************************************
* Name: lpc54_dmasample
*
* Description:
* Sample DMA register contents
*
****************************************************************************/
#ifdef CONFIG_DEBUG_DMA
void lpc54_dmasample(DMA_HANDLE handle, struct lpc54_dmaregs_s *regs)
{
struct lpc54_dmach_s *dmach = (DMA_HANDLE)handle;
uintptr_t base;
DEBUGASSERT(dmach);
/* Sample the global DMA registers */
regs->gbl.ctrl = getreg32(LPC54_DMA_CTRL);
regs->gbl.intstat = getreg32(LPC54_DMA_INTSTAT);
regs->gbl.srambase = getreg32(LPC54_DMA_SRAMBASE);
regs->gbl.enableset0 = getreg32(LPC54_DMA_ENABLESET0);
regs->gbl.active0 = getreg32(LPC54_DMA_ACTIVE0);
regs->gbl.busy0 = getreg32(LPC54_DMA_BUSY0);
regs->gbl.errint0 = getreg32(LPC54_DMA_ERRINT0);
regs->gbl.intenset0 = getreg32(LPC54_DMA_INTENSET0);
regs->gbl.inta0 = getreg32(LPC54_DMA_INTA0);
regs->gbl.intb0 = getreg32(LPC54_DMA_INTB0);
/* Sample the DMA channel registers */
base = LPC54_DMA_CHAN_BASE((uint32_t)dmach->chn);
regs->ch.cfg = getreg32(base + LPC54_DMA_CFG_OFFSET);
regs->ch.ctlstat = getreg32(base + LPC54_DMA_CTLSTAT_OFFSET);
regs->ch.xfercfg = getreg32(base + LPC54_DMA_XFERCFG_OFFSET);
}
#endif /* CONFIG_DEBUG_DMA */
/****************************************************************************
* Name: lpc54_dmadump
*
* Description:
* Dump previously sampled DMA register contents
*
****************************************************************************/
#ifdef CONFIG_DEBUG_DMA
void lpc54_dmadump(DMA_HANDLE handle, const struct lpc54_dmaregs_s *regs, const char *msg)
{
struct lpc54_dmach_s *dmach = (DMA_HANDLE)handle;
uintptr_t base;
DEBUGASSERT(dmach);
/* Dump the sampled global DMA registers */
dmainfo("Global DMA Registers: %s\n", msg);
dmainfo(" CTRL[%08x]: %08lx\n",
LPC54_DMA_CTRL, (unsigned long)regs->gbl.ctrl);
dmainfo(" INTSTAT[%08x]: %08lx\n",
LPC54_DMA_INTSTAT, (unsigned long)regs->gbl.intstat);
dmainfo(" SRAMBASE[%08x]: %08lx\n",
LPC54_DMA_SRAMBASE, (unsigned long)regs->gbl.srambase);
dmainfo(" ENABLESET0[%08x]: %08lx\n",
LPC54_DMA_ENABLESET0, (unsigned long)regs->gbl.enableset0);
dmainfo(" ACTIVE0[%08x]: %08lx\n",
LPC54_DMA_ACTIVE0, (unsigned long)regs->gbl.active0);
dmainfo(" BUSY0[%08x]: %08lx\n",
LPC54_DMA_BUSY0, (unsigned long)regs->gbl.busy0);
dmainfo(" ERRINT0[%08x]: %08lx\n",
LPC54_DMA_ERRINT0, (unsigned long)regs->gbl.errint0);
dmainfo(" INTENSET0[%08x]: %08lx\n",
LPC54_DMA_INTENSET0, (unsigned long)regs->gbl.intenset0);
dmainfo(" INTA0[%08x]: %08lx\n",
LPC54_DMA_INTA0, (unsigned long)regs->gbl.inta0);
dmainfo(" INTB0[%08x]: %08lx\n",
LPC54_DMA_INTB0, (unsigned long)regs->gbl.intb0);
/* Dump the DMA channel registers */
base = LPC54_DMA_CHAN_BASE((uint32_t)dmach->chn);
dmainfo("Channel DMA Registers: %d\n", dmach->chn);
dmainfo(" CFG[%08x]: %08lx\n",
base + LPC54_DMA_CFG_OFFSET, (unsigned long)regs->ch.cfg);
dmainfo(" CTLSTAT[%08x]: %08lx\n",
base + LPC54_DMA_CTLSTAT_OFFSET, (unsigned long)regs->ch.ctlstat);
dmainfo(" XFERCFG[%08x]: %08lx\n",
base + LPC54_DMA_XFERCFG_OFFSET, (unsigned long)regs->ch.xfercfg);
}
#endif /* CONFIG_DEBUG_DMA */
#endif /* CONFIG_LPC54_DMA */

View File

@ -0,0 +1,218 @@
/****************************************************************************
* arch/arm/src/lpc54xx/lpc54_dma.h
*
* Copyright (C) 2017 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_LPC54XX_LP54_DMA_H
#define __ARCH_ARM_SRC_LPC54XX_LP54_DMA_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include "chip/lpc54_dma.h"
#ifdef CONFIG_LPC54_DMA
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
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 lpc54_dmaglobalregs_s
{
/* Global Registers */
uint32_t ctrl; /* DMA control */
uint32_t intstat; /* DMA Interrupt status */
uint32_t srambase; /* SRAM address of the channel configuration table */
uint32_t enableset0; /* DMA Channel enable read and set */
uint32_t active0; /* DMA Channel active status */
uint32_t busy0; /* DMA Channel busy status */
uint32_t errint0; /* DMA Error interrupt status */
uint32_t intenset0; /* DMA Interrupt enable read and set */
uint32_t inta0; /* DMA Interrupt A status */
uint32_t intb0; /* DMA Interrupt B status */
};
struct lpc54_dmachanregs_s
{
/* Channel Registers */
uint32_t cfg; /* DMA Configuration register */
uint32_t ctlstat; /* DMA Control and status register */
uint32_t xfercfg; /* DMA Transfer configuration register */
};
struct lpc54_dmaregs_s
{
/* Global Registers */
struct lpc54_dmaglobalregs_s gbl;
/* Channel Registers */
struct lpc54_dmachanregs_s ch;
};
#endif
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: lpc54_dmachannel
*
* Description:
* Allocate a DMA channel. This function sets aside a DMA channel and
* gives the caller exclusive access to the DMA channel.
*
* Returned Value:
* One success, this function returns a non-NULL, void* DMA channel
* handle. NULL is returned on any failure. This function can fail only
* if no DMA channel is available.
*
****************************************************************************/
DMA_HANDLE lpc54_dmachannel(void);
/****************************************************************************
* Name: lpc54_dmafree
*
* Description:
* Release a DMA channel. NOTE: The 'handle' used in this argument must
* NEVER be used again until lpc54_dmachannel() is called again to re-gain
* a valid handle.
*
* Returned Value:
* None
*
****************************************************************************/
void lpc54_dmafree(DMA_HANDLE handle);
/****************************************************************************
* Name: lpc54_dmasetup
*
* Description:
* Configure DMA for one transfer.
*
****************************************************************************/
int lpc54_dmarxsetup(DMA_HANDLE handle, uint32_t control, uint32_t config,
uint32_t srcaddr, uint32_t destaddr, size_t nbytes);
/****************************************************************************
* Name: lpc54_dmastart
*
* Description:
* Start the DMA transfer
*
****************************************************************************/
int lpc54_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg);
/****************************************************************************
* Name: lpc54_dmastop
*
* Description:
* Cancel the DMA. After lpc54_dmastop() is called, the DMA channel is
* reset and lpc54_dmasetup() must be called before lpc54_dmastart() can be
* called again
*
****************************************************************************/
void lpc54_dmastop(DMA_HANDLE handle);
/****************************************************************************
* Name: lpc54_dmasample
*
* Description:
* Sample DMA register contents
*
****************************************************************************/
#ifdef CONFIG_DEBUG_DMA
void lpc54_dmasample(DMA_HANDLE handle, struct lpc54_dmaregs_s *regs);
#else
# define lpc54_dmasample(handle,regs)
#endif
/****************************************************************************
* Name: lpc54_dmadump
*
* Description:
* Dump previously sampled DMA register contents
*
****************************************************************************/
#ifdef CONFIG_DEBUG_DMA
void lpc54_dmadump(DMA_HANDLE handle, const struct lpc54_dmaregs_s *regs,
const char *msg);
#else
# define lpc54_dmadump(handle,regs,msg)
#endif
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* CONFIG_LPC54_DMA */
#endif /* __ARCH_ARM_SRC_LPC54XX_LP54_DMA_H */

View File

@ -83,7 +83,7 @@ Configurations
Each LPCXpresso-LPC54628 configuration is maintained in a sub-directory
and can be selected as follow:
.tools/configure.sh [OPTIONS] xmc5400-relax/<subdir>
.tools/configure.sh [OPTIONS] lpcxpresso-lpc54628/<subdir>
See '.tools/configure.sh -h' for a list of all options. The most typical
are -l to select the Linux host or -c to select the Windows Cygwin host.