/**
  *****************************************************************************
  * @file    dma_hal.h
  * @author  Product application department
  * @version V1.0
  * @date    2020.02.13
  * @brief   Header file of DMA HAL module.
  *
  ******************************************************************************
  */

/* Define to prevent recursive inclusion -------------------------------------*/

#ifndef DMA_HAL_H_
#define DMA_HAL_H_

#include "debug.h"
#include "hal_def.h"
#include "dma_drv.h"


#ifdef __cplusplus
extern "C"
{
#endif

/**@defgroup HAL HAL driver
  *
  *@{
  */

/** @defgroup HAL_DMA DMA
  *
  *@{
  */

/*** 宏定义 *******************************************************************/
/** @defgroup DMA_Exported_Macros Exported Macros
  *
  * @{
  */

 #define HAL_TIMEOUT_DMA_ABORT    ((uint32_t)1000)  /**< 1s */

#define HAL_DMA_MSG               //MSG

#define DMAC_NUMBER_CHANNELS        4

#define HAL_DMAC_SINC_INC           0/**< DMAC Source Address Increment */
#define HAL_DMAC_SINC_DEC           1/**< DMAC Source Address Decrement */
#define HAL_DMAC_SINC_NO_CHANGE     2/**< DMAC Source Address No Change */

#define HAL_DMAC_DINC_INC           0/**< DMAC Destination Address Increment */
#define HAL_DMAC_DINC_DEC           1/**< DMAC Destination Address Decrement */
#define HAL_DMAC_DINC_NO_CHANGE     2/**< DMAC Destination Address No Change */

#define HAL_DMAC_LLP_DIS            0/**< 源端和目的端都不使用LLP */
#define HAL_DMAC_LLP_SRC_EN         1/**< 源端使用LLP */
#define HAL_DMAC_LLP_DST_EN         2/**< 目的端使用LLP */
#define HAL_DMAC_LLP_SRC_DST_EN     3/**< 源端和目的端都使用LLP */

/**
  * @}
  */

/*** 结构体、枚举变量定义 *****************************************************/
/** @defgroup DMA_Exported_Types Exported Types
  *
  * @{
  */

/**
* @brief DNAC 状态定义
*
*/
typedef enum
{
  HAL_DMA_STATE_RESET             = 0x00,  /**< DMA not yet initialized or disabled */
  HAL_DMA_STATE_READY             = 0x01,  /**< DMA initialized and ready for use   */
  HAL_DMA_STATE_BUSY              = 0x02,  /**< DMA process is ongoing              */
  HAL_DMA_STATE_TIMEOUT           = 0x03,  /**< DMA timeout state                   */
  HAL_DMA_STATE_ERROR             = 0x04,  /**< DMA error state                     */
}DMAC_StateTypeDef;

/**
  * @brief  HAL dmac channel index structure definition
  */
typedef enum
{

    HAL_DMAC_CHANNEL_0 = 0x00,
    HAL_DMAC_CHANNEL_1,
    HAL_DMAC_CHANNEL_2,
    HAL_DMAC_CHANNEL_3 
    
}DMAC_ChannelIndexTypeDef;

/**
  * @brief	HAL dmac burst transfer length structure definition
  */
typedef enum
{
    HAL_DMAC_MSIZE_1 = 0x00,
    HAL_DMAC_MSIZE_4,
    HAL_DMAC_MSIZE_8,
    HAL_DMAC_MSIZE_16,
    HAL_DMAC_MSIZE_32,
    HAL_DMAC_MSIZE_64,
    HAL_DMAC_MSIZE_128,
    HAL_DMAC_MSIZE_256,
    
}DMAC_BurstTransLengthTypedef;

/**
* @brief DNAC 通信宽度定义
*
*/
typedef enum
{
    HAL_DMAC_TR_WIDTH_8BITS = 0x00,
    HAL_DMAC_TR_WIDTH_16BITS,
    HAL_DMAC_TR_WIDTH_32BITS,
    HAL_DMAC_TR_WIDTH_64BITS,
    HAL_DMAC_TR_WIDTH_128BITS,
    HAL_DMAC_TR_WIDTH_256BITS,    
}DMAC_TransWidthTypeDef;

/**
 * @brief DMAC Transfer type of DMA controller
 */
typedef enum
{
    HAL_DMAC_TRANSFERTYPE_M2M_CONTROLLER_DMA              = ((0UL)),	/**< Memory to memory - DMA control */
    HAL_DMAC_TRANSFERTYPE_M2P_CONTROLLER_DMA              = ((1UL)),	/**< Memory to peripheral - DMA control */
    HAL_DMAC_TRANSFERTYPE_P2M_CONTROLLER_DMA              = ((2UL)),	/**< Peripheral to memory - DMA control */
    HAL_DMAC_TRANSFERTYPE_P2P_CONTROLLER_DMA              = ((3UL)),	/**< Source peripheral to destination peripheral - DMA control */
    HAL_DMAC_TRANSFERTYPE_P2M_CONTROLLER_PERIPHERAL       = ((4UL)),	/**< Source peripheral to destination peripheral - destination peripheral control */
    HAL_DMAC_TRANSFERTYPE_P2P_CONTROLLER_SRCPERIPHERAL    = ((5UL)),	/**< Memory to peripheral - peripheral control */
    HAL_DMAC_TRANSFERTYPE_M2P_CONTROLLER_PERIPHERAL       = ((6UL)),	/**< Peripheral to memory - peripheral control */
    HAL_DMAC_TRANSFERTYPE_P2P_CONTROLLER_DSTPERIPHERAL    = ((7UL))	  /**< Source peripheral to destination peripheral - source peripheral control */
} DMAC_FlowControlTypeDef;

/**
  *@brief DMAC 设备支持
 */
#if 0
typedef enum
{
	HAL_DMAC_PERIPHERAL_SPI1_TX  = 0X00,
	HAL_DMAC_PERIPHERAL_SPI2_TX  = 0X01,
	HAL_DMAC_PERIPHERAL_SS2_TX   = 0X02,
	HAL_DMAC_PERIPHERAL_SPI1_RX  = 0X03,
	HAL_DMAC_PERIPHERAL_SPI2_RX  = 0X04,
	HAL_DMAC_PERIPHERAL_SS2_RX   = 0X05,
	HAL_DMAC_PER3PHERAL_QADC     = 0x06,
	HAL_DMAC_PER3PHERAL_MCC1     = 0x07,
	HAL_DMAC_PERIPHERAL_MCC2     = 0x08,
	HAL_DMAC_PERIPHERAL_MCC3     = 0x09,
	HAL_DMAC_PERIPHERAL_UART1_TX  = 0x0A,
	HAL_DMAC_PERIPHERAL_UART1_RX  = 0x0B,
	HAL_DMAC_PERIPHERAL_UART3_TX  = 0x0C,
	HAL_DMAC_PERIPHERAL_UART3_RX  = 0x0D,
	HAL_DMAC_PERIPHERAL_DAC		   = 0x08,
	
}DMAC_PeripheralTypeDef;

/**
  *@brief DMAC2 设备支持
 */
typedef enum
{
	HAL_DMAC2_PERIPHERAL_UART2_RX  = 0X00,
	HAL_DMAC2_PERIPHERAL_UART2_TX  = 0X01,
	HAL_DMAC2_PERIPHERAL_SSI1_RX  = 0X02,
	HAL_DMAC2_PERIPHERAL_SSI1_TX  = 0X03,
	HAL_DMAC2_PERIPHERAL_SPI3_RX  = 0X04,
	HAL_DMAC2_PERIPHERAL_SPI3_TX  = 0X05,
}DMAC2_PeripheralTypeDef;
#else
typedef enum
{
	HAL_DMAC_PERIPHERAL_SPI1_TX  = 0X00,
	HAL_DMAC_PERIPHERAL_SPI2_TX  = 0X01,
	HAL_DMAC_PERIPHERAL_SPI3_TX  = 0X02,	
	HAL_DMAC_PERIPHERAL_SPI1_RX  = 0X03,
	HAL_DMAC_PERIPHERAL_SPI2_RX  = 0X04,
	HAL_DMAC_PERIPHERAL_SPI3_RX  = 0X05,
	HAL_DMAC_PER3PHERAL_QADC     = 0x06,
	HAL_DMAC_PER3PHERAL_MCC1     = 0x07,
	HAL_DMAC_PERIPHERAL_MCC2     = 0x08,
	HAL_DMAC_PERIPHERAL_MCC3     = 0x09,
	HAL_DMAC_PERIPHERAL_UART1_TX  = 0x0A,
	HAL_DMAC_PERIPHERAL_UART1_RX  = 0x0B,
	HAL_DMAC_PERIPHERAL_UART3_TX  = 0x0C,
	HAL_DMAC_PERIPHERAL_UART3_RX  = 0x0D,
	
}DMAC_PeripheralTypeDef;

/**
  *@brief DMAC2 设备支持
 */
typedef enum
{
	HAL_DMAC2_PERIPHERAL_UART2_RX  = 0X00,
	HAL_DMAC2_PERIPHERAL_UART2_TX  = 0X01,
	HAL_DMAC2_PERIPHERAL_SSI1_RX   = 0X02,
	HAL_DMAC2_PERIPHERAL_SSI1_TX   = 0X03,
	HAL_DMAC2_PERIPHERAL_SSI2_RX   = 0X04,
	HAL_DMAC2_PERIPHERAL_SSI2_TX   = 0X05,
	HAL_DMAC2_PERIPHERAL_I2S_RX    = 0X06,
	HAL_DMAC2_PERIPHERAL_I2S_TX    = 0X07,
	HAL_DMAC_PERIPHERAL_DAC        = 0X08,
	HAL_DMAC_PERIPHERAL_DCMI       = 0X09,
	HAL_DMAC2_PERIPHERAL_UART4_RX  = 0X0A,
	HAL_DMAC2_PERIPHERAL_UART4_TX  = 0X0B,
	HAL_DMAC_PERIPHERAL_PWMT       = 0X0C,
	HAL_DMAC_PERIPHERAL_DCMI_DVT   = 0X0D,
}DMAC2_PeripheralTypeDef;
#endif

/**
  *@brief DMA Init 结构体定义
  *
  */
typedef struct
{
    uint32_t channel_num;	  /**< DMA channel number, should be in
							          *  range from 0 to 7.
							          *  Note: DMA channel 0 has the highest priority
							          *  and DMA channel 7 the lowest priority.
							          */
							          
	uint32_t transfer_lli;  /*源端和目的端LLP标识，
	                         * should be one of the following:
                             * - HAL_DMAC_LLP_DIS
                             * - HAL_DMAC_LLP_SRC_EN
                             * - HAL_DMAC_LLP_DST_EN
                             * - HAL_DMAC_LLP_SRC_DST_EN
						     */
									  
	uint32_t src_msize;
	uint32_t dst_msize;

    uint32_t src_tr_width; /**< Transfer width - used for TransferType is DMAC_TRANSFERTYPE_M2M only */
	uint32_t dst_tr_width;

    
	uint32_t src_inc;         /**< Specifies whether the Source address register should be incremented or not.
                                           This parameter can be a value of @ref DMA_Peripheral_incremented_mode */
                               
    uint32_t dst_inc;        /**< Specifies whether the Destination address register should be incremented or not.
                                           This parameter can be a value of @ref DMA_Memory_incremented_mode */
										   
    uint32_t transfer_type;  /**< Transfer Type, should be one of the following:
							          * - DMAC_TRANSFERTYPE_M2M: Memory to memory - DMA control
							          * - DMAC_TRANSFERTYPE_M2P: Memory to peripheral - DMA control
							          * - DMAC_TRANSFERTYPE_P2M: Peripheral to memory - DMA control
							          * - DMAC_TRANSFERTYPE_P2P: Source peripheral to destination peripheral - DMA control*/

	uint32_t peripheral_type;/*Transfer Type, should be one of the following:
                               DMAC_PeripheralTypeDef
							*/								  
	uint32_t src_addr;	     /**< Physical Source Address, used in case TransferType is chosen as
							          *   DMAC_TRANSFERTYPE_M2M or DMAC_TRANSFERTYPE_M2P */
    uint32_t dst_addr;	     /**< Physical Destination Address, used in case TransferType is chosen as
							          *   DMAC_TRANSFERTYPE_M2M or DMAC_TRANSFERTYPE_P2M */
	uint32_t transfer_size;  /**< Length/Size of transfer */
							          
}DMAC_InitTypeDef;

typedef void (*dmac_callback_t)(void);

/**
  *@brief DMA handler 结构体定义
  *
  */
typedef struct
{  
  DMAC_TypeDef      		*instance;    /**< register base address       */
	DMAC_InitTypeDef      init; 		 /**< init required parameters	  */
	HAL_LockTypeDef       lock;          /**< DMA locking object          */  
	DMAC_StateTypeDef     state;         /**< DMA transfer state          */
	dmac_callback_t       dma_raw_callback;	 /**< DMA callback                */
	dmac_callback_t       dma_block_callback;
	dmac_callback_t       dma_err_callback;
	
}DMAC_HandleTypeDef;

/**
  * @}
  */

/*** 全局变量声明 **************************************************************/
/** @defgroup DMA_Exported_Variables Exported Variables
  *
  * @{
  */



/**
  * @}
  */

/*** 函数声明 ******************************************************************/
/** @defgroup DMA_Exported_Functions Exported Functions
  * @{
  */

  extern HAL_StatusTypeDef HAL_DMAC_GetFreeChannel(DMAC_TypeDef *pdma,uint8_t *pres);
  extern HAL_StatusTypeDef HAL_DMAC_Init(DMAC_HandleTypeDef *hdma);
  extern HAL_StatusTypeDef HAL_DMAC_Deinit(DMAC_HandleTypeDef *hdma);
  extern HAL_StatusTypeDef HAL_DMAC_Start(DMAC_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
  extern HAL_StatusTypeDef HAL_DMAC_Start_IT(DMAC_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
  extern HAL_StatusTypeDef HAL_DMAC_Abort(DMAC_HandleTypeDef *hdma);
  extern HAL_StatusTypeDef HAL_DMAC_PollForTransfer(DMAC_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout);
  extern HAL_StatusTypeDef HAL_DMAC_PollForTransfer_IT(DMAC_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout);
  extern DMAC_StateTypeDef HAL_DMAC_GetState(DMAC_HandleTypeDef *hdma);
  extern DMAC_StateTypeDef HAL_DMAC_ConfigLLi(DMAC_HandleTypeDef *hdma,DMAC_LLITypeDef* lli);
  extern void HAL_DMAC_ClearRawStatus(DMAC_HandleTypeDef *hdma,uint32_t ch);
  extern void HAL_DMAC_IRQHandler(DMAC_HandleTypeDef *hdma);
HAL_StatusTypeDef HAL_DMAC_StartPolling(DMAC_HandleTypeDef *hdma);
/**
  * @}
  */

/**
  *@}
  */

/**
  *@}
  */


#ifdef __cplusplus
}
#endif




#endif /* DMA_HAL_H_ */



