#include "mcbsp.h"
#include "main.h"
#include "evmc6748.h"
/*-------PINMUX-------*/
#define PINMUX_MCBSP1_REG       (1)
#define PINMUX_MCBSP1_MASK      (0x0F0F0F00)
#define PINMUX_MCBSP1_VAL       (0x02020200)


#define FPER_shift 16
#define CLKSM_shift 29
#define FSGM_shift 28
#define CLKGDV_shift 0
#define FWID_shift 8
#define XFRLEN1_shift 8
#define NULL 0

#define CLKSM_INTERNAL 1<<29
#define FSGM_DXR2XSR 0 << 28
#define FSGM_FSG 1 << 28

extern int i;

uint32_t MCBSP_init (McbspRegs *mcbsp, uint8_t CLKGDV,uint8_t FPER, uint8_t FWID, uint8_t xferlen)
{
	uint32_t rtn = ERR_INVALID_PARAMETER;
if (mcbsp==MCBSP1)
{
	EVMC6748_lpscTransition(PSC1, DOMAIN0, LPSC_MCBSP1, PSC_ENABLE);
	EVMC6748_pinmuxConfig( PINMUX_MCBSP1_REG,  PINMUX_MCBSP1_MASK,  PINMUX_MCBSP1_VAL);
	}

//reset mcbsp registers
mcbsp->SPCR=0;//hold Tx and Rx parts in reset
mcbsp->XCR=0;
mcbsp->SRGR=0;
mcbsp->PCR=0;

mcbsp->MCR=0;

mcbsp->RCERE0=0;
mcbsp->RCERE1=0;
mcbsp->RCERE2=0;
mcbsp->RCERE3=0;

mcbsp->XCERE0=0;
mcbsp->XCERE1=0;
mcbsp->XCERE2=0;
mcbsp->XCERE3=0;


SETBIT(mcbsp->SRGR,
		(CLKGDV-1) <<CLKGDV_shift | //
		(FPER-1) <<FPER_shift | //
		(FWID-1) <<FWID_shift | //
		MCBSP_SRGR_CLKSM | //internal input clock
		FSGM_FSG | //
		MCBSP_SRGR_CLKSP); //Falling edge of CLKS generates CLKG and FSG.

SETBIT(mcbsp->PCR,MCBSP_PCR_FSXP| MCBSP_PCR_CLKXM | MCBSP_PCR_FSXM);

SETBIT(mcbsp->XCR,XCR_XFIG_IGNORE |XCR_XDATDLY_1bit);//word length 8 bits |5 words in phase 1 | 1-bit data delay |Single-phase frame.

SETBIT(mcbsp->XCR,XCR_XFRLEN1_5word);
for (i=0; i<5; i++) {;}

SETBIT(mcbsp->SPCR,MCBSP_SPCR_GRST);// enable bit clk generator

for (i=0; i<20; i++) {;} // wait for GRST

SETBIT(mcbsp->SPCR,MCBSP_SPCR_XRST);// take Tx portion out of reset
for (i=0; i<5; i++) {;} //wait to check Transmit synchronization error

if (CHKBIT(mcbsp->SPCR,MCBSP_SPCR_XSYNCERR))// if XSYNCERR occured
	CLRBIT(mcbsp->SPCR,MCBSP_SPCR_XRST); // reset transmitter to clear the error

if (!CHKBIT(mcbsp->SPCR,MCBSP_SPCR_XRST))
SETBIT(mcbsp->SPCR,MCBSP_SPCR_XRST);// enable transmitter if it was reset by XSYNCERR

while (!CHKBIT(mcbsp->SPCR,MCBSP_SPCR_XRDY)) {;} //wait for XRDY
SETBIT(mcbsp->SPCR,MCBSP_SPCR_FRST);// enable frame sync generator


return (rtn);
}



uint32_t MCBSP_write(McbspRegs *mcbsp, int8_t *src_buffer, int16_t in_length)
{
   uint32_t rtn = ERR_INVALID_PARAMETER;

   if ((mcbsp != NULL) && (src_buffer != NULL))
   {
      uint32_t i;
      uint32_t mcbsp_DXR = mcbsp->DXR;
      
      // transmit data one byte at a time, copy receive data into input buffer.
      for (i = 0; i < in_length; i++)
      {
         // wait for tx buffer to be empty.
         if (CHKBIT (mcbsp->SPCR,MCBSP_SPCR_XRDY)){
           mcbsp_DXR=*src_buffer;
               src_buffer++;                  
         
         // copy the tmp reg to the real thing.
         mcbsp->DXR = mcbsp_DXR;
         }
         
         }
      
      rtn = ERR_NO_ERROR;
   }

   return (rtn);
}



