/** * * 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); } }
/** * * 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 }
/** * * 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)' */ }
/** * * 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 }