SAM3/4 DMA fixes in general for SPI DMA in particular
This commit is contained in:
parent
dba6cca886
commit
e2ab7d8a33
@ -6995,4 +6995,7 @@
|
|||||||
well have (temporarily) broken SPI for the SAM3/4/ family (2014-3-13).
|
well have (temporarily) broken SPI for the SAM3/4/ family (2014-3-13).
|
||||||
* configs/sam4e-ek/src/sam_at25.c and sam_hsmci.c: Added support for
|
* configs/sam4e-ek/src/sam_at25.c and sam_hsmci.c: Added support for
|
||||||
the AT25 serial FLASH. Restructured the logic that registers the
|
the AT25 serial FLASH. Restructured the logic that registers the
|
||||||
HSMCI block driver (2014-3-13).
|
HSMCI block driver (2014-3-13).
|
||||||
|
* arch/arm/src/sam34/sam_dmac.c and sam_spi.c: Fixes to DMA in general
|
||||||
|
and to SPI in particular (2014-3-14).
|
||||||
|
|
@ -340,11 +340,15 @@ config SAM34_EIC
|
|||||||
depends on ARCH_CHIP_SAM4L || ARCH_CHIP_SAM4E
|
depends on ARCH_CHIP_SAM4L || ARCH_CHIP_SAM4E
|
||||||
|
|
||||||
config SAM34_DMAC0
|
config SAM34_DMAC0
|
||||||
bool "DMA controller (DMAC)"
|
bool "DMA controller (DMAC0)"
|
||||||
default n
|
default n
|
||||||
depends on ARCH_CHIP_SAM3U || ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4E
|
depends on ARCH_CHIP_SAM3U || ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4E
|
||||||
select ARCH_DMA
|
select ARCH_DMA
|
||||||
|
|
||||||
|
config SAM34_DMAC1
|
||||||
|
bool
|
||||||
|
default n
|
||||||
|
|
||||||
config SAM34_EMAC
|
config SAM34_EMAC
|
||||||
bool "Ethernet MAC (EMAC)"
|
bool "Ethernet MAC (EMAC)"
|
||||||
default n
|
default n
|
||||||
|
@ -71,10 +71,12 @@
|
|||||||
/* DMA channel registers */
|
/* DMA channel registers */
|
||||||
|
|
||||||
#define SAM_DMACHAN_OFFSET(n) (0x003c+((n)*0x28))
|
#define SAM_DMACHAN_OFFSET(n) (0x003c+((n)*0x28))
|
||||||
#define SAM_DMACHAN0_OFFSET 0x003c /* 0x3c-0x60: Channel 0 */
|
#define SAM_DMACHAN0_OFFSET 0x003c /* 0x003c-0x0060: Channel 0 */
|
||||||
#define SAM_DMACHAN1_OFFSET 0x0064 /* 0x64-0x88: Channel 1 */
|
#define SAM_DMACHAN1_OFFSET 0x0064 /* 0x0064-0x0088: Channel 1 */
|
||||||
#define SAM_DMACHAN2_OFFSET 0x008c /* 0x8c-0xb0: Channel 2 */
|
#define SAM_DMACHAN2_OFFSET 0x008c /* 0x008c-0x00b0: Channel 2 */
|
||||||
#define SAM_DMACHAN3_OFFSET 0x00b4 /* 0xb4-0xd8: Channel 3 */
|
#define SAM_DMACHAN3_OFFSET 0x00b4 /* 0x00b4-0x00d8: Channel 3 */
|
||||||
|
#define SAM_DMACHAN4_OFFSET 0x00dc /* 0x00dc-0x0103: Channel 4 */
|
||||||
|
#define SAM_DMACHAN5_OFFSET 0x0104 /* 0x0104-0x0128: Channel 5 */
|
||||||
|
|
||||||
#define SAM_DMACHAN_SADDR_OFFSET 0x0000 /* DMAC Channel Source Address Register */
|
#define SAM_DMACHAN_SADDR_OFFSET 0x0000 /* DMAC Channel Source Address Register */
|
||||||
#define SAM_DMACHAN_DADDR_OFFSET 0x0004 /* DMAC Channel Destination Address Register */
|
#define SAM_DMACHAN_DADDR_OFFSET 0x0004 /* DMAC Channel Destination Address Register */
|
||||||
@ -115,6 +117,8 @@
|
|||||||
#define SAM_DMACHAN1_BASE (SAM_DMAC_BASE+SAM_DMACHAN1_OFFSET)
|
#define SAM_DMACHAN1_BASE (SAM_DMAC_BASE+SAM_DMACHAN1_OFFSET)
|
||||||
#define SAM_DMACHAN2_BASE (SAM_DMAC_BASE+SAM_DMACHAN2_OFFSET)
|
#define SAM_DMACHAN2_BASE (SAM_DMAC_BASE+SAM_DMACHAN2_OFFSET)
|
||||||
#define SAM_DMACHAN3_BASE (SAM_DMAC_BASE+SAM_DMACHAN3_OFFSET)
|
#define SAM_DMACHAN3_BASE (SAM_DMAC_BASE+SAM_DMACHAN3_OFFSET)
|
||||||
|
#define SAM_DMACHAN4_BASE (SAM_DMAC_BASE+SAM_DMACHAN4_OFFSET)
|
||||||
|
#define SAM_DMACHAN5_BASE (SAM_DMAC_BASE+SAM_DMACHAN5_OFFSET)
|
||||||
|
|
||||||
#define SAM_DMACHAN_SADDR(n) (SAM_DMACHAN_BASE(n)+SAM_DMACHAN_SADDR_OFFSET)
|
#define SAM_DMACHAN_SADDR(n) (SAM_DMACHAN_BASE(n)+SAM_DMACHAN_SADDR_OFFSET)
|
||||||
#define SAM_DMACHAN_DADDR(n) (SAM_DMACHAN_BASE(n)+SAM_DMACHAN_DADDR_OFFSET)
|
#define SAM_DMACHAN_DADDR(n) (SAM_DMACHAN_BASE(n)+SAM_DMACHAN_DADDR_OFFSET)
|
||||||
@ -361,10 +365,19 @@
|
|||||||
/* DMAC Channel n [n = 0..3] Descriptor Address Register -- 32-bit address*/
|
/* DMAC Channel n [n = 0..3] Descriptor Address Register -- 32-bit address*/
|
||||||
/* DMAC Channel n [n = 0..3] Control A Register */
|
/* DMAC Channel n [n = 0..3] Control A Register */
|
||||||
|
|
||||||
#define DMACHAN_CTRLA_BTSIZE_MAX (0xfff)
|
#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \
|
||||||
#define DMACHAN_CTRLA_BTSIZE_SHIFT (0) /* Bits 0-11: Buffer Transfer Size */
|
defined(CONFIG_ARCH_CHIP_SAM3A)
|
||||||
#define DMACHAN_CTRLA_BTSIZE_MASK (DMACHAN_CTRLA_BTSIZE_MAX << DMACHAN_CTRLA_BTSIZE_SHIFT)
|
# define DMACHAN_CTRLA_BTSIZE_MAX (0xfff)
|
||||||
# define DMACHAN_CTRLA_BTSIZE(n) ((uint32_t)(n) << DMACHAN_CTRLA_BTSIZE_SHIFT)
|
# define DMACHAN_CTRLA_BTSIZE_SHIFT (0) /* Bits 0-11: Buffer Transfer Size */
|
||||||
|
# define DMACHAN_CTRLA_BTSIZE_MASK (DMACHAN_CTRLA_BTSIZE_MAX << DMACHAN_CTRLA_BTSIZE_SHIFT)
|
||||||
|
# define DMACHAN_CTRLA_BTSIZE(n) ((uint32_t)(n) << DMACHAN_CTRLA_BTSIZE_SHIFT)
|
||||||
|
#elif defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A) || \
|
||||||
|
defined(CONFIG_ARCH_CHIP_SAM4E)
|
||||||
|
# define DMACHAN_CTRLA_BTSIZE_MAX (0xffff)
|
||||||
|
# define DMACHAN_CTRLA_BTSIZE_SHIFT (0) /* Bits 0-15: Buffer Transfer Size */
|
||||||
|
# define DMACHAN_CTRLA_BTSIZE_MASK (DMACHAN_CTRLA_BTSIZE_MAX << DMACHAN_CTRLA_BTSIZE_SHIFT)
|
||||||
|
# define DMACHAN_CTRLA_BTSIZE(n) ((uint32_t)(n) << DMACHAN_CTRLA_BTSIZE_SHIFT)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \
|
#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \
|
||||||
defined(CONFIG_ARCH_CHIP_SAM3A)
|
defined(CONFIG_ARCH_CHIP_SAM3A)
|
||||||
@ -458,15 +471,35 @@
|
|||||||
|
|
||||||
/* DMA Hardware interface numbers *******************************************************/
|
/* DMA Hardware interface numbers *******************************************************/
|
||||||
|
|
||||||
#if defined(CONFIG_ARCH_CHIP_SAM3U) || defined(CONFIG_ARCH_CHIP_SAM3X) || \
|
#if defined(CONFIG_ARCH_CHIP_SAM3U)
|
||||||
defined(CONFIG_ARCH_CHIP_SAM3A)
|
|
||||||
# define DMACHAN_INTF_MCI0 0
|
|
||||||
# define DMACHAN_INTF_SSC 3
|
|
||||||
# define DMACHAN_INTF_MCI1 13
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_ARCH_CHIP_SAM4E)
|
# define DMACHAN_INTF_HSMCI0 0
|
||||||
# define DMACHAN_INTF_HSMCI 0 /* HSMCI Transmit/Receive */
|
# define DMACHAN_INTF_SPI0TX 1 /* SPI0 Transmit */
|
||||||
|
# define DMACHAN_INTF_SPI0RX 2 /* SPI0 Receive */
|
||||||
|
# define DMACHAN_INTF_SSC0TX 3 /* SSC0 Transmit */
|
||||||
|
# define DMACHAN_INTF_SSC0RX 4 /* SSC0 Receive */
|
||||||
|
# define DMACHAN_INTF_PWM0EV0 5 /* PWM0 Event Line 0 */
|
||||||
|
# define DMACHAN_INTF_PWM0EV1 6 /* PWM0 Event Line 1 */
|
||||||
|
# define DMACHAN_INTF_TIO0 7 /* TIO Output of TC Ch. 0 */
|
||||||
|
|
||||||
|
#elif defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A)
|
||||||
|
|
||||||
|
# define DMACHAN_INTF_HSMCI0 0 /* HSMCI0 Transmit/Receive */
|
||||||
|
# define DMACHAN_INTF_SPI0TX 1 /* SPI0 Transmit */
|
||||||
|
# define DMACHAN_INTF_SPI0RX 2 /* SPI0 Receive */
|
||||||
|
# define DMACHAN_INTF_SSC0TX 3 /* SSC0 Transmit */
|
||||||
|
# define DMACHAN_INTF_SSC0RX 4 /* SSC0 Receive */
|
||||||
|
# define DMACHAN_INTF_SPI0TX 5 /* SPI1 Transmit */
|
||||||
|
# define DMACHAN_INTF_SPI0RX 6 /* SPI1 Receive */
|
||||||
|
# define DMACHAN_INTF_USART0TX 11 /* USART0 Transmit */
|
||||||
|
# define DMACHAN_INTF_USART0RX 12 /* USART0 Receive */
|
||||||
|
# define DMACHAN_INTF_USART1TX 13 /* USART1 Transmit */
|
||||||
|
# define DMACHAN_INTF_USART1RX 14 /* USART1 Receive */
|
||||||
|
# define DMACHAN_INTF_PWM0TX 15 /* PWM0 Transmit */
|
||||||
|
|
||||||
|
#elif defined(CONFIG_ARCH_CHIP_SAM4E)
|
||||||
|
|
||||||
|
# define DMACHAN_INTF_HSMCI0 0 /* HSMCI Transmit/Receive */
|
||||||
# define DMACHAN_INTF_SPI0TX 1 /* SPI Transmit */
|
# define DMACHAN_INTF_SPI0TX 1 /* SPI Transmit */
|
||||||
# define DMACHAN_INTF_SPI0RX 2 /* SPI Receive */
|
# define DMACHAN_INTF_SPI0RX 2 /* SPI Receive */
|
||||||
# define DMACHAN_INTF_USART0TX 3 /* USART0 Transmit */
|
# define DMACHAN_INTF_USART0TX 3 /* USART0 Transmit */
|
||||||
@ -475,7 +508,8 @@
|
|||||||
# define DMACHAN_INTF_USART1RX 6 /* USART1 Receive */
|
# define DMACHAN_INTF_USART1RX 6 /* USART1 Receive */
|
||||||
# define DMACHAN_INTF_AESTX 11 /* AES Transmit */
|
# define DMACHAN_INTF_AESTX 11 /* AES Transmit */
|
||||||
# define DMACHAN_INTF_AESRX 12 /* AES Receive */
|
# define DMACHAN_INTF_AESRX 12 /* AES Receive */
|
||||||
# define DMACHAN_INTF_PWMTX 13 /* PWM Transmit */
|
# define DMACHAN_INTF_PWM0TX 13 /* PWM0 Transmit */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
|
@ -98,7 +98,7 @@
|
|||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* This structure descibes one DMA channel */
|
/* This structure describes one DMA channel */
|
||||||
|
|
||||||
struct sam_dma_s
|
struct sam_dma_s
|
||||||
{
|
{
|
||||||
@ -153,8 +153,8 @@ static struct dma_linklist_s g_linklist[CONFIG_SAM34_NLLDESC];
|
|||||||
|
|
||||||
static struct sam_dma_s g_dma[SAM34_NDMACHAN] =
|
static struct sam_dma_s g_dma[SAM34_NDMACHAN] =
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_ARCH_CHIP_ATSAM3U4E)
|
#if defined(CONFIG_ARCH_CHIP_SAM3U)
|
||||||
/* the AT91SAM3U4E has four DMA channels. The FIFOs for channels 0-2 are
|
/* The SAM3U has four DMA channels. The FIFOs for channels 0-2 are
|
||||||
* 8 bytes in size; channel 3 is 32 bytes.
|
* 8 bytes in size; channel 3 is 32 bytes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -179,10 +179,50 @@ static struct sam_dma_s g_dma[SAM34_NDMACHAN] =
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
.chan = 3,
|
.chan = 3,
|
||||||
.flags = (DMACH_FLAG_FIFO_32BYTES | DMACH_FLAG_FLOWCONTROL),
|
.flags = DMACH_FLAG_FIFO_32BYTES,
|
||||||
.base = SAM_DMACHAN3_BASE,
|
.base = SAM_DMACHAN3_BASE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A)
|
||||||
|
/* The SAM3A/X have six DMA channels. The FIFOs for channels 0-2 are
|
||||||
|
* 8 bytes in size; channel 3 is 32 bytes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if SAM34_NDMACHAN != 6
|
||||||
|
# error "Logic here assumes SAM34_NDMACHAN is 6"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{
|
||||||
|
.chan = 0,
|
||||||
|
.flags = DMACH_FLAG_FIFO_8BYTES,
|
||||||
|
.base = SAM_DMACHAN0_BASE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.chan = 1,
|
||||||
|
.flags = DMACH_FLAG_FIFO_8BYTES,
|
||||||
|
.base = SAM_DMACHAN1_BASE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.chan = 2,
|
||||||
|
.flags = DMACH_FLAG_FIFO_8BYTES,
|
||||||
|
.base = SAM_DMACHAN2_BASE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.chan = 3,
|
||||||
|
.flags = DMACH_FLAG_FIFO_32BYTES,
|
||||||
|
.base = SAM_DMACHAN3_BASE,
|
||||||
|
}
|
||||||
|
{
|
||||||
|
.chan = 4,
|
||||||
|
.flags = DMACH_FLAG_FIFO_8BYTES,
|
||||||
|
.base = SAM_DMACHAN4_BASE,
|
||||||
|
}
|
||||||
|
{
|
||||||
|
.chan = 5,
|
||||||
|
.flags = DMACH_FLAG_FIFO_32BYTES,
|
||||||
|
.base = SAM_DMACHAN5_BASE,
|
||||||
|
}
|
||||||
|
|
||||||
#elif defined(CONFIG_ARCH_CHIP_SAM4E)
|
#elif defined(CONFIG_ARCH_CHIP_SAM4E)
|
||||||
/* The SAM4E16E, SAM4E8E, SAM4E16C, and SAM4E8C have four DMA channels.
|
/* The SAM4E16E, SAM4E8E, SAM4E16C, and SAM4E8C have four DMA channels.
|
||||||
*
|
*
|
||||||
@ -212,7 +252,7 @@ static struct sam_dma_s g_dma[SAM34_NDMACHAN] =
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
.chan = 3,
|
.chan = 3,
|
||||||
.flags = (DMACH_FLAG_FIFO_32BYTES | DMACH_FLAG_FLOWCONTROL),
|
.flags = DMACH_FLAG_FIFO_32BYTES,
|
||||||
.base = SAM_DMACHAN3_BASE,
|
.base = SAM_DMACHAN3_BASE,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,19 +340,6 @@ static unsigned int sam_fifosize(uint8_t chflags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: sam_flowcontrol
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Decode the FIFO flow control from the flags
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static inline bool sam_flowcontrol(uint8_t chflags)
|
|
||||||
{
|
|
||||||
return ((chflags & DMACH_FLAG_FLOWCONTROL) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: sam_fifocfg
|
* Name: sam_fifocfg
|
||||||
*
|
*
|
||||||
@ -834,6 +861,7 @@ static inline uint32_t sam_rxctrlb(struct sam_dma_s *dmach)
|
|||||||
{
|
{
|
||||||
regval |= DMACHAN_CTRLB_DSTINCR_FIXED;
|
regval |= DMACHAN_CTRLB_DSTINCR_FIXED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return regval;
|
return regval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1375,12 +1403,12 @@ void weak_function up_dmainitialize(void)
|
|||||||
DMA_HANDLE sam_dmachannel(uint32_t chflags)
|
DMA_HANDLE sam_dmachannel(uint32_t chflags)
|
||||||
{
|
{
|
||||||
struct sam_dma_s *dmach;
|
struct sam_dma_s *dmach;
|
||||||
|
unsigned int fifosize;
|
||||||
unsigned int chndx;
|
unsigned int chndx;
|
||||||
|
|
||||||
/* Get the search parameters */
|
/* Get the search parameters */
|
||||||
|
|
||||||
bool flowcontrol = sam_flowcontrol(chflags);
|
fifosize = sam_fifosize(chflags);
|
||||||
unsigned int fifosize = sam_fifosize(chflags);
|
|
||||||
|
|
||||||
/* Search for an available DMA channel with at least the requested FIFO
|
/* Search for an available DMA channel with at least the requested FIFO
|
||||||
* size.
|
* size.
|
||||||
@ -1393,8 +1421,7 @@ DMA_HANDLE sam_dmachannel(uint32_t chflags)
|
|||||||
{
|
{
|
||||||
struct sam_dma_s *candidate = &g_dma[chndx];
|
struct sam_dma_s *candidate = &g_dma[chndx];
|
||||||
if (!candidate->inuse &&
|
if (!candidate->inuse &&
|
||||||
(sam_fifosize(candidate->flags) >= fifosize) &&
|
(sam_fifosize(candidate->flags) >= fifosize))
|
||||||
(!flowcontrol || sam_flowcontrol(chflags)))
|
|
||||||
{
|
{
|
||||||
dmach = candidate;
|
dmach = candidate;
|
||||||
dmach->inuse = true;
|
dmach->inuse = true;
|
||||||
@ -1411,13 +1438,13 @@ DMA_HANDLE sam_dmachannel(uint32_t chflags)
|
|||||||
|
|
||||||
putreg32(DMAC_CHDR_DIS(chndx), SAM_DMAC_CHDR);
|
putreg32(DMAC_CHDR_DIS(chndx), SAM_DMAC_CHDR);
|
||||||
|
|
||||||
/* Set the DMA channel flags, retaining the fifo size and flow
|
/* Set the DMA channel flags, retaining the fifo size setting
|
||||||
* control settings which are inherent properties of the FIFO
|
* which is an inherent properties of the FIFO and cannot be
|
||||||
* and cannot be changed.
|
* changed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dmach->flags &= (DMACH_FLAG_FLOWCONTROL | DMACH_FLAG_FIFOSIZE_MASK);
|
dmach->flags &= DMACH_FLAG_FIFOSIZE_MASK;
|
||||||
dmach->flags |= (chflags & ~((DMACH_FLAG_FLOWCONTROL | DMACH_FLAG_FIFOSIZE_MASK)));
|
dmach->flags |= (chflags & ~DMACH_FLAG_FIFOSIZE_MASK);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1478,7 +1505,7 @@ void sam_dmafree(DMA_HANDLE handle)
|
|||||||
* operation and so should be safe.
|
* operation and so should be safe.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dmach->flags &= (DMACH_FLAG_FLOWCONTROL | DMACH_FLAG_FIFOSIZE_MASK);
|
dmach->flags &= DMACH_FLAG_FIFOSIZE_MASK;
|
||||||
dmach->inuse = false; /* No longer in use */
|
dmach->inuse = false; /* No longer in use */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1496,6 +1523,7 @@ void sam_dmafree(DMA_HANDLE handle)
|
|||||||
int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nbytes)
|
int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nbytes)
|
||||||
{
|
{
|
||||||
struct sam_dma_s *dmach = (struct sam_dma_s *)handle;
|
struct sam_dma_s *dmach = (struct sam_dma_s *)handle;
|
||||||
|
ssize_t remaining = (ssize_t)nbytes;
|
||||||
size_t maxtransfer;
|
size_t maxtransfer;
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
|
|
||||||
@ -1512,7 +1540,7 @@ int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nby
|
|||||||
|
|
||||||
/* If this is a large transfer, break it up into smaller buffers */
|
/* If this is a large transfer, break it up into smaller buffers */
|
||||||
|
|
||||||
while (nbytes > maxtransfer)
|
while (remaining > maxtransfer)
|
||||||
{
|
{
|
||||||
/* Set up the maximum size transfer */
|
/* Set up the maximum size transfer */
|
||||||
|
|
||||||
@ -1521,7 +1549,7 @@ int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nby
|
|||||||
{
|
{
|
||||||
/* Decrement the number of bytes left to transfer */
|
/* Decrement the number of bytes left to transfer */
|
||||||
|
|
||||||
nbytes -= maxtransfer;
|
remaining -= maxtransfer;
|
||||||
|
|
||||||
/* Increment the memory & peripheral address (if it is appropriate to
|
/* Increment the memory & peripheral address (if it is appropriate to
|
||||||
* do do).
|
* do do).
|
||||||
@ -1541,9 +1569,9 @@ int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nby
|
|||||||
|
|
||||||
/* Then set up the final buffer transfer */
|
/* Then set up the final buffer transfer */
|
||||||
|
|
||||||
if (ret == OK && nbytes > 0)
|
if (ret == OK && remaining > 0)
|
||||||
{
|
{
|
||||||
ret = sam_txbuffer(dmach, paddr, maddr, nbytes);
|
ret = sam_txbuffer(dmach, paddr, maddr, remaining);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -1563,6 +1591,7 @@ int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nby
|
|||||||
int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nbytes)
|
int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nbytes)
|
||||||
{
|
{
|
||||||
struct sam_dma_s *dmach = (struct sam_dma_s *)handle;
|
struct sam_dma_s *dmach = (struct sam_dma_s *)handle;
|
||||||
|
ssize_t remaining = (ssize_t)nbytes;
|
||||||
size_t maxtransfer;
|
size_t maxtransfer;
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
|
|
||||||
@ -1579,7 +1608,7 @@ int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nby
|
|||||||
|
|
||||||
/* If this is a large transfer, break it up into smaller buffers */
|
/* If this is a large transfer, break it up into smaller buffers */
|
||||||
|
|
||||||
while (nbytes > maxtransfer)
|
while (remaining > maxtransfer)
|
||||||
{
|
{
|
||||||
/* Set up the maximum size transfer */
|
/* Set up the maximum size transfer */
|
||||||
|
|
||||||
@ -1588,7 +1617,7 @@ int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nby
|
|||||||
{
|
{
|
||||||
/* Decrement the number of bytes left to transfer */
|
/* Decrement the number of bytes left to transfer */
|
||||||
|
|
||||||
nbytes -= maxtransfer;
|
remaining -= maxtransfer;
|
||||||
|
|
||||||
/* Increment the memory & peripheral address (if it is appropriate to
|
/* Increment the memory & peripheral address (if it is appropriate to
|
||||||
* do do).
|
* do do).
|
||||||
@ -1608,9 +1637,9 @@ int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nby
|
|||||||
|
|
||||||
/* Then set up the final buffer transfer */
|
/* Then set up the final buffer transfer */
|
||||||
|
|
||||||
if (ret == OK && nbytes > 0)
|
if (ret == OK && remaining > 0)
|
||||||
{
|
{
|
||||||
ret = sam_rxbuffer(dmach, paddr, maddr, nbytes);
|
ret = sam_rxbuffer(dmach, paddr, maddr, remaining);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -1638,12 +1667,12 @@ int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg)
|
|||||||
|
|
||||||
if (dmach->llhead)
|
if (dmach->llhead)
|
||||||
{
|
{
|
||||||
/* Save the callback info. This will be invoked whent the DMA commpletes */
|
/* Save the callback info. This will be invoked when the DMA completes */
|
||||||
|
|
||||||
dmach->callback = callback;
|
dmach->callback = callback;
|
||||||
dmach->arg = arg;
|
dmach->arg = arg;
|
||||||
|
|
||||||
/* Is this a single block transfer? Or a multiple block tranfer? */
|
/* Is this a single block transfer? Or a multiple block transfer? */
|
||||||
|
|
||||||
if (dmach->llhead == dmach->lltail)
|
if (dmach->llhead == dmach->lltail)
|
||||||
{
|
{
|
||||||
@ -1654,6 +1683,7 @@ int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg)
|
|||||||
ret = sam_multiple(dmach);
|
ret = sam_multiple(dmach);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@
|
|||||||
|
|
||||||
/* Unchange-able properties of the channel */
|
/* Unchange-able properties of the channel */
|
||||||
|
|
||||||
#define DMACH_FLAG_FLOWCONTROL (1 << 0) /* Bit 0: Channel supports flow control */
|
/* Bit 0: Not used */
|
||||||
#define DMACH_FLAG_FIFOSIZE_SHIFT (1) /* Bit 1: Size of DMA FIFO */
|
#define DMACH_FLAG_FIFOSIZE_SHIFT (1) /* Bit 1: Size of DMA FIFO */
|
||||||
#define DMACH_FLAG_FIFOSIZE_MASK (1 << DMACH_FLAG_FIFOSIZE_SHIFT)
|
#define DMACH_FLAG_FIFOSIZE_MASK (1 << DMACH_FLAG_FIFOSIZE_SHIFT)
|
||||||
# define DMACH_FLAG_FIFO_8BYTES (0 << DMACH_FLAG_FIFOSIZE_SHIFT) /* 8 bytes */
|
# define DMACH_FLAG_FIFO_8BYTES (0 << DMACH_FLAG_FIFOSIZE_SHIFT) /* 8 bytes */
|
||||||
@ -102,7 +102,7 @@
|
|||||||
/* Memory endpoint characteristics */
|
/* Memory endpoint characteristics */
|
||||||
|
|
||||||
#define DMACH_FLAG_MEMPID_SHIFT (14) /* Bits 14-17: Memory PID */
|
#define DMACH_FLAG_MEMPID_SHIFT (14) /* Bits 14-17: Memory PID */
|
||||||
#define DMACH_FLAG_MEMPID_MASK (15 << DMACH_FLAG_PERIPHPID_SHIFT)
|
#define DMACH_FLAG_MEMPID_MASK (15 << DMACH_FLAG_MEMPID_SHIFT)
|
||||||
#define DMACH_FLAG_MEMH2SEL (1 << 18) /* Bits 18: HW handshaking */
|
#define DMACH_FLAG_MEMH2SEL (1 << 18) /* Bits 18: HW handshaking */
|
||||||
#define DMACH_FLAG_MEMISPERIPH (1 << 19) /* Bits 19: 0=memory; 1=peripheral */
|
#define DMACH_FLAG_MEMISPERIPH (1 << 19) /* Bits 19: 0=memory; 1=peripheral */
|
||||||
#define DMACH_FLAG_MEMWIDTH_SHIFT (20) /* Bits 20-21: Memory width */
|
#define DMACH_FLAG_MEMWIDTH_SHIFT (20) /* Bits 20-21: Memory width */
|
||||||
@ -111,9 +111,10 @@
|
|||||||
# define DMACH_FLAG_MEMWIDTH_16BITS (1 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 16 bits */
|
# define DMACH_FLAG_MEMWIDTH_16BITS (1 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 16 bits */
|
||||||
# define DMACH_FLAG_MEMWIDTH_32BITS (2 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 32 bits */
|
# define DMACH_FLAG_MEMWIDTH_32BITS (2 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 32 bits */
|
||||||
#define DMACH_FLAG_MEMINCREMENT (1 << 22) /* Bit 22: Autoincrement memory address */
|
#define DMACH_FLAG_MEMINCREMENT (1 << 22) /* Bit 22: Autoincrement memory address */
|
||||||
#define DMACH_FLAG_MEMCHUNKSIZE (1 << 22) /* Bit 23: Memory chunk size */
|
#define DMACH_FLAG_MEMCHUNKSIZE (1 << 23) /* Bit 23: Memory chunk size */
|
||||||
# define DMACH_FLAG_MEMCHUNKSIZE_1 (0) /* Memory chunksize = 1 */
|
# define DMACH_FLAG_MEMCHUNKSIZE_1 (0) /* Memory chunksize = 1 */
|
||||||
# define DMACH_FLAG_MEMCHUNKSIZE_4 DMACH_FLAG_MEMCHUNKSIZE /* Memory chunksize = 4 */
|
# define DMACH_FLAG_MEMCHUNKSIZE_4 DMACH_FLAG_MEMCHUNKSIZE /* Memory chunksize = 4 */
|
||||||
|
/* Bits 24-31: Not used */
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Public Types
|
* Public Types
|
||||||
|
@ -125,7 +125,7 @@
|
|||||||
|
|
||||||
#define DMA_FLAGS \
|
#define DMA_FLAGS \
|
||||||
(DMACH_FLAG_FIFO_8BYTES | DMACH_FLAG_FIFOCFG_LARGEST | \
|
(DMACH_FLAG_FIFO_8BYTES | DMACH_FLAG_FIFOCFG_LARGEST | \
|
||||||
(DMACHAN_INTF_MCI0 << DMACH_FLAG_PERIPHPID_SHIFT) | \
|
(DMACHAN_INTF_HSMCI0 << DMACH_FLAG_PERIPHPID_SHIFT) | \
|
||||||
DMACH_FLAG_PERIPHH2SEL | DMACH_FLAG_PERIPHISPERIPH | \
|
DMACH_FLAG_PERIPHH2SEL | DMACH_FLAG_PERIPHISPERIPH | \
|
||||||
DMACH_FLAG_PERIPHWIDTH_32BITS | DMACH_FLAG_PERIPHCHUNKSIZE_1 | \
|
DMACH_FLAG_PERIPHWIDTH_32BITS | DMACH_FLAG_PERIPHCHUNKSIZE_1 | \
|
||||||
DMACH_FLAG_MEMWIDTH_32BITS | DMACH_FLAG_MEMINCREMENT | DMACH_FLAG_MEMCHUNKSIZE_4)
|
DMACH_FLAG_MEMWIDTH_32BITS | DMACH_FLAG_MEMINCREMENT | DMACH_FLAG_MEMCHUNKSIZE_4)
|
||||||
|
@ -719,10 +719,10 @@ static void spi_dma_sampledone(struct sam_spics_s *spics)
|
|||||||
"RX: At DMA callback");
|
"RX: At DMA callback");
|
||||||
}
|
}
|
||||||
|
|
||||||
sam_dmadump(spics->rxdma, &spics->rxdmaregs[DMA_END_TRANSFER],
|
|
||||||
"RX: At End-of-Transfer");
|
|
||||||
sam_dmadump(spics->txdma, &spics->txdmaregs[DMA_END_TRANSFER],
|
sam_dmadump(spics->txdma, &spics->txdmaregs[DMA_END_TRANSFER],
|
||||||
"TX: At End-of-Transfer");
|
"TX: At End-of-Transfer");
|
||||||
|
sam_dmadump(spics->rxdma, &spics->rxdmaregs[DMA_END_TRANSFER],
|
||||||
|
"RX: At End-of-Transfer");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1449,7 +1449,7 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
|||||||
((uint32_t)spi->rxintf << DMACH_FLAG_PERIPHPID_SHIFT) |
|
((uint32_t)spi->rxintf << DMACH_FLAG_PERIPHPID_SHIFT) |
|
||||||
DMACH_FLAG_PERIPHH2SEL | DMACH_FLAG_PERIPHISPERIPH |
|
DMACH_FLAG_PERIPHH2SEL | DMACH_FLAG_PERIPHISPERIPH |
|
||||||
DMACH_FLAG_PERIPHWIDTH_8BITS | DMACH_FLAG_PERIPHCHUNKSIZE_1 |
|
DMACH_FLAG_PERIPHWIDTH_8BITS | DMACH_FLAG_PERIPHCHUNKSIZE_1 |
|
||||||
((uint32_t)(0x3f) << DMACH_FLAG_MEMPID_SHIFT) |
|
((uint32_t)(15) << DMACH_FLAG_MEMPID_SHIFT) |
|
||||||
DMACH_FLAG_MEMWIDTH_8BITS | DMACH_FLAG_MEMCHUNKSIZE_1;
|
DMACH_FLAG_MEMWIDTH_8BITS | DMACH_FLAG_MEMCHUNKSIZE_1;
|
||||||
|
|
||||||
if (!rxbuffer)
|
if (!rxbuffer)
|
||||||
@ -1471,7 +1471,7 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
|||||||
((uint32_t)spi->txintf << DMACH_FLAG_PERIPHPID_SHIFT) |
|
((uint32_t)spi->txintf << DMACH_FLAG_PERIPHPID_SHIFT) |
|
||||||
DMACH_FLAG_PERIPHH2SEL | DMACH_FLAG_PERIPHISPERIPH |
|
DMACH_FLAG_PERIPHH2SEL | DMACH_FLAG_PERIPHISPERIPH |
|
||||||
DMACH_FLAG_PERIPHWIDTH_8BITS | DMACH_FLAG_PERIPHCHUNKSIZE_1 |
|
DMACH_FLAG_PERIPHWIDTH_8BITS | DMACH_FLAG_PERIPHCHUNKSIZE_1 |
|
||||||
((uint32_t)(0x3f) << DMACH_FLAG_MEMPID_SHIFT) |
|
((uint32_t)(15) << DMACH_FLAG_MEMPID_SHIFT) |
|
||||||
DMACH_FLAG_MEMWIDTH_8BITS | DMACH_FLAG_MEMCHUNKSIZE_1;
|
DMACH_FLAG_MEMWIDTH_8BITS | DMACH_FLAG_MEMCHUNKSIZE_1;
|
||||||
|
|
||||||
if (!txbuffer)
|
if (!txbuffer)
|
||||||
|
Loading…
Reference in New Issue
Block a user