A simple library to access the DMA functionality.

Fork of SimpleDMA by Erik -

Revision:
3:34f5bf8adfa0
Parent:
2:fe2fcaa72434
Child:
4:c3a84c6c432c
--- a/SimpleDMA.h	Sun Dec 22 21:42:49 2013 +0000
+++ b/SimpleDMA.h	Thu Dec 26 12:19:29 2013 +0000
@@ -18,7 +18,12 @@
 */
 class SimpleDMA {
 public:
-SimpleDMA(int channel = 0);
+/**
+* Constructor
+*
+* @param channel - optional parameter which channel should be used, default is automatic channel selection
+*/
+SimpleDMA(int channel = -1);
 
 /**
 * Set the source of the DMA transfer
@@ -33,11 +38,11 @@
 *
 * @param pointer - pointer to the memory location
 * @param autoinc - should the pointer be incremented by the DMA module
-* @param size - size of the transfer (optional, generally can be omitted)
+* @param size - wordsize in bits (optional, generally can be omitted)
 * @return - 0 on success
 */
 template<typename Type>
-int source(Type* pointer, bool autoinc, int size = sizeof(Type*)) {
+int source(Type* pointer, bool autoinc, int size = sizeof(Type) * 8) {
     return setAddress((uint32_t)pointer, size, true, autoinc);
 }
 
@@ -54,11 +59,11 @@
 *
 * @param pointer - pointer to the memory location
 * @param autoinc - should the pointer be incremented by the DMA module
-* @param size - size of the transfer (optional, generally can be omitted)
+* @param size - wordsize in bits (optional, generally can be omitted)
 * @return - 0 on success
 */
 template<typename Type>
-int destination(Type* pointer, bool autoinc, int size = sizeof(Type*)) {
+int destination(Type* pointer, bool autoinc, int size = sizeof(Type) * 8) {
     return setAddress((uint32_t)pointer, size, false, autoinc);
 }
 
@@ -76,6 +81,15 @@
 int trigger(SimpleDMA_Trigger trig);
 
 /**
+* Set the DMA channel
+*
+* Generally you will not need to call this function, the constructor does so for you
+*
+* @param chan - DMA channel to use, -1 = variable channel (highest priority channel which is available)
+*/
+void channel(int chan);
+
+/**
 * Start the transfer
 *
 * @param length - number of BYTES to be moved by the DMA
@@ -85,9 +99,10 @@
 /**
 * Is the DMA channel busy
 *
+* @param channel - channel to check, -1 = current channel
 * @return - true if it is busy
 */
-bool isBusy( void );
+bool isBusy( int channel = -1 );
 
 /**
 * Attach an interrupt upon completion of DMA transfer or error
@@ -106,6 +121,19 @@
     }
 
 #ifdef RTOS_H
+/**
+* Start a DMA transfer similar to start, however block current Thread
+* until the transfer is finished
+*
+* When using this function only the current Thread is halted.
+* The Thread is moved to Waiting state: other Threads will continue
+* to run normally. 
+*
+* This function is only available if you included rtos.h before 
+* including SimpleDMA.h.
+*
+* @param length - number of BYTES to be moved by the DMA
+*/
 void wait(int length) {
     id = Thread::gettid();
     this->attach(this, &SimpleDMA::waitCallback);
@@ -115,15 +143,10 @@
 #endif
 
 protected:
-/**
-* Set the DMA channel
-*
-* @param chan - DMA channel to use
-*/
-void channel(int chan);
 int setAddress(uint32_t address, int wordsize, bool source, bool autoinc);
 
 int _channel;
+bool auto_channel;
 uint32_t SAR, DAR, DSR, DCR;
 uint8_t CHCFG;
 
@@ -159,5 +182,16 @@
 }
 #endif
 
+//Keep searching until we find a non-busy channel, start with lowest channel number
+int getFreeChannel(void) {
+    int retval = 0;
+    while(1) {
+        if (!isBusy(retval))
+            return retval;
+        retval++;
+        if (retval >= DMA_CHANNELS)
+            retval = 0;
+    }  
+}
 };
 #endif
\ No newline at end of file