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