/**
******************************************************************************************************************************************************************************************
*@file                       cpu_dma.h
*@author         
*@data                       
*@version                    v1.0
*@par Copyright(c):
*
*@par History:
*     version:author,date,desc
*     v1.0   :create this file
*
*******************************************************************************************************************************************************************************************
*/
#ifndef CPU_DMA_H
#define CPU_DMA_H

#ifdef __cplusplus
 extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "cpu.h"

typedef struct
{
  uint32_t dma_peripheral;

  uint32_t dma_perpheral_base_addr; /*!< Specifies the peripheral base address for DMAy Channelx. */

  uint32_t dma_memory_base_addr;     /*!< Specifies the memory base address for DMAy Channelx. */

  uint32_t dma_dir;                /*!< Specifies if the peripheral is the source or destination.
                                        This parameter can be a value of @ref DMA_data_transfer_direction */

  uint32_t dma_periphearl_inc;      /*!< Specifies whether the Peripheral address register is incremented or not.
                                        This parameter can be a value of @ref DMA_incremented_mode */

  uint32_t dma_memory_inc;          /*!< Specifies whether the memory address register is incremented or not.
                                        This parameter can be a value of @ref DMA_incremented_mode */

  uint32_t dma_peripheral_data_size; /*!< Specifies the Peripheral data item width.
                                        This parameter can be a value of @ref DMA_data_size */

  uint32_t dma_memory_data_size;     /*!< Specifies the Memory data item width.
								   This parameter can be a value of @ref DMA_data_size */

  uint32_t dma_peripheral_burst_size; /*!< Specifies the Peripheral Number of data items during per burst transaction.
									read or write from the Peripheral every time a burst transaction request 
									This parameter can be a value of @ref DMA_burst_size */

  uint32_t dma_memory_burst_size;     /*!< Specifies the Memory Number of data items during per burst transaction.
									read or write from the Memory every time a burst transaction request 
									This parameter can be a value of @ref DMA_burst_size */

  uint32_t dma_peripheral_handshake_size;	/*!< Specifies the HandShake to control the DMA transacation.
									This parameter can be a value of @ref DMA_peripheral_handshake */

  uint32_t dma_block_size;			/*!< Specifies the Total Number of data items during the transaction. */

  uint32_t dma_priority;           /*!< Specifies the software priority for the DMAy Channelx.
										This parameter can be a value of @ref DMA_priority_level */
}dma_init_type_def;

/** @defgroup DMA_data_transfer_direction 
  * @{
  */
#define DMA_DIR_Memory_To_Memory								((uint32_t)0x0000)
#define DMA_DIR_Peripheral_To_Memory							((uint32_t)0x0001)
#define DMA_DIR_Memory_To_Peripheral							((uint32_t)0x0002)
/**
  * @}
  */

/** @defgroup DMA_peripheral_data_size 
  * @{
  */
 typedef enum _dma_peripheral{
	 DMA_Peripheral_Memory=	((uint32_t)0x0000),
	 DMA_Peripheral_UART0	=	((uint32_t)0x0001),
	 DMA_Peripheral_UART1	=	((uint32_t)0x0002),
	 DMA_Peripheral_UART2	=	((uint32_t)0x0003),
	 DMA_Peripheral_UART3	=	((uint32_t)0x0004),
	 DMA_Peripheral_SPI0	=	((uint32_t)0x0005),
	 DMA_Peripheral_SPI1	=	((uint32_t)0x0006),
	 DMA_Peripheral_SPI2	=	((uint32_t)0x0007),
	 DMA_Peripheral_I2C0	=	((uint32_t)0x0008),
}dma_peripheral;
/**
  * @}
  */
/** @defgroup DMA_incremented_mode 
  * @{
  */

#define DMA_Inc_Increment						((uint32_t)0x00000000)
#define DMA_Inc_Decrement						((uint32_t)0x00000001)
#define DMA_Inc_Nochange						((uint32_t)0x00000002)
#define IS_DMA_INC_STATE(STATE) (((STATE) == DMA_Inc_Increment) || \
                                            ((STATE) == DMA_Inc_Decrement) || \
                                            ((STATE) == DMA_Inc_Nochange))
/**
  * @}
  */

/** @defgroup DMA_data_size 
  * @{
  */

#define DMA_DataSize_Byte									((uint32_t)0x0000)
#define DMA_DataSize_HalfWord								((uint32_t)0x0001)
#define DMA_DataSize_Word									((uint32_t)0x0002)
#define IS_DMA_DATA_SIZE(SIZE)								(((SIZE) == DMA_DataSize_Byte) || \
														    ((SIZE) == DMA_DataSize_HalfWord) || \
														    ((SIZE) == DMA_DataSize_Word))
/**
  * @}
  */

/** @defgroup DMA_burst_size
  * @{
  */
#define DMA_BurstSize_1										((uint32_t)0x00)
#define DMA_BurstSize_4										((uint32_t)0x01)
#define DMA_BurstSize_8										((uint32_t)0x02)
/**
  * @}
  */

/** @defgroup DMA_peripheral_handshake
  * @{
  */
#define DMA_PeripheralHandShake_Hardware						((uint32_t)0x0000)
#define DMA_PeripheralHandShake_Software						((uint32_t)0x0001)
/**
  * @}
  */

/** @defgroup dma_priority
  * @{
  */
#define DMA_Priority_0											((uint32_t)0x00000000)
#define DMA_Priority_1											((uint32_t)0x00000020)
#define DMA_Priority_2											((uint32_t)0x00000040)
#define DMA_Priority_3											((uint32_t)0x00000060)
/**
  * @}
  */

/** @defgroup dma_it
  * @{
  */
#define DMA_IT_BlockTransferComplete					((uint32_t)0x01)
#define DMA_IT_DestinationTransactionComplete			((uint32_t)0x02)
#define DMA_IT_Error									((uint32_t)0x04)
#define DMA_IT_SourceTransactionComplete				((uint32_t)0x08)
#define DMA_IT_DMATransferComplete					    ((uint32_t)0x10)
/**
  * @}
  */

/** @defgroup DMA
  * @{
  */
typedef enum _dma_diriction 
{
	DMA_RX	= ((uint32_t)0x01),
	DMA_TX	= ((uint32_t)0x02)
}dma_diriction;

void dma_init(dma_type_def* dma_channelx, dma_init_type_def* dma_init_struct);
void dma_channel_cmd(dma_type_def* dma_channelx, functional_state_t new_state);
void dma_cmd(functional_state_t new_state);

void dma_set_src_address(dma_type_def* dma_channelx, uint32_t Address);
void dma_set_dsr_address(dma_type_def* dma_channelx, uint32_t Address);
void dma_set_channel_hardshake_periph(dma_type_def* dma_channelx,uint32_t HardwareHandshake_Peripheral);
void dma_set_src_single_req(dma_type_def* dma_channelx);
void dma_set_src_block_req(dma_type_def* dma_channelx);
	 
void dma_it_config(dma_type_def* dma_channelx, uint32_t dma_it, functional_state_t new_state);
	 
flag_status dma_get_flag_status(uint32_t DMA_FLAG);	 
void dma_clear_flag(uint32_t DMA_FLAG);

boolean dma_is_channel_enable(dma_type_def* dma_channelx);
	 
itstatus dma_get_it_status(dma_type_def* dma_channelx,uint32_t dma_it);
flag_status dma_get_raw_status(dma_type_def* dma_channelx,uint32_t dma_it);
void dma_clear_it_pending_bit(dma_type_def* dma_channelx,uint32_t dma_it);

#ifdef __cplusplus
}
#endif

#endif 
