A library with drivers for different peripherals on the LPC4088 QuickStart Board or related add-on boards.
Dependencies: FATFileSystem
Fork of EALib by
gpdma.cpp@10:f2409dc07e49, 2014-01-10 (annotated)
- Committer:
- embeddedartists
- Date:
- Fri Jan 10 08:24:42 2014 +0000
- Revision:
- 10:f2409dc07e49
- Parent:
- 0:0fdadbc3d852
- Child:
- 12:15597e45eea0
Fixed example in QSPIFileSystem documentation
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
embeddedartists | 0:0fdadbc3d852 | 1 | |
embeddedartists | 0:0fdadbc3d852 | 2 | /****************************************************************************** |
embeddedartists | 0:0fdadbc3d852 | 3 | * Includes |
embeddedartists | 0:0fdadbc3d852 | 4 | *****************************************************************************/ |
embeddedartists | 0:0fdadbc3d852 | 5 | |
embeddedartists | 0:0fdadbc3d852 | 6 | #include "gpdma.h" |
embeddedartists | 0:0fdadbc3d852 | 7 | |
embeddedartists | 0:0fdadbc3d852 | 8 | /****************************************************************************** |
embeddedartists | 0:0fdadbc3d852 | 9 | * Defines and typedefs |
embeddedartists | 0:0fdadbc3d852 | 10 | *****************************************************************************/ |
embeddedartists | 0:0fdadbc3d852 | 11 | |
embeddedartists | 0:0fdadbc3d852 | 12 | #define NUM_GPDMA_CHANNELS 8 |
embeddedartists | 0:0fdadbc3d852 | 13 | |
embeddedartists | 0:0fdadbc3d852 | 14 | #define GPDMACH(__x) ((LPC_GPDMACH_TypeDef*)(LPC_GPDMACH0_BASE + (0x20 * (__x)))) |
embeddedartists | 0:0fdadbc3d852 | 15 | |
embeddedartists | 0:0fdadbc3d852 | 16 | #define CH_MASK(__ch) (((1UL << (__ch)) & 0xFF)) |
embeddedartists | 0:0fdadbc3d852 | 17 | |
embeddedartists | 0:0fdadbc3d852 | 18 | /** |
embeddedartists | 0:0fdadbc3d852 | 19 | * @brief GPDMA request connections |
embeddedartists | 0:0fdadbc3d852 | 20 | */ |
embeddedartists | 0:0fdadbc3d852 | 21 | #define GPDMA_CONN_MEMORY ((0UL)) |
embeddedartists | 0:0fdadbc3d852 | 22 | #define GPDMA_CONN_SDC ((1UL)) /*!< SD card */ |
embeddedartists | 0:0fdadbc3d852 | 23 | |
embeddedartists | 0:0fdadbc3d852 | 24 | /** |
embeddedartists | 0:0fdadbc3d852 | 25 | * @brief Macro defines for DMA channel control registers |
embeddedartists | 0:0fdadbc3d852 | 26 | */ |
embeddedartists | 0:0fdadbc3d852 | 27 | #define GPDMA_DMACCxControl_TransferSize(n) (((n & 0xFFF) << 0)) /*!< Transfer size*/ |
embeddedartists | 0:0fdadbc3d852 | 28 | #define GPDMA_DMACCxControl_SBSize(n) (((n & 0x07) << 12)) /*!< Source burst size*/ |
embeddedartists | 0:0fdadbc3d852 | 29 | #define GPDMA_DMACCxControl_DBSize(n) (((n & 0x07) << 15)) /*!< Destination burst size*/ |
embeddedartists | 0:0fdadbc3d852 | 30 | #define GPDMA_DMACCxControl_SWidth(n) (((n & 0x07) << 18)) /*!< Source transfer width*/ |
embeddedartists | 0:0fdadbc3d852 | 31 | #define GPDMA_DMACCxControl_DWidth(n) (((n & 0x07) << 21)) /*!< Destination transfer width*/ |
embeddedartists | 0:0fdadbc3d852 | 32 | #define GPDMA_DMACCxControl_SI ((1UL << 26)) /*!< Source increment*/ |
embeddedartists | 0:0fdadbc3d852 | 33 | #define GPDMA_DMACCxControl_DI ((1UL << 27)) /*!< Destination increment*/ |
embeddedartists | 0:0fdadbc3d852 | 34 | #define GPDMA_DMACCxControl_SrcTransUseAHBMaster1 0 |
embeddedartists | 0:0fdadbc3d852 | 35 | #define GPDMA_DMACCxControl_DestTransUseAHBMaster1 0 |
embeddedartists | 0:0fdadbc3d852 | 36 | #define GPDMA_DMACCxControl_Prot1 ((1UL << 28)) /*!< Indicates that the access is in user mode or privileged mode*/ |
embeddedartists | 0:0fdadbc3d852 | 37 | #define GPDMA_DMACCxControl_Prot2 ((1UL << 29)) /*!< Indicates that the access is bufferable or not bufferable*/ |
embeddedartists | 0:0fdadbc3d852 | 38 | #define GPDMA_DMACCxControl_Prot3 ((1UL << 30)) /*!< Indicates that the access is cacheable or not cacheable*/ |
embeddedartists | 0:0fdadbc3d852 | 39 | #define GPDMA_DMACCxControl_I ((1UL << 31)) /*!< Terminal count interrupt enable bit */ |
embeddedartists | 0:0fdadbc3d852 | 40 | |
embeddedartists | 0:0fdadbc3d852 | 41 | /** |
embeddedartists | 0:0fdadbc3d852 | 42 | * @brief GPDMA Burst size in Source and Destination definitions |
embeddedartists | 0:0fdadbc3d852 | 43 | */ |
embeddedartists | 0:0fdadbc3d852 | 44 | #define GPDMA_BSIZE_1 ((0UL)) /*!< Burst size = 1 */ |
embeddedartists | 0:0fdadbc3d852 | 45 | #define GPDMA_BSIZE_4 ((1UL)) /*!< Burst size = 4 */ |
embeddedartists | 0:0fdadbc3d852 | 46 | #define GPDMA_BSIZE_8 ((2UL)) /*!< Burst size = 8 */ |
embeddedartists | 0:0fdadbc3d852 | 47 | #define GPDMA_BSIZE_16 ((3UL)) /*!< Burst size = 16 */ |
embeddedartists | 0:0fdadbc3d852 | 48 | #define GPDMA_BSIZE_32 ((4UL)) /*!< Burst size = 32 */ |
embeddedartists | 0:0fdadbc3d852 | 49 | #define GPDMA_BSIZE_64 ((5UL)) /*!< Burst size = 64 */ |
embeddedartists | 0:0fdadbc3d852 | 50 | #define GPDMA_BSIZE_128 ((6UL)) /*!< Burst size = 128 */ |
embeddedartists | 0:0fdadbc3d852 | 51 | #define GPDMA_BSIZE_256 ((7UL)) /*!< Burst size = 256 */ |
embeddedartists | 0:0fdadbc3d852 | 52 | |
embeddedartists | 0:0fdadbc3d852 | 53 | /** |
embeddedartists | 0:0fdadbc3d852 | 54 | * @brief Width in Source transfer width and Destination transfer width definitions |
embeddedartists | 0:0fdadbc3d852 | 55 | */ |
embeddedartists | 0:0fdadbc3d852 | 56 | #define GPDMA_WIDTH_BYTE ((0UL)) /*!< Width = 1 byte */ |
embeddedartists | 0:0fdadbc3d852 | 57 | #define GPDMA_WIDTH_HALFWORD ((1UL)) /*!< Width = 2 bytes */ |
embeddedartists | 0:0fdadbc3d852 | 58 | #define GPDMA_WIDTH_WORD ((2UL)) /*!< Width = 4 bytes */ |
embeddedartists | 0:0fdadbc3d852 | 59 | |
embeddedartists | 0:0fdadbc3d852 | 60 | /** |
embeddedartists | 0:0fdadbc3d852 | 61 | * @brief Macro defines for DMA Configuration register |
embeddedartists | 0:0fdadbc3d852 | 62 | */ |
embeddedartists | 0:0fdadbc3d852 | 63 | #define GPDMA_DMACConfig_E ((0x01)) /*!< DMA Controller enable*/ |
embeddedartists | 0:0fdadbc3d852 | 64 | #define GPDMA_DMACConfig_M ((0x02)) /*!< AHB Master endianness configuration*/ |
embeddedartists | 0:0fdadbc3d852 | 65 | #define GPDMA_DMACConfig_BITMASK ((0x03)) |
embeddedartists | 0:0fdadbc3d852 | 66 | |
embeddedartists | 0:0fdadbc3d852 | 67 | /** |
embeddedartists | 0:0fdadbc3d852 | 68 | * @brief Macro defines for DMA Channel Configuration registers |
embeddedartists | 0:0fdadbc3d852 | 69 | */ |
embeddedartists | 0:0fdadbc3d852 | 70 | #define GPDMA_DMACCxConfig_E ((1UL << 0)) /*!< DMA control enable*/ |
embeddedartists | 0:0fdadbc3d852 | 71 | #define GPDMA_DMACCxConfig_SrcPeripheral(n) (((n & 0x1F) << 1)) /*!< Source peripheral*/ |
embeddedartists | 0:0fdadbc3d852 | 72 | #define GPDMA_DMACCxConfig_DestPeripheral(n) (((n & 0x1F) << 6)) /*!< Destination peripheral*/ |
embeddedartists | 0:0fdadbc3d852 | 73 | #define GPDMA_DMACCxConfig_TransferType(n) (((n & 0x7) << 11)) /*!< This value indicates the type of transfer*/ |
embeddedartists | 0:0fdadbc3d852 | 74 | #define GPDMA_DMACCxConfig_IE ((1UL << 14)) /*!< Interrupt error mask*/ |
embeddedartists | 0:0fdadbc3d852 | 75 | #define GPDMA_DMACCxConfig_ITC ((1UL << 15)) /*!< Terminal count interrupt mask*/ |
embeddedartists | 0:0fdadbc3d852 | 76 | #define GPDMA_DMACCxConfig_L ((1UL << 16)) /*!< Lock*/ |
embeddedartists | 0:0fdadbc3d852 | 77 | #define GPDMA_DMACCxConfig_A ((1UL << 17)) /*!< Active*/ |
embeddedartists | 0:0fdadbc3d852 | 78 | #define GPDMA_DMACCxConfig_H ((1UL << 18)) /*!< Halt*/ |
embeddedartists | 0:0fdadbc3d852 | 79 | |
embeddedartists | 0:0fdadbc3d852 | 80 | /** |
embeddedartists | 0:0fdadbc3d852 | 81 | * @brief GPDMA structure using for DMA configuration |
embeddedartists | 0:0fdadbc3d852 | 82 | */ |
embeddedartists | 0:0fdadbc3d852 | 83 | typedef struct { |
embeddedartists | 0:0fdadbc3d852 | 84 | uint32_t ChannelNum; /*!< DMA channel number, should be in |
embeddedartists | 0:0fdadbc3d852 | 85 | * range from 0 to 7. |
embeddedartists | 0:0fdadbc3d852 | 86 | * Note: DMA channel 0 has the highest priority |
embeddedartists | 0:0fdadbc3d852 | 87 | * and DMA channel 7 the lowest priority. |
embeddedartists | 0:0fdadbc3d852 | 88 | */ |
embeddedartists | 0:0fdadbc3d852 | 89 | uint32_t TransferSize; /*!< Length/Size of transfer */ |
embeddedartists | 0:0fdadbc3d852 | 90 | uint32_t TransferWidth; /*!< Transfer width - used for TransferType is GPDMA_TRANSFERTYPE_M2M only */ |
embeddedartists | 0:0fdadbc3d852 | 91 | uint32_t SrcAddr; /*!< Physical Source Address, used in case TransferType is chosen as |
embeddedartists | 0:0fdadbc3d852 | 92 | * GPDMA_TRANSFERTYPE_M2M or GPDMA_TRANSFERTYPE_M2P */ |
embeddedartists | 0:0fdadbc3d852 | 93 | uint32_t DstAddr; /*!< Physical Destination Address, used in case TransferType is chosen as |
embeddedartists | 0:0fdadbc3d852 | 94 | * GPDMA_TRANSFERTYPE_M2M or GPDMA_TRANSFERTYPE_P2M */ |
embeddedartists | 0:0fdadbc3d852 | 95 | uint32_t TransferType; /*!< Transfer Type, should be one of the following: |
embeddedartists | 0:0fdadbc3d852 | 96 | * - GPDMA_TRANSFERTYPE_M2M: Memory to memory - DMA control |
embeddedartists | 0:0fdadbc3d852 | 97 | * - GPDMA_TRANSFERTYPE_M2P: Memory to peripheral - DMA control |
embeddedartists | 0:0fdadbc3d852 | 98 | * - GPDMA_TRANSFERTYPE_P2M: Peripheral to memory - DMA control |
embeddedartists | 0:0fdadbc3d852 | 99 | * - GPDMA_TRANSFERTYPE_P2P: Source peripheral to destination peripheral - DMA control |
embeddedartists | 0:0fdadbc3d852 | 100 | */ |
embeddedartists | 0:0fdadbc3d852 | 101 | } GPDMA_Channel_CFG_T; |
embeddedartists | 0:0fdadbc3d852 | 102 | |
embeddedartists | 0:0fdadbc3d852 | 103 | /****************************************************************************** |
embeddedartists | 0:0fdadbc3d852 | 104 | * External global variables |
embeddedartists | 0:0fdadbc3d852 | 105 | *****************************************************************************/ |
embeddedartists | 0:0fdadbc3d852 | 106 | |
embeddedartists | 0:0fdadbc3d852 | 107 | /****************************************************************************** |
embeddedartists | 0:0fdadbc3d852 | 108 | * Local variables |
embeddedartists | 0:0fdadbc3d852 | 109 | *****************************************************************************/ |
embeddedartists | 0:0fdadbc3d852 | 110 | |
embeddedartists | 0:0fdadbc3d852 | 111 | static bool used_channels[NUM_GPDMA_CHANNELS]; |
embeddedartists | 0:0fdadbc3d852 | 112 | |
embeddedartists | 0:0fdadbc3d852 | 113 | /****************************************************************************** |
embeddedartists | 0:0fdadbc3d852 | 114 | * Local Functions |
embeddedartists | 0:0fdadbc3d852 | 115 | *****************************************************************************/ |
embeddedartists | 0:0fdadbc3d852 | 116 | |
embeddedartists | 0:0fdadbc3d852 | 117 | static void gpdma_transfer(GPDMA_Channel_CFG_T* cfg, |
embeddedartists | 0:0fdadbc3d852 | 118 | uint32_t CtrlWord, |
embeddedartists | 0:0fdadbc3d852 | 119 | uint32_t LinkListItem, |
embeddedartists | 0:0fdadbc3d852 | 120 | uint8_t SrcPeripheral, |
embeddedartists | 0:0fdadbc3d852 | 121 | uint8_t DstPeripheral) |
embeddedartists | 0:0fdadbc3d852 | 122 | { |
embeddedartists | 0:0fdadbc3d852 | 123 | /* Get Channel pointer */ |
embeddedartists | 0:0fdadbc3d852 | 124 | LPC_GPDMACH_TypeDef* pCh = GPDMACH(cfg->ChannelNum); |
embeddedartists | 0:0fdadbc3d852 | 125 | |
embeddedartists | 0:0fdadbc3d852 | 126 | /* Reset the Interrupt status */ |
embeddedartists | 0:0fdadbc3d852 | 127 | LPC_GPDMA->IntTCClear = CH_MASK(cfg->ChannelNum); |
embeddedartists | 0:0fdadbc3d852 | 128 | LPC_GPDMA->IntErrClr = CH_MASK(cfg->ChannelNum); |
embeddedartists | 0:0fdadbc3d852 | 129 | |
embeddedartists | 0:0fdadbc3d852 | 130 | /* Assign Linker List Item value */ |
embeddedartists | 0:0fdadbc3d852 | 131 | pCh->CLLI = LinkListItem; |
embeddedartists | 0:0fdadbc3d852 | 132 | |
embeddedartists | 0:0fdadbc3d852 | 133 | /* Enable DMA channels, little endian */ |
embeddedartists | 0:0fdadbc3d852 | 134 | LPC_GPDMA->Config = GPDMA_DMACConfig_E; |
embeddedartists | 0:0fdadbc3d852 | 135 | while (!(LPC_GPDMA->Config & GPDMA_DMACConfig_E)) {} |
embeddedartists | 0:0fdadbc3d852 | 136 | |
embeddedartists | 0:0fdadbc3d852 | 137 | pCh->CSrcAddr = cfg->SrcAddr; |
embeddedartists | 0:0fdadbc3d852 | 138 | pCh->CDestAddr = cfg->DstAddr; |
embeddedartists | 0:0fdadbc3d852 | 139 | |
embeddedartists | 0:0fdadbc3d852 | 140 | /* Configure DMA Channel, enable Error Counter and Terminate counter */ |
embeddedartists | 0:0fdadbc3d852 | 141 | pCh->CConfig = GPDMA_DMACCxConfig_IE |
embeddedartists | 0:0fdadbc3d852 | 142 | | GPDMA_DMACCxConfig_ITC |
embeddedartists | 0:0fdadbc3d852 | 143 | | GPDMA_DMACCxConfig_TransferType((uint32_t) cfg->TransferType) |
embeddedartists | 0:0fdadbc3d852 | 144 | | GPDMA_DMACCxConfig_SrcPeripheral(SrcPeripheral) |
embeddedartists | 0:0fdadbc3d852 | 145 | | GPDMA_DMACCxConfig_DestPeripheral(DstPeripheral); |
embeddedartists | 0:0fdadbc3d852 | 146 | |
embeddedartists | 0:0fdadbc3d852 | 147 | pCh->CControl = CtrlWord; |
embeddedartists | 0:0fdadbc3d852 | 148 | |
embeddedartists | 0:0fdadbc3d852 | 149 | /* Start the Channel */ |
embeddedartists | 0:0fdadbc3d852 | 150 | pCh->CConfig |= GPDMA_DMACCxConfig_E; |
embeddedartists | 0:0fdadbc3d852 | 151 | } |
embeddedartists | 0:0fdadbc3d852 | 152 | |
embeddedartists | 0:0fdadbc3d852 | 153 | /****************************************************************************** |
embeddedartists | 0:0fdadbc3d852 | 154 | * Public Functions |
embeddedartists | 0:0fdadbc3d852 | 155 | *****************************************************************************/ |
embeddedartists | 0:0fdadbc3d852 | 156 | |
embeddedartists | 0:0fdadbc3d852 | 157 | void gpdma_init() |
embeddedartists | 0:0fdadbc3d852 | 158 | { |
embeddedartists | 0:0fdadbc3d852 | 159 | uint8_t i; |
embeddedartists | 0:0fdadbc3d852 | 160 | |
embeddedartists | 0:0fdadbc3d852 | 161 | /* Enable GPDMA master clock */ |
embeddedartists | 0:0fdadbc3d852 | 162 | LPC_SC->PCONP |= (1<<29); |
embeddedartists | 0:0fdadbc3d852 | 163 | |
embeddedartists | 0:0fdadbc3d852 | 164 | /* Reset all channel configuration register */ |
embeddedartists | 0:0fdadbc3d852 | 165 | for (i = 0; i < NUM_GPDMA_CHANNELS; i++) { |
embeddedartists | 0:0fdadbc3d852 | 166 | GPDMACH(i)->CConfig = 0; |
embeddedartists | 0:0fdadbc3d852 | 167 | } |
embeddedartists | 0:0fdadbc3d852 | 168 | |
embeddedartists | 0:0fdadbc3d852 | 169 | /* Clear all DMA interrupt and error flag */ |
embeddedartists | 0:0fdadbc3d852 | 170 | LPC_GPDMA->IntTCClear = 0xFF; |
embeddedartists | 0:0fdadbc3d852 | 171 | LPC_GPDMA->IntErrClr = 0xFF; |
embeddedartists | 0:0fdadbc3d852 | 172 | |
embeddedartists | 0:0fdadbc3d852 | 173 | /* Reset all channels are free */ |
embeddedartists | 0:0fdadbc3d852 | 174 | for (int i = 0; i < NUM_GPDMA_CHANNELS; i++) |
embeddedartists | 0:0fdadbc3d852 | 175 | { |
embeddedartists | 0:0fdadbc3d852 | 176 | used_channels[i] = false; |
embeddedartists | 0:0fdadbc3d852 | 177 | } |
embeddedartists | 0:0fdadbc3d852 | 178 | } |
embeddedartists | 0:0fdadbc3d852 | 179 | |
embeddedartists | 0:0fdadbc3d852 | 180 | void gpdma_deinit() |
embeddedartists | 0:0fdadbc3d852 | 181 | { |
embeddedartists | 0:0fdadbc3d852 | 182 | /* Disable GPDMA master clock */ |
embeddedartists | 0:0fdadbc3d852 | 183 | LPC_SC->PCONP &= ~(1<<29); |
embeddedartists | 0:0fdadbc3d852 | 184 | } |
embeddedartists | 0:0fdadbc3d852 | 185 | |
embeddedartists | 0:0fdadbc3d852 | 186 | void gpdma_stop(uint8_t ChannelNum) |
embeddedartists | 0:0fdadbc3d852 | 187 | { |
embeddedartists | 0:0fdadbc3d852 | 188 | if (ChannelNum >= NUM_GPDMA_CHANNELS) { |
embeddedartists | 0:0fdadbc3d852 | 189 | return; |
embeddedartists | 0:0fdadbc3d852 | 190 | } |
embeddedartists | 0:0fdadbc3d852 | 191 | |
embeddedartists | 0:0fdadbc3d852 | 192 | /* Disable channel */ |
embeddedartists | 0:0fdadbc3d852 | 193 | GPDMACH(ChannelNum)->CConfig &= ~GPDMA_DMACCxConfig_E; |
embeddedartists | 0:0fdadbc3d852 | 194 | |
embeddedartists | 0:0fdadbc3d852 | 195 | /* check terminal count interrupt request status for DMA */ |
embeddedartists | 0:0fdadbc3d852 | 196 | if (LPC_GPDMA->IntTCStat & CH_MASK(ChannelNum)) { |
embeddedartists | 0:0fdadbc3d852 | 197 | /* Clear terminate counter Interrupt pending */ |
embeddedartists | 0:0fdadbc3d852 | 198 | LPC_GPDMA->IntTCClear = CH_MASK(ChannelNum); |
embeddedartists | 0:0fdadbc3d852 | 199 | } |
embeddedartists | 0:0fdadbc3d852 | 200 | |
embeddedartists | 0:0fdadbc3d852 | 201 | /* check status of the error interrupt for DMA channels */ |
embeddedartists | 0:0fdadbc3d852 | 202 | if (LPC_GPDMA->IntErrStat & CH_MASK(ChannelNum)) { |
embeddedartists | 0:0fdadbc3d852 | 203 | /* clear the error interrupt request */ |
embeddedartists | 0:0fdadbc3d852 | 204 | LPC_GPDMA->IntErrClr = CH_MASK(ChannelNum); |
embeddedartists | 0:0fdadbc3d852 | 205 | } |
embeddedartists | 0:0fdadbc3d852 | 206 | |
embeddedartists | 0:0fdadbc3d852 | 207 | used_channels[ChannelNum] = false; |
embeddedartists | 0:0fdadbc3d852 | 208 | } |
embeddedartists | 0:0fdadbc3d852 | 209 | |
embeddedartists | 0:0fdadbc3d852 | 210 | bool gpdma_interrupt(uint8_t ChannelNum) |
embeddedartists | 0:0fdadbc3d852 | 211 | { |
embeddedartists | 0:0fdadbc3d852 | 212 | /* check status of DMA channel interrupts */ |
embeddedartists | 0:0fdadbc3d852 | 213 | if (LPC_GPDMA->IntStat & CH_MASK(ChannelNum)) { |
embeddedartists | 0:0fdadbc3d852 | 214 | /* Check counter terminal status */ |
embeddedartists | 0:0fdadbc3d852 | 215 | if (LPC_GPDMA->IntTCStat & CH_MASK(ChannelNum)) { |
embeddedartists | 0:0fdadbc3d852 | 216 | /* Clear terminate counter Interrupt pending */ |
embeddedartists | 0:0fdadbc3d852 | 217 | LPC_GPDMA->IntTCClear = CH_MASK(ChannelNum); |
embeddedartists | 0:0fdadbc3d852 | 218 | return true; |
embeddedartists | 0:0fdadbc3d852 | 219 | } |
embeddedartists | 0:0fdadbc3d852 | 220 | /* Check error terminal status */ |
embeddedartists | 0:0fdadbc3d852 | 221 | if (LPC_GPDMA->IntErrStat & CH_MASK(ChannelNum)) { |
embeddedartists | 0:0fdadbc3d852 | 222 | /* Clear error counter Interrupt pending */ |
embeddedartists | 0:0fdadbc3d852 | 223 | LPC_GPDMA->IntErrClr = CH_MASK(ChannelNum); |
embeddedartists | 0:0fdadbc3d852 | 224 | return false; |
embeddedartists | 0:0fdadbc3d852 | 225 | } |
embeddedartists | 0:0fdadbc3d852 | 226 | } |
embeddedartists | 0:0fdadbc3d852 | 227 | return false; |
embeddedartists | 0:0fdadbc3d852 | 228 | } |
embeddedartists | 0:0fdadbc3d852 | 229 | |
embeddedartists | 0:0fdadbc3d852 | 230 | bool gpdma_getFreeChannel(uint8_t* pCh) |
embeddedartists | 0:0fdadbc3d852 | 231 | { |
embeddedartists | 0:0fdadbc3d852 | 232 | for (int i = 0; i < NUM_GPDMA_CHANNELS; i++) |
embeddedartists | 0:0fdadbc3d852 | 233 | { |
embeddedartists | 0:0fdadbc3d852 | 234 | if ((!used_channels[i]) && ((LPC_GPDMA->EnbldChns & CH_MASK(i)) == 0)) |
embeddedartists | 0:0fdadbc3d852 | 235 | { |
embeddedartists | 0:0fdadbc3d852 | 236 | used_channels[i] = true; |
embeddedartists | 0:0fdadbc3d852 | 237 | *pCh = i; |
embeddedartists | 0:0fdadbc3d852 | 238 | return true; |
embeddedartists | 0:0fdadbc3d852 | 239 | } |
embeddedartists | 0:0fdadbc3d852 | 240 | } |
embeddedartists | 0:0fdadbc3d852 | 241 | return false; |
embeddedartists | 0:0fdadbc3d852 | 242 | } |
embeddedartists | 0:0fdadbc3d852 | 243 | |
embeddedartists | 0:0fdadbc3d852 | 244 | bool gpdma_transfer_to_mci(uint8_t ChannelNum, |
embeddedartists | 0:0fdadbc3d852 | 245 | uint32_t src, |
embeddedartists | 0:0fdadbc3d852 | 246 | uint32_t Size) |
embeddedartists | 0:0fdadbc3d852 | 247 | { |
embeddedartists | 0:0fdadbc3d852 | 248 | GPDMA_Channel_CFG_T cfg; |
embeddedartists | 0:0fdadbc3d852 | 249 | cfg.ChannelNum = ChannelNum; |
embeddedartists | 0:0fdadbc3d852 | 250 | cfg.TransferType = GPDMA_TRANSFERTYPE_M2P_CONTROLLER_PERIPHERAL; |
embeddedartists | 0:0fdadbc3d852 | 251 | cfg.TransferSize = Size; |
embeddedartists | 0:0fdadbc3d852 | 252 | cfg.TransferWidth = 0; |
embeddedartists | 0:0fdadbc3d852 | 253 | cfg.SrcAddr = src; |
embeddedartists | 0:0fdadbc3d852 | 254 | cfg.DstAddr = (uint32_t) (&LPC_MCI->FIFO); |
embeddedartists | 0:0fdadbc3d852 | 255 | |
embeddedartists | 0:0fdadbc3d852 | 256 | uint32_t ctrl_word = |
embeddedartists | 0:0fdadbc3d852 | 257 | GPDMA_DMACCxControl_TransferSize((uint32_t) cfg.TransferSize) |
embeddedartists | 0:0fdadbc3d852 | 258 | | GPDMA_DMACCxControl_SBSize(GPDMA_BSIZE_8) |
embeddedartists | 0:0fdadbc3d852 | 259 | | GPDMA_DMACCxControl_DBSize(GPDMA_BSIZE_8) |
embeddedartists | 0:0fdadbc3d852 | 260 | | GPDMA_DMACCxControl_SWidth(GPDMA_WIDTH_WORD) |
embeddedartists | 0:0fdadbc3d852 | 261 | | GPDMA_DMACCxControl_DWidth(GPDMA_WIDTH_WORD) |
embeddedartists | 0:0fdadbc3d852 | 262 | | GPDMA_DMACCxControl_DestTransUseAHBMaster1 |
embeddedartists | 0:0fdadbc3d852 | 263 | | GPDMA_DMACCxControl_SI |
embeddedartists | 0:0fdadbc3d852 | 264 | | GPDMA_DMACCxControl_I; |
embeddedartists | 0:0fdadbc3d852 | 265 | |
embeddedartists | 0:0fdadbc3d852 | 266 | if (LPC_GPDMA->EnbldChns & CH_MASK(ChannelNum)) { |
embeddedartists | 0:0fdadbc3d852 | 267 | /* This channel is enabled, return ERROR, need to release this channel first */ |
embeddedartists | 0:0fdadbc3d852 | 268 | return false; |
embeddedartists | 0:0fdadbc3d852 | 269 | } |
embeddedartists | 0:0fdadbc3d852 | 270 | |
embeddedartists | 0:0fdadbc3d852 | 271 | /* Select SD card interface in the DMA MUX*/ |
embeddedartists | 0:0fdadbc3d852 | 272 | LPC_SC->DMAREQSEL &= ~(1 << 1); |
embeddedartists | 0:0fdadbc3d852 | 273 | |
embeddedartists | 0:0fdadbc3d852 | 274 | gpdma_transfer(&cfg, ctrl_word, 0, GPDMA_CONN_MEMORY, GPDMA_CONN_SDC); |
embeddedartists | 0:0fdadbc3d852 | 275 | return true; |
embeddedartists | 0:0fdadbc3d852 | 276 | } |
embeddedartists | 0:0fdadbc3d852 | 277 | |
embeddedartists | 0:0fdadbc3d852 | 278 | bool gpdma_transfer_from_mci(uint8_t ChannelNum, |
embeddedartists | 0:0fdadbc3d852 | 279 | uint32_t dst, |
embeddedartists | 0:0fdadbc3d852 | 280 | uint32_t Size) |
embeddedartists | 0:0fdadbc3d852 | 281 | { |
embeddedartists | 0:0fdadbc3d852 | 282 | GPDMA_Channel_CFG_T cfg; |
embeddedartists | 0:0fdadbc3d852 | 283 | cfg.ChannelNum = ChannelNum; |
embeddedartists | 0:0fdadbc3d852 | 284 | cfg.TransferType = GPDMA_TRANSFERTYPE_P2M_CONTROLLER_PERIPHERAL; |
embeddedartists | 0:0fdadbc3d852 | 285 | cfg.TransferSize = Size; |
embeddedartists | 0:0fdadbc3d852 | 286 | cfg.TransferWidth = 0; |
embeddedartists | 0:0fdadbc3d852 | 287 | cfg.SrcAddr = (uint32_t) (&LPC_MCI->FIFO); |
embeddedartists | 0:0fdadbc3d852 | 288 | cfg.DstAddr = dst; |
embeddedartists | 0:0fdadbc3d852 | 289 | |
embeddedartists | 0:0fdadbc3d852 | 290 | uint32_t ctrl_word = |
embeddedartists | 0:0fdadbc3d852 | 291 | GPDMA_DMACCxControl_TransferSize((uint32_t) cfg.TransferSize) |
embeddedartists | 0:0fdadbc3d852 | 292 | | GPDMA_DMACCxControl_SBSize(GPDMA_BSIZE_8) |
embeddedartists | 0:0fdadbc3d852 | 293 | | GPDMA_DMACCxControl_DBSize(GPDMA_BSIZE_8) |
embeddedartists | 0:0fdadbc3d852 | 294 | | GPDMA_DMACCxControl_SWidth(GPDMA_WIDTH_WORD) |
embeddedartists | 0:0fdadbc3d852 | 295 | | GPDMA_DMACCxControl_DWidth(GPDMA_WIDTH_WORD) |
embeddedartists | 0:0fdadbc3d852 | 296 | | GPDMA_DMACCxControl_SrcTransUseAHBMaster1 |
embeddedartists | 0:0fdadbc3d852 | 297 | | GPDMA_DMACCxControl_DI |
embeddedartists | 0:0fdadbc3d852 | 298 | | GPDMA_DMACCxControl_I; |
embeddedartists | 0:0fdadbc3d852 | 299 | |
embeddedartists | 0:0fdadbc3d852 | 300 | if (LPC_GPDMA->EnbldChns & CH_MASK(ChannelNum)) { |
embeddedartists | 0:0fdadbc3d852 | 301 | /* This channel is enabled, return ERROR, need to release this channel first */ |
embeddedartists | 0:0fdadbc3d852 | 302 | return false; |
embeddedartists | 0:0fdadbc3d852 | 303 | } |
embeddedartists | 0:0fdadbc3d852 | 304 | |
embeddedartists | 0:0fdadbc3d852 | 305 | /* Select SD card interface in the DMA MUX*/ |
embeddedartists | 0:0fdadbc3d852 | 306 | LPC_SC->DMAREQSEL &= ~(1 << 1); |
embeddedartists | 0:0fdadbc3d852 | 307 | |
embeddedartists | 0:0fdadbc3d852 | 308 | gpdma_transfer(&cfg, ctrl_word, 0, GPDMA_CONN_SDC, GPDMA_CONN_MEMORY); |
embeddedartists | 0:0fdadbc3d852 | 309 | return true; |
embeddedartists | 0:0fdadbc3d852 | 310 | } |
embeddedartists | 0:0fdadbc3d852 | 311 | |
embeddedartists | 0:0fdadbc3d852 | 312 |