A simple library to access the DMA functionality.
Fork of SimpleDMA by
SimpleDMA.h
- Committer:
- Sissors
- Date:
- 2013-12-22
- Revision:
- 2:fe2fcaa72434
- Parent:
- 1:0b73b00bcee8
- Child:
- 3:34f5bf8adfa0
File content as of revision 2:fe2fcaa72434:
#ifndef SIMPLEDMA_H #define SIMPLEDMA_H #ifdef RTOS_H #include "rtos.h" #endif #include "mbed.h" #include "SimpleDMA_KL25.h" /** * SimpleDMA, DMA made simple! (Okay that was bad) * * A class to easily make basic DMA operations happen. Not all features * of the DMA peripherals are used, but the main ones are: From and to memory * and peripherals, either continiously or triggered */ class SimpleDMA { public: SimpleDMA(int channel = 0); /** * Set the source of the DMA transfer * * Autoincrement increments the pointer after each transfer. If the source * is an array this should be true, if it is a peripheral or a single memory * location it should be false. * * The source can be any pointer to any memory location. Automatically * the wordsize is calculated depending on the type, if required you can * also override this. * * @param pointer - pointer to the memory location * @param autoinc - should the pointer be incremented by the DMA module * @param size - size of the transfer (optional, generally can be omitted) * @return - 0 on success */ template<typename Type> int source(Type* pointer, bool autoinc, int size = sizeof(Type*)) { return setAddress((uint32_t)pointer, size, true, autoinc); } /** * Set the destination of the DMA transfer * * Autoincrement increments the pointer after each transfer. If the source * is an array this should be true, if it is a peripheral or a single memory * location it should be false. * * The destination can be any pointer to any memory location. Automatically * the wordsize is calculated depending on the type, if required you can * also override this. * * @param pointer - pointer to the memory location * @param autoinc - should the pointer be incremented by the DMA module * @param size - size of the transfer (optional, generally can be omitted) * @return - 0 on success */ template<typename Type> int destination(Type* pointer, bool autoinc, int size = sizeof(Type*)) { return setAddress((uint32_t)pointer, size, false, autoinc); } /** * Set the trigger for the DMA operation * * In SimpleDMA_[yourdevice].h you can find the names of the different triggers. * Trigger_ALWAYS is defined for all devices, it will simply move the data * as fast as possible. Used for memory-memory transfers. If nothing else is set * that will be used by default. * * @param trig - trigger to use * @param return - 0 on success */ int trigger(SimpleDMA_Trigger trig); /** * Start the transfer * * @param length - number of BYTES to be moved by the DMA */ int start(int length); /** * Is the DMA channel busy * * @return - true if it is busy */ bool isBusy( void ); /** * Attach an interrupt upon completion of DMA transfer or error * * @param function - function to call upon completion (may be a member function) */ void attach(void (*function)(void)) { irq_en = function; _callback.attach(function); } template<typename T> void attach(T *object, void (T::*member)(void)) { irq_en = object; _callback.attach(object, member); } #ifdef RTOS_H void wait(int length) { id = Thread::gettid(); this->attach(this, &SimpleDMA::waitCallback); this->start(length); Thread::signal_wait(0x1); } #endif protected: /** * Set the DMA channel * * @param chan - DMA channel to use */ void channel(int chan); int setAddress(uint32_t address, int wordsize, bool source, bool autoinc); int _channel; uint32_t SAR, DAR, DSR, DCR; uint8_t CHCFG; //IRQ handlers FunctionPointer _callback; bool irq_en; void irq_handler(void); static SimpleDMA *irq_owner[4]; static void irq_handler0( void ) { if (irq_owner[0]!=NULL) irq_owner[0]->irq_handler(); } static void irq_handler1( void ) { if (irq_owner[1]!=NULL) irq_owner[1]->irq_handler(); } static void irq_handler2( void ) { if (irq_owner[2]!=NULL) irq_owner[2]->irq_handler(); } static void irq_handler3( void ) { if (irq_owner[3]!=NULL) irq_owner[3]->irq_handler(); } #ifdef RTOS_H osThreadId id; void waitCallback(void) { osSignalSet(id, 0x1); } #endif }; #endif