Mike R / Mbed 2 deprecated Pinscape_Controller

Dependencies:   USBDevice mbed FastAnalogIn FastIO FastPWM SimpleDMA

Committer:
mjr
Date:
Mon Feb 15 20:30:32 2016 +0000
Revision:
45:c42166b2878c
More work in progress on CCD speedups;

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 45:c42166b2878c 107
mjr 45:c42166b2878c 108 /**
mjr 45:c42166b2878c 109 * Start the transfer
mjr 45:c42166b2878c 110 *
mjr 45:c42166b2878c 111 * @param length - number of BYTES to be moved by the DMA
mjr 45:c42166b2878c 112 */
mjr 45:c42166b2878c 113 int start(uint32_t length);
mjr 45:c42166b2878c 114
mjr 45:c42166b2878c 115 /**
mjr 45:c42166b2878c 116 * Start a new transfer with the same parameters as last time
mjr 45:c42166b2878c 117 */
mjr 45:c42166b2878c 118 int restart(uint32_t length);
mjr 45:c42166b2878c 119
mjr 45:c42166b2878c 120 /**
mjr 45:c42166b2878c 121 * Is the DMA channel busy
mjr 45:c42166b2878c 122 *
mjr 45:c42166b2878c 123 * @param channel - channel to check, -1 = current channel
mjr 45:c42166b2878c 124 * @return - true if it is busy
mjr 45:c42166b2878c 125 */
mjr 45:c42166b2878c 126 bool isBusy( int channel = -1 );
mjr 45:c42166b2878c 127
mjr 45:c42166b2878c 128 /**
mjr 45:c42166b2878c 129 * Number of bytes remaining in running transfer. This reads the controller
mjr 45:c42166b2878c 130 * register with the remaining byte count, which the hardware updates each
mjr 45:c42166b2878c 131 * time it completes a destination transfer.
mjr 45:c42166b2878c 132 */
mjr 45:c42166b2878c 133 uint32_t remaining(int channel = -1);
mjr 45:c42166b2878c 134
mjr 45:c42166b2878c 135 /**
mjr 45:c42166b2878c 136 * Attach an interrupt upon completion of DMA transfer or error
mjr 45:c42166b2878c 137 *
mjr 45:c42166b2878c 138 * @param function - function to call upon completion (may be a member function)
mjr 45:c42166b2878c 139 */
mjr 45:c42166b2878c 140 void attach(void (*function)(void)) {
mjr 45:c42166b2878c 141 _callback.attach(function);
mjr 45:c42166b2878c 142 }
mjr 45:c42166b2878c 143
mjr 45:c42166b2878c 144 template<typename T>
mjr 45:c42166b2878c 145 void attach(T *object, void (T::*member)(void)) {
mjr 45:c42166b2878c 146 _callback.attach(object, member);
mjr 45:c42166b2878c 147 }
mjr 45:c42166b2878c 148
mjr 45:c42166b2878c 149 #ifdef RTOS_H
mjr 45:c42166b2878c 150 /**
mjr 45:c42166b2878c 151 * Start a DMA transfer similar to start, however block current Thread
mjr 45:c42166b2878c 152 * until the transfer is finished
mjr 45:c42166b2878c 153 *
mjr 45:c42166b2878c 154 * When using this function only the current Thread is halted.
mjr 45:c42166b2878c 155 * The Thread is moved to Waiting state: other Threads will continue
mjr 45:c42166b2878c 156 * to run normally.
mjr 45:c42166b2878c 157 *
mjr 45:c42166b2878c 158 * This function is only available if you included rtos.h before
mjr 45:c42166b2878c 159 * including SimpleDMA.h.
mjr 45:c42166b2878c 160 *
mjr 45:c42166b2878c 161 * @param length - number of BYTES to be moved by the DMA
mjr 45:c42166b2878c 162 */
mjr 45:c42166b2878c 163 void wait(int length) {
mjr 45:c42166b2878c 164 id = Thread::gettid();
mjr 45:c42166b2878c 165 this->attach(this, &SimpleDMA::waitCallback);
mjr 45:c42166b2878c 166 this->start(length);
mjr 45:c42166b2878c 167 Thread::signal_wait(0x1);
mjr 45:c42166b2878c 168 }
mjr 45:c42166b2878c 169 #endif
mjr 45:c42166b2878c 170
mjr 45:c42166b2878c 171 protected:
mjr 45:c42166b2878c 172 int _channel;
mjr 45:c42166b2878c 173 SimpleDMA_Trigger _trigger;
mjr 45:c42166b2878c 174 uint32_t _source;
mjr 45:c42166b2878c 175 uint32_t _destination;
mjr 45:c42166b2878c 176 bool source_inc;
mjr 45:c42166b2878c 177 bool destination_inc;
mjr 45:c42166b2878c 178 uint8_t source_size;
mjr 45:c42166b2878c 179 uint8_t destination_size;
mjr 45:c42166b2878c 180 uint32_t source_mod;
mjr 45:c42166b2878c 181 uint32_t destination_mod;
mjr 45:c42166b2878c 182 bool cycle_steal;
mjr 45:c42166b2878c 183
mjr 45:c42166b2878c 184 bool auto_channel;
mjr 45:c42166b2878c 185
mjr 45:c42166b2878c 186 //IRQ handlers
mjr 45:c42166b2878c 187 FunctionPointer _callback;
mjr 45:c42166b2878c 188 void irq_handler(void);
mjr 45:c42166b2878c 189
mjr 45:c42166b2878c 190 static SimpleDMA *irq_owner[DMA_CHANNELS];
mjr 45:c42166b2878c 191
mjr 45:c42166b2878c 192 static void irq_handler0( void );
mjr 45:c42166b2878c 193
mjr 45:c42166b2878c 194 #if DMA_IRQS > 1
mjr 45:c42166b2878c 195 static void irq_handler1( void );
mjr 45:c42166b2878c 196 static void irq_handler2( void );
mjr 45:c42166b2878c 197 static void irq_handler3( void );
mjr 45:c42166b2878c 198 #endif
mjr 45:c42166b2878c 199
mjr 45:c42166b2878c 200 //Keep searching until we find a non-busy channel, start with lowest channel number
mjr 45:c42166b2878c 201 int getFreeChannel(void);
mjr 45:c42166b2878c 202
mjr 45:c42166b2878c 203 #ifdef RTOS_H
mjr 45:c42166b2878c 204 osThreadId id;
mjr 45:c42166b2878c 205 void waitCallback(void) {
mjr 45:c42166b2878c 206 osSignalSet(id, 0x1);
mjr 45:c42166b2878c 207 }
mjr 45:c42166b2878c 208 #endif
mjr 45:c42166b2878c 209 };
mjr 45:c42166b2878c 210 #endif