/*!
 * @file       apm32f10x_spi.h
 *
 * @brief      This file contains all the functions prototypes for the SPI firmware library
 *
 * @details    
 *
 * @version        V1.0.0
 *
 * @date       2019-8-6
 *
 */

#ifndef __APM32F10x_SPI_H
#define __APM32F10x_SPI_H

#ifdef __cplusplus
extern "C" {
#endif

#include "apm32f10x.h"

typedef enum
{
    SPI_DERECTION_2LINES_FULLDUPLEX = 0x0000,
    SPI_DERECTION_2LINES_RXONLY = 0x0400,
    SPI_DERECTION_1LINE_RX = 0x8000,
    SPI_DERECTION_1LINE_TX = 0xC000
}SPI_DIRECTION_T;

/**
 * @brief    Configuration Mode enumeration
 */
typedef enum
{
    SPI_MODE_MASTER = 0x0104,
    SPI_MODE_SLAVE = 0x0000
}SPI_MODE_T;

/**
 * @brief    SPI Data size
 */
typedef enum
{
    SPI_DATASIZE_16B = 0x0800,
    SPI_DATASIZE_8B = 0x0000
}SPI_DATASIZE_T;

/**
 * @brief    SPI Clock Polarity
 */
typedef enum
{
    SPI_CPOL_LOW = 0x0000,
    SPI_CPOL_HIGH = 0x0002
}SPI_CPOL_T;

/**
 * @brief    SPI Clock Phase
 */
typedef enum
{
    SPI_CPHA_1EDGE = 0x0000,
    SPI_CPHA_2EDGE = 0x0001
}SPI_CPHA_T;

/**
 * @brief    SPI Slave Select management
 */
typedef enum
{
    SPI_NSS_SOFT = 0x0200,
    SPI_NSS_HARD = 0x0000
}SPI_NSS_T;

/**
 * @brief    SPI BaudRate Prescaler
 */
typedef enum
{
    SPI_BAUDRATE_PRESCALER_2 = 0x0000,
    SPI_BAUDRATE_PRESCALER_4 = 0x0008,
    SPI_BAUDRATE_PRESCALER_8 = 0x0010,
    SPI_BAUDRATE_PRESCALER_16 = 0x0018,
    SPI_BAUDRATE_PRESCALER_32 = 0x0020,
    SPI_BAUDRATE_PRESCALER_64 = 0x0028,
    SPI_BAUDRATE_PRESCALER_128 = 0x0039,
    SPI_BAUDRATE_PRESCALER_256 = 0x0038,
}SPI_BAUDRATE_PRESCALER_T;

/**
 * @brief    SPI MSB LSB transmission
 */
typedef enum
{
    SPI_FIRSTBIT_MSB = 0x0000,
    SPI_FIRSTBIT_LSB = 0x0080
}SPI_FIRSTBIT_T;

/**
 * @brief    SPI Config structure definition
 */
typedef struct
{
    uint16_t direction;
    uint16_t mode;
    uint16_t dataSize;
    uint16_t cpol;
    uint16_t cpha;
    uint16_t nss;
    uint16_t baudRatePrescaler;
    uint16_t firstBit;
    uint16_t crcPolynomial;
}SPI_ConfigStruct_T;

/**
 * @brief    SPI Direction select
 */
typedef enum
{
    SPI_DIRECTION_RX = 0xBFFF,
    SPI_DIRECTION_TX = 0x4000
}SPI_DIRECTION_SELECT_T;

/**
 * @brief    SPI interrupts definition
 */
typedef enum
{
    SPI_INT_TXE = 0x71,
    SPI_INT_RXNE = 0x60,
    SPI_INT_ERR = 0x50,
    SPI_INT_OVR = 0x56,
    SPI_INT_MODF = 0x55,
    SPI_INT_CRCERR = 0x54
}SPI_INT_T;

/**
 * @brief    SPI flags definition
 */
typedef enum
{
    SPI_FLAG_RXNE = 0x0001,
    SPI_FLAG_TXE = 0x0002,
    SPI_FLAG_CRCERR = 0x0010,
    SPI_FLAG_MODF = 0x0020,
    SPI_FLAG_OVR = 0x0040,
    SPI_FLAG_BSY = 0x0080
}SPI_FLAG_T;

/*  Function used to set the SPI configuration to the default reset state *****/
void SPI_Reset(SPI_T* spi);
/* Configuration functions **********************************************************/
void SPI_Config(SPI_T* spi, SPI_ConfigStruct_T* configStruct);
void SPI_StructInit(SPI_ConfigStruct_T* configStruct);
void SPI_Enable(SPI_T* spi);
void SPI_Disable(SPI_T* spi);
void SPI_NSSInternalSoftwareSet(SPI_T* spi);
void SPI_NSSInternalSoftwareReset(SPI_T* spi);
void SPI_SSOutputEnable(SPI_T* spi);
void SPI_SSOutputDisable(SPI_T* spi);
void SPI_DataSizeConfig(SPI_T* spi, uint16_t dataSize);
void SPI_TransmitCRC_Enable(SPI_T* spi);
void SPI_CalculateCRC_Enable(SPI_T* spi);
void SPI_CalculateCRC_Disable(SPI_T* spi);
uint16_t SPI_ReadCRC_TX(SPI_T* spi);
uint16_t SPI_ReadCRC_RX(SPI_T* spi);
uint16_t SPI_ReadCRCPolynomial(SPI_T* spi);
void SPI_BiDirectionalLineConfig(SPI_T* spi, uint16_t direction);
#ifdef __cplusplus
}
#endif

#endif /* __APM32F10x_SPI_H */
