Subdirectory provided by Embedded Artists
Dependencies: DM_FATFileSystem DM_HttpServer DM_USBHost EthernetInterface USBDevice mbed-rpc mbed-rtos mbed-src
Dependents: lpc4088_displaymodule_hello_world_Sept_2018
Fork of DMSupport by
GPDMA.h
00001 /* 00002 * Copyright 2015 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 #ifndef GPDMA_H 00018 #define GPDMA_H 00019 00020 #include "mbed.h" 00021 #include "rtos.h" 00022 00023 /** 00024 * @brief GPDMA request connections 00025 */ 00026 #define GPDMA_CONN_MEMORY ((0UL)) 00027 #define GPDMA_CONN_SDC ((1UL)) /*!< SD card */ 00028 00029 /** 00030 * @brief Macro defines for DMA channel control registers 00031 */ 00032 #define GPDMA_DMACCxControl_TransferSize(n) (((n & 0xFFF) << 0)) /*!< Transfer size*/ 00033 #define GPDMA_DMACCxControl_SBSize(n) (((n & 0x07) << 12)) /*!< Source burst size*/ 00034 #define GPDMA_DMACCxControl_DBSize(n) (((n & 0x07) << 15)) /*!< Destination burst size*/ 00035 #define GPDMA_DMACCxControl_SWidth(n) (((n & 0x07) << 18)) /*!< Source transfer width*/ 00036 #define GPDMA_DMACCxControl_DWidth(n) (((n & 0x07) << 21)) /*!< Destination transfer width*/ 00037 #define GPDMA_DMACCxControl_SI ((1UL << 26)) /*!< Source increment*/ 00038 #define GPDMA_DMACCxControl_DI ((1UL << 27)) /*!< Destination increment*/ 00039 #define GPDMA_DMACCxControl_SrcTransUseAHBMaster1 0 00040 #define GPDMA_DMACCxControl_DestTransUseAHBMaster1 0 00041 #define GPDMA_DMACCxControl_Prot1 ((1UL << 28)) /*!< Indicates that the access is in user mode or privileged mode*/ 00042 #define GPDMA_DMACCxControl_Prot2 ((1UL << 29)) /*!< Indicates that the access is bufferable or not bufferable*/ 00043 #define GPDMA_DMACCxControl_Prot3 ((1UL << 30)) /*!< Indicates that the access is cacheable or not cacheable*/ 00044 #define GPDMA_DMACCxControl_I ((1UL << 31)) /*!< Terminal count interrupt enable bit */ 00045 00046 /** 00047 * @brief GPDMA Burst size in Source and Destination definitions 00048 */ 00049 #define GPDMA_BSIZE_1 ((0UL)) /*!< Burst size = 1 */ 00050 #define GPDMA_BSIZE_4 ((1UL)) /*!< Burst size = 4 */ 00051 #define GPDMA_BSIZE_8 ((2UL)) /*!< Burst size = 8 */ 00052 #define GPDMA_BSIZE_16 ((3UL)) /*!< Burst size = 16 */ 00053 #define GPDMA_BSIZE_32 ((4UL)) /*!< Burst size = 32 */ 00054 #define GPDMA_BSIZE_64 ((5UL)) /*!< Burst size = 64 */ 00055 #define GPDMA_BSIZE_128 ((6UL)) /*!< Burst size = 128 */ 00056 #define GPDMA_BSIZE_256 ((7UL)) /*!< Burst size = 256 */ 00057 00058 /** 00059 * @brief Width in Source transfer width and Destination transfer width definitions 00060 */ 00061 #define GPDMA_WIDTH_BYTE ((0UL)) /*!< Width = 1 byte */ 00062 #define GPDMA_WIDTH_HALFWORD ((1UL)) /*!< Width = 2 bytes */ 00063 #define GPDMA_WIDTH_WORD ((2UL)) /*!< Width = 4 bytes */ 00064 00065 /** 00066 * @brief Macro defines for DMA Configuration register 00067 */ 00068 #define GPDMA_DMACConfig_E ((0x01)) /*!< DMA Controller enable*/ 00069 #define GPDMA_DMACConfig_M ((0x02)) /*!< AHB Master endianness configuration*/ 00070 #define GPDMA_DMACConfig_BITMASK ((0x03)) 00071 00072 /** 00073 * @brief Macro defines for DMA Channel Configuration registers 00074 */ 00075 #define GPDMA_DMACCxConfig_E ((1UL << 0)) /*!< DMA control enable*/ 00076 #define GPDMA_DMACCxConfig_SrcPeripheral(n) (((n & 0x1F) << 1)) /*!< Source peripheral*/ 00077 #define GPDMA_DMACCxConfig_DestPeripheral(n) (((n & 0x1F) << 6)) /*!< Destination peripheral*/ 00078 #define GPDMA_DMACCxConfig_TransferType(n) (((n & 0x7) << 11)) /*!< This value indicates the type of transfer*/ 00079 #define GPDMA_DMACCxConfig_IE ((1UL << 14)) /*!< Interrupt error mask*/ 00080 #define GPDMA_DMACCxConfig_ITC ((1UL << 15)) /*!< Terminal count interrupt mask*/ 00081 #define GPDMA_DMACCxConfig_L ((1UL << 16)) /*!< Lock*/ 00082 #define GPDMA_DMACCxConfig_A ((1UL << 17)) /*!< Active*/ 00083 #define GPDMA_DMACCxConfig_H ((1UL << 18)) /*!< Halt*/ 00084 00085 /** 00086 * @brief GPDMA Linker List Item structure type definition 00087 */ 00088 typedef struct { 00089 uint32_t SrcAddr; /**< Source Address */ 00090 uint32_t DstAddr; /**< Destination address */ 00091 uint32_t NextLLI; /**< Next LLI address, otherwise set to '0' */ 00092 uint32_t Control; /**< GPDMA Control of this LLI */ 00093 } GPDMA_LLI_Type; 00094 00095 /** 00096 * Wrapper for the General Purpose DMA controller. 00097 * 00098 * The GPDMA class allows multiple users of DMA to claim one or more 00099 * of the eight available DMA channels and to register handlers for the 00100 * interrupts. This centralized control is needed as there are eight 00101 * channels but only one DMA IRQ. 00102 * 00103 * By having to request a channel to use it is possible to avoid having 00104 * hardcoded DMA channel number in the code 00105 * 00106 * An example of use: 00107 * 00108 * @code 00109 * void handler() { 00110 * _eventSuccess = LPC_GPDMA->IntTCStat & (1<<ch); 00111 * LPC_GPDMA->IntTCClear = (1<<ch); 00112 * } 00113 * 00114 * void foo() { 00115 * GPDMA* dma = &GPDMA::instance(); 00116 * dma->init(); 00117 * 00118 * DMAChannels ch = dma->acquireChannel(handler) 00119 * if (ch == DMACh_Unavailable) { 00120 * // handle error 00121 * } 00122 * 00123 * // prepare the channel data (see e.g. gpdma_transfer_from_mci() in MCIFileSystem) 00124 * ... 00125 * 00126 * // start the transfer 00127 * dma->transfer(&cfg, ctrl_word, 0, GPDMA_CONN_SDC, GPDMA_CONN_MEMORY); 00128 * 00129 * // wait for transfer to complete (e.g. by handler() setting a flag) 00130 * ... 00131 * 00132 * // return the channel now that it is no longer needed 00133 * dma->releaseChannel(ch); 00134 * } 00135 * @endcode 00136 */ 00137 class GPDMA { 00138 public: 00139 enum DMAChannels { 00140 DMACh0, /* DMA channel 0 has the highest priority */ 00141 DMACh1, 00142 DMACh2, 00143 DMACh3, 00144 DMACh4, 00145 DMACh5, 00146 DMACh6, 00147 DMACh7, /* DMA channel 7 has the lowest priority */ 00148 NumDMAChannels, 00149 DMACh_Unavailable = NumDMAChannels, 00150 }; 00151 enum FlowControl { 00152 FlowControl_M2M_Ctrl_DMA, /* Memory to memory - DMA control */ 00153 FlowControl_M2P_Ctrl_DMA, /* Memory to peripheral - DMA control */ 00154 FlowControl_P2M_Ctrl_DMA, /* Peripheral to memory - DMA control */ 00155 FlowControl_P2P_Ctrl_DMA, /* Source peripheral to destination peripheral - DMA control */ 00156 FlowControl_P2P_Ctrl_DestPeriph, /* Source peripheral to destination peripheral - destination peripheral control */ 00157 FlowControl_M2P_Ctrl_Periph, /* Memory to peripheral - peripheral control */ 00158 FlowControl_P2M_Ctrl_Periph, /* Peripheral to memory - peripheral control */ 00159 FlowControl_P2P_Ctrl_SrcPeriph, /* Source peripheral to destination peripheral - source peripheral control */ 00160 }; 00161 typedef struct { 00162 DMAChannels ChannelNum; 00163 uint32_t TransferSize; /* Length/Size of transfer */ 00164 uint32_t TransferWidth; /* Transfer width - used only for M2M */ 00165 uint32_t SrcAddr; /* Physical Source Address, only for M2M and M2P */ 00166 uint32_t DstAddr; /* Physical Destination Address, only for M2M and P2M */ 00167 FlowControl TransferType; 00168 } GPDMA_Channel_CFG_T; 00169 00170 /** Get the only instance of the GPDMA 00171 * 00172 * @returns The Registry 00173 */ 00174 static GPDMA& instance() 00175 { 00176 static GPDMA singleton; 00177 return singleton; 00178 } 00179 00180 /** Initializes the GPDMA 00181 * 00182 * Safe to call even with multiple DMA users 00183 */ 00184 void init(); 00185 00186 /** Shuts down the GPDMA 00187 * 00188 * Call will be ignored if there are any acquired channels 00189 */ 00190 void deinit(); 00191 00192 /** Get a free GPDMA channel for one DMA connection 00193 * 00194 * The function will start to look for the suggested channel. 00195 * If it is in use then the next, higher, channel number will 00196 * be tested. The default is set to use DMACh3 which has 00197 * medium priority. 00198 * 00199 * To acquire a channel with the highest available priority 00200 * call this function with DMACh0 as parameter. 00201 * 00202 * @param func the interrupt callback function 00203 * @param suggested the first channel to look for 00204 * 00205 * @returns 00206 * DMACh0 to DMACh7 on success 00207 * DMACh_Unavailable if there are no channels available 00208 */ 00209 DMAChannels acquireChannel(void (*irqfunc)(void), DMAChannels suggested = DMACh3); 00210 00211 /** Release a previously acquired channel 00212 * 00213 * @param ch the DMA channel to release 00214 */ 00215 void releaseChannel(DMAChannels ch); 00216 00217 /** Returns the raw registers for the GPDMA channel for direct manipulation 00218 * 00219 * @param ch the DMA channel 00220 * 00221 * @returns 00222 * The registers on success 00223 * NULL if the channel is invalid 00224 */ 00225 LPC_GPDMACH_TypeDef* getDirectRegisters(DMAChannels ch); 00226 00227 // Internal use only. Called by the IRQ handler 00228 void processInterrupt(); 00229 00230 /** Does the actual DMA transfer 00231 * 00232 * @param cfg the DMA configuration 00233 * @param CtrlWord data for the DMA channel's CONTROL register 00234 * @param LinkListItem address to the linked list or 0 if not used 00235 * @param SrcPeripheral source of the transfer (GPDMA_CONN_MEMORY or GPDMA_CONN_SDC) 00236 * @param DstPeripheral destination of the transfer (GPDMA_CONN_MEMORY or GPDMA_CONN_SDC) 00237 * 00238 * @returns 00239 * True on success, false on failure 00240 */ 00241 bool transfer(GPDMA_Channel_CFG_T* cfg, 00242 uint32_t CtrlWord, 00243 uint32_t LinkListItem, 00244 uint8_t SrcPeripheral, 00245 uint8_t DstPeripheral); 00246 00247 void stopTransfer(DMAChannels ch); 00248 00249 private: 00250 typedef struct { 00251 bool inUse; 00252 void (*func)(void); 00253 } channelData_t; 00254 00255 Mutex _mutex; 00256 channelData_t _chData[NumDMAChannels]; 00257 int _usedChannels; 00258 bool _initialized; 00259 00260 explicit GPDMA(); 00261 // hide copy constructor 00262 GPDMA(const GPDMA&); 00263 // hide assign operator 00264 GPDMA& operator=(const GPDMA&); 00265 ~GPDMA(); 00266 }; 00267 00268 #endif
Generated on Wed Jul 13 2022 02:57:23 by 1.7.2