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
- Committer:
- Ivop
- Date:
- 2011-07-03
- Revision:
- 0:7a91348b4a02
File content as of revision 0:7a91348b4a02:
/* Copyright (C) 2010, 2011 by Ivo van Poorten <ivop@euronet.nl> * This file is licensed under the terms of the GNU Lesser * General Public License, version 3. */ #ifndef FASTLIB_DMA_H #define FASTLIB_DMA_H #include "fastlib/common.h" #define FL_DMACIntStat ((volatile uint32_t *) 0x50004000) #define FL_DMACIntTCStat ((volatile uint32_t *) 0x50004004) #define FL_DMACIntTCClear ((volatile uint32_t *) 0x50004008) #define FL_DMACIntErrStat ((volatile uint32_t *) 0x5000400C) #define FL_DMACIntErrClr ((volatile uint32_t *) 0x50004010) #define FL_DMACRawIntTCStat ((volatile uint32_t *) 0x50004014) #define FL_DMACRawIntErrStat ((volatile uint32_t *) 0x50004018) #define FL_DMACEnbldChns ((volatile uint32_t *) 0x5000401C) #define FL_DMACSoftBReq ((volatile uint32_t *) 0x50004020) #define FL_DMACSoftSReq ((volatile uint32_t *) 0x50004024) #define FL_DMACSoftLBReq ((volatile uint32_t *) 0x50004028) #define FL_DMACSoftLSReq ((volatile uint32_t *) 0x5000402C) #define FL_DMACConfig ((volatile uint32_t *) 0x50004030) #define FL_DMACSync ((volatile uint32_t *) 0x50004034) #define FL_DMAReqSel ((volatile uint32_t *) 0x400FC1C4) #define FL_DMACC0 0x50004100 #define FL_DMACC1 0x50004120 #define FL_DMACC2 0x50004140 #define FL_DMACC3 0x50004160 #define FL_DMACC4 0x50004180 #define FL_DMACC5 0x500041A0 #define FL_DMACC6 0x500041C0 #define FL_DMACC7 0x500041E0 #define FL_DMA_SrcAddr 0x00 #define FL_DMA_DestAddr 0x04 #define FL_DMA_LLI 0x08 #define FL_DMA_Control 0x0C #define FL_DMA_Config 0x10 #define FL_DMA(channel, field) \ ((volatile uint32_t *)(fl_dma_channel_to_base(channel) + FL_DMA_##field)) static inline unsigned fl_dma_channel_to_base(const unsigned channel) { switch(channel) { case 0: return FL_DMACC0; case 1: return FL_DMACC1; case 2: return FL_DMACC2; case 3: return FL_DMACC3; case 4: return FL_DMACC4; case 5: return FL_DMACC5; case 6: return FL_DMACC6; default: return FL_DMACC7; } } // channel: 0-7 static inline unsigned fl_dma_channel_has_active_interrupt_request(const unsigned channel) { return *FL_DMACIntStat & (1U<<channel); } static inline unsigned fl_dma_channel_has_active_terminal_count_interrupt_request(const unsigned channel) { return *FL_DMACIntTCStat & (1U<<channel); } static inline void fl_dma_clear_terminal_count_interrupt_request(const unsigned channel) { *FL_DMACIntTCClear |= 1U<<channel; } static inline unsigned fl_dma_channel_has_active_terminal_count_interrupt_request_raw(const unsigned channel) { return *FL_DMACRawIntTCStat & (1U<<channel); // raw is prior to masking } static inline unsigned fl_dma_channel_has_active_error_interrupt_request(const unsigned channel) { return *FL_DMACIntErrStat & (1U<<channel); } static inline void fl_dma_clear_error_interrupt_request(const unsigned channel) { *FL_DMACIntErrClr |= 1U<<channel; } static inline unsigned fl_dma_channel_has_active_error_interrupt_request_raw(const unsigned channel) { return *FL_DMACRawIntErrStat & (1U<<channel); } static inline unsigned fl_dma_channel_is_enabled(const unsigned channel) { return *FL_DMACEnbldChns & (1U<<channel); } static inline void fl_dma_generate_software_burst_request(const unsigned request) { *FL_DMACSoftBReq |= 1U << request; } static inline unsigned fl_dma_software_burst_request_sources(void) { return *FL_DMACSoftBReq; } static inline void fl_dma_generate_software_single_request(const unsigned request) { *FL_DMACSoftSReq |= 1U << request; } static inline unsigned fl_dma_software_single_request_sources(void) { return *FL_DMACSoftSReq; } static inline void fl_dma_generate_software_last_burst_request(const unsigned request) { *FL_DMACSoftLBReq |= 1U << request; } static inline unsigned fl_dma_software_last_burst_request_sources(void) { return *FL_DMACSoftLBReq; } static inline void fl_dma_generate_software_last_single_request(const unsigned request) { *FL_DMACSoftLSReq |= 1U << request; } static inline unsigned fl_dma_software_last_single_request_sources(void) { return *FL_DMACSoftLSReq; } static inline void fl_dma_enable(const unsigned state) { if (state) *FL_DMACConfig |= 1U<<0 ; else *FL_DMACConfig &= ~(1U<<0); } static inline unsigned fl_dma_is_enabled(void) { return *FL_DMACConfig & 1; } static inline void fl_dma_set_endianness(const unsigned endianness) { if (endianness) *FL_DMACConfig |= 1U<<1 ; else *FL_DMACConfig &= ~(1U<<1); } static inline void fl_dma_request_synchronization_enable(const unsigned request, const unsigned state) { if (!state) *FL_DMACSync |= 1U<<request ; // note that 0 is enabled else *FL_DMACSync &= ~(1U<<request); } #define FL_DMA_UART 0 #define FL_DMA_TIMER 1 // select between uart or timer dma requests for inputs 8 through 15 // input: 8-16 which: 0-1 static inline void fl_dma_request_select(const unsigned input, const unsigned which) { if (which) *FL_DMAReqSel |= 1U<<(which-8) ; else *FL_DMAReqSel &= ~(1U<<(which-8)); } // channel: 0-7 static inline void fl_dma_set_srcaddr(const unsigned channel, const void *srcaddr) { *FL_DMA(channel, SrcAddr) = (unsigned) srcaddr; } static inline void fl_dma_set_destaddr(const unsigned channel, const void *destaddr) { *FL_DMA(channel, DestAddr) = (unsigned) destaddr; } // lli must be word-aligned static inline void fl_dma_set_next_lli(const unsigned channel, const void *lli) { *FL_DMA(channel, LLI) = (unsigned) lli & (~3U); } #define FL_NO_SRC_INCREMENT 0 #define FL_SRC_INCREMENT 1 #define FL_NO_DEST_INCREMENT 0 #define FL_DEST_INCREMENT 1 static inline unsigned fl_dma_size_to_mask(const unsigned size) { switch(size) { case 4: return 1; case 8: return 2; case 16: return 3; case 32: return 4; case 64: return 5; case 128: return 6; case 256: return 7; default: return 0; } } static inline unsigned fl_dma_width_to_mask(const unsigned width) { switch(width) { case 16: return 1; case 32: return 2; default: return 0; } } // transfer_size: 12 bits // size: 1, 4, 8, 16, 32, 64, 128 or 256 // width: 8, 16 or 32 // irq: 0-1 static inline void fl_dma_channel_control(const unsigned channel, const unsigned transfer_size, const unsigned src_burst_size, const unsigned dest_burst_size, const unsigned src_width, const unsigned dest_width, const unsigned src_increment, const unsigned dest_increment, const unsigned terminal_count_irq) { *FL_DMA(channel, Control) = transfer_size & 0xfff | (fl_dma_size_to_mask(src_burst_size) << 12) | (fl_dma_size_to_mask(dest_burst_size) << 15) | (fl_dma_width_to_mask(src_width) << 18) | (fl_dma_width_to_mask(dest_width) << 21) | (src_increment << 26) | (dest_increment << 27) | (terminal_count_irq << 31); } static inline void fl_dma_channel_control_by_mask(const unsigned channel, const unsigned mask) { *FL_DMA(channel, Control) = mask; } static inline unsigned fl_dma_channel_get_control_mask(const unsigned channel) { return *FL_DMA(channel, Control); } static inline void fl_dma_channel_terminal_count_irq_enable(const unsigned channel, const unsigned state) { if (state) *FL_DMA(channel, Control) |= 1U<<31 ; else *FL_DMA(channel, Control) &= ~(1U<<31); } // channel configuration constants, src and dest peripherals #define FL_DMA_SINGLE_REQUEST_SSP0_Tx 0 #define FL_DMA_SINGLE_REQUEST_SSP0_Rx 1 #define FL_DMA_SINGLE_REQUEST_SSP1_Tx 2 #define FL_DMA_SINGLE_REQUEST_SSP1_Rx 3 #define FL_DMA_SINGLE_REQUEST_ADC 4 #define FL_DMA_BURST_REQUEST_SSP0_Tx 0 #define FL_DMA_BURST_REQUEST_SSP0_Rx 1 #define FL_DMA_BURST_REQUEST_SSP1_Tx 2 #define FL_DMA_BURST_REQUEST_SSP1_Rx 3 #define FL_DMA_BURST_REQUEST_ADC 4 #define FL_DMA_BURST_REQUEST_I2S_CH0 5 #define FL_DMA_BURST_REQUEST_I2S_CH1 6 #define FL_DMA_BURST_REQUEST_DAC 7 #define FL_DMA_BURST_REQUEST_UART0_Tx 8 #define FL_DMA_BURST_REQUEST_UART0_Rx 9 #define FL_DMA_BURST_REQUEST_UART1_Tx 10 #define FL_DMA_BURST_REQUEST_uART1_Rx 11 #define FL_DMA_BURST_REQUEST_UART2_Tx 12 #define FL_DMA_BURST_REQUEST_UART2_Rx 13 #define FL_DMA_BURST_REQUEST_UART3_Tx 14 #define FL_DMA_BURST_REQUEST_UART3_Rx 15 #define FL_DMA_PERIPHERAL_IS_MEMORY 0 // transfer types #define FL_DMA_MEMORY_TO_MEMORY 0 #define FL_DMA_MEMORY_TO_PERIPHERAL 1 #define FL_DMA_PERIPHERAL_TO_MEMORY 2 #define FL_DMA_PERIPHERAL_TO_PERIPHERAL 3 static inline void fl_dma_channel_config(const unsigned channel, const unsigned enable, const unsigned src_peripheral, const unsigned dest_peripheral, const unsigned transfer_type, const unsigned mask_error, const unsigned mask_tc) { *FL_DMA(channel, Config) = enable | (src_peripheral<<1) | (dest_peripheral<<6) | (transfer_type<<11) | (mask_error<<14) | (mask_tc<<15); } // return 0 or !0 (channel fifo has data) static inline unsigned fl_dma_channel_is_active(const unsigned channel) { return *FL_DMA(channel, Config) & (1U<<17); } static inline void fl_dma_channel_halt(const unsigned channel, const unsigned state) { if (state) *FL_DMA(channel, Config) |= 1U<<18 ; else *FL_DMA(channel, Config) &= ~(1U<<18); } #endif