Fork of Andy Kirkham's MODDMA GPDMA Controller for Mbed OS 6
Read MODDMA for more info.
MODDMA.h@1:9700b9455cbf, 2010-11-23 (annotated)
- Committer:
- AjK
- Date:
- Tue Nov 23 14:53:25 2010 +0000
- Revision:
- 1:9700b9455cbf
- Parent:
- 0:c409efd8df78
- Child:
- 2:203d22a890cd
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AjK | 0:c409efd8df78 | 1 | /* |
AjK | 0:c409efd8df78 | 2 | Copyright (c) 2010 Andy Kirkham |
AjK | 0:c409efd8df78 | 3 | |
AjK | 0:c409efd8df78 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy |
AjK | 0:c409efd8df78 | 5 | of this software and associated documentation files (the "Software"), to deal |
AjK | 0:c409efd8df78 | 6 | in the Software without restriction, including without limitation the rights |
AjK | 0:c409efd8df78 | 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
AjK | 0:c409efd8df78 | 8 | copies of the Software, and to permit persons to whom the Software is |
AjK | 0:c409efd8df78 | 9 | furnished to do so, subject to the following conditions: |
AjK | 0:c409efd8df78 | 10 | |
AjK | 0:c409efd8df78 | 11 | The above copyright notice and this permission notice shall be included in |
AjK | 0:c409efd8df78 | 12 | all copies or substantial portions of the Software. |
AjK | 0:c409efd8df78 | 13 | |
AjK | 0:c409efd8df78 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
AjK | 0:c409efd8df78 | 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
AjK | 0:c409efd8df78 | 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
AjK | 0:c409efd8df78 | 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
AjK | 0:c409efd8df78 | 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
AjK | 0:c409efd8df78 | 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
AjK | 0:c409efd8df78 | 20 | THE SOFTWARE. |
AjK | 0:c409efd8df78 | 21 | |
AjK | 0:c409efd8df78 | 22 | @file MODDMA.h |
AjK | 0:c409efd8df78 | 23 | @purpose Adds DMA controller and multiple transfer configurations |
AjK | 0:c409efd8df78 | 24 | @version 1.0 |
AjK | 0:c409efd8df78 | 25 | @date Nov 2010 |
AjK | 0:c409efd8df78 | 26 | @author Andy Kirkham |
AjK | 0:c409efd8df78 | 27 | */ |
AjK | 0:c409efd8df78 | 28 | |
AjK | 0:c409efd8df78 | 29 | #ifndef MODDMA_H |
AjK | 0:c409efd8df78 | 30 | #define MODDMA_H |
AjK | 0:c409efd8df78 | 31 | |
AjK | 0:c409efd8df78 | 32 | /** @defgroup API The MODSERIAL API */ |
AjK | 0:c409efd8df78 | 33 | /** @defgroup MISC Misc MODSERIAL functions */ |
AjK | 0:c409efd8df78 | 34 | /** @defgroup INTERNALS MODSERIAL Internals */ |
AjK | 0:c409efd8df78 | 35 | |
AjK | 0:c409efd8df78 | 36 | #include "mbed.h" |
AjK | 0:c409efd8df78 | 37 | |
AjK | 0:c409efd8df78 | 38 | namespace AjK { |
AjK | 0:c409efd8df78 | 39 | |
AjK | 0:c409efd8df78 | 40 | /** |
AjK | 1:9700b9455cbf | 41 | * @brief The MODDMA configuration system |
AjK | 0:c409efd8df78 | 42 | * @author Andy Kirkham |
AjK | 1:9700b9455cbf | 43 | * @see http://mbed.org/cookbook/MODDMA_Config |
AjK | 1:9700b9455cbf | 44 | * @see MODDMA |
AjK | 0:c409efd8df78 | 45 | * @see API |
AjK | 0:c409efd8df78 | 46 | * |
AjK | 1:9700b9455cbf | 47 | * <b>MODDMA_Config</b> defines a configuration that can be passed to the MODDMA controller |
AjK | 1:9700b9455cbf | 48 | * instance to perform a GPDMA data transfer. |
AjK | 0:c409efd8df78 | 49 | * transfers from memory to memory, memory to peripheral or peripheral to memory. |
AjK | 0:c409efd8df78 | 50 | */ |
AjK | 0:c409efd8df78 | 51 | class MODDMA_Config { |
AjK | 0:c409efd8df78 | 52 | protected: |
AjK | 0:c409efd8df78 | 53 | |
AjK | 0:c409efd8df78 | 54 | // ***************************************** |
AjK | 0:c409efd8df78 | 55 | // From GPDMA by NXP MCU SW Application Team |
AjK | 0:c409efd8df78 | 56 | // ***************************************** |
AjK | 0:c409efd8df78 | 57 | |
AjK | 0:c409efd8df78 | 58 | uint32_t ChannelNum; //!< DMA channel number, should be in range from 0 to 7. |
AjK | 0:c409efd8df78 | 59 | uint32_t TransferSize; //!< Length/Size of transfer |
AjK | 0:c409efd8df78 | 60 | uint32_t TransferWidth; //!< Transfer width - used for TransferType is GPDMA_TRANSFERTYPE_m2m only |
AjK | 0:c409efd8df78 | 61 | uint32_t SrcMemAddr; //!< Physical Src Addr, used in case TransferType is chosen as MODDMA::GPDMA_TRANSFERTYPE::m2m or MODDMA::GPDMA_TRANSFERTYPE::m2p |
AjK | 0:c409efd8df78 | 62 | uint32_t DstMemAddr; //!< Physical Destination Address, used in case TransferType is chosen as MODDMA::GPDMA_TRANSFERTYPE::m2m or MODDMA::GPDMA_TRANSFERTYPE::p2m |
AjK | 0:c409efd8df78 | 63 | uint32_t TransferType; //!< Transfer Type |
AjK | 0:c409efd8df78 | 64 | uint32_t SrcConn; //!< Peripheral Source Connection type, used in case TransferType is chosen as |
AjK | 0:c409efd8df78 | 65 | uint32_t DstConn; //!< Peripheral Destination Connection type, used in case TransferType is chosen as |
AjK | 0:c409efd8df78 | 66 | uint32_t DMALLI; //!< Linker List Item structure data address if there's no Linker List, set as '0' |
AjK | 0:c409efd8df78 | 67 | |
AjK | 0:c409efd8df78 | 68 | // Mbed specifics. |
AjK | 0:c409efd8df78 | 69 | |
AjK | 0:c409efd8df78 | 70 | public: |
AjK | 0:c409efd8df78 | 71 | |
AjK | 0:c409efd8df78 | 72 | MODDMA_Config() { |
AjK | 0:c409efd8df78 | 73 | isrIntTCStat = new FunctionPointer; |
AjK | 0:c409efd8df78 | 74 | isrIntErrStat = new FunctionPointer; |
AjK | 0:c409efd8df78 | 75 | ChannelNum = 0xFFFF; |
AjK | 0:c409efd8df78 | 76 | TransferSize = 0; |
AjK | 0:c409efd8df78 | 77 | TransferWidth = 0; |
AjK | 0:c409efd8df78 | 78 | SrcMemAddr = 0; |
AjK | 0:c409efd8df78 | 79 | DstMemAddr = 0; |
AjK | 0:c409efd8df78 | 80 | TransferType = 0; |
AjK | 0:c409efd8df78 | 81 | SrcConn = 0; |
AjK | 0:c409efd8df78 | 82 | DstConn = 0; |
AjK | 0:c409efd8df78 | 83 | DMALLI = 0; |
AjK | 0:c409efd8df78 | 84 | } |
AjK | 0:c409efd8df78 | 85 | |
AjK | 0:c409efd8df78 | 86 | ~MODDMA_Config() { |
AjK | 0:c409efd8df78 | 87 | delete(isrIntTCStat); |
AjK | 0:c409efd8df78 | 88 | delete(isrIntErrStat); |
AjK | 0:c409efd8df78 | 89 | } |
AjK | 0:c409efd8df78 | 90 | |
AjK | 0:c409efd8df78 | 91 | class MODDMA_Config * channelNum(uint32_t n) { ChannelNum = n & 0x7; return this; } |
AjK | 0:c409efd8df78 | 92 | class MODDMA_Config * transferSize(uint32_t n) { TransferSize = n; return this; } |
AjK | 0:c409efd8df78 | 93 | class MODDMA_Config * transferWidth(uint32_t n) { TransferWidth = n; return this; } |
AjK | 0:c409efd8df78 | 94 | class MODDMA_Config * srcMemAddr(uint32_t n) { SrcMemAddr = n; return this; } |
AjK | 0:c409efd8df78 | 95 | class MODDMA_Config * dstMemAddr(uint32_t n) { DstMemAddr = n; return this; } |
AjK | 0:c409efd8df78 | 96 | class MODDMA_Config * transferType(uint32_t n) { TransferType = n; return this; } |
AjK | 0:c409efd8df78 | 97 | class MODDMA_Config * srcConn(uint32_t n) { SrcConn = n; return this; } |
AjK | 0:c409efd8df78 | 98 | class MODDMA_Config * dstConn(uint32_t n) { DstConn = n; return this; } |
AjK | 0:c409efd8df78 | 99 | class MODDMA_Config * dmaLLI(uint32_t n) { DMALLI = n; return this; } |
AjK | 0:c409efd8df78 | 100 | |
AjK | 0:c409efd8df78 | 101 | uint32_t channelNum(void) { return ChannelNum; } |
AjK | 0:c409efd8df78 | 102 | uint32_t transferSize(void) { return TransferSize; } |
AjK | 0:c409efd8df78 | 103 | uint32_t transferWidth(void) { return TransferWidth; } |
AjK | 0:c409efd8df78 | 104 | uint32_t srcMemAddr(void) { return SrcMemAddr; } |
AjK | 0:c409efd8df78 | 105 | uint32_t dstMemAddr(void) { return DstMemAddr; } |
AjK | 0:c409efd8df78 | 106 | uint32_t transferType(void) { return TransferType; } |
AjK | 0:c409efd8df78 | 107 | uint32_t srcConn(void) { return SrcConn; } |
AjK | 0:c409efd8df78 | 108 | uint32_t dstConn(void) { return DstConn; } |
AjK | 0:c409efd8df78 | 109 | uint32_t dmaLLI(void) { return DMALLI; } |
AjK | 0:c409efd8df78 | 110 | |
AjK | 0:c409efd8df78 | 111 | FunctionPointer *isrIntTCStat; |
AjK | 0:c409efd8df78 | 112 | FunctionPointer *isrIntErrStat; |
AjK | 0:c409efd8df78 | 113 | }; |
AjK | 0:c409efd8df78 | 114 | |
AjK | 0:c409efd8df78 | 115 | /** |
AjK | 0:c409efd8df78 | 116 | * @brief GPDMA Linker List Item structure type definition |
AjK | 0:c409efd8df78 | 117 | */ |
AjK | 0:c409efd8df78 | 118 | /* |
AjK | 0:c409efd8df78 | 119 | typedef struct { |
AjK | 0:c409efd8df78 | 120 | uint32_t SrcAddr; //!< Source Address |
AjK | 0:c409efd8df78 | 121 | uint32_t DstAddr; //!< Destination address |
AjK | 0:c409efd8df78 | 122 | uint32_t NextLLI; //!< Next LLI address, otherwise set to '0' |
AjK | 0:c409efd8df78 | 123 | uint32_t Control; //!< GPDMA Control of this LLI |
AjK | 0:c409efd8df78 | 124 | } GPDMA_LLI_t; |
AjK | 0:c409efd8df78 | 125 | */ |
AjK | 0:c409efd8df78 | 126 | |
AjK | 1:9700b9455cbf | 127 | |
AjK | 1:9700b9455cbf | 128 | /** |
AjK | 1:9700b9455cbf | 129 | * @brief MODDMA GPDMA Controller |
AjK | 0:c409efd8df78 | 130 | * @author Andy Kirkham |
AjK | 1:9700b9455cbf | 131 | * @see http://mbed.org/cookbook/MODDMA |
AjK | 1:9700b9455cbf | 132 | * @see example1.cpp |
AjK | 0:c409efd8df78 | 133 | * @see API |
AjK | 0:c409efd8df78 | 134 | * |
AjK | 1:9700b9455cbf | 135 | * <b>MODDMA</b> defines a GPDMA controller and multiple DMA configurations that allow for DMA |
AjK | 0:c409efd8df78 | 136 | * transfers from memory to memory, memory to peripheral or peripheral to memory. |
AjK | 1:9700b9455cbf | 137 | * |
AjK | 1:9700b9455cbf | 138 | * At the heart of the library is the MODDMA class the defines a single instance controller that |
AjK | 1:9700b9455cbf | 139 | * manages all the GPDMA hardware registers and interrupts. The controller can accept multiple |
AjK | 1:9700b9455cbf | 140 | * configurations that define the transfer. Each configuration specifies the src and dest information |
AjK | 1:9700b9455cbf | 141 | * and other associated parts to maintain the transfer process. |
AjK | 1:9700b9455cbf | 142 | * |
AjK | 1:9700b9455cbf | 143 | * Standard example: |
AjK | 1:9700b9455cbf | 144 | * @code |
AjK | 1:9700b9455cbf | 145 | * #include "mbed.h" |
AjK | 1:9700b9455cbf | 146 | * #include "MODDMA.h" |
AjK | 1:9700b9455cbf | 147 | * |
AjK | 1:9700b9455cbf | 148 | * DigitalOut led1(LED1); |
AjK | 1:9700b9455cbf | 149 | * Serial pc(USBTX, USBRX); // tx, rx |
AjK | 1:9700b9455cbf | 150 | * MODDMA dma; |
AjK | 1:9700b9455cbf | 151 | * |
AjK | 1:9700b9455cbf | 152 | * int main() { |
AjK | 1:9700b9455cbf | 153 | * |
AjK | 1:9700b9455cbf | 154 | * // Create a string buffer to send directly to a Uart/Serial |
AjK | 1:9700b9455cbf | 155 | * char s[] = "***DMA*** ABCDEFGHIJKLMNOPQRSTUVWXYZ ***DMA***"; |
AjK | 1:9700b9455cbf | 156 | * |
AjK | 1:9700b9455cbf | 157 | * // Create a transfer configuarion |
AjK | 1:9700b9455cbf | 158 | * MODDMA_Config *config = new MODDMA_Config; |
AjK | 1:9700b9455cbf | 159 | * |
AjK | 1:9700b9455cbf | 160 | * // Provide a "minimal" setup for demo purposes. |
AjK | 1:9700b9455cbf | 161 | * config |
AjK | 1:9700b9455cbf | 162 | * ->channelNum ( MODDMA::Channel_0 ) // The DMA channel to use. |
AjK | 1:9700b9455cbf | 163 | * ->srcMemAddr ( (uint32_t) &s ) // A pointer to the buffer to send. |
AjK | 1:9700b9455cbf | 164 | * ->transferSize ( sizeof(s) ) // The size of that buffer. |
AjK | 1:9700b9455cbf | 165 | * ->transferType ( MODDMA::m2p ) // Buffer is memory, dest is peripheral |
AjK | 1:9700b9455cbf | 166 | * ->dstConn ( MODDMA::UART0_Tx ) // Specifically, peripheral is Uart0 TX (USBTX, USBRX) |
AjK | 1:9700b9455cbf | 167 | * ; // config end. |
AjK | 1:9700b9455cbf | 168 | * |
AjK | 1:9700b9455cbf | 169 | * // Pass the configuration to the MODDMA controller. |
AjK | 1:9700b9455cbf | 170 | * dma.Setup( config ); |
AjK | 1:9700b9455cbf | 171 | * |
AjK | 1:9700b9455cbf | 172 | * // Enable the channel and begin transfer. |
AjK | 1:9700b9455cbf | 173 | * dma.Enable( config->channelNum() ); |
AjK | 1:9700b9455cbf | 174 | * |
AjK | 1:9700b9455cbf | 175 | * while(1) { |
AjK | 1:9700b9455cbf | 176 | * led1 = !led1; |
AjK | 1:9700b9455cbf | 177 | * wait(0.25); |
AjK | 1:9700b9455cbf | 178 | * } |
AjK | 1:9700b9455cbf | 179 | * } |
AjK | 1:9700b9455cbf | 180 | * @endcode |
AjK | 0:c409efd8df78 | 181 | */ |
AjK | 0:c409efd8df78 | 182 | class MODDMA |
AjK | 0:c409efd8df78 | 183 | { |
AjK | 0:c409efd8df78 | 184 | public: |
AjK | 0:c409efd8df78 | 185 | |
AjK | 0:c409efd8df78 | 186 | //! Channel definitions. |
AjK | 0:c409efd8df78 | 187 | enum CHANNELS { |
AjK | 0:c409efd8df78 | 188 | Channel_0 = 0 /*!< Channel 0 */ |
AjK | 0:c409efd8df78 | 189 | , Channel_1 /*!< Channel 1 */ |
AjK | 0:c409efd8df78 | 190 | , Channel_2 /*!< Channel 2 */ |
AjK | 0:c409efd8df78 | 191 | , Channel_3 /*!< Channel 3 */ |
AjK | 0:c409efd8df78 | 192 | , Channel_4 /*!< Channel 4 */ |
AjK | 0:c409efd8df78 | 193 | , Channel_5 /*!< Channel 5 */ |
AjK | 0:c409efd8df78 | 194 | , Channel_6 /*!< Channel 6 */ |
AjK | 0:c409efd8df78 | 195 | , Channel_7 /*!< Channel 7 */ |
AjK | 0:c409efd8df78 | 196 | }; |
AjK | 0:c409efd8df78 | 197 | |
AjK | 0:c409efd8df78 | 198 | //! Interrupt callback types. |
AjK | 0:c409efd8df78 | 199 | enum IrqType_t { |
AjK | 0:c409efd8df78 | 200 | TcIrq = 0 /*!< Terminal Count interrupt */ |
AjK | 0:c409efd8df78 | 201 | , ErrIrq /*!< Error interrupt */ |
AjK | 0:c409efd8df78 | 202 | }; |
AjK | 0:c409efd8df78 | 203 | |
AjK | 0:c409efd8df78 | 204 | //! Return status codes. |
AjK | 0:c409efd8df78 | 205 | enum Status { |
AjK | 0:c409efd8df78 | 206 | Ok = 0 /*!< Ok, suceeded */ |
AjK | 0:c409efd8df78 | 207 | , Error = -1 /*!< General error */ |
AjK | 0:c409efd8df78 | 208 | , ErrChInUse = -2 /*!< Specific error, channel in use */ |
AjK | 0:c409efd8df78 | 209 | }; |
AjK | 0:c409efd8df78 | 210 | |
AjK | 0:c409efd8df78 | 211 | //! DMA Connection number definitions |
AjK | 0:c409efd8df78 | 212 | enum GPDMA_CONNECTION { |
AjK | 0:c409efd8df78 | 213 | SSP0_Tx = 0UL /*!< SSP0 Tx */ |
AjK | 0:c409efd8df78 | 214 | , SSP0_Rx = 1UL /*!< SSP0 Rx */ |
AjK | 0:c409efd8df78 | 215 | , SSP1_Tx = 2UL /*!< SSP1 Tx */ |
AjK | 0:c409efd8df78 | 216 | , SSP1_Rx = 3UL /*!< SSP1 Rx */ |
AjK | 0:c409efd8df78 | 217 | , ADC = 4UL /*!< ADC */ |
AjK | 0:c409efd8df78 | 218 | , I2S_Channel_0 = 5UL /*!< I2S channel 0 */ |
AjK | 0:c409efd8df78 | 219 | , I2S_Channel_1 = 6UL /*!< I2S channel 1 */ |
AjK | 0:c409efd8df78 | 220 | , DAC = 7UL /*!< DAC */ |
AjK | 0:c409efd8df78 | 221 | , UART0_Tx = 8UL /*!< UART0 Tx */ |
AjK | 0:c409efd8df78 | 222 | , UART0_Rx = 9UL /*!< UART0 Rx */ |
AjK | 0:c409efd8df78 | 223 | , UART1_Tx = 10UL /*!< UART1 Tx */ |
AjK | 0:c409efd8df78 | 224 | , UART1_Rx = 11UL /*!< UART1 Rx */ |
AjK | 0:c409efd8df78 | 225 | , UART2_Tx = 12UL /*!< UART2 Tx */ |
AjK | 0:c409efd8df78 | 226 | , UART2_Rx = 13UL /*!< UART2 Rx */ |
AjK | 0:c409efd8df78 | 227 | , UART3_Tx = 14UL /*!< UART3 Tx */ |
AjK | 0:c409efd8df78 | 228 | , UART3_Rx = 15UL /*!< UART3 Rx */ |
AjK | 0:c409efd8df78 | 229 | , MAT0_0 = 16UL /*!< MAT0.0 */ |
AjK | 0:c409efd8df78 | 230 | , MAT0_1 = 17UL /*!< MAT0.1 */ |
AjK | 0:c409efd8df78 | 231 | , MAT1_0 = 18UL /*!< MAT1.0 */ |
AjK | 0:c409efd8df78 | 232 | , MAT1_1 = 19UL /*!< MAT1.1 */ |
AjK | 0:c409efd8df78 | 233 | , MAT2_0 = 20UL /**< MAT2.0 */ |
AjK | 0:c409efd8df78 | 234 | , MAT2_1 = 21UL /*!< MAT2.1 */ |
AjK | 0:c409efd8df78 | 235 | , MAT3_0 = 22UL /*!< MAT3.0 */ |
AjK | 0:c409efd8df78 | 236 | , MAT3_1 = 23UL /*!< MAT3.1 */ |
AjK | 0:c409efd8df78 | 237 | }; |
AjK | 0:c409efd8df78 | 238 | |
AjK | 0:c409efd8df78 | 239 | //! GPDMA Transfer type definitions |
AjK | 0:c409efd8df78 | 240 | enum GPDMA_TRANSFERTYPE { |
AjK | 0:c409efd8df78 | 241 | m2m = 0UL /*!< Memory to memory - DMA control */ |
AjK | 0:c409efd8df78 | 242 | , m2p = 1UL /*!< Memory to peripheral - DMA control */ |
AjK | 0:c409efd8df78 | 243 | , p2m = 2UL /*!< Peripheral to memory - DMA control */ |
AjK | 0:c409efd8df78 | 244 | , p2p = 3UL /*!< Src peripheral to dest peripheral - DMA control */ |
AjK | 0:c409efd8df78 | 245 | }; |
AjK | 0:c409efd8df78 | 246 | |
AjK | 0:c409efd8df78 | 247 | //! Burst size in Source and Destination definitions */ |
AjK | 0:c409efd8df78 | 248 | enum GPDMA_BSIZE { |
AjK | 0:c409efd8df78 | 249 | _1 = 0UL /*!< Burst size = 1 */ |
AjK | 0:c409efd8df78 | 250 | , _4 = 1UL /*!< Burst size = 4 */ |
AjK | 0:c409efd8df78 | 251 | , _8 = 2UL /*!< Burst size = 8 */ |
AjK | 0:c409efd8df78 | 252 | , _16 = 3UL /*!< Burst size = 16 */ |
AjK | 0:c409efd8df78 | 253 | , _32 = 4UL /*!< Burst size = 32 */ |
AjK | 0:c409efd8df78 | 254 | , _64 = 5UL /*!< Burst size = 64 */ |
AjK | 0:c409efd8df78 | 255 | , _128 = 6UL /*!< Burst size = 128 */ |
AjK | 0:c409efd8df78 | 256 | , _256 = 7UL /*!< Burst size = 256 */ |
AjK | 0:c409efd8df78 | 257 | }; |
AjK | 0:c409efd8df78 | 258 | |
AjK | 0:c409efd8df78 | 259 | //! Width in Src transfer width and Dest transfer width definitions */ |
AjK | 0:c409efd8df78 | 260 | enum GPDMA_WIDTH { |
AjK | 0:c409efd8df78 | 261 | byte = 0UL /*!< Width = 1 byte */ |
AjK | 0:c409efd8df78 | 262 | , halfword = 1UL /*!< Width = 2 bytes */ |
AjK | 0:c409efd8df78 | 263 | , word = 2UL /*!< Width = 4 bytes */ |
AjK | 0:c409efd8df78 | 264 | }; |
AjK | 0:c409efd8df78 | 265 | |
AjK | 0:c409efd8df78 | 266 | //! DMA Request Select Mode definitions. */ |
AjK | 0:c409efd8df78 | 267 | enum GPDMA_REQSEL { |
AjK | 0:c409efd8df78 | 268 | uart = 0UL /*!< UART TX/RX is selected */ |
AjK | 0:c409efd8df78 | 269 | , timer = 1UL /*!< Timer match is selected */ |
AjK | 0:c409efd8df78 | 270 | }; |
AjK | 0:c409efd8df78 | 271 | |
AjK | 0:c409efd8df78 | 272 | //! GPDMA Control register bits. |
AjK | 0:c409efd8df78 | 273 | enum Config { |
AjK | 0:c409efd8df78 | 274 | _E = 1 /*!< DMA Controller enable */ |
AjK | 0:c409efd8df78 | 275 | , _M = 2 /*!< AHB Master endianness configuration */ |
AjK | 0:c409efd8df78 | 276 | }; |
AjK | 0:c409efd8df78 | 277 | |
AjK | 0:c409efd8df78 | 278 | //! GPDMA Channel config register bits. |
AjK | 0:c409efd8df78 | 279 | enum CConfig { |
AjK | 0:c409efd8df78 | 280 | _CE = (1UL << 0) /*!< Channel enable */ |
AjK | 0:c409efd8df78 | 281 | , _IE = (1UL << 14) /*!< Interrupt error mask */ |
AjK | 0:c409efd8df78 | 282 | , _ITC = (1UL << 15) /*!< Terminal count interrupt mask */ |
AjK | 0:c409efd8df78 | 283 | , _L = (1UL << 16) /*!< Lock */ |
AjK | 0:c409efd8df78 | 284 | , _A = (1UL << 17) /*!< Active */ |
AjK | 0:c409efd8df78 | 285 | , _H = (1UL << 18) /*!< Halt */ |
AjK | 0:c409efd8df78 | 286 | }; |
AjK | 0:c409efd8df78 | 287 | |
AjK | 0:c409efd8df78 | 288 | /** |
AjK | 0:c409efd8df78 | 289 | * The MODDMA constructor is used to initialise the DMA controller object. |
AjK | 0:c409efd8df78 | 290 | */ |
AjK | 0:c409efd8df78 | 291 | MODDMA() { init(true); } |
AjK | 0:c409efd8df78 | 292 | |
AjK | 0:c409efd8df78 | 293 | /** |
AjK | 0:c409efd8df78 | 294 | * The MODDMA destructor. |
AjK | 0:c409efd8df78 | 295 | */ |
AjK | 0:c409efd8df78 | 296 | ~MODDMA() {} |
AjK | 0:c409efd8df78 | 297 | |
AjK | 0:c409efd8df78 | 298 | /** |
AjK | 0:c409efd8df78 | 299 | * Used to setup the DMA controller to prepare for a data transfer. |
AjK | 0:c409efd8df78 | 300 | * |
AjK | 0:c409efd8df78 | 301 | * @param c A pointer to an instance of MODDMA_Config to setup. |
AjK | 0:c409efd8df78 | 302 | */ |
AjK | 0:c409efd8df78 | 303 | Status Setup(MODDMA_Config *c); |
AjK | 0:c409efd8df78 | 304 | |
AjK | 0:c409efd8df78 | 305 | /** |
AjK | 0:c409efd8df78 | 306 | * Enable and begin data transfer. |
AjK | 0:c409efd8df78 | 307 | * |
AjK | 0:c409efd8df78 | 308 | * @param ChannelNumber Type CHANNELS, the channel number to enable |
AjK | 0:c409efd8df78 | 309 | */ |
AjK | 0:c409efd8df78 | 310 | void Enable(CHANNELS ChannelNumber); |
AjK | 0:c409efd8df78 | 311 | |
AjK | 0:c409efd8df78 | 312 | /** |
AjK | 0:c409efd8df78 | 313 | * Enable and begin data transfer (overloaded function) |
AjK | 0:c409efd8df78 | 314 | * |
AjK | 0:c409efd8df78 | 315 | * @param ChannelNumber Type uin32_t, the channel number to enable |
AjK | 0:c409efd8df78 | 316 | */ |
AjK | 0:c409efd8df78 | 317 | void Enable(uint32_t ChannelNumber) { Enable((CHANNELS)(ChannelNumber & 0x7)); } |
AjK | 0:c409efd8df78 | 318 | |
AjK | 0:c409efd8df78 | 319 | /** |
AjK | 0:c409efd8df78 | 320 | * Disable a channel and end data transfer. |
AjK | 0:c409efd8df78 | 321 | * |
AjK | 0:c409efd8df78 | 322 | * @param ChannelNumber Type CHANNELS, the channel number to enable |
AjK | 0:c409efd8df78 | 323 | */ |
AjK | 0:c409efd8df78 | 324 | void Disable(CHANNELS ChannelNumber); |
AjK | 0:c409efd8df78 | 325 | |
AjK | 0:c409efd8df78 | 326 | /** |
AjK | 0:c409efd8df78 | 327 | * Disable a channel and end data transfer (overloaded function) |
AjK | 0:c409efd8df78 | 328 | * |
AjK | 0:c409efd8df78 | 329 | * @param ChannelNumber Type uin32_t, the channel number to disable |
AjK | 0:c409efd8df78 | 330 | */ |
AjK | 0:c409efd8df78 | 331 | void Disable(uint32_t ChannelNumber) { Disable((CHANNELS)(ChannelNumber & 0x7)); } |
AjK | 0:c409efd8df78 | 332 | |
AjK | 0:c409efd8df78 | 333 | /** |
AjK | 0:c409efd8df78 | 334 | * Is the specified channel enabled? |
AjK | 0:c409efd8df78 | 335 | * |
AjK | 0:c409efd8df78 | 336 | * @param ChannelNumber Type CHANNELS, the channel number to test |
AjK | 0:c409efd8df78 | 337 | * @return bool true if enabled, false otherwise. |
AjK | 0:c409efd8df78 | 338 | */ |
AjK | 0:c409efd8df78 | 339 | bool Enabled(CHANNELS ChannelNumber); |
AjK | 0:c409efd8df78 | 340 | |
AjK | 0:c409efd8df78 | 341 | /** |
AjK | 0:c409efd8df78 | 342 | * Is the specified channel enabled? (overloaded function) |
AjK | 0:c409efd8df78 | 343 | * |
AjK | 0:c409efd8df78 | 344 | * @param ChannelNumber Type uin32_t, the channel number to test |
AjK | 0:c409efd8df78 | 345 | * @return bool true if enabled, false otherwise. |
AjK | 0:c409efd8df78 | 346 | */ |
AjK | 0:c409efd8df78 | 347 | bool Enabled(uint32_t ChannelNumber) { Enabled((CHANNELS)(ChannelNumber & 0x7)); } |
AjK | 0:c409efd8df78 | 348 | |
AjK | 0:c409efd8df78 | 349 | __INLINE uint32_t IntStat(uint32_t n) { return (1UL << n) & 0xFF; } |
AjK | 0:c409efd8df78 | 350 | __INLINE uint32_t IntTCStat_Ch(uint32_t n) { return (1UL << n) & 0xFF; } |
AjK | 0:c409efd8df78 | 351 | __INLINE uint32_t IntTCClear_Ch(uint32_t n) { return (1UL << n) & 0xFF; } |
AjK | 0:c409efd8df78 | 352 | __INLINE uint32_t IntErrStat_Ch(uint32_t n) { return (1UL << n) & 0xFF; } |
AjK | 0:c409efd8df78 | 353 | __INLINE uint32_t IntErrClr_Ch(uint32_t n) { return (1UL << n) & 0xFF; } |
AjK | 0:c409efd8df78 | 354 | __INLINE uint32_t RawIntErrStat_Ch(uint32_t n) { return (1UL << n) & 0xFF; } |
AjK | 0:c409efd8df78 | 355 | __INLINE uint32_t EnbldChns_Ch(uint32_t n) { return (1UL << n) & 0xFF; } |
AjK | 0:c409efd8df78 | 356 | __INLINE uint32_t SoftBReq_Src(uint32_t n) { return (1UL << n) & 0xFFFF; } |
AjK | 0:c409efd8df78 | 357 | __INLINE uint32_t SoftSReq_Src(uint32_t n) { return (1UL << n) & 0xFFFF; } |
AjK | 0:c409efd8df78 | 358 | __INLINE uint32_t SoftLBReq_Src(uint32_t n) { return (1UL << n) & 0xFFFF; } |
AjK | 0:c409efd8df78 | 359 | __INLINE uint32_t SoftLSReq_Src(uint32_t n) { return (1UL << n) & 0xFFFF; } |
AjK | 0:c409efd8df78 | 360 | __INLINE uint32_t Sync_Src(uint32_t n) { return (1UL << n) & 0xFFFF; } |
AjK | 0:c409efd8df78 | 361 | __INLINE uint32_t ReqSel_Input(uint32_t n) { return (1UL << (n - 8)) & 0xFF; } |
AjK | 0:c409efd8df78 | 362 | |
AjK | 0:c409efd8df78 | 363 | |
AjK | 0:c409efd8df78 | 364 | __INLINE uint32_t CxControl_TransferSize(uint32_t n) { return (n & 0xFFF) << 0; } |
AjK | 0:c409efd8df78 | 365 | __INLINE uint32_t CxControl_SBSize(uint32_t n) { return (n & 0x7) << 12; } |
AjK | 0:c409efd8df78 | 366 | __INLINE uint32_t CxControl_DBSize(uint32_t n) { return (n & 0x7) << 15; } |
AjK | 0:c409efd8df78 | 367 | __INLINE uint32_t CxControl_SWidth(uint32_t n) { return (n & 0x7) << 18; } |
AjK | 0:c409efd8df78 | 368 | __INLINE uint32_t CxControl_DWidth(uint32_t n) { return (n & 0x7) << 21; } |
AjK | 0:c409efd8df78 | 369 | __INLINE uint32_t CxControl_SI() { return (1UL << 26); } |
AjK | 0:c409efd8df78 | 370 | __INLINE uint32_t CxControl_DI() { return (1UL << 27); } |
AjK | 0:c409efd8df78 | 371 | __INLINE uint32_t CxControl_Prot1() { return (1UL << 28); } |
AjK | 0:c409efd8df78 | 372 | __INLINE uint32_t CxControl_Prot2() { return (1UL << 29); } |
AjK | 0:c409efd8df78 | 373 | __INLINE uint32_t CxControl_Prot3() { return (1UL << 30); } |
AjK | 0:c409efd8df78 | 374 | __INLINE uint32_t CxControl_I() { return (1UL << 31); } |
AjK | 0:c409efd8df78 | 375 | __INLINE uint32_t CxControl_E() { return (1UL << 0); } |
AjK | 0:c409efd8df78 | 376 | __INLINE uint32_t CxConfig_SrcPeripheral(uint32_t n) { return (n & 0x1F) << 1; } |
AjK | 0:c409efd8df78 | 377 | __INLINE uint32_t CxConfig_DestPeripheral(uint32_t n) { return (n & 0x1F) << 6; } |
AjK | 0:c409efd8df78 | 378 | __INLINE uint32_t CxConfig_TransferType(uint32_t n) { return (n & 0x7) << 11; } |
AjK | 0:c409efd8df78 | 379 | __INLINE uint32_t CxConfig_IE() { return (1UL << 14); } |
AjK | 0:c409efd8df78 | 380 | __INLINE uint32_t CxConfig_ITC() { return (1UL << 15); } |
AjK | 0:c409efd8df78 | 381 | __INLINE uint32_t CxConfig_L() { return (1UL << 16); } |
AjK | 0:c409efd8df78 | 382 | __INLINE uint32_t CxConfig_A() { return (1UL << 17); } |
AjK | 0:c409efd8df78 | 383 | __INLINE uint32_t CxConfig_H() { return (1UL << 18); } |
AjK | 0:c409efd8df78 | 384 | |
AjK | 0:c409efd8df78 | 385 | /** |
AjK | 0:c409efd8df78 | 386 | * A store for up to 8 (8 channels) of configurations. |
AjK | 0:c409efd8df78 | 387 | * @see MODDMA_Config |
AjK | 0:c409efd8df78 | 388 | */ |
AjK | 0:c409efd8df78 | 389 | MODDMA_Config *setups[8]; |
AjK | 0:c409efd8df78 | 390 | |
AjK | 0:c409efd8df78 | 391 | /** |
AjK | 0:c409efd8df78 | 392 | * Get a pointer to the current configuration the ISR is servicing. |
AjK | 0:c409efd8df78 | 393 | * |
AjK | 0:c409efd8df78 | 394 | * @return MODDMA_Config * A pointer to the setup the ISR is currently servicing. |
AjK | 0:c409efd8df78 | 395 | */ |
AjK | 0:c409efd8df78 | 396 | MODDMA_Config *getConfig(void) { return setups[IrqProcessingChannel]; } |
AjK | 0:c409efd8df78 | 397 | |
AjK | 0:c409efd8df78 | 398 | /** |
AjK | 0:c409efd8df78 | 399 | * Set which channel the ISR is currently servicing. |
AjK | 0:c409efd8df78 | 400 | * |
AjK | 0:c409efd8df78 | 401 | * *** USED INTERNALLY. DO NOT CALL FROM USER PROGRAMS *** |
AjK | 0:c409efd8df78 | 402 | * |
AjK | 0:c409efd8df78 | 403 | * Must be public so the extern "C" ISR can use it. |
AjK | 0:c409efd8df78 | 404 | */ |
AjK | 0:c409efd8df78 | 405 | void setIrqProcessingChannel(CHANNELS n) { IrqProcessingChannel = n; } |
AjK | 0:c409efd8df78 | 406 | |
AjK | 0:c409efd8df78 | 407 | /** |
AjK | 0:c409efd8df78 | 408 | * Gets which channel the ISR is currently servicing. |
AjK | 0:c409efd8df78 | 409 | * |
AjK | 0:c409efd8df78 | 410 | * @return CHANNELS The current channel the ISR is servicing. |
AjK | 0:c409efd8df78 | 411 | */ |
AjK | 0:c409efd8df78 | 412 | CHANNELS irqProcessingChannel(void) { return IrqProcessingChannel; } |
AjK | 0:c409efd8df78 | 413 | |
AjK | 0:c409efd8df78 | 414 | /** |
AjK | 0:c409efd8df78 | 415 | * Gets which channel the ISR is currently servicing. |
AjK | 0:c409efd8df78 | 416 | * |
AjK | 0:c409efd8df78 | 417 | * @return uint32_t The current channel the ISR is servicing. |
AjK | 0:c409efd8df78 | 418 | */ |
AjK | 0:c409efd8df78 | 419 | uint32_t irqProcessingChannel(void) { return (uint32_t)(IrqProcessingChannel & 0x7); } |
AjK | 0:c409efd8df78 | 420 | |
AjK | 0:c409efd8df78 | 421 | /** |
AjK | 0:c409efd8df78 | 422 | * Sets which type of IRQ the ISR is making a callback for. |
AjK | 0:c409efd8df78 | 423 | * |
AjK | 0:c409efd8df78 | 424 | * *** USED INTERNALLY. DO NOT CALL FROM USER PROGRAMS *** |
AjK | 0:c409efd8df78 | 425 | * |
AjK | 0:c409efd8df78 | 426 | * Must be public so the extern "C" ISR can use it. |
AjK | 0:c409efd8df78 | 427 | */ |
AjK | 0:c409efd8df78 | 428 | void setIrqType(IrqType_t n) { IrqType = n; } |
AjK | 0:c409efd8df78 | 429 | |
AjK | 0:c409efd8df78 | 430 | /** |
AjK | 0:c409efd8df78 | 431 | * Get which type of IRQ the ISR is calling you about, |
AjK | 0:c409efd8df78 | 432 | * terminal count or error. |
AjK | 0:c409efd8df78 | 433 | */ |
AjK | 0:c409efd8df78 | 434 | IrqType_t irqType(void) { return IrqType; } |
AjK | 0:c409efd8df78 | 435 | |
AjK | 0:c409efd8df78 | 436 | /** |
AjK | 0:c409efd8df78 | 437 | * Clear the interrupt after handling. |
AjK | 0:c409efd8df78 | 438 | * |
AjK | 0:c409efd8df78 | 439 | * @param CHANNELS The channel the IQR occured on. |
AjK | 0:c409efd8df78 | 440 | */ |
AjK | 0:c409efd8df78 | 441 | void clearTcIrq(CHANNELS n) { LPC_GPDMA->DMACIntTCClear = (uint32_t)(1UL << n); } |
AjK | 0:c409efd8df78 | 442 | |
AjK | 0:c409efd8df78 | 443 | /** |
AjK | 0:c409efd8df78 | 444 | * Clear the interrupt the ISR is currently handing.. |
AjK | 0:c409efd8df78 | 445 | */ |
AjK | 0:c409efd8df78 | 446 | void clearTcIrq(void) { clearTcIrq( IrqProcessingChannel ); } |
AjK | 0:c409efd8df78 | 447 | |
AjK | 0:c409efd8df78 | 448 | /** |
AjK | 0:c409efd8df78 | 449 | * Clear the error interrupt after handling. |
AjK | 0:c409efd8df78 | 450 | * |
AjK | 0:c409efd8df78 | 451 | * @param CHANNELS The channel the IQR occured on. |
AjK | 0:c409efd8df78 | 452 | */ |
AjK | 0:c409efd8df78 | 453 | void clearErrIrq(CHANNELS n) { LPC_GPDMA->DMACIntTCClear = (uint32_t)(1UL << n); } |
AjK | 0:c409efd8df78 | 454 | |
AjK | 0:c409efd8df78 | 455 | /** |
AjK | 0:c409efd8df78 | 456 | * Clear the error interrupt the ISR is currently handing. |
AjK | 0:c409efd8df78 | 457 | */ |
AjK | 0:c409efd8df78 | 458 | void clearErrIrq(void) { clearErrIrq( IrqProcessingChannel ); } |
AjK | 0:c409efd8df78 | 459 | |
AjK | 0:c409efd8df78 | 460 | /** |
AjK | 0:c409efd8df78 | 461 | * Is the supplied channel currently active? |
AjK | 0:c409efd8df78 | 462 | * |
AjK | 0:c409efd8df78 | 463 | * @param CHANNELS The channel to inquire about. |
AjK | 0:c409efd8df78 | 464 | * @return bool true if active, false otherwise. |
AjK | 0:c409efd8df78 | 465 | */ |
AjK | 0:c409efd8df78 | 466 | bool isActive(CHANNELS ChannelNumber); |
AjK | 0:c409efd8df78 | 467 | |
AjK | 0:c409efd8df78 | 468 | /** |
AjK | 0:c409efd8df78 | 469 | * Halt the supplied channel. |
AjK | 0:c409efd8df78 | 470 | * |
AjK | 0:c409efd8df78 | 471 | * @param CHANNELS The channel to halt. |
AjK | 0:c409efd8df78 | 472 | */ |
AjK | 0:c409efd8df78 | 473 | void haltChannel(CHANNELS ChannelNumber); |
AjK | 0:c409efd8df78 | 474 | |
AjK | 0:c409efd8df78 | 475 | /** |
AjK | 0:c409efd8df78 | 476 | * Wait for channel transfer to complete and then halt. |
AjK | 0:c409efd8df78 | 477 | * |
AjK | 0:c409efd8df78 | 478 | * @param CHANNELS The channel to wait for then halt. |
AjK | 0:c409efd8df78 | 479 | */ |
AjK | 0:c409efd8df78 | 480 | void haltAndWaitChannelComplete(CHANNELS n) { haltChannel(n); while (isActive(n)); } |
AjK | 0:c409efd8df78 | 481 | |
AjK | 0:c409efd8df78 | 482 | /** |
AjK | 0:c409efd8df78 | 483 | * The MODDMA controllers terminal count interrupt callback. |
AjK | 0:c409efd8df78 | 484 | */ |
AjK | 0:c409efd8df78 | 485 | FunctionPointer isrIntTCStat; |
AjK | 0:c409efd8df78 | 486 | |
AjK | 0:c409efd8df78 | 487 | /** |
AjK | 0:c409efd8df78 | 488 | * The MODDMA controllers error interrupt callback. |
AjK | 0:c409efd8df78 | 489 | */ |
AjK | 0:c409efd8df78 | 490 | FunctionPointer isrIntErrStat; |
AjK | 0:c409efd8df78 | 491 | |
AjK | 0:c409efd8df78 | 492 | protected: |
AjK | 0:c409efd8df78 | 493 | |
AjK | 0:c409efd8df78 | 494 | void init(bool isConstructorCalling, int Channels = 0xFF, int Tc = 0xFF, int Err = 0xFF); |
AjK | 0:c409efd8df78 | 495 | |
AjK | 0:c409efd8df78 | 496 | // Data LUTs. |
AjK | 0:c409efd8df78 | 497 | uint32_t LUTPerAddr(int n); |
AjK | 0:c409efd8df78 | 498 | uint8_t LUTPerBurst(int n); |
AjK | 0:c409efd8df78 | 499 | uint8_t LUTPerWid(int n); |
AjK | 0:c409efd8df78 | 500 | uint32_t Channel_p(int channel); |
AjK | 0:c409efd8df78 | 501 | |
AjK | 0:c409efd8df78 | 502 | CHANNELS IrqProcessingChannel; |
AjK | 0:c409efd8df78 | 503 | |
AjK | 0:c409efd8df78 | 504 | IrqType_t IrqType; |
AjK | 0:c409efd8df78 | 505 | }; |
AjK | 0:c409efd8df78 | 506 | |
AjK | 0:c409efd8df78 | 507 | }; // namespace AjK ends. |
AjK | 0:c409efd8df78 | 508 | |
AjK | 0:c409efd8df78 | 509 | using namespace AjK; |
AjK | 0:c409efd8df78 | 510 | |
AjK | 0:c409efd8df78 | 511 | #endif |