#ifndef __BSP_SPI_H
#define __BSP_SPI_H

#include "spl_spi.h"


/*
 * @brief  SPI Status structures definition
 */
typedef enum
{
    SPI_OK       = 0x00U,
    SPI_ERROR    = 0x01U,
    SPI_BUSY     = 0x02U,
    SPI_TIMEOUT  = 0x03U
}SPI_StatusTypeDef;

typedef struct
{ 
    uint32_t               RxState;          /* SPI state machine */
    uint32_t               TxState;          /* SPI state machine */
    
    uint8_t               *Rx_Buffer;        /* SPI Rx Buffer */
    uint8_t               *Tx_Buffer;        /* SPI Tx Buffer */
    
    uint32_t               Rx_Size;          /* SPI Rx Size */
    uint32_t               Tx_Size;          /* SPI Tx Size */
    
    uint32_t               Rx_Count;         /* SPI RX Count */
    uint32_t               Tx_Count;         /* SPI TX Count */
}SPI_Handler_t;


/** @defgroup SLAVE State machine
 *  @{
 */
#define    SPI_RX_STATE_IDLE         (0U)
#define    SPI_RX_STATE_RECEIVING    (1U)
#define    SPI_TX_STATE_IDLE         (0U)
#define    SPI_TX_STATE_SENDING      (1U)
/**
  * @}
  */



uint8_t SPI_GetTxState(void);
uint8_t SPI_GetRxState(void);
void SPI_IRQHandler(SPI_TypeDef* SPIx, SPI_Handler_t* hspi);

uint32_t SPI_Master_Receive(SPI_TypeDef* SPIx, uint8_t *pData, uint32_t Size, uint32_t Timeout);
uint32_t SPI_Master_Transmit(SPI_TypeDef* SPIx, uint8_t *Buf, uint32_t Size, uint32_t Timeout);
uint32_t SPI_Slave_Receive(SPI_TypeDef* SPIx, uint8_t *Buf, uint32_t Size, uint32_t Timeout);
uint32_t SPI_Slave_Transmit(SPI_TypeDef* SPIx, uint8_t *Buf, uint32_t Size, uint32_t Timeout);

SPI_StatusTypeDef SPI_Master_Transmit_IT(SPI_TypeDef* SPIx, SPI_Handler_t* hspi, uint8_t *pData, uint32_t Size);
SPI_StatusTypeDef SPI_Master_Receive_IT(SPI_TypeDef* SPIx, SPI_Handler_t* hspi, uint8_t *pData, uint32_t Size);
SPI_StatusTypeDef SPI_Slave_Transmit_IT(SPI_TypeDef* SPIx, SPI_Handler_t* hspi, uint8_t *pData, uint32_t Size);
SPI_StatusTypeDef SPI_Slave_Receive_IT(SPI_TypeDef* SPIx, SPI_Handler_t* hspi, uint8_t *pData, uint32_t Size);

SPI_StatusTypeDef SPI_Master_TransmitReceive(SPI_TypeDef* SPIx, uint8_t *pTxData, uint8_t *pRxData, uint32_t Size, uint32_t Timeout);
SPI_StatusTypeDef SPI_Slave_TransmitReceive(SPI_TypeDef* SPIx, uint8_t *pTxData, uint8_t *pRxData, uint32_t Size, uint32_t Timeout);


#endif  /* __BSP_SPI_H */
