/* * Copyright (C) 2017-2020 Alibaba Group Holding Limited */ /****************************************************************************** * @file dma.h * @brief header file for dma driver * @version V1.0 * @date 08. Apr 2020 * @model dma ******************************************************************************/ #ifndef _DRV_DMA_H_ #define _DRV_DMA_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif /****** DMA Event *****/ typedef enum { DMA_EVENT_TRANSFER_DONE = 0, ///< transfer complete DMA_EVENT_TRANSFER_HALF_DONE, ///< transfer half done DMA_EVENT_TRANSFER_ERROR, ///< transfer error } csi_dma_event_t; typedef enum { DMA_ADDR_INC = 0, DMA_ADDR_DEC, DMA_ADDR_CONSTANT } csi_dma_addr_inc_t; typedef enum { DMA_DATA_WIDTH_8_BITS = 0, DMA_DATA_WIDTH_16_BITS, DMA_DATA_WIDTH_32_BITS, DMA_DATA_WIDTH_64_BITS, DMA_DATA_WIDTH_128_BITS, DMA_DATA_WIDTH_512_BITS } csi_dma_data_width_t; typedef enum { DMA_MEM2MEM = 0, DMA_MEM2PERH, DMA_PERH2MEM, } csi_dma_trans_dir_t; typedef struct { int8_t ctrl_idx; int8_t ch_idx; } csi_dma_ch_desc_t; typedef struct { uint16_t dev_tag; int8_t ctrl_idx; const csi_dma_ch_desc_t *ch_list; } csi_dma_ch_spt_list_t; typedef struct { csi_dma_addr_inc_t src_inc; ///< source address increment csi_dma_addr_inc_t dst_inc; ///< destination address increment csi_dma_data_width_t src_tw; ///< source transfer width in byte csi_dma_data_width_t dst_tw; ///< destination transfer width in byte csi_dma_trans_dir_t trans_dir; ///< transfer direction uint16_t handshake; ///< handshake id uint16_t group_len; ///< group transaction length (unit: bytes) uint8_t src_reload_en; ///< 1:dma enable src addr auto reload, 0:disable uint8_t dst_reload_en; ///< 1:dma enable dst addr auto reload, 0:disable uint8_t half_int_en; ///< 1:dma enable half interrupt, 0: disable uint8_t lli_src_en; ///< 1:dma enable llp, 0 disable uint8_t lli_dst_en; ///< 1:dma enable llp, 0 disable } csi_dma_ch_config_t; #ifndef DMA_LLI_SIZE #define DMA_LLI_SIZE 28 #endif #define DEFINE_DESC_BUF(buf_name, num) uint8_t buf_name[num * DMA_LLI_SIZE] typedef struct csi_dma_ch csi_dma_ch_t; struct csi_dma_ch { void *parent; int8_t ctrl_id; int8_t ch_id; void (*callback)(csi_dma_ch_t *dma_ch, csi_dma_event_t event, void *arg); void *arg; uint32_t lli_num; //lli buffer len uint32_t lli_count; //lli data count int32_t lli_w_p; //write position int32_t lli_r_p; //read position void *lli; //lli buffer uint32_t lli_loop_buf0; //lli loop data uint32_t lli_loop_buf1; //lli loop data uint8_t lli_loop[DMA_LLI_SIZE]; //lli loop handle int16_t etb_ch_id; slist_t next; }; typedef struct { csi_dev_t dev; slist_t head; uint32_t alloc_status; uint32_t ch_num; void *priv; } csi_dma_t; /** \brief Init dma controller \param[in] dma the dma controller operate handle \param[in] ctrl_id the dma controller id \return csi error code */ csi_error_t csi_dma_init(csi_dma_t *dma, int8_t ctrl_id); /** \brief Uninit dma controller \param[in] dma the dma controller operate handle \return none */ void csi_dma_uninit(csi_dma_t *dma); /** \brief Alloc a dma channel \param[in] dma_ch the dma channel operate handle \param[in] ch_id the channel id of dma; when set -1, means auto alloc \param[in] ctrl_id the dma controller id; when set -1, means auto alloc \return csi error code */ csi_error_t csi_dma_ch_alloc(csi_dma_ch_t *dma_ch, int8_t ch_id, int8_t ctrl_id); /** \brief Free a dma channel \param[in] dma_ch the dma channel operate handle \return none */ void csi_dma_ch_free(csi_dma_ch_t *dma_ch); /** \brief Config a dma channel \param[in] dma_ch the dma channel operate handle \param[in] config the config structure for dma channel \return csi error code */ csi_error_t csi_dma_ch_config(csi_dma_ch_t *dma_ch, csi_dma_ch_config_t *config); /** \brief Start a dma channel \param[in] dma_ch the dma channel operate handle \param[in] psrcaddr transfer source address \param[in] pdstaddr transfer destination address \param[in] length transfer length (unit: bytes), if set data_width is 16, the length should be the multiple of 2, and if set data_width is 32, the length should be the multiple of 4 \return none */ void csi_dma_ch_start(csi_dma_ch_t *dma_ch, void *srcaddr, void *dstaddr, uint32_t length); /** \brief Stop a dma channel \param[in] dma_ch the dma channel operate handle \return none */ void csi_dma_ch_stop(csi_dma_ch_t *dma_ch); /** \brief Attach the callback handler to DMA channel \param[in] dma_ch operate handle. \param[in] callback callback function \param[in] arg user can define it by himself as callback's param \return error code */ csi_error_t csi_dma_ch_attach_callback(csi_dma_ch_t *dma_ch, void *callback, void *arg); /** \brief detach the callback handler \param[in] uart operate handle. */ void csi_dma_ch_detach_callback(csi_dma_ch_t *dma_ch); /** \brief enable dma power manage \param[in] dma dma handle to operate. \return error code */ csi_error_t csi_dma_enable_pm(csi_dma_t *dma); /** \brief disable dma power manage \param[in] dma dma handle to operate. */ void csi_dma_disable_pm(csi_dma_t *dma); #ifdef __cplusplus } #endif #endif /* _CSI_DMA_H_ */