XilinxProcessorIPLib/drivers/axiethernet/examples/avb/xavb_ptp_packets.c
void XAvb_SendPDelayRespFollowUp(XAvb * InstancePtr) {
  u32 TimestampT3 = 0;
  u32 BufferWordA = 0;
  u32 BufferWordB = 0;
  XAvb_RtcFormat Rtc[1];

  /** Wait until there are no PTP frames to be transmitted */
  XAvb_WaitOnTxPtpQueue(InstancePtr);

  /** Format the Timestamp
   *---------------------*/

  /** Capture the current Synchronised time */
  XAvb_ReadRtc(InstancePtr->Config.BaseAddress, Rtc);


  /** Read the TimestampT3 for PDelayResp transmission and adjust it for MAC
   *  transmit latency */
  TimestampT3 = XAvb_ReadPtpBuffer(InstancePtr->Config.BaseAddress,
                                    XAVB_PTP_TX_PDELAYRESP_OFFSET,
                                    XAVB_PTP_PKT_CAPTURED_TIMESTAMP_OFFSET)
                + XAVB_TX_MAC_LATENCY_IN_NS;

  /** The TimestampT3 was captured using syntonised ns time.  We need to
   * convert this into synchronised time by adding on the ns offset.  We
   * use the same offset here as for the PDelayResp frame since if a
   * ns offset change had been made between PDelayResp and ,
   * PDelayRespFollowUp, this would result in an error in the link delay
   * measurement. */
  TimestampT3 = TimestampT3 + InstancePtr->PtpRecords.NsOffsetForPDelayResp;

  /** Check for ns wrap-around condition */
  if (TimestampT3 >= XAVB_ONE_SECOND) {
    TimestampT3   = TimestampT3 - XAVB_ONE_SECOND;
  }

  /** Even though we read the RTC value at the beginning of this
   * function, there would have been processing delay between the
   * actual reception (and timestamping) of the PDelayReq frame and the
   * start of this function.  During this time, the RTC seconds
   * field could have wrapped around.  We need to detect this and if it
   * has done, the slave seconds field would also have incremented (so
   * it needs to be set back).
   */
  if (Rtc->NanoSeconds < TimestampT3) {
    /** nanosec has wrapped since timestamp was taken so decrement the
     * seconds field */
    if (Rtc->SecondsLower == 0x00000000) {
      Rtc->SecondsUpper = Rtc->SecondsUpper - 0x1;
    }
    Rtc->SecondsLower = Rtc->SecondsLower - 0x1;
  }

  /** Format the Timestamp (t3) into correct byte positioning for PTP frame
   *  storage, the write the Timestamp (t3) to the PDelayRespFollowUp frame
   */
  BufferWordA = XAvb_ReorderWord((Rtc->SecondsUpper<<16) |
                                 (Rtc->SecondsLower>>16));

  XAvb_WritePtpBuffer(InstancePtr->Config.BaseAddress,
                       XAVB_PTP_TX_PDELAYRESP_FOLLOW_UP_OFFSET,
                       XAVB_PTP_TX_PKT_TIMESTAMP_UPPER_OFFSET,
                       BufferWordA);

  BufferWordA = XAvb_ReorderWord((Rtc->SecondsLower<<16) | (TimestampT3>>16));

  XAvb_WritePtpBuffer(InstancePtr->Config.BaseAddress,
                       XAVB_PTP_TX_PDELAYRESP_FOLLOW_UP_OFFSET,
                       XAVB_PTP_TX_PKT_TIMESTAMP_MID_OFFSET,
                       BufferWordA);

  BufferWordA = XAvb_ReorderWord(TimestampT3<<16);
  BufferWordB = XAvb_ReadPtpBuffer(InstancePtr->Config.BaseAddress,
                                     XAVB_PTP_TX_PDELAYRESP_FOLLOW_UP_OFFSET,
                                     XAVB_PTP_TX_PKT_TIMESTAMP_LOWER_OFFSET);
  BufferWordA &= 0x0000ffff;
  BufferWordA |= (BufferWordB & 0xffff0000);

  XAvb_WritePtpBuffer(InstancePtr->Config.BaseAddress,
                       XAVB_PTP_TX_PDELAYRESP_FOLLOW_UP_OFFSET,
                       XAVB_PTP_TX_PKT_TIMESTAMP_LOWER_OFFSET,
                       BufferWordA);


  /** Send the PDelayRespFollowUp Frame!
   *----------------------------------- */

  XAvb_WriteReg(InstancePtr->Config.BaseAddress,
                 XAVB_PTP_TX_CONTROL_OFFSET,
                 XAVB_PTP_TX_SEND_PDELAYRESPFOLLOWUP_FRAME_MASK);

#ifdef DEBUG_XAVB_LEVEL3
  xil_printf("\r\n--------------------------------");
  xil_printf("\r\n--XAvb_SendPDelayRespFollowUp()-");
  xil_printf("\r\n--------------------------------");
  xil_printf("\r\nReading TimestampT3 from address %x",
            (InstancePtr->Config.BaseAddress + XAVB_PTP_TX_PDELAYRESP_OFFSET
             + XAVB_PTP_PKT_CAPTURED_TIMESTAMP_OFFSET));
  xil_printf("\r\nTimestampT3 is %x", TimestampT3);
#endif

}
/****************************************************************************/
/**
*
* A function to format then request the transmission of a PTP PDelay Response
* Follow-Up Packet
*
* @param  InstancePtr is a pointer to the XAvb instance to be worked on
*
* @return None.  But the relevant Tx PTP Packet Buffer is written to with the
*                updated PTP fields, and then the Tx PTP Packet Buffer Control
*                Register is written to request the frame transmission.
*
* @note   None.
*
*****************************************************************************/
A function to format then request the transmission of a PTP PDelay Response
Follow-Up Packet
A function to format then request the transmission of a PTP PDelay Response Follow - Up Packet
void XAvb_SendPDelayRespFollowUp(XAvb * InstancePtr) {
  u32 TimestampT3 = 0;
  u32 BufferWordA = 0;
  u32 BufferWordB = 0;
  XAvb_RtcFormat Rtc[1];
  XAvb_WaitOnTxPtpQueue(InstancePtr);
  XAvb_ReadRtc(InstancePtr->Config.BaseAddress, Rtc);
  TimestampT3 = XAvb_ReadPtpBuffer(InstancePtr->Config.BaseAddress,
                                    XAVB_PTP_TX_PDELAYRESP_OFFSET,
                                    XAVB_PTP_PKT_CAPTURED_TIMESTAMP_OFFSET)
                + XAVB_TX_MAC_LATENCY_IN_NS;
  TimestampT3 = TimestampT3 + InstancePtr->PtpRecords.NsOffsetForPDelayResp;
  if (TimestampT3 >= XAVB_ONE_SECOND) {
    TimestampT3   = TimestampT3 - XAVB_ONE_SECOND;
  }
  if (Rtc->NanoSeconds < TimestampT3) {
    if (Rtc->SecondsLower == 0x00000000) {
      Rtc->SecondsUpper = Rtc->SecondsUpper - 0x1;
    }
    Rtc->SecondsLower = Rtc->SecondsLower - 0x1;
  }
  BufferWordA = XAvb_ReorderWord((Rtc->SecondsUpper<<16) |
                                 (Rtc->SecondsLower>>16));
  XAvb_WritePtpBuffer(InstancePtr->Config.BaseAddress,
                       XAVB_PTP_TX_PDELAYRESP_FOLLOW_UP_OFFSET,
                       XAVB_PTP_TX_PKT_TIMESTAMP_UPPER_OFFSET,
                       BufferWordA);
  BufferWordA = XAvb_ReorderWord((Rtc->SecondsLower<<16) | (TimestampT3>>16));
  XAvb_WritePtpBuffer(InstancePtr->Config.BaseAddress,
                       XAVB_PTP_TX_PDELAYRESP_FOLLOW_UP_OFFSET,
                       XAVB_PTP_TX_PKT_TIMESTAMP_MID_OFFSET,
                       BufferWordA);
  BufferWordA = XAvb_ReorderWord(TimestampT3<<16);
  BufferWordB = XAvb_ReadPtpBuffer(InstancePtr->Config.BaseAddress,
                                     XAVB_PTP_TX_PDELAYRESP_FOLLOW_UP_OFFSET,
                                     XAVB_PTP_TX_PKT_TIMESTAMP_LOWER_OFFSET);
  BufferWordA &= 0x0000ffff;
  BufferWordA |= (BufferWordB & 0xffff0000);
  XAvb_WritePtpBuffer(InstancePtr->Config.BaseAddress,
                       XAVB_PTP_TX_PDELAYRESP_FOLLOW_UP_OFFSET,
                       XAVB_PTP_TX_PKT_TIMESTAMP_LOWER_OFFSET,
                       BufferWordA);
  XAvb_WriteReg(InstancePtr->Config.BaseAddress,
                 XAVB_PTP_TX_CONTROL_OFFSET,
                 XAVB_PTP_TX_SEND_PDELAYRESPFOLLOWUP_FRAME_MASK);
#ifdef DEBUG_XAVB_LEVEL3
  xil_printf("\r\n--------------------------------");
  xil_printf("\r\n--XAvb_SendPDelayRespFollowUp()-");
  xil_printf("\r\n--------------------------------");
  xil_printf("\r\nReading TimestampT3 from address %x",
            (InstancePtr->Config.BaseAddress + XAVB_PTP_TX_PDELAYRESP_OFFSET
             + XAVB_PTP_PKT_CAPTURED_TIMESTAMP_OFFSET));
  xil_printf("\r\nTimestampT3 is %x", TimestampT3);
#endif
}
void XAvb_SendPDelayRespFollowUp ( XAvb * InstancePtr ) { u32 TimestampT3 = 0 ; u32 BufferWordA = 0 ; u32 BufferWordB = 0 ; XAvb_RtcFormat Rtc [ 1 ] ; XAvb_WaitOnTxPtpQueue ( InstancePtr ) ; XAvb_ReadRtc ( InstancePtr -> Config . BaseAddress , Rtc ) ; TimestampT3 = XAvb_ReadPtpBuffer ( InstancePtr -> Config . BaseAddress , XAVB_PTP_TX_PDELAYRESP_OFFSET , XAVB_PTP_PKT_CAPTURED_TIMESTAMP_OFFSET ) + XAVB_TX_MAC_LATENCY_IN_NS ; TimestampT3 = TimestampT3 + InstancePtr -> PtpRecords . NsOffsetForPDelayResp ; if ( TimestampT3 >= XAVB_ONE_SECOND ) { TimestampT3 = TimestampT3 - XAVB_ONE_SECOND ; } if ( Rtc -> NanoSeconds < TimestampT3 ) { if ( Rtc -> SecondsLower == 0x00000000 ) { Rtc -> SecondsUpper = Rtc -> SecondsUpper - 0x1 ; } Rtc -> SecondsLower = Rtc -> SecondsLower - 0x1 ; } BufferWordA = XAvb_ReorderWord ( ( Rtc -> SecondsUpper << 16 ) | ( Rtc -> SecondsLower >> 16 ) ) ; XAvb_WritePtpBuffer ( InstancePtr -> Config . BaseAddress , XAVB_PTP_TX_PDELAYRESP_FOLLOW_UP_OFFSET , XAVB_PTP_TX_PKT_TIMESTAMP_UPPER_OFFSET , BufferWordA ) ; BufferWordA = XAvb_ReorderWord ( ( Rtc -> SecondsLower << 16 ) | ( TimestampT3 >> 16 ) ) ; XAvb_WritePtpBuffer ( InstancePtr -> Config . BaseAddress , XAVB_PTP_TX_PDELAYRESP_FOLLOW_UP_OFFSET , XAVB_PTP_TX_PKT_TIMESTAMP_MID_OFFSET , BufferWordA ) ; BufferWordA = XAvb_ReorderWord ( TimestampT3 << 16 ) ; BufferWordB = XAvb_ReadPtpBuffer ( InstancePtr -> Config . BaseAddress , XAVB_PTP_TX_PDELAYRESP_FOLLOW_UP_OFFSET , XAVB_PTP_TX_PKT_TIMESTAMP_LOWER_OFFSET ) ; BufferWordA &= 0x0000ffff ; BufferWordA |= ( BufferWordB & 0xffff0000 ) ; XAvb_WritePtpBuffer ( InstancePtr -> Config . BaseAddress , XAVB_PTP_TX_PDELAYRESP_FOLLOW_UP_OFFSET , XAVB_PTP_TX_PKT_TIMESTAMP_LOWER_OFFSET , BufferWordA ) ; XAvb_WriteReg ( InstancePtr -> Config . BaseAddress , XAVB_PTP_TX_CONTROL_OFFSET , XAVB_PTP_TX_SEND_PDELAYRESPFOLLOWUP_FRAME_MASK ) ; #ifdef DEBUG_XAVB_LEVEL3 xil_printf ( " \r \n " ) ; xil_printf ( " \r \n " ) ; xil_printf ( " \r \n " ) ; xil_printf ( " \r \n " , ( InstancePtr -> Config . BaseAddress + XAVB_PTP_TX_PDELAYRESP_OFFSET + XAVB_PTP_PKT_CAPTURED_TIMESTAMP_OFFSET ) ) ; xil_printf ( " \r \n " , TimestampT3 ) ; #endif }
A function to format then request the transmission of a PTP PDelay Response
Follow-Up Packet
A function to format then request the transmission of a PTP PDelay Response Follow - Up Packet
/** Wait until there are no PTP frames to be transmitted */ /** Format the Timestamp
   *---------------------*/ /** Capture the current Synchronised time */ /** Read the TimestampT3 for PDelayResp transmission and adjust it for MAC
   *  transmit latency */ /** The TimestampT3 was captured using syntonised ns time.  We need to
   * convert this into synchronised time by adding on the ns offset.  We
   * use the same offset here as for the PDelayResp frame since if a
   * ns offset change had been made between PDelayResp and ,
   * PDelayRespFollowUp, this would result in an error in the link delay
   * measurement. */ /** Check for ns wrap-around condition */ /** Even though we read the RTC value at the beginning of this
   * function, there would have been processing delay between the
   * actual reception (and timestamping) of the PDelayReq frame and the
   * start of this function.  During this time, the RTC seconds
   * field could have wrapped around.  We need to detect this and if it
   * has done, the slave seconds field would also have incremented (so
   * it needs to be set back).
   */ /** nanosec has wrapped since timestamp was taken so decrement the
     * seconds field */ /** Format the Timestamp (t3) into correct byte positioning for PTP frame
   *  storage, the write the Timestamp (t3) to the PDelayRespFollowUp frame
   */ /** Send the PDelayRespFollowUp Frame!
   *----------------------------------- */