MODDMA GPDMA Controller New features: transfer pins to memory buffer under periodic timer control and send double buffers to DAC
Dependents: FirstTest WaveSim IO-dma-memmem DACDMAfuncgenlib ... more
Revision 6:40d38be4bb59, committed 2010-11-23
- Comitter:
- AjK
- Date:
- Tue Nov 23 21:34:21 2010 +0000
- Parent:
- 5:c39b22fa0c60
- Child:
- 7:347110c7aefc
- Commit message:
- 1.3
Changed in this revision
--- a/ChangeLog.c Tue Nov 23 16:04:32 2010 +0000 +++ b/ChangeLog.c Tue Nov 23 21:34:21 2010 +0000 @@ -1,5 +1,14 @@ /* $Id:$ +1.3 - 23/10/2010 + + * Added the LLI class wrapper. + * Added checking channel's LLI for non-null before auto-disable + of a channel with the ISR. + * Tested with MODSERIAL which is now natively MODDMA "aware". + MODSERIAL can now, using MODDMA, send blocks of bytes out + of it's TX port under DMA control. + 1.2 - 23/10/2010 * Improved the IRQ callback attachment API to make
--- a/MODDMA.cpp Tue Nov 23 16:04:32 2010 +0000 +++ b/MODDMA.cpp Tue Nov 23 21:34:21 2010 +0000 @@ -97,9 +97,12 @@ // Not, we don't check Active here as it may block inside // an ISR, we just shut it down immediately. If the user // must wait for completion they should implement their - // own ISR. + // own ISR. But only disable if the LLI linked list register + // is null otherwise we can crap out a series of transfers. if (moddma_p->Enabled( (MODDMA::CHANNELS)channel_number )) { - moddma_p->Disable( (MODDMA::CHANNELS)channel_number ); + if (moddma_p->lli(channel_number) == 0 ) { + moddma_p->Disable( (MODDMA::CHANNELS)channel_number ); + } } } } @@ -120,9 +123,12 @@ // Not, we don't check Active here as it may block inside // an ISR, we just shut it down immediately. If the user // must wait for completion they should implement their - // own ISR. + // own ISR. But only disable if the LLI linked list register + // is null otherwise we can crap out a series of transfers. if (moddma_p->Enabled( (MODDMA::CHANNELS)channel_number )) { - moddma_p->Disable( (MODDMA::CHANNELS)channel_number ); + if (moddma_p->lli(channel_number) == 0 ) { + moddma_p->Disable( (MODDMA::CHANNELS)channel_number ); + } } } }
--- a/MODDMA.h Tue Nov 23 16:04:32 2010 +0000 +++ b/MODDMA.h Tue Nov 23 21:34:21 2010 +0000 @@ -21,7 +21,7 @@ @file MODDMA.h @purpose Adds DMA controller and multiple transfer configurations - @version 1.2 + @version see ChangeLog.c @date Nov 2010 @author Andy Kirkham */ @@ -162,14 +162,31 @@ FunctionPointer *isrIntErrStat; }; - /* -typedef struct { +/** + * @brief The MODDMA configuration system (linked list items) + * @author Andy Kirkham + * @see http://mbed.org/cookbook/MODDMA_Config + * @see MODDMA + * @see MODDMA_Config + * @see API + */ +class MODDMA_LLI { +public: + class MODDMA_LLI *srcAddr(uint32_t n) { SrcAddr = n; return this; } + class MODDMA_LLI *dstAddr(uint32_t n) { DstAddr = n; return this; } + class MODDMA_LLI *nextLLI(uint32_t n) { NextLLI = n; return this; } + class MODDMA_LLI *control(uint32_t n) { Control = n; return this; } + uint32_t srcAddr(void) { return SrcAddr; } + uint32_t dstAddr(void) { return DstAddr; } + uint32_t nextLLI(void) { return NextLLI; } + uint32_t control(void) { return Control; } +protected: uint32_t SrcAddr; //!< Source Address uint32_t DstAddr; //!< Destination address uint32_t NextLLI; //!< Next LLI address, otherwise set to '0' uint32_t Control; //!< GPDMA Control of this LLI -} GPDMA_LLI_t; -*/ +}; + /** @@ -346,6 +363,15 @@ * Used to setup the DMA controller to prepare for a data transfer. * * @ingroup API + * @param isConstructorCalling Set true when called from teh constructor + * @param + */ + void init(bool isConstructorCalling, int Channels = 0xFF, int Tc = 0xFF, int Err = 0xFF); + + /** + * Used to setup the DMA controller to prepare for a data transfer. + * + * @ingroup API * @param c A pointer to an instance of MODDMA_Config to setup. */ Status Setup(MODDMA_Config *c); @@ -553,10 +579,10 @@ * @return this */ template<typename T> - class MODDMA_Config * attach_tc(T* tptr, void (T::*mptr)(void)) { + void attach_tc(T* tptr, void (T::*mptr)(void)) { if((mptr != NULL) && (tptr != NULL)) { isrIntTCStat.attach(tptr, mptr); - } + } } /** @@ -572,7 +598,7 @@ * @return this */ void attach_err(void (*fptr)(void)) { - isrIntErrStat.attach(fptr); + isrIntErrStat.attach(fptr); } /** @@ -584,21 +610,30 @@ * @return this */ template<typename T> - class MODDMA_Config * attach_err(T* tptr, void (T::*mptr)(void)) { + void attach_err(T* tptr, void (T::*mptr)(void)) { if((mptr != NULL) && (tptr != NULL)) { isrIntErrStat.attach(tptr, mptr); } } /** + * Get the Linked List index regsiter for the requested channel. + * + * @param channelNum The channel number. + * @return uint32_t The valie of the DMACCLLI register + */ + uint32_t lli(int channelNum) { + LPC_GPDMACH_TypeDef *pChannel = (LPC_GPDMACH_TypeDef *)Channel_p( channelNum & 0x7 ); + return pChannel->DMACCLLI; + } + + /** * The MODDMA controllers error interrupt callback. */ FunctionPointer isrIntErrStat; protected: - - void init(bool isConstructorCalling, int Channels = 0xFF, int Tc = 0xFF, int Err = 0xFF); - + // Data LUTs. uint32_t LUTPerAddr(int n); uint8_t LUTPerBurst(int n);
--- a/example1.cpp Tue Nov 23 16:04:32 2010 +0000 +++ b/example1.cpp Tue Nov 23 21:34:21 2010 +0000 @@ -2,13 +2,14 @@ #include "mbed.h" #include "MODDMA.h" +#include "MODSERIAL.h" DigitalOut led1(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); DigitalOut led4(LED4); MODDMA dma; -Serial pc(USBTX, USBRX); +MODSERIAL pc(USBTX, USBRX); // Function prototypes for IRQ callbacks. // See definitions following main() below.