EFM32: Completes very basic DMA support. Needs review. Untested
This commit is contained in:
parent
1502ba31b3
commit
116129adf8
@ -72,107 +72,107 @@
|
||||
*******************************************************************************************************************************/
|
||||
|
||||
#if defined(CONFIG_EFM32_EFM32GG)
|
||||
# define EFM_DMA_NCHANNELS 12
|
||||
# define EFM32_DMA_NCHANNELS 12
|
||||
#elif defined(CONFIG_EFM32_EFM32G)
|
||||
# define EFM_DMA_NCHANNELS 8
|
||||
# define EFM32_DMA_NCHANNELS 8
|
||||
#endif
|
||||
|
||||
/* DMA Register Offsets ********************************************************************************************************/
|
||||
|
||||
#define EFM_DMA_STATUS_OFFSET 0x0000 /* DMA Status Registers */
|
||||
#define EFM_DMA_CONFIG_OFFSET 0x0004 /* DMA Configuration Register */
|
||||
#define EFM_DMA_CTRLBASE_OFFSET 0x0008 /* Channel Control Data Base Pointer Register */
|
||||
#define EFM_DMA_ALTCTRLBASE_OFFSET 0x000c /* Channel Alternate Control Data Base Pointer Register */
|
||||
#define EFM_DMA_CHWAITSTATUS_OFFSET 0x0010 /* Channel Wait on Request Status Register */
|
||||
#define EFM_DMA_CHSWREQ_OFFSET 0x0014 /* Channel Software Request Register */
|
||||
#define EFM_DMA_CHUSEBURSTS_OFFSET 0x0018 /* Channel Useburst Set Register */
|
||||
#define EFM_DMA_CHUSEBURSTC_OFFSET 0x001c /* Channel Useburst Clear Register */
|
||||
#define EFM_DMA_CHREQMASKS_OFFSET 0x0020 /* Channel Request Mask Set Register */
|
||||
#define EFM_DMA_CHREQMASKC_OFFSET 0x0024 /* Channel Request Mask Clear Register */
|
||||
#define EFM_DMA_CHENS_OFFSET 0x0028 /* Channel Enable Set Register */
|
||||
#define EFM_DMA_CHENC_OFFSET 0x002c /* Channel Enable Clear Register */
|
||||
#define EFM_DMA_CHALTS_OFFSET 0x0030 /* Channel Alternate Set Register */
|
||||
#define EFM_DMA_CHALTC_OFFSET 0x0034 /* Channel Alternate Clear Register */
|
||||
#define EFM_DMA_CHPRIS_OFFSET 0x0038 /* Channel Priority Set Register */
|
||||
#define EFM_DMA_CHPRIC_OFFSET 0x003c /* Channel Priority Clear Register */
|
||||
#define EFM_DMA_ERRORC_OFFSET 0x004c /* Bus Error Clear Register */
|
||||
#define EFM_DMA_CHREQSTATUS_OFFSET 0x0e10 /* Channel Request Status */
|
||||
#define EFM_DMA_CHSREQSTATUS_OFFSET 0x0e18 /* Channel Single Request Status */
|
||||
#define EFM_DMA_IF_OFFSET 0x1000 /* Interrupt Flag Register */
|
||||
#define EFM_DMA_IFS_OFFSET 0x1004 /* Interrupt Flag Set Register */
|
||||
#define EFM_DMA_IFC_OFFSET 0x1008 /* Interrupt Flag Clear Register */
|
||||
#define EFM_DMA_IEN_OFFSET 0x100c /* Interrupt Enable register */
|
||||
#define EFM32_DMA_STATUS_OFFSET 0x0000 /* DMA Status Registers */
|
||||
#define EFM32_DMA_CONFIG_OFFSET 0x0004 /* DMA Configuration Register */
|
||||
#define EFM32_DMA_CTRLBASE_OFFSET 0x0008 /* Channel Control Data Base Pointer Register */
|
||||
#define EFM32_DMA_ALTCTRLBASE_OFFSET 0x000c /* Channel Alternate Control Data Base Pointer Register */
|
||||
#define EFM32_DMA_CHWAITSTATUS_OFFSET 0x0010 /* Channel Wait on Request Status Register */
|
||||
#define EFM32_DMA_CHSWREQ_OFFSET 0x0014 /* Channel Software Request Register */
|
||||
#define EFM32_DMA_CHUSEBURSTS_OFFSET 0x0018 /* Channel Useburst Set Register */
|
||||
#define EFM32_DMA_CHUSEBURSTC_OFFSET 0x001c /* Channel Useburst Clear Register */
|
||||
#define EFM32_DMA_CHREQMASKS_OFFSET 0x0020 /* Channel Request Mask Set Register */
|
||||
#define EFM32_DMA_CHREQMASKC_OFFSET 0x0024 /* Channel Request Mask Clear Register */
|
||||
#define EFM32_DMA_CHENS_OFFSET 0x0028 /* Channel Enable Set Register */
|
||||
#define EFM32_DMA_CHENC_OFFSET 0x002c /* Channel Enable Clear Register */
|
||||
#define EFM32_DMA_CHALTS_OFFSET 0x0030 /* Channel Alternate Set Register */
|
||||
#define EFM32_DMA_CHALTC_OFFSET 0x0034 /* Channel Alternate Clear Register */
|
||||
#define EFM32_DMA_CHPRIS_OFFSET 0x0038 /* Channel Priority Set Register */
|
||||
#define EFM32_DMA_CHPRIC_OFFSET 0x003c /* Channel Priority Clear Register */
|
||||
#define EFM32_DMA_ERRORC_OFFSET 0x004c /* Bus Error Clear Register */
|
||||
#define EFM32_DMA_CHREQSTATUS_OFFSET 0x0e10 /* Channel Request Status */
|
||||
#define EFM32_DMA_CHSREQSTATUS_OFFSET 0x0e18 /* Channel Single Request Status */
|
||||
#define EFM32_DMA_IF_OFFSET 0x1000 /* Interrupt Flag Register */
|
||||
#define EFM32_DMA_IFS_OFFSET 0x1004 /* Interrupt Flag Set Register */
|
||||
#define EFM32_DMA_IFC_OFFSET 0x1008 /* Interrupt Flag Clear Register */
|
||||
#define EFM32_DMA_IEN_OFFSET 0x100c /* Interrupt Enable register */
|
||||
#if defined(CONFIG_EFM32_EFM32GG)
|
||||
# define EFM_DMA_CTRL_OFFSET 0x1010 /* DMA Control Register */
|
||||
# define EFM_DMA_RDS_OFFSET 0x1014 /* DMA Retain Descriptor State */
|
||||
# define EFM_DMA_LOOP0_OFFSET 0x1020 /* Channel 0 Loop Register */
|
||||
# define EFM_DMA_LOOP1_OFFSET 0x1024 /* Channel 1 Loop Register */
|
||||
# define EFM_DMA_RECT0_OFFSET 0x1060 /* Channel 0 Rectangle Register */
|
||||
# define EFM32_DMA_CTRL_OFFSET 0x1010 /* DMA Control Register */
|
||||
# define EFM32_DMA_RDS_OFFSET 0x1014 /* DMA Retain Descriptor State */
|
||||
# define EFM32_DMA_LOOP0_OFFSET 0x1020 /* Channel 0 Loop Register */
|
||||
# define EFM32_DMA_LOOP1_OFFSET 0x1024 /* Channel 1 Loop Register */
|
||||
# define EFM32_DMA_RECT0_OFFSET 0x1060 /* Channel 0 Rectangle Register */
|
||||
#endif
|
||||
|
||||
#define EFM_DMA_CHn_CTRL_OFFSET(n) (0x1100+((n)<<2)) /* Channel n Control Register */
|
||||
#define EFM_DMA_CH0_CTRL_OFFSET 0x1100 /* Channel 0 Control Register */
|
||||
#define EFM_DMA_CH1_CTRL_OFFSET 0x1104 /* Channel 1 Control Register */
|
||||
#define EFM_DMA_CH2_CTRL_OFFSET 0x1108 /* Channel 2 Control Register */
|
||||
#define EFM_DMA_CH3_CTRL_OFFSET 0x110c /* Channel 3 Control Register */
|
||||
#define EFM_DMA_CH4_CTRL_OFFSET 0x1110 /* Channel 4 Control Register */
|
||||
#define EFM_DMA_CH5_CTRL_OFFSET 0x1114 /* Channel 5 Control Register */
|
||||
#define EFM_DMA_CH6_CTRL_OFFSET 0x1118 /* Channel 6 Control Register */
|
||||
#define EFM_DMA_CH7_CTRL_OFFSET 0x111c /* Channel 7 Control Register */
|
||||
#define EFM32_DMA_CHn_CTRL_OFFSET(n) (0x1100+((n)<<2)) /* Channel n Control Register */
|
||||
#define EFM32_DMA_CH0_CTRL_OFFSET 0x1100 /* Channel 0 Control Register */
|
||||
#define EFM32_DMA_CH1_CTRL_OFFSET 0x1104 /* Channel 1 Control Register */
|
||||
#define EFM32_DMA_CH2_CTRL_OFFSET 0x1108 /* Channel 2 Control Register */
|
||||
#define EFM32_DMA_CH3_CTRL_OFFSET 0x110c /* Channel 3 Control Register */
|
||||
#define EFM32_DMA_CH4_CTRL_OFFSET 0x1110 /* Channel 4 Control Register */
|
||||
#define EFM32_DMA_CH5_CTRL_OFFSET 0x1114 /* Channel 5 Control Register */
|
||||
#define EFM32_DMA_CH6_CTRL_OFFSET 0x1118 /* Channel 6 Control Register */
|
||||
#define EFM32_DMA_CH7_CTRL_OFFSET 0x111c /* Channel 7 Control Register */
|
||||
#if defined(CONFIG_EFM32_EFM32GG)
|
||||
# define EFM_DMA_CH8_CTRL_OFFSET 0x1120 /* Channel 8 Control Register */
|
||||
# define EFM_DMA_CH9_CTRL_OFFSET 0x1124 /* Channel 9 Control Register */
|
||||
# define EFM_DMA_CH10_CTRL_OFFSET 0x1128 /* Channel 10 Control Register */
|
||||
# define EFM_DMA_CH11_CTRL_OFFSET 0x112c /* Channel 11 Control Register */
|
||||
# define EFM32_DMA_CH8_CTRL_OFFSET 0x1120 /* Channel 8 Control Register */
|
||||
# define EFM32_DMA_CH9_CTRL_OFFSET 0x1124 /* Channel 9 Control Register */
|
||||
# define EFM32_DMA_CH10_CTRL_OFFSET 0x1128 /* Channel 10 Control Register */
|
||||
# define EFM32_DMA_CH11_CTRL_OFFSET 0x112c /* Channel 11 Control Register */
|
||||
#endif
|
||||
|
||||
/* DMA Register Addresses ******************************************************************************************************/
|
||||
|
||||
#define EFM_DMA_STATUS (EFM32_DMA_BASE+EFM_DMA_STATUS_OFFSET)
|
||||
#define EFM_DMA_CONFIG (EFM32_DMA_BASE+EFM_DMA_CONFIG_OFFSET)
|
||||
#define EFM_DMA_CTRLBASE (EFM32_DMA_BASE+EFM_DMA_CTRLBASE_OFFSET)
|
||||
#define EFM_DMA_ALTCTRLBASE (EFM32_DMA_BASE+EFM_DMA_ALTCTRLBASE_OFFSET)
|
||||
#define EFM_DMA_CHWAITSTATUS (EFM32_DMA_BASE+EFM_DMA_CHWAITSTATUS_OFFSET)
|
||||
#define EFM_DMA_CHSWREQ (EFM32_DMA_BASE+EFM_DMA_CHSWREQ_OFFSET)
|
||||
#define EFM_DMA_CHUSEBURSTS (EFM32_DMA_BASE+EFM_DMA_CHUSEBURSTS_OFFSET)
|
||||
#define EFM_DMA_CHUSEBURSTC (EFM32_DMA_BASE+EFM_DMA_CHUSEBURSTC_OFFSET)
|
||||
#define EFM_DMA_CHREQMASKS (EFM32_DMA_BASE+EFM_DMA_CHREQMASKS_OFFSET)
|
||||
#define EFM_DMA_CHREQMASKC (EFM32_DMA_BASE+EFM_DMA_CHREQMASKC_OFFSET)
|
||||
#define EFM_DMA_CHENS (EFM32_DMA_BASE+EFM_DMA_CHENS_OFFSET)
|
||||
#define EFM_DMA_CHENC (EFM32_DMA_BASE+EFM_DMA_CHENC_OFFSET)
|
||||
#define EFM_DMA_CHALTS (EFM32_DMA_BASE+EFM_DMA_CHALTS_OFFSET)
|
||||
#define EFM_DMA_CHALTC (EFM32_DMA_BASE+EFM_DMA_CHALTC_OFFSET)
|
||||
#define EFM_DMA_CHPRIS (EFM32_DMA_BASE+EFM_DMA_CHPRIS_OFFSET)
|
||||
#define EFM_DMA_CHPRIC (EFM32_DMA_BASE+EFM_DMA_CHPRIC_OFFSET)
|
||||
#define EFM_DMA_ERRORC (EFM32_DMA_BASE+EFM_DMA_ERRORC_OFFSET)
|
||||
#define EFM_DMA_CHREQSTATUS (EFM32_DMA_BASE+EFM_DMA_CHREQSTATUS_OFFSET)
|
||||
#define EFM_DMA_CHSREQSTATUS (EFM32_DMA_BASE+EFM_DMA_CHSREQSTATUS_OFFSET)
|
||||
#define EFM_DMA_IF (EFM32_DMA_BASE+EFM_DMA_IF_OFFSET)
|
||||
#define EFM_DMA_IFS (EFM32_DMA_BASE+EFM_DMA_IFS_OFFSET)
|
||||
#define EFM_DMA_IFC (EFM32_DMA_BASE+EFM_DMA_IFC_OFFSET)
|
||||
#define EFM_DMA_IEN (EFM32_DMA_BASE+EFM_DMA_IEN_OFFSET)
|
||||
#define EFM32_DMA_STATUS (EFM32_DMA_BASE+EFM32_DMA_STATUS_OFFSET)
|
||||
#define EFM32_DMA_CONFIG (EFM32_DMA_BASE+EFM32_DMA_CONFIG_OFFSET)
|
||||
#define EFM32_DMA_CTRLBASE (EFM32_DMA_BASE+EFM32_DMA_CTRLBASE_OFFSET)
|
||||
#define EFM32_DMA_ALTCTRLBASE (EFM32_DMA_BASE+EFM32_DMA_ALTCTRLBASE_OFFSET)
|
||||
#define EFM32_DMA_CHWAITSTATUS (EFM32_DMA_BASE+EFM32_DMA_CHWAITSTATUS_OFFSET)
|
||||
#define EFM32_DMA_CHSWREQ (EFM32_DMA_BASE+EFM32_DMA_CHSWREQ_OFFSET)
|
||||
#define EFM32_DMA_CHUSEBURSTS (EFM32_DMA_BASE+EFM32_DMA_CHUSEBURSTS_OFFSET)
|
||||
#define EFM32_DMA_CHUSEBURSTC (EFM32_DMA_BASE+EFM32_DMA_CHUSEBURSTC_OFFSET)
|
||||
#define EFM32_DMA_CHREQMASKS (EFM32_DMA_BASE+EFM32_DMA_CHREQMASKS_OFFSET)
|
||||
#define EFM32_DMA_CHREQMASKC (EFM32_DMA_BASE+EFM32_DMA_CHREQMASKC_OFFSET)
|
||||
#define EFM32_DMA_CHENS (EFM32_DMA_BASE+EFM32_DMA_CHENS_OFFSET)
|
||||
#define EFM32_DMA_CHENC (EFM32_DMA_BASE+EFM32_DMA_CHENC_OFFSET)
|
||||
#define EFM32_DMA_CHALTS (EFM32_DMA_BASE+EFM32_DMA_CHALTS_OFFSET)
|
||||
#define EFM32_DMA_CHALTC (EFM32_DMA_BASE+EFM32_DMA_CHALTC_OFFSET)
|
||||
#define EFM32_DMA_CHPRIS (EFM32_DMA_BASE+EFM32_DMA_CHPRIS_OFFSET)
|
||||
#define EFM32_DMA_CHPRIC (EFM32_DMA_BASE+EFM32_DMA_CHPRIC_OFFSET)
|
||||
#define EFM32_DMA_ERRORC (EFM32_DMA_BASE+EFM32_DMA_ERRORC_OFFSET)
|
||||
#define EFM32_DMA_CHREQSTATUS (EFM32_DMA_BASE+EFM32_DMA_CHREQSTATUS_OFFSET)
|
||||
#define EFM32_DMA_CHSREQSTATUS (EFM32_DMA_BASE+EFM32_DMA_CHSREQSTATUS_OFFSET)
|
||||
#define EFM32_DMA_IF (EFM32_DMA_BASE+EFM32_DMA_IF_OFFSET)
|
||||
#define EFM32_DMA_IFS (EFM32_DMA_BASE+EFM32_DMA_IFS_OFFSET)
|
||||
#define EFM32_DMA_IFC (EFM32_DMA_BASE+EFM32_DMA_IFC_OFFSET)
|
||||
#define EFM32_DMA_IEN (EFM32_DMA_BASE+EFM32_DMA_IEN_OFFSET)
|
||||
#if defined(CONFIG_EFM32_EFM32GG)
|
||||
# define EFM_DMA_CTRL (EFM32_DMA_BASE+EFM_DMA_CTRL_OFFSET)
|
||||
# define EFM_DMA_RDS (EFM32_DMA_BASE+EFM_DMA_RDS_OFFSET)
|
||||
# define EFM_DMA_LOOP0 (EFM32_DMA_BASE+EFM_DMA_LOOP0_OFFSET)
|
||||
# define EFM_DMA_LOOP1 (EFM32_DMA_BASE+EFM_DMA_LOOP1_OFFSET)
|
||||
# define EFM_DMA_RECT0 (EFM32_DMA_BASE+EFM_DMA_RECT0_OFFSET)
|
||||
# define EFM32_DMA_CTRL (EFM32_DMA_BASE+EFM32_DMA_CTRL_OFFSET)
|
||||
# define EFM32_DMA_RDS (EFM32_DMA_BASE+EFM32_DMA_RDS_OFFSET)
|
||||
# define EFM32_DMA_LOOP0 (EFM32_DMA_BASE+EFM32_DMA_LOOP0_OFFSET)
|
||||
# define EFM32_DMA_LOOP1 (EFM32_DMA_BASE+EFM32_DMA_LOOP1_OFFSET)
|
||||
# define EFM32_DMA_RECT0 (EFM32_DMA_BASE+EFM32_DMA_RECT0_OFFSET)
|
||||
#endif
|
||||
|
||||
#define EFM_DMA_CHn_CTRL(n) (EFM32_DMA_BASE+EFM_DMA_CHn_CTRL_OFFSET(n))
|
||||
#define EFM_DMA_CH0_CTRL (EFM32_DMA_BASE+EFM_DMA_CH0_CTRL_OFFSET)
|
||||
#define EFM_DMA_CH1_CTRL (EFM32_DMA_BASE+EFM_DMA_CH1_CTRL_OFFSET)
|
||||
#define EFM_DMA_CH2_CTRL (EFM32_DMA_BASE+EFM_DMA_CH2_CTRL_OFFSET)
|
||||
#define EFM_DMA_CH3_CTRL (EFM32_DMA_BASE+EFM_DMA_CH3_CTRL_OFFSET)
|
||||
#define EFM_DMA_CH4_CTRL (EFM32_DMA_BASE+EFM_DMA_CH4_CTRL_OFFSET)
|
||||
#define EFM_DMA_CH5_CTRL (EFM32_DMA_BASE+EFM_DMA_CH5_CTRL_OFFSET)
|
||||
#define EFM_DMA_CH6_CTRL (EFM32_DMA_BASE+EFM_DMA_CH6_CTRL_OFFSET)
|
||||
#define EFM_DMA_CH7_CTRL (EFM32_DMA_BASE+EFM_DMA_CH7_CTRL_OFFSET)
|
||||
#define EFM32_DMA_CHn_CTRL(n) (EFM32_DMA_BASE+EFM32_DMA_CHn_CTRL_OFFSET(n))
|
||||
#define EFM32_DMA_CH0_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH0_CTRL_OFFSET)
|
||||
#define EFM32_DMA_CH1_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH1_CTRL_OFFSET)
|
||||
#define EFM32_DMA_CH2_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH2_CTRL_OFFSET)
|
||||
#define EFM32_DMA_CH3_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH3_CTRL_OFFSET)
|
||||
#define EFM32_DMA_CH4_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH4_CTRL_OFFSET)
|
||||
#define EFM32_DMA_CH5_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH5_CTRL_OFFSET)
|
||||
#define EFM32_DMA_CH6_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH6_CTRL_OFFSET)
|
||||
#define EFM32_DMA_CH7_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH7_CTRL_OFFSET)
|
||||
#if defined(CONFIG_EFM32_EFM32GG)
|
||||
# define EFM_DMA_CH8_CTRL (EFM32_DMA_BASE+EFM_DMA_CH8_CTRL_OFFSET)
|
||||
# define EFM_DMA_CH9_CTRL (EFM32_DMA_BASE+EFM_DMA_CH9_CTRL_OFFSET)
|
||||
# define EFM_DMA_CH10_CTRL (EFM32_DMA_BASE+EFM_DMA_CH10_CTRL_OFFSET)
|
||||
# define EFM_DMA_CH11_CTRL (EFM32_DMA_BASE+EFM_DMA_CH11_CTRL_OFFSET)
|
||||
# define EFM32_DMA_CH8_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH8_CTRL_OFFSET)
|
||||
# define EFM32_DMA_CH9_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH9_CTRL_OFFSET)
|
||||
# define EFM32_DMA_CH10_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH10_CTRL_OFFSET)
|
||||
# define EFM32_DMA_CH11_CTRL (EFM32_DMA_BASE+EFM32_DMA_CH11_CTRL_OFFSET)
|
||||
#endif
|
||||
|
||||
/* DMA Register Bit Field Definitions ******************************************************************************************/
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "up_arch.h"
|
||||
#include "chip/efm32_cmu.h"
|
||||
#include "chip/efm32_dma.h"
|
||||
#include "efm32_dma.h"
|
||||
|
||||
@ -76,7 +77,7 @@ union dma_descriptor_u
|
||||
|
||||
struct dma_channel_s
|
||||
{
|
||||
uint8_t chan; /* DMA channel number (0-EFM_DMA_NCHANNELS) */
|
||||
uint8_t chan; /* DMA channel number (0-EFM32_DMA_NCHANNELS) */
|
||||
bool inuse; /* TRUE: The DMA channel is in use */
|
||||
struct dma_descriptor_s *desc; /* DMA descriptor assigned to the channel */
|
||||
dma_config_t config; /* Current configuration */
|
||||
@ -104,7 +105,7 @@ static struct dma_controller_s g_dmac;
|
||||
|
||||
/* This is the array of all DMA channels */
|
||||
|
||||
static struct dma_channel_s g_dmach[EFM_DMA_NCHANNELS];
|
||||
static struct dma_channel_s g_dmach[EFM32_DMA_NCHANNELS];
|
||||
|
||||
/* This array describes the available channel control data structures.
|
||||
* Each structure must be aligned to the size of the DMA descriptor.
|
||||
@ -216,7 +217,7 @@ static void efm32_set_chctrl(struct dma_channel_s *dmach, dma_config_t config)
|
||||
decoded = (uint32_t)(config & EFM32_DMA_SOURCSEL_MASK) >> EFM32_DMA_SOURCSEL_SHIFT;
|
||||
regval |= (decoded << _DMA_CH_CTRL_SOURCESEL_SHIFT);
|
||||
|
||||
regaddr = EFM_DMA_CHn_CTRL(dmach->chan);
|
||||
regaddr = EFM32_DMA_CHn_CTRL(dmach->chan);
|
||||
putreg32(regval, regaddr);
|
||||
}
|
||||
|
||||
@ -247,7 +248,47 @@ static inline unsigned int efm32_align_shift(dma_config_t config)
|
||||
|
||||
static int efm32_dmac_interrupt(int irq, void *context)
|
||||
{
|
||||
#warning Missing logic
|
||||
struct dma_channel_s *dmach;
|
||||
unsigned int chndx;
|
||||
uint32_t pending;
|
||||
uint32_t bit;
|
||||
|
||||
/* Get the set of pending, unmasked global XDMAC interrupts */
|
||||
|
||||
pending = getreg32(EFM32_DMA_IF) & getreg32(EFM32_DMA_IEN);
|
||||
putreg32(pending, EFM32_DMA_IFC);
|
||||
|
||||
/* Check each bit to see which channel(s) have interrupted */
|
||||
|
||||
for (chndx = 0; chndx < EFM32_DMA_NCHANNELS && pending != 0; chndx++)
|
||||
{
|
||||
/* Are any interrupts pending for this channel? */
|
||||
|
||||
bit = 1 << chndx;
|
||||
if ((pending & bit) != 0)
|
||||
{
|
||||
dmach = &g_dmach[chndx];
|
||||
|
||||
/* Put the DMA channel in the stopped state */
|
||||
|
||||
efm32_dmastop((DMA_HANDLE)dmach);
|
||||
|
||||
/* Call the DMA completion callback */
|
||||
|
||||
if (dmach->callback)
|
||||
{
|
||||
dmach->callback((DMA_HANDLE)dmach, OK, dmach->arg);
|
||||
dmach->callback = NULL;
|
||||
}
|
||||
|
||||
dmach->arg = NULL;
|
||||
|
||||
/* Clear the bit in the sampled set of pending interrupts */
|
||||
|
||||
pending &= !bit;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -268,6 +309,7 @@ static int efm32_dmac_interrupt(int irq, void *context)
|
||||
|
||||
void weak_function up_dmainitialize(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
int i;
|
||||
|
||||
dmallvdbg("Initialize XDMAC0\n");
|
||||
@ -285,23 +327,26 @@ void weak_function up_dmainitialize(void)
|
||||
/* Initialize the channel list */
|
||||
|
||||
sem_init(&g_dmac.exclsem, 0, 1);
|
||||
sem_init(&g_dmac.chansem, 0, EFM_DMA_NCHANNELS);
|
||||
sem_init(&g_dmac.chansem, 0, EFM32_DMA_NCHANNELS);
|
||||
|
||||
for (i = 0; i < EFM_DMA_NCHANNELS; i++)
|
||||
for (i = 0; i < EFM32_DMA_NCHANNELS; i++)
|
||||
{
|
||||
g_dmach[i].chan = i;
|
||||
}
|
||||
|
||||
/* Enable clock to the DMA module */
|
||||
#warning Missing logic
|
||||
/* Enable clock to the DMA module. DMA is clocked by HFCORECLK. */
|
||||
|
||||
regval = getreg32(EFM32_CMU_HFCORECLKEN0);
|
||||
regval |= CMU_HFCORECLKEN0_DMA;
|
||||
putreg32(regval, EFM32_CMU_HFCORECLKEN0);
|
||||
|
||||
/* Attach DMA interrupt vector */
|
||||
|
||||
(void)irq_attach(EFM32_IRQ_DMA, efm32_dmac_interrupt);
|
||||
|
||||
/* Enale the DMA controller */
|
||||
/* Enable the DMA controller */
|
||||
|
||||
putreg32(DMA_CONFIG_EN, EFM_DMA_CONFIG);
|
||||
putreg32(DMA_CONFIG_EN, EFM32_DMA_CONFIG);
|
||||
|
||||
/* Enable the IRQ at the AIC (still disabled at the DMA controller) */
|
||||
|
||||
@ -335,6 +380,7 @@ DMA_HANDLE efm32_dmachannel(void)
|
||||
{
|
||||
struct dma_channel_s *dmach;
|
||||
unsigned int chndx;
|
||||
uint32_t bit;
|
||||
|
||||
/* Take a count from from the channel counting semaphore. We may block
|
||||
* if there are no free channels. When we get the count, then we can
|
||||
@ -360,7 +406,7 @@ DMA_HANDLE efm32_dmachannel(void)
|
||||
|
||||
/* Search for an available DMA channel */
|
||||
|
||||
for (chndx = 0, dmach = NULL; chndx < EFM_DMA_NCHANNELS; chndx++)
|
||||
for (chndx = 0, dmach = NULL; chndx < EFM32_DMA_NCHANNELS; chndx++)
|
||||
{
|
||||
struct dma_channel_s *candidate = &g_dmach[chndx];
|
||||
if (!candidate->inuse)
|
||||
@ -369,11 +415,13 @@ DMA_HANDLE efm32_dmachannel(void)
|
||||
dmach->inuse = true;
|
||||
|
||||
/* Clear any pending channel interrupts */
|
||||
#warning Missing logic
|
||||
|
||||
bit = 1 << chndx;
|
||||
putreg32(bit, EFM32_DMA_IFC);
|
||||
|
||||
/* Disable the channel */
|
||||
|
||||
putreg32(1 << dmach->chan, EFM_DMA_CHENC);
|
||||
putreg32(bit, EFM32_DMA_CHENC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -422,7 +470,7 @@ void efm32_dmafree(DMA_HANDLE handle)
|
||||
|
||||
/* Disable the channel */
|
||||
|
||||
putreg32(1 << dmach->chan, EFM_DMA_CHENC);
|
||||
putreg32(1 << dmach->chan, EFM32_DMA_CHENC);
|
||||
|
||||
/* Mark the channel no longer in use. Clearing the in-use flag is an atomic
|
||||
* operation and so should be safe.
|
||||
@ -624,6 +672,8 @@ void efm32_txdmasetup(DMA_HANDLE handle, uintptr_t paddr, uintptr_t maddr,
|
||||
void efm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg)
|
||||
{
|
||||
struct dma_channel_s *dmach = (struct dma_channel_s *)handle;
|
||||
irqstate_t flags;
|
||||
uint32_t regval;
|
||||
uint32_t bit;
|
||||
|
||||
DEBUGASSERT(dmach && dmach->inuse && dmach->desc);
|
||||
@ -642,30 +692,38 @@ void efm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg)
|
||||
* available, wait for buffer full)
|
||||
*/
|
||||
|
||||
putreg32(bit, EFM_DMA_CHUSEBURSTS);
|
||||
putreg32(bit, EFM32_DMA_CHUSEBURSTS);
|
||||
|
||||
/* Enable buffer-full requests for the channel */
|
||||
|
||||
putreg32(bit, EFM_DMA_CHREQMASKC);
|
||||
putreg32(bit, EFM32_DMA_CHREQMASKC);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Enable the single requests for the channel */
|
||||
|
||||
putreg32(bit, EFM_DMA_CHUSEBURSTC);
|
||||
putreg32(bit, EFM32_DMA_CHUSEBURSTC);
|
||||
|
||||
/* Disable buffer-full requests for the channel */
|
||||
|
||||
putreg32(bit, EFM_DMA_CHREQMASKS);
|
||||
putreg32(bit, EFM32_DMA_CHREQMASKS);
|
||||
}
|
||||
|
||||
/* Use the primary data structure for channel 0 */
|
||||
|
||||
putreg32(bit, EFM_DMA_CHALTC);
|
||||
putreg32(bit, EFM32_DMA_CHALTC);
|
||||
|
||||
/* Enable DMA completion interrupts */
|
||||
|
||||
flags = irqsave();
|
||||
regval = getreg32(EFM32_DMA_IEN);
|
||||
regval |= bit;
|
||||
putreg32(bit, EFM32_DMA_IEN);
|
||||
|
||||
/* Enable the channel */
|
||||
|
||||
putreg32(bit, EFM_DMA_CHENS);
|
||||
putreg32(bit, EFM32_DMA_CHENS);
|
||||
irqrestore(flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -683,49 +741,36 @@ void efm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg)
|
||||
|
||||
void efm32_dmastop(DMA_HANDLE handle)
|
||||
{
|
||||
#warning Missing logic
|
||||
struct dma_channel_s *dmach = (struct dma_channel_s *)handle;
|
||||
irqstate_t flags;
|
||||
uint32_t regval;
|
||||
uint32_t bit;
|
||||
|
||||
DEBUGASSERT(dmach && dmach->inuse && dmach->desc);
|
||||
bit = 1 << dmach->chan;
|
||||
|
||||
/* Disable the channel */
|
||||
|
||||
flags = irqsave();
|
||||
putreg32(bit, EFM32_DMA_CHENC);
|
||||
|
||||
/* Disable Channel interrupts */
|
||||
|
||||
regval = getreg32(EFM32_DMA_IEN);
|
||||
regval |= bit;
|
||||
putreg32(bit, EFM32_DMA_IEN);
|
||||
|
||||
/* Free any attached DMA descriptor */
|
||||
|
||||
if (dmach->desc)
|
||||
{
|
||||
efm32_free_descriptor(dmach->desc);
|
||||
dmach->desc = NULL;
|
||||
}
|
||||
|
||||
irqrestore(flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: efm32_dmaresidual
|
||||
*
|
||||
* Description:
|
||||
* Returns the number of bytes remaining to be transferred
|
||||
*
|
||||
* Assumptions:
|
||||
* - DMA handle allocated by efm32_dmachannel()
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
size_t efm32_dmaresidual(DMA_HANDLE handle)
|
||||
{
|
||||
#warning Missing logic
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: efm32_dmacapable
|
||||
*
|
||||
* Description:
|
||||
* Check if the DMA controller can transfer data to/from given memory
|
||||
* address with the given configuration. This depends on the internal
|
||||
* connections in the ARM bus matrix of the processor. Note that this
|
||||
* only applies to memory addresses, it will return false for any peripheral
|
||||
* address.
|
||||
*
|
||||
* Returned value:
|
||||
* True, if transfer is possible.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_EFM32_DMACAPABLE
|
||||
bool efm32_dmacapable(uintptr_t maddr, uint32_t count, uint32_t ccr)
|
||||
{
|
||||
#warning Missing logic
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: efm32_dmasample
|
||||
*
|
||||
@ -740,7 +785,42 @@ return false;
|
||||
#ifdef CONFIG_DEBUG_DMA
|
||||
void efm32_dmasample(DMA_HANDLE handle, struct efm32_dmaregs_s *regs)
|
||||
{
|
||||
#warning Missing logic
|
||||
struct sam_dmach_s *dmach = (struct sam_dmach_s *)handle;
|
||||
uintptr_t regaddr;
|
||||
irqstate_t flags;
|
||||
|
||||
/* Sample DMA registers. */
|
||||
|
||||
flags = irqsave();
|
||||
|
||||
regs->status = getreg32(EFM32_DMA_STATUS);
|
||||
regs->ctrlbase = getreg32(EFM32_DMA_CTRLBASE);
|
||||
regs->altctrlbase = getreg32(EFM32_DMA_ALTCTRLBASE);
|
||||
regs->chwaitstatus = getreg32(EFM32_DMA_CHWAITSTATUS);
|
||||
regs->chusebursts = getreg32(EFM32_DMA_CHUSEBURSTS);
|
||||
regs->chreqmasks = getreg32(EFM32_DMA_CHREQMASKS);
|
||||
regs->chens = getreg32(EFM32_DMA_CHENS);
|
||||
regs->chalts = getreg32(EFM32_DMA_CHALTS);
|
||||
regs->chpris = getreg32(EFM32_DMA_CHPRIS);
|
||||
regs->errorc = getreg32(EFM32_DMA_ERRORC);
|
||||
regs->chreqstatus = getreg32(EFM32_DMA_CHREQSTATUS);
|
||||
regs->chsreqstatus = getreg32(EFM32_DMA_CHSREQSTATUS);
|
||||
regs->ifr = getreg32(EFM32_DMA_IF);
|
||||
regs->ien = getreg32(EFM32_DMA_IEN);
|
||||
#if defined(CONFIG_EFM32_EFM32GG)
|
||||
regs->ctrl = getreg32(EFM32_DMA_CTRL);
|
||||
regs->rds = getreg32(EFM32_DMA_RDS);
|
||||
regs->loop0 = getreg32(EFM32_DMA_LOOP0);
|
||||
regs->loop1 = getreg32(EFM32_DMA_LOOP1);
|
||||
regs->rect0 = getreg32(EFM32_DMA_RECT0);
|
||||
#endif
|
||||
|
||||
/* Sample channel control register */
|
||||
|
||||
regaddr = EFM32_DMA_CHn_CTRL(dmach->chan)
|
||||
regs->chnctrl = getreg32(regaddr);
|
||||
|
||||
irqrestore(flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -759,6 +839,32 @@ void efm32_dmasample(DMA_HANDLE handle, struct efm32_dmaregs_s *regs)
|
||||
void efm32_dmadump(DMA_HANDLE handle, const struct efm32_dmaregs_s *regs,
|
||||
const char *msg)
|
||||
{
|
||||
#warning Missing logic
|
||||
struct sam_xdmach_s *xdmach = (struct sam_xdmach_s *)handle;
|
||||
struct sam_xdmac_s *xdmac = sam_controller(xdmach);
|
||||
|
||||
dmadbg("%s\n", msg);
|
||||
dmadbg(" DMA Registers:\n");
|
||||
dmadbg(" STATUS: %08x\n", regs->status);
|
||||
dmadbg(" CTRLBASE: %08x\n", regs->ctrlbase);
|
||||
dmadbg(" ALTCTRLBASE: %08x\n", regs->altctrlbase);
|
||||
dmadbg(" CHWAITSTATUS: %08x\n", regs->chwaitstatus);
|
||||
dmadbg(" CHUSEBURSTS: %08x\n", regs->chusebursts);
|
||||
dmadbg(" CHREQMASKS: %08x\n", regs->chreqmasks);
|
||||
dmadbg(" CHENS: %08x\n", regs->chens);
|
||||
dmadbg(" CHALTS: %08x\n", regs->chalts);
|
||||
dmadbg(" CHPRIS: %08x\n", regs->chpris);
|
||||
dmadbg(" ERRORC: %08x\n", regs->errorc);
|
||||
dmadbg(" CHREQSTATUS: %08x\n", regs->chreqstatus);
|
||||
dmadbg(" CHSREQSTATUS: %08x\n", regs->chsreqstatus);
|
||||
dmadbg(" IEN: %08x\n", regs->ien);
|
||||
#if defined(CONFIG_EFM32_EFM32GG)
|
||||
dmadbg(" CTRL: %08x\n", regs->ctrl);
|
||||
dmadbg(" RDS: %08x\n", regs->rds);
|
||||
dmadbg(" LOOP0: %08x\n", regs->loop0);
|
||||
dmadbg(" LOOP1: %08x\n", regs->loop1);
|
||||
dmadbg(" RECT0: %08x\n", regs->rect0);
|
||||
#endif
|
||||
dmadbg(" DMA Channel %d Registers:\n", dmach->chan);
|
||||
dmadbg(" CHCTRL: %08x\n", regs->chnctrl);
|
||||
}
|
||||
#endif
|
||||
|
@ -107,7 +107,7 @@ typedef void (*dma_callback_t)(DMA_HANDLE handle, uint8_t status, void *arg);
|
||||
#ifdef CONFIG_DEBUG_DMA
|
||||
struct efm32_dmaregs_s
|
||||
{
|
||||
uint32_t status; /* DMA Status Registers */
|
||||
uint32_t status; /* DMA Status Register */
|
||||
uint32_t ctrlbase; /* Channel Control Data Base Pointer Register */
|
||||
uint32_t altctrlbase; /* Channel Alternate Control Data Base Pointer Register */
|
||||
uint32_t chwaitstatus; /* Channel Wait on Request Status Register */
|
||||
@ -128,7 +128,7 @@ struct efm32_dmaregs_s
|
||||
uint32_t loop1; /* Channel 1 Loop Register */
|
||||
uint32_t rect0; /* Channel 0 Rectangle Register */
|
||||
#endif
|
||||
uint32_t chcgrl /* Channel n Control Register */
|
||||
uint32_t chnctrl; /* Channel n Control Register */
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -266,40 +266,6 @@ void efm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg);
|
||||
|
||||
void efm32_dmastop(DMA_HANDLE handle);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: efm32_dmaresidual
|
||||
*
|
||||
* Description:
|
||||
* Returns the number of bytes remaining to be transferred
|
||||
*
|
||||
* Assumptions:
|
||||
* - DMA handle allocated by efm32_dmachannel()
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
size_t efm32_dmaresidual(DMA_HANDLE handle);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: efm32_dmacapable
|
||||
*
|
||||
* Description:
|
||||
* Check if the DMA controller can transfer data to/from given memory
|
||||
* address with the given configuration. This depends on the internal
|
||||
* connections in the ARM bus matrix of the processor. Note that this
|
||||
* only applies to memory addresses, it will return false for any peripheral
|
||||
* address.
|
||||
*
|
||||
* Returned value:
|
||||
* True, if transfer is possible.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_EFM32_DMACAPABLE
|
||||
bool efm32_dmacapable(uintptr_t maddr, uint32_t count, uint32_t ccr);
|
||||
#else
|
||||
# define efm32_dmacapable(maddr, count, ccr) (true)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: efm32_dmasample
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user