/****************************************************************************
/*  F i l e   D a t a                                                        
/*                                                                           
/*  Module       : BasicSW                                                   
/*  C.I. No.     :                                                           
/*  $Revision: 1.1.1.1 $
/*  $Date: 2006/04/25 09:00:20 $
/*  Belonging to :                                                           
/*               :                                                           
/*  $RCSfile: BI_Bus1553B_op.c,v $
/*  Program Type :                                                           
/*  Sub-modules  :                                                           
/*                                                                           
/****************************************************************************
/*  S W   D e v e l o p m e n t   E n v i r o n m e n t                      
/*                                                                           
/*  Host system  :                                                           
/*  SW Compiler  :                                                           
/*  $Author: kusanagi $
/*               :                                                           
/****************************************************************************
/*  U p d a t i n g                                                          
/*                                                                           
/*  $Log: BI_Bus1553B_op.c,v $
/*  Revision 1.1.1.1  2006/04/25 09:00:20  kusanagi
/*  These program extract in an XML format the info contained into the ROOT files generated by YODA from the PAMELA data. To visualize the XML files in a more human readable format a collection of XSL files are given in the Data subfolder.
/*
/*  Revision 1.1.1.1  2003/08/04 09:40:21  sebastiani
/*  Imported sources laben rel. 19.06.2003 integrated with pam2
/*
/*  Revision 1.11  2003/06/09 07:17:02  aurora
/*  fixed 1553 mcmd ack word
/*
/*  Revision 1.10  2003/05/06 15:39:19  aurora
/*  correct the downlink size of RT
/*
/*  Revision 1.9  2003/04/29 13:18:56  aurora
/*  removed mcmd counter in RT (bug)
/*
/*  Revision 1.8  2002/11/14 09:40:45  zulia
/*  Removed unused "status" variable
/*
/*  Revision 1.7  2002/11/06 15:48:00  zulia
/*  Correct 1553 ack bug
/*
/*  Revision 1.6  2002/05/15 13:13:09  aurora
/*  Modified to return MCMD ID and
/*  Source Sequence Counter in case of MCMD validation error
/*
/*  Revision 1.5  2002/05/09 08:16:33  zulia
/*  *  acceptance release
/*
/*                                                                           
/*****************************************************************************/

/*============================= Include File ================================*/
  
#include <src/BasicSW/Bus1553B/BI_Bus1553B_op.h>
#include <src/BasicSW/Bus1553B/BI_Bus1553B_int.h>
#include <src/HKManager/HistoryArea/HA_HistoryArea_p.h>
#include <src/HKManager/ReportGenerator/RG_ReportGenerator_p.h>
#include <src/BasicSW/PatchDumpManager/PD_PatchDumpManager_p.h>
#include <src/BasicSW/TimingInfo/TI_TimingInfo_p.h>
#include <src/ModeManager/ModeCoordinator/MC_ModeCoordinator_p.h>

/*****************************************************************************/
/*============================== Local Variables ============================*/

/*****************************************************************************/
/* @Variable: BI_1553MCMDBuffer                                              */
/* @Purpose :                                                                */
/*  Array of unsigned short int.                                             */
/*  Array whose contents is the MCMD data                                    */
/* @@                                                                        */
/*****************************************************************************/
static unsigned short int BI_1553MCMDBuffer[768];

/*****************************************************************************/
/* @Variable: BI_1553CCABuffer                                               */
/* @Purpose :                                                                */
/*  Array of unsigned short int.                                             */
/*  Array whose contents is the Communication Control Word                   */
/* @@                                                                        */
/*****************************************************************************/
static unsigned short int BI_1553CCABuffer[BI_MAX_CCA_VORDS];

/*****************************************************************************/
/* @Variable: BI_1553MCMDACKWord                                             */
/* @Purpose :                                                                */
/*  Array of unsigned short int.                                             */
/*  Array whose contents is the Acknowledge word                             */
/* @@                                                                        */
/*****************************************************************************/
static unsigned short int BI_1553MCMDACKWord[2];

/*****************************************************************************/
/* @Variable: HandshakeExecAck                                               */
/* @Purpose :                                                                */
/*  Unsigned int                                                             */
/*  Variable to perform the handshake high level protocol                    */
/* @@                                                                        */
/*****************************************************************************/
static unsigned int  HandshakeExecAck;

/*****************************************************************************/
/* @Variable: subAddBlkIDs                                                   */
/* @Purpose :                                                                */
/*  Array of unsigned int.                                                   */
/*  Array whose contents are the subaddress identifiers (0..255)             */
/* @@                                                                        */
/*****************************************************************************/
static unsigned int  subAddBlkIDs[MAX_1553SUBAD];

/*****************************************************************************/
/* @Variable: SubAddress                                                     */
/* @Purpose :                                                                */
/*  Array of pointer to unsigned int.                                        */
/*  Array whose contents are the memory addresses of the subaddress          */
/* @@                                                                        */
/*****************************************************************************/
static unsigned int* SubAddress[MAX_1553SUBAD];

/*****************************************************************************/
/* @Variable: Descriptor                                                     */
/* @Purpose :                                                                */
/*  Array of DESC_BLK                                                        */
/*  Array whose contents are the descriptor blocks of the subaddress         */
/* @@                                                                        */
/*****************************************************************************/
static const DESC_BLK Descriptor[] =
                    {//ControlWord,   TA,     CA,     MIB,        Length
                     {BI_CTRLW_RSA01, 0x3630, 0x3630, 0x3D00}, // 32=0x20
                     {BI_CTRLW_RSA20, 0x0140, 0x0140, 0x0440}, // 768=0x300
                     {BI_CTRLW_RSA21, 0x0610, 0x0610, 0x0612}, // 2
                     {BI_CTRLW_RSA22, 0x0614, 0x0614, 0x0616}, // 2
                     {BI_CTRLW_TSA01, 0x3630, 0x3630, 0x3D00}, // 32=0x20
                     {BI_CTRLW_TSA02, 0x0620, 0x0620, 0x3D00}, // 2
                     {BI_CTRLW_TSA03, 0x0622, 0x0622, 0x3D00}, // 2
                     {BI_CTRLW_TSA04, 0x0624, 0x0624, 0x3D00}, // 12
                     {BI_CTRLW_TSA05, 0x0630, 0x0630, 0x3D00}, // 4096=0x1000
                     {BI_CTRLW_TSA06, 0x1630, 0x1630, 0x3D00}, // 4096=0x1000
                     {BI_CTRLW_TSA07, 0x2630, 0x2630, 0x3D00}, // 4096=0x1000
                     {BI_CTRLW_TMC02, 0x3630, 0x3630, 0x3D00}, // 2
                     {BI_CTRLW_TMC04, 0x3630, 0x3630, 0x3D00}, // 2
                     {BI_CTRLW_TMC05, 0x3630, 0x3630, 0x3D00}  // 2
                    };


/*****************************************************************************/
/* @Variable: BI_1553McmdCounter                                             */
/* @Purpose :                                                                */
/*  This variable counts the number of received macrocommands                */
/* @@                                                                        */
/*****************************************************************************/
static unsigned int BI_1553McmdCounter = 0;

/*****************************************************************************/

/*======= B u s 1 5 5 3 B   O P E R A T I O N A L   F U N C T I O N S =======*/

/*****************************************************************************/
/* @Function: BI_opInitBus1553B                                              */
/* @Purpose :                                                                */
/*  The function prepares the state of init for the module of 1553           */
/*  setting the SuMMIT as a remote terminal and opening (legalize) all       */
/*  the subaddreesses to be used                                             */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code BI_opInitBus1553B( void ) {
#ifndef SIMULATOR
  status_1553 ret_val = BI_OK;
  BI_TYPE_1553SUBAD j;
  unsigned int* pexg;
  
  for( pexg = (unsigned int*)EXG_MEM_ADRS_AREA0; pexg < (unsigned int*)(EXG_MEM_ADRS_AREA0+0x10000); pexg++ )
    {
      *pexg = 0;
    }
#endif

    HandshakeExecAck = FALSE;

#ifndef SIMULATOR
    /* setting the SuMMIT Remote Terminal Address */
    ret_val = BI_ifSuMMITRTDrv(BI_SUM_REMOTE_TERMINAL_IDENTIFIER); 

    /* legalize all the used subaddress */
    subAddBlkIDs[BI_RSA01] = BI_ifSuMMITRTDbLegalize( BI_RX_BLK, BI_SUM_DB_ID_RSA01 );
    subAddBlkIDs[BI_RSA20] = BI_ifSuMMITRTDbLegalize( BI_RX_BLK, BI_SUM_DB_ID_RSA20 );
    subAddBlkIDs[BI_RSA21] = BI_ifSuMMITRTDbLegalize( BI_RX_BLK, BI_SUM_DB_ID_RSA21 );
    subAddBlkIDs[BI_RSA22] = BI_ifSuMMITRTDbLegalize( BI_RX_BLK, BI_SUM_DB_ID_RSA22 );
    subAddBlkIDs[BI_TSA01] = BI_ifSuMMITRTDbLegalize( BI_TX_BLK, BI_SUM_DB_ID_TSA01 );
    subAddBlkIDs[BI_TSA02] = BI_ifSuMMITRTDbLegalize( BI_TX_BLK, BI_SUM_DB_ID_TSA02 );
    subAddBlkIDs[BI_TSA03] = BI_ifSuMMITRTDbLegalize( BI_TX_BLK, BI_SUM_DB_ID_TSA03 );
    subAddBlkIDs[BI_TSA04] = BI_ifSuMMITRTDbLegalize( BI_TX_BLK, BI_SUM_DB_ID_TSA04 );
    subAddBlkIDs[BI_TSA05] = BI_ifSuMMITRTDbLegalize( BI_TX_BLK, BI_SUM_DB_ID_TSA05 );
    subAddBlkIDs[BI_TSA06] = BI_ifSuMMITRTDbLegalize( BI_TX_BLK, BI_SUM_DB_ID_TSA06 );
    subAddBlkIDs[BI_TSA07] = BI_ifSuMMITRTDbLegalize( BI_TX_BLK, BI_SUM_DB_ID_TSA07 );
    subAddBlkIDs[BI_TMC02] = BI_ifSuMMITRTDbLegalize( BI_MC_BLK, BI_SUM_DB_ID_TMC02 );
    subAddBlkIDs[BI_TMC04] = BI_ifSuMMITRTDbLegalize( BI_MC_BLK, BI_SUM_DB_ID_TMC04 );
    subAddBlkIDs[BI_TMC05] = BI_ifSuMMITRTDbLegalize( BI_MC_BLK, BI_SUM_DB_ID_TMC05 );


    /* setting SuMMIT Descriptor Blocks at starup */
    for( j = BI_RSA01; j < MAX_1553SUBAD; j++ )
    {
        if ( subAddBlkIDs[j] >= 0 )
        {
            SubAddress[j] = (unsigned int*)BI_ifSuMMITRTDbWrite(subAddBlkIDs[j],Descriptor[j]);
        }
        else
        {
            ret_val = BI_SUB_ADRS_ERROR;
        }
    }


    BI_1553McmdCounter = 0;
    
    return (ret_val == BI_OK) ? SUCCESSFUL : UNSATISFIED;
#else
    return SUCCESSFUL;
#endif // SIMULATOR
}


/*****************************************************************************/
/* @Function: BI_op1553BInterruptHandler                                     */
/* @Purpose :                                                                */
/*  The function is called by interrups received from 1553 and manages       */
/*  the macrocommands high level protocol. Retrieves data from the           */
/*  accesssed subaddress and then restores it                                */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/
status_code BI_op1553BInterruptHandler ( void )
{
  status_code status = SUCCESSFUL;
  unsigned int irq_pending_reg;
  unsigned int irq_log_list_reg;
  unsigned int offset,
               *dbadrs,
               num_irq;
  BI_TYPE_1553SUBAD sub_accessed = MAX_1553SUBAD;
  DESC_BLK      db;
  unsigned int* pexg;
  unsigned int  ssw, i;
  MsgTsk        sndMsg;
  RG_RTFHEADER  hd;
  unsigned short int* pDump;

    irq_log_list_reg = 0;
    num_irq = 0;
    /* reading the pending regs to determinate the event that generate intr */
    BI_ifSuMMITRTRegRead(BI_SUM_PENDING_INTR_REG, &irq_pending_reg);

    /* determinating if a SUBAD interrupt has been received (bit 10 in PIR) */
    if( (irq_pending_reg & BI_IRQ_SUBAD_MASK) == BI_IRQ_SUBAD_MASK )
    {
        /* retrieves the starting  address of Interrupt Log List */
        BI_ifSuMMITRTRegRead(BI_SUM_INTR_LOG_LIST_PTR_REG, &irq_log_list_reg);

        num_irq = (irq_log_list_reg & 0x001F) >> 1;

        if( num_irq == 0 ) /* wrap around circular buffer 1^ or 16^ IRQ received */
        {
            offset = *((unsigned int*)EXG_MEM_ADRS_AREA0 + irq_log_list_reg + 0x1F) >> 16;
        }
        else
        {
            offset = *((unsigned int*)EXG_MEM_ADRS_AREA0 + irq_log_list_reg - 1) >> 16;
        }
        
        dbadrs = (unsigned int*)EXG_MEM_ADRS_AREA0 + offset;

        if( dbadrs == SubAddress[BI_RSA21] ) /* EXECUTE */
        {
            sub_accessed = BI_RSA21;
            
            BI_ifSuMMITRTDbGet( subAddBlkIDs[BI_RSA20], &db );
         
            if ( !(db.ctrlWord & BI_RX_SUBADD_ACCESSED) )
            {
                status = UNSATISFIED;
                BI_1553MCMDACKWord[0] |= BI_MCMD_NOT_OK | BI_MCMD_PROTOCOL_ERROR;        
            }
            else
            {
                if( HandshakeExecAck == TRUE )
                {
                    status = UNSATISFIED;
                    BI_1553MCMDACKWord[0] |= BI_MCMD_NOT_OK | BI_MCMD_PROTOCOL_ERROR;
                }
                else
                {
                    HandshakeExecAck = TRUE;
                    BI_1553MCMDACKWord[0] = 0;
                    BI_1553MCMDACKWord[1] = 0;
                    status = BI_if1553BLoadMCMD(subAddBlkIDs[BI_RSA20],BI_1553MCMDBuffer,BI_1553MCMDACKWord);
                    if( BI_1553McmdCounter == 0xFFFF )
                    {
                        BI_1553McmdCounter = 0;
                    }
                    else
                    {
                        BI_1553McmdCounter += 1;
                    }
                }
            }
	    
            BI_if1553BWriteAck(subAddBlkIDs[BI_TSA03],subAddBlkIDs[BI_RSA20],BI_1553MCMDACKWord);
            BI_if1553BWriteCCA(subAddBlkIDs[BI_TSA04],BI_1553CCABuffer,BI_1553MCMDACKWord);
        }
        else if(dbadrs == SubAddress[BI_RSA22]) /* PREPARE FORMAT */
        {
             sub_accessed = BI_RSA22;
             pexg = BI_ifSuMMITRTGetDataAddress(subAddBlkIDs[BI_RSA22]);
             
             if ( pexg == (unsigned int*)0 )
             {
                 status = UNSATISFIED;
             }
             else
             {
                 switch ( *pexg >> 16 ) /* only 16MSB are meaningful */
                 {
                     case BI_SSW:
                          BI_ifSuMMITRTDbWrite(subAddBlkIDs[BI_TSA02], Descriptor[BI_TSA02]);
                          status = BI_if1553BWriteSSW(subAddBlkIDs[BI_TSA02]);
                          break;
           
                     case BI_CCA:
                          BI_ifSuMMITRTDbWrite(subAddBlkIDs[BI_TSA03], Descriptor[BI_TSA03]);
                          status = BI_if1553BWriteCCA(subAddBlkIDs[BI_TSA04],BI_1553CCABuffer,BI_1553MCMDACKWord);
                          break;
           
                     case BI_RT:
                          BI_ifSuMMITRTDbWrite(subAddBlkIDs[BI_TSA05], Descriptor[BI_TSA05]);
                          sndMsg.LlInfo = 0;
                          sndMsg.Code = RG_PREPARE_FRM_RT;
                          status = RG_piSndMsgReportGenerator(&sndMsg);
                          break;
                          
                     case BI_HA:
                          BI_ifSuMMITRTDbWrite(subAddBlkIDs[BI_TSA07], Descriptor[BI_TSA07]);
                          sndMsg.LlInfo = 0;
                          sndMsg.Code = HA_PREPAREFORMAT;
                          status = HA_piSndMsgHistoryArea(&sndMsg);
                          break;
           
                     case BI_DUMP:
                          BI_ifSuMMITRTDbWrite(subAddBlkIDs[BI_TSA06], Descriptor[BI_TSA06]);
                          RG_piPrepareHeader((unsigned short int*)&hd, RG_FORMAT_DUMP);
                          
                          /* retrieve the start memory address of dumped data from PatchDump module */
                          PD_piGetDumpDataAddress(&pDump);
                          
                          pexg = BI_ifSuMMITRTGetDataAddress(subAddBlkIDs[BI_TSA06]);
                          pexg[0] = hd.FmtBeginId;     
                          pexg[1] = hd.SourceState;    
                          pexg[2] = hd.FmtLength_Type; 
                          pexg[3] = hd.FrmCounter;     
                          pexg[4] = hd.OBTHigh;        
                          pexg[5] = hd.OBTLow;         
                          pexg[6] = hd.AnomCnt_HASpace;

                          pexg[PD_DUMP_MAX_BUFFER-1] = PD_DUMP_END_ID;

                          /* skip the header so increase by this value */
                          pexg += 7;
                          
                          /* copies the dump into 1553 exchange memory */
                          i = 0;
                          while( i < PD_BUFFER_DUMP_MAX_SIZE )
                          {
                              *pexg++ = pDump[i++];
                          }
                          break;                     
                     default:
                          status = UNSATISFIED;
                          break;
                 }
           
             }
        }
        else if(dbadrs == SubAddress[BI_TSA03]) /* SEND ACK */
        {
            sub_accessed = BI_TSA03;
            if( HandshakeExecAck == TRUE )
            {
                HandshakeExecAck = FALSE;
            }
            else
            {
                status = UNSATISFIED;
                BI_1553MCMDACKWord[0] |= BI_MCMD_NOT_OK | BI_MCMD_PROTOCOL_ERROR;
                BI_if1553BWriteAck(subAddBlkIDs[BI_TSA03],subAddBlkIDs[BI_RSA20],BI_1553MCMDACKWord);
                BI_if1553BWriteCCA(subAddBlkIDs[BI_TSA04],BI_1553CCABuffer,BI_1553MCMDACKWord);
            }
        }
        else
        {
            sub_accessed = MAX_1553SUBAD;
            status = UNSATISFIED;
        }

        if( sub_accessed != MAX_1553SUBAD )
        {   
            BI_ifSuMMITRTDbWrite(subAddBlkIDs[BI_RSA20], Descriptor[BI_RSA20]);
            BI_ifSuMMITRTDbWrite(subAddBlkIDs[sub_accessed], Descriptor[sub_accessed]);
        }
    }
    

    return (status);
}



/*****************************************************************************/
/* @Function: BI_op1553BWriteHistory                                         */
/* @Purpose :                                                                */
/*  This function writes History Area Logs into 1553 memory area.            */
/*  Return code can be SUCCESSFUL or UNSATISFIED.                            */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  History              IN      Buffer in RAM from where to reads the data  */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/
status_code BI_op1553BWriteHistory(unsigned short int* History)
{
  unsigned int *pexg, i;
  status_code   status = SUCCESSFUL;

    pexg = BI_ifSuMMITRTGetDataAddress(subAddBlkIDs[BI_TSA07]);

    if ( pexg == (unsigned int*)0 )
    {
        status = UNSATISFIED;
    }
    else
    {
        /* copy the History data into 1553 exchange memory */
        i = 0;
        while( i < BI_HA_SIZE )
        {
            *pexg++ = History[i++];
        }
    }

    return status;
}


/*****************************************************************************/
/* @Function: BI_op1553BWriteRTFrm                                           */
/* @Purpose :                                                                */
/*  This function writes Telemetry formats into 1553 memory area.            */
/*  Return code can be SUCCESSFUL or UNSATISFIED.                            */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  tmlf                 IN      Buffer in RAM from where to reads the data  */
/*  nword16              IN      number of 16 bit words to be written        */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/
status_code BI_op1553BWriteRTFrm(unsigned short int* tmlf, unsigned int nword16)
{

  unsigned int *pexg, *pmcmd_cnt, i;
  status_code   status = SUCCESSFUL;

    pexg = BI_ifSuMMITRTGetDataAddress(subAddBlkIDs[BI_TSA05]);

    if ( pexg == (unsigned int*)0 )
    {
        status = UNSATISFIED;
    }
    else
    {
        /* copy the RTF data into 1553 exchange memory */
        i = 0;
        while( i <= nword16 )
        {
            *pexg++ = tmlf[i++];
        }
    }

    return status;
}



/*****************************************************************************/
/* @Function: BI_op1553BWriteStatusWord                                      */
/* @Purpose :                                                                */
/*  This function writes the subsystem status word into 1553 exchange        */
/*  memory at a fixed address of subaddress TSA2.                            */
/*  Return code can be SUCCESSFUL or UNSATISFIED.                            */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  substatusword        IN      subsystem status word                       */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/
status_code BI_op1553BWriteStatusWord(unsigned short int substatusword)
{
  *(unsigned int *)BI_SSW_EXG_MEM_ADDR = substatusword;

  return (status_code)SUCCESSFUL;
}


/*****************************************************************************/
/* @Function: BI_opGetCCAFormat                                              */
/* @Purpose :                                                                */
/*  This function returns the CCA format words.                              */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  CCABuffer            IN      CCA buffer                                  */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/
status_code BI_opGetCCAFormat (unsigned short int* CCABuffer)
{
unsigned int i;

    BI_if1553BWriteCCA(subAddBlkIDs[BI_TSA04],BI_1553CCABuffer,BI_1553MCMDACKWord);
    for (i=0; i<BI_MAX_CCA_VORDS; i++)
    {
        CCABuffer[i] =BI_1553CCABuffer[i];
    }
    return (SUCCESSFUL);
}
