A simple library to access the DMA functionality.
Fork of SimpleDMA by
SimpleDMA.h
00001 #ifndef SIMPLEDMA_H 00002 #define SIMPLEDMA_H 00003 00004 #ifdef RTOS_H 00005 #include "rtos.h" 00006 #endif 00007 00008 #include "mbed.h" 00009 #include "SimpleDMA_KL25.h" 00010 #include "SimpleDMA_LPC1768.h" 00011 00012 00013 /** 00014 * SimpleDMA, DMA made simple! (Okay that was bad) 00015 * 00016 * A class to easily make basic DMA operations happen. Not all features 00017 * of the DMA peripherals are used, but the main ones are: From and to memory 00018 * and peripherals, either continiously or triggered 00019 */ 00020 class SimpleDMA { 00021 public: 00022 /** 00023 * Constructor 00024 * 00025 * @param channel - optional parameter which channel should be used, default is automatic channel selection 00026 */ 00027 SimpleDMA(int channel = -1); 00028 00029 /** 00030 * Set the source of the DMA transfer 00031 * 00032 * Autoincrement increments the pointer after each transfer. If the source 00033 * is an array this should be true, if it is a peripheral or a single memory 00034 * location it should be false. 00035 * 00036 * The source can be any pointer to any memory location. Automatically 00037 * the wordsize is calculated depending on the type, if required you can 00038 * also override this. 00039 * 00040 * @param pointer - pointer to the memory location 00041 * @param autoinc - should the pointer be incremented by the DMA module 00042 * @param size - wordsize in bits (optional, generally can be omitted) 00043 * @return - 0 on success 00044 */ 00045 template<typename Type> 00046 void source(Type* pointer, bool autoinc, int size = sizeof(Type) * 8) { 00047 _source = (uint32_t)pointer; 00048 source_inc = autoinc; 00049 source_size = size; 00050 } 00051 00052 /** 00053 * Set the destination of the DMA transfer 00054 * 00055 * Autoincrement increments the pointer after each transfer. If the source 00056 * is an array this should be true, if it is a peripheral or a single memory 00057 * location it should be false. 00058 * 00059 * The destination can be any pointer to any memory location. Automatically 00060 * the wordsize is calculated depending on the type, if required you can 00061 * also override this. 00062 * 00063 * @param pointer - pointer to the memory location 00064 * @param autoinc - should the pointer be incremented by the DMA module 00065 * @param size - wordsize in bits (optional, generally can be omitted) 00066 * @return - 0 on success 00067 */ 00068 template<typename Type> 00069 void destination(Type* pointer, bool autoinc, int size = sizeof(Type) * 8) { 00070 _destination = (uint32_t)pointer; 00071 destination_inc = autoinc; 00072 destination_size = size; 00073 } 00074 00075 /** 00076 * Set the trigger for the DMA operation 00077 * 00078 * In SimpleDMA_[yourdevice].h you can find the names of the different triggers. 00079 * Trigger_ALWAYS is defined for all devices, it will simply move the data 00080 * as fast as possible. Used for memory-memory transfers. If nothing else is set 00081 * that will be used by default. 00082 * 00083 * @param trig - trigger to use 00084 * @param return - 0 on success 00085 */ 00086 void trigger(SimpleDMA_Trigger trig) { 00087 _trigger = trig; 00088 } 00089 00090 /** 00091 * Set the DMA channel 00092 * 00093 * Generally you will not need to call this function, the constructor does so for you 00094 * 00095 * @param chan - DMA channel to use, -1 = variable channel (highest priority channel which is available) 00096 */ 00097 void channel(int chan); 00098 00099 /** 00100 * Start the transfer 00101 * 00102 * @param length - number of BYTES to be moved by the DMA 00103 */ 00104 int start(int length); 00105 00106 /** 00107 * Is the DMA channel busy 00108 * 00109 * @param channel - channel to check, -1 = current channel 00110 * @return - true if it is busy 00111 */ 00112 bool isBusy( int channel = -1 ); 00113 00114 /** 00115 * Attach an interrupt upon completion of DMA transfer or error 00116 * 00117 * @param function - function to call upon completion (may be a member function) 00118 */ 00119 void attach(void (*function)(void)) { 00120 _callback.attach(function); 00121 } 00122 00123 template<typename T> 00124 void attach(T *object, void (T::*member)(void)) { 00125 _callback.attach(object, member); 00126 } 00127 00128 #ifdef RTOS_H 00129 /** 00130 * Start a DMA transfer similar to start, however block current Thread 00131 * until the transfer is finished 00132 * 00133 * When using this function only the current Thread is halted. 00134 * The Thread is moved to Waiting state: other Threads will continue 00135 * to run normally. 00136 * 00137 * This function is only available if you included rtos.h before 00138 * including SimpleDMA.h. 00139 * 00140 * @param length - number of BYTES to be moved by the DMA 00141 */ 00142 void wait(int length) { 00143 id = Thread::gettid(); 00144 this->attach(this, &SimpleDMA::waitCallback); 00145 this->start(length); 00146 Thread::signal_wait(0x1); 00147 } 00148 #endif 00149 00150 protected: 00151 int _channel; 00152 SimpleDMA_Trigger _trigger; 00153 uint32_t _source; 00154 uint32_t _destination; 00155 bool source_inc; 00156 bool destination_inc; 00157 uint8_t source_size; 00158 uint8_t destination_size; 00159 00160 bool auto_channel; 00161 00162 //IRQ handlers 00163 FunctionPointer _callback; 00164 void irq_handler(void); 00165 00166 static SimpleDMA *irq_owner[DMA_CHANNELS]; 00167 00168 static void irq_handler0( void ); 00169 00170 #if DMA_IRQS > 1 00171 static void irq_handler1( void ); 00172 static void irq_handler2( void ); 00173 static void irq_handler3( void ); 00174 #endif 00175 00176 //Keep searching until we find a non-busy channel, start with lowest channel number 00177 int getFreeChannel(void); 00178 00179 #ifdef RTOS_H 00180 osThreadId id; 00181 void waitCallback(void) { 00182 osSignalSet(id, 0x1); 00183 } 00184 #endif 00185 }; 00186 #endif
Generated on Fri Jul 15 2022 17:30:44 by 1.7.2