#include "REG_MG84FL54.H"
#include "Define.H"
#include "Extern.H"
#include "SPI.H"


BYTE OutLen = 0;
XBYTE OutBuffer[SPI_MAX] _at_ (0x200-SPI_MAX);   // XRAM total 576(0~575) bytes ( 512~575
                                                 // for InBuffer , 448~511 for OutBuffer )

SPI Spi;


void SPI_Send_Data_To_PC( void )                 // Only for SLAVER Mode
  { if ( Spi.Mode == SPI_MASTER )
      return;
    
    if ( Spi.Data_Cnt == 0 )                     // Do Nothing
      return;

    AUXIE &= ~ESPI;                              // Disable " ISP INT " , prevent 
    if (( Spi.Out_Addr + Spi.Data_Cnt  ) > SPI_MAX ) // Spi.Data_Cnt Change
      OutLen = SPI_MAX - Spi.Out_Addr;           // OutBuffer boundary
    else
      OutLen = Spi.Data_Cnt;
    Spi.Data_Cnt -= OutLen;
    AUXIE |= ESPI;                               // Enable " ISP INT "
    
    USB_Send_Data_To_PC( OutLen , ( OutBuffer+Spi.Out_Addr ));
    Spi.Out_Addr += OutLen;
    OutLen = 0;
    
    if ( Spi.Out_Addr == SPI_MAX )               // Top of " OutBuffer "
      Spi.Out_Addr = 0;                          // Reset " Out_Addr " from 0
  }


void SPI_Send_Data_To_Device( BYTE Size , BYTE *Buffer )// Only for MASTER Mode
  { BYTE i = 0;
    
    
    if ( Spi.Mode == SPI_SLAVER )
      return;
    
    OutLen = 0;
    
    SPI_SS = CLR;                                // Select SLAVE device
    
    Size += 1;                                   // For read lasted data
    while( i < Size )
      { Spi.Tx_Busy = SET;
      	if ( i != ( Size - 1 ))
      	  SPDAT = Buffer[i];                     // Send data
      	else
      	  SPDAT = 0xFF;                          // Dummy Write for Read lasted data from SLAVER
      	while( Spi.Tx_Busy == SET );             // Wait Tx Complete
      	if ( i )
      	  { OutBuffer[OutLen] = SPDAT;
      	    OutLen++;
      	  }
      	i++;
      }
    
    SPI_SS = SET;                                // Release SLAVE device
  }


void Initial_SPI( void )
  { SPCTL = ( SPEN | SPR1 | SPR0 );              // MSB of data byte is transmitted first
    SPSTAT |= SPR2;                              // SPICKL = 125khz
    
    Spi.In_Addr = 0;
    Spi.Out_Addr = 0;
    Spi.Data_Cnt = 0;
    Spi.Tx_Busy = CLR;
    
#ifdef SPI_MASTER_MODE                           // Master Mode
    Spi.Mode = SPI_MASTER;
    SPCTL |= ( SSIG | MSTR );
#endif
#ifndef SPI_MASTER_MODE                          // Slaver Mode
    Spi.Mode = SPI_SLAVER;                       // /SS decides the device is Slaver or Master
#endif
                                                 // SPICLK is LOW when IDLE, Sample DATA on leading edge
    AUXIE |= ESPI;                               // Enable SPI int
  }