#include "periph_spis.h"

// #define CTRLR_CLEAR         (uint32_t)0x00000
// #define SER_CLEAR            0x1
// #define BAUDR_CLEAR          (uint16_t)0xffff
// //#define SPI_SLV_OE           (uint32_t)0x00400
// #define SPI_SS               0x1
// #define FIFO_Threshold_CLEAR (uint8_t)0xff
// #define CTRLR1_CLEAR         (uint16_t)0xffff

void SPIS_DeInit(void)
{
    SYS_CTRL->SYS_RESET |= (1 << 14);
    SYS_CTRL->SYS_RESET &= (~(1 << 14));
    *(volatile int *)(0x40000028) &= (~(1<<11));
}

void SPIS_Cmd(FunctionalState NewState)
{
    if (NewState != DISABLE)
    {
        /* Enable the selected SPI peripheral */
        SPIS0->SSIENR |= ENABLE;
    }
    else
    {
        /* Disable the selected SPI peripheral */
        SPIS0->SSIENR &= ~ENABLE;
    }
}

void SPIS_Init(SPIS_InitTypeDef* SPIS_InitStruct)
{
    uint32_t tmpreg = 0;
    // RCC
    *(volatile int *)(0x40000028) |= (1<<11);

    /* Configure SPIS0: direction, NSS management, first transmitted bit, BaudRate prescaler
    master/salve mode, CPOL and CPHA */
    /* Set BR bits according to SPI_BaudRatePrescaler value */
    /* Set CPOL bit according to SPI_CPOL value */
    /* Set CPHA bit according to SPI_CPHA value */
    tmpreg |= (SPIS_InitStruct->SPIS_Direction | SPIS_InitStruct->SPIS_SCPOL |   
               SPIS_InitStruct->SPIS_SCPH | SPIS_FRF_MOTOROLA_SPI | SPIS_DATA_SIZE_8BITS);
    /* Write to SPIS0 CTRLR0 */
    SPIS0->CTRLR0 = tmpreg;
    
    //Set number of wires
    tmpreg = SPIS0->SSIENR;
    tmpreg &= 0x1;
    tmpreg |= SPIS_InitStruct->SPIS_Wires;
    SPIS0->SSIENR = tmpreg;
    
    //Set TX FIFO Threshold level
    SPIS0->TXFTLR = SPIS_InitStruct->SPIS_TxFIFOThreshold;
    
    //Set RX FIFO Threshold level
    SPIS0->RXFTLR = SPIS_InitStruct->SPIS_RxFIFOThreshold;
    
	SPIS0->IMR = 0x0;
}

void SPIS_StructInit(SPIS_InitTypeDef* SPIS_InitStruct)
{
    SPIS_InitStruct->SPIS_Direction = SPIS_DIRECTION_TX_AND_RX;  
    SPIS_InitStruct->SPIS_SCPOL = SPIS_SCPOL_LOW;
    SPIS_InitStruct->SPIS_SCPH = SPIS_SCPH_MIDDLE;
    SPIS_InitStruct->SPIS_RxFIFOThreshold = 0x08;
    SPIS_InitStruct->SPIS_TxFIFOThreshold = 0x08;
    SPIS_InitStruct->SPIS_Wires = SPIS_WIRES_4;
}

void SPIS_SendData(uint8_t Data)
{
    /* Write in the DR16 register the data to be sent */
    //while(SPIS_GetFlagStatus(SPI_Transmit_FIFO_Not_Full) == RESET);
    //if(SPIS_GetFlagStatus(SPI_Transmit_FIFO_Not_Full) != RESET)
    //{
    SPIS0->DR16 = Data;
    //}
}


uint8_t SPIS_ReceiveData(void)
{
    /* Return the data in the DR16 register */
    return SPIS0->DR16;
}


void SPIS_DataSizeConfig(uint32_t SPI_DataSize)
{
    /* Clear  bit */
    SPIS0->CTRLR0 &= (uint32_t)(~0xF);
    /* Set new  bit value */
    SPIS0->CTRLR0 |= SPI_DataSize;
}

FlagStatus SPIS_GetUsrStatus(uint8_t Flag)
{
    FlagStatus bitstatus = RESET;

    /* Check the status of the specified SPI flag */
    if ((SPIS0->SR & Flag) != RESET)
    {
        /* SPI_FLAG is set */
        bitstatus = SET;
    }
    else
    {
        /* SPI_FLAG is reset */
        bitstatus = RESET;
    }
    /* Return the SPI_FLAG status */
    return  bitstatus;
}

void SPIS_ITConfig(uint8_t SPIS_IT, FunctionalState NewState)
{
    if (NewState != DISABLE)
    {
        /* Enable the selected SPI interrupt */
        SPIS0->IMR |= SPIS_IT;
    }
    else
    {
        /* Disable the selected SPI interrupt */
        SPIS0->IMR &= ~SPIS_IT;
    }
}

ITStatus SPIS_GetITStatus(uint8_t SPIS_IT)
{
    ITStatus bitstatus = RESET;
    uint8_t itpos = 0;

    itpos = SPIS0->ISR & SPIS_IT;
    /* Check the status of the specified SPI interrupt */
    if (itpos != RESET)
    {
        /* SPI_IT is set */
        bitstatus = SET;
    }
    else
    {
        /* SPI_IT is reset */
        bitstatus = RESET;
    }
    /* Return the SPI_IT status */
    return bitstatus;
}

void SPIS_Direction_Switch(uint32_t SPIS_Direction)
{
    //change spi direction
    /* Clear  bit */
    SPIS0->CTRLR0 &= (uint32_t)(~0x700);
    /* Set new  bit value */
    SPIS0->CTRLR0 |= SPIS_Direction;
}

