Library to access LPC17xx peripherals. It uses static inline functions, constant propagation and dead code elimination to be as fast as possible.
Dependents: Chua-VGA Wolfram-1D-VGA WolframRnd-1D-VGA Basin-VGA ... more
dma.h
00001 /* Copyright (C) 2010, 2011 by Ivo van Poorten <ivop@euronet.nl> 00002 * This file is licensed under the terms of the GNU Lesser 00003 * General Public License, version 3. 00004 */ 00005 00006 #ifndef FASTLIB_DMA_H 00007 #define FASTLIB_DMA_H 00008 00009 #include "fastlib/common.h" 00010 00011 #define FL_DMACIntStat ((volatile uint32_t *) 0x50004000) 00012 #define FL_DMACIntTCStat ((volatile uint32_t *) 0x50004004) 00013 #define FL_DMACIntTCClear ((volatile uint32_t *) 0x50004008) 00014 #define FL_DMACIntErrStat ((volatile uint32_t *) 0x5000400C) 00015 #define FL_DMACIntErrClr ((volatile uint32_t *) 0x50004010) 00016 #define FL_DMACRawIntTCStat ((volatile uint32_t *) 0x50004014) 00017 #define FL_DMACRawIntErrStat ((volatile uint32_t *) 0x50004018) 00018 #define FL_DMACEnbldChns ((volatile uint32_t *) 0x5000401C) 00019 #define FL_DMACSoftBReq ((volatile uint32_t *) 0x50004020) 00020 #define FL_DMACSoftSReq ((volatile uint32_t *) 0x50004024) 00021 #define FL_DMACSoftLBReq ((volatile uint32_t *) 0x50004028) 00022 #define FL_DMACSoftLSReq ((volatile uint32_t *) 0x5000402C) 00023 #define FL_DMACConfig ((volatile uint32_t *) 0x50004030) 00024 #define FL_DMACSync ((volatile uint32_t *) 0x50004034) 00025 #define FL_DMAReqSel ((volatile uint32_t *) 0x400FC1C4) 00026 00027 #define FL_DMACC0 0x50004100 00028 #define FL_DMACC1 0x50004120 00029 #define FL_DMACC2 0x50004140 00030 #define FL_DMACC3 0x50004160 00031 #define FL_DMACC4 0x50004180 00032 #define FL_DMACC5 0x500041A0 00033 #define FL_DMACC6 0x500041C0 00034 #define FL_DMACC7 0x500041E0 00035 00036 #define FL_DMA_SrcAddr 0x00 00037 #define FL_DMA_DestAddr 0x04 00038 #define FL_DMA_LLI 0x08 00039 #define FL_DMA_Control 0x0C 00040 #define FL_DMA_Config 0x10 00041 00042 #define FL_DMA(channel, field) \ 00043 ((volatile uint32_t *)(fl_dma_channel_to_base(channel) + FL_DMA_##field)) 00044 00045 static inline unsigned fl_dma_channel_to_base(const unsigned channel) { 00046 switch(channel) { 00047 case 0: return FL_DMACC0; 00048 case 1: return FL_DMACC1; 00049 case 2: return FL_DMACC2; 00050 case 3: return FL_DMACC3; 00051 case 4: return FL_DMACC4; 00052 case 5: return FL_DMACC5; 00053 case 6: return FL_DMACC6; 00054 default: return FL_DMACC7; 00055 } 00056 } 00057 00058 // channel: 0-7 00059 static inline unsigned fl_dma_channel_has_active_interrupt_request(const unsigned channel) { 00060 return *FL_DMACIntStat & (1U<<channel); 00061 } 00062 00063 static inline unsigned fl_dma_channel_has_active_terminal_count_interrupt_request(const unsigned channel) { 00064 return *FL_DMACIntTCStat & (1U<<channel); 00065 } 00066 static inline void fl_dma_clear_terminal_count_interrupt_request(const unsigned channel) { 00067 *FL_DMACIntTCClear |= 1U<<channel; 00068 } 00069 static inline unsigned fl_dma_channel_has_active_terminal_count_interrupt_request_raw(const unsigned channel) { 00070 return *FL_DMACRawIntTCStat & (1U<<channel); // raw is prior to masking 00071 } 00072 00073 static inline unsigned fl_dma_channel_has_active_error_interrupt_request(const unsigned channel) { 00074 return *FL_DMACIntErrStat & (1U<<channel); 00075 } 00076 static inline void fl_dma_clear_error_interrupt_request(const unsigned channel) { 00077 *FL_DMACIntErrClr |= 1U<<channel; 00078 } 00079 static inline unsigned fl_dma_channel_has_active_error_interrupt_request_raw(const unsigned channel) { 00080 return *FL_DMACRawIntErrStat & (1U<<channel); 00081 } 00082 00083 static inline unsigned fl_dma_channel_is_enabled(const unsigned channel) { 00084 return *FL_DMACEnbldChns & (1U<<channel); 00085 } 00086 00087 static inline void fl_dma_generate_software_burst_request(const unsigned request) { 00088 *FL_DMACSoftBReq |= 1U << request; 00089 } 00090 static inline unsigned fl_dma_software_burst_request_sources(void) { 00091 return *FL_DMACSoftBReq; 00092 } 00093 00094 static inline void fl_dma_generate_software_single_request(const unsigned request) { 00095 *FL_DMACSoftSReq |= 1U << request; 00096 } 00097 static inline unsigned fl_dma_software_single_request_sources(void) { 00098 return *FL_DMACSoftSReq; 00099 } 00100 00101 static inline void fl_dma_generate_software_last_burst_request(const unsigned request) { 00102 *FL_DMACSoftLBReq |= 1U << request; 00103 } 00104 static inline unsigned fl_dma_software_last_burst_request_sources(void) { 00105 return *FL_DMACSoftLBReq; 00106 } 00107 00108 static inline void fl_dma_generate_software_last_single_request(const unsigned request) { 00109 *FL_DMACSoftLSReq |= 1U << request; 00110 } 00111 static inline unsigned fl_dma_software_last_single_request_sources(void) { 00112 return *FL_DMACSoftLSReq; 00113 } 00114 00115 static inline void fl_dma_enable(const unsigned state) { 00116 if (state) *FL_DMACConfig |= 1U<<0 ; 00117 else *FL_DMACConfig &= ~(1U<<0); 00118 } 00119 00120 static inline unsigned fl_dma_is_enabled(void) { 00121 return *FL_DMACConfig & 1; 00122 } 00123 00124 static inline void fl_dma_set_endianness(const unsigned endianness) { 00125 if (endianness) *FL_DMACConfig |= 1U<<1 ; 00126 else *FL_DMACConfig &= ~(1U<<1); 00127 } 00128 00129 static inline void fl_dma_request_synchronization_enable(const unsigned request, const unsigned state) { 00130 if (!state) *FL_DMACSync |= 1U<<request ; // note that 0 is enabled 00131 else *FL_DMACSync &= ~(1U<<request); 00132 } 00133 00134 #define FL_DMA_UART 0 00135 #define FL_DMA_TIMER 1 00136 00137 // select between uart or timer dma requests for inputs 8 through 15 00138 // input: 8-16 which: 0-1 00139 static inline void fl_dma_request_select(const unsigned input, const unsigned which) { 00140 if (which) *FL_DMAReqSel |= 1U<<(which-8) ; 00141 else *FL_DMAReqSel &= ~(1U<<(which-8)); 00142 } 00143 00144 // channel: 0-7 00145 static inline void fl_dma_set_srcaddr(const unsigned channel, const void *srcaddr) { 00146 *FL_DMA(channel, SrcAddr) = (unsigned) srcaddr; 00147 } 00148 00149 static inline void fl_dma_set_destaddr(const unsigned channel, const void *destaddr) { 00150 *FL_DMA(channel, DestAddr) = (unsigned) destaddr; 00151 } 00152 00153 // lli must be word-aligned 00154 static inline void fl_dma_set_next_lli(const unsigned channel, const void *lli) { 00155 *FL_DMA(channel, LLI) = (unsigned) lli & (~3U); 00156 } 00157 00158 #define FL_NO_SRC_INCREMENT 0 00159 #define FL_SRC_INCREMENT 1 00160 #define FL_NO_DEST_INCREMENT 0 00161 #define FL_DEST_INCREMENT 1 00162 00163 static inline unsigned fl_dma_size_to_mask(const unsigned size) { 00164 switch(size) { 00165 case 4: return 1; 00166 case 8: return 2; 00167 case 16: return 3; 00168 case 32: return 4; 00169 case 64: return 5; 00170 case 128: return 6; 00171 case 256: return 7; 00172 default: return 0; 00173 } 00174 } 00175 00176 static inline unsigned fl_dma_width_to_mask(const unsigned width) { 00177 switch(width) { 00178 case 16: return 1; 00179 case 32: return 2; 00180 default: return 0; 00181 } 00182 } 00183 00184 // transfer_size: 12 bits 00185 // size: 1, 4, 8, 16, 32, 64, 128 or 256 00186 // width: 8, 16 or 32 00187 // irq: 0-1 00188 static inline void fl_dma_channel_control(const unsigned channel, const unsigned transfer_size, 00189 const unsigned src_burst_size, const unsigned dest_burst_size, 00190 const unsigned src_width, const unsigned dest_width, 00191 const unsigned src_increment, const unsigned dest_increment, 00192 const unsigned terminal_count_irq) { 00193 *FL_DMA(channel, Control) = transfer_size & 0xfff 00194 | (fl_dma_size_to_mask(src_burst_size) << 12) 00195 | (fl_dma_size_to_mask(dest_burst_size) << 15) 00196 | (fl_dma_width_to_mask(src_width) << 18) 00197 | (fl_dma_width_to_mask(dest_width) << 21) 00198 | (src_increment << 26) 00199 | (dest_increment << 27) 00200 | (terminal_count_irq << 31); 00201 } 00202 00203 static inline void fl_dma_channel_control_by_mask(const unsigned channel, const unsigned mask) { 00204 *FL_DMA(channel, Control) = mask; 00205 } 00206 00207 static inline unsigned fl_dma_channel_get_control_mask(const unsigned channel) { 00208 return *FL_DMA(channel, Control); 00209 } 00210 00211 static inline void fl_dma_channel_terminal_count_irq_enable(const unsigned channel, const unsigned state) { 00212 if (state) *FL_DMA(channel, Control) |= 1U<<31 ; 00213 else *FL_DMA(channel, Control) &= ~(1U<<31); 00214 } 00215 00216 // channel configuration constants, src and dest peripherals 00217 #define FL_DMA_SINGLE_REQUEST_SSP0_Tx 0 00218 #define FL_DMA_SINGLE_REQUEST_SSP0_Rx 1 00219 #define FL_DMA_SINGLE_REQUEST_SSP1_Tx 2 00220 #define FL_DMA_SINGLE_REQUEST_SSP1_Rx 3 00221 #define FL_DMA_SINGLE_REQUEST_ADC 4 00222 00223 #define FL_DMA_BURST_REQUEST_SSP0_Tx 0 00224 #define FL_DMA_BURST_REQUEST_SSP0_Rx 1 00225 #define FL_DMA_BURST_REQUEST_SSP1_Tx 2 00226 #define FL_DMA_BURST_REQUEST_SSP1_Rx 3 00227 #define FL_DMA_BURST_REQUEST_ADC 4 00228 #define FL_DMA_BURST_REQUEST_I2S_CH0 5 00229 #define FL_DMA_BURST_REQUEST_I2S_CH1 6 00230 #define FL_DMA_BURST_REQUEST_DAC 7 00231 #define FL_DMA_BURST_REQUEST_UART0_Tx 8 00232 #define FL_DMA_BURST_REQUEST_UART0_Rx 9 00233 #define FL_DMA_BURST_REQUEST_UART1_Tx 10 00234 #define FL_DMA_BURST_REQUEST_uART1_Rx 11 00235 #define FL_DMA_BURST_REQUEST_UART2_Tx 12 00236 #define FL_DMA_BURST_REQUEST_UART2_Rx 13 00237 #define FL_DMA_BURST_REQUEST_UART3_Tx 14 00238 #define FL_DMA_BURST_REQUEST_UART3_Rx 15 00239 00240 #define FL_DMA_PERIPHERAL_IS_MEMORY 0 00241 00242 // transfer types 00243 #define FL_DMA_MEMORY_TO_MEMORY 0 00244 #define FL_DMA_MEMORY_TO_PERIPHERAL 1 00245 #define FL_DMA_PERIPHERAL_TO_MEMORY 2 00246 #define FL_DMA_PERIPHERAL_TO_PERIPHERAL 3 00247 00248 static inline void fl_dma_channel_config(const unsigned channel, 00249 const unsigned enable, const unsigned src_peripheral, const unsigned dest_peripheral, 00250 const unsigned transfer_type, const unsigned mask_error, const unsigned mask_tc) { 00251 *FL_DMA(channel, Config) = enable | (src_peripheral<<1) | (dest_peripheral<<6) | 00252 (transfer_type<<11) | (mask_error<<14) | (mask_tc<<15); 00253 } 00254 00255 // return 0 or !0 (channel fifo has data) 00256 static inline unsigned fl_dma_channel_is_active(const unsigned channel) { 00257 return *FL_DMA(channel, Config) & (1U<<17); 00258 } 00259 00260 static inline void fl_dma_channel_halt(const unsigned channel, const unsigned state) { 00261 if (state) *FL_DMA(channel, Config) |= 1U<<18 ; 00262 else *FL_DMA(channel, Config) &= ~(1U<<18); 00263 } 00264 00265 #endif
Generated on Thu Jul 14 2022 22:04:23 by 1.7.2