/**
 * \file    drv_dma.h
 * \brief   DMA operations
 *
 * \par     Copyright (c) 2018 UWE Technologies Corp., Ltd. All Rights Reserved.
 * \author  James
 * \date    2018-06-03
 * \version 
 * 
 * \history 
 *  Date        Note
 *  2018-06-03  Original Creation
 * 
 */
 
#ifndef __DRV_DMA_H_
#define __DRV_DMA_H_

#include "types.h"
#include "utils.h"
#include "drv_reg_intf.h"
#include "reg_def_dma.h"


typedef enum DRV_DMA_MODE_e
{
    DRV_DMA_MODE_ADDR_INC,
    DRV_DMA_MODE_ADDR_DEC,
    DRV_DMA_MODE_SRC_ADDR_HOLD,
    DRV_DMA_MODE_DES_ADDR_HOLD
} DRV_DMA_MODE_t;

/** \brief DMA0 memory copy, likes memcpy
 *
 * \param dst       Destination memory address
 * \param src       Source memory address
 * \param count     Memory copy count
 * \param mode      Memory operation mode, 
 *                    0: memory address increment 
 *                    1: memory address decrement
 *                    2: memory source address hold
 *                    3: memory destination address hold
 * \return          Destination memory address
 */
void *drv_dma_memcpy(void *dst, const void *src, u32_t count, DRV_DMA_MODE_t mode);

/** \brief DMA0 memory move, likes memmove
 *
 * \param dst       Destination memory address
 * \param src       Source memory address
 * \param count     Memory copy count
 * \return          Destination memory address
 */
void *drv_dma_memmove(void *dst, const void *src, u32_t count);


/** \brief DMA1 memory copy with interrupt support
 *
 * \param dst       Destination memory address
 * \param src       Source memory address
 * \param count     Memory copy count
 * \param mode      Memory operation mode, 
 *                    0: memory address increment
 *                    1: memory address decrement
 *                    2: memory source address hold, for UART and SPI RX
 *                    3: memory destination address hold, for UART and SPI TX
 * \param intr      Interrupt enable or not
 * \param intr_cb   If enable interrupt, need callback function
 */
void drv_dma1_memcpy(void *dst, const void *src, u32_t count, DRV_DMA_MODE_t mode, bool_t intr, v_func_ptr_t intr_cb);


/** \brief Stop DMA1 memory operation
 *
 */
void drv_dma1_stop(void);

#define drv_dma1_intr_en_set(flg)   \
    do {\
        DRV_REG_FIELD_SET(DMA_INT_REG, DMA1_INT_ENA, flg); \
    } while(0)


#define drv_dma0_dst_addr_get()     DRV_REG_GET(DMA0_CTRL_REG1)
#define drv_dma0_src_addr_get()     DRV_REG_GET(DMA0_CTRL_REG0)

#define drv_dma1_dst_addr_get()     DRV_REG_GET(DMA1_CTRL_REG1)
#define drv_dma1_src_addr_get()     DRV_REG_GET(DMA1_CTRL_REG0)



#endif /* #ifndef __DRV_DMA_H_ */


