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


extern BYTE OutLen;
extern XBYTE OutBuffer[TWSI_MAX];

extern TWSI Twsi;


void INT_TWSI(void) interrupt 14 using 2
  { switch( SISTA )
      { case 0x08: Twsi.RetryCnt = 0;
      	case 0x10: Twsi.Stage = TWSI_START;      // Repeat Start
                   STA = CLR;
                   SIDAT = Twsi.Dev;             // Assign " SLAVE " address
                   SI = CLR;
                   break;
      	case 0x18:                               // SLA+W has been transmited ( ACK received )
      	case 0x28: if ( Twsi.InIndex != InLen )  // DATA has been transmited ( ACK received )
      	             { SIDAT = InBuffer[Twsi.InIndex];
      	               Twsi.InIndex++;
      	               SI = CLR;
      	             }
      	           else
      	             { STO = SET;                // Generate a STOP
      	               SI = CLR;
      	               while( STO );             // Wait STOP complete
      	               Twsi.Stage = TWSI_STOP;
      	             }
      	           break;
      	case 0x20:                               // SLA+W has been transmited ( Device NO ACK )
      	case 0x30: if ( Twsi.RetryCnt >= RETRY_MAX )
      	             { STO = SET;                // DATA has been transmited ( Device NO ACK )
      	               SI = CLR;
      	               while( STO );             // Wait STOP complete
      	               Twsi.Stage = TWSI_ERROR;
      	             }
      	           else
      	             { STA = SET;                // Retry
      	               SI = CLR;
      	               Twsi.RetryCnt++;
      	             }
      	           break;
      	case 0x38: STA = SET;                    // Arbitration Error , Generate a START
      	           SI = CLR;
      	           break;
      	case 0x40: if ( Twsi.InIndex == ( InLen - 1 ))
      	             AA = CLR;                   // Last DATA ,Will return NO ACK to Device
      	           SI = CLR;                     // SLA+R has been transmited ( ACK received )
      	           break;
      	case 0x50: InBuffer[Twsi.InIndex] = SIDAT;// DATA has been Received ( Return ACK )
      	           Twsi.InIndex++;
      	           if ( Twsi.InIndex == ( InLen - 1 ))
      	             AA = CLR;                   // Last DATA ,Will return NO ACK to Device
      	           SI = CLR;
      	           break;
      	case 0x48: if ( Twsi.RetryCnt >= RETRY_MAX )
      	             { STO = SET;                // SLA+R has been transmited ( Device NO ACK )
      	               SI = CLR;
      	               while( STO );
      	               Twsi.Stage = TWSI_ERROR;
      	             }
      	           else
      	             { STA = SET;                // Retry
      	               SI = CLR;
      	               Twsi.RetryCnt++;
      	             }
      	           break;
      	case 0x58: InBuffer[Twsi.InIndex] = SIDAT;// DATA has been Received ( Return ACK )
      	           Twsi.InIndex++;
      	           AA = SET;                     // DATA has been Received ( Return NO ACK )
      	           STO = SET;
      	           SI = CLR;
      	           while( STO );                 // Wait STOP complete
      	           Twsi.Stage = TWSI_STOP;
      	           break;
      	                                         // Slaver Transmitter
      	case 0xB0: STA = SET;                    // Arbitation lost " Reset STA "
      	case 0xA8: Twsi.OutIndex = 0;            // Own SLA+R has been Received ( Return ACK )
      	case 0xB8: SIDAT = OutBuffer[Twsi.OutIndex];// DATA has been transmited ( ACK received )
      	           Twsi.OutIndex++;
      	           if ( Twsi.OutIndex == TWSI_MAX )
      	             Twsi.OutIndex = 0;
      	           SI = CLR;
      	           break;
      	case 0xC0: SI = CLR;                     // Enter NAslave
      	           break;
      	                                         // Slaver Receiver
      	case 0x68: STA = SET;                    // Arbitation lost " Reset STA "
      	case 0x60: Twsi.OutIndex = 0;            // Own SLA+W has been Received ( Return ACK )
      	           SI = CLR;
      	           break;
      	case 0x80: OutBuffer[Twsi.OutIndex] = SIDAT;// DATA has been Received ( Return ACK )
      	           Twsi.OutIndex++;
      	           if ( Twsi.OutIndex == TWSI_MAX )
      	             Twsi.OutIndex = 0;
      	           SI = CLR;
      	           break;
      	case 0xA0: OutLen = Twsi.OutIndex;
      	           if ( OutLen == 0 )
      	             OutLen = TWSI_MAX;
      	           AUXIE &= ~ETWSI;              // Disable TWSI int for " TWSI_Send_Data_To_PC "
      	           SI = CLR;                     // Enter NAslave
      	           break;
      	
      	default:   STO = SET;                    // Bus Error
      	           SI = CLR;
      	           while( STO );                 // Wait STOP complete
      	           Twsi.Stage = TWSI_ERROR;
      	           break;
      }
  }