Mirror with some correction

Dependencies:   mbed FastIO FastPWM USBDevice

Revision:
54:fd77a6b2f76c
Parent:
48:058ace2aed1d
Child:
76:7f5912b6340e
--- a/SimpleDMA/SimpleDMA_KL25_46.cpp	Fri Apr 22 17:58:35 2016 +0000
+++ b/SimpleDMA/SimpleDMA_KL25_46.cpp	Sat Apr 30 17:43:38 2016 +0000
@@ -25,13 +25,15 @@
 SimpleDMA::SimpleDMA(int channel) 
 {
     class_init();
-    
+
+    // remember the channel (-1 means we automatically select on start())
     this->channel(channel);
        
-    //Enable DMA
-    SIM->SCGC6 |= 1<<1;     //Enable clock to DMA mux
-    SIM->SCGC7 |= 1<<8;     //Enable clock to DMA
+    // Enable DMA
+    SIM->SCGC6 |= 1<<1;     // Enable clock to DMA mux
+    SIM->SCGC7 |= 1<<8;     // Enable clock to DMA
     
+    // use the "always" software trigger by default
     trigger(Trigger_ALWAYS);
    
     // presume no link channels
@@ -40,12 +42,15 @@
     linkChannel2 = 0;
 }
 
-int SimpleDMA::start(uint32_t length) 
+int SimpleDMA::start(uint32_t length, bool wait)
 {
     if (auto_channel)
         _channel = getFreeChannel();
-    else
-        while(isBusy());
+    else if (!wait && isBusy())
+        return -1;
+    else {
+        while (isBusy());
+    }
     
     if (length > DMA_DSR_BCR_BCR_MASK)
         return -1;
@@ -54,47 +59,51 @@
 
     // disable the channel while we're setting it up
     DMAMUX0->CHCFG[_channel] = 0;
+    
+    // set the DONE flag on the channel
+    DMA0->DMA[_channel].DSR_BCR = DMA_DSR_BCR_DONE_MASK;
 
     uint32_t config = 
         DMA_DCR_EINT_MASK 
         | DMA_DCR_ERQ_MASK 
         | DMA_DCR_CS_MASK
-        | (source_inc << DMA_DCR_SINC_SHIFT) 
-        | (destination_inc << DMA_DCR_DINC_SHIFT)
-        | ((linkChannel1 & 3) << DMA_DCR_LCH1_SHIFT)
-        | ((linkChannel2 & 3) << DMA_DCR_LCH2_SHIFT)
-        | ((linkMode & 3) << DMA_DCR_LINKCC_SHIFT);
+        | ((source_inc & 0x01) << DMA_DCR_SINC_SHIFT) 
+        | ((destination_inc & 0x01) << DMA_DCR_DINC_SHIFT)
+        | ((linkChannel1 & 0x03) << DMA_DCR_LCH1_SHIFT)
+        | ((linkChannel2 & 0x03) << DMA_DCR_LCH2_SHIFT)
+        | ((linkMode & 0x03) << DMA_DCR_LINKCC_SHIFT);
         
-    switch (source_size) {
-        case 8:
-            config |= 1 << DMA_DCR_SSIZE_SHIFT;
-            break;
-        case 16:
-            config |= 2 << DMA_DCR_SSIZE_SHIFT; 
-            break;
+    switch (source_size) 
+    {
+    case 8:
+        config |= 1 << DMA_DCR_SSIZE_SHIFT;
+        break;
+
+    case 16:
+        config |= 2 << DMA_DCR_SSIZE_SHIFT; 
+        break;
     }
-    switch (destination_size) {
-        case 8:
-            config |= 1 << DMA_DCR_DSIZE_SHIFT;
-            break;
-        case 16:
-            config |= 2 << DMA_DCR_DSIZE_SHIFT; 
-            break;
+
+    switch (destination_size) 
+    {
+    case 8:
+        config |= 1 << DMA_DCR_DSIZE_SHIFT;
+        break;
+
+    case 16:
+        config |= 2 << DMA_DCR_DSIZE_SHIFT; 
+        break;
     }
     
-    DMA0->DMA[_channel].DCR = config;      
     DMA0->DMA[_channel].SAR = _source;
     DMA0->DMA[_channel].DAR = _destination;
     DMAMUX0->CHCFG[_channel] = _trigger;
+    DMA0->DMA[_channel].DCR = config;      
     DMA0->DMA[_channel].DSR_BCR = length;
     
-    //$$$
- //   static int iii; if (_channel != 0 && iii++ < 3)
- //       printf("DMA channel %d: mode %04x, source %08lx, dest %08lx, trigger %d, len %d\r\n", _channel, config, _source, _destination, _trigger, length);
-           
-    //Start - set ENBL bit in the DMAMUX channel config register
-    DMAMUX0->CHCFG[_channel] |= 1<<7;
-    
+    // Start - set the ENBL bit in the DMAMUX channel config register
+    DMAMUX0->CHCFG[_channel] |= DMAMUX_CHCFG_ENBL_MASK;
+
     return 0;
 }
 
@@ -113,22 +122,14 @@
 }
 
 
-int SimpleDMA::restart(uint32_t length)
-{
-    DMA0->DMA[_channel].SAR = _source;
-    DMA0->DMA[_channel].DAR = _destination;
-    DMA0->DMA[_channel].DSR_BCR = length;
-    DMAMUX0->CHCFG[_channel] |= 1<<7;
-    return 0;
-}
-
 bool SimpleDMA::isBusy( int channel ) 
 {
-    //Busy bit doesn't work as I expect it to do, so just check if counter is at zero
-    //return (DMA0->DMA[_channel].DSR_BCR & (1<<25) == 1<<25);
     if (channel == -1)
         channel = _channel;
-    
+
+    // The busy bit doesn't seem to work as expected.  Just check if 
+    // counter is at zero - if not, treat it as busy.
+    //return (DMA0->DMA[_channel].DSR_BCR & (1<<25) == 1<<25);
     return (DMA0->DMA[channel].DSR_BCR & 0xFFFFF);
 }
 
@@ -147,31 +148,31 @@
 void SimpleDMA::irq_handler(void) 
 {
     DMAMUX0->CHCFG[_channel] = 0;
-    DMA0->DMA[_channel].DSR_BCR |= DMA_DSR_BCR_DONE_MASK ; 
+    DMA0->DMA[_channel].DSR_BCR |= DMA_DSR_BCR_DONE_MASK;
     _callback.call();
 }
 
 void SimpleDMA::irq_handler0( void ) 
 {
-    if (irq_owner[0]!=NULL)
+    if (irq_owner[0] != NULL)
         irq_owner[0]->irq_handler();
 }
 
 void SimpleDMA::irq_handler1( void ) 
 {
-    if (irq_owner[1]!=NULL)
+    if (irq_owner[1] != NULL)
         irq_owner[1]->irq_handler();
 }
 
 void SimpleDMA::irq_handler2( void ) 
 {
-    if (irq_owner[2]!=NULL)
+    if (irq_owner[2] != NULL)
         irq_owner[2]->irq_handler();
 }
 
 void SimpleDMA::irq_handler3( void ) 
 {
-    if (irq_owner[3]!=NULL)
+    if (irq_owner[3] != NULL)
         irq_owner[3]->irq_handler();
 }
-#endif
\ No newline at end of file
+#endif