A library with drivers for different peripherals on the LPC4088 QuickStart Board or related add-on boards.
Fork of EALib by
gpdma.cpp
00001 /* 00002 * Copyright 2013 Embedded Artists AB 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 /****************************************************************************** 00018 * Includes 00019 *****************************************************************************/ 00020 00021 #include "gpdma.h" 00022 00023 /****************************************************************************** 00024 * Defines and typedefs 00025 *****************************************************************************/ 00026 00027 #define NUM_GPDMA_CHANNELS 8 00028 00029 #define GPDMACH(__x) ((LPC_GPDMACH_TypeDef*)(LPC_GPDMACH0_BASE + (0x20 * (__x)))) 00030 00031 #define CH_MASK(__ch) (((1UL << (__ch)) & 0xFF)) 00032 00033 /** 00034 * @brief GPDMA request connections 00035 */ 00036 #define GPDMA_CONN_MEMORY ((0UL)) 00037 #define GPDMA_CONN_SDC ((1UL)) /*!< SD card */ 00038 00039 /** 00040 * @brief Macro defines for DMA channel control registers 00041 */ 00042 #define GPDMA_DMACCxControl_TransferSize(n) (((n & 0xFFF) << 0)) /*!< Transfer size*/ 00043 #define GPDMA_DMACCxControl_SBSize(n) (((n & 0x07) << 12)) /*!< Source burst size*/ 00044 #define GPDMA_DMACCxControl_DBSize(n) (((n & 0x07) << 15)) /*!< Destination burst size*/ 00045 #define GPDMA_DMACCxControl_SWidth(n) (((n & 0x07) << 18)) /*!< Source transfer width*/ 00046 #define GPDMA_DMACCxControl_DWidth(n) (((n & 0x07) << 21)) /*!< Destination transfer width*/ 00047 #define GPDMA_DMACCxControl_SI ((1UL << 26)) /*!< Source increment*/ 00048 #define GPDMA_DMACCxControl_DI ((1UL << 27)) /*!< Destination increment*/ 00049 #define GPDMA_DMACCxControl_SrcTransUseAHBMaster1 0 00050 #define GPDMA_DMACCxControl_DestTransUseAHBMaster1 0 00051 #define GPDMA_DMACCxControl_Prot1 ((1UL << 28)) /*!< Indicates that the access is in user mode or privileged mode*/ 00052 #define GPDMA_DMACCxControl_Prot2 ((1UL << 29)) /*!< Indicates that the access is bufferable or not bufferable*/ 00053 #define GPDMA_DMACCxControl_Prot3 ((1UL << 30)) /*!< Indicates that the access is cacheable or not cacheable*/ 00054 #define GPDMA_DMACCxControl_I ((1UL << 31)) /*!< Terminal count interrupt enable bit */ 00055 00056 /** 00057 * @brief GPDMA Burst size in Source and Destination definitions 00058 */ 00059 #define GPDMA_BSIZE_1 ((0UL)) /*!< Burst size = 1 */ 00060 #define GPDMA_BSIZE_4 ((1UL)) /*!< Burst size = 4 */ 00061 #define GPDMA_BSIZE_8 ((2UL)) /*!< Burst size = 8 */ 00062 #define GPDMA_BSIZE_16 ((3UL)) /*!< Burst size = 16 */ 00063 #define GPDMA_BSIZE_32 ((4UL)) /*!< Burst size = 32 */ 00064 #define GPDMA_BSIZE_64 ((5UL)) /*!< Burst size = 64 */ 00065 #define GPDMA_BSIZE_128 ((6UL)) /*!< Burst size = 128 */ 00066 #define GPDMA_BSIZE_256 ((7UL)) /*!< Burst size = 256 */ 00067 00068 /** 00069 * @brief Width in Source transfer width and Destination transfer width definitions 00070 */ 00071 #define GPDMA_WIDTH_BYTE ((0UL)) /*!< Width = 1 byte */ 00072 #define GPDMA_WIDTH_HALFWORD ((1UL)) /*!< Width = 2 bytes */ 00073 #define GPDMA_WIDTH_WORD ((2UL)) /*!< Width = 4 bytes */ 00074 00075 /** 00076 * @brief Macro defines for DMA Configuration register 00077 */ 00078 #define GPDMA_DMACConfig_E ((0x01)) /*!< DMA Controller enable*/ 00079 #define GPDMA_DMACConfig_M ((0x02)) /*!< AHB Master endianness configuration*/ 00080 #define GPDMA_DMACConfig_BITMASK ((0x03)) 00081 00082 /** 00083 * @brief Macro defines for DMA Channel Configuration registers 00084 */ 00085 #define GPDMA_DMACCxConfig_E ((1UL << 0)) /*!< DMA control enable*/ 00086 #define GPDMA_DMACCxConfig_SrcPeripheral(n) (((n & 0x1F) << 1)) /*!< Source peripheral*/ 00087 #define GPDMA_DMACCxConfig_DestPeripheral(n) (((n & 0x1F) << 6)) /*!< Destination peripheral*/ 00088 #define GPDMA_DMACCxConfig_TransferType(n) (((n & 0x7) << 11)) /*!< This value indicates the type of transfer*/ 00089 #define GPDMA_DMACCxConfig_IE ((1UL << 14)) /*!< Interrupt error mask*/ 00090 #define GPDMA_DMACCxConfig_ITC ((1UL << 15)) /*!< Terminal count interrupt mask*/ 00091 #define GPDMA_DMACCxConfig_L ((1UL << 16)) /*!< Lock*/ 00092 #define GPDMA_DMACCxConfig_A ((1UL << 17)) /*!< Active*/ 00093 #define GPDMA_DMACCxConfig_H ((1UL << 18)) /*!< Halt*/ 00094 00095 /** 00096 * @brief GPDMA structure using for DMA configuration 00097 */ 00098 typedef struct { 00099 uint32_t ChannelNum; /*!< DMA channel number, should be in 00100 * range from 0 to 7. 00101 * Note: DMA channel 0 has the highest priority 00102 * and DMA channel 7 the lowest priority. 00103 */ 00104 uint32_t TransferSize; /*!< Length/Size of transfer */ 00105 uint32_t TransferWidth; /*!< Transfer width - used for TransferType is GPDMA_TRANSFERTYPE_M2M only */ 00106 uint32_t SrcAddr; /*!< Physical Source Address, used in case TransferType is chosen as 00107 * GPDMA_TRANSFERTYPE_M2M or GPDMA_TRANSFERTYPE_M2P */ 00108 uint32_t DstAddr; /*!< Physical Destination Address, used in case TransferType is chosen as 00109 * GPDMA_TRANSFERTYPE_M2M or GPDMA_TRANSFERTYPE_P2M */ 00110 uint32_t TransferType; /*!< Transfer Type, should be one of the following: 00111 * - GPDMA_TRANSFERTYPE_M2M: Memory to memory - DMA control 00112 * - GPDMA_TRANSFERTYPE_M2P: Memory to peripheral - DMA control 00113 * - GPDMA_TRANSFERTYPE_P2M: Peripheral to memory - DMA control 00114 * - GPDMA_TRANSFERTYPE_P2P: Source peripheral to destination peripheral - DMA control 00115 */ 00116 } GPDMA_Channel_CFG_T; 00117 00118 /****************************************************************************** 00119 * External global variables 00120 *****************************************************************************/ 00121 00122 /****************************************************************************** 00123 * Local variables 00124 *****************************************************************************/ 00125 00126 static bool used_channels[NUM_GPDMA_CHANNELS]; 00127 00128 /****************************************************************************** 00129 * Local Functions 00130 *****************************************************************************/ 00131 00132 static void gpdma_transfer(GPDMA_Channel_CFG_T* cfg, 00133 uint32_t CtrlWord, 00134 uint32_t LinkListItem, 00135 uint8_t SrcPeripheral, 00136 uint8_t DstPeripheral) 00137 { 00138 /* Get Channel pointer */ 00139 LPC_GPDMACH_TypeDef* pCh = GPDMACH(cfg->ChannelNum); 00140 00141 /* Reset the Interrupt status */ 00142 LPC_GPDMA->IntTCClear = CH_MASK(cfg->ChannelNum); 00143 LPC_GPDMA->IntErrClr = CH_MASK(cfg->ChannelNum); 00144 00145 /* Assign Linker List Item value */ 00146 pCh->CLLI = LinkListItem; 00147 00148 /* Enable DMA channels, little endian */ 00149 LPC_GPDMA->Config = GPDMA_DMACConfig_E; 00150 while (!(LPC_GPDMA->Config & GPDMA_DMACConfig_E)) {} 00151 00152 pCh->CSrcAddr = cfg->SrcAddr; 00153 pCh->CDestAddr = cfg->DstAddr; 00154 00155 /* Configure DMA Channel, enable Error Counter and Terminate counter */ 00156 pCh->CConfig = GPDMA_DMACCxConfig_IE 00157 | GPDMA_DMACCxConfig_ITC 00158 | GPDMA_DMACCxConfig_TransferType((uint32_t) cfg->TransferType) 00159 | GPDMA_DMACCxConfig_SrcPeripheral(SrcPeripheral) 00160 | GPDMA_DMACCxConfig_DestPeripheral(DstPeripheral); 00161 00162 pCh->CControl = CtrlWord; 00163 00164 /* Start the Channel */ 00165 pCh->CConfig |= GPDMA_DMACCxConfig_E; 00166 } 00167 00168 /****************************************************************************** 00169 * Public Functions 00170 *****************************************************************************/ 00171 00172 void gpdma_init() 00173 { 00174 uint8_t i; 00175 00176 /* Enable GPDMA master clock */ 00177 LPC_SC->PCONP |= (1<<29); 00178 00179 /* Reset all channel configuration register */ 00180 for (i = 0; i < NUM_GPDMA_CHANNELS; i++) { 00181 GPDMACH(i)->CConfig = 0; 00182 } 00183 00184 /* Clear all DMA interrupt and error flag */ 00185 LPC_GPDMA->IntTCClear = 0xFF; 00186 LPC_GPDMA->IntErrClr = 0xFF; 00187 00188 /* Reset all channels are free */ 00189 for (int i = 0; i < NUM_GPDMA_CHANNELS; i++) 00190 { 00191 used_channels[i] = false; 00192 } 00193 } 00194 00195 void gpdma_deinit() 00196 { 00197 /* Disable GPDMA master clock */ 00198 LPC_SC->PCONP &= ~(1<<29); 00199 } 00200 00201 void gpdma_stop(uint8_t ChannelNum) 00202 { 00203 if (ChannelNum >= NUM_GPDMA_CHANNELS) { 00204 return; 00205 } 00206 00207 /* Disable channel */ 00208 GPDMACH(ChannelNum)->CConfig &= ~GPDMA_DMACCxConfig_E; 00209 00210 /* check terminal count interrupt request status for DMA */ 00211 if (LPC_GPDMA->IntTCStat & CH_MASK(ChannelNum)) { 00212 /* Clear terminate counter Interrupt pending */ 00213 LPC_GPDMA->IntTCClear = CH_MASK(ChannelNum); 00214 } 00215 00216 /* check status of the error interrupt for DMA channels */ 00217 if (LPC_GPDMA->IntErrStat & CH_MASK(ChannelNum)) { 00218 /* clear the error interrupt request */ 00219 LPC_GPDMA->IntErrClr = CH_MASK(ChannelNum); 00220 } 00221 00222 used_channels[ChannelNum] = false; 00223 } 00224 00225 bool gpdma_interrupt(uint8_t ChannelNum) 00226 { 00227 /* check status of DMA channel interrupts */ 00228 if (LPC_GPDMA->IntStat & CH_MASK(ChannelNum)) { 00229 /* Check counter terminal status */ 00230 if (LPC_GPDMA->IntTCStat & CH_MASK(ChannelNum)) { 00231 /* Clear terminate counter Interrupt pending */ 00232 LPC_GPDMA->IntTCClear = CH_MASK(ChannelNum); 00233 return true; 00234 } 00235 /* Check error terminal status */ 00236 if (LPC_GPDMA->IntErrStat & CH_MASK(ChannelNum)) { 00237 /* Clear error counter Interrupt pending */ 00238 LPC_GPDMA->IntErrClr = CH_MASK(ChannelNum); 00239 return false; 00240 } 00241 } 00242 return false; 00243 } 00244 00245 bool gpdma_getFreeChannel(uint8_t* pCh) 00246 { 00247 for (int i = 0; i < NUM_GPDMA_CHANNELS; i++) 00248 { 00249 if ((!used_channels[i]) && ((LPC_GPDMA->EnbldChns & CH_MASK(i)) == 0)) 00250 { 00251 used_channels[i] = true; 00252 *pCh = i; 00253 return true; 00254 } 00255 } 00256 return false; 00257 } 00258 00259 bool gpdma_transfer_to_mci(uint8_t ChannelNum, 00260 uint32_t src, 00261 uint32_t Size) 00262 { 00263 GPDMA_Channel_CFG_T cfg; 00264 cfg.ChannelNum = ChannelNum; 00265 cfg.TransferType = GPDMA_TRANSFERTYPE_M2P_CONTROLLER_PERIPHERAL; 00266 cfg.TransferSize = Size; 00267 cfg.TransferWidth = 0; 00268 cfg.SrcAddr = src; 00269 cfg.DstAddr = (uint32_t) (&LPC_MCI->FIFO); 00270 00271 uint32_t ctrl_word = 00272 GPDMA_DMACCxControl_TransferSize((uint32_t) cfg.TransferSize) 00273 | GPDMA_DMACCxControl_SBSize(GPDMA_BSIZE_8) 00274 | GPDMA_DMACCxControl_DBSize(GPDMA_BSIZE_8) 00275 | GPDMA_DMACCxControl_SWidth(GPDMA_WIDTH_WORD) 00276 | GPDMA_DMACCxControl_DWidth(GPDMA_WIDTH_WORD) 00277 | GPDMA_DMACCxControl_DestTransUseAHBMaster1 00278 | GPDMA_DMACCxControl_SI 00279 | GPDMA_DMACCxControl_I; 00280 00281 if (LPC_GPDMA->EnbldChns & CH_MASK(ChannelNum)) { 00282 /* This channel is enabled, return ERROR, need to release this channel first */ 00283 return false; 00284 } 00285 00286 /* Select SD card interface in the DMA MUX*/ 00287 LPC_SC->DMAREQSEL &= ~(1 << 1); 00288 00289 gpdma_transfer(&cfg, ctrl_word, 0, GPDMA_CONN_MEMORY, GPDMA_CONN_SDC); 00290 return true; 00291 } 00292 00293 bool gpdma_transfer_from_mci(uint8_t ChannelNum, 00294 uint32_t dst, 00295 uint32_t Size) 00296 { 00297 GPDMA_Channel_CFG_T cfg; 00298 cfg.ChannelNum = ChannelNum; 00299 cfg.TransferType = GPDMA_TRANSFERTYPE_P2M_CONTROLLER_PERIPHERAL; 00300 cfg.TransferSize = Size; 00301 cfg.TransferWidth = 0; 00302 cfg.SrcAddr = (uint32_t) (&LPC_MCI->FIFO); 00303 cfg.DstAddr = dst; 00304 00305 uint32_t ctrl_word = 00306 GPDMA_DMACCxControl_TransferSize((uint32_t) cfg.TransferSize) 00307 | GPDMA_DMACCxControl_SBSize(GPDMA_BSIZE_8) 00308 | GPDMA_DMACCxControl_DBSize(GPDMA_BSIZE_8) 00309 | GPDMA_DMACCxControl_SWidth(GPDMA_WIDTH_WORD) 00310 | GPDMA_DMACCxControl_DWidth(GPDMA_WIDTH_WORD) 00311 | GPDMA_DMACCxControl_SrcTransUseAHBMaster1 00312 | GPDMA_DMACCxControl_DI 00313 | GPDMA_DMACCxControl_I; 00314 00315 if (LPC_GPDMA->EnbldChns & CH_MASK(ChannelNum)) { 00316 /* This channel is enabled, return ERROR, need to release this channel first */ 00317 return false; 00318 } 00319 00320 /* Select SD card interface in the DMA MUX*/ 00321 LPC_SC->DMAREQSEL &= ~(1 << 1); 00322 00323 gpdma_transfer(&cfg, ctrl_word, 0, GPDMA_CONN_SDC, GPDMA_CONN_MEMORY); 00324 return true; 00325 } 00326 00327
Generated on Wed Jul 13 2022 02:29:31 by 1.7.2