diff --git a/arch/arm/include/samdl/chip.h b/arch/arm/include/samdl/chip.h index 70e1de0a38c..a2b49e63cff 100644 --- a/arch/arm/include/samdl/chip.h +++ b/arch/arm/include/samdl/chip.h @@ -84,6 +84,7 @@ # define SAMDL_FLASH_SIZE (16*1024) /* 16KB */ # define SAMDL_SRAM0_SIZE (2*1024) /* 2KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ #elif defined(CONFIG_ARCH_CHIP_SAMD20E15) @@ -96,6 +97,7 @@ # define SAMDL_FLASH_SIZE (32*1024) /* 32KB */ # define SAMDL_SRAM0_SIZE (4*1024) /* 4KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ #elif defined(CONFIG_ARCH_CHIP_SAMD20E16) @@ -108,6 +110,7 @@ # define SAMDL_FLASH_SIZE (64*1024) /* 64KB */ # define SAMDL_SRAM0_SIZE (8*1024) /* 8KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ #elif defined(CONFIG_ARCH_CHIP_SAMD20E17) @@ -120,6 +123,7 @@ # define SAMDL_FLASH_SIZE (128*1024) /* 128KB */ # define SAMDL_SRAM0_SIZE (16*1024) /* 16KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ #elif defined(CONFIG_ARCH_CHIP_SAMD20E18) @@ -132,6 +136,7 @@ # define SAMDL_FLASH_SIZE (256*1024) /* 256KB */ # define SAMDL_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ #elif defined(CONFIG_ARCH_CHIP_SAMD20G14) @@ -144,6 +149,7 @@ # define SAMDL_FLASH_SIZE (16*1024) /* 16KB */ # define SAMDL_SRAM0_SIZE (2*1024) /* 2KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ #elif defined(CONFIG_ARCH_CHIP_SAMD20G15) @@ -156,6 +162,7 @@ # define SAMDL_FLASH_SIZE (32*1024) /* 32KB */ # define SAMDL_SRAM0_SIZE (4*1024) /* 4KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ #elif defined(CONFIG_ARCH_CHIP_SAMD20G16) @@ -168,6 +175,7 @@ # define SAMDL_FLASH_SIZE (64*1024) /* 64KB */ # define SAMDL_SRAM0_SIZE (8*1024) /* 8KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ #elif defined(CONFIG_ARCH_CHIP_SAMD20G17) @@ -180,6 +188,7 @@ # define SAMDL_FLASH_SIZE (128*1024) /* 128KB */ # define SAMDL_SRAM0_SIZE (16*1024) /* 16KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ #elif defined(CONFIG_ARCH_CHIP_SAMD20G18) @@ -192,6 +201,7 @@ # define SAMDL_FLASH_SIZE (256*1024) /* 256KB */ # define SAMDL_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ #elif defined(CONFIG_ARCH_CHIP_SAMD20J14) @@ -204,6 +214,7 @@ # define SAMDL_FLASH_SIZE (16*1024) /* 16KB */ # define SAMDL_SRAM0_SIZE (2*1024) /* 2KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ #elif defined(CONFIG_ARCH_CHIP_SAMD20J15) @@ -216,6 +227,7 @@ # define SAMDL_FLASH_SIZE (32*1024) /* 32KB */ # define SAMDL_SRAM0_SIZE (4*1024) /* 4KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ #elif defined(CONFIG_ARCH_CHIP_SAMD20J16) @@ -228,6 +240,7 @@ # define SAMDL_FLASH_SIZE (64*1024) /* 64KB */ # define SAMDL_SRAM0_SIZE (8*1024) /* 8KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ #elif defined(CONFIG_ARCH_CHIP_SAMD20J17) @@ -240,6 +253,7 @@ # define SAMDL_FLASH_SIZE (128*1024) /* 128KB */ # define SAMDL_SRAM0_SIZE (16*1024) /* 16KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ #elif defined(CONFIG_ARCH_CHIP_SAMD20J18) @@ -252,6 +266,7 @@ # define SAMDL_FLASH_SIZE (256*1024) /* 256KB */ # define SAMDL_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAMDL_LPRAM_SIZE (0*1024) /* None */ #else @@ -383,6 +398,7 @@ # define SAMDL_FLASH_SIZE (32*1024) /* 32KB */ # define SAMDL_FLASHRWW_SIZE (1*1024) /* 1KB */ # define SAMDL_SRAM0_SIZE (4*1024) /* 4KB */ +# define SAMDL_LPRAM_SIZE (2*1024) /* 2KB */ /* TCC waveform outputs */ @@ -400,6 +416,7 @@ # define SAMDL_FLASH_SIZE (64*1024) /* 64KB */ # define SAMDL_FLASHRWW_SIZE (2*1024) /* 2KB */ # define SAMDL_SRAM0_SIZE (8*1024) /* 8KB */ +# define SAMDL_LPRAM_SIZE (4*1024) /* 4KB */ /* TCC waveform outputs */ @@ -417,6 +434,7 @@ # define SAMDL_FLASH_SIZE (128*1024) /* 128KB */ # define SAMDL_FLASHRWW_SIZE (4*1024) /* 4KB */ # define SAMDL_SRAM0_SIZE (16*1024) /* 16KB */ +# define SAMDL_LPRAM_SIZE (8*1024) /* 8KB */ /* TCC waveform outputs */ @@ -434,6 +452,7 @@ # define SAMDL_FLASH_SIZE (256*1024) /* 256KB */ # define SAMDL_FLASHRWW_SIZE (8*1024) /* 8KB */ # define SAMDL_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAMDL_LPRAM_SIZE (8*1024) /* 8KB */ /* TCC waveform outputs */ @@ -451,6 +470,7 @@ # define SAMDL_FLASH_SIZE (64*1024) /* 64KB */ # define SAMDL_FLASHRWW_SIZE (2*1024) /* 2KB */ # define SAMDL_SRAM0_SIZE (8*1024) /* 8KB */ +# define SAMDL_LPRAM_SIZE (4*1024) /* 4KB */ /* TCC waveform outputs */ @@ -465,9 +485,10 @@ /* Internal memory */ -# define SAMDL_FLASH_SIZE (128*1024) /* 128KB */ -# define SAMDL_FLASHRWW_SIZE (4*1024) /* 4KB */ -# define SAMDL_SRAM0_SIZE (16*1024) /* 16KB */ +# define SAMDL_FLASH_SIZE (128*1024) /* 128KB */ +# define SAMDL_FLASHRWW_SIZE (4*1024) /* 4KB */ +# define SAMDL_SRAM0_SIZE (16*1024) /* 16KB */ +# define SAMDL_LPRAM_SIZE (8*1024) /* 8KB */ /* TCC waveform outputs */ @@ -482,9 +503,10 @@ /* Internal memory */ -# define SAMDL_FLASH_SIZE (256*1024) /* 256KB */ -# define SAMDL_FLASHRWW_SIZE (8*1024) /* 8KB */ -# define SAMDL_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAMDL_FLASH_SIZE (256*1024) /* 256KB */ +# define SAMDL_FLASHRWW_SIZE (8*1024) /* 8KB */ +# define SAMDL_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAMDL_LPRAM_SIZE (8*1024) /* 8KB */ /* TCC waveform outputs */ @@ -502,6 +524,7 @@ # define SAMDL_FLASH_SIZE (64*1024) /* 64KB */ # define SAMDL_FLASHRWW_SIZE (2*1024) /* 2KB */ # define SAMDL_SRAM0_SIZE (8*1024) /* 8KB */ +# define SAMDL_LPRAM_SIZE (8*1024) /* 4KB */ /* TCC waveform outputs */ @@ -519,6 +542,7 @@ # define SAMDL_FLASH_SIZE (128*1024) /* 128KB */ # define SAMDL_FLASHRWW_SIZE (4*1024) /* 4KB */ # define SAMDL_SRAM0_SIZE (16*1024) /* 16KB */ +# define SAMDL_LPRAM_SIZE (8*1024) /* 8KB */ /* TCC waveform outputs */ @@ -536,6 +560,7 @@ # define SAMDL_FLASH_SIZE (256*1024) /* 256KB */ # define SAMDL_FLASHRWW_SIZE (8*1024) /* 8KB */ # define SAMDL_SRAM0_SIZE (32*1024) /* 32KB */ +# define SAMDL_LPRAM_SIZE (8*1024) /* 8KB */ /* TCC waveform outputs */ diff --git a/arch/arm/src/sam34/sam_dmac.c b/arch/arm/src/sam34/sam_dmac.c index 07430f7cb4c..63b46ada61d 100644 --- a/arch/arm/src/sam34/sam_dmac.c +++ b/arch/arm/src/sam34/sam_dmac.c @@ -1384,7 +1384,7 @@ void weak_function up_dmainitialize(void) /* Initialize semaphores */ sem_init(&g_chsem, 0, 1); - sem_init(&g_dsem, 0, SAM34_NDMACHAN); + sem_init(&g_dsem, 0, CONFIG_SAM34_NLLDESC); } /**************************************************************************** diff --git a/arch/arm/src/samdl/Kconfig b/arch/arm/src/samdl/Kconfig index a6a34b5e70d..124e886798b 100644 --- a/arch/arm/src/samdl/Kconfig +++ b/arch/arm/src/samdl/Kconfig @@ -241,6 +241,7 @@ config ARCH_FAMILY_SAMD20J config ARCH_FAMILY_SAML21 bool default n + selest SAMDL_HAVE_DMAC config ARCH_FAMILY_SAML21E bool @@ -261,6 +262,12 @@ config ARCH_FAMILY_SAML21J select SAMDL_HAVE_TC3 select SAMDL_HAVE_TC5 +menu "SAMD/L Peripheral Support" + +config SAMDL_HAVE_DMAC + bool + default n + config SAMDL_HAVE_SERCOM4 bool default n @@ -289,8 +296,6 @@ config SAMDL_HAVE_TC7 bool default n -menu "SAMD/L Peripheral Support" - config SAMDL_AC bool "Analog Comparator" default n @@ -307,7 +312,7 @@ config SAMDL_DMAC bool "DMA Controller" default n select ARCH_DMA - depends on EXPERIMENTAL + depends on SAMDL_HAVE_DMAC && EXPERIMENTAL config SAMDL_EVSYS bool "Event System" @@ -414,6 +419,11 @@ config SAMDL_SERCOM0_ISUSART endchoice +config SAMDL_DMAC_NDESC + int "Number of DMA Descriptors" + default 64 + depends on SAMDL_DMAC + choice prompt "SERCOM1 mode" default SAMDL_SERCOM1_ISUSART diff --git a/arch/arm/src/samdl/chip/saml_dmac.h b/arch/arm/src/samdl/chip/saml_dmac.h index 2f3b31ede12..654e021681b 100644 --- a/arch/arm/src/samdl/chip/saml_dmac.h +++ b/arch/arm/src/samdl/chip/saml_dmac.h @@ -365,6 +365,16 @@ trigger */ /******************************************************************************************** * Public Types ********************************************************************************************/ +/* DMA descriptor */ + +struct dma_desc_s +{ + uint16_t btctrl; /* Block Transfer Control Register */ + uint16_t btcnt; /* Block Transfer Count Register */ + uint32_t srcaddr; /* Block Transfer Source Address Register */ + uint32_t dstaddr; /* Block Transfer Destination Address Register */ + uint32_t descaddr; /* Next Address Descriptor Register */ +}; /******************************************************************************************** * Public Data diff --git a/arch/arm/src/samdl/sam_dmac.c b/arch/arm/src/samdl/sam_dmac.c index 9bf9612cc5e..820417e8cdb 100644 --- a/arch/arm/src/samdl/sam_dmac.c +++ b/arch/arm/src/samdl/sam_dmac.c @@ -74,6 +74,12 @@ # warning "SAM3/4 DMA enabled but CONFIG_ARCH_DMA disabled" #endif +/* Number of DMA descriptors in LPRAM */ + +#ifndef CONFIG_SAMDL_DMAC_NDESC +# define CONFIG_SAMDL_DMAC_NDESC 64 +#endif + /**************************************************************************** * Private Types ****************************************************************************/ @@ -82,25 +88,56 @@ struct sam_dmach_s { - uint8_t dc_chan; /* DMA channel number (0-6) */ - bool dc_inuse; /* TRUE: The DMA channel is in use */ - 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 */ + uint8_t dc_chan; /* DMA channel number (0-6) */ + bool dc_inuse; /* TRUE: The DMA channel is in use */ + 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 */ + struct dma_desc_s *llhead; /* DMA link list head */ + struct dma_desc_s *lltail; /* DMA link list head */ }; +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void sam_takechsem(void); +static inline void sam_givechsem(void); +static void sam_takedsem(void); +static inline void sam_givedsem(void); +static void sam_dmaterminate(struct sam_dmach_s *dmach, int result); +static int sam_dmainterrupt(int irq, void *context); +static struct dma_desc_s * + sam_allocdesc(struct sam_dmach_s *dmach, + struct dma_desc_s *prev, uint16_t btctrl, uint16_t btcnt, + 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 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 ****************************************************************************/ -/* These semaphores protect the DMA channel tables */ +/* These semaphores protect the DMA channel and descriptor tables */ static sem_t g_chsem; +static sem_t g_dsem; /* This array describes the state of each DMA channel */ static struct sam_dmach_s g_dmach[SAMDL_NDMACHAN]; +/* DMA descriptors positioned in LPRAM */ + +static struct dma_desc_s g_dma_desc[CONFIG_SAMDL_DMAC_NDESC] + __attribute__ ((section(".lpram"),aligned(16))); + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -132,6 +169,33 @@ static inline void sam_givechsem(void) (void)sem_post(&g_chsem); } +/**************************************************************************** + * Name: sam_takedsem() and sam_givedsem() + * + * Description: + * Used to wait for availability of descriptors in the descriptor table. + * + ****************************************************************************/ + +static void sam_takedsem(void) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&g_dsem) != 0) + { + /* The only case that an error should occur here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +static inline void sam_givedsem(void) +{ + (void)sem_post(&g_dsem); +} + /**************************************************************************** * Name: sam_dmaterminate * @@ -148,8 +212,9 @@ static void sam_dmaterminate(struct sam_dmach_s *dmach, int result) /* Disable the channel */ #warning Missing logic - /* Free the resources */ -#warning Missing logic + /* Free the linklist */ + + sam_freelinklist(dmach); /* Perform the DMA complete callback */ @@ -246,6 +311,141 @@ static size_t sam_addrincr(struct sam_dmach_s *dmach) } #endif +/**************************************************************************** + * Name: sam_allocdesc + * + * Description: + * Allocate and add one descriptor to the DMA channel's link list. + * + * NOTE: link list entries are freed by the DMA interrupt handler. However, + * since the setting/clearing of the 'in use' indication is atomic, no + * special actions need be performed. It would be a good thing to add logic + * to handle the case where all of the entries are exhausted and we could + * wait for some to be freed by the interrupt handler. + * + ****************************************************************************/ + +static struct dma_desc_s * +sam_allocdesc(struct sam_dmach_s *dmach, struct dma_desc_s *prev, + uint16_t btctrl, uint16_t btcnt, uint32_t srcaddr, + uint32_t dstaddr) +{ + struct dma_desc_s *desc = NULL; + int i; + + /* Sanity check -- src == 0 is the indication that the link is unused. + * Obviously setting it to zero would break that usage. + */ + +#ifdef CONFIG_DEBUG + if (src != 0) +#endif + { + /* Table a descriptor table semaphore count. When we get one, then there + * is at least one free descriptor in the table and it is ours. + */ + + sam_takedsem(); + + /* Examine each link list entry to find an available one -- i.e., one + * with src == 0. That src field is set to zero by the DMA transfer + * complete interrupt handler. The following should be safe because + * that is an atomic operation. + */ + + sam_takechsem(); + for (i = 0; i < CONFIG_SAMDL_DMAC_NDESC; i++) + { + if (g_dma_desc[i].srcaddr == 0) + { + /* We have it. Initialize the new link list entry */ + + desc = &g_dma_desc[i]; + desc->btctrl = btctrl; /* Block Transfer Control Register */ + desc->btcnt = btcnt; /* Block Transfer Count Register */ + desc->srcaddr = srcaddr; /* Block Transfer Source Address Register */ + desc->dstaddr = dstaddr; /* Block Transfer Destination Address Register */ + desc->descaddr = 0; /* Next Address Descriptor Register */ + + /* And then hook it at the tail of the link list */ + + if (!prev) + { + /* There is no previous link. This is the new head of + * the list + */ + + DEBUGASSERT(dmach->llhead == NULL && dmach->lltail == NULL); + dmach->llhead = desc; + } + else + { + DEBUGASSERT(dmach->llhead != NULL && dmach->lltail == prev); + + /* When the second link is added to the list, that is the + * cue that we are going to do the link list transfer. + */ +#warning Missing logic + + /* Link the previous tail to the new tail */ + + prev->descaddr = (uint32_t)desc; + } + + /* In any event, this is the new tail of the list. */ +#warning Missing logic + + dmach->lltail = desc; + break; + } + } + + /* Because we hold a count from the counting semaphore, the above + * search loop should always be successful. + */ + + sam_givechsem(); + DEBUGASSERT(desc != NULL); + } + + return desc; +} + +/**************************************************************************** + * Name: sam_freelinklist + * + * Description: + * Free all descriptors in the DMA channel's link list. + * + * NOTE: Called from the DMA interrupt handler. + * + ****************************************************************************/ + +static void sam_freelinklist(struct sam_dmach_s *dmach) +{ + struct dma_desc_s *desc; + struct dma_desc_s *next; + + /* Get the head of the link list and detach the link list from the DMA + * channel + */ + + desc = dmach->llhead; + dmach->llhead = NULL; + dmach->lltail = NULL; + + /* Reset each descriptor in the link list (thereby freeing them) */ + + while (desc != NULL) + { + next = (struct dma_desc_s *)desc->descaddr; + DEBUGASSERT(desc->src != 0); + memset(desc, 0, sizeof(struct dma_desc_s)); + sam_givedsem(); + desc = next; + } +} + /**************************************************************************** * Name: sam_maxtransfer * @@ -273,7 +473,18 @@ static size_t sam_maxtransfer(struct sam_dmach_s *dmach) static int sam_txbuffer(struct sam_dmach_s *dmach, uint32_t paddr, uint32_t maddr, size_t nbytes) { + uint16_t btctrl; + uint16_t btcnt; + #warning Missing logic + + /* Add the new link list entry */ + + if (!sam_allocdesc(dmach, dmach->lltail, btctrl, btcnt, maddr, paddr)) + { + return -ENOMEM; + } + return OK; } @@ -290,7 +501,18 @@ static int sam_txbuffer(struct sam_dmach_s *dmach, uint32_t paddr, static int sam_rxbuffer(struct sam_dmach_s *dmach, uint32_t paddr, uint32_t maddr, size_t nbytes) { + uint16_t btctrl; + uint16_t btcnt; + #warning Missing logic + + /* Add the new link list entry */ + + if (!sam_allocdesc(dmach, dmach->lltail, btctrl, btcnt, maddr, paddr)) + { + return -ENOMEM; + } + return OK; } @@ -302,8 +524,10 @@ static int sam_rxbuffer(struct sam_dmach_s *dmach, uint32_t paddr, * ****************************************************************************/ -static inline int sam_single(struct sam_dmach_s *dmach) +static int sam_single(struct sam_dmach_s *dmach) { + struct dma_desc_s *llhead = dmach->llhead; + /* Clear any pending interrupts from any previous DMAC transfer. * * REVISIT: If DMAC interrupts are disabled at the NVIKC, then reading the @@ -313,6 +537,7 @@ static inline int sam_single(struct sam_dmach_s *dmach) /* Set up the DMA */ #warning Missing logic + DEBUGASSERT(llhead != NULL && llhead->src != 0); /* Enable the channel */ #warning Missing logic @@ -331,8 +556,10 @@ static inline int sam_single(struct sam_dmach_s *dmach) * ****************************************************************************/ -static inline int sam_multiple(struct sam_dmach_s *dmach) +static int sam_multiple(struct sam_dmach_s *dmach) { + struct dma_desc_s *llhead = dmach->llhead; + /* Clear any pending interrupts from any previous DMAC transfer. * * REVISIT: If DMAC interrupts are disabled at the NVIKC, then reading the @@ -342,6 +569,8 @@ static inline int sam_multiple(struct sam_dmach_s *dmach) /* Set up the initial DMA */ #warning Missing logic + DEBUGASSERT(llhead != NULL && llhead->src != 0); + /* Enable the channel */ #warning Missing logic @@ -375,6 +604,7 @@ void weak_function up_dmainitialize(void) /* Initialize global semaphores */ sem_init(&g_chsem, 0, 1); + sem_init(&g_dsem, 0, CONFIG_SAMDL_DMAC_NDESC); /* Initialized the DMA channel table */ @@ -676,9 +906,11 @@ int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg) dmavdbg("dmach: %p callback: %p arg: %p\n", dmach, callback, arg); DEBUGASSERT(dmach != NULL); - /* Verify that the DMA has been setup */ -#warning Missing logic + /* Verify that the DMA has been setup (i.e., at least one entry in the + * link list). + */ + if (dmach->llhead) { /* Save the callback info. This will be invoked when the DMA completes */ @@ -686,9 +918,8 @@ int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg) dmach->dc_arg = arg; /* Is this a single block transfer? Or a multiple block transfer? */ -#warning Missing logic - if (true) + if (dmach->llhead == dmach->lltail) { ret = sam_single(dmach); } @@ -766,16 +997,6 @@ void sam_dmasample(DMA_HANDLE handle, struct sam_dmaregs_s *regs) regs->chctrlb = getreg32(SAM_DMAC_CHCTRLB); /* Channel Control B Register */ regs->chintflag = getreg8(SAM_DMAC_CHINTFLAG); /* Channel Interrupt Flag Status and Clear Register */ regs->chstatus = getreg8(SAM_DMAC_CHSTATUS); /* Channel Status Register */ - - /* LPSRAM Registers Relative to BASEADDR or WRBADDR */ -#warning How do we get the base address - - regs->btctrl = getreg16(base + SAM_LPSRAM_BTCTRL_OFFSET); - regs->btcnt = getreg16(base + SAM_LPSRAM_BTCNT_OFFSET); - regs->srcaddr = getreg32(base + SAM_LPSRAM_SRCADDR_OFFSET); - regs->dstaddr = getreg32(base + SAM_LPSRAM_DSTADDR_OFFSET); - regs->descaddr = getreg32(base + SAM_LPSRAM_DESCADDR_OFFSET); - irqrestore(flags); } #endif /* CONFIG_DEBUG_DMA */ @@ -812,14 +1033,6 @@ void sam_dmadump(DMA_HANDLE handle, const struct sam_dmaregs_s *regs, regs->chid, regs->chctrla, regs->chctrlb, regs->chintflag, dmadbg(" CHSTATUS: %02x\n", regs->chstatus); - - /* LPSRAM Registers Relative to BASEADDR or WRBADDR */ -#warning How do we get the base address - - dmadbg(" LPSRAM Values:\n"); - dmadbg(" BTCTRL: %04x BTCNT: %04x SRCADDR: %08x DSTADDR: %08x\n", - regs->btctrl, regs->btcnt, regs->srcaddr, regs->dstaddr); - dmadbg(" DESCADDR: %08x\n", regs->descaddr); } #endif /* CONFIG_DEBUG_DMA */ #endif /* CONFIG_SAMDL_DMAC */ diff --git a/configs/saml21-xplained/scripts/flash.ld b/configs/saml21-xplained/scripts/flash.ld index 51bda76bb31..f97540fff42 100755 --- a/configs/saml21-xplained/scripts/flash.ld +++ b/configs/saml21-xplained/scripts/flash.ld @@ -34,13 +34,15 @@ ****************************************************************************/ /* The ATSAML21J18A has 256KB of FLASH beginning at address 0x0000:0000 and - * 32KB of SRAM beginning at address 0x2000:0000 + * 32KB of SRAM beginning at address 0x2000:0000. There is also 8KB low- + * power SRAM at 0x30000000 that may be used by the DMAC. */ MEMORY { flash (rx) : ORIGIN = 0x00000000, LENGTH = 256K sram (rwx) : ORIGIN = 0x20000000, LENGTH = 32K + lpram (rw) : ORIGIN = 0x30000000, LENGTH = 8K } OUTPUT_ARCH(arm) @@ -107,6 +109,10 @@ SECTIONS _ebss = ABSOLUTE(.); } > sram + .lpram : { + *(.lpram) + } > lpram + /* Stabs debugging sections. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) }