288 lines
9.7 KiB
C
288 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 2U //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_ALL_CHANNELS = 0x0303,
|
|
// 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,
|
|
DMA_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_ */
|