Remove context from api, to keep it more simple.
authorasterix <asterix@38d2e660-2303-0410-9eaa-f027e97ec537>
Fri, 9 Sep 2011 16:51:56 +0000 (16:51 +0000)
committerasterix <asterix@38d2e660-2303-0410-9eaa-f027e97ec537>
Fri, 9 Sep 2011 16:51:56 +0000 (16:51 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@5043 38d2e660-2303-0410-9eaa-f027e97ec537

bertos/cpu/cortex-m3/drv/dmac_sam3.c
bertos/cpu/cortex-m3/drv/dmac_sam3.h

index 202b4f37259b5ce08df04dab6a714a2ee9d54934..d0b8128c0bc6e2b3c02953a113811a7e9e208c5f 100644 (file)
@@ -42,6 +42,8 @@
 
 #include <io/cm3.h>
 
+#include <mware/event.h>
+
 #include <string.h>
 
 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);
 }
index eb87989c016de100fff67d8e05e215e7c9970f6b..2fb192df0952d5b601e6474f72273a01cd2d6bd0 100644 (file)
@@ -41,6 +41,9 @@
 #include <cfg/macros.h>
 
 #include <cpu/types.h>
+#include <drv/irq_cm3.h>
+
+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 */