arch/mips/src/pic32mz/pic32mz-dma.c: Make the DMA interrupt event configurable when setting up a transfer. This allows changing the event without deallocating a channel first. Clear the DMA interrupt flag when the ISR is called. Change some misleading names.

This commit is contained in:
Ouss4 2019-11-23 08:33:06 -06:00 committed by Gregory Nutt
parent afb40d87fb
commit b853a5c750
2 changed files with 45 additions and 41 deletions

View File

@ -66,7 +66,7 @@
/* Convert a virtual address to a physical address */
#define VIRT2PHY(a) ((a) & 0x1FFFFFFF)
#define PHYS_ADDR(va) ((uint32_t)(va) & 0x1fffffff)
/****************************************************************************
* Private Types
@ -137,12 +137,12 @@ static inline void pic32mz_dma_abortirq(FAR struct pic32mz_dmach_s *dmach,
static inline void pic32mz_dma_forceabort(FAR struct pic32mz_dmach_s *dmach);
static inline void pic32mz_dma_intctrl(FAR struct pic32mz_dmach_s *dmach,
uint32_t cfg);
uint8_t cfg);
static inline void pic32mz_dma_intclr(FAR struct pic32mz_dmach_s *dmach);
static int pic32mz_dma_interrupt(int irq, void *context, FAR void *arg);
static void pic32mz_dma_mode(FAR struct pic32mz_dmach_s *dmach,
enum pic32mz_dma_chmode_e mode);
uint8_t mode);
static void pic32mz_dma_config(FAR struct pic32mz_dmach_s *dmach,
FAR const struct pic32mz_dma_chcfg_s *cfg);
@ -370,7 +370,7 @@ static inline void pic32mz_dma_priority(FAR struct pic32mz_dmach_s *dmach,
static inline void pic32mz_dma_srcaddr(FAR struct pic32mz_dmach_s *dmach,
uint32_t addr)
{
pic32mz_dma_putreg(dmach, PIC32MZ_DMACH_SSA_OFFSET, VIRT2PHY(addr));
pic32mz_dma_putreg(dmach, PIC32MZ_DMACH_SSA_OFFSET, PHYS_ADDR(addr));
}
/****************************************************************************
@ -384,7 +384,7 @@ static inline void pic32mz_dma_srcaddr(FAR struct pic32mz_dmach_s *dmach,
static inline void pic32mz_dma_destaddr(FAR struct pic32mz_dmach_s *dmach,
uint32_t addr)
{
pic32mz_dma_putreg(dmach, PIC32MZ_DMACH_DSA_OFFSET, VIRT2PHY(addr));
pic32mz_dma_putreg(dmach, PIC32MZ_DMACH_DSA_OFFSET, PHYS_ADDR(addr));
}
/****************************************************************************
@ -522,7 +522,7 @@ static inline void pic32mz_dma_intclr(FAR struct pic32mz_dmach_s *dmach)
****************************************************************************/
static inline void pic32mz_dma_intctrl(FAR struct pic32mz_dmach_s *dmach,
uint32_t cfg)
uint8_t cfg)
{
/* Clear all interrupts flags */
@ -535,7 +535,8 @@ static inline void pic32mz_dma_intctrl(FAR struct pic32mz_dmach_s *dmach,
/* Enable the interrupts requested. */
pic32mz_dma_putreg(dmach, PIC32MZ_DMACH_INTSET_OFFSET, cfg);
pic32mz_dma_putreg(dmach, PIC32MZ_DMACH_INTSET_OFFSET,
cfg << DMACH_INT_EN_SHIFT);
}
/****************************************************************************
@ -564,6 +565,7 @@ static int pic32mz_dma_interrupt(int irq, void *context, FAR void *arg)
/* Clear the interrupt flags. */
up_clrpend_irq(dmach->irq);
pic32mz_dma_intclr(dmach);
/* Invoke the callback. */
@ -585,7 +587,7 @@ static int pic32mz_dma_interrupt(int irq, void *context, FAR void *arg)
****************************************************************************/
static void pic32mz_dma_mode(FAR struct pic32mz_dmach_s *dmach,
enum pic32mz_dma_chmode_e mode)
uint8_t mode)
{
if (mode & PIC32MZ_DMA_MODE_BASIC)
{
@ -615,21 +617,17 @@ static void pic32mz_dma_config(FAR struct pic32mz_dmach_s *dmach,
/* Set the channel's start and abort IRQs if they are specified */
if (cfg->startirq != PIC32MZ_DMA_NOEVENT)
if (cfg->startirq != PIC32MZ_DMA_NOIRQ)
{
pic32mz_dma_startirq(dmach, cfg->startirq);
}
if (cfg->abortirq != PIC32MZ_DMA_NOEVENT)
if (cfg->abortirq != PIC32MZ_DMA_NOIRQ)
{
pic32mz_dma_abortirq(dmach, cfg->abortirq);
}
/* Set the interrupt event(s) */
pic32mz_dma_intctrl(dmach, cfg->event);
/* Set the cahnnel's mode */
/* Set the channel's mode */
pic32mz_dma_mode(dmach, cfg->mode);
@ -909,10 +907,14 @@ int pic32mz_dma_xfrsetup(DMA_HANDLE handle,
/* Set transfer size (source, destination and cell) */
pic32mz_dma_srcsize(dmach, cfg->srcsize);
pic32mz_dma_srcsize(dmach, cfg->srcsize);
pic32mz_dma_destsize(dmach, cfg->destsize);
pic32mz_dma_cellsize(dmach, cfg->cellsize);
/* Set the interrupt event(s) */
pic32mz_dma_intctrl(dmach, cfg->event);
return OK;
}
@ -939,9 +941,9 @@ int pic32mz_dma_start(DMA_HANDLE handle, dma_callback_t callback, void *arg)
pic32mz_dma_enable(dmach);
/* If no event is set to start the channel, force it */
/* If no irq is set to start the channel, force it */
if (dmach->cfg.startirq == PIC32MZ_DMA_NOEVENT)
if (dmach->cfg.startirq == PIC32MZ_DMA_NOIRQ)
{
pic32mz_dma_forcestart(dmach);
}

View File

@ -60,7 +60,7 @@
*
* If a start irq is set this function will only enable the channel.
* The transfer will be controlled by the start irq.
* If no start irq is specified then the a force start is performed.
* If start irq is set to PIC32MZ_DMA_NOIRQ then a force start is performed.
*
* 4. Stop and free the channel
*
@ -80,31 +80,16 @@
#include <sys/types.h>
#include <stdint.h>
#include "hardware/pic32mz-dma.h"
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
/* Interrupt type arguments for pic32mz_dma_intctrl. */
/* This is used when setting a channel with no start/abort irq */
#define PIC32MZ_DMA_INT_SRCDONE DMACH_INT_CHSDIE
#define PIC32MZ_DMA_INT_SRCHALF DMACH_INT_CHSHIE
#define PIC32MZ_DMA_INT_DESTDONE DMACH_INT_CHDDIE
#define PIC32MZ_DMA_INT_DESTHALF DMACH_INT_CHDHIE
#define PIC32MZ_DMA_INT_BLOCKDONE DMACH_INT_CHBCIE
#define PIC32MZ_DMA_INT_CELLDONE DMACH_INT_CHCCIE
#define PIC32MZ_DMA_INT_ABORT DMACH_INT_CHTAIE
#define PIC32MZ_DMA_INT_ERR DMACH_INT_CHERIE
#define PIC32MZ_DMA_INT_DISABLE (0)
/* This is used when setting a channel with no start/abort event */
#define PIC32MZ_DMA_NOEVENT (NR_IRQS + 1)
#define PIC32MZ_DMA_NOIRQ (NR_IRQS + 1)
/*******************************************************************************
* Public Types
*
******************************************************************************/
#ifndef __ASSEMBLY__
@ -112,6 +97,8 @@
typedef FAR void *DMA_HANDLE;
typedef void (*dma_callback_t)(DMA_HANDLE handle, uint8_t status, void *arg);
/* DMA channel modes, arguments for pic32mz_dma_mode. */
enum pic32mz_dma_chmode_e
{
PIC32MZ_DMA_MODE_BASIC = 1 << 0U, /* Basic transfert mode */
@ -121,15 +108,29 @@ enum pic32mz_dma_chmode_e
PIC32MZ_DMA_MODE_SFM = 1 << 4U /* Special Function Module mode */
};
/* Interrupt type arguments for pic32mz_dma_intctrl. */
enum pic32Mz_dma_event_e
{
PIC32MZ_DMA_INT_DISABLE = 0U,
PIC32MZ_DMA_INT_ADDRERR = 1 << 0U, /* Address error interrupt */
PIC32MZ_DMA_INT_ABORT = 1 << 1U, /* Transfer abort interrupt */
PIC32MZ_DMA_INT_CELLDONE = 1 << 2U, /* Cell transfer complete interrupt */
PIC32MZ_DMA_INT_BLOCKDONE = 1 << 3U, /* Block transfer complete interrupt */
PIC32MZ_DMA_INT_DESTHALF = 1 << 4U, /* Destination half full interrup t*/
PIC32MZ_DMA_INT_DESTDONE = 1 << 5U, /* Destination done interrupt */
PIC32MZ_DMA_INT_SRCHALF = 1 << 6U, /* Source half full interrupt */
PIC32MZ_DMA_INT_SRCDONE = 1 << 7U /* Source done interrupt */
};
/* This structure holds the channel's configuration */
struct pic32mz_dma_chcfg_s
{
uint8_t priority; /* Channel's priority (0..3) */
uint8_t startirq; /* Start event */
uint8_t abortirq; /* Abort event */
uint8_t event; /* Interrupt event */
enum pic32mz_dma_chmode_e mode; /* Channel's mode of operation */
uint8_t priority; /* Channel's priority (0..3) */
uint8_t startirq; /* Start event */
uint8_t abortirq; /* Abort event */
uint8_t mode; /* Channel's modes (enum pic32mz_dma_chmode_e) */
};
/* This structure holds a transfer's configuration */
@ -141,6 +142,7 @@ struct pic32mz_dma_xfrcfg_s
uint16_t srcsize; /* Source size */
uint16_t destsize; /* Destination size */
uint16_t cellsize; /* Cell size */
uint8_t event; /* Interrupt events (enum pic32mz_dma_event_e) */
};
/* The following is used for sampling DMA registers when CONFIG_DEBUG_DMA