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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MODDMA.h Source File

MODDMA.h

00001 /*
00002     Copyright (c) 2010 Andy Kirkham
00003  
00004     Permission is hereby granted, free of charge, to any person obtaining a copy
00005     of this software and associated documentation files (the "Software"), to deal
00006     in the Software without restriction, including without limitation the rights
00007     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008     copies of the Software, and to permit persons to whom the Software is
00009     furnished to do so, subject to the following conditions:
00010  
00011     The above copyright notice and this permission notice shall be included in
00012     all copies or substantial portions of the Software.
00013  
00014     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020     THE SOFTWARE.
00021     
00022     @file          MODDMA.h 
00023     @purpose       Adds DMA controller and multiple transfer configurations
00024     @version       see ChangeLog.c
00025     @date          Nov 2010
00026     @author        Andy Kirkham    
00027 */
00028 
00029 #ifndef MODDMA_H
00030 #define MODDMA_H
00031 
00032 /** @defgroup API The MODDMA API */
00033 /** @defgroup MISC Misc MODSERIAL functions */
00034 /** @defgroup INTERNALS MODSERIAL Internals */
00035 
00036 #include "mbed.h"
00037 #include "iomacros.h"
00038 
00039 namespace AjK {
00040 
00041 /**
00042  * @brief The MODDMA configuration system
00043  * @author Andy Kirkham
00044  * @see http://mbed.org/cookbook/MODDMA_Config
00045  * @see MODDMA
00046  * @see API 
00047  *
00048  * <b>MODDMA_Config</b> defines a configuration that can be passed to the MODDMA controller
00049  * instance to perform a GPDMA data transfer.
00050  */
00051 class  MODDMA_Config {
00052 protected:
00053 
00054     // *****************************************
00055     // From GPDMA by NXP MCU SW Application Team
00056     // *****************************************
00057     
00058     uint32_t ChannelNum;        //!< DMA channel number, should be in range from 0 to 7. 
00059     uint32_t TransferSize;      //!< Length/Size of transfer 
00060     uint32_t TransferWidth;     //!< Transfer width - used for TransferType is GPDMA_TRANSFERTYPE_m2m only 
00061     uint32_t SrcMemAddr;        //!< Physical Src Addr, used in case TransferType is chosen as MODDMA::GPDMA_TRANSFERTYPE::m2m or MODDMA::GPDMA_TRANSFERTYPE::m2p 
00062     uint32_t DstMemAddr;        //!< Physical Destination Address, used in case TransferType is chosen as MODDMA::GPDMA_TRANSFERTYPE::m2m or MODDMA::GPDMA_TRANSFERTYPE::p2m 
00063     uint32_t TransferType;      //!< Transfer Type
00064     uint32_t SrcConn;           //!< Peripheral Source Connection type, used in case TransferType is chosen as
00065     uint32_t DstConn;           //!< Peripheral Destination Connection type, used in case TransferType is chosen as
00066     uint32_t DMALLI;            //!< Linker List Item structure data address if there's no Linker List, set as '0'
00067     uint32_t DMACSync;          //!< DMACSync if required.
00068     
00069     // Mbed specifics.
00070 
00071 public: 
00072    
00073     MODDMA_Config() {
00074         isrIntTCStat  = new FunctionPointer;
00075         isrIntErrStat = new FunctionPointer;
00076         ChannelNum    = 0xFFFF;
00077         TransferSize  = 0;
00078         TransferWidth = 0;
00079         SrcMemAddr    = 0;
00080         DstMemAddr    = 0;
00081         TransferType  = 0;
00082         SrcConn       = 0;
00083         DstConn       = 0;
00084         DMALLI        = 0;
00085         DMACSync      = 0;
00086     }
00087     
00088     ~MODDMA_Config() {
00089         delete(isrIntTCStat);
00090         delete(isrIntErrStat);
00091     }
00092         
00093     class MODDMA_Config * channelNum(uint32_t n)    { ChannelNum = n & 0x7;  return this; }
00094     class MODDMA_Config * transferSize(uint32_t n)  { TransferSize = n;      return this; }
00095     class MODDMA_Config * transferWidth(uint32_t n) { TransferWidth = n;     return this; }
00096     class MODDMA_Config * srcMemAddr(uint32_t n)    { SrcMemAddr = n;        return this; }
00097     class MODDMA_Config * dstMemAddr(uint32_t n)    { DstMemAddr = n;        return this; }
00098     class MODDMA_Config * transferType(uint32_t n)  { TransferType = n;      return this; }
00099     class MODDMA_Config * srcConn(uint32_t n)       { SrcConn = n;           return this; }
00100     class MODDMA_Config * dstConn(uint32_t n)       { DstConn = n;           return this; }
00101     class MODDMA_Config * dmaLLI(uint32_t n)        { DMALLI = n;            return this; }
00102     class MODDMA_Config * dmacSync(uint32_t n)      { DMACSync = n;          return this; }
00103     
00104     uint32_t channelNum(void)    { return ChannelNum;    }
00105     uint32_t transferSize(void)  { return TransferSize;  }
00106     uint32_t transferWidth(void) { return TransferWidth; }
00107     uint32_t srcMemAddr(void)    { return SrcMemAddr;    }
00108     uint32_t dstMemAddr(void)    { return DstMemAddr;    }
00109     uint32_t transferType(void)  { return TransferType;  }
00110     uint32_t srcConn(void)       { return SrcConn;       }
00111     uint32_t dstConn(void)       { return DstConn;       }
00112     uint32_t dmaLLI(void)        { return DMALLI;        }
00113     uint32_t dmacSync(void)      { return DMACSync; }
00114     
00115     /**
00116      * Attach a callback to the TC IRQ configuration.
00117      *
00118      * @param fptr A function pointer to call
00119      * @return this
00120      */
00121     class MODDMA_Config * attach_tc(void (*fptr)(void)) {  
00122         isrIntTCStat->attach(fptr); 
00123         return this;
00124     }
00125     
00126     /**
00127      * Attach a callback to the ERR IRQ configuration.
00128      *
00129      * @param fptr A function pointer to call
00130      * @return this
00131      */
00132     class MODDMA_Config * attach_err(void (*fptr)(void)) {  
00133         isrIntErrStat->attach(fptr);         
00134         return this;
00135     }
00136     
00137     /**
00138      * Attach a callback to the TC IRQ configuration.
00139      *
00140      * @param tptr A template pointer to the calling object
00141      * @param mptr A method pointer within the object to call.
00142      * @return this
00143      */
00144     template<typename T>
00145     class MODDMA_Config * attach_tc(T* tptr, void (T::*mptr)(void)) {  
00146         if((mptr != NULL) && (tptr != NULL)) {
00147             isrIntTCStat->attach(tptr, mptr);
00148         }
00149         return this;
00150     }
00151     
00152     /**
00153      * Attach a callback to the ERR IRQ configuration.
00154      *
00155      * @param tptr A template pointer to the calling object
00156      * @param mptr A method pointer within the object to call.
00157      * @return this
00158      */
00159     template<typename T>
00160     class MODDMA_Config * attach_err(T* tptr, void (T::*mptr)(void)) {  
00161         if((mptr != NULL) && (tptr != NULL)) {
00162             isrIntErrStat->attach(tptr, mptr);
00163         }
00164         return this;
00165     }
00166     FunctionPointer *isrIntTCStat;                        
00167     FunctionPointer *isrIntErrStat;                        
00168 };
00169 
00170 /**
00171  * @brief The MODDMA configuration system (linked list items)
00172  * @author Andy Kirkham
00173  * @see http://mbed.org/cookbook/MODDMA_Config
00174  * @see MODDMA
00175  * @see MODDMA_Config
00176  * @see API 
00177  */
00178 class MODDMA_LLI {
00179 public:
00180     class MODDMA_LLI *srcAddr(uint32_t n) { SrcAddr = n; return this; }
00181     class MODDMA_LLI *dstAddr(uint32_t n) { DstAddr = n; return this; }
00182     class MODDMA_LLI *nextLLI(uint32_t n) { NextLLI = n; return this; }
00183     class MODDMA_LLI *control(uint32_t n) { Control = n; return this; }
00184     uint32_t srcAddr(void) { return SrcAddr; }
00185     uint32_t dstAddr(void) { return DstAddr; }
00186     uint32_t nextLLI(void) { return NextLLI; }
00187     uint32_t control(void) { return Control; }
00188 
00189     uint32_t SrcAddr;    //!< Source Address 
00190     uint32_t DstAddr;    //!< Destination address 
00191     uint32_t NextLLI;    //!< Next LLI address, otherwise set to '0' 
00192     uint32_t Control;    //!< GPDMA Control of this LLI 
00193 };
00194 
00195 
00196 
00197  /**
00198  * @brief MODDMA GPDMA Controller
00199  * @author Andy Kirkham
00200  * @see http://mbed.org/cookbook/MODDMA
00201  * @see example1.cpp
00202  * @see API 
00203  *
00204  * <b>MODDMA</b> defines a GPDMA controller and multiple DMA configurations that allow for DMA
00205  * transfers from memory to memory, memory to peripheral or peripheral to memory.
00206  *
00207  * At the heart of the library is the MODDMA class that defines a single instance controller that
00208  * manages all the GPDMA hardware registers and interrupts. The controller can accept multiple
00209  * configurations that define the channel transfers. Each configuration specifies the source and 
00210  * destination information and other associated parts to maintain the transfer process.
00211  *
00212  * Standard example:
00213  * @code
00214  * #include "mbed.h"
00215  * #include "MODDMA.h"
00216  *
00217  * DigitalOut led1(LED1);
00218  * Serial pc(USBTX, USBRX); // tx, rx
00219  * MODDMA dma;
00220  *
00221  * int main() {
00222  *
00223  *     // Create a string buffer to send directly to a Uart/Serial
00224  *     char s[] = "***DMA*** ABCDEFGHIJKLMNOPQRSTUVWXYZ ***DMA***";
00225  *
00226  *     // Create a transfer configuarion
00227  *     MODDMA_Config *config = new MODDMA_Config;
00228  *
00229  *     // Provide a "minimal" setup for demo purposes.
00230  *     config
00231  *      ->channelNum    ( MODDMA::Channel_0 )   // The DMA channel to use.
00232  *      ->srcMemAddr    ( (uint32_t) &s )       // A pointer to the buffer to send.
00233  *      ->transferSize  ( sizeof(s) )           // The size of that buffer.
00234  *      ->transferType  ( MODDMA::m2p )         // Source is memory, destination is peripheral
00235  *      ->dstConn       ( MODDMA::UART0_Tx )    // Specifically, peripheral is Uart0 TX (USBTX, USBRX)
00236  *    ; // config end.
00237  *
00238  *    // Pass the configuration to the MODDMA controller.
00239  *    dma.Setup( config );
00240  *
00241  *    // Enable the channel and begin transfer.
00242  *    dma.Enable( config->channelNum() );
00243  *
00244  *    while(1) {
00245  *         led1 = !led1;
00246  *         wait(0.25);
00247  *     }
00248  * }
00249  * @endcode
00250  */
00251 class MODDMA
00252 {
00253 public:
00254 
00255     //! Channel definitions.
00256     enum CHANNELS {
00257           Channel_0  = 0     /*!< Channel 0 */ 
00258         , Channel_1          /*!< Channel 1 */ 
00259         , Channel_2          /*!< Channel 2 */ 
00260         , Channel_3          /*!< Channel 3 */ 
00261         , Channel_4          /*!< Channel 4 */ 
00262         , Channel_5          /*!< Channel 5 */ 
00263         , Channel_6          /*!< Channel 6 */ 
00264         , Channel_7          /*!< Channel 7 */ 
00265     };
00266     
00267     //! Interrupt callback types.
00268     enum IrqType_t {
00269           TcIrq  = 0     /*!< Terminal Count interrupt */
00270         , ErrIrq         /*!< Error interrupt */
00271     };
00272     
00273     //! Return status codes.
00274     enum Status {
00275           Ok             = 0     /*!< Ok, suceeded */
00276         , Error          = -1    /*!< General error */
00277         , ErrChInUse     = -2    /*!< Specific error, channel in use */
00278     };
00279     
00280     //! DMA Connection number definitions 
00281     enum GPDMA_CONNECTION {
00282           SSP0_Tx        = 0UL   /*!< SSP0 Tx */
00283         , SSP0_Rx        = 1UL   /*!< SSP0 Rx */
00284         , SSP1_Tx        = 2UL   /*!< SSP1 Tx */
00285         , SSP1_Rx        = 3UL   /*!< SSP1 Rx */
00286         , ADC            = 4UL   /*!< ADC */
00287         , I2S_Channel_0  = 5UL   /*!< I2S channel 0 */
00288         , I2S_Channel_1  = 6UL   /*!< I2S channel 1 */
00289         , DAC            = 7UL   /*!< DAC */
00290         , UART0_Tx       = 8UL   /*!< UART0 Tx */
00291         , UART0_Rx       = 9UL   /*!< UART0 Rx */
00292         , UART1_Tx       = 10UL  /*!< UART1 Tx */
00293         , UART1_Rx       = 11UL  /*!< UART1 Rx */
00294         , UART2_Tx       = 12UL  /*!< UART2 Tx */
00295         , UART2_Rx       = 13UL  /*!< UART2 Rx */
00296         , UART3_Tx       = 14UL  /*!< UART3 Tx */
00297         , UART3_Rx       = 15UL  /*!< UART3 Rx */
00298         , MAT0_0         = 16UL  /*!< MAT0.0 */
00299         , MAT0_1         = 17UL  /*!< MAT0.1 */
00300         , MAT1_0         = 18UL  /*!< MAT1.0 */
00301         , MAT1_1         = 19UL  /*!< MAT1.1 */
00302         , MAT2_0        = 20UL  /**< MAT2.0 */
00303         , MAT2_1         = 21UL  /*!< MAT2.1 */
00304         , MAT3_0         = 22UL  /*!< MAT3.0 */
00305         , MAT3_1         = 23UL  /*!< MAT3.1 */
00306     };
00307 
00308     //! GPDMA Transfer type definitions 
00309     enum  GPDMA_TRANSFERTYPE {
00310           m2m  = 0UL     /*!< Memory to memory - DMA control */
00311         , m2p  = 1UL     /*!< Memory to peripheral - DMA control */
00312         , p2m  = 2UL     /*!< Peripheral to memory - DMA control */
00313         , p2p  = 3UL     /*!< Src peripheral to dest peripheral - DMA control */         
00314         , g2m  = 4UL     /*!< Psuedo special case for reading "peripheral GPIO" that's memory mapped. */
00315         , m2g  = 5UL     /*!< Psuedo Special case for writing "peripheral GPIO" that's memory mapped. */        
00316     };   
00317 
00318     //! Burst size in Source and Destination definitions */
00319     enum GPDMA_BSIZE {
00320           _1     = 0UL   /*!< Burst size = 1 */
00321         , _4     = 1UL   /*!< Burst size = 4 */
00322         , _8     = 2UL   /*!< Burst size = 8 */
00323         , _16    = 3UL   /*!< Burst size = 16 */
00324         , _32    = 4UL   /*!< Burst size = 32 */
00325         , _64    = 5UL   /*!< Burst size = 64 */
00326         , _128   = 6UL   /*!< Burst size = 128 */
00327         , _256   = 7UL   /*!< Burst size = 256 */
00328     };
00329     
00330     //! Width in Src transfer width and Dest transfer width definitions */
00331     enum GPDMA_WIDTH {
00332           byte      = 0UL    /*!< Width = 1 byte */
00333         , halfword  = 1UL    /*!< Width = 2 bytes */
00334         , word      = 2UL    /*!< Width = 4 bytes */
00335     };
00336     
00337     //! DMA Request Select Mode definitions. */
00338     enum GPDMA_REQSEL {
00339           uart   = 0UL   /*!< UART TX/RX is selected */
00340         , timer  = 1UL   /*!< Timer match is selected */
00341     };
00342 
00343     //! GPDMA Control register bits.
00344     enum Config {
00345           _E  = 1        /*!< DMA Controller enable */
00346         , _M  = 2        /*!< AHB Master endianness configuration */
00347     };    
00348 
00349     //! GPDMA Channel config register bits.
00350     enum CConfig {
00351           _CE   = (1UL << 0)     /*!< Channel enable */
00352         , _IE   = (1UL << 14)    /*!< Interrupt error mask */
00353         , _ITC  = (1UL << 15)    /*!< Terminal count interrupt mask */
00354         , _L    = (1UL << 16)    /*!< Lock */
00355         , _A    = (1UL << 17)    /*!< Active */
00356         , _H    = (1UL << 18)    /*!< Halt */
00357     };
00358     
00359     /**
00360      * The MODDMA constructor is used to initialise the DMA controller object.
00361      */    
00362     MODDMA() { init(true); }
00363     
00364     /**
00365      * The MODDMA destructor.
00366      */    
00367     ~MODDMA() {}
00368     
00369     /**
00370      * Used to setup the DMA controller to prepare for a data transfer.
00371      *
00372      * @ingroup API
00373      * @param isConstructorCalling Set true when called from teh constructor
00374      * @param 
00375      */
00376     void init(bool isConstructorCalling, int Channels = 0xFF, int Tc = 0xFF, int Err = 0xFF);
00377     
00378     /**
00379      * Used to setup and enable the DMA controller.
00380      *
00381      * @see Setup
00382      * @see Enable
00383      * @ingroup API
00384      * @param c A pointer to an instance of MODDMA_Config to setup.
00385      */
00386     uint32_t Prepare(MODDMA_Config *c) {
00387         uint32_t u = Setup(c);
00388         if (u) Enable(c);
00389         return u;
00390     }
00391     
00392     /**
00393      * Used to setup the DMA controller to prepare for a data transfer.
00394      *
00395      * @ingroup API
00396      * @param c A pointer to an instance of MODDMA_Config to setup.
00397      */
00398     uint32_t Setup(MODDMA_Config *c);
00399     
00400     /**
00401      * Enable and begin data transfer.
00402      *
00403      * @ingroup API
00404      * @param ChannelNumber Type CHANNELS, the channel number to enable
00405      */
00406     void Enable(CHANNELS ChannelNumber);
00407     
00408     /**
00409      * Enable and begin data transfer (overloaded function)
00410      *
00411      * @ingroup API
00412      * @param ChannelNumber Type uin32_t, the channel number to enable
00413      */
00414     void Enable(uint32_t ChannelNumber) { Enable((CHANNELS)(ChannelNumber & 0x7)); }
00415     
00416     /**
00417      * Enable and begin data transfer (overloaded function)
00418      *
00419      * @ingroup API
00420      * @param config A pointer to teh configuration
00421      */
00422     void Enable(MODDMA_Config *config) { Enable( config->channelNum() ); }
00423         
00424     
00425     /**
00426      * Disable a channel and end data transfer.
00427      *
00428      * @ingroup API
00429      * @param ChannelNumber Type CHANNELS, the channel number to enable
00430      */
00431     void Disable(CHANNELS ChannelNumber);
00432     
00433     /**
00434      * Disable a channel and end data transfer (overloaded function)
00435      *
00436      * @ingroup API
00437      * @param ChannelNumber Type uin32_t, the channel number to disable
00438      */
00439     void Disable(uint32_t ChannelNumber) { Disable((CHANNELS)(ChannelNumber & 0x7)); }
00440     
00441     /**
00442      * Is the specified channel enabled?
00443      *
00444      * @ingroup API
00445      * @param ChannelNumber Type CHANNELS, the channel number to test
00446      * @return bool true if enabled, false otherwise.
00447      */
00448     bool Enabled(CHANNELS ChannelNumber);
00449     
00450     /**
00451      * Is the specified channel enabled? (overloaded function)
00452      *
00453      * @ingroup API
00454      * @param ChannelNumber Type uin32_t, the channel number to test
00455      * @return bool true if enabled, false otherwise.
00456      */
00457     bool Enabled(uint32_t ChannelNumber) { return Enabled((CHANNELS)(ChannelNumber & 0x7)); }
00458     
00459     __INLINE uint32_t IntStat(uint32_t n)            { return (1UL << n) & 0xFF; }
00460     __INLINE uint32_t IntTCStat_Ch(uint32_t n)       { return (1UL << n) & 0xFF; }
00461     __INLINE uint32_t IntTCClear_Ch(uint32_t n)      { return (1UL << n) & 0xFF; }
00462     __INLINE uint32_t IntErrStat_Ch(uint32_t n)      { return (1UL << n) & 0xFF; }
00463     __INLINE uint32_t IntErrClr_Ch(uint32_t n)       { return (1UL << n) & 0xFF; }
00464     __INLINE uint32_t RawIntErrStat_Ch(uint32_t n)   { return (1UL << n) & 0xFF; }
00465     __INLINE uint32_t EnbldChns_Ch(uint32_t n)       { return (1UL << n) & 0xFF; }
00466     __INLINE uint32_t SoftBReq_Src(uint32_t n)       { return (1UL << n) & 0xFFFF; }
00467     __INLINE uint32_t SoftSReq_Src(uint32_t n)       { return (1UL << n) & 0xFFFF; }
00468     __INLINE uint32_t SoftLBReq_Src(uint32_t n)      { return (1UL << n) & 0xFFFF; }
00469     __INLINE uint32_t SoftLSReq_Src(uint32_t n)      { return (1UL << n) & 0xFFFF; }
00470     __INLINE uint32_t Sync_Src(uint32_t n)           { return (1UL << n) & 0xFFFF; }
00471     __INLINE uint32_t ReqSel_Input(uint32_t n)       { return (1UL << (n - 8)) & 0xFF; }
00472     
00473 
00474     __INLINE uint32_t CxControl_TransferSize(uint32_t n)     { return (n & 0xFFF) << 0; }
00475     __INLINE uint32_t CxControl_SBSize(uint32_t n)           { return (n & 0x7) << 12; }
00476     __INLINE uint32_t CxControl_DBSize(uint32_t n)           { return (n & 0x7) << 15; }
00477     __INLINE uint32_t CxControl_SWidth(uint32_t n)           { return (n & 0x7) << 18; }
00478     __INLINE uint32_t CxControl_DWidth(uint32_t n)           { return (n & 0x7) << 21; }
00479     __INLINE uint32_t CxControl_SI()                         { return (1UL << 26); }
00480     __INLINE uint32_t CxControl_DI()                         { return (1UL << 27); }
00481     __INLINE uint32_t CxControl_Prot1()                      { return (1UL << 28); }
00482     __INLINE uint32_t CxControl_Prot2()                      { return (1UL << 29); }
00483     __INLINE uint32_t CxControl_Prot3()                      { return (1UL << 30); }
00484     __INLINE uint32_t CxControl_I()                          { return (1UL << 31); }
00485     __INLINE uint32_t CxControl_E()                          { return (1UL << 0); }
00486     __INLINE uint32_t CxConfig_SrcPeripheral(uint32_t n)     { return (n & 0x1F) << 1; }
00487     __INLINE uint32_t CxConfig_DestPeripheral(uint32_t n)    { return (n & 0x1F) << 6; }
00488     __INLINE uint32_t CxConfig_TransferType(uint32_t n)      { return (n & 0x7) << 11; }
00489     __INLINE uint32_t CxConfig_IE()                          { return (1UL << 14); }
00490     __INLINE uint32_t CxConfig_ITC()                         { return (1UL << 15); }
00491     __INLINE uint32_t CxConfig_L()                           { return (1UL << 16); }
00492     __INLINE uint32_t CxConfig_A()                           { return (1UL << 17); }
00493     __INLINE uint32_t CxConfig_H()                           { return (1UL << 18); }
00494     
00495     /**
00496      * A store for up to 8 (8 channels) of configurations.
00497      * @see MODDMA_Config
00498      */
00499     MODDMA_Config *setups[8];
00500     
00501     /**
00502      * Get a pointer to the current configuration the ISR is servicing.
00503      *
00504      * @ingroup API
00505      * @return MODDMA_Config * A pointer to the setup the ISR is currently servicing.
00506      */
00507     MODDMA_Config *getConfig(void) { return setups[IrqProcessingChannel]; }
00508     
00509     /**
00510      * Set which channel the ISR is currently servicing.
00511      *
00512      * *** USED INTERNALLY. DO NOT CALL FROM USER PROGRAMS ***
00513      *
00514      * Must be public so the extern "C" ISR can use it.
00515      */
00516     void setIrqProcessingChannel(CHANNELS n) { IrqProcessingChannel = n; }
00517     
00518     /**
00519      * Gets which channel the ISR is currently servicing.
00520      *
00521      * @ingroup API
00522      * @return CHANNELS The current channel the ISR is servicing.
00523      */
00524     CHANNELS irqProcessingChannel(void) { return IrqProcessingChannel; }
00525     
00526     /**
00527      * Sets which type of IRQ the ISR is making a callback for.
00528      *
00529      * *** USED INTERNALLY. DO NOT CALL FROM USER PROGRAMS ***
00530      *
00531      * Must be public so the extern "C" ISR can use it.
00532      */ 
00533     void setIrqType(IrqType_t n) { IrqType = n; }
00534     
00535     /**
00536      * Get which type of IRQ the ISR is calling you about,
00537      * terminal count or error.
00538      */
00539     IrqType_t irqType(void) { return IrqType; }
00540     
00541     /**
00542      * Clear the interrupt after handling.
00543      *
00544      * @param CHANNELS The channel the IQR occured on.
00545      */
00546     void clearTcIrq(CHANNELS n) { LPC_GPDMA->DMACIntTCClear = (uint32_t)(1UL << n); } 
00547     
00548     /**
00549      * Clear the interrupt the ISR is currently handing..
00550      */
00551     void clearTcIrq(void) { clearTcIrq( IrqProcessingChannel ); }
00552     
00553     /**
00554      * Clear the error interrupt after handling.
00555      *
00556      * @ingroup API
00557      * @param CHANNELS The channel the IQR occured on.
00558      */
00559     void clearErrIrq(CHANNELS n) { LPC_GPDMA->DMACIntTCClear = (uint32_t)(1UL << n); } 
00560     
00561     /**
00562      * Clear the error interrupt the ISR is currently handing.
00563      * @ingroup API
00564      */
00565     void clearErrIrq(void) { clearErrIrq( IrqProcessingChannel ); }
00566    
00567     /**
00568      * Is the supplied channel currently active?
00569      *
00570      * @ingroup API
00571      * @param CHANNELS The channel to inquire about.
00572      * @return bool true if active, false otherwise.
00573      */     
00574     bool isActive(CHANNELS ChannelNumber);
00575     
00576     /**
00577      * Halt the supplied channel. 
00578      *
00579      * @ingroup API
00580      * @param CHANNELS The channel to halt.
00581      */
00582     void haltChannel(CHANNELS ChannelNumber);
00583     
00584     /**
00585      * get a channels control register. 
00586      *
00587      * @ingroup API
00588      * @param CHANNELS The channel to get the control register for.
00589      */
00590     uint32_t getControl(CHANNELS ChannelNumber);
00591     
00592     /**
00593      * Wait for channel transfer to complete and then halt.
00594      *
00595      * @ingroup API
00596      * @param CHANNELS The channel to wait for then halt.
00597      */
00598     void haltAndWaitChannelComplete(CHANNELS n) { haltChannel(n); while (isActive(n)); }
00599     
00600     /**
00601      * Attach a callback to the TC IRQ controller.
00602      *
00603      * @ingroup API
00604      * @param fptr A function pointer to call
00605      * @return this
00606      */
00607     void attach_tc(void (*fptr)(void)) {  
00608         isrIntTCStat.attach(fptr);         
00609     }
00610     
00611     /**
00612      * Attach a callback to the TC IRQ controller.
00613      *
00614      * @ingroup API
00615      * @param tptr A template pointer to the calling object
00616      * @param mptr A method pointer within the object to call.
00617      * @return this
00618      */
00619     template<typename T>
00620     void attach_tc(T* tptr, void (T::*mptr)(void)) {  
00621         if((mptr != NULL) && (tptr != NULL)) {
00622             isrIntTCStat.attach(tptr, mptr);         
00623         }        
00624     }
00625        
00626     /**
00627      * The MODDMA controllers terminal count interrupt callback.
00628      */
00629     FunctionPointer isrIntTCStat;                        
00630     
00631     /**
00632      * Attach a callback to the ERR IRQ controller.
00633      *
00634      * @ingroup API
00635      * @param fptr A function pointer to call
00636      * @return this
00637      */
00638     void attach_err(void (*fptr)(void)) {  
00639         isrIntErrStat.attach(fptr);                 
00640     }
00641     
00642     /**
00643      * Attach a callback to the ERR IRQ controller.
00644      *
00645      * @ingroup API
00646      * @param tptr A template pointer to the calling object
00647      * @param mptr A method pointer within the object to call.
00648      * @return this
00649      */
00650     template<typename T>
00651     void attach_err(T* tptr, void (T::*mptr)(void)) {  
00652         if((mptr != NULL) && (tptr != NULL)) {
00653             isrIntErrStat.attach(tptr, mptr);         
00654         }
00655     }
00656     
00657     /**
00658      * Get the Linked List index regsiter for the requested channel.
00659      *
00660      * @param channelNum The channel number.
00661      * @return uint32_t The value of the DMACCLLI register
00662      */
00663     uint32_t lli(CHANNELS ChannelNumber, MODDMA_LLI *set = 0) { 
00664         LPC_GPDMACH_TypeDef *pChannel = (LPC_GPDMACH_TypeDef *)Channel_p( ChannelNumber & 0x7 );
00665         if (set) pChannel->DMACCLLI = (uint32_t)set;
00666         return pChannel->DMACCLLI; 
00667     }
00668     
00669     /**
00670      * The MODDMA controllers error interrupt callback.
00671      */
00672     FunctionPointer isrIntErrStat;                        
00673     
00674     uint32_t Channel_p(int channel);
00675     
00676 protected:
00677    
00678     // Data LUTs.
00679     uint32_t LUTPerAddr(int n);
00680     uint8_t  LUTPerBurst(int n);
00681     uint8_t  LUTPerWid(int n);    
00682     //uint32_t Channel_p(int channel);
00683     
00684     CHANNELS IrqProcessingChannel;
00685     
00686     IrqType_t IrqType;
00687 };
00688 
00689 }; // namespace AjK ends.
00690 
00691 using namespace AjK;
00692 
00693 #endif