/****************************************************************************
 *  F i l e   D a t a                                                        
 *  $Id: TRK_Driver_INFN.c,v 1.4 2003/10/30 14:55:52 faber Exp $
 *  $Revision: 1.4 $
 *  $Date: 2003/10/30 14:55:52 $
 *  $RCSfile: TRK_Driver_INFN.c,v $
 *                                                                           
 ****************************************************************************
 *  S W   D e v e l o p m e n t   E n v i r o n m e n t                      
 *                                                                           
 *  $Author: faber $
 *               :                                                           
 ****************************************************************************
 *  U p d a t i n g                                                          

 *  $Log: TRK_Driver_INFN.c,v $
 *  Revision 1.4  2003/10/30 14:55:52  faber
 *  CRC function debuggin (some fixes)
 *
 *  Revision 1.3  2003/10/27 18:59:38  sebastiani
 *  CRC moved into Commong module
 *
 *  Revision 1.2  2003/10/22 12:47:06  faber
 *  *** empty log message ***
 *
 *                                                                           
 *****************************************************************************/


/*============================= Include File ================================*/

#ifndef I386
#include <src/INFN/LU_SourceFileID_INFN.h>
#define __FILEID__ _TRK_Driver_INFN__c
#include <src/INFN/PRH_ParamHandler_INFN.h>
#include <src/INFN/LU_LogUtility_INFN.h>
#include <src/INFN/PRH_ParamHandler_INFN_auto.h>
LU_DECL_MASK();
#endif // no I386


#include <src/INFN/DAQ_IDAQ_INFN.h>
#include <src/INFN/CM_Common_INFN.h>
#include <src/INFN/Drivers/TRK_Driver_INFN.h>

#ifndef I386
#include <src/INFN/CH_CommandHandler_INFN.h>
#include <src/INFN/TRG_Trigger_INFN.h>
#include <src/INFN/RM_RunManager_INFN.h>
#endif

/*============================ External define ================================*/

/*============================ Global define ================================*/


DAQ_DECLBUF(TRK_TempBuf,TRK_MAXTEMPBUFFER);


/*============================== global types  ==============================*/





/*=========================== Structure define ==============================*/


/*============================ Enumerate define =============================*/



status_code TRK_Driver_Init() 
{
  DAQ_BUFFER_INIT(TRK_TempBuf);
  return CM_RC_SUCCESSFUL;
}



/*****************************************************************************/
/*  
 *  TRK_Format_Cmd
 *
 *  format the command for the FE when there is no data block to write     
 *
 *  Input parameters: 
 *                   periph_no  = peripheral number 
 *                   command_no = command number   
 *                   febuf      = pointer to the buffer to fill 
 *                 
 *  Output parameters: status_code
 *
 */
/*****************************************************************************/

status_code TRK_Format_Cmd(DAQ_CMD_BUF *febuf,BYTE periph_no, BYTE command_no)
{
  febuf->buf[0] = 0;                                             // comm. length MSB
  febuf->buf[1] = 2;                                             // comm. length LSB
  febuf->buf[2] = command_no | (periph_no << 4);                 // command id

  febuf->buf[3]=CM_Compute_CRC8_8(0,febuf->buf,3);               // intermediate crc

  febuf->buf[4] = febuf->buf[3];                                // final crc 
  febuf->len = 5;

  return CM_RC_SUCCESSFUL;
}

/*****************************************************************************/
/*  
 *  TRK_Format_CmdWriteBlock
 *
 *  format the command for the FE when there is a data block to write    
 *
 *  Input parameters: 
 *                   periph_no   = peripheral number 
 *                   command_no  = command number   
 *                   data_block  = pointer to the buffer to write 
 *                   data_length = size of the data block     
 *                   febuf       = pointer to the buffer to fill 
 *                 
 *  Output parameters: status_code
 *
 */
/*****************************************************************************/

status_code TRK_Format_CmdWriteBlock(DAQ_CMD_BUF *febuf,BYTE periph_no,BYTE command_no,DAQ_CMD_BUF *data_block)
{
  UINT16 len;

  len = data_block->len;

  febuf->buf[0] = CM_HI_UINT16(2+len);                                          // comm. length MSB
  febuf->buf[1] = CM_LO_UINT16(2+len);                                          // comm. length LSB
  febuf->buf[2] = command_no | (periph_no << 4);                                // command id

  febuf->buf[3]=CM_Compute_CRC8_8(0,febuf->buf,3);                             // intermediate crc
  memcpy(&febuf->buf[4],data_block->buf,len);                                   // fill data block 
  febuf->buf[4+len]=CM_Compute_CRC8_8(febuf->buf[3],data_block->buf,len);       // final crc
  febuf->len = 5+len;

  return CM_RC_SUCCESSFUL;
}

/*****************************************************************************/
/*  
 *  TRK_Format_DataBlock
 *
 *  format a data block to send to a dsp 
 *
 *  Input parameters: 
 *                   block   = pointer to the formatted block
 *                   type    = DATA_MEMORY or PROGRAM_MEMORY 
 *                   ovlay   = DM or PM overlay 
 *                   address = starting address on dsp 
 *                   data    = pointer to actual data or program to store
 *                   data_len = length of data 
 *  
 *  Output parameters: status_code
 *
 */
/*****************************************************************************/


status_code TRK_Format_DataBlock(DAQ_CMD_BUF *block,BYTE type,BYTE ovlay,UINT16 address,BYTE *data,UINT32 data_len)
{
  BYTE dm;

  dm = (type << 6);

  block->buf[0] = dm ? (ovlay << 4) : ovlay;
  block->buf[1] = dm | (BYTE) ((address & 0x3f00) >> 8);
  block->buf[2] = (BYTE) address & 0x00ff;
  memcpy(&block->buf[3],data,data_len);
  block->len = 3 + data_len;
  
  return CM_RC_SUCCESSFUL;
}


/*****************************************************************************/
/*  
 *  TRK_Format_ResetDSP
 *
 *  format buffer to send a reset to periph_no DSP (non read cmd)     
 *
 *  Input parameters: 
 *                   periph_no      = number of dsp
 *                   link       = tracker link    
 *                   buffer     = pointer to the buffer to fill 
 *                 
 *  Output parameters: status_code
 *
 */
/*****************************************************************************/

status_code TRK_Format_ResetDSP(DAQ_CMD_BUF *buffer,BYTE periph_no,DAQ_FE link)
{
  status_code status;
 
  if ((link == DAQ_FE_TRK_1) || (link == DAQ_FE_TRK_2)) 
    {
      DAQ_Format_CMD_Empty(&TRK_TempBuf);
      
      TRK_Format_Cmd(&TRK_TempBuf,periph_no,RESET_DSP);
      status = DAQ_Format_Cmd2Fe(buffer,&TRK_TempBuf,link);
    }
  else
    status = CM_RC_BAD_IDAQ_LINK;

  return(status);
}

/*****************************************************************************/
/*  
 *  TRK_Format_WriteDSP
 *
 *  format buffer to send a write request to periph_no DSP (non read cmd)     
 *
 *  Input parameters: 
 *                   periph_no      = number of dsp
 *                   link       = tracker link    
 *                   data_block = pointer to the buffer to fill (see TRK_Format_DataBlock)
 *                   buffer     = pointer to formatted output buffer                    
 *                 
 *  Output parameters: status_code
 *
 */
/*****************************************************************************/

status_code TRK_Format_WriteDSP(DAQ_CMD_BUF *buffer,BYTE periph_no,DAQ_FE link, DAQ_CMD_BUF *data_block)
{
  status_code status;
 
  if ((link == DAQ_FE_TRK_1) || (link == DAQ_FE_TRK_2)) 
    {
      DAQ_Format_CMD_Empty(&TRK_TempBuf);
      
      TRK_Format_CmdWriteBlock(&TRK_TempBuf,periph_no,WRITE_DSP,data_block);
      status = DAQ_Format_Cmd2Fe(buffer,&TRK_TempBuf,link);
    }
  else
    status = CM_RC_BAD_IDAQ_LINK;

  return(status);
}

/*****************************************************************************/
/*  
 *  TRK_Format_LoadPMDSP
 *
 *  format buffer to send a load PM request to periph_no DSP (non read cmd)     
 *
 *  Input parameters: 
 *                   periph_no      = number of dsp
 *                   link       = tracker link    
 *                   buffer     = pointer to formatted output buffer                    
 *                 
 *  Output parameters: status_code
 *
 */
/*****************************************************************************/

status_code TRK_Format_LoadPMDSP(DAQ_CMD_BUF *buffer,BYTE periph_no,DAQ_FE link)
{
  status_code status;
 
  if ((link == DAQ_FE_TRK_1) || (link == DAQ_FE_TRK_2)) 
    {
      DAQ_Format_CMD_Empty(&TRK_TempBuf);
      
      TRK_Format_Cmd(&TRK_TempBuf,periph_no,LOAD_DSP_PRG_BLOCK);
      status = DAQ_Format_Cmd2Fe(buffer,&TRK_TempBuf,link);
    }
  else
    status = CM_RC_BAD_IDAQ_LINK;

  return(status);
}

/*****************************************************************************/
/*  
 *  TRK_Format_LoadWriteOnCR
 *
 *  format buffer to send a write on CR command (non read cmd)     
 *
 *  Input parameters: 
 *                   link       = tracker link    
 *                   mask       = CR mask to set 
 *                   buffer     = pointer to formatted output buffer                    
 *                 
 *  Output parameters: status_code
 *
 */
/*****************************************************************************/

status_code TRK_Format_WriteOnCR(DAQ_CMD_BUF *buffer,DAQ_FE link,BYTE mask)
{
  status_code status;
  DAQ_DECL_LOCAL_BUF(Temp,1);
 
  DAQ_Format_CMD_Empty(&Temp);

  if ((link == DAQ_FE_TRK_1) || (link == DAQ_FE_TRK_2)) 
    {
      DAQ_Format_CMD_Empty(&TRK_TempBuf);
     
      *Temp.buf = mask;
      Temp.len = 1;

      TRK_Format_CmdWriteBlock(&TRK_TempBuf,OTHER_COMMAND,WRITE_CR,&Temp);
      status = DAQ_Format_Cmd2Fe(buffer,&TRK_TempBuf,link);
    }
  else
    status = CM_RC_BAD_IDAQ_LINK;

  return(status);
}

/*****************************************************************************/
/*  
 *  TRK_Format_TurnOnFlash
 *
 *  format buffer to send a turn-on flash command (non read cmd)     
 *
 *  Input parameters: 
 *                   link       = tracker link    
 *                   buffer     = pointer to formatted output buffer                    
 *                 
 *  Output parameters: status_code
 *
 */
/*****************************************************************************/

status_code TRK_Format_TurnOnFlash(DAQ_CMD_BUF *buffer,DAQ_FE link)
{
  status_code status;
  
  if ((link == DAQ_FE_TRK_1) || (link == DAQ_FE_TRK_2)) 
    {
      DAQ_Format_CMD_Empty(&TRK_TempBuf);
     
      TRK_Format_Cmd(&TRK_TempBuf,OTHER_COMMAND,TURN_ON_FLASH);
      status = DAQ_Format_Cmd2Fe(buffer,&TRK_TempBuf,link);
    }
  else
    status = CM_RC_BAD_IDAQ_LINK;

  return(status);
}

/*****************************************************************************/
/*  
 *  TRK_Format_ShutDownFlash
 *
 *  format buffer to send a shutdown flash command (non read cmd)     
 *
 *  Input parameters: 
 *                   link       = tracker link    
 *                   buffer     = pointer to formatted output buffer                    
 *                 
 *  Output parameters: status_code
 *
 */
/*****************************************************************************/

status_code TRK_Format_ShutDownFlash(DAQ_CMD_BUF *buffer,DAQ_FE link)
{
  status_code status;
  
  if ((link == DAQ_FE_TRK_1) || (link == DAQ_FE_TRK_2)) 
    {
      DAQ_Format_CMD_Empty(&TRK_TempBuf);
     
      TRK_Format_Cmd(&TRK_TempBuf,OTHER_COMMAND,SHUTDOWN_FLASH);
      status = DAQ_Format_Cmd2Fe(buffer,&TRK_TempBuf,link);
    }
  else
    status = CM_RC_BAD_IDAQ_LINK;

  return(status);
}

/*****************************************************************************/
/*  
 *  TRK_Format_GeneralReset
 *
 *  format buffer to send a general reset command (non read cmd)     
 *
 *  Input parameters: 
 *                   link       = tracker link    
 *                   buffer     = pointer to formatted output buffer                    
 *                 
 *  Output parameters: status_code
 *
 */
/*****************************************************************************/

status_code TRK_Format_GeneralReset(DAQ_CMD_BUF *buffer,DAQ_FE link)
{
  status_code status;
  
  if ((link == DAQ_FE_TRK_1) || (link == DAQ_FE_TRK_2)) 
    {
      DAQ_Format_CMD_Empty(&TRK_TempBuf);
     
      TRK_Format_Cmd(&TRK_TempBuf,OTHER_COMMAND,GENERAL_RESET);
      status = DAQ_Format_Cmd2Fe(buffer,&TRK_TempBuf,link);
    }
  else
    status = CM_RC_BAD_IDAQ_LINK;

  return(status);
}

/*****************************************************************************/
/*  
 *  TRK_Format_SetFlashMemAddress
 *
 *  format buffer to send a set flash memory address command (non read cmd)     
 *
 *  Input parameters: 
 *                   link       = tracker link 
 *                   address    = address to store    
 *                   buffer     = pointer to formatted output buffer                    
 *                 
 *  Output parameters: status_code
 *
 */
/*****************************************************************************/

status_code TRK_Format_SetFlashMemAddress(DAQ_CMD_BUF *buffer,DAQ_FE link,UINT32 address)
{
  status_code status;
  DAQ_DECL_LOCAL_BUF(Temp,4);
 
  DAQ_Format_CMD_Empty(&Temp);

  if ((link == DAQ_FE_TRK_1) || (link == DAQ_FE_TRK_2)) 
    {
      DAQ_Format_CMD_Empty(&TRK_TempBuf);
     
      Temp.buf[0] = FLASH_CONTROL_SET_ADDR;
      Temp.buf[1] = (BYTE)(address & 0xff);
      Temp.buf[2] = (BYTE)((address & 0xff00) >> 8);
      Temp.buf[3] = (BYTE)((address & 0xf0000) >> 16); 
      Temp.len = 4;

      TRK_Format_CmdWriteBlock(&TRK_TempBuf,OTHER_COMMAND,FLASH_CONTROL,&Temp);
      status = DAQ_Format_Cmd2Fe(buffer,&TRK_TempBuf,link);
    }
  else
    status = CM_RC_BAD_IDAQ_LINK;

  return(status);
}

/*****************************************************************************/
/*  
 *  TRK_Format_WriteSingleByte
 *
 *  format buffer to send a set flash memory address command (non read cmd)     
 *
 *  Input parameters: 
 *                   link       = tracker link 
 *                   towrite    = byte to write    
 *                   buffer     = pointer to formatted output buffer                    
 *                 
 *  Output parameters: status_code
 *
 */
/*****************************************************************************/

status_code TRK_Format_WriteSingleByte(DAQ_CMD_BUF *buffer,DAQ_FE link,BYTE towrite)
{
  status_code status;
  DAQ_DECL_LOCAL_BUF(Temp,2);
 
  DAQ_Format_CMD_Empty(&Temp);

  if ((link == DAQ_FE_TRK_1) || (link == DAQ_FE_TRK_2)) 
    {
      DAQ_Format_CMD_Empty(&TRK_TempBuf);
     
      Temp.buf[0] = FLASH_CONTROL_WRITE_BYTE;
      Temp.buf[1] = towrite;
      Temp.len = 2;

      TRK_Format_CmdWriteBlock(&TRK_TempBuf,OTHER_COMMAND,FLASH_CONTROL,&Temp);
      status = DAQ_Format_Cmd2Fe(buffer,&TRK_TempBuf,link);
    }
  else
    status = CM_RC_BAD_IDAQ_LINK;

  return(status);
}


/*****************************************************************************/
/*  
 *  TRK_Format_WriteEndBlock
 *
 *  format buffer to send a set flash memory address command (non read cmd)     
 *
 *  Input parameters: 
 *                   link       = tracker link 
 *                   buffer     = pointer to formatted output buffer                    
 *                 
 *  Output parameters: status_code
 *
 */
/*****************************************************************************/

status_code TRK_Format_WriteEndBlock(DAQ_CMD_BUF *buffer,DAQ_FE link)
{
  status_code status;
  DAQ_DECL_LOCAL_BUF(Temp,1);
 
  DAQ_Format_CMD_Empty(&Temp);

  if ((link == DAQ_FE_TRK_1) || (link == DAQ_FE_TRK_2)) 
    {
      DAQ_Format_CMD_Empty(&TRK_TempBuf);
     
      Temp.buf[0] = FLASH_CONTROL_WRITE_END_BLOCK;
      Temp.len = 1;

      TRK_Format_CmdWriteBlock(&TRK_TempBuf,OTHER_COMMAND,FLASH_CONTROL,&Temp);
      status = DAQ_Format_Cmd2Fe(buffer,&TRK_TempBuf,link);
    }
  else
    status = CM_RC_BAD_IDAQ_LINK;

  return(status);
}

/*****************************************************************************/
/*  
 *  TRK_Format_EraseFlashSector
 *
 *  format buffer to send a set flash memory address command (non read cmd)     
 *
 *  Input parameters: 
 *                   link       = tracker link 
 *                   buffer     = pointer to formatted output buffer                    
 *                 
 *  Output parameters: status_code
 *
 */
/*****************************************************************************/

status_code TRK_Format_EraseFlashSector(DAQ_CMD_BUF *buffer,DAQ_FE link,BYTE sector)
{
  status_code status;
  DAQ_DECL_LOCAL_BUF(Temp,2);
 
  DAQ_Format_CMD_Empty(&Temp);

  if ((link == DAQ_FE_TRK_1) || (link == DAQ_FE_TRK_2)) 
    {
      DAQ_Format_CMD_Empty(&TRK_TempBuf);
     
      Temp.buf[0] = FLASH_CONTROL_ERASE_SECTOR;
      Temp.buf[1] = sector;
      Temp.len = 2;

      TRK_Format_CmdWriteBlock(&TRK_TempBuf,OTHER_COMMAND,FLASH_CONTROL,&Temp);
      status = DAQ_Format_Cmd2Fe(buffer,&TRK_TempBuf,link);
    }
  else
    status = CM_RC_BAD_IDAQ_LINK;

  return(status);
}

/*****************************************************************************/
/*  
 *  TRK_Format_ResetFlashController
 *
 *  format buffer to send a general reset command (non read cmd)     
 *
 *  Input parameters: 
 *                   link       = tracker link    
 *                   buffer     = pointer to formatted output buffer                    
 *                 
 *  Output parameters: status_code
 *
 */
/*****************************************************************************/

status_code TRK_Format_ResetFlashController(DAQ_CMD_BUF *buffer,DAQ_FE link)
{
  status_code status;
  
  if ((link == DAQ_FE_TRK_1) || (link == DAQ_FE_TRK_2)) 
    {
      DAQ_Format_CMD_Empty(&TRK_TempBuf);
     
      TRK_Format_Cmd(&TRK_TempBuf,OTHER_COMMAND,FLASH_RESET);
      status = DAQ_Format_Cmd2Fe(buffer,&TRK_TempBuf,link);
    }
  else
    status = CM_RC_BAD_IDAQ_LINK;

  return(status);
}

/*****************************************************************************/
/*  
 *  TRK_Format_ReadDSPDataBuffer
 *
 *  format buffer to send a set flash memory address command (non read cmd)     
 *
 *  Input parameters: 
 *                   periph_no  = peripheral number 
 *                   link       = tracker link 
 *                   buffer     = pointer to formatted output buffer                    
 *                   ovlay      = overlay 
 *                   adress     = starting address
 *                   maxnumber  = max word number   
 *                 
 *  Output parameters: status_code
 *
 */
/*****************************************************************************/

status_code TRK_Format_ReadDSPDataBuffer(DAQ_CMD_BUF *buffer,DAQ_FE link,BYTE periph_no,BYTE ovlay,UINT16 address, UINT16 maxnumber)
{
  status_code status;
  DAQ_DECL_LOCAL_BUF(Temp,5);
 
  DAQ_Format_CMD_Empty(&Temp);

  if ((link == DAQ_FE_TRK_1) || (link == DAQ_FE_TRK_2)) 
    {
      DAQ_Format_CMD_Empty(&TRK_TempBuf);
     
      Temp.buf[0] = ovlay << 4;
      Temp.buf[1] = 64 | (CM_HI_UINT16(address) & 0x3f);
      Temp.buf[2] = CM_LO_UINT16(address);
      Temp.buf[3] = CM_HI_UINT16(maxnumber) & 0x7f;
      Temp.buf[4] = CM_LO_UINT16(maxnumber);
      Temp.len = 5;

      TRK_Format_CmdWriteBlock(&TRK_TempBuf,periph_no,READ_DSP_DATA,&Temp);
      status = DAQ_Format_Cmd2Fe(buffer,&TRK_TempBuf,link);
    }
  else
    status = CM_RC_BAD_IDAQ_LINK;

  return(status);
}

/*****************************************************************************/
/*  
 *  TRK_Format_ReadDSPMemoryBlock
 *
 *  format buffer to send a set flash memory address command (non read cmd)     
 *
 *  Input parameters: 
 *                   periph_no  = peripheral number 
 *                   link       = tracker link
 *                   type       = DATA_MEMORY or PROGRAM_MEMORY  
 *                   ovlay      = overlay 
 *                   adress     = starting address
 *                   wordnumber = number of words to read   
 *                   buffer     = pointer to formatted output buffer                    
 *                 
 *  Output parameters: status_code
 *
 */
/*****************************************************************************/

status_code TRK_Format_ReadDSPMemoryBlock(DAQ_CMD_BUF *buffer,DAQ_FE link,BYTE datatype,BYTE periph_no,BYTE ovlay,UINT16 address, UINT16 wordnumber)
{
  BYTE dm;
  status_code status;
  DAQ_DECL_LOCAL_BUF(Temp,5);

  dm = (datatype << 6);
  DAQ_Format_CMD_Empty(&Temp);

  if ((link == DAQ_FE_TRK_1) || (link == DAQ_FE_TRK_2)) 
    {
      DAQ_Format_CMD_Empty(&TRK_TempBuf);
     
      Temp.buf[0] = dm ? (ovlay << 4) : ovlay;
      Temp.buf[1] = dm | (BYTE) ((address & 0x3f00) >> 8);
      Temp.buf[2] = CM_LO_UINT16(address);
      Temp.buf[3] = CM_HI_UINT16(wordnumber) & 0x7f;
      Temp.buf[4] = CM_LO_UINT16(wordnumber);
      Temp.len = 5;

      TRK_Format_CmdWriteBlock(&TRK_TempBuf,periph_no,READ_DSP_MEM_BLOCK,&Temp);
      status = DAQ_Format_Cmd2Fe(buffer,&TRK_TempBuf,link);
    }
  else
    status = CM_RC_BAD_IDAQ_LINK;

  return(status);
}

/*****************************************************************************/
/*  
 *  TRK_Format_ReadControlRegister
 *
 *  format buffer to send a general reset command (non read cmd)     
 *
 *  Input parameters: 
 *                   link       = tracker link    
 *                   buffer     = pointer to formatted output buffer                    
 *                 
 *  Output parameters: status_code
 *
 */
/*****************************************************************************/

status_code TRK_Format_ReadControlRegister(DAQ_CMD_BUF *buffer,DAQ_FE link)
{
  status_code status;
  
  if ((link == DAQ_FE_TRK_1) || (link == DAQ_FE_TRK_2)) 
    {
      DAQ_Format_CMD_Empty(&TRK_TempBuf);
     
      TRK_Format_Cmd(&TRK_TempBuf,OTHER_COMMAND,READ_CR);
      status = DAQ_Format_Cmd2Fe(buffer,&TRK_TempBuf,link);
    }
  else
    status = CM_RC_BAD_IDAQ_LINK;

  return(status);
}
