DMA library for the KL25Z

Dependents:   SimpleDMA_HelloWorld RTOS_SPI spiDMAtest Pinscape_Controller_v1 ... more

Introduction

SimpleDMA is a standard library for different DMA peripherals. Currently the LPC1768, KL46Z and KL25Z are supported. It provided one set of functions for different peripherals. It does not allow for usage of all the advanced functions, partially because the goal was to provide a simple interface, and partially because they are different for different microcontrollers.

Examples

Helloworld: http://mbed.org/users/Sissors/code/SimpleDMA_HelloWorld/

Example in a library (SPI): http://mbed.org/users/Sissors/code/RTOS_SPI/

Files at this revision

API Documentation at this revision

Comitter:
Tomo2k
Date:
Fri Jun 27 10:12:27 2014 +0000
Parent:
6:e9ab0bb912c8
Child:
8:876f3b55e6f5
Commit message:
Added support for KL46

Changed in this revision

SimpleDMA.h Show annotated file Show diff for this revision Revisions of this file
SimpleDMA_KL25.cpp Show diff for this revision Revisions of this file
SimpleDMA_KL25.h Show annotated file Show diff for this revision Revisions of this file
SimpleDMA_KL25_46.cpp Show annotated file Show diff for this revision Revisions of this file
SimpleDMA_KL46.h Show annotated file Show diff for this revision Revisions of this file
--- a/SimpleDMA.h	Tue Mar 18 12:44:46 2014 +0000
+++ b/SimpleDMA.h	Fri Jun 27 10:12:27 2014 +0000
@@ -7,6 +7,7 @@
 
 #include "mbed.h"
 #include "SimpleDMA_KL25.h"
+#include "SimpleDMA_KL46.h"
 #include "SimpleDMA_LPC1768.h"
 
 
--- a/SimpleDMA_KL25.cpp	Tue Mar 18 12:44:46 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-#ifdef TARGET_KL25Z
-#include "SimpleDMA.h"
-
-
-
-SimpleDMA *SimpleDMA::irq_owner[4] = {NULL};
-
-SimpleDMA::SimpleDMA(int channel) {
-    this->channel(channel);
-       
-    //Enable DMA
-    SIM->SCGC6 |= 1<<1;     //Enable clock to DMA mux
-    SIM->SCGC7 |= 1<<8;     //Enable clock to DMA
-    
-    trigger(Trigger_ALWAYS);
-   
-    NVIC_SetVector(DMA0_IRQn, (uint32_t)&irq_handler0);
-    NVIC_SetVector(DMA1_IRQn, (uint32_t)&irq_handler1);
-    NVIC_SetVector(DMA2_IRQn, (uint32_t)&irq_handler2);
-    NVIC_SetVector(DMA3_IRQn, (uint32_t)&irq_handler3);
-    NVIC_EnableIRQ(DMA0_IRQn);
-    NVIC_EnableIRQ(DMA1_IRQn);
-    NVIC_EnableIRQ(DMA2_IRQn);
-    NVIC_EnableIRQ(DMA3_IRQn);
-}
-
-
-int SimpleDMA::start(int length) {  
-    if (auto_channel)
-        _channel = getFreeChannel();
-    else
-        while(isBusy());
-    
-    if (length > DMA_DSR_BCR_BCR_MASK)
-        return -1;
-
-    irq_owner[_channel] = this;
-    
-    DMA0->DMA[_channel].SAR = _source;
-    DMA0->DMA[_channel].DAR = _destination;
-    DMA0->DMA[_channel].DSR_BCR = length;
-    DMAMUX0->CHCFG[_channel] = _trigger;
-    
-    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);
-    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;
-    }
-    
-    DMA0->DMA[_channel].DCR = config;      
-           
-    //Start
-    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;
-    
-    return (DMA0->DMA[channel].DSR_BCR & 0xFFFFFF);
-}
-
-
-/*****************************************************************/
-void SimpleDMA::irq_handler(void) {
-    DMAMUX0->CHCFG[_channel] = 0;
-    DMA0->DMA[_channel].DSR_BCR |= DMA_DSR_BCR_DONE_MASK ; 
-    _callback.call();
-}
-
-void SimpleDMA::irq_handler0( void ) {
-    if (irq_owner[0]!=NULL)
-        irq_owner[0]->irq_handler();
-}
-
-void SimpleDMA::irq_handler1( void ) {
-    if (irq_owner[1]!=NULL)
-        irq_owner[1]->irq_handler();
-}
-
-void SimpleDMA::irq_handler2( void ) {
-    if (irq_owner[2]!=NULL)
-        irq_owner[2]->irq_handler();
-}
-
-void SimpleDMA::irq_handler3( void ) {
-    if (irq_owner[3]!=NULL)
-        irq_owner[3]->irq_handler();
-}
-#endif
\ No newline at end of file
--- a/SimpleDMA_KL25.h	Tue Mar 18 12:44:46 2014 +0000
+++ b/SimpleDMA_KL25.h	Fri Jun 27 10:12:27 2014 +0000
@@ -1,4 +1,4 @@
-#ifdef TARGET_KL25Z
+#if defined TARGET_KL25Z
 
 #define DMA_CHANNELS        4
 #define DMA_IRQS            4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SimpleDMA_KL25_46.cpp	Fri Jun 27 10:12:27 2014 +0000
@@ -0,0 +1,106 @@
+#if defined TARGET_KL25Z || defined TARGET_KL46Z
+#include "SimpleDMA.h"
+
+
+
+SimpleDMA *SimpleDMA::irq_owner[4] = {NULL};
+
+SimpleDMA::SimpleDMA(int channel) {
+    this->channel(channel);
+       
+    //Enable DMA
+    SIM->SCGC6 |= 1<<1;     //Enable clock to DMA mux
+    SIM->SCGC7 |= 1<<8;     //Enable clock to DMA
+    
+    trigger(Trigger_ALWAYS);
+   
+    NVIC_SetVector(DMA0_IRQn, (uint32_t)&irq_handler0);
+    NVIC_SetVector(DMA1_IRQn, (uint32_t)&irq_handler1);
+    NVIC_SetVector(DMA2_IRQn, (uint32_t)&irq_handler2);
+    NVIC_SetVector(DMA3_IRQn, (uint32_t)&irq_handler3);
+    NVIC_EnableIRQ(DMA0_IRQn);
+    NVIC_EnableIRQ(DMA1_IRQn);
+    NVIC_EnableIRQ(DMA2_IRQn);
+    NVIC_EnableIRQ(DMA3_IRQn);
+}
+
+
+int SimpleDMA::start(int length) {  
+    if (auto_channel)
+        _channel = getFreeChannel();
+    else
+        while(isBusy());
+    
+    if (length > DMA_DSR_BCR_BCR_MASK)
+        return -1;
+
+    irq_owner[_channel] = this;
+    
+    DMA0->DMA[_channel].SAR = _source;
+    DMA0->DMA[_channel].DAR = _destination;
+    DMA0->DMA[_channel].DSR_BCR = length;
+    DMAMUX0->CHCFG[_channel] = _trigger;
+    
+    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);
+    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;
+    }
+    
+    DMA0->DMA[_channel].DCR = config;      
+           
+    //Start
+    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;
+    
+    return (DMA0->DMA[channel].DSR_BCR & 0xFFFFFF);
+}
+
+
+/*****************************************************************/
+void SimpleDMA::irq_handler(void) {
+    DMAMUX0->CHCFG[_channel] = 0;
+    DMA0->DMA[_channel].DSR_BCR |= DMA_DSR_BCR_DONE_MASK ; 
+    _callback.call();
+}
+
+void SimpleDMA::irq_handler0( void ) {
+    if (irq_owner[0]!=NULL)
+        irq_owner[0]->irq_handler();
+}
+
+void SimpleDMA::irq_handler1( void ) {
+    if (irq_owner[1]!=NULL)
+        irq_owner[1]->irq_handler();
+}
+
+void SimpleDMA::irq_handler2( void ) {
+    if (irq_owner[2]!=NULL)
+        irq_owner[2]->irq_handler();
+}
+
+void SimpleDMA::irq_handler3( void ) {
+    if (irq_owner[3]!=NULL)
+        irq_owner[3]->irq_handler();
+}
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SimpleDMA_KL46.h	Fri Jun 27 10:12:27 2014 +0000
@@ -0,0 +1,48 @@
+#if defined TARGET_KL46Z
+
+#define DMA_CHANNELS        4
+#define DMA_IRQS            4
+
+enum SimpleDMA_Trigger {
+    Trigger_ALWAYS = 60,
+    Trigger_UART0_RX = 2,
+    Trigger_UART0_TX,
+    Trigger_UART1_RX,
+    Trigger_UART1_TX,
+    Trigger_UART2_RX,
+    Trigger_UART2_TX,
+    Trigger_I2S0_RX = 14,
+    Trigger_I2S0_TX,
+    Trigger_SPI0_RX = 16,
+    Trigger_SPI0_TX,
+    Trigger_SPI1_RX,
+    Trigger_SPI1_TX,
+    Trigger_I2C0 = 22,
+    Trigger_I2C1,
+    Trigger_TPM0_C0,
+    Trigger_TPM0_C1,
+    Trigger_TPM0_C2,
+    Trigger_TPM0_C3,
+    Trigger_TPM0_C4,
+    Trigger_TPM0_C5,
+    Trigger_TPM1_C0 = 32,
+    Trigger_TPM1_C1,
+    Trigger_TPM2_C0,
+    Trigger_TPM2_C1,
+    Trigger_ADC0 = 40,
+    Trigger_CMP0 = 42,
+    Trigger_DAC0 = 45,
+    Trigger_PORTA = 49,
+    Trigegr_PORTC = 51,
+    Trigger_PORTD = 52,
+    Trigger_TPM0 = 54,
+    Trigger_TPM1,
+    Trigger_TPM2,
+    Trigger_TSI,
+    Trigger_ALWAYS0 = 60,
+    Trigger_ALWAYS1,
+    Trigger_ALWAYS2,
+    Trigger_ALWAYS3,
+};    
+
+#endif
\ No newline at end of file