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:
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