/**
  *********************************************************************************
  *
  * @file    ald_usart.h
  * @brief   Header file of SMARTCARD driver module.
  *
  * @version V1.0
  * @date    25 Apr 2017
  * @author  AE Team
  * @note
  *
  * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
  *
  *********************************************************************************
  */

#ifndef __ALD_SMARTCARD_H__
#define __ALD_SMARTCARD_H__

#ifdef __cplusplus
 extern "C" {
#endif

#include "utils.h"
#include "ald_dma.h"
#include "ald_usart.h"


/** @addtogroup ES32FXXX_ALD
  * @{
  */

/** @addtogroup SMARTCARD
  * @{
  */

/** @defgroup SMARTCARD_Public_Constants  SMARTCARD Public constants
  * @{
  */

/**
  * @brief SMARTCARD error codes
  */
typedef enum {
	SMARTCARD_ERROR_NONE = ((uint32_t)0x00),	/**< No error */
	SMARTCARD_ERROR_PE   = ((uint32_t)0x01),	/**< Parity error */
	SMARTCARD_ERROR_NE   = ((uint32_t)0x02),	/**< Noise error */
	SMARTCARD_ERROR_FE   = ((uint32_t)0x04),	/**< frame error */
	SMARTCARD_ERROR_ORE  = ((uint32_t)0x08),	/**< Overrun error */
	SMARTCARD_ERROR_DMA  = ((uint32_t)0x10),	/**< DMA transfer error */
} smartcard_error_t;

/**
  * @brief SMARTCARD Prescaler
  */
typedef enum {
	SMARTCARD_PRESCALER_SYSCLK_DIV2  = ((uint32_t)0x1),	/**< SYSCLK divided by 2 */
	SMARTCARD_PRESCALER_SYSCLK_DIV4  = ((uint32_t)0x2),	/**< SYSCLK divided by 4 */
	SMARTCARD_PRESCALER_SYSCLK_DIV6  = ((uint32_t)0x3),	/**< SYSCLK divided by 6 */
	SMARTCARD_PRESCALER_SYSCLK_DIV8  = ((uint32_t)0x4),	/**< SYSCLK divided by 8 */
	SMARTCARD_PRESCALER_SYSCLK_DIV10 = ((uint32_t)0x5),	/**< SYSCLK divided by 10 */
	SMARTCARD_PRESCALER_SYSCLK_DIV12 = ((uint32_t)0x6),	/**< SYSCLK divided by 12 */
	SMARTCARD_PRESCALER_SYSCLK_DIV14 = ((uint32_t)0x7),	/**< SYSCLK divided by 14 */
	SMARTCARD_PRESCALER_SYSCLK_DIV16 = ((uint32_t)0x8),	/**< SYSCLK divided by 16 */
	SMARTCARD_PRESCALER_SYSCLK_DIV18 = ((uint32_t)0x9),	/**< SYSCLK divided by 18 */
	SMARTCARD_PRESCALER_SYSCLK_DIV20 = ((uint32_t)0xA),	/**< SYSCLK divided by 20 */
	SMARTCARD_PRESCALER_SYSCLK_DIV22 = ((uint32_t)0xB),	/**< SYSCLK divided by 22 */
	SMARTCARD_PRESCALER_SYSCLK_DIV24 = ((uint32_t)0xC),	/**< SYSCLK divided by 24 */
	SMARTCARD_PRESCALER_SYSCLK_DIV26 = ((uint32_t)0xD),	/**< SYSCLK divided by 26 */
	SMARTCARD_PRESCALER_SYSCLK_DIV28 = ((uint32_t)0xE),	/**< SYSCLK divided by 28 */
	SMARTCARD_PRESCALER_SYSCLK_DIV30 = ((uint32_t)0xF),	/**< SYSCLK divided by 30 */
	SMARTCARD_PRESCALER_SYSCLK_DIV32 = ((uint32_t)0x10),	/**< SYSCLK divided by 32 */
	SMARTCARD_PRESCALER_SYSCLK_DIV34 = ((uint32_t)0x11),	/**< SYSCLK divided by 34 */
	SMARTCARD_PRESCALER_SYSCLK_DIV36 = ((uint32_t)0x12),	/**< SYSCLK divided by 36 */
	SMARTCARD_PRESCALER_SYSCLK_DIV38 = ((uint32_t)0x13),	/**< SYSCLK divided by 38 */
	SMARTCARD_PRESCALER_SYSCLK_DIV40 = ((uint32_t)0x14),	/**< SYSCLK divided by 40 */
	SMARTCARD_PRESCALER_SYSCLK_DIV42 = ((uint32_t)0x15),	/**< SYSCLK divided by 42 */
	SMARTCARD_PRESCALER_SYSCLK_DIV44 = ((uint32_t)0x16),	/**< SYSCLK divided by 44 */
	SMARTCARD_PRESCALER_SYSCLK_DIV46 = ((uint32_t)0x17),	/**< SYSCLK divided by 46 */
	SMARTCARD_PRESCALER_SYSCLK_DIV48 = ((uint32_t)0x18),	/**< SYSCLK divided by 48 */
	SMARTCARD_PRESCALER_SYSCLK_DIV50 = ((uint32_t)0x19),	/**< SYSCLK divided by 50 */
	SMARTCARD_PRESCALER_SYSCLK_DIV52 = ((uint32_t)0x1A),	/**< SYSCLK divided by 52 */
	SMARTCARD_PRESCALER_SYSCLK_DIV54 = ((uint32_t)0x1B),	/**< SYSCLK divided by 54 */
	SMARTCARD_PRESCALER_SYSCLK_DIV56 = ((uint32_t)0x1C),	/**< SYSCLK divided by 56 */
	SMARTCARD_PRESCALER_SYSCLK_DIV58 = ((uint32_t)0x1D),	/**< SYSCLK divided by 58 */
	SMARTCARD_PRESCALER_SYSCLK_DIV60 = ((uint32_t)0x1E),	/**< SYSCLK divided by 60 */
	SMARTCARD_PRESCALER_SYSCLK_DIV62 = ((uint32_t)0x1F),	/**< SYSCLK divided by 62 */
} smartcard_prescaler_t;

/**
  * @}
  */

/** @defgroup SMARTCARD_Public_Types SMARTCARD Public Types
  * @{
  */

/**
  * @brief SMARTCARD Init Structure definition
  */
typedef struct {
	uint32_t baud;			/**< This member configures the SmartCard communication baud rate. */
	usart_word_length_t word_length;/**< Specifies the number of data bits transmitted or received in a frame. */
	usart_stop_bits_t stop_bits;	/**< Specifies the number of stop bits transmitted. */
	usart_parity_t parity;		/**< Specifies the parity mode.
						@note When parity is enabled, the computed parity is inserted
                                                      at the MSB position of the transmitted data (9th bit when
                                                      the word length is set to 9 data bits; 8th bit when the
                                                      word length is set to 8 data bits).*/
	usart_mode_t mode;		/**< Specifies whether the Receive or Transmit mode is enabled or disabled. */
	usart_cpol_t polarity;		/**< Specifies the steady state of the serial clock. */
	usart_cpha_t phase;		/**< Specifies the clock transition on which the bit capture is made.*/
	usart_last_bit_t last_bit;	/**< Specifies whether the clock pulse corresponding to the last transmitted
					     data bit (MSB) has to be output on the SCLK pin in synchronous mode.
                                             This parameter can be a value of @ref usart_last_bit_t */
	smartcard_prescaler_t prescaler;/**< Specifies the SmartCard Prescaler value used for dividing the system clock
					     to provide the smartcard clock. The value given in the register (5 significant bits)
					     is multiplied by 2 to give the division factor of the source clock frequency. */
	uint32_t guard_time;		/**< Specifies the SmartCard Guard Time value in terms of number of baud clocks */
	type_func_t nack;		/**< Specifies the SmartCard NACK Transmission state. */
} smartcard_init_t;

/**
  * @brief ALD state structures definition
  */
typedef enum {
	SMARTCARD_STATE_RESET      = 0x00,	/**< Peripheral is not yet Initialized */
	SMARTCARD_STATE_READY      = 0x01,	/**< Peripheral Initialized and ready for use */
	SMARTCARD_STATE_BUSY       = 0x02,	/**< an internal process is ongoing */
	SMARTCARD_STATE_BUSY_TX    = 0x11,	/**< Data Transmission process is ongoing */
	SMARTCARD_STATE_BUSY_RX    = 0x21,	/**< Data Reception process is ongoing */
	SMARTCARD_STATE_BUSY_TX_RX = 0x31,	/**< Data Transmission and Reception process is ongoing */
	SMARTCARD_STATE_TIMEOUT    = 0x03,	/**< Timeout state */
	SMARTCARD_STATE_ERROR      = 0x04	/**< Error */
} smartcard_state_t;


/**
  * @brief  SMARTCARD handle structure definition
  */
typedef struct smartcard_handle_s {
	USART_TypeDef *perh;		/**< USART registers base address */
	smartcard_init_t init;		/**< SmartCard communication parameters */
	uint8_t *tx_buf;		/**< Pointer to SmartCard Tx transfer Buffer */
	uint16_t tx_size;		/**< SmartCard Tx Transfer size */
	uint16_t tx_count;		/**< SmartCard Tx Transfer Counter */
	uint8_t *rx_buf;		/**< Pointer to SmartCard Rx transfer Buffer */
	uint16_t rx_size;		/**< SmartCard Rx Transfer size */
	uint16_t rx_count;		/**< SmartCard Rx Transfer Counter */
#ifdef ALD_DMA
	dma_handle_t hdmatx;		/**< SmartCard Tx DMA Handle parameters */
	dma_handle_t hdmarx;		/**< SmartCard Rx DMA Handle parameters */
#endif
	lock_state_t lock;		/**< Locking object */
	smartcard_state_t state;	/**< SmartCard communication state */
	uint32_t  err_code;		/**< SmartCard Error code */

	void (*tx_cplt_cbk)(struct smartcard_handle_s *arg);	/**< Tx completed callback */
	void (*rx_cplt_cbk)(struct smartcard_handle_s *arg);	/**< Rx completed callback */
	void (*error_cbk)(struct smartcard_handle_s *arg);	/**< error callback */
} smartcard_handle_t;

/**
  * @}
  */

/** @defgroup SMARTCARD_Public_Macros SMARTCARD Public Macros
  * @{
  */

/** @defgroup SMARTCARD_Public_Macros_1 SMARTCARD handle reset
  * @{
  */
#define SMARTCARD_RESET_HANDLE_STATE(handle) ((handle)->state = SMARTCARD_STATE_RESET)
/**
  * @}
  */

/** @defgroup SMARTCARD_Public_Macros_2 SMARTCARD flush data
  * @{
  */
#define SMARTCARD_FLUSH_DRREGISTER(handle) ((handle)->perh->DATA)
/**
  * @}
  */

/** @defgroup SMARTCARD_Public_Macros_3 SMARTCARD enable
  * @{
  */
#define SMARTCARD_ENABLE(handle)	(SET_BIT((handle)->perh->CON0, USART_CON0_EN_MSK))
/**
  * @}
  */

/** @defgroup SMARTCARD_Public_Macros_4 SMARTCARD disable
  * @{
  */
#define SMARTCARD_DISABLE(handle)	(CLEAR_BIT((handle)->perh->CON0, USART_CON0_EN_MSK))
/**
  * @}
  */

/**
  * @}
  */

/** @defgroup SMARTCARD_Private_Macros SMARTCARD Private Macros
  * @{
  */

#define IS_SMARTCARD_PRESCALER(x)   (((x) >= SMARTCARD_PRESCALER_SYSCLK_DIV2) && \
				     ((x) <= SMARTCARD_PRESCALER_SYSCLK_DIV62))
/**
  * @}
  */

/** @addtogroup SMARTCARD_Public_Functions
  * @{
  */

/** @addtogroup SMARTCARD_Public_Functions_Group1
  * @{
  */
/* Initialization functions */
ald_status_t smartcard_init(smartcard_handle_t *hperh);
ald_status_t smartcard_reset(smartcard_handle_t *hperh);
/**
  * @}
  */

/** @addtogroup SMARTCARD_Public_Functions_Group2
  * @{
  */
/* IO operation functions */
ald_status_t smartcard_send(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout);
ald_status_t smartcard_recv(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout);
ald_status_t smartcard_send_by_it(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size);
ald_status_t smartcard_recv_by_it(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size);
#ifdef ALD_DMA
ald_status_t smartcard_send_by_dma(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel);
ald_status_t smartcard_recv_by_dma(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel);
#endif
void smartcard_irq_handle(smartcard_handle_t *hperh);
/**
  * @}
  */

/** @addtogroup SMARTCARD_Public_Functions_Group3
  * @{
  */
/* Peripheral State and Errors functions functions */
smartcard_state_t smartcard_get_state(smartcard_handle_t *hperh);
uint32_t smartcard_get_error(smartcard_handle_t *hperh);
/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

#ifdef __cplusplus
}
#endif

#endif /* __ALD_SMARTCARD_H__ */
