Exemplo n.º 1
0
/**
*
* This function will make any adjustments needed when the node becomes the Grand
* Master, including resetting the RTC to its nominal value
*
* @param  InstancePtr is a pointer to the XAvb instance to be worked on
*
* @param  txAnnounceHasWon indicates that this function has been called from
*         the function XAvb_DecodeTxAnnounceFrame(). Is this is set then this
*         function has no need to repeat actions that have been already performed.
*
* @return None.
*
* @note   None.
*
*****************************************************************************/
void XAvb_BecomeRtcMaster(XAvb *InstancePtr,
                          u8    txAnnounceHasWon) {

  XAvb_BmcData deviceData;

  if (txAnnounceHasWon == 0) {
    /**
     * Update the BMCA records to this device's information
     */

    /** Read the attributes in the Tx PTP buffer */
    XAvb_ReadAnnounceFrame(InstancePtr->Config.BaseAddress,
                           (XAVB_PTP_TX_ANNOUNCE_OFFSET + 8),
                           &deviceData);

    /** Update records  */
    XAvb_UpdateBmcRecords(&deviceData,
                          &InstancePtr->CurrentBmc);
  }

  /** reset the RTC to a nominal value */
  XAvb_WriteReg(InstancePtr->Config.BaseAddress,
                 XAVB_RTC_INCREMENT_OFFSET,
                 XAVB_RTC_INCREMENT_NOMINAL_RATE);

  /** set timestamp uncertainty if new status */
  if( !InstancePtr->CurrentBmc.IAmTheRtcMaster ) {
    xil_printf("\r\n*** I am now the Grand Master ***");
    xil_printf("\r\nNOTICE: timestamps are now certain\r\n");
    InstancePtr->GMDiscHandler(InstancePtr->GMDiscCallBackRef,
                               0);
  }

  /** inform the rest of the system */
  InstancePtr->CurrentBmc.IAmTheRtcMaster = 1;

}
Exemplo n.º 2
0
/**
*
* The Interrupt subroutine for the "interruptPtpTimer" signal.  This interrupt
* fires reguarly on a 1/128 second period (based on the RTC).
*
* @param  InstancePtr is a pointer to the XAvb instance to be worked on
*
* @return None.
*
* @note   None.
*
*****************************************************************************/
void XAvb_PtpTimerInterruptHandler(XAvb * InstancePtr) {

  /** Clear Interrupt */
  XAvb_WriteReg(InstancePtr->Config.BaseAddress,
                 XAVB_RTC_CLEAR_INT_OFFSET,
                 XAVB_RTC_CLEAR_INT_MASK);

  /** If PTP functions are marked as not running, then take no further action */
  if (InstancePtr->PtpIsRunning == 1) {

    /** If the Link Partner is not AS capable, then take no further action */
    if (InstancePtr->PeerASCapable == 1) {


      /** If a Master, then initiate Sync Frames and Announce frames at the
       *  correct intervals
       */
      if (InstancePtr->CurrentBmc.IAmTheRtcMaster == 1) {

         /** Master will initiate a Sync Frame when the SyncIntervalDuration
          *  expires (SyncIntervalDuration is used to count/time the duration)
          * - unless a Signalling frame has told us not to send Sync Frames
          */
         if ((InstancePtr->SignallingFrameData.SyncIntervalDuration != XAVB_PKT_TYPE_DISABLED) &&
             (InstancePtr->PtpCounters.CounterSyncInterval >=
            (InstancePtr->SignallingFrameData.SyncIntervalDuration-1))) {

           XAvb_MasterSendSync(InstancePtr);
           InstancePtr->PtpCounters.CounterSyncInterval = 0;

           /** Following a Sync Frame, a Follow Up frame should always be sent
            */
           XAvb_MasterSendFollowUp(InstancePtr);


         } else {
           InstancePtr->PtpCounters.CounterSyncInterval
               = InstancePtr->PtpCounters.CounterSyncInterval + 1;
         }

         /** Master will initiate an Announce Frame when the
          *  AnnounceIntervalDuration expires (CounterAnnounceInterval is used
          *  to count/time the duration)
          * - unless a Signalling frame has told us not to send Announce Frames
          */
         if ((InstancePtr->SignallingFrameData.AnnounceIntervalDuration != XAVB_PKT_TYPE_DISABLED) &&
             (InstancePtr->PtpCounters.CounterAnnounceInterval >=
              (InstancePtr->SignallingFrameData.AnnounceIntervalDuration-1))) {

           XAvb_MasterSendAnnounce(InstancePtr);
           InstancePtr->PtpCounters.CounterAnnounceInterval = 0;

         } else {
           InstancePtr->PtpCounters.CounterAnnounceInterval
               = InstancePtr->PtpCounters.CounterAnnounceInterval + 1;
         }

      /** If a Slave, monitor Announce/Sync Packet reception from the Master */
      } else {

        /** Timeout for Announce Packet reception: XAVB_ANNOUNCE_RECEIPT_TIMEOUT
         *  The AnnounceIntervalDuration is stored with the GrandMaster BMCA data
         *  as it is captured from the last Announce frame that was received.
         */
        if (InstancePtr->PtpCounters.CounterAnnounceInterval >=
            ((InstancePtr->CurrentBmc.AnnounceIntervalDuration-1) *
             XAVB_ANNOUNCE_RECEIPT_TIMEOUT) ) {

#ifdef XAVB_DEBUG_LEVEL1
          xil_printf("XAVB_ANNOUNCE_RECEIPT_TIMEOUT: Becoming GM! CounterAnnounceInterval = %d\r\n", InstancePtr->PtpCounters.CounterAnnounceInterval);
#endif

          InstancePtr->PtpCounters.CounterAnnounceInterval = 0;

          /** No Announce received from GM for timeout interval: we become the master */
          xil_printf("\r\n*** Announce timeout : Call XAvb_BecomeRtcMaster() *** \r\n");
          XAvb_BecomeRtcMaster(InstancePtr,0);

        } else {
          InstancePtr->PtpCounters.CounterAnnounceInterval
              = InstancePtr->PtpCounters.CounterAnnounceInterval + 1;
        }

        /** Timeout for Sync Packet reception: XAVB_SYNC_RECEIPT_TIMEOUT *
         *  The SyncIntervalDuration is stored with the Received Sync data
         *  as it is captured from the last Sync frame that was received.
         */
        if( InstancePtr->PtpCounters.CounterSyncInterval >=
            ((InstancePtr->latestMDSyncReceive.SyncIntervalDuration-1) *
             XAVB_SYNC_RECEIPT_TIMEOUT) ) {

#ifdef XAVB_DEBUG_LEVEL1
          xil_printf("\r\nXAVB_SYNC_RECEIPT_TIMEOUT: Becoming GM! CounterSyncInterval = %d\r\n", InstancePtr->PtpCounters.CounterSyncInterval);
          xil_printf("\r\nXAVB_SYNC_RECEIPT_TIMEOUT: SyncIntervalDuration = %d\r\n", InstancePtr->SignallingFrameData.SyncIntervalDuration);
#endif

          InstancePtr->PtpCounters.CounterSyncInterval = 0;


          /** No Syncs received from GM for timeout interval: we become
           *  the master */
          xil_printf("\r\n*** Sync Timeout : Call XAvb_BecomeRtcMaster() *** \r\n");
          XAvb_BecomeRtcMaster(InstancePtr,0);

        } else {
          InstancePtr->PtpCounters.CounterSyncInterval
              = InstancePtr->PtpCounters.CounterSyncInterval + 1;
        }
      }
    }

    /** Both Master and Slave will initiate a link delay measurement when the
     *  LinkDelayIntervalDuration expires (LinkDelayIntervalDuration is used to
     *  count/time the duration)
     * - unless a Signalling frame has told us not to send PdelayReq Frames
     */
    if ((InstancePtr->SignallingFrameData.LinkDelayIntervalDuration != XAVB_PKT_TYPE_DISABLED) &&
        (InstancePtr->PtpCounters.CounterLinkDelayInterval >=
         (InstancePtr->SignallingFrameData.LinkDelayIntervalDuration-1))) {

      /** Check to see if we've received PDelayResp and
       *  PDelayRespFollowUp messages since the last PDelayReq was
       *  sent */
      if( InstancePtr->StateMachineData.rcvdPDelayResp &&
          InstancePtr->StateMachineData.rcvdPDelayRespFollowUp ) {

        InstancePtr->StateMachineData.lostResponses = 0;
      } else {
        InstancePtr->StateMachineData.lostResponses++;
      }

      if( InstancePtr->StateMachineData.lostResponses >= XAVB_ALLOWED_LOST_RESPONSES ) {
        /** the peer is no longer ASCapable */
        XAvb_ChangePeerASCapability(InstancePtr, 0);

        xil_printf("\r\n** XAvb_PtpTimerInterruptHandler(): The peer is no longer ASCapable **");
        xil_printf("\r\n** XAvb_PtpTimerInterruptHandler(): StateMachineData.lostResponses >= %d **",
                   XAVB_ALLOWED_LOST_RESPONSES);

        /** avoid potential overflow */
        InstancePtr->StateMachineData.lostResponses = XAVB_ALLOWED_LOST_RESPONSES;
      }

      XAvb_SendPDelayReq(InstancePtr);

      InstancePtr->StateMachineData.rcvdPDelayResp         = 0;
      InstancePtr->StateMachineData.rcvdPDelayRespFollowUp = 0;
      InstancePtr->PtpCounters.CounterLinkDelayInterval    = 0;

    } else {
      InstancePtr->PtpCounters.CounterLinkDelayInterval
          = InstancePtr->PtpCounters.CounterLinkDelayInterval + 1;
    }

  } /** end of 'if (InstancePtr->PtpIsRunning == 1)' */

}
Exemplo n.º 3
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
}