Wiznet makers

ronpang

Published August 04, 2025 © Apache License 2.0 (Apache-2.0)

130 UCC

63 WCC

32 VAR

0 Contests

1 Followers

0 Following

Hardwired TCP/IP Chapter 10: W55MH32 SNTP Example

Hardwired TCP/IP Chapter 10: W55MH32 SNTP Example

COMPONENTS
PROJECT DESCRIPTION

Hardwired TCP/IP Chapter 10: W55MH32 SNTP Example

In this article, we will provide a detailed explanation on how to implement the SNTP timing function on the W55MH32 chip. Through practical examples, we will guide you on how to have the W55MH32 obtain accurate real-time data from the SNTP server.

Other network protocols used in this example, such as DHCP and DNS, please refer to the relevant sections. Regarding the initialization process of the W55MH32, please refer to the "Network Installation" chapter. We will not elaborate on this here.

1 Introduction to the SNTP Protocol

SNTP (Simple Network Time Protocol) is a network time protocol based on the UDP protocol, mainly used to synchronize the time of devices in computer networks. SNTP aims to provide a simple time calibration service. Compared with NTP (Network Time Protocol), SNTP has simpler functions and lower accuracy.

2 The difference between SNTP and NTP

The differences between SNTP and NTP are as shown in the table below:

Characteristics

SNTP

NTP

Precision

The accuracy is relatively low, with the error usually ranging from several tens of milliseconds to several hundred milliseconds.

High precision, with errors typically at the millisecond or even microsecond level.

Algorithm complexity

Simple, suitable for applications with low precision requirements

Complex, using precise algorithms for correction

Server selection

Usually relies on a single time server

Multi-server selection to avoid single-point failure

Application scenario

Home, office, small devices, embedded devices

Scenarios requiring precise clock synchronization, such as in financial systems and scientific research.

Complexity of the agreement

Simple and easy to implement

More complex, requiring more calculations and state management

3 Characteristics of the SNTP Protocol

  • Using UDP communication: SNTP uses the UDP protocol to communicate on port 123.
  • Supports request-response mode: SNTP uses a single request-response mode to complete time synchronization: The client sends a request to the time server, and the server returns the current timestamp.
  • Low implementation and deployment cost: The implementation of SNTP is very simple, usually requiring only a small amount of code, making it easy to integrate in embedded systems. Due to its low resource consumption, it is suitable for large-scale deployment.
  • Compatible with NTP: SNTP is a subset of NTP. The client can communicate with an NTP server to obtain the time. The NTP server can seamlessly provide time synchronization services without additional configuration.
  • Supports one-way time synchronization: In specific scenarios (such as when a device only needs to synchronize its local time and does not need to calculate network latency), SNTP can complete time synchronization based solely on the timestamp provided by the server.

4 SNTP application scenarios

The SNTP protocol is typically used in scenarios that require time synchronization. By synchronizing the time to the RTC, the following functions can be achieved:

  • Collaborative Work: Regularly synchronize the time to enable each module to execute tasks in the predetermined sequence.
  • Log and Event Management: Ensure the accuracy of log time and event recording for W55MH32, facilitating subsequent analysis and troubleshooting.
  • Scheduled Tasks: Through time synchronization, support the accurate execution of scheduled tasks.

5 Time Zone Introduction

After obtaining the world standard time (UTC) through SNTP, a calculation based on the local time zone is required to determine the local time. For example, China is located in the UTC+8 time zone, which is defined as 39 in the sample code. Therefore, after obtaining UTC, 8 hours need to be added to convert it to the local time in China.

/*
00)UTC-12:00 Baker Island, Howland Island (both uninhabited)
01) UTC-11:00 American Samoa, Samoa
02) UTC-10:00 (Summer)French Polynesia (most), United States (Aleutian Islands, Hawaii)
03) UTC-09:30 Marquesas Islands
04) UTC-09:00 Gambier Islands;(Summer)United States (most of Alaska)
05) UTC-08:00 (Summer)Canada (most of British Columbia), Mexico (Baja California)
06) UTC-08:00 United States (California, most of Nevada, most of Oregon, Washington (state))
07) UTC-07:00 Mexico (Sonora), United States (Arizona); (Summer)Canada (Alberta)
08) UTC-07:00 Mexico (Chihuahua), United States (Colorado)
09) UTC-06:00 Costa Rica, El Salvador, Ecuador (Galapagos Islands), Guatemala, Honduras
10) UTC-06:00 Mexico (most), Nicaragua;(Summer)Canada (Manitoba, Saskatchewan), United States (Illinois, most of Texas)
11) UTC-05:00 Colombia, Cuba, Ecuador (continental), Haiti, Jamaica, Panama, Peru
12) UTC-05:00 (Summer)Canada (most of Ontario, most of Quebec)
13) UTC-05:00 United States (most of Florida, Georgia, Massachusetts, most of Michigan, New York, North Carolina, Ohio, Washington D.C.)
14) UTC-04:30 Venezuela
15) UTC-04:00 Bolivia, Brazil (Amazonas), Chile (continental), Dominican Republic, Canada (Nova Scotia), Paraguay,
16) UTC-04:00 Puerto Rico, Trinidad and Tobago
17) UTC-03:30 Canada (Newfoundland)
18) UTC-03:00 Argentina; (Summer) Brazil (Brasilia, Rio de Janeiro, Sao Paulo), most of Greenland, Uruguay
19) UTC-02:00 Brazil (Fernando de Noronha), South Georgia and the South Sandwich Islands
20) UTC-01:00 Portugal (Azores), Cape Verde
21) UTC±00:00 Cote d'Ivoire, Faroe Islands, Ghana, Iceland, Senegal; (Summer) Ireland, Portugal (continental and Madeira)
22) UTC±00:00 Spain (Canary Islands), Morocco, United Kingdom
23) UTC+01:00 Angola, Cameroon, Nigeria, Tunisia; (Summer)Albania, Algeria, Austria, Belgium, Bosnia and Herzegovina,
24) UTC+01:00 Spain (continental), Croatia, Czech Republic, Denmark, Germany, Hungary, Italy, Kinshasa, Kosovo,
25) UTC+01:00 Macedonia, France (metropolitan), the Netherlands, Norway, Poland, Serbia, Slovakia, Slovenia, Sweden, Switzerland
26) UTC+02:00 Libya, Egypt, Malawi, Mozambique, South Africa, Zambia, Zimbabwe, (Summer)Bulgaria, Cyprus, Estonia,
27) UTC+02:00 Finland, Greece, Israel, Jordan, Latvia, Lebanon, Lithuania, Moldova, Palestine, Romania, Syria, Turkey, Ukraine
28) UTC+03:00 Belarus, Djibouti, Eritrea, Ethiopia, Iraq, Kenya, Madagascar, Russia (Kaliningrad Oblast), Saudi Arabia,
29) UTC+03:00 South Sudan, Sudan, Somalia, South Sudan, Tanzania, Uganda, Yemen
30) UTC+03:30 (Summer)Iran
31) UTC+04:00 Armenia, Azerbaijan, Georgia, Mauritius, Oman, Russia (European), Seychelles, United Arab Emirates
32) UTC+04:30 Afghanistan
33) UTC+05:00 Kazakhstan (West), Maldives, Pakistan, Uzbekistan
34) UTC+05:30 India, Sri Lanka
35) UTC+05:45 Nepal
36) UTC+06:00 Kazakhstan (most), Bangladesh, Russia (Ural: Sverdlovsk Oblast, Chelyabinsk Oblast)
37) UTC+06:30 Cocos Islands, Myanmar
38) UTC+07:00 Jakarta, Russia (Novosibirsk Oblast), Thailand, Vietnam
39) UTC+08:00 China, Hong Kong, Russia (Krasnoyarsk Krai), Malaysia, Philippines, Singapore, Taiwan, most of Mongolia, Western Australia
40) UTC+09:00 Korea, East Timor, Russia (Irkutsk Oblast), Japan
41) UTC+09:30 Australia (Northern Territory);(Summer)Australia (South Australia))
42) UTC+10:00 Russia (Zabaykalsky Krai); (Summer)Australia (New South Wales, Queensland, Tasmania, Victoria)
43) UTC+10:30 Lord Howe Island
44) UTC+11:00 New Caledonia, Russia (Primorsky Krai), Solomon Islands
45) UTC+11:30 Norfolk Island
46) UTC+12:00 Fiji, Russia (Kamchatka Krai);(Summer)New Zealand
47) UTC+12:45 (Summer)New Zealand
48) UTC+13:00 Tonga
49) UTC+14:00 Kiribati (Line Islands)
*/

6 The basic process of synchronizing time through the SNTP protocol

1. Client sends a time request

  • The client sends a request data packet to the SNTP server and records the T1 timestamp information.
  • The request data packet usually contains the timestamp of the client (the time when the request was sent) so that it can be used when calculating the delay.

2. The server receives the request and processes it.

  • After receiving the request, the SNTP server records the time T2 when the request was received.
  • The server then generates a response data packet, which includes the following timestamp information:
  • o T2: The time when the server received the request.
  • o T3: The time when the server sent the response.

3. The client receives the response and calculates the time.

  • The client extracts the timestamp information (T2, T3) from the data packets returned by the server and records the reception time T4.
  • The client calculates the difference between the local time and the server time, as well as the network latency based on these timestamps:
    • Network latency formula: Network latency = (T4 - T1) - (T3 - T2)
    • Local time calibration formula: Calibrated time = T3 + (T4 - T1) - (T3 - T2) / 2

4. Adjust the local time

  • The client adjusts its local clock according to the calibration time to synchronize with the time on the server.

7 Analysis of SNTP Protocol Messages

The sending and receiving messages of SNTP have a fixed structure, usually 48 bytes in length. The message structure is as follows:

Byte offset

Field name

Length (bytes)

Description

0

Leap Indicator (LI), Version Number, Mode

1

It includes information such as leap second flag, version number, mode, etc.

1

Stratum

1

Server level (0 indicates not synchronized, 1 indicates main clock).

2

Poll Interval

1

Polling interval, which indicates the frequency of client requests.

3

Precision

1

Server time accuracy.

4–7

Root Delay

4

The total delay to the master clock, expressed in seconds to the power of negative 16.

8–11

Root Dispersion

4

The maximum error of the master clock, expressed in seconds and with the exponent of 2 raised to the power of -16.

12–15

Reference ID

4

Indicate the time source (IPv4 address or ASCII identifier).

16–23

Reference Timestamp

8

Reference timestamp indicates the UTC time of the last synchronization.

24–31

Originate Timestamp

8

Client request timestamp (T1).

32–39

Receive Timestamp

8

The timestamp (T2) at which the server received this request.

40–47

Transmit Timestamp

8

The server sends the response timestamp (T3).

Note: The definition of the timestamp refers to the number of seconds starting from 00:00:00 UTC on January 1, 1900.

SNTP Request Instance:

Offset

Data

Description

0

23

Leap Indicator (LI): 0

Version Number: 4

Mode: 3 (Client request)

1

00

Stratum: 0 (Not synchronized. This field is 0 when the client makes a request.)

2

00

Poll Interval: 0 (Default value)

3

00

Precision: 0 (Not set up)

4 - 7

00000000

Root Delay: 0 (This field is 0 when the client makes a request.)

8 - 11

00000000

Root Dispersion: 0 (This field is 0 when the client makes a request.)

12 - 15

00000000

Reference ID: Not set (0 is set when the client requests)

16 - 23

0000000000000000

Reference Timestamp: Not set up

24 - 31

0000000000000000

Originate Timestamp (T1): Not set up

32 - 39

0000000000000000

Receive Timestamp (T2): Not set up

40 - 47

0000000000000000

Transmit Timestamp (T3): Not set up

SNTP Server Response Example:

Offset

Data

Description

0

24

Leap Indicator (LI): 0

Version Number: 4

Mode: 4 (Server response)

1

03

Stratum: 3 (Third-level clock)

2

00

Poll Interval: 0

3

E7

Precision: -25 (Indicates a time accuracy of 2^(-25) seconds)

4 - 7

00000755

Root Delay: 0.007324 s

8 - 11

00002d0a

Root Dispersion: 0.011017 s

12 - 15

d30804eb

Reference ID: IPv4 Address 211.8.4.235

16 - 23

2368c6b074d70e00

Reference Timestamp:

The fractional part: 0x2368C6B0 (59,427,9216 seconds)

The decimal part: 0x74D70E00 (converted to 0.456789 seconds)

24 - 31

0000000000000000

Original Timestamp (T1): Not set (indicating that the client has not set the request timestamp)

32 - 39

eb2368fcfb5dfcad

Receive Timestamp (T2):

The fractional part: 0xEB2368FC (3949187836 seconds)

The decimal part: 0xFB5DFCAD (converted to 0.982354 seconds)

40 - 47

eb2368fcfb618c14

Transmit Timestamp (T3):

The fractional part: 0xEB2368FC (3949187836 seconds)

The decimal part: 0xFB618C14 (converted to 0.983214 seconds)

8 The implementation process

Next, we implement the SNTP timing function on the W55MH32.

Note: Since this example requires access to the internet, please ensure that the network environment and configuration of the W55MH32 can access the internet normally.

Step 1: Initialize RTC

1.     RTC_Init();

The specific content of the RTC_Init() function is as follows:

 1. uint8_t RTC_Init(void)
 2. {
 3.     uint8_t temp = 0;
 4.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //Enable PWR and BKP peripheral clocks
 5.     PWR_BackupAccessCmd(ENABLE);
 6.  
 7.     RCC_LSEConfig(RCC_LSE_ON);                                        //Set up external low-speed crystal oscillator (LSE) and use external low-speed crystal oscillator
 8.     while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET && temp < 250) //Check whether the specified RCC flag is set and wait for the low-speed crystal oscillator to be ready
 9.     {
10.         temp++;
11.         delay_ms(10);
12.     }
13.     if (temp >= 250) return 1;              //Initialization of the clock failed, there is a problem with the crystal oscillator
14.     RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //Set the RTC clock (RTCCLK) and select LSE as the RTC clock
15.     RCC_RTCCLKCmd(ENABLE);                  //Enable the RTC clock
16.     RTC_WaitForLastTask();                  //Waiting for the most recent write operation to the RTC register to complete
17.     RTC_WaitForSynchro();                   //Waiting for RTC register synchronization
18.     RTC_ITConfig(RTC_IT_SEC, ENABLE);       //Enable RTC seconds interrupt
19.     RTC_WaitForLastTask();                  //Waiting for the most recent write operation to the RTC register to complete
20.     RTC_EnterConfigMode();                  // Allow configuration
21.     RTC_SetPrescaler(32767);                //Set the RTC prescaler value, calculated as 32768/(32767+1) = 1Hz, and the period is exactly 1 second.
22.     RTC_WaitForLastTask();                  //Waiting for the most recent write operation to the RTC register to complete
23.     RTC_Set(1900, 1, 1, 0, 0, 1);           //Set the time
24.     RTC_ExitConfigMode();                   //Exit configuration mode
25.  
26.     RTC_WaitForSynchro();                   //Waiting for the most recent write operation to the RTC register to complete
27.     RTC_ITConfig(RTC_IT_SEC, ENABLE);       //Enable RTC seconds interrupt
28.     RTC_WaitForLastTask();                  //Waiting for the most recent write operation to the RTC register to complete
29.     RTC_NVIC_Config();                      //RCT interrupt group setting
30.     RTC_Get();                              //Update Time
31.     return 0;                               //ok
32. }

Step 2: Resolve the IP address of the SNTP server through DNS

1.     if (do_dns(ethernet_buf, sntp_server_name, sntp_server_ip))
2.     {
3.         while (1)
4.         {
5.         }
6.     }

Step 3: SNTP Initialization

1.     SNTP_init(SOCKET_ID, sntp_server_ip, timezone, ethernet_buf);

The SNTP_init() function requires four parameters to be passed in, namely the socket channel number, the SNTP server address, the time zone, and the socket cache. In this function, we will perform the SNTP message packetization operation and register the passed socket channel number, time zone, and socket cache in the library. The detailed content is as follows:

 1. void SNTP_init(uint8_t s, uint8_t *ntp_server, uint8_t tz, uint8_t *buf)
 2. {
 3.                   NTP_SOCKET = s;
 4.  
 5.                   NTPformat.dstaddr[0] = ntp_server[0];
 6.                   NTPformat.dstaddr[1] = ntp_server[1];
 7.                   NTPformat.dstaddr[2] = ntp_server[2];
 8.                   NTPformat.dstaddr[3] = ntp_server[3];
 9.  
10.                  time_zone = tz;
11.  
12.                  data_buf = buf;
13.  
14.                  uint8_t Flag;
15.                  NTPformat.leap = 0;           /* leap indicator */
16.                  NTPformat.version = 4;        /* version number */
17.                  NTPformat.mode = 3;           /* mode */
18.                  NTPformat.stratum = 0;        /* stratum */
19.                  NTPformat.poll = 0;           /* poll interval */
20.                  NTPformat.precision = 0;      /* precision */
21.                  NTPformat.rootdelay = 0;      /* root delay */
22.                  NTPformat.rootdisp = 0;       /* root dispersion */
23.                  NTPformat.refid = 0;          /* reference ID */
24.                  NTPformat.reftime = 0;        /* reference time */
25.                  NTPformat.org = 0;            /* origin timestamp */
26.                  NTPformat.rec = 0;            /* receive timestamp */
27.                  NTPformat.xmt = 1;            /* transmit timestamp */
28.  
29.                  Flag = (NTPformat.leap<<6)+(NTPformat.version<<3)+NTPformat.mode; //one byte Flag
30.                  memcpy(ntpmessage,(void const*)(&Flag),1);
31. }

Step 4: Send an SNTP request message to obtain the time

1.     while (1) //Automatically obtain time upon power on
2.     {
3.         if (SNTP_run(&date))
4.         {
5.             RTC_Set(date.yy, date.mo, date.dd, date.hh, date.mm, date.ss);
6.             break;
7.         }
8.     }

Next, we need to run the SNTP_run() function to perform the operations of sending and parsing the message. Once the time is successfully obtained, we will set it in the RTC.

The SNTP_run() function requires an input of a time structure named date, whose definition is as follows:

 1. typedef struct _datetime
 2. {
 3.                   uint16_t yy;
 4.                   uint8_t mo;
 5.                   uint8_t dd;
 6.                   uint8_t hh;
 7.                   uint8_t mm;
 8.                   uint8_t ss;
 9. } datetime;

The definition of the SNTP_run() function is as follows:

 1. int8_t SNTP_run(datetime *time)
 2. {
 3.                   uint16_t RSR_len;
 4.                   uint32_t destip = 0;
 5.                   uint16_t destport;
 6.                   uint16_t startindex = 40; //last 8-byte of data_buf[size is 48 byte] is xmt, so the startindex should be 40
 7.  
 8.                   switch(getSn_SR(NTP_SOCKET))
 9.                   {
10.                  case SOCK_UDP:
11.                                        if ((RSR_len = getSn_RX_RSR(NTP_SOCKET)) > 0)
12.                                        {
13.                                                               if (RSR_len > MAX_SNTP_BUF_SIZE) RSR_len = MAX_SNTP_BUF_SIZE; // if Rx data size is lager than TX_RX_MAX_BUF_SIZE
14.                                                               recvfrom(NTP_SOCKET, data_buf, RSR_len, (uint8_t *)&destip, &destport);
15.  
16.                                                               get_seconds_from_ntp_server(data_buf,startindex);
17.                                                               time->yy = Nowdatetime.yy;
18.                                                               time->mo = Nowdatetime.mo;
19.                                                               time->dd = Nowdatetime.dd;
20.                                                               time->hh = Nowdatetime.hh;
21.                                                               time->mm = Nowdatetime.mm;
22.                                                               time->ss = Nowdatetime.ss;
23.  
24.                                                               ntp_retry_cnt=0;
25.                                                               close(NTP_SOCKET);
26.  
27.                                                               return 1;
28.                                        }
29.  
30.                                        if(ntp_retry_cnt<0xFFFF)
31.                                        {
32.                                                               if(ntp_retry_cnt==0)//first send request, no need to wait
33.                                                               {
34.                                                                                      sendto(NTP_SOCKET,ntpmessage,sizeof(ntpmessage),NTPformat.dstaddr,ntp_port);
35.                                                                                      ntp_retry_cnt++;
36.                                                               }
37.                                                               else // send request again? it should wait for a while
38.                                                               {
39.                                                                                      if((ntp_retry_cnt % 0xFFF) == 0) //wait time
40.                                                                                      {
41.                                                                                                             sendto(NTP_SOCKET,ntpmessage,sizeof(ntpmessage),NTPformat.dstaddr,ntp_port);
42. #ifdef _SNTP_DEBUG_
43.                                                                                                             printf("ntp retry: %d\r\n", ntp_retry_cnt);
44. #endif
45.                                                                                                             ntp_retry_cnt++;
46.                                                                                      }
47.                                                               }
48.                                        }
49.                                        else //ntp retry fail
50.                                        {
51.                                                               ntp_retry_cnt=0;
52. #ifdef _SNTP_DEBUG_
53.                                                               printf("ntp retry failed!\r\n");
54. #endif
55.                                                               close(NTP_SOCKET);
56.                                        }
57.                                        break;
58.                  case SOCK_CLOSED:
59.                                        socket(NTP_SOCKET,Sn_MR_UDP,ntp_port,0);
60.                                        break;
61.                  }
62.                  // Return value
63.                  // 0 - failed / 1 - success
64.                  return 0;
65. }

Here, a UDP state machine will be executed. When the socket is in the SOCK_UDP state, it will first execute the sendto function to send the assembled SNTP request message for initialization, and then listen for the server's response.

Step 5: Analyze the SNTP response message

 1.                                          if ((RSR_len = getSn_RX_RSR(NTP_SOCKET)) > 0)
 2.                                          {
 3.                                                                 if (RSR_len > MAX_SNTP_BUF_SIZE) RSR_len = MAX_SNTP_BUF_SIZE; // if Rx data size is lager than TX_RX_MAX_BUF_SIZE
 4.                                                                 recvfrom(NTP_SOCKET, data_buf, RSR_len, (uint8_t *)&destip, &destport);
 5.  
 6.                                                                 get_seconds_from_ntp_server(data_buf,startindex);
 7.                                                                 time->yy = Nowdatetime.yy;
 8.                                                                 time->mo = Nowdatetime.mo;
 9.                                                                 time->dd = Nowdatetime.dd;
10.                                                               time->hh = Nowdatetime.hh;
11.                                                               time->mm = Nowdatetime.mm;
12.                                                               time->ss = Nowdatetime.ss;
13.  
14.                                                               ntp_retry_cnt=0;
15.                                                               close(NTP_SOCKET);
16.  
17.                                                               return 1;
18.                                        }

When the value of Sn_RX_RSR (Socket n idle receive buffer register) is greater than 0, it indicates that the server has returned a response to W55MH32. Firstly, the response message will be read through the recvfrom() function, and then the get_seconds_from_ntp_server function will be executed to parse the time.

Note: The get_seconds_from_ntp_server() function currently only parses the server's response timestamp (i.e., the last 8 bytes) and does not subtract the network delay.

The definition of the get_seconds_from_ntp_server() function is as follows:

  1. void get_seconds_from_ntp_server(uint8_t *buf, uint16_t idx)
  2. {
  3.                  tstamp seconds = 0;
  4.                  uint8_t i=0;
  5.                  for (i = 0; i < 4; i++)
  6.                  {
  7.                                        seconds = (seconds << 8) | buf[idx + i];
  8.                  }
  9.                  switch (time_zone)
 10.                 {
 11.                 case 0:
 12.                                       seconds -=  12*3600;
 13.                                       break;
 14.                 case 1:
 15.                                       seconds -=  11*3600;
 16.                                       break;
 17.                 case 2:
 18.                                       seconds -=  10*3600;
 19.                                       break;
 20.                 case 3:
 21.                                       seconds -=  (9*3600+30*60);
 22.                                       break;
 23.                 case 4:
 24.                                       seconds -=  9*3600;
 25.                                       break;
 26.                 case 5:
 27.                 case 6:
 28.                                       seconds -=  8*3600;
 29.                                       break;
 30.                 case 7:
 31.                 case 8:
 32.                                       seconds -=  7*3600;
 33.                                       break;
 34.                 case 9:
 35.                 case 10:
 36.                                       seconds -=  6*3600;
 37.                                       break;
 38.                 case 11:
 39.                 case 12:
 40.                 case 13:
 41.                                       seconds -= 5*3600;
 42.                                       break;
 43.                 case 14:
 44.                                       seconds -=  (4*3600+30*60);
 45.                                       break;
 46.                 case 15:
 47.                 case 16:
 48.                                       seconds -=  4*3600;
 49.                                       break;
 50.                 case 17:
 51.                                       seconds -=  (3*3600+30*60);
 52.                                       break;
 53.                 case 18:
 54.                                       seconds -=  3*3600;
 55.                                       break;
 56.                 case 19:
 57.                                       seconds -=  2*3600;
 58.                                       break;
 59.                 case 20:
 60.                                       seconds -=  1*3600;
 61.                                       break;
 62.                 case 21:                           
 63.                 case 22:
 64.                                       break;
 65.                 case 23:
 66.                 case 24:
 67.                 case 25:
 68.                                       seconds +=  1*3600;
 69.                                       break;
 70.                 case 26:
 71.                 case 27:
 72.                                       seconds +=  2*3600;
 73.                                       break;
 74.                 case 28:
 75.                 case 29:
 76.                                       seconds +=  3*3600;
 77.                                       break;
 78.                 case 30:
 79.                                       seconds +=  (3*3600+30*60);
 80.                                       break;
 81.                 case 31:
 82.                                       seconds +=  4*3600;
 83.                                       break;
 84.                 case 32:
 85.                                       seconds +=  (4*3600+30*60);
 86.                                       break;
 87.                 case 33:
 88.                                       seconds +=  5*3600;
 89.                                       break;
 90.                 case 34:
 91.                                       seconds +=  (5*3600+30*60);
 92.                                       break;
 93.                 case 35:
 94.                                       seconds +=  (5*3600+45*60);
 95.                                       break;
 96.                 case 36:
 97.                                       seconds +=  6*3600;
 98.                                       break;
 99.                 case 37:
100.                                      seconds +=  (6*3600+30*60);
101.                                      break;
102.                case 38:
103.                                      seconds +=  7*3600;
104.                                      break;
105.                case 39:
106.                                      seconds +=  8*3600;
107.                                      break;
108.                case 40:
109.                                      seconds +=  9*3600;
110.                                      break;
111.                case 41:
112.                                      seconds +=  (9*3600+30*60);
113.                                      break;
114.                case 42:
115.                                      seconds +=  10*3600;
116.                                      break;
117.                case 43:
118.                                      seconds +=  (10*3600+30*60);
119.                                      break;
120.                case 44:
121.                                      seconds +=  11*3600;
122.                                      break;
123.                case 45:
124.                                      seconds +=  (11*3600+30*60);
125.                                      break;
126.                case 46:
127.                                      seconds +=  12*3600;
128.                                      break;
129.                case 47:
130.                                      seconds +=  (12*3600+45*60);
131.                                      break;
132.                case 48:
133.                                      seconds +=  13*3600;
134.                                      break;
135.                case 49:
136.                                      seconds +=  14*3600;
137.                                      break;
138.  
139.                }
140.  
141.                //calculation for date
142.                calcdatetime(seconds);
143. }

Then, the calcdatetime() function is called to convert the adjusted number of seconds into the specific time format of year, month, day, hour, minute and second.

 1. void calcdatetime(tstamp seconds)
 2. {
 3.                   uint8_t yf=0;
 4.                   tstamp n=0,d=0,total_d=0,rz=0;
 5.                   uint16_t y=0,r=0,yr=0;
 6.                   signed long long yd=0;
 7.  
 8.                   n = seconds;
 9.                   total_d = seconds/(SECS_PERDAY);
10.                  d=0;
11.                  uint32_t p_year_total_sec=SECS_PERDAY*365;
12.                  uint32_t r_year_total_sec=SECS_PERDAY*366;
13.                  while(n>=p_year_total_sec)
14.                  {
15.                                        if((EPOCH+r)%400==0 || ((EPOCH+r)%100!=0 && (EPOCH+r)%4==0))
16.                                        {
17.                                                               if(n<r_year_total_sec)
18.                                                                                      break;
19.                                                               n = n -(r_year_total_sec);
20.                                                               d = d + 366;
21.                                                               
22.                                        }
23.                                        else
24.                                        {
25.                                                               n = n - (p_year_total_sec);
26.                                                               d = d + 365;
27.                                        }
28.                                        r+=1;
29.                                        y+=1;
30.  
31.                  }
32.  
33.                  y += EPOCH;
34.  
35.                  Nowdatetime.yy = y;
36.  
37.                  yd=0;
38.                  yd = total_d - d;
39.  
40.                  yf=1;
41.                  while(yd>=28)
42.                  {
43.  
44.                                        if(yf==1 || yf==3 || yf==5 || yf==7 || yf==8 || yf==10 || yf==12)
45.                                        {
46.                                                               yd -= 31;
47.                                                               if(yd<0)break;
48.                                                               rz += 31;
49.                                        }
50.  
51.                                        if (yf==2)
52.                                        {
53.                                                               if (y%400==0 || (y%100!=0 && y%4==0))
54.                                                               {
55.                                                                                      yd -= 29;
56.                                                                                      if(yd<0)break;
57.                                                                                      rz += 29;
58.                                                               }
59.                                                               else
60.                                                               {
61.                                                                                      yd -= 28;
62.                                                                                      if(yd<0)break;
63.                                                                                      rz += 28;
64.                                                               }
65.                                        }
66.                                        if(yf==4 || yf==6 || yf==9 || yf==11 )
67.                                        {
68.                                                               yd -= 30;
69.                                                               if(yd<0)break;
70.                                                               rz += 30;
71.                                        }
72.                                        yf += 1;
73.  
74.                  }
75.                  Nowdatetime.mo=yf;
76.                  yr = total_d-d-rz;
77.  
78.                  yr += 1;
79.  
80.                  Nowdatetime.dd=yr;
81.  
82.                  //calculation for time
83.                  seconds = seconds%SECS_PERDAY;
84.                  Nowdatetime.hh = seconds/3600;
85.                  Nowdatetime.mm = (seconds%3600)/60;
86.                  Nowdatetime.ss = (seconds%3600)%60;
87.  
88. }

Finally, the current time is printed once every 1 second in the main loop.

1.     while (1)
2.     {
3.         printf("Beijing time now: %04d-%02d-%02d  %s %02d:%02d:%02d\r\n", calendar.w_year, calendar.w_month, calendar.w_date, week_name[calendar.week], calendar.hour, calendar.min, calendar.sec);
4.         delay_ms(1000);
5.     }

9 Run results

After the burning routine is executed, it first performs PHY link detection, then acquires the network address through DHCP and prints the network address information. Finally, after obtaining the time through SNTP, it assigns the time value to the RTC, and then the main loop prints the current time once every second. As shown in the figure below:

10 Summary

This article explains how to implement the SNTP timing function on the W55MH32 chip. Through examples, it details the implementation process of synchronizing time from the SNTP server, including core steps such as time request, response parsing, and local time calibration. The article also analyzes the application scenarios of SNTP, helping readers understand its practical application value in time synchronization.

In the next article, we will explain the principle of the SMTP protocol and its application in email communication, as well as how to implement the SMTP function on the W55MH32 chip. Stay tuned!

 

 

WIZnet is a non-chipfoundry semiconductor company founded in 1998. Its products include the Internet processor iMCU™, which adopts TOE (TCP/IP Offloading Engine) technology and is based on a unique patented fully hardwired TCP/IP. iMCU™ is designed for embedded Internet devices in various applications.

WIZnet has over 70 distributors worldwide, with offices in Hong Kong, South Korea, and the United States, providing technical support and product marketing.

The region managed by the Hong Kong office includes: Australia, India, Turkey, Asia (excluding South Korea and Japan).

Documents
Comments Write