A simple library to access the DMA functionality.

Fork of SimpleDMA by Erik -

Committer:
Sissors
Date:
Fri Dec 20 20:48:17 2013 +0000
Revision:
1:0b73b00bcee8
Parent:
0:d77ea45fa625
Child:
2:fe2fcaa72434
v0.2, KL25, interrupts

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 0:d77ea45fa625 1 #ifndef SIMPLEDMA_H
Sissors 0:d77ea45fa625 2 #define SIMPLEDMA_H
Sissors 0:d77ea45fa625 3
Sissors 0:d77ea45fa625 4 #include "mbed.h"
Sissors 1:0b73b00bcee8 5 #include "rtos.h"
Sissors 0:d77ea45fa625 6 #include "SimpleDMA_KL25.h"
Sissors 0:d77ea45fa625 7
Sissors 0:d77ea45fa625 8
Sissors 0:d77ea45fa625 9 /**
Sissors 0:d77ea45fa625 10 * SimpleDMA, DMA made simple! (Okay that was bad)
Sissors 0:d77ea45fa625 11 *
Sissors 0:d77ea45fa625 12 * A class to easily make basic DMA operations happen. Not all features
Sissors 0:d77ea45fa625 13 * of the DMA peripherals are used, but the main ones are: From and to memory
Sissors 0:d77ea45fa625 14 * and peripherals, either continiously or triggered
Sissors 0:d77ea45fa625 15 */
Sissors 0:d77ea45fa625 16 class SimpleDMA {
Sissors 0:d77ea45fa625 17 public:
Sissors 0:d77ea45fa625 18 SimpleDMA(int channel = 0);
Sissors 0:d77ea45fa625 19
Sissors 0:d77ea45fa625 20 /**
Sissors 0:d77ea45fa625 21 * Set the source of the DMA transfer
Sissors 0:d77ea45fa625 22 *
Sissors 0:d77ea45fa625 23 * Autoincrement increments the pointer after each transfer. If the source
Sissors 0:d77ea45fa625 24 * is an array this should be true, if it is a peripheral or a single memory
Sissors 0:d77ea45fa625 25 * location it should be false.
Sissors 0:d77ea45fa625 26 *
Sissors 0:d77ea45fa625 27 * The source can be any pointer to any memory location. Automatically
Sissors 0:d77ea45fa625 28 * the wordsize is calculated depending on the type, if required you can
Sissors 0:d77ea45fa625 29 * also override this.
Sissors 0:d77ea45fa625 30 *
Sissors 0:d77ea45fa625 31 * @param pointer - pointer to the memory location
Sissors 0:d77ea45fa625 32 * @param autoinc - should the pointer be incremented by the DMA module
Sissors 0:d77ea45fa625 33 * @param size - size of the transfer (optional, generally can be omitted)
Sissors 0:d77ea45fa625 34 * @return - 0 on success
Sissors 0:d77ea45fa625 35 */
Sissors 0:d77ea45fa625 36 template<typename Type>
Sissors 0:d77ea45fa625 37 int source(Type* pointer, bool autoinc, int size = sizeof(Type*)) {
Sissors 0:d77ea45fa625 38 return setMemory((uint32_t)pointer, size, true, autoinc);
Sissors 0:d77ea45fa625 39 }
Sissors 0:d77ea45fa625 40
Sissors 0:d77ea45fa625 41 /**
Sissors 0:d77ea45fa625 42 * Set the destination of the DMA transfer
Sissors 0:d77ea45fa625 43 *
Sissors 0:d77ea45fa625 44 * Autoincrement increments the pointer after each transfer. If the source
Sissors 0:d77ea45fa625 45 * is an array this should be true, if it is a peripheral or a single memory
Sissors 0:d77ea45fa625 46 * location it should be false.
Sissors 0:d77ea45fa625 47 *
Sissors 0:d77ea45fa625 48 * The destination can be any pointer to any memory location. Automatically
Sissors 0:d77ea45fa625 49 * the wordsize is calculated depending on the type, if required you can
Sissors 0:d77ea45fa625 50 * also override this.
Sissors 0:d77ea45fa625 51 *
Sissors 0:d77ea45fa625 52 * @param pointer - pointer to the memory location
Sissors 0:d77ea45fa625 53 * @param autoinc - should the pointer be incremented by the DMA module
Sissors 0:d77ea45fa625 54 * @param size - size of the transfer (optional, generally can be omitted)
Sissors 0:d77ea45fa625 55 * @return - 0 on success
Sissors 0:d77ea45fa625 56 */
Sissors 0:d77ea45fa625 57 template<typename Type>
Sissors 0:d77ea45fa625 58 int destination(Type* pointer, bool autoinc, int size = sizeof(Type*)) {
Sissors 0:d77ea45fa625 59 return setMemory((uint32_t)pointer, size, false, autoinc);
Sissors 0:d77ea45fa625 60 }
Sissors 0:d77ea45fa625 61
Sissors 0:d77ea45fa625 62 /**
Sissors 0:d77ea45fa625 63 * Set the trigger for the DMA operation
Sissors 0:d77ea45fa625 64 *
Sissors 0:d77ea45fa625 65 * In SimpleDMA_[yourdevice].h you can find the names of the different triggers.
Sissors 0:d77ea45fa625 66 * Trigger_ALWAYS is defined for all devices, it will simply move the data
Sissors 0:d77ea45fa625 67 * as fast as possible. Used for memory-memory transfers. If nothing else is set
Sissors 0:d77ea45fa625 68 * that will be used by default.
Sissors 0:d77ea45fa625 69 *
Sissors 0:d77ea45fa625 70 * @param trig - trigger to use
Sissors 0:d77ea45fa625 71 * @param return - 0 on success
Sissors 0:d77ea45fa625 72 */
Sissors 0:d77ea45fa625 73 int trigger(SimpleDMA_Trigger trig);
Sissors 0:d77ea45fa625 74
Sissors 0:d77ea45fa625 75 /**
Sissors 0:d77ea45fa625 76 * Start the transfer
Sissors 0:d77ea45fa625 77 *
Sissors 0:d77ea45fa625 78 * @param length - number of BYTES to be moved by the DMA
Sissors 0:d77ea45fa625 79 */
Sissors 0:d77ea45fa625 80 int start(int length);
Sissors 0:d77ea45fa625 81
Sissors 0:d77ea45fa625 82 /**
Sissors 0:d77ea45fa625 83 * Is the DMA channel busy
Sissors 0:d77ea45fa625 84 *
Sissors 0:d77ea45fa625 85 * @return - true if it is busy
Sissors 0:d77ea45fa625 86 */
Sissors 0:d77ea45fa625 87 bool isBusy( void );
Sissors 0:d77ea45fa625 88
Sissors 1:0b73b00bcee8 89 /**
Sissors 1:0b73b00bcee8 90 * Attach an interrupt upon completion of DMA transfer or error
Sissors 1:0b73b00bcee8 91 *
Sissors 1:0b73b00bcee8 92 * @param function - function to call upon completion (may be a member function)
Sissors 1:0b73b00bcee8 93 */
Sissors 1:0b73b00bcee8 94 void attach(void (*function)(void)) {
Sissors 1:0b73b00bcee8 95 irq_en = function;
Sissors 1:0b73b00bcee8 96 _callback.attach(function);
Sissors 1:0b73b00bcee8 97 }
Sissors 1:0b73b00bcee8 98
Sissors 1:0b73b00bcee8 99 template<typename T>
Sissors 1:0b73b00bcee8 100 void attach(T *object, void (T::*member)(void)) {
Sissors 1:0b73b00bcee8 101 irq_en = object;
Sissors 1:0b73b00bcee8 102 _callback.attach(object, member);
Sissors 1:0b73b00bcee8 103 }
Sissors 0:d77ea45fa625 104
Sissors 1:0b73b00bcee8 105 void wait(void) {
Sissors 1:0b73b00bcee8 106 id = Thread::gettid();
Sissors 1:0b73b00bcee8 107 this->attach(this, &SimpleDMA::waitCallback);
Sissors 1:0b73b00bcee8 108 this->start(8);
Sissors 1:0b73b00bcee8 109 Thread::signal_wait(0x1);
Sissors 1:0b73b00bcee8 110 }
Sissors 0:d77ea45fa625 111
Sissors 0:d77ea45fa625 112
Sissors 0:d77ea45fa625 113 protected:
Sissors 1:0b73b00bcee8 114 /**
Sissors 1:0b73b00bcee8 115 * Set the DMA channel
Sissors 1:0b73b00bcee8 116 *
Sissors 1:0b73b00bcee8 117 * @param chan - DMA channel to use
Sissors 1:0b73b00bcee8 118 */
Sissors 1:0b73b00bcee8 119 void channel(int chan);
Sissors 1:0b73b00bcee8 120
Sissors 0:d77ea45fa625 121 int setMemory(uint32_t address, int wordsize, bool source, bool autoinc);
Sissors 0:d77ea45fa625 122 int _channel;
Sissors 1:0b73b00bcee8 123 FunctionPointer _callback;
Sissors 1:0b73b00bcee8 124 bool irq_en;
Sissors 1:0b73b00bcee8 125 void irq_handler(void);
Sissors 0:d77ea45fa625 126
Sissors 1:0b73b00bcee8 127 //IRQ handlers
Sissors 0:d77ea45fa625 128
Sissors 1:0b73b00bcee8 129 static SimpleDMA *irq_owner[4];
Sissors 1:0b73b00bcee8 130
Sissors 1:0b73b00bcee8 131 static void irq_handler0( void ) {
Sissors 1:0b73b00bcee8 132 if (irq_owner[0]!=NULL)
Sissors 1:0b73b00bcee8 133 irq_owner[0]->irq_handler();
Sissors 1:0b73b00bcee8 134 }
Sissors 1:0b73b00bcee8 135 static void irq_handler1( void ) {
Sissors 1:0b73b00bcee8 136 if (irq_owner[1]!=NULL)
Sissors 1:0b73b00bcee8 137 irq_owner[1]->irq_handler();
Sissors 1:0b73b00bcee8 138 }
Sissors 1:0b73b00bcee8 139 static void irq_handler2( void ) {
Sissors 1:0b73b00bcee8 140 if (irq_owner[2]!=NULL)
Sissors 1:0b73b00bcee8 141 irq_owner[2]->irq_handler();
Sissors 1:0b73b00bcee8 142 }
Sissors 1:0b73b00bcee8 143 static void irq_handler3( void ) {
Sissors 1:0b73b00bcee8 144 if (irq_owner[3]!=NULL)
Sissors 1:0b73b00bcee8 145 irq_owner[3]->irq_handler();
Sissors 1:0b73b00bcee8 146 }
Sissors 1:0b73b00bcee8 147 public:
Sissors 1:0b73b00bcee8 148 osThreadId id;
Sissors 1:0b73b00bcee8 149 void waitCallback(void) {
Sissors 1:0b73b00bcee8 150
Sissors 1:0b73b00bcee8 151 //id = Thread::gettid();
Sissors 1:0b73b00bcee8 152 osSignalSet(id, 0x1);
Sissors 1:0b73b00bcee8 153
Sissors 1:0b73b00bcee8 154 }
Sissors 0:d77ea45fa625 155
Sissors 0:d77ea45fa625 156 };
Sissors 0:d77ea45fa625 157 #endif