A simple library to access the DMA functionality.

Fork of SimpleDMA by Erik -

Committer:
Sissors
Date:
Sun Dec 22 21:42:49 2013 +0000
Revision:
2:fe2fcaa72434
Parent:
1:0b73b00bcee8
Child:
3:34f5bf8adfa0
v1.0 KL25Z

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