mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 08:36:24 +08:00
SAML21: Completes first rought cut of DMAC driver
This commit is contained in:
@@ -158,19 +158,19 @@
|
||||
#define DMAC_QOSCTRL_WRBQOS_SHIFT (0) /* Bits 0-1: Write back quality of service */
|
||||
#define DMAC_QOSCTRL_WRBQOS_MASK (3 << DMAC_QOSCTRL_WRBQOS_SHIFT)
|
||||
# define DMAC_QOSCTRL_WRBQOS_DISABLE (0 << DMAC_QOSCTRL_WRBQOS_SHIFT) /* Background */
|
||||
# define DMAC_QOSCTRL_WRBQOS_LOW (1 << DMAC_QOSCTRL_WRBQOS_SHIFT) /* Sensitve bandwidth */
|
||||
# define DMAC_QOSCTRL_WRBQOS_LOW (1 << DMAC_QOSCTRL_WRBQOS_SHIFT) /* Sensitive bandwidth */
|
||||
# define DMAC_QOSCTRL_WRBQOS_MEDIUM (2 << DMAC_QOSCTRL_WRBQOS_SHIFT) /* Sensitive latency */
|
||||
# define DMAC_QOSCTRL_WRBQOS_HIGH (3 << DMAC_QOSCTRL_WRBQOS_SHIFT) /* Critical latency */
|
||||
#define DMAC_QOSCTRL_FQOS_SHIFT (2) /* Bits 2-3: Fetch quality of service */
|
||||
#define DMAC_QOSCTRL_FQOS_MASK (3 << DMAC_QOSCTRL_FQOS_SHIFT)
|
||||
# define DMAC_QOSCTRL_FQOS_DISABLE (0 << DMAC_QOSCTRL_FQOS_SHIFT) /* Background */
|
||||
# define DMAC_QOSCTRL_FQOS_LOW (1 << DMAC_QOSCTRL_FQOS_SHIFT) /* Sensitve bandwidth */
|
||||
# define DMAC_QOSCTRL_FQOS_LOW (1 << DMAC_QOSCTRL_FQOS_SHIFT) /* Sensitive bandwidth */
|
||||
# define DMAC_QOSCTRL_FQOS_MEDIUM (2 << DMAC_QOSCTRL_FQOS_SHIFT) /* Sensitive latency */
|
||||
# define DMAC_QOSCTRL_FQOS_HIGH (3 << DMAC_QOSCTRL_FQOS_SHIFT) /* Critical latency */
|
||||
#define DMAC_QOSCTRL_DQOS_SHIFT (4) /* Bits 4-5: Data transfer quality of service */
|
||||
#define DMAC_QOSCTRL_DQOS_MASK (3 << DMAC_QOSCTRL_DQOS_SHIFT)
|
||||
# define DMAC_QOSCTRL_DQOS_DISABLE (0 << DMAC_QOSCTRL_DQOS_SHIFT) /* Background */
|
||||
# define DMAC_QOSCTRL_DQOS_LOW (1 << DMAC_QOSCTRL_DQOS_SHIFT) /* Sensitve bandwidth */
|
||||
# define DMAC_QOSCTRL_DQOS_LOW (1 << DMAC_QOSCTRL_DQOS_SHIFT) /* Sensitive bandwidth */
|
||||
# define DMAC_QOSCTRL_DQOS_MEDIUM (2 << DMAC_QOSCTRL_DQOS_SHIFT) /* Sensitive latency */
|
||||
# define DMAC_QOSCTRL_DQOS_HIGH (3 << DMAC_QOSCTRL_DQOS_SHIFT) /* Critical latency */
|
||||
|
||||
@@ -208,9 +208,9 @@
|
||||
|
||||
/* Active Channels and Levels Register */
|
||||
|
||||
#define DMAC_ACTIVE_LVLEX0 (1 << 0) /* Bit 0: Level 0 channel trigger requrest executing */
|
||||
#define DMAC_ACTIVE_LVLEX1 (1 << 1) /* Bit 1: Level 1 channel trigger requrest executing */
|
||||
#define DMAC_ACTIVE_LVLEX2 (1 << 2) /* Bit 2: Level 2 channel trigger requrest executing */
|
||||
#define DMAC_ACTIVE_LVLEX0 (1 << 0) /* Bit 0: Level 0 channel trigger request executing */
|
||||
#define DMAC_ACTIVE_LVLEX1 (1 << 1) /* Bit 1: Level 1 channel trigger request executing */
|
||||
#define DMAC_ACTIVE_LVLEX2 (1 << 2) /* Bit 2: Level 2 channel trigger request executing */
|
||||
#define DMAC_ACTIVE_ID_SHIFT (8) /* Bits 8-11: Active channel ID */
|
||||
#define DMAC_ACTIVE_ID_MASK (15 << DMAC_ACTIVE_ID_SHIFT)
|
||||
#define DMAC_ACTIVE_ABUSY (1 << 15) /* Bit 15: Active channel busy */
|
||||
|
||||
+219
-79
@@ -83,13 +83,23 @@
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
/* The direction of the transfer */
|
||||
|
||||
enum sam_dmadir_e
|
||||
{
|
||||
DMADIR_UNKOWN = 0, /* We don't know the direction of the
|
||||
* transfer yet */
|
||||
DMADIR_TX, /* Transmit: Memory to peripheral */
|
||||
DMADIR_RX /* Receive: Peripheral to memory */
|
||||
};
|
||||
|
||||
/* This structure describes one DMA channel */
|
||||
|
||||
struct sam_dmach_s
|
||||
{
|
||||
uint8_t dc_chan; /* DMA channel number (0-6) */
|
||||
bool dc_inuse; /* TRUE: The DMA channel is in use */
|
||||
uint8_t dc_chan; /* DMA channel number (0-15) */
|
||||
uint8_t dc_dir; /* See enum sam_dmadir_e */
|
||||
uint32_t dc_flags; /* DMA channel flags */
|
||||
dma_callback_t dc_callback; /* Callback invoked when the DMA completes */
|
||||
void *dc_arg; /* Argument passed to callback function */
|
||||
@@ -116,12 +126,11 @@ static struct dma_desc_s *sam_append_desc(struct sam_dmach_s *dmach,
|
||||
uint32_t srcaddr,uint32_t dstaddr);
|
||||
static void sam_freelinklist(struct sam_dmach_s *dmach);
|
||||
static size_t sam_maxtransfer(struct sam_dmach_s *dmach);
|
||||
static uint16_t sam_bytes2beats(struct sam_dmach_s *dmach, size_t nbytes);
|
||||
static int sam_txbuffer(struct sam_dmach_s *dmach, uint32_t paddr,
|
||||
uint32_t maddr, size_t nbytes);
|
||||
static int sam_rxbuffer(struct sam_dmach_s *dmach, uint32_t paddr,
|
||||
uint32_t maddr, size_t nbytes);
|
||||
static int sam_single(struct sam_dmach_s *dmach);
|
||||
static int sam_multiple(struct sam_dmach_s *dmach);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
@@ -259,6 +268,7 @@ static void sam_dmaterminate(struct sam_dmach_s *dmach, int result)
|
||||
|
||||
dmach->dc_callback = NULL;
|
||||
dmach->dc_arg = NULL;
|
||||
dmach->dc_dir = DMADIR_UNKOWN;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -310,7 +320,7 @@ static int sam_dmainterrupt(int irq, void *context)
|
||||
|
||||
else if ((intpend & DMAC_INTPEND_SUSP) != 0)
|
||||
{
|
||||
#warning Missing logic
|
||||
/* REVISIT: Do we want to do anything here? */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -538,8 +548,43 @@ static void sam_freelinklist(struct sam_dmach_s *dmach)
|
||||
|
||||
static size_t sam_maxtransfer(struct sam_dmach_s *dmach)
|
||||
{
|
||||
#warning Missing logic
|
||||
return 0;
|
||||
int beatsize;
|
||||
|
||||
/* The number of bytes per beat is 2**BEATSIZE */
|
||||
|
||||
beatsize = (dmach->dc_flags & DMACH_FLAG_BEATSIZE_MASK) >>
|
||||
LPSRAM_BTCTRL_STEPSIZE_SHIFT;
|
||||
|
||||
/* Maximum beats is UINT16_MAX */
|
||||
|
||||
return (size_t)UINT16_MAX << beatsize;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_bytes2beats
|
||||
*
|
||||
* Description:
|
||||
* Convert a count of bytes into a count of beats
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t sam_bytes2beats(struct sam_dmach_s *dmach, size_t nbytes)
|
||||
{
|
||||
size_t mask;
|
||||
int beatsize;
|
||||
size_t nbeats;
|
||||
|
||||
/* The number of bytes per beat is 2**BEATSIZE */
|
||||
|
||||
beatsize = (dmach->dc_flags & DMACH_FLAG_BEATSIZE_MASK) >>
|
||||
LPSRAM_BTCTRL_STEPSIZE_SHIFT;
|
||||
|
||||
/* The number of beats is then the ceiling of the division */
|
||||
|
||||
mask = (1 < beatsize) - 1;
|
||||
nbeats = (nbytes + mask) >> beatsize;
|
||||
DEBUGASSERT(nbeats <= UINT16_MAX);
|
||||
return (uint16_t)nbeats;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -557,12 +602,55 @@ static int sam_txbuffer(struct sam_dmach_s *dmach, uint32_t paddr,
|
||||
{
|
||||
uint16_t btctrl;
|
||||
uint16_t btcnt;
|
||||
uint16_t tmp;
|
||||
|
||||
/* Set up the Block Transfer Control Register configuration */
|
||||
#warning Missing logic
|
||||
DEBUGASSERT(dmac->dc_dir == DMADIR_UNKOWN || dmac->dc_dir == DMADIR_TX);
|
||||
|
||||
/* Set up the Block Transfer Control Register configuration:
|
||||
*
|
||||
* This are fixed register selections:
|
||||
*
|
||||
* LPSRAM_BTCTRL_VALID - Descriptor is valid
|
||||
* LPSRAM_BTCTRL_EVOSEL_DISABLE - No event output
|
||||
* LPSRAM_BTCTRL_BLOCKACT_INT - Disable channel and generate interrupt
|
||||
* when the last block transfer completes.
|
||||
*
|
||||
* Other settings come from the channel configuration:
|
||||
*
|
||||
* LPSRAM_BTCTRL_BEATSIZE - Determined by DMACH_FLAG_BEATSIZE
|
||||
* LPSRAM_BTCTRL_SRCINC - Determined by DMACH_FLAG_MEMINCREMENT
|
||||
* LPSRAM_BTCTRL_DSTINC - Determined by DMACH_FLAG_PERIPHINCREMENT
|
||||
* LPSRAM_BTCTRL_STEPSEL - Determined by DMACH_FLAG_STEPSEL
|
||||
* LPSRAM_BTCTRL_STEPSIZE - Determined by DMACH_FLAG_STEPSIZE
|
||||
*/
|
||||
|
||||
btctrl = LPSRAM_BTCTRL_VALID | LPSRAM_BTCTRL_EVOSEL_DISABLE |
|
||||
LPSRAM_BTCTRL_BLOCKACT_INT;
|
||||
|
||||
tmp = (dmach->dc_flags & DMACH_FLAG_BEATSIZE_MASK) >> DMACH_FLAG_BEATSIZE_SHIFT;
|
||||
btctrl |= tmp << LPSRAM_BTCTRL_BEATSIZE_SHIFT;
|
||||
|
||||
if ((dmach->dc_flags & DMACH_FLAG_MEMINCREMENT) != 0)
|
||||
{
|
||||
btctrl |= LPSRAM_BTCTRL_SRCINC;
|
||||
}
|
||||
|
||||
if ((dmach->dc_flags & DMACH_FLAG_PERIPHINCREMENT) != 0)
|
||||
{
|
||||
btctrl |= LPSRAM_BTCTRL_DSTINC;
|
||||
}
|
||||
|
||||
if ((dmach->dc_flags & DMACH_FLAG_STEPSEL) == DMACH_FLAG_STEPSEL_PERIPH)
|
||||
{
|
||||
btctrl |= LPSRAM_BTCTRL_STEPSEL;
|
||||
}
|
||||
|
||||
tmp = (dmach->dc_flags & DMACH_FLAG_STEPSIZE_MASK) >> LPSRAM_BTCTRL_STEPSIZE_SHIFT;
|
||||
btctrl |= tmp << LPSRAM_BTCTRL_STEPSIZE_SHIFT;
|
||||
|
||||
/* Set up the Block Transfer Count Register configuration */
|
||||
#warning Missing logic
|
||||
|
||||
btcnt = sam_bytes2beats(dmach, nbytes);
|
||||
|
||||
/* Add the new link list entry */
|
||||
|
||||
@@ -571,6 +659,7 @@ static int sam_txbuffer(struct sam_dmach_s *dmach, uint32_t paddr,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dmach->dc_dir = DMADIR_TX;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -589,12 +678,55 @@ static int sam_rxbuffer(struct sam_dmach_s *dmach, uint32_t paddr,
|
||||
{
|
||||
uint16_t btctrl;
|
||||
uint16_t btcnt;
|
||||
uint16_t tmp;
|
||||
|
||||
/* Set up the Block Transfer Control Register configuration */
|
||||
#warning Missing logic
|
||||
DEBUGASSERT(dmac->dc_dir == DMADIR_UNKOWN || dmac->dc_dir == DMADIR_RX);
|
||||
|
||||
/* Set up the Block Transfer Control Register configuration:
|
||||
*
|
||||
* This are fixed register selections:
|
||||
*
|
||||
* LPSRAM_BTCTRL_VALID - Descriptor is valid
|
||||
* LPSRAM_BTCTRL_EVOSEL_DISABLE - No event output
|
||||
* LPSRAM_BTCTRL_BLOCKACT_INT - Disable channel and generate interrupt
|
||||
* when the last block transfer completes.
|
||||
*
|
||||
* Other settings come from the channel configuration:
|
||||
*
|
||||
* LPSRAM_BTCTRL_BEATSIZE - Determined by DMACH_FLAG_BEATSIZE
|
||||
* LPSRAM_BTCTRL_SRCINC - Determined by DMACH_FLAG_PERIPHINCREMENT
|
||||
* LPSRAM_BTCTRL_DSTINC - Determined by DMACH_FLAG_MEMINCREMENT
|
||||
* LPSRAM_BTCTRL_STEPSEL - Determined by DMACH_FLAG_STEPSEL
|
||||
* LPSRAM_BTCTRL_STEPSIZE - Determined by DMACH_FLAG_STEPSIZE
|
||||
*/
|
||||
|
||||
btctrl = LPSRAM_BTCTRL_VALID | LPSRAM_BTCTRL_EVOSEL_DISABLE |
|
||||
LPSRAM_BTCTRL_BLOCKACT_INT;
|
||||
|
||||
tmp = (dmach->dc_flags & DMACH_FLAG_BEATSIZE_MASK) >> DMACH_FLAG_BEATSIZE_SHIFT;
|
||||
btctrl |= tmp << LPSRAM_BTCTRL_BEATSIZE_SHIFT;
|
||||
|
||||
if ((dmach->dc_flags & DMACH_FLAG_PERIPHINCREMENT) != 0)
|
||||
{
|
||||
btctrl |= LPSRAM_BTCTRL_SRCINC;
|
||||
}
|
||||
|
||||
if ((dmach->dc_flags & DMACH_FLAG_MEMINCREMENT) != 0)
|
||||
{
|
||||
btctrl |= LPSRAM_BTCTRL_DSTINC;
|
||||
}
|
||||
|
||||
if ((dmach->dc_flags & DMACH_FLAG_STEPSEL) == DMACH_FLAG_STEPSEL_MEM)
|
||||
{
|
||||
btctrl |= LPSRAM_BTCTRL_STEPSEL;
|
||||
}
|
||||
|
||||
tmp = (dmach->dc_flags & DMACH_FLAG_STEPSIZE_MASK) >> LPSRAM_BTCTRL_STEPSIZE_SHIFT;
|
||||
btctrl |= tmp << LPSRAM_BTCTRL_STEPSIZE_SHIFT;
|
||||
|
||||
/* Set up the Block Transfer Count Register configuration */
|
||||
#warning Missing logic
|
||||
|
||||
btcnt = sam_bytes2beats(dmach, nbytes);
|
||||
|
||||
/* Add the new link list entry */
|
||||
|
||||
@@ -603,67 +735,10 @@ static int sam_rxbuffer(struct sam_dmach_s *dmach, uint32_t paddr,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dmach->dc_dir = DMADIR_RX;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_single
|
||||
*
|
||||
* Description:
|
||||
* Start a single buffer DMA.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int sam_single(struct sam_dmach_s *dmach)
|
||||
{
|
||||
struct dma_desc_s *head = &g_base_desc[dmach->dc_chan];
|
||||
|
||||
/* Clear any pending interrupts from any previous DMAC transfer. */
|
||||
#warning Missing logic
|
||||
|
||||
/* Set up the DMA */
|
||||
#warning Missing logic
|
||||
DEBUGASSERT(head->srcaddr != 0);
|
||||
|
||||
/* Enable the channel */
|
||||
#warning Missing logic
|
||||
|
||||
/* Enable DMA interrupts */
|
||||
#warning Missing logic
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_multiple
|
||||
*
|
||||
* Description:
|
||||
* Start a multiple buffer DMA.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_SAMDL_DMAC_NDESC > 0
|
||||
static int sam_multiple(struct sam_dmach_s *dmach)
|
||||
{
|
||||
struct dma_desc_s *head = &g_base_desc[dmach->dc_chan];
|
||||
|
||||
/* Clear any pending interrupts from any previous DMAC transfer. */
|
||||
#warning Missing logic
|
||||
|
||||
/* Set up the initial DMA */
|
||||
#warning Missing logic
|
||||
DEBUGASSERT(head->srcaddr != 0);
|
||||
|
||||
/* Enable the channel */
|
||||
#warning Missing logic
|
||||
|
||||
/* Enable DMA interrupts */
|
||||
#warning Missing logic
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@@ -1014,6 +1089,13 @@ int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg)
|
||||
{
|
||||
struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle;
|
||||
struct dma_desc_s *head;
|
||||
irqstate_t flags;
|
||||
uint8_t ctrla;
|
||||
uint32_t chctrlb;
|
||||
uint32_t tmp;
|
||||
uint8_t qosctrl;
|
||||
uint8_t periphqos;
|
||||
uint8_t memqos;
|
||||
int ret = -EINVAL;
|
||||
|
||||
dmavdbg("dmach: %p callback: %p arg: %p\n", dmach, callback, arg);
|
||||
@@ -1031,20 +1113,78 @@ int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg)
|
||||
dmach->dc_callback = callback;
|
||||
dmach->dc_arg = arg;
|
||||
|
||||
#if CONFIG_SAMDL_DMAC_NDESC > 0
|
||||
/* Is this a single block transfer? Or a multiple block transfer? */
|
||||
/* Clear any pending interrupts from any previous DMAC transfer. */
|
||||
|
||||
if (head == dmach->dc_tail)
|
||||
flags = irqsave();
|
||||
putreg8(dmach->dc_chan, SAM_DMAC_CHID);
|
||||
putreg8(0, SAM_DMAC_CHCTRLA);
|
||||
|
||||
/* Setup the Channel Control B Register
|
||||
*
|
||||
* DMAC_CHCTRLB_EVACT_TRIG - Normal transfer and trigger
|
||||
* DMAC_CHCTRLB_EVIE=0 - No channel input actions
|
||||
* DMAC_CHCTRLB_EVOE=0 - Channel event output disabled
|
||||
* DMAC_CHCTRLB_LVL - Determined by DMACH_FLAG_PRIORITY
|
||||
* DMAC_CHCTRLB_TRIGSRC - Determined by DMACH_FLAG_PERIPHTRIG
|
||||
* DMAC_CHCTRLB_TRIGACT_BEAT - One trigger required for beat transfer
|
||||
* DMAC_CHCTRLB_CMD_NOACTION - No action
|
||||
*/
|
||||
|
||||
chctrlb = DMAC_CHCTRLB_EVACT_TRIG | DMAC_CHCTRLB_TRIGACT_BEAT |
|
||||
DMAC_CHCTRLB_CMD_NOACTION;
|
||||
|
||||
tmp = (dmach->dc_flags & DMACH_FLAG_PRIORITY_MASK) >>
|
||||
DMACH_FLAG_PRIORITY_SHIFT;
|
||||
chctrlb |= tmp << DMAC_CHCTRLB_LVL_SHIFT;
|
||||
|
||||
tmp = (dmach->dc_flags & DMACH_FLAG_PERIPHTRIG_MASK) >>
|
||||
DMACH_FLAG_PERIPHTRIG_SHIFT;
|
||||
chctrlb |= tmp << DMAC_CHCTRLB_TRIGSRC_SHIFT;
|
||||
|
||||
putreg8(chctrlb, SAM_DMAC_CHCTRLB);
|
||||
|
||||
/* Setup the Quality of Service Control Register
|
||||
*
|
||||
* DMAC_QOSCTRL_WRBQOS_DISABLE - Background
|
||||
* DMAC_QOSCTRL_FQOS, DMAC_QOSCTRL_DQOS - Depend on DMACH_FLAG_PERIPHQOS
|
||||
* and DMACH_FLAG_MEMQOS
|
||||
*/
|
||||
|
||||
periphqos = (dmach->dc_flags & DMACH_FLAG_PERIPHQOS_MASK) >>
|
||||
DMACH_FLAG_PERIPHQOS_SHIFT;
|
||||
memqos = (dmach->dc_flags & DMACH_FLAG_MEMQOS_MASK) >>
|
||||
DMACH_FLAG_MEMQOS_SHIFT;
|
||||
|
||||
if (dmach->dc_dir == DMADIR_TX)
|
||||
{
|
||||
ret = sam_single(dmach);
|
||||
/* Memory to periphery */
|
||||
|
||||
qosctrl = (memqos << DMAC_QOSCTRL_FQOS_SHIFT) |
|
||||
(periphqos << DMAC_QOSCTRL_DQOS_SHIFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = sam_multiple(dmach);
|
||||
qosctrl = (periphqos << DMAC_QOSCTRL_FQOS_SHIFT) |
|
||||
(memqos << DMAC_QOSCTRL_DQOS_SHIFT);
|
||||
}
|
||||
#else
|
||||
ret = sam_single(dmach);
|
||||
#endif
|
||||
|
||||
putreg8(qosctrl | DMAC_QOSCTRL_WRBQOS_DISABLE, SAM_DMAC_QOSCTRL);
|
||||
|
||||
/* Enable the channel */
|
||||
|
||||
ctrla = DMAC_CHCTRLA_ENABLE;
|
||||
if (dmach->dc_flags & DMACH_FLAG_RUNINSTDBY)
|
||||
{
|
||||
ctrla |= DMAC_CHCTRLA_RUNSTDBY;
|
||||
}
|
||||
|
||||
putreg8(ctrla, SAM_DMAC_CHCTRLA);
|
||||
|
||||
/* Enable DMA channel interrupts */
|
||||
|
||||
putreg8(DMAC_INT_TERR | DMAC_INT_TCMPL, SAM_DMAC_CHINTENSET);
|
||||
irqrestore(flags);
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -1146,7 +1286,7 @@ void sam_dmadump(DMA_HANDLE handle, const struct sam_dmaregs_s *regs,
|
||||
dmadbg(" PENDCH: %08x ACTIVE: %08x BASEADDR: %08x WRBADDR: %08x\n",
|
||||
regs->pendch, regs->active, regs->baseaddr, regs->wrbaddr);
|
||||
dmadbg(" CHID: %02x CHCRTRLA: %02x CHCRTRLB: %08x CHINFLAG: %02x\n",
|
||||
regs->chid, regs->chctrla, regs->chctrlb, regs->chintflag,
|
||||
regs->chid, regs->chctrla, regs->chctrlb, regs->chintflag,
|
||||
dmadbg(" CHSTATUS: %02x\n",
|
||||
regs->chstatus);
|
||||
}
|
||||
|
||||
@@ -82,7 +82,10 @@
|
||||
# define DMACH_FLAG_BEATSIZE_BYTE (0 << DMACH_FLAG_BEATSIZE_SHIFT) /* 8-bit bus transfer */
|
||||
# define DMACH_FLAG_BEATSIZE_HWORD (1 << DMACH_FLAG_BEATSIZE_SHIFT) /* 16-bit bus transfer */
|
||||
# define DMACH_FLAG_BEATSIZE_WORD (2 << DMACH_FLAG_BEATSIZE_SHIFT) /* 32-bit bus transfer */
|
||||
#define DMACH_FLAG_STEPSIZE_SHIFT (2) /* Bits 2-4: Address increment step */
|
||||
#define DMACH_FLAG_STEPSEL (1 << 2) /* Bit 2: Step selection */
|
||||
# define DMACH_FLAG_STEPSEL_MEM (0) /* 0=Step size applies to memory */
|
||||
# define DMACH_FLAG_STEPSEL_PERIPH (1 << 2) /* 1=Step size applies to peripheral */
|
||||
#define DMACH_FLAG_STEPSIZE_SHIFT (3) /* Bits 3-5: Address increment step */
|
||||
#define DMACH_FLAG_STEPSIZE_MASK (7 << DMACH_FLAG_STEPSIZE_SHIFT)
|
||||
# define DMACH_FLAG_STEPSIZE_X1 (0 << DMACH_FLAG_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 1 */
|
||||
# define DMACH_FLAG_STEPSIZE_X2 (1 << DMACH_FLAG_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 2 */
|
||||
@@ -92,15 +95,18 @@
|
||||
# define DMACH_FLAG_STEPSIZE_X32 (5 << DMACH_FLAG_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 32 */
|
||||
# define DMACH_FLAG_STEPSIZE_X64 (6 << DMACH_FLAG_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 64 */
|
||||
# define DMACH_FLAG_STEPSIZE_X128 (7 << DMACH_FLAG_STEPSIZE_SHIFT) /* Next ADDR = ADDR + (BEATSIZE+1) * 128 */
|
||||
#define DMACH_FLAG_RUNINSTDBY (1 << 5) /* Bit 5: Run in standby */
|
||||
#define DMACH_FLAG_PRIORITY_SHIFT (6) /* Bit 6-7: Arbitration priority */
|
||||
#define DMACH_FLAG_PRIORITY_MASK (3 << DMACH_FLAG_PRIORITY_SHIFT)
|
||||
# define DMACH_FLAG_PRIORITY(n) ((uint32_t)(n) << DMACH_FLAG_PRIORITY_SHIFT)
|
||||
#define DMACH_FLAG_RUNINSTDBY (1 << 8) /* Bit 8: Run in standby */
|
||||
|
||||
/* Peripheral endpoint characteristics */
|
||||
|
||||
#define DMACH_FLAG_PERIPHTRIG_SHIFT (6) /* Bits 6-11: See DMAC_TRIGSRC_* */
|
||||
#define DMACH_FLAG_PERIPHTRIG_SHIFT (9) /* Bits 9-13: See DMAC_TRIGSRC_* */
|
||||
#define DMACH_FLAG_PERIPHTRIG_MASK (0x3f << DMACH_FLAG_PERIPHTRIG_SHIFT)
|
||||
# define DMACH_FLAG_PERIPHTRIG(n) ((uint32_t)(n) << DMACH_FLAG_PERIPHTRIG_SHIFT)
|
||||
#define DMACH_FLAG_PERIPHINCREMENT (1 << 12) /* Bit 12: Autoincrement peripheral address */
|
||||
#define DMACH_FLAG_PERIPHQOS_SHIFT (14) /* Bits 14-15: Peripheral quality of service */
|
||||
#define DMACH_FLAG_PERIPHINCREMENT (1 << 14) /* Bit 14: Autoincrement peripheral address */
|
||||
#define DMACH_FLAG_PERIPHQOS_SHIFT (15) /* Bits 15-16: Peripheral quality of service */
|
||||
#define DMACH_FLAG_PERIPHQOS_MASK (3 << DMACH_FLAG_PERIPHQOS_SHIFT)
|
||||
# define DMACH_FLAG_PERIPHQOS_DISABLE (0 << DMACH_FLAG_PERIPHQOS_SHIFT) /* Background */
|
||||
# define DMACH_FLAG_PERIPHQOS_LOW (1 << DMACH_FLAG_PERIPHQOS_SHIFT) /* Sensitve bandwidth */
|
||||
@@ -109,14 +115,14 @@
|
||||
|
||||
/* Memory endpoint characteristics */
|
||||
|
||||
#define DMACH_FLAG_MEMINCREMENT (1 << 16) /* Bit 16: Autoincrement memory address */
|
||||
#define DMACH_FLAG_MEMQOS_SHIFT (17) /* Bits 17-18: Memory quality of service */
|
||||
#define DMACH_FLAG_MEMINCREMENT (1 << 17) /* Bit 17: Autoincrement memory address */
|
||||
#define DMACH_FLAG_MEMQOS_SHIFT (18) /* Bits 18-19: Memory quality of service */
|
||||
#define DMACH_FLAG_MEMQOS_MASK (3 << DMACH_FLAG_MEMQOS_SHIFT)
|
||||
# define DMACH_FLAG_MEMQOS_DISABLE (0 << DMACH_FLAG_MEMQOS_SHIFT) /* Background */
|
||||
# define DMACH_FLAG_MEMQOS_LOW (1 << DMACH_FLAG_MEMQOS_SHIFT) /* Sensitve bandwidth */
|
||||
# define DMACH_FLAG_MEMQOS_MEDIUM (2 << DMACH_FLAG_MEMQOS_SHIFT) /* Sensitive latency */
|
||||
# define DMACH_FLAG_MEMQOS_HIGH (3 << DMACH_FLAG_MEMQOS_SHIFT) /* Critical latency */
|
||||
/* Bits 19-31: Not used */
|
||||
/* Bits 20-31: Not used */
|
||||
|
||||
/************************************************************************************
|
||||
* Public Types
|
||||
|
||||
Reference in New Issue
Block a user