i.MX‑RT1170: Question regarding correctness of ENET_Ptp1588GetTimer()

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

i.MX‑RT1170: Question regarding correctness of ENET_Ptp1588GetTimer()

660 次查看
michael_fischer
Contributor III

Hello,

I am working with the i.MX‑RT1170 ENET1588 hardware timestamping unit. While validating the accuracy of PTP timestamp reconstruction, I noticed a potential issue in the SDK function: ENET_Ptp1588GetTimer()

The function builds a timestamp consisting of:

  • handle->msTimerSecond (software second counter updated in the 1‑Hz PTP timer interrupt)
  • ATVR (hardware nanoseconds, captured via ATCR)
  • EIR & kENET_TsTimerInterrupt (wrap flag)

After testing various timing edge cases, I have found a problematic scenario where the function may return an incorrect value.

However, I don't have a test program for this; I've only played it through theoretically.

Problem description
The issue occurs when a wrap happens close to the nanosecond capture, but the 1‑Hz ISR (which increments msTimerSecond) cannot run because interrupts are disabled, or because we are already inside an ENET interrupt handler.

Sequence:

  1. The PTP hardware timestamp counter is close to the wrap event (e.g. around 3.999999990 seconds).
  2. Global interrupts become disabled (or we are inside an ENET ISR).
  3. A capture is performed via ATCR → the captured nanoseconds may still belong to the old second, e.g.
    t_nsec = 999999998.
  4. After the capture, but before interrupts are re‑enabled, the hardware second actually wraps to the next second. The hardware sets EIR & kENET_TsTimerInterrupt.
  5. However, the 1‑Hz ISR that increments msTimerSecond cannot run, so
    msTimerSecond still holds the old second value.
  6. ENET_Ptp1588GetTimer() interprets a set wrap flag ( if (0U != (base->EIR & (uint32_t)kENET_TsTimerInterrupt)) ) as “current time is in the new second” and returns: ptpTime->second++

This results in a timestamp such as: 4.999999998   (incorrect)
even though the correct time represented by the captured nanoseconds is: 3.999999998   (correct)

In other words:
The function cannot distinguish whether the wrap flag was set before or after the nanosecond capture, and therefore may add one second incorrectly.

Question
Is the current implementation of ENET_Ptp1588GetTimer() intended to work correctly under these timing conditions?

Specifically:

  • Does NXP consider it correct to use the wrap flag alone (without knowing whether it occurred before or after the nanosecond capture)?
  • Should the function read the wrap flag both before and after the ATCR capture in order to determine whether the wrap actually happened before the sampled nanoseconds?
  • Or is there an updated or recommended implementation for robust timestamp reconstruction on the i.MX‑RT1170?

Any clarification or guidance you can provide would be greatly appreciated.

Best regards,
Michael

0 项奖励
回复
3 回复数

614 次查看
Kan_Li
NXP TechSupport
NXP TechSupport

Hi @michael_fischer ,

 

Are you referring to the latest SDK version? The current code also checks the value of ptpTime->nanosecond on the step 6 - ENET_Ptp1588GetTimer() interprets a set wrap flag ( if (0U != (base->EIR & (uint32_t)kENET_TsTimerInterrupt)) ) as “current time is in the new second” and returns: ptpTime->second++

 

Please kindly clarify.

 

Have a great day,
Kan


-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

 

0 项奖励
回复

603 次查看
michael_fischer
Contributor III

Hello Kan,

reference was made to the SDK 25_12_00, here the function looks like:

void ENET_Ptp1588GetTimer(ENET_Type *base, enet_handle_t *handle, enet_ptp_time_t *ptpTime)
{
    assert(handle != NULL);
    assert(ptpTime != NULL);
    uint32_t primask;

    /* Disables the interrupt. */
    primask = DisableGlobalIRQ();

    ENET_Ptp1588GetTimerNoIrqDisable(base, handle, ptpTime);

    /* Get PTP timer wrap event. */
    if ((0U != (base->EIR & (uint32_t)kENET_TsTimerInterrupt)) && (ptpTime->nanosecond < (ENET_NANOSECOND_ONE_SECOND / 2)))
    {
        ptpTime->second++;
    }

    /* Enables the interrupt. */
    EnableGlobalIRQ(primask);
}

Yes, there is a check for the interrupt flag, and I think it's in the wrong place. That's why I'm asking. Here's my example with a check before and after:

static inline void GetTime (ptp_t *ptp, enet_ptp_time_t *ptpTime)
{
   ENET_Type *base = ptp->base;
   uint32_t   primask;
   uint32_t   t_nsec;
   
   /*
    * Note:
    *   - ptpSeconds is incremented ONLY in the 1-Hz ISR.
    *   - IRQs are disabled here, so ptpSeconds remains stable.
    *   - The EIR flag kENET_TsTimerInterrupt is sticky (HW sets it, ISR clears it).
    *     Therefore, we read it BEFORE and AFTER the capture to correctly detect
    *     whether the wrap occurred before or after the capture.
    */

   primask = DisableGlobalIRQ();

   /* Event before capture */
   const uint32_t e0 = base->EIR & (uint32_t)kENET_TsTimerInterrupt;

   /* Start to capture the nano seconds */
   base->ATCR |= ENET_ATCR_CAPTURE_MASK;
   while ( (base->ATCR & ENET_ATCR_CAPTURE_MASK) != 0U )
   {
      /* Wait until CAPTURE bit auto-clears */
   }
   t_nsec = base->ATVR;

   /* Event after capture */
   const uint32_t e1 = base->EIR & (uint32_t)kENET_TsTimerInterrupt;
   
   ptpTime->second = ptp->seconds;

   EnableGlobalIRQ(primask);
   
   /*
    * Note:
    *
    * The second-wrap flag (kENET_TsTimerInterrupt) is sticky and is cleared
    * only by the ISR. If this flag is set, there are two possible cases:
    *
    * 1) Real second rollover:
    *    - The nanoseconds value (nsec) right after the capture is very small
    *      (close to 0 ... a few microseconds).
    *    - In this case, the captured timestamp belongs to the NEW second -> sec = s + 1.
    *
    * 2) Old / stale flag:
    *    - The flag originates from an earlier rollover (the ISR has not yet cleared it).
    *    - The nanoseconds value is then large (far away from 0).
    *    - In this case, the captured timestamp still belongs to the OLD second -> sec = s.
    *
    * Therefore: If the wrap flag is set, increment the second only if nsec < THRESHOLD.
    */   
   if ((e0 == 0U) && (e1 == 0U))
   {
      /* No wrap, do nothing */
   }
   else if ((e0 == 0U) && (e1 != 0U))
   {
      /* Wrap after capture, t_nsec still belongs to the old second */
   }
   else
   {
      /* e0 != 0: wrap was already set check THRESHOLD */
      if (t_nsec < ENET_PTP_WRAP_NS_THRESHOLD)
      {
         ptpTime->second++;
      }   
   }

   ptpTime->nanosecond = t_nsec;
   
} /* GetTime */

I conducted tests in the "TsTimerInterrupt" to determine the value of t_nsec after the interrupt. The maximum value I found was 540ns. Therefore, I generously set THRESHOLD to 5000, which is 5µs.

I've also noticed now that you don't actually need the flag afterwards, but that you should save the flag beforehand, and only then perform the check after querying "ATVR".

Referring to the original NXP function, I would therefore note the flag before ENET_Ptp1588GetTimerNoIrqDisable, and then later increase the time based on the flag if necessary.

Best regards,
Michael

0 项奖励
回复

542 次查看
Kan_Li
NXP TechSupport
NXP TechSupport

Hi  @michael_fischer ,

 

Thanks for the clarification! Yes, your understanding is correct, and we recommend handling such adjustment on a higher layer, such as we implement it in an-ethernet-lwip-ptpd-imxrt , you may fetch this demo from the application code hub, and refer to enet_get_txframe_time() for details.  You may refer to https://docs.nxp.com/bundle/AN12149/page/topics/introduction.html for more details regarding this demo.

 

Hope that helps,

 

Have a great day,
Kan


-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

 

 

0 项奖励
回复
%3CLINGO-SUB%20id%3D%22lingo-sub-2321742%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3Ei.MX-RT1170%EF%BC%9A%E6%9C%89%E5%85%B3%20ENET_Ptp1588GetTimer()%20%E6%AD%A3%E7%A1%AE%E6%80%A7%E7%9A%84%E9%97%AE%E9%A2%98%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2321742%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CP%3E%E4%BD%A0%E5%A5%BD%3C%2FP%3E%3CP%3E%E6%88%91%E6%AD%A3%E5%9C%A8%E4%BD%BF%E7%94%A8%20i.MX-RT1170%20ENET1588%20%E7%A1%AC%E4%BB%B6%E6%97%B6%E9%97%B4%E6%88%B3%E5%8D%95%E5%85%83%E3%80%82%20%E5%9C%A8%E9%AA%8C%E8%AF%81%20PTP%20%E6%97%B6%E9%97%B4%E6%88%B3%E9%87%8D%E5%BB%BA%E7%9A%84%E5%87%86%E7%A1%AE%E6%80%A7%E6%97%B6%EF%BC%8C%E6%88%91%E6%B3%A8%E6%84%8F%E5%88%B0%20SDK%20%E5%87%BD%E6%95%B0%E4%B8%AD%E7%9A%84%E4%B8%80%E4%B8%AA%E6%BD%9C%E5%9C%A8%E9%97%AE%E9%A2%98%EF%BC%9AENET_Ptp1588GetTimer()%3C%2FP%3E%3CP%3E%E8%AF%A5%E5%87%BD%E6%95%B0%E7%94%9F%E6%88%90%E4%B8%80%E4%B8%AA%E6%97%B6%E9%97%B4%E6%88%B3%EF%BC%8C%E5%85%B6%E4%B8%AD%E5%8C%85%E5%90%AB%EF%BC%9A%3C%2FP%3E%3CUL%3E%3CLI%3Ehandle-%26gt%3BmsTimerSecond%EF%BC%88%E5%9C%A8%201%20%E8%B5%AB%E5%85%B9%20PTP%20%E5%AE%9A%E6%97%B6%E5%99%A8%E4%B8%AD%E6%96%AD%E4%B8%AD%E6%9B%B4%E6%96%B0%E7%9A%84%E8%BD%AF%E4%BB%B6%E7%A7%92%E8%AE%A1%E6%95%B0%E5%99%A8%EF%BC%89%3C%2FLI%3E%3CLI%3EATVR%EF%BC%88%E7%A1%AC%E4%BB%B6%E7%BA%B3%E7%A7%92%EF%BC%8C%E9%80%9A%E8%BF%87%20ATCR%20%E6%8D%95%E8%8E%B7%EF%BC%89%3C%2FLI%3E%3CLI%3EEIR%26amp%3B%20kENET_TsTimerInterrupt%EF%BC%88%E5%8C%85%E8%A3%85%E6%A0%87%E5%BF%97%EF%BC%89%3C%2FLI%3E%3C%2FUL%3E%3CP%3E%E5%9C%A8%E6%B5%8B%E8%AF%95%E4%BA%86%E5%90%84%E7%A7%8D%E6%97%B6%E5%BA%8F%E8%BE%B9%E7%BC%98%E6%83%85%E5%86%B5%E5%90%8E%EF%BC%8C%E6%88%91%E5%8F%91%E7%8E%B0%E4%BA%86%E4%B8%80%E4%B8%AA%E6%9C%89%E9%97%AE%E9%A2%98%E7%9A%84%E6%83%85%E5%86%B5%EF%BC%8C%E5%8D%B3%E5%87%BD%E6%95%B0%E5%8F%AF%E8%83%BD%E4%BC%9A%E8%BF%94%E5%9B%9E%E4%B8%80%E4%B8%AA%E4%B8%8D%E6%AD%A3%E7%A1%AE%E7%9A%84%E5%80%BC%E3%80%82%3C%2FP%3E%3CP%3E%E4%B8%8D%E8%BF%87%EF%BC%8C%E6%88%91%E6%B2%A1%E6%9C%89%E8%BF%99%E6%96%B9%E9%9D%A2%E7%9A%84%E6%B5%8B%E8%AF%95%E7%A8%8B%E5%BA%8F%EF%BC%8C%E5%8F%AA%E6%98%AF%E5%9C%A8%E7%90%86%E8%AE%BA%E4%B8%8A%E7%8E%A9%E4%BA%86%E4%B8%80%E9%81%8D%E3%80%82%3C%2FP%3E%3CP%3E%3CSTRONG%3E%E9%97%AE%E9%A2%98%E6%8F%8F%E8%BF%B0%3CBR%20%2F%3E%3C%2FSTRONG%3E%E5%BD%93%3CSTRONG%3E%E5%8C%85%E8%A3%B9%E5%8F%91%E7%94%9F%E5%9C%A8%E6%8E%A5%E8%BF%91%E7%BA%B3%E7%A7%92%E6%8D%95%E8%8E%B7%3C%2FSTRONG%3E%E6%97%B6%EF%BC%8C%E5%B0%B1%E4%BC%9A%E5%87%BA%E7%8E%B0%E9%97%AE%E9%A2%98%EF%BC%8C%E4%BD%86%E6%98%AF%201Hz%20ISR%EF%BC%88%E4%BB%A5%20mstimerSecond%20%E4%B8%BA%E5%A2%9E%E9%87%8F%EF%BC%89%E6%97%A0%E6%B3%95%E8%BF%90%E8%A1%8C%EF%BC%8C%E5%9B%A0%E4%B8%BA%E4%B8%AD%E6%96%AD%E8%A2%AB%E7%A6%81%E7%94%A8%EF%BC%8C%E6%88%96%E8%80%85%E5%9B%A0%E4%B8%BA%E6%88%91%E4%BB%AC%E5%B7%B2%E7%BB%8F%E5%9C%A8%20ENET%20%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86%E7%A8%8B%E5%BA%8F%E4%B8%AD%E4%BA%86%E3%80%82%3C%2FP%3E%3CP%3E%E9%A1%BA%E5%BA%8F%EF%BC%9A%3C%2FP%3E%3COL%3E%3CLI%3EPTP%20%E7%A1%AC%E4%BB%B6%E6%97%B6%E9%97%B4%E6%88%B3%E8%AE%A1%E6%95%B0%E5%99%A8%E6%8E%A5%E8%BF%91%E5%8C%85%E7%BB%9C%E4%BA%8B%E4%BB%B6%EF%BC%88%E4%BE%8B%E5%A6%82%E7%BA%A6%3CSTRONG%3E3.999999990%20%E7%A7%92%3C%2FSTRONG%3E%EF%BC%89%E3%80%82%3C%2FLI%3E%3CLI%3E%E5%85%A8%E5%B1%80%E4%B8%AD%E6%96%AD%E8%A2%AB%E7%A6%81%E7%94%A8%EF%BC%88%E6%88%96%E8%80%85%E6%88%91%E4%BB%AC%E6%AD%A3%E5%9C%A8%20ENET%20ISR%20%E4%B8%AD%EF%BC%89%E3%80%82%3C%2FLI%3E%3CLI%3E%E6%8D%95%E8%8E%B7%E6%98%AF%E9%80%9A%E8%BF%87%20ATCR%20%E6%89%A7%E8%A1%8C%E7%9A%84%20%E2%86%92%20%E6%8D%95%E8%8E%B7%E7%9A%84%E7%BA%B3%E7%A7%92%E5%8F%AF%E8%83%BD%E4%BB%8D%E5%B1%9E%E4%BA%8E%3CSTRONG%3E%E6%97%A7%E7%A7%92%3C%2FSTRONG%3E%EF%BC%8C%E4%BE%8B%E5%A6%82%20%3CBR%20%2F%3E%20t_nsec%20%3D%20999999998%E3%80%82%3C%2FLI%3E%3CLI%3E%E5%9C%A8%E6%8D%95%E8%8E%B7%40%40%20%3CSTRONG%3E%E4%B9%8B%E5%90%8E%3C%2FSTRONG%3E%EF%BC%8C%E4%BD%86%E5%9C%A8%E9%87%8D%E6%96%B0%E5%90%AF%E7%94%A8%E4%B8%AD%E6%96%AD%3CSTRONG%3E%E4%B9%8B%E5%89%8D%3C%2FSTRONG%3E%EF%BC%8C%E7%A1%AC%E4%BB%B6%E7%A7%92%E5%AE%9E%E9%99%85%E4%B8%8A%E4%BC%9A%E6%8A%98%E5%8F%A0%E5%88%B0%E4%B8%8B%E4%B8%80%E7%A7%92%E3%80%82%E7%A1%AC%E4%BB%B6%E8%AE%BE%E7%BD%AE%20EIR%26amp%3B%20kENET_TsTimerInterrupt%E3%80%82%3C%2FLI%3E%3CLI%3E%E4%BD%86%E6%98%AF%EF%BC%8C%E9%80%92%E5%A2%9E%20msTimerSecond%20%E7%9A%84%201-Hz%20ISR%20%E6%97%A0%E6%B3%95%E8%BF%90%E8%A1%8C%EF%BC%8C%E5%9B%A0%E6%AD%A4%3CBR%20%2F%3EmsTimerSecond%20%E4%BB%8D%E4%BF%9D%E6%8C%81%3CSTRONG%3E%E6%97%A7%E7%9A%84%3C%2FSTRONG%3E%E7%A7%92%E5%80%BC%E3%80%82%3C%2FLI%3E%3CLI%3EENET_Ptp1588GetTimer()%E5%B0%86%3CEM%3E%E5%B7%B2%E8%AE%BE%E7%BD%AE%E7%9A%84%E6%8D%A2%E8%A1%8C%E6%A0%87%E5%BF%97%3C%2FEM%3E%EF%BC%88if%20(0U%20!%3D%20(base-%26gt%3BEIR%26amp%3B%20(uint32_t)kENET_TsTimerInterrupt))%20%EF%BC%89%E8%A7%A3%E9%87%8A%E4%B8%BA%20%22%E5%BD%93%E5%89%8D%E6%97%B6%E9%97%B4%E6%98%AF%E6%96%B0%E7%A7%92%22%EF%BC%8C%E5%B9%B6%E8%BF%94%E5%9B%9E%EF%BC%9AptpTime-%26gt%3Bsecond%2B%2B%2B%2B%3C%2FLI%3E%3C%2FOL%3E%3CP%3E%3CBR%20%2F%3E%E5%B0%BD%E7%AE%A1%E6%8D%95%E8%8E%B7%E7%9A%84%E7%BA%B3%E7%A7%92%E8%A1%A8%E7%A4%BA%E7%9A%84%E6%AD%A3%E7%A1%AE%E6%97%B6%E9%97%B4%E4%B8%BA%EF%BC%9A3.999999998%EF%BC%88%E6%AD%A3%E7%A1%AE%EF%BC%89%EF%BC%8C%E4%BD%86%E8%BF%99%E4%BC%9A%E5%AF%BC%E8%87%B4%E6%97%B6%E9%97%B4%E6%88%B3%E5%A6%82%EF%BC%9A4.999999998%EF%BC%88%E4%B8%8D%E6%AD%A3%E7%A1%AE%EF%BC%89%3C%2FP%3E%3CP%3E%E6%8D%A2%E5%8F%A5%E8%AF%9D%E8%AF%B4%EF%BC%9A%3CBR%20%2F%3E%E8%AF%A5%E5%87%BD%E6%95%B0%E6%97%A0%E6%B3%95%E5%8C%BA%E5%88%86%E6%8D%A2%E8%A1%8C%E6%A0%87%E5%BF%97%E6%98%AF%E5%9C%A8%E7%BA%B3%E7%A7%92%E6%8D%95%E8%8E%B7%3CSTRONG%3E%E4%B9%8B%E5%89%8D%3C%2FSTRONG%3E%E8%BF%98%E6%98%AF%3CSTRONG%3E%E4%B9%8B%E5%90%8E%3C%2FSTRONG%3E%E8%AE%BE%E7%BD%AE%E7%9A%84%EF%BC%8C%E5%9B%A0%E6%AD%A4%E5%8F%AF%E8%83%BD%E4%BC%9A%E9%94%99%E8%AF%AF%E5%9C%B0%E6%B7%BB%E5%8A%A0%E4%B8%80%E7%A7%92%E3%80%82%3CBR%20%2F%3E%3CBR%20%2F%3E%3C%2FP%3E%3CP%3E%3CSTRONG%3E%E9%97%AE%E9%A2%98%3CBR%20%2F%3E%3C%2FSTRONG%3EENET_Ptp1588GetTimer()%20%E7%9B%AE%E5%89%8D%E7%9A%84%E5%AE%9E%E7%8E%B0%E6%98%AF%E5%90%A6%E6%89%93%E7%AE%97%E5%9C%A8%E8%BF%99%E4%BA%9B%E6%97%B6%E5%BA%8F%E6%9D%A1%E4%BB%B6%E4%B8%8B%E6%AD%A3%E5%B8%B8%E5%B7%A5%E4%BD%9C%EF%BC%9F%3C%2FP%3E%3CP%3E%E5%85%B7%E4%BD%93%E6%9D%A5%E8%AF%B4%3C%2FP%3E%3CUL%3E%3CLI%3E%E6%81%A9%E6%99%BA%E6%B5%A6%E6%98%AF%E5%90%A6%E8%AE%A4%E4%B8%BA%E5%8D%95%E7%8B%AC%E4%BD%BF%E7%94%A8%E5%8C%85%E8%A3%85%E6%A0%87%E5%BF%97%EF%BC%88%E4%B8%8D%E7%9F%A5%E9%81%93%E5%AE%83%E6%98%AF%E5%9C%A8%E7%BA%B3%E7%A7%92%E6%8D%95%E8%8E%B7%3CEM%3E%E4%B9%8B%E5%89%8D%3C%2FEM%3E%E8%BF%98%E6%98%AF%3CEM%3E%E4%B9%8B%E5%90%8E%3C%2FEM%3E%E5%8F%91%E7%94%9F%E7%9A%84%EF%BC%89%EF%BC%9F%3C%2FLI%3E%3CLI%3E%E8%AF%A5%E5%87%BD%E6%95%B0%E6%98%AF%E5%90%A6%E5%BA%94%E8%AF%A5%E5%9C%A8%E6%8D%95%E8%8E%B7%20ATCR%20%3CSTRONG%3E%E4%B9%8B%E5%89%8D%E5%92%8C%E4%B9%8B%E5%90%8E%3C%2FSTRONG%3E%E8%AF%BB%E5%8F%96%E6%8D%A2%E8%A1%8C%E6%A0%87%E5%BF%97%EF%BC%8C%E4%BB%A5%E7%A1%AE%E5%AE%9A%E5%8C%85%E8%A3%B9%E6%98%AF%E5%90%A6%E7%9C%9F%E7%9A%84%E5%8F%91%E7%94%9F%E5%9C%A8%E9%87%87%E6%A0%B7%E7%BA%B3%E7%A7%92%E4%B9%8B%E5%89%8D%EF%BC%9F%3C%2FLI%3E%3CLI%3E%E6%88%96%E8%80%85%E5%9C%A8%20i.MX-RT1170%20%E4%B8%8A%E6%98%AF%E5%90%A6%E6%9C%89%E6%9B%B4%E6%96%B0%E6%88%96%E6%8E%A8%E8%8D%90%E7%9A%84%E7%A8%B3%E5%81%A5%E6%97%B6%E9%97%B4%E6%88%B3%E9%87%8D%E6%9E%84%E5%AE%9E%E7%8E%B0%EF%BC%9F%3C%2FLI%3E%3C%2FUL%3E%3CP%3E%E5%A6%82%E6%9E%9C%E6%82%A8%E8%83%BD%E6%8F%90%E4%BE%9B%E4%BB%BB%E4%BD%95%E8%AF%B4%E6%98%8E%E6%88%96%E6%8C%87%E5%AF%BC%EF%BC%8C%E6%88%91%E4%BB%AC%E5%B0%86%E4%B8%8D%E8%83%9C%E6%84%9F%E6%BF%80%E3%80%82%3C%2FP%3E%3CP%3E%E8%87%B4%E4%BB%A5%E6%9C%80%E8%AF%9A%E6%8C%9A%E7%9A%84%E9%97%AE%E5%80%99%EF%BC%8C%3CBR%20%2F%3EMichael%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2322949%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%20translate%3D%22no%22%3ERe%3A%20i.MX%E2%80%91RT1170%3A%20Question%20regarding%20correctness%20of%20ENET_Ptp1588GetTimer()%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2322949%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CP%3E%E4%BD%A0%E5%A5%BD%EF%BC%8CKan%E3%80%81%3C%2FP%3E%3CP%3E%E5%8F%82%E8%80%83%E4%BA%86%20SDK%2025_12_00%EF%BC%8C%E8%BF%99%E9%87%8C%E7%9A%84%E5%87%BD%E6%95%B0%E5%A6%82%E4%B8%8B%E6%89%80%E7%A4%BA%EF%BC%9A%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-c%22%3E%3CCODE%20translate%3D%22no%22%3Evoid%20ENET_Ptp1588GetTimer(ENET_Type%20*base%2C%20enet_handle_t%20*handle%2C%20enet_ptp_time_t%20*ptpTime)%0A%7B%0A%20%20%20%20assert(handle%20!%3D%20NULL)%3B%0A%20%20%20%20assert(ptpTime%20!%3D%20NULL)%3B%0A%20%20%20%20uint32_t%20primask%3B%0A%0A%20%20%20%20%2F*%20Disables%20the%20interrupt.%20*%2F%0A%20%20%20%20primask%20%3D%20DisableGlobalIRQ()%3B%0A%0A%20%20%20%20ENET_Ptp1588GetTimerNoIrqDisable(base%2C%20handle%2C%20ptpTime)%3B%0A%0A%20%20%20%20%2F*%20Get%20PTP%20timer%20wrap%20event.%20*%2F%0A%20%20%20%20if%20((0U%20!%3D%20(base-%26gt%3BEIR%20%26amp%3B%20(uint32_t)kENET_TsTimerInterrupt))%20%26amp%3B%26amp%3B%20(ptpTime-%26gt%3Bnanosecond%20%26lt%3B%20(ENET_NANOSECOND_ONE_SECOND%20%2F%202)))%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20ptpTime-%26gt%3Bsecond%2B%2B%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F*%20Enables%20the%20interrupt.%20*%2F%0A%20%20%20%20EnableGlobalIRQ(primask)%3B%0A%7D%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%E6%98%AF%E7%9A%84%EF%BC%8C%E6%9C%89%E4%B8%80%E4%B8%AA%E4%B8%AD%E6%96%AD%E6%A0%87%E5%BF%97%E6%A3%80%E6%9F%A5%EF%BC%8C%E4%BD%86%E6%88%91%E8%AE%A4%E4%B8%BA%E5%AE%83%E6%94%BE%E9%94%99%E4%BA%86%E5%9C%B0%E6%96%B9%E3%80%82%E8%BF%99%E5%B0%B1%E6%98%AF%E6%88%91%E9%97%AE%E8%BF%99%E4%B8%AA%E9%97%AE%E9%A2%98%E7%9A%84%E5%8E%9F%E5%9B%A0%E3%80%82%E4%B8%8B%E9%9D%A2%E6%98%AF%E6%88%91%E7%9A%84%E4%BE%8B%E5%AD%90%EF%BC%8C%E5%89%8D%E5%90%8E%E8%BF%9B%E8%A1%8C%E4%BA%86%E6%A3%80%E6%9F%A5%EF%BC%9A%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-c%22%3E%3CCODE%20translate%3D%22no%22%3Estatic%20inline%20void%20GetTime%20(ptp_t%20*ptp%2C%20enet_ptp_time_t%20*ptpTime)%0A%7B%0A%20%20%20ENET_Type%20*base%20%3D%20ptp-%26gt%3Bbase%3B%0A%20%20%20uint32_t%20%20%20primask%3B%0A%20%20%20uint32_t%20%20%20t_nsec%3B%0A%20%20%20%0A%20%20%20%2F*%0A%20%20%20%20*%20Note%3A%0A%20%20%20%20*%20%20%20-%20ptpSeconds%20is%20incremented%20ONLY%20in%20the%201-Hz%20ISR.%0A%20%20%20%20*%20%20%20-%20IRQs%20are%20disabled%20here%2C%20so%20ptpSeconds%20remains%20stable.%0A%20%20%20%20*%20%20%20-%20The%20EIR%20flag%20kENET_TsTimerInterrupt%20is%20sticky%20(HW%20sets%20it%2C%20ISR%20clears%20it).%0A%20%20%20%20*%20%20%20%20%20Therefore%2C%20we%20read%20it%20BEFORE%20and%20AFTER%20the%20capture%20to%20correctly%20detect%0A%20%20%20%20*%20%20%20%20%20whether%20the%20wrap%20occurred%20before%20or%20after%20the%20capture.%0A%20%20%20%20*%2F%0A%0A%20%20%20primask%20%3D%20DisableGlobalIRQ()%3B%0A%0A%20%20%20%2F*%20Event%20before%20capture%20*%2F%0A%20%20%20const%20uint32_t%20e0%20%3D%20base-%26gt%3BEIR%20%26amp%3B%20(uint32_t)kENET_TsTimerInterrupt%3B%0A%0A%20%20%20%2F*%20Start%20to%20capture%20the%20nano%20seconds%20*%2F%0A%20%20%20base-%26gt%3BATCR%20%7C%3D%20ENET_ATCR_CAPTURE_MASK%3B%0A%20%20%20while%20(%20(base-%26gt%3BATCR%20%26amp%3B%20ENET_ATCR_CAPTURE_MASK)%20!%3D%200U%20)%0A%20%20%20%7B%0A%20%20%20%20%20%20%2F*%20Wait%20until%20CAPTURE%20bit%20auto-clears%20*%2F%0A%20%20%20%7D%0A%20%20%20t_nsec%20%3D%20base-%26gt%3BATVR%3B%0A%0A%20%20%20%2F*%20Event%20after%20capture%20*%2F%0A%20%20%20const%20uint32_t%20e1%20%3D%20base-%26gt%3BEIR%20%26amp%3B%20(uint32_t)kENET_TsTimerInterrupt%3B%0A%20%20%20%0A%20%20%20ptpTime-%26gt%3Bsecond%20%3D%20ptp-%26gt%3Bseconds%3B%0A%0A%20%20%20EnableGlobalIRQ(primask)%3B%0A%20%20%20%0A%20%20%20%2F*%0A%20%20%20%20*%20Note%3A%0A%20%20%20%20*%0A%20%20%20%20*%20The%20second-wrap%20flag%20(kENET_TsTimerInterrupt)%20is%20sticky%20and%20is%20cleared%0A%20%20%20%20*%20only%20by%20the%20ISR.%20If%20this%20flag%20is%20set%2C%20there%20are%20two%20possible%20cases%3A%0A%20%20%20%20*%0A%20%20%20%20*%201)%20Real%20second%20rollover%3A%0A%20%20%20%20*%20%20%20%20-%20The%20nanoseconds%20value%20(nsec)%20right%20after%20the%20capture%20is%20very%20small%0A%20%20%20%20*%20%20%20%20%20%20(close%20to%200%20...%20a%20few%20microseconds).%0A%20%20%20%20*%20%20%20%20-%20In%20this%20case%2C%20the%20captured%20timestamp%20belongs%20to%20the%20NEW%20second%20-%26gt%3B%20sec%20%3D%20s%20%2B%201.%0A%20%20%20%20*%0A%20%20%20%20*%202)%20Old%20%2F%20stale%20flag%3A%0A%20%20%20%20*%20%20%20%20-%20The%20flag%20originates%20from%20an%20earlier%20rollover%20(the%20ISR%20has%20not%20yet%20cleared%20it).%0A%20%20%20%20*%20%20%20%20-%20The%20nanoseconds%20value%20is%20then%20large%20(far%20away%20from%200).%0A%20%20%20%20*%20%20%20%20-%20In%20this%20case%2C%20the%20captured%20timestamp%20still%20belongs%20to%20the%20OLD%20second%20-%26gt%3B%20sec%20%3D%20s.%0A%20%20%20%20*%0A%20%20%20%20*%20Therefore%3A%20If%20the%20wrap%20flag%20is%20set%2C%20increment%20the%20second%20only%20if%20nsec%20%26lt%3B%20THRESHOLD.%0A%20%20%20%20*%2F%20%20%20%0A%20%20%20if%20((e0%20%3D%3D%200U)%20%26amp%3B%26amp%3B%20(e1%20%3D%3D%200U))%0A%20%20%20%7B%0A%20%20%20%20%20%20%2F*%20No%20wrap%2C%20do%20nothing%20*%2F%0A%20%20%20%7D%0A%20%20%20else%20if%20((e0%20%3D%3D%200U)%20%26amp%3B%26amp%3B%20(e1%20!%3D%200U))%0A%20%20%20%7B%0A%20%20%20%20%20%20%2F*%20Wrap%20after%20capture%2C%20t_nsec%20still%20belongs%20to%20the%20old%20second%20*%2F%0A%20%20%20%7D%0A%20%20%20else%0A%20%20%20%7B%0A%20%20%20%20%20%20%2F*%20e0%20!%3D%200%3A%20wrap%20was%20already%20set%20check%20THRESHOLD%20*%2F%0A%20%20%20%20%20%20if%20(t_nsec%20%26lt%3B%20ENET_PTP_WRAP_NS_THRESHOLD)%0A%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20ptpTime-%26gt%3Bsecond%2B%2B%3B%0A%20%20%20%20%20%20%7D%20%20%20%0A%20%20%20%7D%0A%0A%20%20%20ptpTime-%26gt%3Bnanosecond%20%3D%20t_nsec%3B%0A%20%20%20%0A%7D%20%2F*%20GetTime%20*%2F%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%E6%88%91%E5%9C%A8%22TsTimerInterrupt%22%20%E4%B8%AD%E8%BF%9B%E8%A1%8C%E4%BA%86%E6%B5%8B%E8%AF%95%EF%BC%8C%E4%BB%A5%E7%A1%AE%E5%AE%9A%E4%B8%AD%E6%96%AD%E5%90%8E%20t_nsec%20%E7%9A%84%E5%80%BC%E3%80%82%E6%88%91%E5%8F%91%E7%8E%B0%E7%9A%84%E6%9C%80%E5%A4%A7%E5%80%BC%E6%98%AF%20540ns%E3%80%82%E5%9B%A0%E6%AD%A4%EF%BC%8C%E6%88%91%E6%85%B7%E6%85%A8%E5%9C%B0%E5%B0%86%20THRESHOLD%20%E8%AE%BE%E7%BD%AE%E4%B8%BA%205000%EF%BC%8C%E5%8D%B3%205%20%E5%BE%AE%E7%A7%92%E3%80%82%3C%2FP%3E%3CP%3E%E6%88%91%E7%8E%B0%E5%9C%A8%E8%BF%98%E6%B3%A8%E6%84%8F%E5%88%B0%EF%BC%8C%E6%82%A8%E5%85%B6%E5%AE%9E%E5%B9%B6%E4%B8%8D%E9%9C%80%E8%A6%81%E4%BA%8B%E5%90%8E%E4%BF%9D%E5%AD%98%E6%A0%87%E8%AE%B0%EF%BC%8C%E8%80%8C%E6%98%AF%E5%BA%94%E8%AF%A5%E4%BA%8B%E5%85%88%E4%BF%9D%E5%AD%98%E6%A0%87%E8%AE%B0%EF%BC%8C%E7%84%B6%E5%90%8E%E5%9C%A8%E6%9F%A5%E8%AF%A2%22ATVR%22%20%E5%90%8E%E5%86%8D%E6%89%A7%E8%A1%8C%E6%A3%80%E6%9F%A5%E3%80%82%3C%2FP%3E%3CP%3E%E5%9B%A0%E6%AD%A4%EF%BC%8C%E5%8F%82%E7%85%A7%E6%81%A9%E6%99%BA%E6%B5%A6%E7%9A%84%E5%8E%9F%E5%A7%8B%E5%87%BD%E6%95%B0%EF%BC%8C%E6%88%91%E4%BC%9A%E5%9C%A8%20ENET_Ptp1588GetTimerNoIrqDisable%20%E4%B9%8B%E5%89%8D%E6%B3%A8%E6%84%8F%E8%AF%A5%E6%A0%87%E8%AE%B0%EF%BC%8C%E7%84%B6%E5%90%8E%E5%9C%A8%E5%BF%85%E8%A6%81%E6%97%B6%E6%A0%B9%E6%8D%AE%E8%AF%A5%E6%A0%87%E8%AE%B0%E5%A2%9E%E5%8A%A0%E6%97%B6%E9%97%B4%E3%80%82%3C%2FP%3E%3CP%3E%E8%87%B4%E4%BB%A5%E6%9C%80%E8%AF%9A%E6%8C%9A%E7%9A%84%E9%97%AE%E5%80%99%EF%BC%8C%3CBR%20%2F%3EMichael%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2322923%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%20translate%3D%22no%22%3ERe%3A%20i.MX%E2%80%91RT1170%3A%20Question%20regarding%20correctness%20of%20ENET_Ptp1588GetTimer()%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2322923%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CP%3E%E5%97%A8%EF%BC%8C%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F214553%22%20target%3D%22_blank%22%3E%40michael_fischer%3C%2FA%3E%E3%80%81%3C%2FP%3E%0A%3CBR%20%2F%3E%0A%3CP%3E%E6%82%A8%E6%8C%87%E7%9A%84%E6%98%AF%E6%9C%80%E6%96%B0%E7%9A%84%20SDK%20%E7%89%88%E6%9C%AC%E5%90%97%EF%BC%9F%E5%BD%93%E5%89%8D%E4%BB%A3%E7%A0%81%E8%BF%98%3CSPAN%3E%E5%9C%A8%E7%AC%AC%206%20%E6%AD%A5%20%3C%2FSPAN%3E%E6%A3%80%E6%9F%A5ptpTime-%26gt%3B%E7%BA%B3%E7%A7%92%E7%9A%84%20%E5%80%BC-%20ENET_Ptp1588GetTimer()%20%E5%B0%86%3CEM%3E%E5%B7%B2%E8%AE%BE%E7%BD%AE%E7%9A%84%E6%8D%A2%E8%A1%8C%E6%A0%87%E5%BF%97%3C%2FEM%3E(%20if%20(0U%20!%3D%20(base-%26gt%3BEIR%26amp%3B%20(uint32_t)kENET_TsTimerInterrupt))%20%E8%A7%A3%E9%87%8A%E4%B8%BA%20%22%E5%BD%93%E5%89%8D%E6%97%B6%E9%97%B4%E4%BD%8D%E4%BA%8E%E6%96%B0%E7%A7%92%22%EF%BC%8C%E5%B9%B6%E8%BF%94%E5%9B%9E%EF%BC%9A%20ptpTime-%26gt%3Bsecond%2B%2B%2B%2B%3C%2FP%3E%0A%3CBR%20%2F%3E%0A%3CP%3E%E8%AF%B7%E4%BA%88%E4%BB%A5%E6%BE%84%E6%B8%85%E3%80%82%3C%2FP%3E%0A%3CBR%20%2F%3E%0A%3CP%3E%E7%A5%9D%E6%82%A8%E6%84%89%E5%BF%AB%EF%BC%8C%3CBR%20%2F%3EKan%3C%2FP%3E%0A%3CP%3E%3CBR%20%2F%3E-------------------------------------------------------------------------------%3CBR%20%2F%3E%E6%B3%A8%EF%BC%9A%3CBR%20%2F%3E-%20%E5%A6%82%E6%9E%9C%E6%9C%AC%E5%B8%96%E5%9B%9E%E7%AD%94%E4%BA%86%E6%82%A8%E7%9A%84%E9%97%AE%E9%A2%98%EF%BC%8C%E8%AF%B7%E7%82%B9%E5%87%BB%22%E6%A0%87%E8%AE%B0%E6%AD%A3%E7%A1%AE%22%20%E6%8C%89%E9%92%AE%E3%80%82%E8%B0%A2%E8%B0%A2%EF%BC%81%3CBR%20%2F%3E-%20%E6%88%91%E4%BB%AC%E4%BC%9A%E5%9C%A8%E6%9C%80%E5%90%8E%E4%B8%80%E6%AC%A1%E5%8F%91%E5%B8%96%E5%90%8E%E7%9A%84%207%20%E5%91%A8%E5%86%85%E8%B7%9F%E8%B8%AA%E4%B8%BB%E9%A2%98%EF%BC%8C%E4%B9%8B%E5%90%8E%E7%9A%84%E5%9B%9E%E5%A4%8D%E5%B0%86%E8%A2%AB%E5%BF%BD%E7%95%A5%3CBR%20%2F%3E%E5%A6%82%E6%9E%9C%E6%82%A8%E4%BB%A5%E5%90%8E%E6%9C%89%E7%9B%B8%E5%85%B3%E9%97%AE%E9%A2%98%EF%BC%8C%E8%AF%B7%E6%89%93%E5%BC%80%E4%B8%80%E4%B8%AA%E6%96%B0%E4%B8%BB%E9%A2%98%E5%B9%B6%E5%8F%82%E8%80%83%E5%B7%B2%E5%85%B3%E9%97%AD%E7%9A%84%E4%B8%BB%E9%A2%98%E3%80%82%3CBR%20%2F%3E-------------------------------------------------------------------------------%3C%2FP%3E%0A%3CBR%20%2F%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2325376%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%20translate%3D%22no%22%3ERe%3A%20i.MX%E2%80%91RT1170%3A%20Question%20regarding%20correctness%20of%20ENET_Ptp1588GetTimer()%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2325376%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CP%3E%E5%97%A8%EF%BC%8C%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F214553%22%20target%3D%22_blank%22%3E%40michael_fischer%3C%2FA%3E%E3%80%81%3C%2FP%3E%0A%3CBR%20%2F%3E%0A%3CP%3E%E8%B0%A2%E8%B0%A2%E4%BD%A0%E7%9A%84%E6%BE%84%E6%B8%85%EF%BC%81%E6%98%AF%E7%9A%84%EF%BC%8C%E6%82%A8%E7%9A%84%E7%90%86%E8%A7%A3%E6%98%AF%E6%AD%A3%E7%A1%AE%E7%9A%84%EF%BC%8C%E6%88%91%E4%BB%AC%E5%BB%BA%E8%AE%AE%E5%9C%A8%E6%9B%B4%E9%AB%98%E7%9A%84%E5%B1%82%E4%B8%8A%E8%BF%9B%E8%A1%8C%E6%AD%A4%E7%B1%BB%E8%B0%83%E6%95%B4%EF%BC%8C%E4%BE%8B%E5%A6%82%E6%88%91%E4%BB%AC%E5%9C%A8%3CSPAN%20data-teams%3D%22true%22%3E%E4%BB%A5%E5%A4%AA%E7%BD%91-lwip-ptpd-imxrt%E4%B8%AD%E5%AE%9E%E7%8E%B0%E4%BA%86%E8%B0%83%E6%95%B4%EF%BC%8C%E6%82%A8%E5%8F%AF%E4%BB%A5%E4%BB%8E%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E4%BB%A3%E7%A0%81%E4%B8%AD%E5%BF%83%E8%8E%B7%E5%8F%96%E6%AD%A4%E6%BC%94%E7%A4%BA%EF%BC%8C%E5%B9%B6%E5%8F%82%E9%98%85%20enet_get_txframe_time%20()%20%E4%BA%86%E8%A7%A3%E8%AF%A6%E7%BB%86%E4%BF%A1%E6%81%AF%E3%80%82%E4%BD%A0%E5%8F%AF%E4%BB%A5%E5%8F%82%E9%98%85%20%3CA%20href%3D%22https%3A%2F%2Fdocs.nxp.com%2Fbundle%2FAN12149%2Fpage%2Ftopics%2Fintroduction.html%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3Ehttps%3A%2F%2Fdocs.nxp.com%2Fbundle%2FAN12149%2Fpage%2Ftopics%2Fintroduction.html%3C%2FA%3E%20%E4%BA%86%E8%A7%A3%E6%9C%89%E5%85%B3%E8%BF%99%E4%B8%AA%E6%BC%94%E7%A4%BA%E7%9A%84%E6%9B%B4%E5%A4%9A%E7%BB%86%E8%8A%82%E3%80%82%3C%2FSPAN%3E%3C%2FP%3E%0A%3CBR%20%2F%3E%0A%3CP%3E%3CSPAN%20data-teams%3D%22true%22%3E%E5%B8%8C%E6%9C%9B%E5%AF%B9%E4%BD%A0%E6%9C%89%E6%89%80%E5%B8%AE%E5%8A%A9%E3%80%81%3C%2FSPAN%3E%3C%2FP%3E%0A%3CBR%20%2F%3E%0A%3CP%3E%E7%A5%9D%E6%82%A8%E6%84%89%E5%BF%AB%EF%BC%8C%3CBR%20%2F%3EKan%3C%2FP%3E%0A%3CP%3E%3CBR%20%2F%3E-------------------------------------------------------------------------------%3CBR%20%2F%3E%E6%B3%A8%EF%BC%9A%3CBR%20%2F%3E-%20%E5%A6%82%E6%9E%9C%E6%9C%AC%E5%B8%96%E5%9B%9E%E7%AD%94%E4%BA%86%E6%82%A8%E7%9A%84%E9%97%AE%E9%A2%98%EF%BC%8C%E8%AF%B7%E7%82%B9%E5%87%BB%22%E6%A0%87%E8%AE%B0%E6%AD%A3%E7%A1%AE%22%20%E6%8C%89%E9%92%AE%E3%80%82%E8%B0%A2%E8%B0%A2%EF%BC%81%3CBR%20%2F%3E-%20%E6%88%91%E4%BB%AC%E4%BC%9A%E5%9C%A8%E6%9C%80%E5%90%8E%E4%B8%80%E6%AC%A1%E5%8F%91%E5%B8%96%E5%90%8E%E7%9A%84%207%20%E5%91%A8%E5%86%85%E8%B7%9F%E8%B8%AA%E4%B8%BB%E9%A2%98%EF%BC%8C%E4%B9%8B%E5%90%8E%E7%9A%84%E5%9B%9E%E5%A4%8D%E5%B0%86%E8%A2%AB%E5%BF%BD%E7%95%A5%3CBR%20%2F%3E%E5%A6%82%E6%9E%9C%E6%82%A8%E4%BB%A5%E5%90%8E%E6%9C%89%E7%9B%B8%E5%85%B3%E9%97%AE%E9%A2%98%EF%BC%8C%E8%AF%B7%E6%89%93%E5%BC%80%E4%B8%80%E4%B8%AA%E6%96%B0%E4%B8%BB%E9%A2%98%E5%B9%B6%E5%8F%82%E8%80%83%E5%B7%B2%E5%85%B3%E9%97%AD%E7%9A%84%E4%B8%BB%E9%A2%98%E3%80%82%3CBR%20%2F%3E-------------------------------------------------------------------------------%3C%2FP%3E%0A%3CBR%20%2F%3E%0A%3CBR%20%2F%3E%3C%2FLINGO-BODY%3E