mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 16:50:55 +08:00
EFM32: Integrate SPI DMA capability
This commit is contained in:
@@ -340,4 +340,38 @@ config LEUART1_2STOP
|
||||
|
||||
endmenu # LEUART1 Configuration
|
||||
|
||||
if EFM32_USART_ISSPI
|
||||
menu "SPI Configuration"
|
||||
|
||||
config EFM32_SPI_DMA
|
||||
bool "SPI DMA support"
|
||||
default n
|
||||
depends on EFM32_DMA
|
||||
---help---
|
||||
Select to enable DMA SPI transfers
|
||||
|
||||
if EFM32_SPI_DMA
|
||||
|
||||
config EFM32_SPI_DMA_TIMEO_NSEC
|
||||
int "Per word timer (nsec)"
|
||||
default 500
|
||||
---help---
|
||||
A timeout will be be used to detect hung DMA transfers. The timeout
|
||||
will vary as a function of the number of words transferred. This
|
||||
value provides the per-word timeout value in nanoseconds.
|
||||
|
||||
config EFM32_SPI_DMA_MINSIZE
|
||||
int "Minimum DMA size"
|
||||
default 16
|
||||
---help---
|
||||
DMA is particularly helpful for the case of large SPI transfers.
|
||||
Smaller SPI transfer may be more efficiently performed without DMA.
|
||||
This option determines a threshold: For transfers of this size and
|
||||
below, DMA will not be used. A value of zero will force all DMA-
|
||||
based transfers.
|
||||
|
||||
endif # EFM32_SPI_DMA
|
||||
endmenu # SPI Configuration
|
||||
endif # EFM32_USART_ISSPI
|
||||
|
||||
endif # ARCH_CHIP_EFM32
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/********************************************************************************************************************************
|
||||
* arch/arm/src/efm32/EFM32GG/efm32_usart.h
|
||||
*
|
||||
*
|
||||
* (C) Copyright 2014 Silicon Labs, http://www.silabs.com
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
|
||||
@@ -457,6 +457,7 @@ void efm32_rxdmasetup(DMA_HANDLE handle, uintptr_t paddr, uintptr_t maddr,
|
||||
unsigned int xfersize;
|
||||
unsigned int shift;
|
||||
uint32_t regval;
|
||||
uint32_t incr;
|
||||
uint32_t mask;
|
||||
|
||||
DEBUGASSERT(dmach != NULL && dmach->inuse);
|
||||
@@ -500,18 +501,28 @@ void efm32_rxdmasetup(DMA_HANDLE handle, uintptr_t paddr, uintptr_t maddr,
|
||||
{
|
||||
default:
|
||||
case 0: /* Byte transfer */
|
||||
regval = DMA_CTRL_DST_INC_BYTE | DMA_CTRL_DST_SIZE_BYTE | DMA_CTRL_SRC_SIZE_BYTE;
|
||||
regval |= DMA_CTRL_DST_SIZE_BYTE | DMA_CTRL_SRC_SIZE_BYTE;
|
||||
incr = DMA_CTRL_DST_INC_BYTE;
|
||||
break;
|
||||
|
||||
case 1: /* Half word transfer */
|
||||
regval = DMA_CTRL_DST_INC_HALFWORD | DMA_CTRL_DST_SIZE_HALFWORD | DMA_CTRL_SRC_SIZE_HALFWORD;
|
||||
regval |= DMA_CTRL_DST_SIZE_HALFWORD | DMA_CTRL_SRC_SIZE_HALFWORD;
|
||||
incr = DMA_CTRL_DST_INC_HALFWORD;
|
||||
break;
|
||||
|
||||
case 2: /* Word transfer */
|
||||
regval = DMA_CTRL_DST_INC_WORD | DMA_CTRL_DST_SIZE_WORD | DMA_CTRL_SRC_SIZE_WORD;
|
||||
regval |= DMA_CTRL_DST_SIZE_WORD | DMA_CTRL_SRC_SIZE_WORD;
|
||||
incr = DMA_CTRL_DST_INC_WORD;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Do we need to increment the memory address? */
|
||||
|
||||
if ((config & EFM32_DMA_MEMINCR_MASK) == EFM32_DMA_MEMINCR)
|
||||
{
|
||||
regval |= incr;
|
||||
}
|
||||
|
||||
/* Set the number of transfers (minus 1) */
|
||||
|
||||
DEBUGASSERT((nbytes >> shift) < 1024);
|
||||
@@ -543,6 +554,7 @@ void efm32_txdmasetup(DMA_HANDLE handle, uintptr_t paddr, uintptr_t maddr,
|
||||
unsigned int xfersize;
|
||||
unsigned int shift;
|
||||
uint32_t regval;
|
||||
uint32_t incr;
|
||||
uint32_t mask;
|
||||
|
||||
DEBUGASSERT(dmach != NULL && dmach->inuse);
|
||||
@@ -579,25 +591,35 @@ void efm32_txdmasetup(DMA_HANDLE handle, uintptr_t paddr, uintptr_t maddr,
|
||||
*/
|
||||
|
||||
regval = DMA_CTRL_DST_INC_NONE | DMA_CTRL_DST_PROT_NON_PRIVILEGED |
|
||||
DMA_CTRL_SRC_PROT_NON_PRIVILEGED | DMA_CTRL_R_POWER_1 |
|
||||
(0 << _DMA_CTRL_NEXT_USEBURST_SHIFT) | _DMA_CTRL_CYCLE_CTRL_BASIC;
|
||||
DMA_CTRL_SRC_PROT_NON_PRIVILEGED | DMA_CTRL_R_POWER_1 |
|
||||
(0 << _DMA_CTRL_NEXT_USEBURST_SHIFT) | _DMA_CTRL_CYCLE_CTRL_BASIC;
|
||||
|
||||
switch (shift)
|
||||
{
|
||||
default:
|
||||
case 0: /* Byte transfer */
|
||||
regval = DMA_CTRL_DST_SIZE_BYTE | DMA_CTRL_SRC_INC_BYTE | DMA_CTRL_SRC_SIZE_BYTE;
|
||||
regval |= DMA_CTRL_DST_SIZE_BYTE | DMA_CTRL_SRC_SIZE_BYTE;
|
||||
incr = DMA_CTRL_SRC_INC_BYTE;
|
||||
break;
|
||||
|
||||
case 1: /* Half word transfer */
|
||||
regval = DMA_CTRL_DST_SIZE_HALFWORD | DMA_CTRL_SRC_INC_HALFWORD | DMA_CTRL_SRC_SIZE_HALFWORD;
|
||||
regval |= DMA_CTRL_DST_SIZE_HALFWORD | DMA_CTRL_SRC_SIZE_HALFWORD;
|
||||
incr = DMA_CTRL_SRC_INC_HALFWORD;
|
||||
break;
|
||||
|
||||
case 2: /* Word transfer */
|
||||
regval = DMA_CTRL_DST_SIZE_WORD | DMA_CTRL_SRC_INC_WORD | DMA_CTRL_SRC_SIZE_WORD;
|
||||
regval |= DMA_CTRL_DST_SIZE_WORD | DMA_CTRL_SRC_SIZE_WORD;
|
||||
incr = DMA_CTRL_SRC_INC_WORD;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Do we need to increment the memory address? */
|
||||
|
||||
if ((config & EFM32_DMA_MEMINCR_MASK) == EFM32_DMA_MEMINCR)
|
||||
{
|
||||
regval |= incr;
|
||||
}
|
||||
|
||||
/* Set the number of transfers (minus 1) */
|
||||
|
||||
DEBUGASSERT((nbytes >> shift) < 1024);
|
||||
|
||||
@@ -63,23 +63,27 @@
|
||||
* - Memory address is always incremented.
|
||||
*/
|
||||
|
||||
#define EFM32_DMA_SIGSEL_SHIFT (0) /* Bits 0-3: _DMA_CH_CTRL_ * value */
|
||||
#define EFM32_DMA_SIGSEL_MASK (15 << EFM32_DMA_SIGSEL_SHIFT)
|
||||
# define EFM32_DMA_SIGSEL(n) ((dma_config_t)(n) << EFM32_DMA_SIGSEL_SHIFT)
|
||||
#define EFM32_DMA_SIGSEL_SHIFT (0) /* Bits 0-3: _DMA_CH_CTRL_ * value */
|
||||
#define EFM32_DMA_SIGSEL_MASK (15 << EFM32_DMA_SIGSEL_SHIFT)
|
||||
# define EFM32_DMA_SIGSEL(n) ((dma_config_t)(n) << EFM32_DMA_SIGSEL_SHIFT)
|
||||
|
||||
#define EFM32_DMA_SOURCSEL_SHIFT (4) /* Bits 4-9: _DMA_CH_SOURCESEL_* value */
|
||||
#define EFM32_DMA_SOURCSEL_MASK (63 << EFM32_DMA_SOURCSEL_SHIFT)
|
||||
# define EFM32_DMA_SOURCSEL(n) (dma_config_t)(n) << EFM32_DMA_SOURCSEL_SHIFT)
|
||||
#define EFM32_DMA_SOURCSEL_SHIFT (4) /* Bits 4-9: _DMA_CH_SOURCESEL_* value */
|
||||
#define EFM32_DMA_SOURCSEL_MASK (63 << EFM32_DMA_SOURCSEL_SHIFT)
|
||||
# define EFM32_DMA_SOURCSEL(n) ((dma_config_t)(n) << EFM32_DMA_SOURCSEL_SHIFT)
|
||||
|
||||
#define EFM32_DMA_XFERSIZE_SHIFT (10) /* Bits 10-11: Transfer size */
|
||||
#define EFM32_DMA_XFERSIZE_MASK (3 << EFM32_DMA_XFERSIZE_SHIFT)
|
||||
# define EFM32_DMA_XFERSIZE_SHIFT_BYTE (0 << EFM32_DMA_SOURCSEL_SHIFT)
|
||||
# define EFM32_DMA_XFERSIZE_SHIFT_HWORD (1 << EFM32_DMA_SOURCSEL_SHIFT)
|
||||
# define EFM32_DMA_XFERSIZE_SHIFT_WORD (2 << EFM32_DMA_SOURCSEL_SHIFT)
|
||||
#define EFM32_DMA_XFERSIZE_SHIFT (10) /* Bits 10-11: Transfer size */
|
||||
#define EFM32_DMA_XFERSIZE_MASK (3 << EFM32_DMA_XFERSIZE_SHIFT)
|
||||
# define EFM32_DMA_XFERSIZE_BYTE (0 << EFM32_DMA_SOURCSEL_SHIFT)
|
||||
# define EFM32_DMA_XFERSIZE_HWORD (1 << EFM32_DMA_SOURCSEL_SHIFT)
|
||||
# define EFM32_DMA_XFERSIZE_WORD (2 << EFM32_DMA_SOURCSEL_SHIFT)
|
||||
|
||||
#define EFM32_DMA_SINGLE_MASK (1 << 12) /* Bit 12: Single or Buffer full request */
|
||||
# define EFM32_DMA_SINGLE (1 << 12) /* 1=Buffer full request */
|
||||
# define EFM32_DMA_BUFFER_FULL (0) /* 0=Buffer full request */
|
||||
#define EFM32_DMA_SINGLE_MASK (1 << 12) /* Bit 12: Single or Buffer full request */
|
||||
# define EFM32_DMA_SINGLE (1 << 12) /* 1=Buffer full request */
|
||||
# define EFM32_DMA_BUFFER_FULL (0) /* 0=Buffer full request */
|
||||
|
||||
#define EFM32_DMA_MEMINCR_MASK (1 << 13) /* Bit 13: Increment memory address */
|
||||
# define EFM32_DMA_MEMINCR (1 << 13) /* 1=Increment memory address */
|
||||
# define EFM32_DMA_NOINCR (0) /* 0=No memory address increment */
|
||||
|
||||
/************************************************************************************
|
||||
* Public Types
|
||||
|
||||
+470
-81
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user