A simple library to access the DMA functionality.

Fork of SimpleDMA by Erik -

Revision:
0:d77ea45fa625
Child:
1:0b73b00bcee8
diff -r 000000000000 -r d77ea45fa625 SimpleDMA_KL25.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SimpleDMA_KL25.cpp	Fri Oct 18 07:44:42 2013 +0000
@@ -0,0 +1,88 @@
+#include "SimpleDMA.h"
+
+#define DMA_CHANNELS        4
+
+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
+    
+    DMA0->DMA[_channel].DCR |= (1<<29) + (1<<30);   //Set to always use DMAMUX (If no trigger is needed we route via alwayson)
+}
+
+int SimpleDMA::setMemory(uint32_t address, int wordsize, bool source, bool autoinc) {
+    //Check if it is an allowed address
+    switch ((uint32_t) address >> 20) {
+        case 0x000:
+        case 0x1FF:
+        case 0x200:
+        case 0x400:
+        break;
+        default:
+            return -1;
+        }
+    
+    char _size;
+    switch (wordsize) {
+        case 8:
+            _size = 1;
+            break;
+        case 16:
+            _size = 2;
+            break;
+        case 32:
+            _size = 0;
+            break;
+        default:
+            _size = 1;
+        }
+    
+    //Check if source or destination
+    if (source) {
+        DMA0->DMA[_channel].SAR = address;
+        DMA0->DMA[_channel].DCR &= ~(7<<20);
+        DMA0->DMA[_channel].DCR |= autoinc << 22;
+        DMA0->DMA[_channel].DCR |= _size << 20;
+    } else {
+        DMA0->DMA[_channel].DAR = address;
+        DMA0->DMA[_channel].DCR &= ~(7<<17);
+        DMA0->DMA[_channel].DCR |= autoinc << 19;
+        DMA0->DMA[_channel].DCR |= _size << 17;
+    }
+    return 0;
+};
+
+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;
+    
+    //Set length
+    DMA0->DMA[_channel].DSR_BCR &= ~0xFFFFFF;
+    DMA0->DMA[_channel].DSR_BCR |= length;
+    
+    //Start
+    //DMA0->DMA[_channel].DCR|=1<<16;
+    DMAMUX0->CHCFG[_channel] |= 1<<7;
+    
+    return 0;
+}
+
+void SimpleDMA::channel(int chan) {
+    if (chan >= 0 && chan < DMA_CHANNELS)
+        _channel = chan;
+    else
+        _channel = 3;
+}
+
+bool SimpleDMA::isBusy( void ) {
+    return (DMA0->DMA[_channel].DSR_BCR & (1<<25) == 1<<25);
+}
\ No newline at end of file