Files
hpw421/component/xc6xx_drivers/Drivers/xc_driver/xc_drv_dma.h
T
2026-07-03 18:08:25 +08:00

287 lines
9.7 KiB
C

/*!
* \file xc_drv_dma.h
*
* \brief The header of xc_drv_dma.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#ifndef _XC_DRV_DMA_H_
#define _XC_DRV_DMA_H_
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include <stdbool.h>
#include <stdio.h>
#include "xc6xxx.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------------------------------------------------*/
// Macro definitions for DMA operation return code
#define DMA_OK 0 // operation normal
#define DMA_EPERM 1 // operation not permitted
#define DMA_EIO 5 // I/O error
#define DMA_ENXIO 6 // no such device or address
#define DMA_ENOMEM 12 // out of memory
#define DMA_EACCES 13 // permission denied
#define DMA_EBUSY 16 // device or resource busy
#define DMA_ENODEV 19 // no such device
#define DMA_EINVAL 22 // invalid argument
#define DMA_ENOSPC 28 // no space left on device
#define DMA_ENOSYS 38 // function not implemented/supported
#define DMA_ECHRNG 44 // channel number out of range
#define DMA_ENODATA 61 // no data available
#define DMA_ETIME 62 // timer expired
#define DMA_EPROTO 71 // protocol error
// Macro definitions for DMA controller limits
#define DMA_MAX_CHANNELS 4U //5A 2 CH; 5B 4 CH
#define DMA_MAX_INTERRUPTS 5U
/*------------------------------------------------------------------------------------
TypeDef
-------------------------------------------------------------------------------------*/
typedef void (*DMA_Callback)(uint8_t eCode);
typedef enum dmac_channel_number
{
// 4 channel configuration
DMA_NO_CHANNEL = 0x0000,
DMA_CHANNEL0 = 0x0101,
DMA_CHANNEL1 = 0x0202,
DMA_CHANNEL2 = 0x0404,
DMA_CHANNEL3 = 0x0808,
DMA_ALL_CHANNELS = 0x0f0f
} eDMA_Ch_Num;
typedef enum dmac_src_dst_select
{
DMA_SRC = 0x1,
DMA_DST = 0x2,
DMA_SRC_DST = 0x3
} eDMA_Src_Dst_Select;
typedef enum dmac_ch_state
{
DMA_IDLE = 0x0,
DMA_SINGLE_REGION = 0x1,
DMA_BURST_REGION = 0x2
} eDMA_CH_State;
typedef enum dmac_transfer_type
{
DMA_TRANSFER_ROW1 = 0x1, /* single block or last multi-block */
/* no write back */
DMA_TRANSFER_ROW2 = 0x2, /* multi-block auto-reload DAR */
/* contiguous SAR no write back */
DMA_TRANSFER_ROW3 = 0x3, /* multi-block auto reload SAR */
/* contiguous DAR no write back */
DMA_TRANSFER_ROW4 = 0x4, /* multi-block auto-reload SAR DAR */
/* no write back */
DMA_TRANSFER_ROW5 = 0x5, /* single block or last multi-block */
/* with write back */
DMA_TRANSFER_ROW6 = 0x6, /* multi-block linked list DAR */
/* contiguous SAR with write back */
DMA_TRANSFER_ROW7 = 0x7, /* multi-block linked list DAR auto */
/* reload SAR with write back */
DMA_TRANSFER_ROW8 = 0x8, /* multi-block linked list SAR */
/* contiguous DAR with write back */
DMA_TRANSFER_ROW9 = 0x9, /* multi-block linked list SAR auto */
/* reload DAR with write back */
DMA_TRANSFER_ROW10 = 0xa /* multi-block linked list SAR DAR */
/* with write back */
} eDMA_Trans_Type;
typedef enum dw_dmac_irq
{
DMA_IRQ_NONE = 0x00, // no interrupts
DMA_IRQ_TRF = 0x01, // transfer complete
DMA_IRQ_BLOCK = 0x02, // block transfer complete
DMA_IRQ_SRCTRAN = 0x04, // source transaction complete
DMA_IRQ_DSTTRAN = 0x08, // destination transaction complete
DMA_IRQ_ERR = 0x10, // error
DMA_IRQ_ALL = 0x1f // all interrupts
} eDMA_Irq;
typedef enum dmac_burst_trans_length
{
DMA_MSIZE_1 = 0x0,
DMA_MSIZE_4 = 0x1,
DMA_MSIZE_8 = 0x2,
DMA_MSIZE_16 = 0x3,
DMA_MSIZE_32 = 0x4,
DMA_MSIZE_64 = 0x5,
DMA_MSIZE_128 = 0x6,
DMA_MSIZE_256 = 0x7
} eDMA_Burst_Trans_Len;
typedef enum dmac_address_increment
{
DMA_ADDR_INCREMENT = 0x0,
DMA_ADDR_DECREMENT = 0x1,
DMA_ADDR_NOCHANGE = 0x2
} eDMA_Addr_Increment;
typedef enum dmac_transfer_width
{
DMA_TRANS_WIDTH_8 = 0x0,
DMA_TRANS_WIDTH_16 = 0x1,
DMA_TRANS_WIDTH_32 = 0x2,
DMA_TRANS_WIDTH_64 = 0x3,
DMA_TRANS_WIDTH_128 = 0x4,
DMA_TRANS_WIDTH_256 = 0x5
} eDMA_Trans_Width;
typedef enum dw_dmac_sw_hw_hs_select
{
DMA_HS_HARDWARE = 0x0,
DMA_HS_SOFTWARE = 0x1
} eDMA_SW_HW_HS_Select;
typedef enum dmac_hs_interface
{
UART0_DMA_TX_HS_IF0 = 0x0,
UART1_DMA_TX_HS_IF1 = 0x1,
SSI0_DMA_TX_HS_IF2 = 0x2,
SSI1_DMA_TX_HS_IF3 = 0x3,
SSI2_DMA_TX_HS_IF4 = 0x4,
I2S_DMA_TX_HS_IF5 = 0x5,
CDC_DMA_TX_HS_IF6 = 0x6,
DMA_HS_IF7 = 0x7,
UART0_DMA_RX_HS_IF8 = 0x8,
UART1_DMA_RX_HS_IF9 = 0x9,
SSI0_DMA_RX_HS_IF10 = 0xa,
SSI1_DMA_RX_HS_IF11 = 0xb,
GPADC_DMA_RX_HS_IF12 = 0xc,
CDC_DMA_RX_HS_IF13 = 0xd,
SSI2_DMA_RX_HS_IF14 = 0xe,
I2S_DMA_RX_HS_IF15 = 0xf
} eDMA_HS_Interface;
typedef enum dmac_transfer_flow
{
DMA_MEM2MEM_DMA = 0x0, /* mem to mem - DMA flow ctlr */
DMA_MEM2PRF_DMA = 0x1, /* mem to prf - DMA flow ctlr */
DMA_PRF2MEM_DMA = 0x2, /* prf to mem - DMA flow ctlr */
DMA_PRF2PRF_DMA = 0x3, /* prf to prf - DMA flow ctlr */
DMA_PRF2MEM_PRF = 0x4, /* prf to mem - periph flow ctlr */
DMA_PRF2PRF_SRCPRF = 0x5, /* prf to prf - source flow ctlr */
DMA_MEM2PRF_PRF = 0x6, /* mem to prf - periph flow ctlr */
DMA_PRF2PRF_DSTPRF = 0x7 /* prf to prf - dest flow ctlr */
} eDMA_Trans_Flow;
typedef enum dmac_fifo_mode
{
DMA_FIFO_MODE_SINGLE = 0x0,
DMA_FIFO_MODE_HALF = 0x1
} eDMA_Fifo_Mode;
typedef enum dw_dmac_channel_priority
{
DMA_PRIORITY_0 = 0x0,
DMA_PRIORITY_1 = 0x1,
DMA_PRIORITY_2 = 0x2,
DMA_PRIORITY_3 = 0x3,
DMA_PRIORITY_4 = 0x4,
DMA_PRIORITY_5 = 0x5,
DMA_PRIORITY_6 = 0x6,
DMA_PRIORITY_7 = 0x7
} eDMA_CH_Priority;
typedef struct dmac_channel_config
{
uint32_t sar;
uint32_t dar;
eDMA_Burst_Trans_Len ctl_src_msize;
eDMA_Burst_Trans_Len ctl_dst_msize;
eDMA_Addr_Increment ctl_sinc;
eDMA_Addr_Increment ctl_dinc;
eDMA_Trans_Width ctl_src_tr_width;
eDMA_Trans_Width ctl_dst_tr_width;
eDMA_HS_Interface cfg_dst_per;
eDMA_HS_Interface cfg_src_per;
uint32_t ctl_block_ts;
eDMA_Trans_Flow ctl_tt_fc;
eDMA_Fifo_Mode cfg_fifo_mode;
eDMA_SW_HW_HS_Select cfg_hs_sel_src;
eDMA_SW_HW_HS_Select cfg_hs_sel_dst;
eDMA_CH_Priority cfg_ch_prior;
} DMA_Chx_Cfg_t;
typedef struct dmac_param_s
{
bool encoded_params; /* include encoded hardware parameters */
uint8_t num_channels; /* number of DMA channels */
uint8_t num_hs_int; /* number of handshaking interfaces */
uint8_t intr_io; /* individual or combined interrupts */
bool big_endian; /* big or little endian 1=big */
uint16_t s_hdata_width; /* AHB slave data bus width */
} DMA_Params_t;
typedef struct dma_instance_s
{
struct
{
eDMA_Ch_Num ch_num; // channel number
DMA_Callback userCallback; // callback functon for IRQ handler
DMA_Callback userListener; // listener functon for IRQ handler
} Ch[DMA_MAX_CHANNELS];
uint8_t Ch_Order[DMA_MAX_CHANNELS];
} DMA_Instance_t;
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
extern DMA_Instance_t DMA_Instance;
/*------------------------------------------------------------------------------------
Exported Functions
-------------------------------------------------------------------------------------*/
uint8_t xc_dma_init(void);
void xc_dma_enable(void);
uint8_t xc_dma_disable(void);
bool xc_dma_is_enable(void);
uint8_t xc_dma_enable_channel(eDMA_Ch_Num ch_num);
uint8_t xc_dma_disable_channel(eDMA_Ch_Num ch_num);
bool xc_dma_is_channel_enabled(eDMA_Ch_Num ch_num);
uint8_t xc_dma_enable_channel_irq(eDMA_Ch_Num ch_num);
uint8_t xc_dma_set_channel_config(eDMA_Ch_Num ch_num, DMA_Chx_Cfg_t *ch);
bool xc_dma_set_listener(eDMA_Ch_Num ch_num, DMA_Callback userFunction);
uint8_t xc_dma_start_transfer(eDMA_Ch_Num ch_num, DMA_Callback cb_func);
void xc_dma_set_test_mode(uint8_t mode);
void xc_dma_set_channel_priority_order(DMA_Instance_t *inst);
void xc_dma_reset_instance(DMA_Instance_t *inst);
uint8_t xc_dma_check_channel_range(eDMA_Ch_Num ch_num);
uint8_t xc_dma_check_channel_range(eDMA_Ch_Num ch_num);
uint8_t xc_dma_get_channel_index(eDMA_Ch_Num ch_num);
bool dma_irq_handler(DMA_Instance_t *inst);
#endif /* _XC_DRV_DMA_H_ */