Arnaud VALLEY / Mbed 2 deprecated Pinscape_Controller_V2_arnoz

Dependencies:   mbed FastIO FastPWM USBDevice

Committer:
mjr
Date:
Thu Feb 18 07:32:20 2016 +0000
Revision:
47:df7a88cd249c
Parent:
45:c42166b2878c
Child:
48:058ace2aed1d
3-channel linked DMA scheme for CCD image capture working

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mjr 45:c42166b2878c 1 #ifndef SIMPLEDMA_H
mjr 45:c42166b2878c 2 #define SIMPLEDMA_H
mjr 45:c42166b2878c 3
mjr 45:c42166b2878c 4 #ifdef RTOS_H
mjr 45:c42166b2878c 5 #include "rtos.h"
mjr 45:c42166b2878c 6 #endif
mjr 45:c42166b2878c 7
mjr 45:c42166b2878c 8 #include "mbed.h"
mjr 45:c42166b2878c 9 #include "SimpleDMA_KL25.h"
mjr 45:c42166b2878c 10 #include "SimpleDMA_KL46.h"
mjr 45:c42166b2878c 11 #include "SimpleDMA_LPC1768.h"
mjr 45:c42166b2878c 12
mjr 45:c42166b2878c 13
mjr 45:c42166b2878c 14 /**
mjr 45:c42166b2878c 15 * SimpleDMA, DMA made simple! (Okay that was bad)
mjr 45:c42166b2878c 16 *
mjr 45:c42166b2878c 17 * A class to easily make basic DMA operations happen. Not all features
mjr 45:c42166b2878c 18 * of the DMA peripherals are used, but the main ones are: From and to memory
mjr 45:c42166b2878c 19 * and peripherals, either continiously or triggered
mjr 45:c42166b2878c 20 */
mjr 45:c42166b2878c 21 class SimpleDMA {
mjr 45:c42166b2878c 22 public:
mjr 45:c42166b2878c 23 /**
mjr 45:c42166b2878c 24 * Constructor
mjr 45:c42166b2878c 25 *
mjr 45:c42166b2878c 26 * @param channel - optional parameter which channel should be used, default is automatic channel selection
mjr 45:c42166b2878c 27 */
mjr 45:c42166b2878c 28 SimpleDMA(int channel = -1);
mjr 45:c42166b2878c 29
mjr 45:c42166b2878c 30 /**
mjr 45:c42166b2878c 31 * Set the source of the DMA transfer
mjr 45:c42166b2878c 32 *
mjr 45:c42166b2878c 33 * Autoincrement increments the pointer after each transfer. If the source
mjr 45:c42166b2878c 34 * is an array this should be true, if it is a peripheral or a single memory
mjr 45:c42166b2878c 35 * location it should be false.
mjr 45:c42166b2878c 36 *
mjr 45:c42166b2878c 37 * The source can be any pointer to any memory location. Automatically
mjr 45:c42166b2878c 38 * the wordsize is calculated depending on the type, if required you can
mjr 45:c42166b2878c 39 * also override this.
mjr 45:c42166b2878c 40 *
mjr 45:c42166b2878c 41 * @param pointer - pointer to the memory location
mjr 45:c42166b2878c 42 * @param autoinc - should the pointer be incremented by the DMA module
mjr 45:c42166b2878c 43 * @param size - wordsize in bits (optional, generally can be omitted)
mjr 45:c42166b2878c 44 * @return - 0 on success
mjr 45:c42166b2878c 45 */
mjr 45:c42166b2878c 46 template<typename Type>
mjr 45:c42166b2878c 47 void source(Type* pointer, bool autoinc, int size = sizeof(Type) * 8, int mod = 0) {
mjr 45:c42166b2878c 48 _source = (uint32_t)pointer;
mjr 45:c42166b2878c 49 source_inc = autoinc;
mjr 45:c42166b2878c 50 source_size = size;
mjr 45:c42166b2878c 51 source_mod = mod;
mjr 45:c42166b2878c 52 }
mjr 45:c42166b2878c 53
mjr 45:c42166b2878c 54 /**
mjr 45:c42166b2878c 55 * Set the destination of the DMA transfer
mjr 45:c42166b2878c 56 *
mjr 45:c42166b2878c 57 * Autoincrement increments the pointer after each transfer. If the source
mjr 45:c42166b2878c 58 * is an array this should be true, if it is a peripheral or a single memory
mjr 45:c42166b2878c 59 * location it should be false.
mjr 45:c42166b2878c 60 *
mjr 45:c42166b2878c 61 * The destination can be any pointer to any memory location. Automatically
mjr 45:c42166b2878c 62 * the wordsize is calculated depending on the type, if required you can
mjr 45:c42166b2878c 63 * also override this.
mjr 45:c42166b2878c 64 *
mjr 45:c42166b2878c 65 * @param pointer - pointer to the memory location
mjr 45:c42166b2878c 66 * @param autoinc - should the pointer be incremented by the DMA module
mjr 45:c42166b2878c 67 * @param size - wordsize in bits (optional, generally can be omitted)
mjr 45:c42166b2878c 68 * @return - 0 on success
mjr 45:c42166b2878c 69 */
mjr 45:c42166b2878c 70 template<typename Type>
mjr 45:c42166b2878c 71 void destination(Type* pointer, bool autoinc, int size = sizeof(Type) * 8, int mod = 0) {
mjr 45:c42166b2878c 72 _destination = (uint32_t)pointer;
mjr 45:c42166b2878c 73 destination_inc = autoinc;
mjr 45:c42166b2878c 74 destination_size = size;
mjr 45:c42166b2878c 75 destination_mod = mod;
mjr 45:c42166b2878c 76 }
mjr 45:c42166b2878c 77
mjr 45:c42166b2878c 78 /**
mjr 45:c42166b2878c 79 * Set cycle-steal mode. In cycle-steal mode, we do one DMA transfer per
mjr 45:c42166b2878c 80 * trigger. In continuous mode, we do the entire transfer on a single trigger.
mjr 45:c42166b2878c 81 */
mjr 45:c42166b2878c 82 void setCycleSteal(bool f) { cycle_steal = f; }
mjr 45:c42166b2878c 83
mjr 45:c42166b2878c 84 /**
mjr 45:c42166b2878c 85 * Set the trigger for the DMA operation
mjr 45:c42166b2878c 86 *
mjr 45:c42166b2878c 87 * In SimpleDMA_[yourdevice].h you can find the names of the different triggers.
mjr 45:c42166b2878c 88 * Trigger_ALWAYS is defined for all devices, it will simply move the data
mjr 45:c42166b2878c 89 * as fast as possible. Used for memory-memory transfers. If nothing else is set
mjr 45:c42166b2878c 90 * that will be used by default.
mjr 45:c42166b2878c 91 *
mjr 45:c42166b2878c 92 * @param trig - trigger to use
mjr 45:c42166b2878c 93 * @param return - 0 on success
mjr 45:c42166b2878c 94 */
mjr 45:c42166b2878c 95 void trigger(SimpleDMA_Trigger trig) {
mjr 45:c42166b2878c 96 _trigger = trig;
mjr 45:c42166b2878c 97 }
mjr 45:c42166b2878c 98
mjr 45:c42166b2878c 99 /**
mjr 45:c42166b2878c 100 * Set the DMA channel
mjr 45:c42166b2878c 101 *
mjr 45:c42166b2878c 102 * Generally you will not need to call this function, the constructor does so for you
mjr 45:c42166b2878c 103 *
mjr 45:c42166b2878c 104 * @param chan - DMA channel to use, -1 = variable channel (highest priority channel which is available)
mjr 45:c42166b2878c 105 */
mjr 45:c42166b2878c 106 void channel(int chan);
mjr 47:df7a88cd249c 107 int getChannel() { return _channel; }
mjr 45:c42166b2878c 108
mjr 45:c42166b2878c 109 /**
mjr 45:c42166b2878c 110 * Start the transfer
mjr 45:c42166b2878c 111 *
mjr 45:c42166b2878c 112 * @param length - number of BYTES to be moved by the DMA
mjr 45:c42166b2878c 113 */
mjr 45:c42166b2878c 114 int start(uint32_t length);
mjr 45:c42166b2878c 115
mjr 45:c42166b2878c 116 /**
mjr 45:c42166b2878c 117 * Start a new transfer with the same parameters as last time
mjr 45:c42166b2878c 118 */
mjr 45:c42166b2878c 119 int restart(uint32_t length);
mjr 45:c42166b2878c 120
mjr 45:c42166b2878c 121 /**
mjr 45:c42166b2878c 122 * Is the DMA channel busy
mjr 45:c42166b2878c 123 *
mjr 45:c42166b2878c 124 * @param channel - channel to check, -1 = current channel
mjr 45:c42166b2878c 125 * @return - true if it is busy
mjr 45:c42166b2878c 126 */
mjr 45:c42166b2878c 127 bool isBusy( int channel = -1 );
mjr 45:c42166b2878c 128
mjr 45:c42166b2878c 129 /**
mjr 45:c42166b2878c 130 * Number of bytes remaining in running transfer. This reads the controller
mjr 45:c42166b2878c 131 * register with the remaining byte count, which the hardware updates each
mjr 45:c42166b2878c 132 * time it completes a destination transfer.
mjr 45:c42166b2878c 133 */
mjr 45:c42166b2878c 134 uint32_t remaining(int channel = -1);
mjr 45:c42166b2878c 135
mjr 45:c42166b2878c 136 /**
mjr 45:c42166b2878c 137 * Attach an interrupt upon completion of DMA transfer or error
mjr 45:c42166b2878c 138 *
mjr 45:c42166b2878c 139 * @param function - function to call upon completion (may be a member function)
mjr 45:c42166b2878c 140 */
mjr 45:c42166b2878c 141 void attach(void (*function)(void)) {
mjr 45:c42166b2878c 142 _callback.attach(function);
mjr 45:c42166b2878c 143 }
mjr 45:c42166b2878c 144
mjr 45:c42166b2878c 145 template<typename T>
mjr 45:c42166b2878c 146 void attach(T *object, void (T::*member)(void)) {
mjr 45:c42166b2878c 147 _callback.attach(object, member);
mjr 45:c42166b2878c 148 }
mjr 47:df7a88cd249c 149
mjr 47:df7a88cd249c 150 /**
mjr 47:df7a88cd249c 151 * Link to another channel. This triggers the given destination
mjr 47:df7a88cd249c 152 * channel when a transfer on this channel is completed. If 'all'
mjr 47:df7a88cd249c 153 * is true, the link occurs after the entire transfer is complete
mjr 47:df7a88cd249c 154 * (i.e., the byte count register in this channel reaches zero).
mjr 47:df7a88cd249c 155 * Otherwise, the link is triggered once for each transfer on this
mjr 47:df7a88cd249c 156 * channel.
mjr 47:df7a88cd249c 157 */
mjr 47:df7a88cd249c 158 void link(SimpleDMA &dest, bool all = false);
mjr 47:df7a88cd249c 159
mjr 47:df7a88cd249c 160 /**
mjr 47:df7a88cd249c 161 * Link to two other channels. This triggers the 'dest1' channel
mjr 47:df7a88cd249c 162 * once for each transfer on this channel, and then triggers the
mjr 47:df7a88cd249c 163 * 'dest2' channel once when the entire transfer has been completed
mjr 47:df7a88cd249c 164 * (i.e., the byte count register on this channel reaches zero).
mjr 47:df7a88cd249c 165 */
mjr 47:df7a88cd249c 166 void link(SimpleDMA &dest1, SimpleDMA &dest2);
mjr 47:df7a88cd249c 167
mjr 45:c42166b2878c 168
mjr 45:c42166b2878c 169 #ifdef RTOS_H
mjr 45:c42166b2878c 170 /**
mjr 45:c42166b2878c 171 * Start a DMA transfer similar to start, however block current Thread
mjr 45:c42166b2878c 172 * until the transfer is finished
mjr 45:c42166b2878c 173 *
mjr 45:c42166b2878c 174 * When using this function only the current Thread is halted.
mjr 45:c42166b2878c 175 * The Thread is moved to Waiting state: other Threads will continue
mjr 45:c42166b2878c 176 * to run normally.
mjr 45:c42166b2878c 177 *
mjr 45:c42166b2878c 178 * This function is only available if you included rtos.h before
mjr 45:c42166b2878c 179 * including SimpleDMA.h.
mjr 45:c42166b2878c 180 *
mjr 45:c42166b2878c 181 * @param length - number of BYTES to be moved by the DMA
mjr 45:c42166b2878c 182 */
mjr 45:c42166b2878c 183 void wait(int length) {
mjr 45:c42166b2878c 184 id = Thread::gettid();
mjr 45:c42166b2878c 185 this->attach(this, &SimpleDMA::waitCallback);
mjr 45:c42166b2878c 186 this->start(length);
mjr 45:c42166b2878c 187 Thread::signal_wait(0x1);
mjr 45:c42166b2878c 188 }
mjr 45:c42166b2878c 189 #endif
mjr 45:c42166b2878c 190
mjr 45:c42166b2878c 191 protected:
mjr 45:c42166b2878c 192 int _channel;
mjr 45:c42166b2878c 193 SimpleDMA_Trigger _trigger;
mjr 45:c42166b2878c 194 uint32_t _source;
mjr 45:c42166b2878c 195 uint32_t _destination;
mjr 45:c42166b2878c 196 bool source_inc;
mjr 45:c42166b2878c 197 bool destination_inc;
mjr 45:c42166b2878c 198 uint8_t source_size;
mjr 45:c42166b2878c 199 uint8_t destination_size;
mjr 45:c42166b2878c 200 uint32_t source_mod;
mjr 45:c42166b2878c 201 uint32_t destination_mod;
mjr 45:c42166b2878c 202 bool cycle_steal;
mjr 47:df7a88cd249c 203 int linkChannel1;
mjr 47:df7a88cd249c 204 int linkChannel2;
mjr 47:df7a88cd249c 205 int linkMode;
mjr 45:c42166b2878c 206
mjr 45:c42166b2878c 207 bool auto_channel;
mjr 45:c42166b2878c 208
mjr 45:c42166b2878c 209 //IRQ handlers
mjr 45:c42166b2878c 210 FunctionPointer _callback;
mjr 45:c42166b2878c 211 void irq_handler(void);
mjr 45:c42166b2878c 212
mjr 45:c42166b2878c 213 static SimpleDMA *irq_owner[DMA_CHANNELS];
mjr 45:c42166b2878c 214
mjr 45:c42166b2878c 215 static void irq_handler0( void );
mjr 45:c42166b2878c 216
mjr 45:c42166b2878c 217 #if DMA_IRQS > 1
mjr 45:c42166b2878c 218 static void irq_handler1( void );
mjr 45:c42166b2878c 219 static void irq_handler2( void );
mjr 45:c42166b2878c 220 static void irq_handler3( void );
mjr 45:c42166b2878c 221 #endif
mjr 45:c42166b2878c 222
mjr 45:c42166b2878c 223 //Keep searching until we find a non-busy channel, start with lowest channel number
mjr 45:c42166b2878c 224 int getFreeChannel(void);
mjr 45:c42166b2878c 225
mjr 45:c42166b2878c 226 #ifdef RTOS_H
mjr 45:c42166b2878c 227 osThreadId id;
mjr 45:c42166b2878c 228 void waitCallback(void) {
mjr 45:c42166b2878c 229 osSignalSet(id, 0x1);
mjr 45:c42166b2878c 230 }
mjr 45:c42166b2878c 231 #endif
mjr 45:c42166b2878c 232 };
mjr 45:c42166b2878c 233 #endif