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 SETUP.cpp Source File

SETUP.cpp

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 
00023 #include "MODDMA.h"
00024 
00025 namespace AjK {
00026 
00027 uint32_t
00028 MODDMA::Setup(MODDMA_Config *config)
00029 {
00030     LPC_GPDMACH_TypeDef *pChannel = (LPC_GPDMACH_TypeDef *)Channel_p( config->channelNum() );
00031     
00032     setups[config->channelNum() & 0x7] = config;
00033     
00034     // Reset the Interrupt status
00035     LPC_GPDMA->DMACIntTCClear = IntTCClear_Ch( config->channelNum() );
00036     LPC_GPDMA->DMACIntErrClr  = IntErrClr_Ch ( config->channelNum() );
00037 
00038     // Clear DMA configure
00039     pChannel->DMACCControl = 0x00;
00040     pChannel->DMACCConfig  = 0x00;
00041 
00042     // Assign Linker List Item value 
00043     pChannel->DMACCLLI = config->dmaLLI();
00044 
00045     // Set value to Channel Control Registers 
00046     switch (config->transferType()) {
00047     
00048         // Memory to memory
00049         case m2m :
00050             // Assign physical source and destination address
00051             pChannel->DMACCSrcAddr  = config->srcMemAddr();
00052             pChannel->DMACCDestAddr = config->dstMemAddr();
00053             pChannel->DMACCControl
00054                 = CxControl_TransferSize(config->transferSize()) 
00055                 | CxControl_SBSize(_32 ) 
00056                 | CxControl_DBSize(_32 ) 
00057                 | CxControl_SWidth(config->transferWidth()) 
00058                 | CxControl_DWidth(config->transferWidth()) 
00059                 | CxControl_SI() 
00060                 | CxControl_DI() 
00061                 | CxControl_I();
00062             break;
00063         
00064         // Memory to peripheral
00065         case m2p :
00066             // Assign physical source
00067             pChannel->DMACCSrcAddr = config->srcMemAddr();
00068             // Assign peripheral destination address
00069             pChannel->DMACCDestAddr = (uint32_t)LUTPerAddr(config->dstConn());
00070             pChannel->DMACCControl
00071                 = CxControl_TransferSize((uint32_t)config->transferSize()) 
00072                 | CxControl_SBSize((uint32_t)LUTPerBurst(config->dstConn())) 
00073                 | CxControl_DBSize((uint32_t)LUTPerBurst(config->dstConn())) 
00074                 | CxControl_SWidth((uint32_t)LUTPerWid(config->dstConn())) 
00075                 | CxControl_DWidth((uint32_t)LUTPerWid(config->dstConn())) 
00076                 | CxControl_SI() 
00077                 | CxControl_I();
00078             break;
00079             
00080         // Peripheral to memory
00081         case p2m :
00082             // Assign peripheral source address
00083             pChannel->DMACCSrcAddr = (uint32_t)LUTPerAddr(config->srcConn());
00084             // Assign memory destination address
00085             pChannel->DMACCDestAddr = config->dstMemAddr();
00086             pChannel->DMACCControl
00087                 = CxControl_TransferSize((uint32_t)config->transferSize()) 
00088                 | CxControl_SBSize((uint32_t)LUTPerBurst(config->srcConn())) 
00089                 | CxControl_DBSize((uint32_t)LUTPerBurst(config->srcConn())) 
00090                 | CxControl_SWidth((uint32_t)LUTPerWid(config->srcConn())) 
00091                 | CxControl_DWidth((uint32_t)LUTPerWid(config->srcConn())) 
00092                 | CxControl_DI() 
00093                 | CxControl_I();
00094             break;
00095             
00096         // Peripheral to peripheral
00097         case p2p :
00098             // Assign peripheral source address
00099             pChannel->DMACCSrcAddr = (uint32_t)LUTPerAddr(config->srcConn());
00100             // Assign peripheral destination address
00101             pChannel->DMACCDestAddr = (uint32_t)LUTPerAddr(config->dstConn());
00102             pChannel->DMACCControl
00103                 = CxControl_TransferSize((uint32_t)config->transferSize()) 
00104                 | CxControl_SBSize((uint32_t)LUTPerBurst(config->srcConn())) 
00105                 | CxControl_DBSize((uint32_t)LUTPerBurst(config->dstConn())) 
00106                 | CxControl_SWidth((uint32_t)LUTPerWid(config->srcConn())) 
00107                 | CxControl_DWidth((uint32_t)LUTPerWid(config->dstConn())) 
00108                 | CxControl_I();
00109             break;
00110             
00111         // GPIO to memory
00112         case g2m :
00113             // Assign GPIO source address
00114             pChannel->DMACCSrcAddr = config->srcMemAddr();
00115             // Assign memory destination address
00116             pChannel->DMACCDestAddr = config->dstMemAddr();
00117             pChannel->DMACCControl
00118                 = CxControl_TransferSize((uint32_t)config->transferSize()) 
00119                 | CxControl_SBSize((uint32_t)LUTPerBurst(config->srcConn())) 
00120                 | CxControl_DBSize((uint32_t)LUTPerBurst(config->srcConn())) 
00121                 | CxControl_SWidth((uint32_t)LUTPerWid(config->srcConn())) 
00122                 | CxControl_DWidth((uint32_t)LUTPerWid(config->srcConn())) 
00123                 | CxControl_DI() 
00124                 | CxControl_I();
00125             break;
00126             
00127         // Memory to GPIO
00128         case m2g :
00129             // Assign physical source
00130             pChannel->DMACCSrcAddr = config->srcMemAddr();
00131             // Assign peripheral destination address
00132             pChannel->DMACCDestAddr = config->dstMemAddr();
00133             pChannel->DMACCControl
00134                 = CxControl_TransferSize((uint32_t)config->transferSize()) 
00135                 | CxControl_SBSize((uint32_t)LUTPerBurst(config->dstConn())) 
00136                 | CxControl_DBSize((uint32_t)LUTPerBurst(config->dstConn())) 
00137                 | CxControl_SWidth((uint32_t)LUTPerWid(config->dstConn())) 
00138                 | CxControl_DWidth((uint32_t)LUTPerWid(config->dstConn())) 
00139                 | CxControl_SI() 
00140                 | CxControl_I();
00141             break;
00142             
00143         // Do not support any more transfer type, return ERROR
00144         default:
00145             return 0;
00146     }
00147 
00148      // Re-Configure DMA Request Select for source peripheral 
00149     if (config->srcConn() > 15) {
00150         LPC_SC->DMAREQSEL |= (1 << (config->srcConn() - 16));
00151     } 
00152     else {
00153         LPC_SC->DMAREQSEL &= ~(1 << (config->srcConn() - 8));
00154     }
00155 
00156     // Re-Configure DMA Request Select for destination peripheral
00157     if (config->dstConn() > 15) {
00158         LPC_SC->DMAREQSEL |= (1 << (config->dstConn() - 16));
00159     } 
00160     else {
00161         LPC_SC->DMAREQSEL &= ~(1 << (config->dstConn() - 8));
00162     }
00163 
00164     // Enable DMA channels, little endian 
00165     LPC_GPDMA->DMACConfig = _E ;
00166     while (!(LPC_GPDMA->DMACConfig & _E ));
00167 
00168     // Calculate absolute value for Connection number
00169     uint32_t tmp1 = config->srcConn(); tmp1 = ((tmp1 > 15) ? (tmp1 - 8) : tmp1);
00170     uint32_t tmp2 = config->dstConn(); tmp2 = ((tmp2 > 15) ? (tmp2 - 8) : tmp2);
00171 
00172     if (config->dmacSync()) {
00173         uint32_t tmp3 = config->dmacSync(); tmp3 = ((tmp3 > 15) ? (tmp3 - 8) : tmp3);
00174         LPC_GPDMA->DMACSync |= Sync_Src( tmp3 );
00175     }
00176     
00177     uint32_t tfer_type = (uint32_t)config->transferType();
00178     if (tfer_type == g2m  || tfer_type == m2g ) {
00179         tfer_type -= 2; // Adjust psuedo transferType to a real transferType.
00180     }
00181     
00182     // Configure DMA Channel, enable Error Counter and Terminate counter
00183     pChannel->DMACCConfig 
00184         = CxConfig_IE() 
00185         | CxConfig_ITC() 
00186         | CxConfig_TransferType(tfer_type) 
00187         | CxConfig_SrcPeripheral(tmp1) 
00188         | CxConfig_DestPeripheral(tmp2);
00189 
00190     return pChannel->DMACCControl;
00191 }
00192 
00193 }; // namespace AjK ends
00194