Add GPDMA skeleton file
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2750 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
be6c6381f8
commit
55e433f43a
@ -69,6 +69,6 @@ ifeq ($(CONFIG_USBDEV),y)
|
||||
CHIP_CSRCS += lpc17_usbdev.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_LPC17_DMA),y)
|
||||
ifeq ($(CONFIG_LPC17_GPDMA),y)
|
||||
CHIP_CSRCS += lpc17_gpdma.c
|
||||
endif
|
||||
|
226
arch/arm/src/lpc17xx/lpc17_gpdma.c
Executable file
226
arch/arm/src/lpc17xx/lpc17_gpdma.c
Executable file
@ -0,0 +1,226 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/lpc17xx/lpc17_gpdma.c
|
||||
*
|
||||
* Copyright (C) 2010 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* 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.h"
|
||||
#include "lpc17_internal.h"
|
||||
#include "lpc17_syscon.h"
|
||||
#include "lpc17_gpdma.h"
|
||||
|
||||
#ifdef CONFIG_LPC17_GPDMA
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Enables debug output from this file (needs CONFIG_DEBUG too) */
|
||||
|
||||
#undef DMA_DEBUG /* Define to enable debug */
|
||||
#undef DMA_VERBOSE /* Define to enable verbose debug */
|
||||
|
||||
#ifdef DMA_DEBUG
|
||||
# define dmadbg lldbg
|
||||
# ifdef DMA_VERBOSE
|
||||
# define spivdbg lldbg
|
||||
# else
|
||||
# define spivdbg(x...)
|
||||
# endif
|
||||
#else
|
||||
# undef DMA_VERBOSE
|
||||
# define dmadbg(x...)
|
||||
# define spivdbg(x...)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc17_dmainitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the GPDMA subsystem.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void lpc17_dmainitilaize(void)
|
||||
{
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc17_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 lpc17_dmachannel(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc17_dmafree
|
||||
*
|
||||
* Description:
|
||||
* Release a DMA channel. NOTE: The 'handle' used in this argument must
|
||||
* NEVER be used again until lpc17_dmachannel() is called again to re-gain
|
||||
* a valid handle.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void lpc17_dmafree(DMA_HANDLE handle)
|
||||
{
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc17_dmasetup
|
||||
*
|
||||
* Description:
|
||||
* Configure DMA for one transfer.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int lpc17_dmarxsetup(DMA_HANDLE handle, uint32_t control, uint32_t config,
|
||||
uint32_t srcaddr, uint32_t destaddr, size_t nbytes)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc17_dmastart
|
||||
*
|
||||
* Description:
|
||||
* Start the DMA transfer
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int lpc17_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc17_dmastop
|
||||
*
|
||||
* Description:
|
||||
* Cancel the DMA. After lpc17_dmastop() is called, the DMA channel is
|
||||
* reset and lpc17_dmasetup() must be called before lpc17_dmastart() can be
|
||||
* called again
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void lpc17_dmastop(DMA_HANDLE handle)
|
||||
{
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc17_dmasample
|
||||
*
|
||||
* Description:
|
||||
* Sample DMA register contents
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_DMA
|
||||
void lpc17_dmasample(DMA_HANDLE handle, struct lpc17_dmaregs_s *regs)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_DMA */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc17_dmadump
|
||||
*
|
||||
* Description:
|
||||
* Dump previously sampled DMA register contents
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_DMA
|
||||
void lpc17_dmadump(DMA_HANDLE handle, const struct lpc17_dmaregs_s *regs, const char *msg)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_DMA */
|
||||
|
||||
#endif /* CONFIG_LPC17_GPDMA */
|
@ -346,6 +346,53 @@
|
||||
* 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 lpc17_dmaglobalregs_s
|
||||
{
|
||||
/* Global Registers */
|
||||
|
||||
uint32_t intst; /* DMA Interrupt Status Register */
|
||||
uint32_t inttcst; /* DMA Interrupt Terminal Count Request Status Register */
|
||||
uint32_t interrst; /* DMA Interrupt Error Status Register */
|
||||
uint32_t rawinttcst; /* DMA Raw Interrupt Terminal Count Status Register */
|
||||
uint32_t rawinterrst; /* DMA Raw Error Interrupt Status Register */
|
||||
uint32_t enbldchns; /* DMA Enabled Channel Register */
|
||||
uint32_t softbreq; /* DMA Software Burst Request Register */
|
||||
uint32_t softsreq; /* DMA Software Single Request Register */
|
||||
uint32_t softlbreq; /* DMA Software Last Burst Request Register */
|
||||
uint32_t softlsreq; /* DMA Software Last Single Request Register */
|
||||
uint32_t config; /* DMA Configuration Register */
|
||||
uint32_t sync; /* DMA Synchronization Register */
|
||||
};
|
||||
|
||||
struct lpc17_dmachanregs_s
|
||||
{
|
||||
/* Channel Registers */
|
||||
|
||||
uint32_t srcaddr; /* DMA Channel Source Address Register */
|
||||
uint32_t destaddr; /* DMA Channel Destination Address Register */
|
||||
uint32_t lli; /* DMA Channel Linked List Item Register */
|
||||
uint32_t control; /* DMA Channel Control Register */
|
||||
uint32_t config; /* DMA Channel Configuration Register */
|
||||
};
|
||||
|
||||
struct lpc17_dmaregs_s
|
||||
{
|
||||
/* Global Registers */
|
||||
|
||||
struct lpc17_dmaglobalregs_s gbl;
|
||||
|
||||
/* Channel Registers */
|
||||
|
||||
struct lpc17_dmachanregs_s ch;
|
||||
};
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Inline Functions
|
||||
************************************************************************************/
|
||||
@ -560,6 +607,130 @@ EXTERN void spi_flush(FAR struct spi_dev_s *dev);
|
||||
EXTERN void ssp_flush(FAR struct spi_dev_s *dev);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc17_dmainitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the GPDMA subsystem.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LPC17_GPDMA
|
||||
EXTERN void lpc17_dmainitilaize(void);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc17_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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LPC17_GPDMA
|
||||
EXTERN DMA_HANDLE lpc17_dmachannel(void);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc17_dmafree
|
||||
*
|
||||
* Description:
|
||||
* Release a DMA channel. NOTE: The 'handle' used in this argument must
|
||||
* NEVER be used again until lpc17_dmachannel() is called again to re-gain
|
||||
* a valid handle.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LPC17_GPDMA
|
||||
EXTERN void lpc17_dmafree(DMA_HANDLE handle);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc17_dmasetup
|
||||
*
|
||||
* Description:
|
||||
* Configure DMA for one transfer.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LPC17_GPDMA
|
||||
EXTERN int lpc17_dmarxsetup(DMA_HANDLE handle,
|
||||
uint32_t control, uint32_t config,
|
||||
uint32_t srcaddr, uint32_t destaddr,
|
||||
size_t nbytes);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc17_dmastart
|
||||
*
|
||||
* Description:
|
||||
* Start the DMA transfer
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LPC17_GPDMA
|
||||
EXTERN int lpc17_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc17_dmastop
|
||||
*
|
||||
* Description:
|
||||
* Cancel the DMA. After lpc17_dmastop() is called, the DMA channel is
|
||||
* reset and lpc17_dmasetup() must be called before lpc17_dmastart() can be
|
||||
* called again
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LPC17_GPDMA
|
||||
EXTERN void lpc17_dmastop(DMA_HANDLE handle);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc17_dmasample
|
||||
*
|
||||
* Description:
|
||||
* Sample DMA register contents
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LPC17_GPDMA
|
||||
#ifdef CONFIG_DEBUG_DMA
|
||||
EXTERN void lpc17_dmasample(DMA_HANDLE handle, struct lpc17_dmaregs_s *regs);
|
||||
#else
|
||||
# define lpc17_dmasample(handle,regs)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc17_dmadump
|
||||
*
|
||||
* Description:
|
||||
* Dump previously sampled DMA register contents
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LPC17_GPDMA
|
||||
#ifdef CONFIG_DEBUG_DMA
|
||||
EXTERN void lpc17_dmadump(DMA_HANDLE handle, const struct lpc17_dmaregs_s *regs,
|
||||
const char *msg);
|
||||
#else
|
||||
# define lpc17_dmadump(handle,regs,msg)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ struct lpc17_spidev_s
|
||||
sem_t exclsem; /* Held while chip is selected for mutual exclusion */
|
||||
uint32_t frequency; /* Requested clock frequency */
|
||||
uint32_t actual; /* Actual clock frequency */
|
||||
uint8_t nbits; /* Width of word in bits (8 or 16) */
|
||||
uint8_t nbits; /* Width of word in bits (8 to 16) */
|
||||
uint8_t mode; /* Mode 0,1,2,3 */
|
||||
#endif
|
||||
};
|
||||
@ -495,7 +495,9 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nw
|
||||
spidbg("nwords: %d\n", nwords);
|
||||
while (nwords)
|
||||
{
|
||||
/* Write the data to transmitted to the SPI Data Register */
|
||||
/* Write some dummy data to the SPI Data Register in order to clock the
|
||||
* read data.
|
||||
*/
|
||||
|
||||
putreg32(0xff, LPC17_SPI_DR);
|
||||
|
||||
|
@ -507,7 +507,7 @@ static uint16_t ssp_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
|
||||
regval = ssp_getreg(priv, LPC17_SSP_DR_OFFSET);
|
||||
sspdbg("%04x->%04x\n", wd, regval);
|
||||
return regval;
|
||||
return (uint16_t)regval;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@ -532,22 +532,39 @@ static uint16_t ssp_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords)
|
||||
{
|
||||
FAR struct lpc17_sspdev_s *priv = (FAR struct lpc17_sspdev_s *)dev;
|
||||
FAR const uint8_t *ptr = (FAR const uint8_t *)buffer;
|
||||
uint8_t sr;
|
||||
union
|
||||
{
|
||||
FAR const uint8_t *p8;
|
||||
FAR const uint16_t *p16;
|
||||
FAR const void *pv;
|
||||
} u;
|
||||
uint32_t data;
|
||||
uint32_t sr;
|
||||
|
||||
/* Loop while thre are bytes remaining to be sent */
|
||||
|
||||
sspdbg("nwords: %d\n", nwords);
|
||||
u.pv = buffer;
|
||||
while (nwords > 0)
|
||||
{
|
||||
/* While the TX FIFO is not full and there are bytes left to send */
|
||||
|
||||
while ((ssp_getreg(priv, LPC17_SSP_SR_OFFSET) & SSP_SR_TNF) && nwords)
|
||||
{
|
||||
/* Fetch the data to send */
|
||||
|
||||
if (priv->nbits > 8)
|
||||
{
|
||||
data = (uint32_t)*u.p16++;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = (uint32_t)*u.p8++;
|
||||
}
|
||||
|
||||
/* Send the data */
|
||||
|
||||
ssp_putreg(priv, LPC17_SSP_DR_OFFSET, (uint32_t)*ptr);
|
||||
ptr++;
|
||||
ssp_putreg(priv, LPC17_SSP_DR_OFFSET, data);
|
||||
nwords--;
|
||||
}
|
||||
}
|
||||
@ -604,16 +621,22 @@ static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size
|
||||
static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords)
|
||||
{
|
||||
FAR struct lpc17_sspdev_s *priv = (FAR struct lpc17_sspdev_s *)dev;
|
||||
FAR uint8_t *ptr = (FAR uint8_t*)buffer;
|
||||
union
|
||||
{
|
||||
FAR uint8_t *p8;
|
||||
FAR uint16_t *p16;
|
||||
FAR void *pv;
|
||||
} u;
|
||||
uint32_t data;
|
||||
uint32_t rxpending = 0;
|
||||
|
||||
/* While there is remaining to be sent (and no synchronization error has occurred) */
|
||||
#warning "This only works with 8-bit transfers"
|
||||
|
||||
sspdbg("nwords: %d\n", nwords);
|
||||
u.pv = buffer;
|
||||
while (nwords || rxpending)
|
||||
{
|
||||
/* Fill the transmit FIFO with 0xff...
|
||||
/* Fill the transmit FIFO with 0xffff...
|
||||
* Write 0xff to the data register while (1) the TX FIFO is
|
||||
* not full, (2) we have not exceeded the depth of the TX FIFO,
|
||||
* and (3) there are more bytes to be sent.
|
||||
@ -623,7 +646,7 @@ static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nw
|
||||
while ((ssp_getreg(priv, LPC17_SSP_SR_OFFSET) & SSP_SR_TNF) &&
|
||||
(rxpending < LPC17_SSP_FIFOSZ) && nwords)
|
||||
{
|
||||
ssp_putreg(priv, LPC17_SSP_DR_OFFSET, 0xff);
|
||||
ssp_putreg(priv, LPC17_SSP_DR_OFFSET, 0xffff);
|
||||
nwords--;
|
||||
rxpending++;
|
||||
}
|
||||
@ -633,7 +656,15 @@ static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nw
|
||||
spivdbg("RX: rxpending: %d\n", rxpending);
|
||||
while (ssp_getreg(priv, LPC17_SSP_SR_OFFSET) & SSP_SR_RNE)
|
||||
{
|
||||
*ptr++ = (uint8_t)ssp_getreg(priv, LPC17_SSP_DR_OFFSET);
|
||||
data = (uint8_t)ssp_getreg(priv, LPC17_SSP_DR_OFFSET);
|
||||
if (priv->nbits > 8)
|
||||
{
|
||||
*u.p16++ = (uint16_t)data;
|
||||
}
|
||||
else
|
||||
{
|
||||
*u.p8++ = (uint8_t)data;
|
||||
}
|
||||
rxpending--;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user