/**
*
* Operations needed when PTP locks or unlocks
*
* @param  InstancePtr is a pointer to the XAvb instance to be worked on
* @param  locked is 1 if changing to locked status, zero if unlocked
*
* @return None.
*
* @note   None.
*
*****************************************************************************/
void XAvb_ChangePTPLockStatus(XAvb *InstancePtr, u8 locked) {
  u32 lockedOld;
  u32 tu = 0;

  lockedOld = InstancePtr->PTPLocked;

  /** set status variable */
  InstancePtr->PTPLocked = locked;

  /** set timestamp uncertainty if necessary */
  if( InstancePtr->PTPLocked != lockedOld ) {
    XAvb_ChangePeerASCapability(InstancePtr, locked);

#ifdef XAVB_DEBUG_LEVEL2
    if (locked == 0) {
      xil_printf("\r\nXAvb_ChangePTPLockStatus():The peer is no longer ASCapable ");
      xil_printf("\r\nXAvb_ChangePTPLockStatus():locked = %d\r\n",locked);
    }
#endif

    tu = InstancePtr->PTPLocked ? 0 : 1;
    xil_printf("\r\nXAvb_ChangePTPLockStatus()::");
    xil_printf("\r\nNOTICE: timestamps are now %s\r\n", tu ? "uncertain" : "certain");
    InstancePtr->GMDiscHandler(InstancePtr->GMDiscCallBackRef,
                               tu);
  }

}
示例#2
0
文件: xavb.c 项目: flynnjs/embeddedsw
/**
*
* This function will start the PTP drivers running.
*
* @param  InstancePtr is a pointer to the Xavb instance to be worked on.
*
* @return None.
*
* @note   None.
*
******************************************************************************/
void XAvb_Start(XAvb * InstancePtr)
{
  /** Assert bad arguments and conditions */
  Xil_AssertVoid(InstancePtr != NULL);
  Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

  /** Re-run the BMCA algorithm with the current PTP buffer Announce Packet */
  XAvb_DecodeTxAnnounceFrame(InstancePtr);

  /** Set to PTP running in the PTP data structure */
  InstancePtr->PtpIsRunning   = 1;

  /** Assume that the Peer is not AS capable until it replies to a pDelay_Req
    * frame */
  XAvb_ChangePeerASCapability(InstancePtr, 0);

#ifdef DEBUG_XAVB_LEVEL1
  xil_printf("\r\n** XAvb_Start(): Starting PTP **");
#endif
}
示例#3
0
文件: xavb.c 项目: flynnjs/embeddedsw
/**
*
* 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)' */

}
示例#4
0
文件: xavb.c 项目: flynnjs/embeddedsw
/**
*
* 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
}