A simple library to access the DMA functionality.

Fork of SimpleDMA by Erik -

Revision:
1:0b73b00bcee8
Parent:
0:d77ea45fa625
Child:
2:fe2fcaa72434
--- a/SimpleDMA_KL25.cpp	Fri Oct 18 07:44:42 2013 +0000
+++ b/SimpleDMA_KL25.cpp	Fri Dec 20 20:48:17 2013 +0000
@@ -2,15 +2,41 @@
 
 #define DMA_CHANNELS        4
 
+SimpleDMA *SimpleDMA::irq_owner[4] = {NULL};
+
 SimpleDMA::SimpleDMA(int channel) {
     this->channel(channel);
-    trigger(Trigger_ALWAYS);
-    
+       
     //Enable DMA
     SIM->SCGC6 |= 1<<1;     //Enable clock to DMA mux
     SIM->SCGC7 |= 1<<8;     //Enable clock to DMA
     
+    trigger(Trigger_ALWAYS);
+    
     DMA0->DMA[_channel].DCR |= (1<<29) + (1<<30);   //Set to always use DMAMUX (If no trigger is needed we route via alwayson)
+
+    uint32_t handler = NULL;
+    switch (_channel) {
+        case 0:
+            handler = (uint32_t)&irq_handler0;
+            break;
+        case 1:
+            handler = (uint32_t)&irq_handler1;
+            break;
+        case 2:
+            handler = (uint32_t)&irq_handler2;
+            break;
+        case 3:
+            handler = (uint32_t)&irq_handler3;
+            break;
+        default:
+            break;
+    }
+
+    NVIC_SetVector((IRQn) (DMA0_IRQn + _channel), handler);
+    NVIC_EnableIRQ((IRQn) (DMA0_IRQn + _channel));
+
+    irq_owner[_channel] = this;
 }
 
 int SimpleDMA::setMemory(uint32_t address, int wordsize, bool source, bool autoinc) {
@@ -56,12 +82,13 @@
 };
 
 int SimpleDMA::trigger(SimpleDMA_Trigger trig){ 
-    DMAMUX0->CHCFG[_channel] = 0;
+    
     DMAMUX0->CHCFG[_channel] = trig;
     return 0;
 }
 
 int SimpleDMA::start(int length) {
+
     if (length > 0xFFFFF)
         return -1;
     
@@ -69,8 +96,13 @@
     DMA0->DMA[_channel].DSR_BCR &= ~0xFFFFFF;
     DMA0->DMA[_channel].DSR_BCR |= length;
     
+    //Enable interrupts
+    if (irq_en)
+        DMA0->DMA[_channel].DCR |= (uint32_t)(1<<31);
+    else
+        DMA0->DMA[_channel].DCR &= ~(1<<31);
+        
     //Start
-    //DMA0->DMA[_channel].DCR|=1<<16;
     DMAMUX0->CHCFG[_channel] |= 1<<7;
     
     return 0;
@@ -85,4 +117,10 @@
 
 bool SimpleDMA::isBusy( void ) {
     return (DMA0->DMA[_channel].DSR_BCR & (1<<25) == 1<<25);
-}
\ No newline at end of file
+}
+
+void SimpleDMA::irq_handler(void) {
+    DMAMUX0->CHCFG[_channel] = 0;
+    DMA0->DMA[0].DSR_BCR |= DMA_DSR_BCR_DONE_MASK ; 
+    _callback.call();
+}