/******************************************************************************
*@file  : spl_spi.h
*@brief : Header file of SPI SPL module.
******************************************************************************/

#ifndef __SPL_SPI_H
#define __SPL_SPI_H

#ifdef __cplusplus
 extern "C" {
#endif

#include "acm32g103_spl_conf.h"

/** 
  * @brief  SPI Init structure definition  
  */

typedef struct
{
    uint32_t  SPI_Mode;              /*!< Specifies the SPI operating mode.
                                        This parameter can be a value of @ref SPI_mode */
    
    uint32_t  SPI_Work_Mode;         /*!< Specifies the CPOL and CPHA combinations
                                        This parameter can be a value of @ref SPI_WORK_MODE */

    uint32_t  X_Mode;                /*!< Specifies line mode 1/2/4 lines.
                                        This parameter can be a value of @ref X_MODE */    

    uint32_t  First_Bit;             /*!< Specifies whether data transfers start from MSB or LSB bit.
                                        This parameter can be a value of @ref SPI_MSB_LSB_FIRST */  
    
    uint32_t  BaudRate_Prescaler;    /*!< Specifies the Baud Rate prescaler value which will be
                                         used to configure the transmit and receive SCK clock.
                                        This parameter can be a value of @ref BAUDRATE_PRESCALER */
    
    uint32_t  Master_SShift;         /*!< SPI master sample clock shift management.
                                        This parameter can be a value of @ref SPI_MASTER_SSHIFT */
    
    uint32_t  Slave_SWCS;            /*!< SPI Slave Software CS Select management. 
                                        This parameter can be a value of @ref SPI_SLAVE_SOFT_CS */
    
    uint32_t  Slave_CS_Fliter;       /*!< SPI slave CS signal filter management.
                                        This parameter can be a value of @ref SPI_SLAVE_CS_FILTER */
    
    uint32_t  Slave_SCLK_Fliter;     /*!< SPI slave SCLK signal filter management.
                                        This parameter can be a value of @ref SPI_SLAVE_SCLK_FILTER */
    
}SPI_InitTypeDef;


/* Exported constants --------------------------------------------------------*/

/** @defgroup SPI_Exported_Constants
  * @{
  */

#define IS_SPI_ALL_PERIPH(PERIPH) (((PERIPH) == SPI1) || \
                                   ((PERIPH) == SPI2) || \
                                   ((PERIPH) == SPI3))

/** @defgroup SPI_MODE
 *  @{
 */
#define SPI_MODE_SLAVE     (0U)
#define SPI_MODE_MASTER    (SPI_CTL_MST_MODE)
#define IS_SPI_MODE(SPI_Mode)               (((SPI_Mode) == SPI_MODE_SLAVE) || \
                                             ((SPI_Mode) == SPI_MODE_MASTER))
/**
  * @}
  */
  
/** @defgroup SPI_WORK_MODE
  * @{
  */
/* SPI_WORK_MODE_0 stands for CPOL = LOW,  CPHA = 1EDGE  */
#define SPI_WORK_MODE_0    (0x00000000)
/* SPI_WORK_MODE_1 stands for CPOL = LOW,  CPHA = 2EDGE  */
#define SPI_WORK_MODE_1    (0x00000004)
/* SPI_WORK_MODE_2 stands for CPOL = HIGH, CPHA = 1EDGE  */
#define SPI_WORK_MODE_2    (0x00000008)
/* SPI_WORK_MODE_3 stands for CPOL = HIGH, CPHA = 2EDGE  */
#define SPI_WORK_MODE_3    (0x0000000C)
#define IS_SPI_WORK_MODE(WORK_MODE)        (((WORK_MODE) == SPI_WORK_MODE_0) || \
                                            ((WORK_MODE) == SPI_WORK_MODE_1) || \
                                            ((WORK_MODE) == SPI_WORK_MODE_2) || \
                                            ((WORK_MODE) == SPI_WORK_MODE_3))
/**
  * @}
  */



/** @defgroup X_MODE
  * @{
  */
#define SPI_1X_MODE    (0x00000000)
#define SPI_2X_MODE    (0x00000020)
#define SPI_4X_MODE    (0x00000040)
#define IS_SPI_X_MODE(X_MODE)              (((X_MODE) == SPI_1X_MODE) || \
                                            ((X_MODE) == SPI_2X_MODE) || \
                                            ((X_MODE) == SPI_4X_MODE))
/**
  * @}
  */


/** @defgroup SPI_MSB_LSB_FIRST
  * @{
  */
#define SPI_FIRSTBIT_MSB    (0U)
#define SPI_FIRSTBIT_LSB    (SPI_CTL_LSB_FIRST)
#define IS_SPI_FIRST_BIT(FIRST_BIT)        (((FIRST_BIT) == SPI_FIRSTBIT_MSB) || \
                                            ((FIRST_BIT) == SPI_FIRSTBIT_LSB))
/**
  * @}
  */


/** @defgroup BAUDRATE_PRESCALER
  * @{
  */
#define SPI_BAUDRATE_PRESCALER_2      (2U)  
#define SPI_BAUDRATE_PRESCALER_4      (4U)
#define SPI_BAUDRATE_PRESCALER_8      (8U)
#define SPI_BAUDRATE_PRESCALER_16     (16U)
#define SPI_BAUDRATE_PRESCALER_32     (32U)
#define SPI_BAUDRATE_PRESCALER_64     (64U)
#define SPI_BAUDRATE_PRESCALER_128    (128U)
#define SPI_BAUDRATE_PRESCALER_254    (254U)
#define IS_SPI_BAUDRATE_PRESCALER(BAUDRATE)    (((BAUDRATE) == SPI_BAUDRATE_PRESCALER_2)   || \
                                                ((BAUDRATE) == SPI_BAUDRATE_PRESCALER_4)    || \
                                                ((BAUDRATE) == SPI_BAUDRATE_PRESCALER_8)   || \
                                                ((BAUDRATE) == SPI_BAUDRATE_PRESCALER_16)  || \
                                                ((BAUDRATE) == SPI_BAUDRATE_PRESCALER_32)  || \
                                                ((BAUDRATE) == SPI_BAUDRATE_PRESCALER_64)  || \
                                                ((BAUDRATE) == SPI_BAUDRATE_PRESCALER_128) || \
                                                ((BAUDRATE) == SPI_BAUDRATE_PRESCALER_254))
/**
  * @}
  */
  
/** @defgroup SPI_SLAVE_SWCS
  * @{
  */
#define SPI_SLAVE_SWCS_DISABLE               (0U)
#define SPI_SLAVE_SWCS_ENABLE                (1U)
#define IS_SPI_SLAVE_SWCS_MANAGMENT(SWCS)     (((SWCS) == SPI_SLAVE_SWCS_DISABLE) || \
                                             ((SWCS) == SPI_SLAVE_SWCS_ENABLE))
/**
  * @}
  */ 




/** @defgroup SPI_SLAVE_CS_FILTER
  * @{
  */
#define SPI_SLAVE_CS_FILTER_DISABLE          (00000000U)
#define SPI_SLAVE_CS_FILTER_ENABLE           (SPI_CTL_CS_FILTER)
#define IS_SPI_SLAVE_CS_FILSTER(FILTER)      (((FILTER) == SPI_SLAVE_CS_FILTER_DISABLE) || \
                                             ((FILTER) == SPI_SLAVE_CS_FILTER_ENABLE))
/**
  * @}
  */ 
  
/** @defgroup SPI_SLAVE_SCLK_FILTER
  * @{
  */
#define SPI_SLAVE_SCLK_FILTER_DISABLE        (00000000U)
#define SPI_SLAVE_SCLK_FILTER_ENABLE         (SPI_CTL_SFILTER)
#define IS_SPI_SLAVE_SCLK_FILSTER(FILTER)    (((FILTER) == SPI_SLAVE_SCLK_FILTER_DISABLE) || \
                                             ((FILTER) == SPI_SLAVE_SCLK_FILTER_ENABLE))
/**
  * @}
  */
  
  
/** @defgroup SPI_MASTER_SSHIFT
  * @{
  */
#define SPI_MASTER_SSHIFT_NONE               (00000000U)  
#define SPI_MASTER_SSHIFT_1_HCLK             (SPI_RX_CTL_SSHIFT_0)
#define SPI_MASTER_SSHIFT_2_HCLK             (SPI_RX_CTL_SSHIFT_1)
#define SPI_MASTER_SSHIFT_3_HCLK             (SPI_RX_CTL_SSHIFT_1 | SPI_RX_CTL_SSHIFT_0)
#define IS_SPI_MASTER_SSHIFT(SSHIFT)         (((SSHIFT) == SPI_MASTER_SSHIFT_NONE) || \
                                             ((SSHIFT) == SPI_MASTER_SSHIFT_1_HCLK) || \
                                             ((SSHIFT) == SPI_MASTER_SSHIFT_2_HCLK) || \
                                             ((SSHIFT) == SPI_MASTER_SSHIFT_3_HCLK))
/**
  * @}
  */
  

/**
  * @}
  */

/** @defgroup SPI_DMA_transfer_requests 
  * @{
  */

#define SPI_DMAReq_TX               SPI_TX_CTL_DMA_REQ_EN
#define SPI_DMAReq_RX               SPI_RX_CTL_DMA_REQ_EN
#define IS_SPI_DMAREQ(DMAREQ) ((((DMAREQ) & ~BIT3) == 0 ) && ((DMAREQ) != 0x00))
/**
  * @}
  */

/** @defgroup SPI_NSS_internal_software_management 
  * @{
  */
#define SPI_Slave_SWCS_Set              (SPI_CTL_SWCS)
#define SPI_Slave_SWCS_Reset            (~SPI_CTL_SWCS)
#define IS_SPI_SLAVE_SWCS_STATE(STATE) (((STATE) == SPI_Slave_SWCS_Set) || \
                                       ((STATE) == SPI_Slave_SWCS_Reset))
/**
  * @}
  */



/** @defgroup SPI_direction_transmit_receive 
  * @{
  */

#define SPI_Direction_Rx                ((uint16_t)0xBFFF)
#define SPI_Direction_Tx                ((uint16_t)0x4000)
#define IS_SPI_DIRECTION(DIRECTION) (((DIRECTION) == SPI_Direction_Rx) || \
                                     ((DIRECTION) == SPI_Direction_Tx))
/**
  * @}
  */



/** @defgroup SPI_flags_definition 
  * @{
  */
#define IS_SPI_CLEAR_FLAG(FLAG) (((FLAG) == SPI_STATUS_CS_POS_FLG)   || \
                                 ((FLAG) == SPI_STATUS_BATCH_DONE))
                                   
#define IS_SPI_GET_FLAG(FLAG)    (((FLAG) == SPI_STATUS_RX_BATCH_DONE) || \
                                  ((FLAG) == SPI_STATUS_TX_BATCH_DONE) || \
                                  ((FLAG) == SPI_STATUS_RX_FIFO_FULL_OVERFLOW) ||\
                                  ((FLAG) == SPI_STATUS_RX_FIFO_EMPTY_OVERFLOW) || \
                                  ((FLAG) == SPI_STATUS_RX_FIFO_NOT_EMPTY) || \
                                  ((FLAG) == SPI_STATUS_CS_POS_FLG) || \
                                  ((FLAG) == SPI_STATUS_RX_FIFO_HALF_FULL) || \
                                  ((FLAG) == SPI_STATUS_RX_FIFO_HALF_EMPTY) || \
                                  ((FLAG) == SPI_STATUS_TX_FIFO_HALF_FULL) || \
                                  ((FLAG) == SPI_STATUS_TX_FIFO_HALF_EMPTY) || \
                                  ((FLAG) == SPI_STATUS_RX_FIFO_FULL) || \
                                  ((FLAG) == SPI_STATUS_RX_FIFO_EMPTY) || \
                                  ((FLAG) == SPI_STATUS_TX_FIFO_FULL) || \
                                  ((FLAG) == SPI_STATUS_TX_FIFO_EMPTY) ||\
                                  ((FLAG) == SPI_STATUS_BATCH_DONE)  ||\
                                  ((FLAG) == SPI_STATUS_TX_BUSY))
                                  
#define IS_SPI_CONFIG_IT(IT)  (((IT) <= BIT16))
#define IS_SPI_CLEAR_IT(IT)     (IS_SPI_CONFIG_IT(IT))
#define IS_SPI_GET_IT(IT)       (IS_SPI_CONFIG_IT(IT))
/**
  * @}
  */

/*  Function used to set the SPI configuration to the default reset state *****/ 
void SPI_DeInit(SPI_TypeDef* SPIx);

/* Initialization and Configuration functions *********************************/
void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct);
void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct);

void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState);

void SPI_Slave_SWCS_Config(SPI_TypeDef* SPIx, uint32_t Slave_SWCS_State);
void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState);

void SPI_ClearTxFifo(SPI_TypeDef* SPIx);
void SPI_ClearRxFifo(SPI_TypeDef* SPIx);
void SPI_DMA_RXFIFO_Level_Set(SPI_TypeDef* SPIx, uint32_t Fifo_level);
void SPI_DMA_TXFIFO_Level_Set(SPI_TypeDef* SPIx, uint32_t Fifo_level);

void SPI_WriteBatch(SPI_TypeDef* SPIx, uint32_t number);
uint32_t SPI_ReadBatch(SPI_TypeDef* SPIx);
void SPI_Wire_Config(SPI_TypeDef* SPIx, uint32_t X_Mode);
void SPI_Set_BaudRatePrescaler(SPI_TypeDef* SPIx, uint32_t  BaudRate_Prescaler);

void SPI_TxCmd(SPI_TypeDef* SPIx, FunctionalState NewState);
void SPI_RxCmd(SPI_TypeDef* SPIx, FunctionalState NewState);


/* Data transfers functions ***************************************************/ 
void SPI_SendData(SPI_TypeDef* SPIx, uint8_t Data);
uint8_t SPI_ReceiveData(SPI_TypeDef* SPIx);

/* DMA transfers management functions *****************************************/
void SPI_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_DMAReq, FunctionalState NewState);

/* Interrupts and flags management functions **********************************/
void SPI_ITConfig(SPI_TypeDef* SPIx, uint32_t SPI_IT, FunctionalState NewState);
FlagStatus SPI_ITGet(SPI_TypeDef* SPIx, uint32_t SPI_IT);
FlagStatus SPI_GetFlagStatus(SPI_TypeDef* SPIx, uint32_t SPI_FLAG);
void SPI_ClearFlag(SPI_TypeDef* SPIx, uint32_t SPI_FLAG);
ITStatus SPI_GetITStatus(SPI_TypeDef* SPIx, uint32_t SPI_IT);
void SPI_ClearITPendingBit(SPI_TypeDef* SPIx, uint32_t SPI_IT);



#ifdef __cplusplus
}
#endif

#endif  /* __SPL_SPI_H */

