#include "OB90A64U1.h"
#include "I2S.h"
#include <stdio.h>

volatile uint32_t g_I2SInterrupt = 0x00;
void I2S_IRQHandler(void)
{
    g_I2SInterrupt++;
    OB_I2S->IESTC = OB_I2S->IEST; //Clear state
}


/**
  * @brief  This function configures some parameters of I2S interface for general purpose use.
  * @param[in] i2s The pointer of the specified I2S module.
  * @param[in] MasterSlave I2S operation mode. Valid values are:
  *                                     - \ref I2S_MODE_MASTER
  *                                     - \ref I2S_MODE_SLAVE
  * @param[in] SampleRate Sample rate
  * @param[in] WordWidth Data length. Valid values are:
  *                                     - \ref I2S_WIDTH_8BIT
  *                                     - \ref I2S_WIDTH_16BIT
  *                                     - \ref I2S_WIDTH_24BIT
  *                                     - \ref I2S_WIDTH_32BIT
  * @param[in] AudioFormat format. Valid values are:
  *                                     - \ref I2S_MONO_STEREO
  *                                     - \ref I2S_MONO_MONO
  * @param[in] DataFormat Data format. Valid values are:
  *                                     - \ref I2S_FORMAT_I2S
  *                                     - \ref I2S_FORMAT_MSB
  *                                     - \ref I2S_FORMAT_PCM_A
  *                                     - \ref I2S_FORMAT_PCM_B
  */
uint32_t I2S_Open(OB_I2S_Type *pI2S, uint32_t MasterSlave, uint32_t SampleRate, uint32_t WordWidth, uint32_t AudioFormat, uint32_t DataFormat)
{
    pI2S->CON = 0x00;

    /* Configure I2S controller according to input parameters. */
    pI2S->CON_b.SLAVE = MasterSlave;
    pI2S->CON_b.WIDTH = WordWidth;
    pI2S->CON_b.MONO = AudioFormat;
    pI2S->CON_b.RXLEV = I2S_RXLEV_4;
    pI2S->CON_b.TXLEV = I2S_TXLEV_4;
    if(DataFormat == I2S_FORMAT_MSB)
        pI2S->CON_b.FORNAT = 1;
    else if(DataFormat == I2S_FORMAT_PCM_A)
    {
        pI2S->CON_b.PCM = 1;
        pI2S->CON_b.FORNAT = 0;
    }
    else if(DataFormat == I2S_FORMAT_PCM_B)
    {
        pI2S->CON_b.PCM = 1;
        pI2S->CON_b.FORNAT = 1;
    }
    /* Calculate bit clock rate */
    pI2S->CDIV_b.CLK_DIV = (SystemCoreClock / (2 * SampleRate)) - 1;
    /* Calculate real sample rate */
    SampleRate =  SystemCoreClock/ (2 *(pI2S->CDIV_b.CLK_DIV + 1));

    /* Enable TX, RX and I2S controller */
    pI2S->CON_b.RX = 1;
    pI2S->CON_b.TX = 1;
    pI2S->CON_b.EN = 1;

    return SampleRate;
}

/**
  * @brief  Disable I2S function.
  * @param[in]  i2s The pointer of the specified I2S module.
  * @return None
  * @details Disable I2S function.
  */
void I2S_Close(OB_I2S_Type *pI2S)
{
    pI2S->CON_b.EN = 0;
}

void I2S_Enable(OB_I2S_Type *pI2S)
{
    pI2S->CON_b.EN = 1;
}

/**
  * @brief Enable interrupt function.
  * @param[in] i2s The pointer of the specified I2S module.
  * @param[in] InterruptEvent The combination of all related interrupt enable bits.
  *            Each bit corresponds to a interrupt bit. Valid values are:
  *            - \ref I2S_IE_RXUNIE
  *            - \ref I2S_IE_RXOVIE
  *            - \ref I2S_IE_RXTHIE
  *            - \ref I2S_IE_TXUNIE
  *            - \ref I2S_IE_TXOVIE
  *            - \ref I2S_IE_TXTHIE
  *            - \ref I2S_IE_RZCIE
  *            - \ref I2S_IE_LZCIE
  *            - \ref I2S_IE_WDUDIE
  *            - \ref I2S_IE_WDOVIE
  */

void I2S_EnableInt(OB_I2S_Type *pI2S,  uint32_t InterruptEvent)
{
    pI2S->IEENS = InterruptEvent;
}

void I2S_DisableInt(OB_I2S_Type *pI2S,  uint32_t InterruptEvent)
{
    pI2S->IEENC = InterruptEvent;
}


uint32_t I2S_EnableMCLK(OB_I2S_Type *pI2S, uint32_t MclkClock)
{
    uint32_t nClock;
    nClock = SystemCoreClock / 2;

    if(nClock > SystemCoreClock)
    {
        pI2S->CDIV_b.MCLK = 0;
        nClock = SystemCoreClock;
    }
    else
    {
        pI2S->CDIV_b.MCLK = SystemCoreClock/ (2 * MclkClock);
        nClock = SystemCoreClock/ (2 * pI2S->CDIV_b.MCLK);
    }
    pI2S->CON_b.MCLK = 1;
    return nClock;
}


uint32_t I2S_DisableMCLK(OB_I2S_Type *pI2S)
{
    pI2S->CON_b.MCLK = 0;
    return 0;
}

