/*! * \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 #include #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_ */