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/

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