From 4dc00864c00e6921183e89bb2c4256fef09ff78d Mon Sep 17 00:00:00 2001 From: asterix Date: Tue, 30 Aug 2011 16:59:50 +0000 Subject: [PATCH] Add some fuction to read block from sd using dmac. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@5003 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/cpu/cortex-m3/drv/hsmci_sam3.c | 51 ++++++++++++++++++++++++++- bertos/cpu/cortex-m3/drv/hsmci_sam3.h | 15 +++++++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/bertos/cpu/cortex-m3/drv/hsmci_sam3.c b/bertos/cpu/cortex-m3/drv/hsmci_sam3.c index 445022e2..3cd4a4ea 100644 --- a/bertos/cpu/cortex-m3/drv/hsmci_sam3.c +++ b/bertos/cpu/cortex-m3/drv/hsmci_sam3.c @@ -69,6 +69,12 @@ cpu_relax(); \ } while (!(HSMCI_SR & BV(HSMCI_SR_CMDRDY))) + +#define HSMCI_WAIT_DATA_RDY()\ + do { \ + cpu_relax(); \ + } while (!(HSMCI_SR & BV(HSMCI_SR_RXRDY))) + #define HSMCI_ERROR() (HSMCI_SR & HSMCI_ERROR_MASK) #define HSMCI_HW_INIT() \ @@ -127,6 +133,37 @@ bool hsmci_sendCmd(uint8_t index, uint32_t argument, uint32_t reply_type) return 0; } +void hsmci_setBlkSize(size_t blk_size) +{ + HSMCI_DMA = BV(HSMCI_DMA_DMAEN); + HSMCI_BLKR = (blk_size << HSMCI_BLKR_BLKLEN_SHIFT); +} + +bool hsmci_read(uint32_t *buf, size_t word_num) +{ + ASSERT(buf); + ASSERT(!(DMAC_CHSR & BV(DMAC_CHSR_ENA0))); + + kprintf("DMAC status %08lx channel st %08lx\n", DMAC_EBCISR, DMAC_CHSR); + + DMAC_SADDR0 = 0x40000200U; + DMAC_DADDR0 = (uint32_t)buf; + DMAC_DSCR0 = 0; + + DMAC_CTRLA0 = word_num | DMAC_CTRLA_SRC_WIDTH_WORD | DMAC_CTRLA_DST_WIDTH_WORD; + DMAC_CTRLB0 = (BV(DMAC_CTRLB_SRC_DSCR) | DMAC_CTRLB_FC_PER2MEM_DMA_FC | + DMAC_CTRLB_SRC_INCR_FIXED | DMAC_CTRLB_DST_INCR_INCREMENTING | BV(DMAC_CTRLB_IEN)); + + ASSERT(!(DMAC_CHSR & BV(DMAC_CHSR_ENA0))); + DMAC_CHER = BV(DMAC_CHER_ENA0); + + while (!(HSMCI_SR & BV(HSMCI_SR_XFRDONE))) + cpu_relax(); + + DMAC_CHDR = BV(DMAC_CHDR_DIS0); + return 0; +} + void hsmci_init(Hsmci *hsmci) { (void)hsmci; @@ -141,11 +178,23 @@ void hsmci_init(Hsmci *hsmci) HSMCI_DTOR = 0xFF | HSMCI_DTOR_DTOMUL_1048576; HSMCI_CSTOR = 0xFF | HSMCI_CSTOR_CSTOMUL_1048576; - HSMCI_MR = HSMCI_CLK_DIV | ((0x7u << HSMCI_MR_PWSDIV_SHIFT) & HSMCI_MR_PWSDIV_MASK); + HSMCI_MR = HSMCI_CLK_DIV | ((0x7u << HSMCI_MR_PWSDIV_SHIFT) & HSMCI_MR_PWSDIV_MASK) | BV(HSMCI_MR_RDPROOF); HSMCI_SDCR = 0; HSMCI_CFG = BV(HSMCI_CFG_FIFOMODE) | BV(HSMCI_CFG_FERRCTRL); sysirq_setHandler(INT_HSMCI, hsmci_irq); HSMCI_CR = BV(HSMCI_CR_MCIEN); + HSMCI_DMA &= ~BV(HSMCI_DMA_DMAEN); + + //init DMAC + DMAC_EBCIDR = 0x3FFFFF; + DMAC_CHDR = BV(DMAC_CHDR_DIS0); + + DMAC_CFG0 = 0; + DMAC_CFG0 = BV(DMAC_CFG_SRC_H2SEL) | DMAC_CFG_FIFOCFG_ALAP_CFG | BV(DMAC_CFG_SOD); + + pmc_periphEnable(DMAC_ID); + DMAC_EN = BV(DMAC_EN_ENABLE); + //HSMCI_IER = BV(HSMCI_IER_RTOE); } diff --git a/bertos/cpu/cortex-m3/drv/hsmci_sam3.h b/bertos/cpu/cortex-m3/drv/hsmci_sam3.h index 9e41c016..f5cebdc7 100644 --- a/bertos/cpu/cortex-m3/drv/hsmci_sam3.h +++ b/bertos/cpu/cortex-m3/drv/hsmci_sam3.h @@ -38,8 +38,10 @@ #ifndef DRV_HSMCI_SAM3_H #define DRV_HSMCI_SAM3_H -#include #include +#include + +#include #define CMD8_V_RANGE_CHECK_PAT 0xAA #define CMD8_V_RANGE_27V_36V (0x100 | CMD8_V_RANGE_CHECK_PAT) @@ -87,9 +89,20 @@ INLINE void hsmci_disableIrq(void) HSMCI_IDR = BV(HSMCI_IER_RTOE); } +INLINE void hsmci_setBusWidth(size_t len) +{ + ASSERT((len == 8) || (len == 4) || (len == 1)); + HSMCI_SDCR = (len << HSMCI_SDCR_SDCBUS_SHIFT) & HSMCI_SDCR_SDCBUS_MASK; +} + void hsmci_readResp(void *resp, size_t len); bool hsmci_sendCmd(uint8_t index, uint32_t argument, uint32_t reply_type); +void hsmci_setBlkSize(size_t blk_size); +bool hsmci_read(uint32_t *buf, size_t word_num); + + + void hsmci_init(Hsmci *hsmci); #endif /* DRV_HSMCI_SAM3_H */ -- 2.25.1