From 442fdad4adb197550693c24747493799ae293aea Mon Sep 17 00:00:00 2001 From: asterix Date: Fri, 9 Sep 2011 16:51:56 +0000 Subject: [PATCH] Remove context from api, to keep it more simple. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@5043 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/cpu/cortex-m3/drv/dmac_sam3.c | 130 ++++++++++++++++++--------- bertos/cpu/cortex-m3/drv/dmac_sam3.h | 30 ++++--- 2 files changed, 103 insertions(+), 57 deletions(-) diff --git a/bertos/cpu/cortex-m3/drv/dmac_sam3.c b/bertos/cpu/cortex-m3/drv/dmac_sam3.c index 202b4f37..d0b8128c 100644 --- a/bertos/cpu/cortex-m3/drv/dmac_sam3.c +++ b/bertos/cpu/cortex-m3/drv/dmac_sam3.c @@ -42,6 +42,8 @@ #include +#include + #include struct DmacCh @@ -107,113 +109,153 @@ struct DmacCh dmac_ch[] = }, }; -void dmac_setSourcesLLI(Dmac *dmac, DmacDesc *lli, uint32_t src, uint32_t dst, uint32_t desc) + +/* We use event to signal the end of conversion */ +static Event data_ready; +static Dmac dmac[DMAC_CHANNEL_CNT]; +static uint8_t dmac_ch_enabled; + +void dmac_setSourcesLLI(int ch, DmacDesc *lli, uint32_t src, uint32_t dst, uint32_t desc) { ASSERT(lli); - DMAC_CHDR = BV(dmac->ch); + DMAC_CHDR = BV(ch); lli->src_addr = src; lli->dst_addr = dst; lli->dsc_addr = desc; } -void dmac_configureDmacLLI(Dmac *dmac, DmacDesc *lli, size_t transfer_size, uint32_t cfg, uint32_t ctrla, uint32_t ctrlb) +void dmac_configureDmacLLI(int ch, DmacDesc *lli, size_t transfer_size, uint32_t cfg, uint32_t ctrla, uint32_t ctrlb) { - DMAC_CHDR = BV(dmac->ch); + DMAC_CHDR = BV(ch); - *dmac_ch[dmac->ch].cfg = cfg | DMAC_CFG_FIFOCFG_ALAP_CFG | (0x1 << DMAC_CFG_AHB_PROT_SHIFT); + *dmac_ch[ch].cfg = cfg | DMAC_CFG_FIFOCFG_ALAP_CFG | (0x1 << DMAC_CFG_AHB_PROT_SHIFT); lli->ctrla = ctrla | (transfer_size & DMAC_CTRLA_BTSIZE_MASK); - lli->ctrlb = ctrlb | BV(DMAC_CTRLB_IEN); - *dmac_ch[dmac->ch].desc = (uint32_t)lli; + lli->ctrlb = ctrlb & ~BV(DMAC_CTRLB_IEN); + *dmac_ch[ch].desc = (uint32_t)lli; } -void dmac_setSources(Dmac *dmac, uint32_t src, uint32_t dst) +void dmac_setSources(int ch, uint32_t src, uint32_t dst) { - DMAC_CHDR = BV(dmac->ch); + DMAC_CHDR = BV(ch); - *dmac_ch[dmac->ch].src = src; - *dmac_ch[dmac->ch].dst = dst; - *dmac_ch[dmac->ch].desc = 0; + *dmac_ch[ch].src = src; + *dmac_ch[ch].dst = dst; + *dmac_ch[ch].desc = 0; } -void dmac_configureDmac(Dmac *dmac, size_t transfer_size, 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) { - DMAC_CHDR = BV(dmac->ch); + DMAC_CHDR = BV(ch); - *dmac_ch[dmac->ch].cfg = cfg | DMAC_CFG_FIFOCFG_ALAP_CFG | (0x1 << DMAC_CFG_AHB_PROT_SHIFT); - *dmac_ch[dmac->ch].ctrla = ctrla | (transfer_size & DMAC_CTRLA_BTSIZE_MASK); - *dmac_ch[dmac->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) +int dmac_start(int ch) { - if (DMAC_CHSR & BV(dmac->ch)) + 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(dmac->ch); + DMAC_CHER = BV(ch); return 0; } +int dmac_stop(int ch) +{ + DMAC_CHDR = BV(ch); + return 0; +} -bool dmac_isLLIDone(Dmac *dmac) +bool dmac_isLLIDone(int ch) { - return (DMAC_EBCIMR |= (BV(dmac->ch) << DMAC_EBCISR_CBTC0)); + return (DMAC_EBCIMR |= (BV(ch) << DMAC_EBCISR_CBTC0)); } -bool dmac_waitLLIDone(Dmac *dmac) +bool dmac_waitLLIDone(int ch) { - while(!(DMAC_EBCIMR |= (BV(dmac->ch) << DMAC_EBCISR_CBTC0))) + while(!(DMAC_EBCIMR |= (BV(ch) << DMAC_EBCISR_CBTC0))) cpu_relax(); - DMAC_CHDR = BV(dmac->ch); + DMAC_CHDR = BV(ch); return true; } -bool dmac_isDone(Dmac *dmac) +bool dmac_isDone(int ch) { - return (DMAC_EBCIMR |= BV(dmac->ch)); + //event_wait(&data_ready); + return (*dmac_ch[ch].ctrla & BV(31));//(DMAC_CHSR |= (BV(dmac->ch) << DMAC_CHSR_EMPT0)); } -bool dmac_waitDone(Dmac *dmac) +bool dmac_waitDone(int ch) { - while(!(DMAC_EBCIMR |= BV(dmac->ch))) - cpu_relax(); - - DMAC_CHDR = BV(dmac->ch); + event_wait(&data_ready); + DMAC_CHDR = BV(ch); return true; } -int dmac_error(Dmac *dmac) +int dmac_error(int ch) { - uint32_t err = ((DMAC_EBCISR & 0x3F0000) | dmac->errors); - dmac->errors = 0; + 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; - if(status & 0x3f3f) + uint32_t irq_ch = (status & dmac_ch_enabled) & 0xFF; + //kprintf(" %08lx %08lx\n", status, irq_ch); + if (irq_ch) + for(int i = 0; i < 8; i++) + { + if (BV(i) & irq_ch) + if(dmac[i].handler) + dmac[i].handler(); + } +/* + irq_ch = (status & (dmac_ch_enabled << DMAC_EBCIDR_CBTC0)) >> DMAC_EBCIDR_CBTC0; + //kprintf("c %08lx %08lx\n", status, irq_ch); + if (irq_ch) + for(int i = 0; i < 8; i++) + { + if (BV(i) & irq_ch) + if(dmac[i].handler) + dmac[i].handler(); + } +*/ + +} + +bool dmac_enableCh(int ch, dmac_handler_t handler) +{ + ASSERT(ch <= DMAC_CHANNEL_CNT); + + dmac_ch_enabled |= BV(ch); + if (handler) { - kputs("Ends\n"); + dmac[ch].handler = handler; + DMAC_EBCIER |= (BV(ch) << DMAC_EBCIER_BTC0) | (BV(ch) << DMAC_EBCIDR_CBTC0); + kprintf("Init dmac ch[%08lx]\n", DMAC_EBCIMR); } + return true; } -void dmac_init(Dmac *dmac, int channel) +void dmac_init(void) { - ASSERT(channel <= DMAC_CHANNEL_CNT); - memset(dmac, 0, sizeof(dmac)); - dmac->ch = channel; + dmac_ch_enabled = 0; + memset(&dmac, 0, sizeof(dmac)); + //init DMAC DMAC_EBCIDR = 0x3FFFFF; DMAC_CHDR = 0x1F; pmc_periphEnable(DMAC_ID); DMAC_EN = BV(DMAC_EN_ENABLE); - sysirq_setHandler(INT_DMAC, dmac_irq); - DMAC_EBCIER = (BV(dmac->ch) << DMAC_EBCIER_BTC0) | (BV(dmac->ch) << DMAC_EBCIDR_BTC0); + sysirq_setHandler(INT_DMAC, dmac_irq); } diff --git a/bertos/cpu/cortex-m3/drv/dmac_sam3.h b/bertos/cpu/cortex-m3/drv/dmac_sam3.h index eb87989c..2fb192df 100644 --- a/bertos/cpu/cortex-m3/drv/dmac_sam3.h +++ b/bertos/cpu/cortex-m3/drv/dmac_sam3.h @@ -41,6 +41,9 @@ #include #include +#include + +typedef void (*dmac_handler_t)(void); /** * DMA Transfer Descriptor as well as Linked List Item @@ -57,25 +60,26 @@ typedef struct DmacDesc typedef struct Dmac { DmacDesc lli; - uint8_t ch; uint8_t errors; size_t transfer_size; + dmac_handler_t handler; } Dmac; #define DMAC_ERR_CH_ALREDY_ON BV(0) -void dmac_setSourcesLLI(Dmac *dmac, DmacDesc *lli, uint32_t src, uint32_t dst, uint32_t desc); -void dmac_configureDmacLLI(Dmac *dmac, DmacDesc *lli, size_t transfer_size, uint32_t cfg, uint32_t ctrla, uint32_t ctrlb); -bool dmac_isLLIDone(Dmac *dmac); -bool dmac_waitLLIDone(Dmac *dmac); - -void dmac_setSources(Dmac *dmac, uint32_t src, uint32_t dst); -void dmac_configureDmac(Dmac *dmac, size_t transfer_size, uint32_t cfg, uint32_t ctrla, uint32_t ctrlb); -int dmac_start(Dmac *dmac); -bool dmac_isDone(Dmac *dmac); -bool dmac_waitDone(Dmac *dmac); -int dmac_error(Dmac *dmac); +void dmac_setSourcesLLI(int ch, DmacDesc *lli, uint32_t src, uint32_t dst, uint32_t desc); +void dmac_configureDmacLLI(int ch, DmacDesc *lli, size_t transfer_size, uint32_t cfg, uint32_t ctrla, uint32_t ctrlb); +bool dmac_isLLIDone(int ch); +bool dmac_waitLLIDone(int ch); -void dmac_init(Dmac *dmac, int channel); +void dmac_setSources(int ch, uint32_t src, uint32_t dst); +void dmac_configureDmac(int ch, size_t transfer_size, uint32_t cfg, uint32_t ctrla, uint32_t ctrlb); +int dmac_start(int ch); +int dmac_stop(int ch); +bool dmac_isDone(int ch); +bool dmac_waitDone(int ch); +int dmac_error(int ch); +bool dmac_enableCh(int ch, dmac_handler_t handler); +void dmac_init(void); #endif /* DRV_DMAC_SAM3_H */ -- 2.25.1