#include "OB6628P.h"
#include "spi.h"
#include "math.h"

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

void SPI_IRQHandler(void)
{
    if ((OB_SPI->SR & 0x04) == 0x04)
    {
        g_SPIRxData[g_SPIRxCounter] = OB_SPI->DR;
        g_SPIRxCounter++;

        OB_SPI->ICR = SPI_INT_RTIM;
    }
}

uint32_t SPI_MasterOpen(OB_SPI_Type *pSPI, uint32_t nSPICapability, uint32_t nBusClock)
{
    NVIC_EnableIRQ(SPI_IRQn);

    pSPI->CR0 = nSPICapability;

    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 = GetPeripheralClock();
    nClock = nClock / nBusClock;
    nClock = sqrt(nClock);
    pSPI->CR0 = (pSPI->CR0 & 0xFFFF00FF) | (nClock << 8);
    pSPI->CPSR = nClock;

    return SPI_GetBusClock(pSPI);
}

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

    nClock = GetPeripheralClock();
    nSCR   = (pSPI->CR0 >> 0x08) & 0xFF;
    nClock = nClock /(pSPI->CPSR * (nSCR + 1));
    return nClock;
}


