A simple library to access the DMA functionality.
Fork of SimpleDMA by
Diff: SimpleDMA.h
- Revision:
- 3:34f5bf8adfa0
- Parent:
- 2:fe2fcaa72434
- Child:
- 4:c3a84c6c432c
--- a/SimpleDMA.h Sun Dec 22 21:42:49 2013 +0000 +++ b/SimpleDMA.h Thu Dec 26 12:19:29 2013 +0000 @@ -18,7 +18,12 @@ */ class SimpleDMA { public: -SimpleDMA(int channel = 0); +/** +* Constructor +* +* @param channel - optional parameter which channel should be used, default is automatic channel selection +*/ +SimpleDMA(int channel = -1); /** * Set the source of the DMA transfer @@ -33,11 +38,11 @@ * * @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) +* @param size - wordsize in bits (optional, generally can be omitted) * @return - 0 on success */ template<typename Type> -int source(Type* pointer, bool autoinc, int size = sizeof(Type*)) { +int source(Type* pointer, bool autoinc, int size = sizeof(Type) * 8) { return setAddress((uint32_t)pointer, size, true, autoinc); } @@ -54,11 +59,11 @@ * * @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) +* @param size - wordsize in bits (optional, generally can be omitted) * @return - 0 on success */ template<typename Type> -int destination(Type* pointer, bool autoinc, int size = sizeof(Type*)) { +int destination(Type* pointer, bool autoinc, int size = sizeof(Type) * 8) { return setAddress((uint32_t)pointer, size, false, autoinc); } @@ -76,6 +81,15 @@ int trigger(SimpleDMA_Trigger trig); /** +* Set the DMA channel +* +* Generally you will not need to call this function, the constructor does so for you +* +* @param chan - DMA channel to use, -1 = variable channel (highest priority channel which is available) +*/ +void channel(int chan); + +/** * Start the transfer * * @param length - number of BYTES to be moved by the DMA @@ -85,9 +99,10 @@ /** * Is the DMA channel busy * +* @param channel - channel to check, -1 = current channel * @return - true if it is busy */ -bool isBusy( void ); +bool isBusy( int channel = -1 ); /** * Attach an interrupt upon completion of DMA transfer or error @@ -106,6 +121,19 @@ } #ifdef RTOS_H +/** +* Start a DMA transfer similar to start, however block current Thread +* until the transfer is finished +* +* When using this function only the current Thread is halted. +* The Thread is moved to Waiting state: other Threads will continue +* to run normally. +* +* This function is only available if you included rtos.h before +* including SimpleDMA.h. +* +* @param length - number of BYTES to be moved by the DMA +*/ void wait(int length) { id = Thread::gettid(); this->attach(this, &SimpleDMA::waitCallback); @@ -115,15 +143,10 @@ #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; +bool auto_channel; uint32_t SAR, DAR, DSR, DCR; uint8_t CHCFG; @@ -159,5 +182,16 @@ } #endif +//Keep searching until we find a non-busy channel, start with lowest channel number +int getFreeChannel(void) { + int retval = 0; + while(1) { + if (!isBusy(retval)) + return retval; + retval++; + if (retval >= DMA_CHANNELS) + retval = 0; + } +} }; #endif \ No newline at end of file