cancel
Showing results for 
Search instead for 
Did you mean: 

PTP implementation in STM32F437ZGT6

Jose_A
Associate II
Posted on September 17, 2014 at 09:35

Hello. I am working in a R&D Project with the STM32 MCU. I have implemented Ethernet functionality like examples provided by ST. Frame transmission and reception are OK (checked with Wireshark).

Now I must add PTP synchronization. Code made by ST is created for the STM32F1 family (with the PTPv2 library) , so I have followed the documentation to migrate it to my specific MCU (STM32F4).

All operations seem to run without errors. The PTP stack receives the messages and interprets these, but I get continuously the message ''updateOffset: cannot filter seconds'' and the offset from master is always very far from the objective.

Also I have read the Reference Manual of the STM32, and I found an enhanced receive descriptor when the IEEE1588 (PTP) time stamp is enabled (see page 1168 of DocID018909 Rev 7). According to the Figure 383 (see attached image), RDES6 and RDES7 should hold the time stamp, but when I am debugging I can not found the time stamp values. Which internal register(s) does the enhanced descriptor get the time stamp from?

0690X00000605A5QAI.png

Thank you very much!

#ptp-stm32f437zgt6-ieee1588 #ptp-stm32f437-enhanceddescriptor #ptp-stm32f407-descriptor-solved
4 REPLIES 4
Jose_A
Associate II
Posted on September 20, 2014 at 19:33

Hello.

I have found in the file 'ethernetif.c' (adapted to the PTP functionality) that in the function '

static void ETH_PTPRxPkt_ChainMode_CleanUp(FrameTypeDef * frame, struct ptptime_t * timestamp)

' there is a timestamp processing like

timestamp->tv_nsec = ETH_PTPSubSecond2NanoSecond(frame->descriptor->Buffer1Addr);

timestamp->tv_sec = frame->descriptor->Buffer2NextDescAddr;

As I am using PTP, I have enabled the enhanced descriptors (figure in my first post). So I don't understand why to get the

sec

and

nsec

values the program accesses to the

Buffer1Addr

and

Buffer2NextDescAddr

.

Also I don't interpret the use of the

descriptor

and

PTPdescriptor

structures and what are the differences between them.

Thank you.

renato1
Associate II
Posted on September 30, 2014 at 15:45

Hello

According to the reference manual, the RDES2 and RDES3 could contain the time stamp. From the manual:

''RDES2 contains the address pointer to the first data buffer in the descriptor, or it

contains time stamp data.''

But, if you're using enhanced descriptors, the time stamp is stored in RDES6 and RDES7. So the code in your ethernetif.c should be:

  timestamp->tv_nsec = ETH_PTPSubSecond2NanoSecond(frame->descriptor->TimeStampLow);

  timestamp->tv_sec = frame->descriptor->TimeStampHigh;

or you could use #ifdef USE_ENHANCED_DMA_DESCRIPTORS and keep both codes.

About the time stamp not changing, I was having the same problem. After a lot of debugging, I found out that my problem was configuration. First, the clock for the PTP wasn't enabled:

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC_PTP, ENABLE);

Second, the register PTPTSCR wasn't correct at the end of  ETH_PTPStart(). I had to set some bits myself:

/* Bit 11 TSSPTPOEFE: Time stamp snapshot for PTP over ethernet frames enable */

/* Bit 10 TSPTPPSV2E: Time stamp PTP packet snooping for version2 format enable */

ETH->PTPTSCR |= 0x00000C00;

After I did this, the time stamp correctly appeared in frame->descriptor->TimeStampHigh  and  frame->descriptor->TimeStampLow

Hope it helps.

Jose_A
Associate II
Posted on September 30, 2014 at 19:01

Hello!

I think your solution is perfect!! I have made these changes:

  •     Added  

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC_PTP, ENABLE);  

      if user wants to use PTP option (in 'stm32f4x7_eth_bsp.c').
  •     Function  

    ETH_PTPRxPkt_ChainMode_CleanUp

       has two options:

    #ifdef USE_ENHANCED_DMA_DESCRIPTORS

        timestamp->tv_nsec = ETH_PTPSubSecond2NanoSecond(frame->descriptor->TimeStampLow);

        timestamp->tv_sec = frame->descriptor->TimeStampHigh;

    #else

        timestamp->tv_nsec = ETH_PTPSubSecond2NanoSecond(frame->descriptor->Buffer1Addr);

        timestamp->tv_sec = frame->descriptor->Buffer2NextDescAddr;

    #endif

  •     In the same file, function  

    ETH_PTPTxPkt_ChainMode

       I think it should have the two options again:

    #ifdef USE_ENHANCED_DMA_DESCRIPTORS

        timestamp->tv_nsec = ETH_PTPSubSecond2NanoSecond(DMATxDescToSet->TimeStampLow);

        timestamp->tv_sec = DMATxDescToSet->TimeStampHigh;

    #else

        timestamp->tv_nsec = ETH_PTPSubSecond2NanoSecond(DMATxDescToSet->Buffer1Addr);

        timestamp->tv_sec = DMATxDescToSet->Buffer2NextDescAddr;

    #endif

  •     Modification of 

    PTPTSCR

    register.

Thank you very^3 much!!!

Out of curiosity, this was my 'solution': use the value of PTPTSLR and PTPTSHR registers and save them in the structure like this

timestamp->tv_nsec = ETH_PTPSubSecond2NanoSecond(ETH->PTPTSLR);

timestamp->tv_sec = (ETH->PTPTSHR);