X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fcpu%2Fcortex-m3%2Fdrv%2Fdmac_sam3.c;h=e97066860e792f27b7a6f0d882f0ea3a0a075ca0;hb=a535d0ea510fe25b0d27690272bfbed9b3187500;hp=21045b7f89e47f3979a216bbe773cd127b632544;hpb=cb96ac9be7c298f0e0634a048d938b68a3f57ed0;p=bertos.git diff --git a/bertos/cpu/cortex-m3/drv/dmac_sam3.c b/bertos/cpu/cortex-m3/drv/dmac_sam3.c index 21045b7f..e9706686 100644 --- a/bertos/cpu/cortex-m3/drv/dmac_sam3.c +++ b/bertos/cpu/cortex-m3/drv/dmac_sam3.c @@ -35,11 +35,6 @@ */ #include "dmac_sam3.h" - -#include "hsmci_sam3.h" -#include "hw/hw_sd.h" - -#include #include #include @@ -47,6 +42,10 @@ #include +#include + +#include + struct DmacCh { reg32_t *src; @@ -57,7 +56,7 @@ struct DmacCh reg32_t *ctrlb; }; -#define DMAC_CHANNEL_CNT 5 +#define DMAC_CHANNEL_CNT 6 struct DmacCh dmac_ch[] = { { @@ -110,65 +109,97 @@ struct DmacCh dmac_ch[] = }, }; -void dmac_setSources(Dmac *dmac, uint8_t ch, uint32_t src, uint32_t dst, size_t transfer_size) +/* We use event to signal the end of conversion */ +static Dmac dmac[DMAC_CHANNEL_CNT]; +static uint8_t dmac_ch_enabled; + +void dmac_setLLITransfer(int ch, DmacDesc *lli, uint32_t cfg) { - ASSERT(ch <= DMAC_CHANNEL_CNT); + DMAC_CHDR = BV(ch); + reg32_t reg = DMAC_EBCISR; + (void)reg; + *dmac_ch[ch].cfg = cfg | DMAC_CFG_FIFOCFG_ALAP_CFG | (0x1 << DMAC_CFG_AHB_PROT_SHIFT); + *dmac_ch[ch].desc = (uint32_t)lli; +} + +void dmac_setSources(int ch, uint32_t src, uint32_t dst) +{ DMAC_CHDR = BV(ch); *dmac_ch[ch].src = src; *dmac_ch[ch].dst = dst; *dmac_ch[ch].desc = 0; - dmac->transfer_size = transfer_size; } -void dmac_configureDmac(Dmac *dmac, uint8_t ch, uint32_t cfg, uint32_t ctrla, uint32_t ctrlb) +void dmac_configureDmac(int ch, size_t transfer_size, uint32_t cfg, uint32_t ctrla, uint32_t ctrlb) { - ASSERT(ch <= DMAC_CHANNEL_CNT); - DMAC_CHDR = BV(ch); - *dmac_ch[ch].cfg = cfg | DMAC_CFG_FIFOCFG_ALAP_CFG | (0x1 << DMAC_CFG_AHB_PROT_SHIFT); - *dmac_ch[ch].ctrla = ctrla | (dmac->transfer_size & DMAC_CTRLA_BTSIZE_MASK); - *dmac_ch[ch].ctrlb = ctrlb | BV(DMAC_CTRLB_IEN); + *dmac_ch[ch].cfg = cfg | DMAC_CFG_FIFOCFG_ALAP_CFG | (0x1 << DMAC_CFG_AHB_PROT_SHIFT) | BV(DMAC_CFG_SOD); + *dmac_ch[ch].ctrla = ctrla | (transfer_size & DMAC_CTRLA_BTSIZE_MASK); + *dmac_ch[ch].ctrlb = ctrlb & ~BV(DMAC_CTRLB_IEN); } -int dmac_start(Dmac *dmac, uint8_t ch) +int dmac_start(int ch) { - ASSERT(ch <= DMAC_CHANNEL_CNT); - if (DMAC_CHSR & BV(ch)) { - dmac->errors |= DMAC_ERR_CH_ALREDY_ON; + dmac[ch].errors |= DMAC_ERR_CH_ALREDY_ON; return -1; } - DMAC_CHER = BV(ch); + dmac_ch_enabled |= BV(ch); return 0; } -bool dmac_isDone(Dmac *dmac, uint8_t ch) +void dmac_stop(int ch) { - (void)dmac; - return (DMAC_EBCISR |= BV(ch)); + DMAC_CHDR = BV(ch); + dmac_ch_enabled &= ~BV(ch); } -bool dmac_waitDone(Dmac *dmac, uint8_t ch) +int dmac_error(int ch) { - (void)dmac; - while(!(DMAC_EBCISR |= BV(ch))) - cpu_relax(); - - return true; + uint32_t err = ((DMAC_EBCISR & 0x3F0000) | dmac[ch].errors); + dmac[ch].errors = 0; + return err; } static DECLARE_ISR(dmac_irq) { + uint32_t status = DMAC_EBCISR; + uint32_t irq_ch = (status & (((dmac_ch_enabled | + (dmac_ch_enabled << DMAC_EBCIDR_ERR0) >> DMAC_EBCIDR_ERR0) | + (dmac_ch_enabled << DMAC_EBCIDR_CBTC0) >> DMAC_EBCIDR_CBTC0) & 0xFF)); + if (irq_ch) + for(int i = 0; i < 6; i++) + { + if (BV(i) & irq_ch) + if(dmac[i].handler) + dmac[i].handler(status); + } } -void dmac_init(Dmac *dmac) +bool dmac_enableCh(int ch, dmac_handler_t handler) { - (void)dmac; + ASSERT(ch <= DMAC_CHANNEL_CNT); + + dmac_ch_enabled |= BV(ch); + if (handler) + { + dmac[ch].handler = handler; + DMAC_EBCIER |= (BV(ch) << DMAC_EBCIER_BTC0) | (BV(ch) << DMAC_EBCIDR_CBTC0) | (BV(ch) << DMAC_EBCIDR_ERR0); + kprintf("Init dmac ch[%08lx]\n", DMAC_EBCIMR); + } + + return true; +} + +void dmac_init(void) +{ + dmac_ch_enabled = 0; + memset(&dmac, 0, sizeof(dmac)); //init DMAC DMAC_EBCIDR = 0x3FFFFF; @@ -176,5 +207,6 @@ void dmac_init(Dmac *dmac) pmc_periphEnable(DMAC_ID); DMAC_EN = BV(DMAC_EN_ENABLE); + sysirq_setHandler(INT_DMAC, dmac_irq); }