1 /* 2 * Copyright (C) 2017-2019 Alibaba Group Holding Limited 3 */ 4 5 /****************************************************************************** 6 * @file drv_dmac.h 7 * @brief header file for dmac driver 8 * @version V1.0 9 * @date 02. June 2017 10 * @model dmac 11 ******************************************************************************/ 12 #ifndef _CSI_DMA_H_ 13 #define _CSI_DMA_H_ 14 15 #include <stdint.h> 16 #include <drv_common.h> 17 18 #ifdef __cplusplus 19 extern "C" { 20 #endif 21 /** 22 \brief DMA Driver Capabilities. 23 */ 24 typedef struct { 25 uint32_t unalign_addr : 1; ///< support for unalign address transfer when memory is source 26 } dma_capabilities_t; 27 28 typedef enum { 29 DMA_STATE_FREE = 0, ///< DMA channel not yet initialized or disabled 30 DMA_STATE_READY, ///< DMA channel process success and ready for use, but not start yet 31 DMA_STATE_BUSY, ///< DMA channel process is ongoing 32 DMA_STATE_DONE, ///< DMA channel transfer done 33 DMA_STATE_ERROR, ///< DMA channel transfer error 34 } dma_status_e; 35 36 /****** DMA specific error codes *****/ 37 typedef enum { 38 EDRV_DMA_MODE = (DRV_ERROR_SPECIFIC + 1), ///< Specified Mode not supported 39 } dma_error_e; 40 41 /****** DMA Event *****/ 42 typedef enum { 43 DMA_EVENT_TRANSFER_DONE = 0, ///< transfer complete 44 DMA_EVENT_TRANSFER_HALF_DONE = 1, ///< transfer half done 45 DMA_EVENT_TRANSFER_MODE_DONE = 2, ///< transfer complete in a certain dma trigger mode. 46 DMA_EVENT_CAHNNEL_PEND = 3, ///< it happens when there is a low priority channel was preempted by a high priority channel 47 DMA_EVENT_TRANSFER_ERROR = 4, ///< transfer error 48 } dma_event_e; 49 50 typedef enum { 51 DMA_ADDR_INC = 0, 52 DMA_ADDR_DEC, 53 DMA_ADDR_CONSTANT 54 } dma_addr_inc_e; 55 56 typedef enum { 57 DMA_MEM2MEM = 0, 58 DMA_MEM2PERH, 59 DMA_PERH2MEM, 60 DMA_PERH2PERH, 61 } dma_trans_type_e; 62 63 typedef enum { 64 DMA_SINGLE_TRIGGER = 0, 65 DMA_GROUP_TRIGGER, 66 DMA_BLOCK_TRIGGER 67 } dma_trig_trans_mode_e; 68 69 typedef enum { 70 DMA_DIR_DEST = 0, 71 DMA_DIR_SOURCE 72 } dma_single_dir_e; 73 74 typedef enum { 75 DMA_ADDR_LITTLE = 0, 76 DMA_ADDR_BIG 77 } dma_addr_endian_e; 78 79 typedef enum { 80 DMA_MODE_HARDWARE = 0, 81 DMA_MODE_SOFTWARE 82 } dma_channel_req_mode_e; 83 84 typedef struct { 85 dma_addr_inc_e src_inc; ///< source address increment 86 dma_addr_inc_e dst_inc; ///< destination address increment 87 dma_addr_endian_e src_endian; ///< source read data little-big endian change control. 88 dma_addr_endian_e dst_endian; ///< destination write data little-big endian change control. 89 uint8_t src_tw; ///< source transfer width in byte 90 uint8_t dst_tw; ///< destination transfer width in byte 91 uint8_t hs_if; ///< a hardware handshaking interface (optional). 92 uint8_t preemption; ///< determine whether if a channel can be preempted by a higher priority channel, 0 -- not allow preempt, 1 -- allow preempt. 93 dma_trans_type_e type; ///< transfer type 94 dma_trig_trans_mode_e mode; ///< channel trigger mode 95 dma_channel_req_mode_e ch_mode; ///< software or hardware to tigger dma channel work. 96 dma_single_dir_e single_dir; ///< after select single mode control for source(read) or destination(write) transfer. 97 uint32_t group_len; ///< group transaction length (unit: bytes) when use DMA_GROUP_TRIGGER mode. 98 uint32_t src_reload_en; ///< 1:dma enable src addr auto reload, 0:disable 99 uint32_t dest_reload_en; ///< 1:dma enable dst addr auto reload, 0:disable 100 } dma_config_t; 101 102 typedef void (*dma_event_cb_t)(int32_t ch, dma_event_e event, void *arg); ///< Pointer to \ref dma_event_cb_t : dmac event call back. 103 104 /** 105 \brief get one free dma channel 106 \param[in] ch channel num. if -1 then allocate a free channal in this dma 107 else allocate a fix channal 108 \return dma channel num. if -1 alloc channle error 109 */ 110 int32_t csi_dma_alloc_channel_ex(int32_t ch); 111 112 /** 113 \brief get one free dma channel 114 \return dma channel num. if -1 alloc channle error 115 */ 116 int32_t csi_dma_alloc_channel(void); 117 118 /** 119 \brief control dma power. 120 \param[in] ch dma channel num 121 \param[in] state power state.\ref csi_power_stat_e. 122 \return error code 123 */ 124 int32_t csi_dma_power_control(int32_t ch, csi_power_stat_e state); 125 126 /** 127 \brief Get driver capabilities. 128 \param[in] ch dma channel num 129 \return \ref dma_capabilities_t 130 */ 131 dma_capabilities_t csi_dma_get_capabilities(int32_t ch); 132 133 /** 134 \brief release dma channel and related resources 135 \param[in] ch dma channel num 136 \return error code 137 */ 138 void csi_dma_release_channel(int32_t ch); 139 140 /** 141 \brief config dma channel 142 \param[in] ch dma channel num 143 \param[in] config dma channel transfer configure 144 \param[in] cb_event Pointer to \ref dma_event_cb_t 145 \return error code 146 */ 147 int32_t csi_dma_config_channel(int32_t ch, dma_config_t *config, dma_event_cb_t cb_event, void *cb_arg); 148 149 /** 150 \brief start generate dma channel signal. 151 \param[in] ch dma channel num 152 \param[in] psrcaddr dma transfer source address 153 \param[in] pdstaddr dma transfer destination address 154 \param[in] length dma transfer length (unit: bytes). 155 */ 156 void csi_dma_start(int32_t ch, void *psrcaddr, void *pdstaddr, uint32_t length); 157 158 /** 159 \brief Stop generate dma channel signal. 160 \param[in] ch dma channel num 161 */ 162 void csi_dma_stop(int32_t ch); 163 164 /** 165 \brief start generate dma channel cyclic transfer. 166 \param[in] ch dma channel num 167 \param[in] psrcaddr dma transfer source address 168 \param[in] pdstaddr dma transfer destination address 169 \param[in] cycle_len The length of a cycle 170 \param[in] cycle_num the number of a cycle 171 \return error code 172 */ 173 int32_t csi_dma_cyclic_prep(int32_t ch, void *psrcaddr, void *pdstaddr, uint32_t cycle_len, uint32_t cycle_num); 174 /** 175 \brief start generate dma channel cyclic transfer. 176 \param[in] ch dma channel num 177 */ 178 179 void csi_dma_cyclic_start(int32_t ch); 180 181 /** 182 \brief Stop generate dma channel cyclic transfer. 183 \param[in] ch dma channel num 184 */ 185 void csi_dma_cyclic_stop(int32_t ch); 186 187 /** 188 \brief Get DMA channel status. 189 \param[in] ch dma channel num 190 \return DMA status \ref dma_status_e 191 */ 192 dma_status_e csi_dma_get_status(int32_t ch); 193 194 #ifdef __cplusplus 195 } 196 #endif 197 198 #endif /* _CSI_DMA_H_ */ 199 200