#include "def.h"
#include "val.h"
#include "dfu.h"
#include "usb.h"


//-----USB.C-----//
extern EP0INFO Ep0;


idata DFU Dfu;


void Initial_DFU( void )
  { Dfu.Stage = DFU_IDLE;
    Dfu.Addr.DW = 0;
    Dfu.Size.DW = 0;
  }


BYTE DFU_ISP_RW( BYTE Func , BYTE Data )
  { IFADRH = Dfu.Addr.B[2];
    IFADRL = Dfu.Addr.B[3];
    
    if ( Func == ISP_BYTE_WRITE )
      IFD = Data;
      
    ISPCR = ( Func | ISP_ENABLE );
    SCMD = ISP_ACTIVITY_CMD1;
    SCMD = ISP_ACTIVITY_CMD2;
    ISPCR = ISP_DISABLE;
    
    if ( Func == ISP_BYTE_READ )
      return IFD;
    else
      return CLR;
  }


void DFU_Read( void )
  { if ( Dfu.Stage == DFU_RD_STAGE )
      { Dfu.CheckSum.W += Dfu.CheckSumFlg;
      	Ep0.RxTx[0] = Dfu.CheckSum.B[0];
        Ep0.RxTx[1] = Dfu.CheckSum.B[1];
      }
    else if ( Dfu.Stage == DFU_FW_VER )
      { Ep0.RxTx[0] = FW_MSB;
        Ep0.RxTx[1] = FW_LSB;
      }
    Dfu.Stage = DFU_IDLE;
  }


void DFU_Write( BYTE Cnt )
  { BYTE i;
    BYTE Tmp;
    
    
    if ( Dfu.Stage == DFU_IDLE )
      { Dfu.Stage = Ep0.RxTx[0];
        Dfu.Addr.B[1] = Ep0.RxTx[1];
        Dfu.Addr.B[2] = Ep0.RxTx[2];
        Dfu.Addr.B[3] = Ep0.RxTx[3];
        Dfu.Size.B[1] = Ep0.RxTx[4];
        Dfu.Size.B[2] = Ep0.RxTx[5];
        Dfu.Size.B[3] = Ep0.RxTx[6];
        if ( Dfu.Stage == DFU_WR_STAGE )
          { Dfu.CheckSum.W = 0;
            Dfu.CheckSumFlg = 0;
          }
      }
    else
      { if ( Dfu.Size.DW <= Cnt )
      	  { Cnt = Dfu.Size.B[3];
      	    Dfu.Stage = DFU_IDLE;
      	  }
      	
      	Dfu.Size.DW -= Cnt;
      	
      	if (( Dfu.Addr.B[3] == 0x00 )&&(( Dfu.Addr.B[2] & 0x01 ) == 0x00 ))
          DFU_ISP_RW( ISP_PAGE_ERASE , CLR );
      	
      	i = 0;
      	while( i<Cnt )
      	  { DFU_ISP_RW( ISP_BYTE_WRITE , Ep0.RxTx[i] );
            Tmp = DFU_ISP_RW( ISP_BYTE_READ , CLR );
            if ( Tmp != Ep0.RxTx[i] )
              Dfu.CheckSumFlg = 1;
      	    Dfu.CheckSum.W += Ep0.RxTx[i];       // Caculate the CheckSum
            Dfu.Addr.DW++;
      	    i++;
      	  }
      }
  }