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:
wkleunen
Date:
Fri May 12 10:26:15 2017 +0000
Revision:
9:f7345d41b076
Parent:
8:876f3b55e6f5
Use callback template class to integrate library with mbed os 5.

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"
Tomo2k 7:d3be727fa9d2 10 #include "SimpleDMA_KL46.h"
Sissors 5:d9f46ef80e20 11 #include "SimpleDMA_LPC1768.h"
Sissors 0:d77ea45fa625 12
Sissors 0:d77ea45fa625 13
Sissors 0:d77ea45fa625 14 /**
Sissors 0:d77ea45fa625 15 * SimpleDMA, DMA made simple! (Okay that was bad)
Sissors 0:d77ea45fa625 16 *
Sissors 0:d77ea45fa625 17 * A class to easily make basic DMA operations happen. Not all features
Sissors 0:d77ea45fa625 18 * of the DMA peripherals are used, but the main ones are: From and to memory
Sissors 0:d77ea45fa625 19 * and peripherals, either continiously or triggered
Sissors 0:d77ea45fa625 20 */
Sissors 0:d77ea45fa625 21 class SimpleDMA {
Sissors 0:d77ea45fa625 22 public:
Sissors 3:34f5bf8adfa0 23 /**
Sissors 3:34f5bf8adfa0 24 * Constructor
Sissors 3:34f5bf8adfa0 25 *
Sissors 3:34f5bf8adfa0 26 * @param channel - optional parameter which channel should be used, default is automatic channel selection
Sissors 3:34f5bf8adfa0 27 */
Sissors 3:34f5bf8adfa0 28 SimpleDMA(int channel = -1);
Sissors 0:d77ea45fa625 29
Sissors 0:d77ea45fa625 30 /**
Sissors 0:d77ea45fa625 31 * Set the source of the DMA transfer
Sissors 0:d77ea45fa625 32 *
Sissors 0:d77ea45fa625 33 * Autoincrement increments the pointer after each transfer. If the source
Sissors 0:d77ea45fa625 34 * is an array this should be true, if it is a peripheral or a single memory
Sissors 0:d77ea45fa625 35 * location it should be false.
Sissors 0:d77ea45fa625 36 *
Sissors 0:d77ea45fa625 37 * The source can be any pointer to any memory location. Automatically
Sissors 0:d77ea45fa625 38 * the wordsize is calculated depending on the type, if required you can
Sissors 0:d77ea45fa625 39 * also override this.
Sissors 0:d77ea45fa625 40 *
Sissors 0:d77ea45fa625 41 * @param pointer - pointer to the memory location
Sissors 0:d77ea45fa625 42 * @param autoinc - should the pointer be incremented by the DMA module
Sissors 3:34f5bf8adfa0 43 * @param size - wordsize in bits (optional, generally can be omitted)
Sissors 0:d77ea45fa625 44 * @return - 0 on success
Sissors 0:d77ea45fa625 45 */
Sissors 0:d77ea45fa625 46 template<typename Type>
Sissors 5:d9f46ef80e20 47 void source(Type* pointer, bool autoinc, int size = sizeof(Type) * 8) {
Sissors 5:d9f46ef80e20 48 _source = (uint32_t)pointer;
Sissors 5:d9f46ef80e20 49 source_inc = autoinc;
Sissors 5:d9f46ef80e20 50 source_size = size;
Sissors 0:d77ea45fa625 51 }
Sissors 0:d77ea45fa625 52
Sissors 0:d77ea45fa625 53 /**
Sissors 0:d77ea45fa625 54 * Set the destination of the DMA transfer
Sissors 0:d77ea45fa625 55 *
Sissors 0:d77ea45fa625 56 * Autoincrement increments the pointer after each transfer. If the source
Sissors 0:d77ea45fa625 57 * is an array this should be true, if it is a peripheral or a single memory
Sissors 0:d77ea45fa625 58 * location it should be false.
Sissors 0:d77ea45fa625 59 *
Sissors 0:d77ea45fa625 60 * The destination can be any pointer to any memory location. Automatically
Sissors 0:d77ea45fa625 61 * the wordsize is calculated depending on the type, if required you can
Sissors 0:d77ea45fa625 62 * also override this.
Sissors 0:d77ea45fa625 63 *
Sissors 0:d77ea45fa625 64 * @param pointer - pointer to the memory location
Sissors 0:d77ea45fa625 65 * @param autoinc - should the pointer be incremented by the DMA module
Sissors 3:34f5bf8adfa0 66 * @param size - wordsize in bits (optional, generally can be omitted)
Sissors 0:d77ea45fa625 67 * @return - 0 on success
Sissors 0:d77ea45fa625 68 */
Sissors 0:d77ea45fa625 69 template<typename Type>
Sissors 5:d9f46ef80e20 70 void destination(Type* pointer, bool autoinc, int size = sizeof(Type) * 8) {
Sissors 5:d9f46ef80e20 71 _destination = (uint32_t)pointer;
Sissors 5:d9f46ef80e20 72 destination_inc = autoinc;
Sissors 5:d9f46ef80e20 73 destination_size = size;
Sissors 0:d77ea45fa625 74 }
Sissors 0:d77ea45fa625 75
Sissors 0:d77ea45fa625 76 /**
Sissors 0:d77ea45fa625 77 * Set the trigger for the DMA operation
Sissors 0:d77ea45fa625 78 *
Sissors 0:d77ea45fa625 79 * In SimpleDMA_[yourdevice].h you can find the names of the different triggers.
Sissors 0:d77ea45fa625 80 * Trigger_ALWAYS is defined for all devices, it will simply move the data
Sissors 0:d77ea45fa625 81 * as fast as possible. Used for memory-memory transfers. If nothing else is set
Sissors 0:d77ea45fa625 82 * that will be used by default.
Sissors 0:d77ea45fa625 83 *
Sissors 0:d77ea45fa625 84 * @param trig - trigger to use
Sissors 0:d77ea45fa625 85 * @param return - 0 on success
Sissors 0:d77ea45fa625 86 */
Sissors 5:d9f46ef80e20 87 void trigger(SimpleDMA_Trigger trig) {
Sissors 5:d9f46ef80e20 88 _trigger = trig;
Sissors 5:d9f46ef80e20 89 }
Sissors 0:d77ea45fa625 90
Sissors 0:d77ea45fa625 91 /**
Sissors 3:34f5bf8adfa0 92 * Set the DMA channel
Sissors 3:34f5bf8adfa0 93 *
Sissors 3:34f5bf8adfa0 94 * Generally you will not need to call this function, the constructor does so for you
Sissors 3:34f5bf8adfa0 95 *
Sissors 3:34f5bf8adfa0 96 * @param chan - DMA channel to use, -1 = variable channel (highest priority channel which is available)
Sissors 3:34f5bf8adfa0 97 */
Sissors 3:34f5bf8adfa0 98 void channel(int chan);
Sissors 3:34f5bf8adfa0 99
Sissors 3:34f5bf8adfa0 100 /**
Sissors 0:d77ea45fa625 101 * Start the transfer
Sissors 0:d77ea45fa625 102 *
Sissors 0:d77ea45fa625 103 * @param length - number of BYTES to be moved by the DMA
Sissors 0:d77ea45fa625 104 */
marcusbirkin 8:876f3b55e6f5 105 int start(uint32_t length);
Sissors 0:d77ea45fa625 106
Sissors 0:d77ea45fa625 107 /**
Sissors 0:d77ea45fa625 108 * Is the DMA channel busy
Sissors 0:d77ea45fa625 109 *
Sissors 3:34f5bf8adfa0 110 * @param channel - channel to check, -1 = current channel
Sissors 0:d77ea45fa625 111 * @return - true if it is busy
Sissors 0:d77ea45fa625 112 */
Sissors 3:34f5bf8adfa0 113 bool isBusy( int channel = -1 );
Sissors 0:d77ea45fa625 114
Sissors 1:0b73b00bcee8 115 /**
Sissors 1:0b73b00bcee8 116 * Attach an interrupt upon completion of DMA transfer or error
Sissors 1:0b73b00bcee8 117 *
Sissors 1:0b73b00bcee8 118 * @param function - function to call upon completion (may be a member function)
Sissors 1:0b73b00bcee8 119 */
wkleunen 9:f7345d41b076 120 void attach(Callback<void(int)> func) {
wkleunen 9:f7345d41b076 121 _callback = func;
Sissors 1:0b73b00bcee8 122 }
Sissors 1:0b73b00bcee8 123
Sissors 0:d77ea45fa625 124
Sissors 0:d77ea45fa625 125 protected:
Sissors 5:d9f46ef80e20 126 int _channel;
Sissors 5:d9f46ef80e20 127 SimpleDMA_Trigger _trigger;
Sissors 5:d9f46ef80e20 128 uint32_t _source;
Sissors 5:d9f46ef80e20 129 uint32_t _destination;
Sissors 5:d9f46ef80e20 130 bool source_inc;
Sissors 5:d9f46ef80e20 131 bool destination_inc;
Sissors 5:d9f46ef80e20 132 uint8_t source_size;
Sissors 5:d9f46ef80e20 133 uint8_t destination_size;
Sissors 1:0b73b00bcee8 134
Sissors 3:34f5bf8adfa0 135 bool auto_channel;
Sissors 2:fe2fcaa72434 136
Sissors 2:fe2fcaa72434 137 //IRQ handlers
wkleunen 9:f7345d41b076 138 Callback<void(int)> _callback;
Sissors 1:0b73b00bcee8 139 void irq_handler(void);
Sissors 0:d77ea45fa625 140
Sissors 5:d9f46ef80e20 141 static SimpleDMA *irq_owner[DMA_CHANNELS];
Sissors 5:d9f46ef80e20 142
Sissors 5:d9f46ef80e20 143 static void irq_handler0( void );
Sissors 1:0b73b00bcee8 144
Sissors 5:d9f46ef80e20 145 #if DMA_IRQS > 1
Sissors 5:d9f46ef80e20 146 static void irq_handler1( void );
Sissors 5:d9f46ef80e20 147 static void irq_handler2( void );
Sissors 5:d9f46ef80e20 148 static void irq_handler3( void );
Sissors 5:d9f46ef80e20 149 #endif
Sissors 2:fe2fcaa72434 150
Sissors 5:d9f46ef80e20 151 //Keep searching until we find a non-busy channel, start with lowest channel number
Sissors 5:d9f46ef80e20 152 int getFreeChannel(void);
Sissors 2:fe2fcaa72434 153
wkleunen 9:f7345d41b076 154
Sissors 0:d77ea45fa625 155 };
Sissors 0:d77ea45fa625 156 #endif