Ejemplo n.º 1
0
/**
*
* A New Announce Packet has been received.  We need to decode it and rerun the
* Best Master Clock Algorithm (BMCA)
*
* @param  InstancePtr is a pointer to the XAvb instance to be worked on
* @param  PtpFrameBaseAddr is the base address of the received Announce Packet
*         in the Rx PTP Packet Buffer
*
* @return None.  But an updated True/False decision as to whether this device
*         should operate as a clock master or a slave is written into the
*         CurrentBmc data structure.
*
* @note   None.
*
*****************************************************************************/
void XAvb_DecodeRxAnnounceFrame(XAvb * InstancePtr,
                                u32    PtpFrameBaseAddr) {

  u32 NewMaster = 0;
  XAvb_BmcData RxAnnounceFrame;

  /** Read the attributes for the new Announce frame received */
  XAvb_ReadAnnounceFrame(InstancePtr->Config.BaseAddress,
                         PtpFrameBaseAddr,
                         &RxAnnounceFrame);

  /** If the received packet's clockIdentity matches our
   *  clockIdentity, ignore the packet */
  if( XAvb_ComparePortIdentity(InstancePtr->Config.BaseAddress,
                               InstancePtr->portIdLocal,
                               RxAnnounceFrame.SourcePortIdentity) ) {
    xil_printf("Got an announce from myself.. ignoring\r\n");
    return;
  }

  /** If the received packet's stepsRemoved field is >= 255,
   *  ignore the packet */
  if( RxAnnounceFrame.stepsRemoved >= 255 ) {
    xil_printf("Got an announce with stepsRemoved > 255.. ignoring\r\n");
    return;
  }

  /** If the Announce packet's GMID matches that of our current GM
   *  record, then update its records based on the current packet,
   *  just in case something (such as priority) has changed. */
  if( XAvb_CompareClockIdentity(InstancePtr->Config.BaseAddress,
                                RxAnnounceFrame.GrandmasterIdentity,
                                InstancePtr->CurrentBmc.GrandmasterIdentity) ) {

    /** update timeout information */
    InstancePtr->PtpCounters.CounterAnnounceInterval = 0;

    XAvb_UpdateBmcRecords(&RxAnnounceFrame,
                          &InstancePtr->CurrentBmc);
    /** Compare against this device's information to see if we should be GM */
    XAvb_DecodeTxAnnounceFrame(InstancePtr);

  } else if( InstancePtr->CurrentBmc.IAmTheRtcMaster ) {

    /** run BMCA on this announce to see if it is better than me */
    NewMaster =  XAvb_BestMasterClockAlgorithm(&RxAnnounceFrame,
                                               &InstancePtr->CurrentBmc);

    if (NewMaster == 1) {
      /** Update records with the NEW best master */
      XAvb_UpdateBmcRecords(&RxAnnounceFrame,
                            &InstancePtr->CurrentBmc);

      /** Capture the Announce Receipt Timeout Interval.
       *  Reset the announce receipt timeout interval to use the new value.
       */
      XAvb_ReadAnnounceReceiptTimeout(InstancePtr->Config.BaseAddress,
                                      PtpFrameBaseAddr,
                                      &RxAnnounceFrame);

      InstancePtr->CurrentBmc.AnnounceIntervalDuration =
            XAvb_ConvertLogMeanToDuration(RxAnnounceFrame.logMessageInterval);


#ifdef DEBUG_XAVB_LEVEL1
      xil_printf("\r\r\nXAvb_DecodeRxAnnounceFrame()");
      xil_printf("\r\n-----------------------");
      xil_printf("\r\nWinning Announce Frame");
      xil_printf("\r\n-----------------------");

      xil_printf("\r\nGM ID upper %x",
                 InstancePtr->CurrentBmc.GrandmasterIdentity.ClockIdentityUpper);

      xil_printf("\r\nGM ID lower %x",
                 InstancePtr->CurrentBmc.GrandmasterIdentity.ClockIdentityLower);

      xil_printf("\r\nPriority1   %x",
                 InstancePtr->CurrentBmc.GrandmasterPriority1);

      xil_printf("\r\nclockClass  %x",
                 InstancePtr->CurrentBmc.ClockQuality.clockClass);

      xil_printf("\r\nPriority2   %x",
                 InstancePtr->CurrentBmc.GrandmasterPriority2);
#endif

      /** New Rx Announce Packet has won - so this device cannot be a master */
      xil_printf("\r\n* XAvb_DecodeRxAnnounceFrame()::BMC : I am a SLAVE");
      XAvb_BecomeRtcSlave(InstancePtr);
    }
  }
}
Ejemplo n.º 2
0
/**
*
* This function resets all of the AVB device driver functions to the start-up
* (reset) defaults.
*
* @param  InstancePtr is a pointer to the Xavb instance to be worked on.
*
* @return None.
*
* @note   None.
*
******************************************************************************/
void XAvb_Reset(XAvb * InstancePtr)
{
  /** Assert bad arguments and conditions */
  Xil_AssertVoid(InstancePtr != NULL);
  Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

  /**
   * Perform a Software Reset of the AVB Core.
   * This will reset both the transmitter and receiver paths.
   * The RTC counter is not reset here.
   */
  XAvb_WriteReg(InstancePtr->Config.BaseAddress,
                 XAVB_SW_RESET_OFFSET,
                 XAVB_SW_RESET_TX_AND_RX_PATHS);

  /**
   * Set IEEE specification default values in the device's data structure
   */
  xil_printf("\r\n*** XAvb_Reset() : Call XAvb_BecomeRtcMaster() *** \r\n");
  XAvb_BecomeRtcMaster(InstancePtr,0);
  XAvb_ChangePeerASCapability(InstancePtr, 0);

  InstancePtr->PtpIsRunning                                  = 0;
  InstancePtr->PtpRecords.LinkDelay                          = 0;
  InstancePtr->SignallingFrameData.SyncIntervalDuration      =
    XAvb_ConvertLogMeanToDuration(XAVB_DEFAULT_LOG_MEAN_SYNC_INTERVAL);
  InstancePtr->SignallingFrameData.LinkDelayIntervalDuration =
    XAvb_ConvertLogMeanToDuration(XAVB_DEFAULT_LOG_MEAN_PDELAY_REQ_INTERVAL);
  InstancePtr->SignallingFrameData.AnnounceIntervalDuration  =
    XAvb_ConvertLogMeanToDuration(XAVB_DEFAULT_LOG_MEAN_ANNOUNCE_INTERVAL);

  InstancePtr->latestMDSyncReceive.SyncIntervalDuration     =
     XAvb_ConvertLogMeanToDuration(XAVB_DEFAULT_LOG_MEAN_SYNC_INTERVAL);

  /** Update logMeanMessageInterval in the pre-loaded TX SYNC message buffer */
  XAvb_UpdateLogMeanMessageInterval(InstancePtr->Config.BaseAddress,
                                    XAVB_PTP_TX_SYNC_OFFSET,
                                    InstancePtr->SignallingFrameData.SyncIntervalDuration);
  /** Update logMeanMessageInterval in the pre-loaded TX FOLLOW_UP message buffer */
  XAvb_UpdateLogMeanMessageInterval(InstancePtr->Config.BaseAddress,
                                    XAVB_PTP_TX_FOLLOW_UP_OFFSET,
                                    InstancePtr->SignallingFrameData.SyncIntervalDuration);

  /** Update logMeanMessageInterval in the pre-loaded TX PDELAYREQ message buffer */
  XAvb_UpdateLogMeanMessageInterval(InstancePtr->Config.BaseAddress,
                                    XAVB_PTP_TX_PDELAYREQ_OFFSET,
                                    InstancePtr->SignallingFrameData.LinkDelayIntervalDuration);

  /** Update logMeanMessageInterval in the pre-loaded TX ANNOUNCE message buffer  */
  XAvb_UpdateLogMeanMessageInterval(InstancePtr->Config.BaseAddress,
                                    XAVB_PTP_TX_ANNOUNCE_OFFSET,
                                    InstancePtr->SignallingFrameData.AnnounceIntervalDuration);

  /**
   * Initialise other driver variables in the device's data structure
   */
  InstancePtr->PtpCounters.RxPtpHardPointer               = 0;
  InstancePtr->PtpCounters.RxPtpSoftPointer               = 0xFF;
  InstancePtr->PtpCounters.CounterSyncInterval            = 0;
  InstancePtr->PtpCounters.CounterLinkDelayInterval       = 0;
  InstancePtr->PtpCounters.CounterAnnounceInterval        = 0;
  InstancePtr->PtpCounters.CounterSyncEvents              = 0;
  InstancePtr->StateMachineData.lostResponses             = 0;
  InstancePtr->StateMachineData.rcvdPDelayResp            = 0;
  InstancePtr->StateMachineData.rcvdPDelayRespFollowUp    = 0;
#ifdef DEBUG_XAVB_LEVEL1
  xil_printf("\r\n** XAvb_Reset(): PTP Driver Reset **");
#endif
}