2014-09-17 12:35 AM
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?Thank you very much! #ptp-stm32f437zgt6-ieee1588 #ptp-stm32f437-enhanceddescriptor #ptp-stm32f407-descriptor-solved
2014-09-17 01:25 PM
2014-09-20 10:33 AM
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 liketimestamp->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 thesec
andnsec
values the program accesses to theBuffer1Addr
andBuffer2NextDescAddr
. Also I don't interpret the use of thedescriptor
andPTPdescriptor
structures and what are the differences between them. Thank you.2014-09-30 06:45 AM
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 itcontains 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->TimeStampLowHope it helps.2014-09-30 10:01 AM
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; #endifIn the same file, function
ETH_PTPTxPkt_ChainMode
I think it should have the two options again:Modification of
PTPTSCR
register.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);