#include "OB90A64U1.h"
#include "spi.h"
#include "math.h"

volatile uint32_t g_SPIRxCounter = 0x00;
volatile uint32_t g_SPIRxData[SPI_RX_SiZE];

void SPI0_IRQHandler(void)
{
    if ((OB_SPI0->SR & 0x04) == 0x04)
    {
        g_SPIRxData[g_SPIRxCounter] = OB_SPI0->DR;
        g_SPIRxCounter++;
        OB_SPI0->ICR = SPI_INT_RTIM;
    }
}

void SPI1_IRQHandler(void)
{
    if ((OB_SPI1->SR & 0x04) == 0x04)
    {
        g_SPIRxData[g_SPIRxCounter] = OB_SPI1->DR;
        g_SPIRxCounter++;
        OB_SPI1->ICR = SPI_INT_RTIM;
    }
}

void SPI2_IRQHandler(void)
{
    if ((OB_SPI2->SR & 0x04) == 0x04)
    {
        g_SPIRxData[g_SPIRxCounter] = OB_SPI2->DR;
        g_SPIRxCounter++;
        OB_SPI2->ICR = SPI_INT_RTIM;
    }
}
uint32_t SPI_MasterOpen(OB_SPI_Type *pSPI, uint32_t nSPICapability, uint32_t Length, uint32_t nBusClock)
{
    if(pSPI == OB_SPI0)
        NVIC_EnableIRQ(SPI0_IRQn);
    else if(pSPI == OB_SPI1)
        NVIC_EnableIRQ(SPI1_IRQn);
    else if(pSPI == OB_SPI2)
        NVIC_EnableIRQ(SPI2_IRQn);


    pSPI->CR0 = nSPICapability;
    pSPI->DLR = Length | SPI_FIRST_MSB | SPI_CAPTURE_DELAY_2;
    pSPI->CR1_b.MS   = 0; // Master Mode
    pSPI->CR1_b.SSNP = 1; // Slave Hardware Control
    pSPI->CR1_b.SSE  = 1; // SPI Enable

    return (SPI_SetBusClock(pSPI, nBusClock) );
}

void SPI_Close(OB_SPI_Type *pSPI)
{
    pSPI->CR1_b.SSE =  0;  // SPI Disable
}

void SPI_EnableINT(OB_SPI_Type *pSPI, uint32_t nINTSel)
{
    pSPI->IMSC |= nINTSel;
}

void SPI_DisableINT(OB_SPI_Type *pSPI, uint32_t nINTSel)
{
    pSPI->IMSC &= (~nINTSel);

}

void SPI_ClearRxFIFO(OB_SPI_Type *pSPI)
{
    volatile uint32_t Buff;
    while(1)
    {
        if ((pSPI->SR & 0x04) != 0x00)
            Buff = pSPI->DR;
    }
}

void SPI_ClearTxFIFO(OB_SPI_Type *pSPI)
{
    while(1)
    {
        if ((pSPI->SR & 0x01) == 0x01)
            break;
    }
}

uint32_t SPI_SetBusClock(OB_SPI_Type *pSPI, uint32_t nBusClock)
{
    uint32_t nClock;
    nClock = SystemCoreClock / nBusClock;
    if(nClock <= 255)
    {
        pSPI->CPSR = 0x00;
        pSPI->CR0_b.SCR = nClock - 1;
    }
    else
    {
        nClock = sqrt(nClock);
        pSPI->CR0_b.SCR = nClock - 2;
        pSPI->CPSR = nClock - 1;
    }
    return SPI_GetBusClock(pSPI);
}

uint32_t SPI_GetBusClock(OB_SPI_Type *pSPI)
{
    uint32_t nClock, nSCR;

    if(pSPI->CPSR == 0x00)
    {
        nSCR   = pSPI->CR0_b.SCR ;
        nClock = SystemCoreClock /(nSCR + 1);
    }
    else
    {
        nSCR   = pSPI->CR0_b.SCR ;
        nClock = SystemCoreClock /((pSPI->CPSR + 2) * (nSCR + 1));
    }
    return nClock;
}


