cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H745 PTP Offloading

JDWBE
Associate II

Hello

I’m busy with the implementation of PTP support inside my project.

I choose the STM32H745, because there is PTP support in hardware, with a nice offload function. After reading and try to understand the manual I create this code:

uint32_t SubSecondValue = 43;
			#define ADJ_FREQ_BASE_ADDEND      0x35455A81
			// Mask the Timestamp Trigger interrupt by clearing bit 12 of Interrupt enable register (ETH_MACIER).
			heth->Instance->MACIER &= ~(ETH_MACIER_TSIE);
			// Set bit 0 of Timestamp control Register (ETH_MACTSCR) to enable timestamping.
			//heth->Instance->MACTSCR |= 1;			// Done at the END! :)
			//Program Subsecond increment register (ETH_MACSSIR) based on the PTP clock frequency.
			heth->Instance->MACSSIR = (SubSecondValue<<16);

			// if you use the Fine Correction method, program Timestamp addend register (ETH_MACTSAR) and set bit 5 of Timestamp control Register (ETH_MACTSCR)
			heth->Instance->MACTSAR = ADJ_FREQ_BASE_ADDEND;
			heth->Instance->MACTSCR |= ETH_MACTSCR_TSADDREG;

			/* Poll the Time stamp control register until bit 5 is cleared. */
			while(ETH_GetPTPFlagStatus(heth, ETH_PTP_FLAG_TSARU) == SET);

			/* Enable the PTP Fine Update method Fine*/
			heth->Instance->MACTSCR |= ETH_MACTSCR_TSCFUPDT;

			/* Program the Time stamp high update and Time stamp low update registers
			* with the appropriate time value. */
			/* Set the PTP Time Update High Register */
			heth->Instance->MACSTSUR = 0;

			/* Set the PTP Time Update Low Register with sign */
			heth->Instance->MACSTNUR = ETH_PTP_PositiveTime | 0;

			/* Set Time stamp control register bit 2 (Time stamp init). */
			heth->Instance->MACTSCR |= ETH_MACTSCR_TSINIT;

			/* Set PPS frequency to 128 Hz */
			heth->Instance->MACPPSCR = 7;

			// Source: RM0399 Page 3039
			// 1. Program SNAPTYPSEL, TSMSTRENA and TSEVNTENA fields of Timestamp control Register (ETH_MACTSCR) to 0, 0, and 1 respectively.
			heth->Instance->MACTSCR &= ~((0b00)<<16); 	// Clear SNAPTYPSEL
			heth->Instance->MACTSCR &= ~((0b0)<<15); 	// Clear TSMSTRENA
			heth->Instance->MACTSCR |= (1 << 14);			// Set TSEVNTENA
			// 2. Program the PTOEN bit and DN field of PTP Offload control register (ETH_MACPOCR) to enable PTP Offload feature and domain Number to match with ingress PTP Sync message and send in egress PTP Delay_Req message.
			heth->Instance->MACPOCR &= ~((0b00000000)<<8); // Set Domain number to 0

			heth->Instance->MACPOCR |= 4; // Set APDREQEN
			// 3. Program the 80-bit Source Port Identity in PTP Source Port Identity 0 Register (ETH_MACSPI0R), PTP Source port identity 1 register (ETH_MACSPI1R) and PTP Source port identity 2 register (ETH_MACSPI2R) to match with ingress PTP Sync message and send in egress PTP Delay_Req message.
			heth->Instance->MACSPI0R = 0x57ffec79;
			heth->Instance->MACSPI1R = 0xfe81d0c8;
			heth->Instance->MACSPI2R = 0x0001;
			// 4. Program the DRSYNCR field in Log message interval register (ETH_MACLMIR) to indicate one PTP Delay_Req message is generated in response to how many received PTP Sync messages.
			heth->Instance->MACLMIR |= (2<<24);
			heth->Instance->MACPOCR |= 1; // Set PTOEN

This code is called just before “low_level_init” returns.

What I try to do: I want to implement PTP Slave device that reacts on PTP message and try to synchronize the time inside the hardware counter. Without any software interaction, hardware offload.  

When I sniff with Wireshark nothing happens, there is no communication send from the STM to the PTP master. What do I wrong?

My PTP master, is a off the shelve box specially made for PTP. The SYNC and Follow up data packets are sending though the network.

My ClockIdentity: 0xd0c857fffe81ec79

SourcePortID: 0x0001

9 REPLIES 9
JDWBE
Associate II

Nobody with any suggestion?

@STea @LCE 

LCE
Principal II

Since my heavily modified PTPd code is working (without any extra STM32H7 hardware features), I didn't have another look at the hardware capabilities, and it's very low down on my priority list.

I have no idea how far the "automation" of the messages and replies is working.

Right now I cannot imagine that the hardware is creating any UDP messages which are needed for SYNC reply and DELAY REQUEST.

Anyway, you'll need a lot of filtering to control the slave clock, in PTPd a PI controller and a low pass is used for TMS and TSM timing results. I had to adjust these settings, and add some kind of "lucky packet filtering".

But I'm curious, just reading the H723 RM...

Edit: in general it is helpful - mostly for yourself, but also to others reading your code - to use the pre-defined bits / bitmasks from the stm32h7yyxx.h file, like:

heth->Instance->MACTSCR |= ETH_MACTSCR_TSEVNTENA;

 

LCE
Principal II

It looks like it does support message generation (except for follow up as master, but that should not be necessary).

I would start with checking if the PTP messages from the master are actually received, so check the received descriptors for the PTP flags, and toggle a LED or use the UART.

LCE
Principal II

@JDWBE 

Have you made any progress or got new insights?

JDWBE
Associate II

Many Thanks for your answer and suggestion.

I'm just back from a business trip and try to adapt my code to do some debugging.

I shoos the STM32H7 series specially for the PTP support offloading. When i read the manual, the hardware is able to create al the "magic" stuff to-do this... But at ST nobody have some example... How do they test there hardware? We need to do this?

 

LCE
Principal II

Let's hope that they tested that.

But yes, it's really disappointing that they never published any example code for the H7's PTP features.

JDWBE
Associate II

Hello

Here the first test:

No PTP on the network, there is is no output from the printf.

When the PTP master is active i received the "Sync Inside", so there is "live".

 

	if((ETH->MACTSSR & 0x008000) > 1){
		printf("Sync Inside! \r\n");
	}

 

 When i debug with wire shark there is no packet send by the STM. It is enabled (of at least it was the intention :) )

Any suggestion what i can try more?

LCE
Principal II

I would check again the registers how delay request messages are triggered.

Also the IO port ID settings, and compare this with what's in the SYNC message.

 

JDWBE
Associate II

Sourceport ID = 0x0001

My ID is: 0xD0C857FFFE81EC79

In combination to get an 80 bit number: 0xD0C857FFFE81EC790001

I programmed this in this way:

 

	heth->Instance->MACSPI0R = 0xEC790001;
	heth->Instance->MACSPI1R = 0x57FFFE81;
	heth->Instance->MACSPI2R = 0x0000D0C8;

 

Is this correct?