Перейти к содержанию
    

Аппаратная поддержка протокола синхронизации времени STM32F407+LAN8720A.

1. Не надо удивительных коробок. Используйте SNTP. Сервера с SNTP доступны и недороги. Точность после 485-го вас более чем устроит.

2. Сделайте клиента SNTP на PTP таймере STM32F4. Так будет значительно проще, чем на RTC.

3. 1588 v2 - это микросекундная и субмикросекундная точность. Зачем она вам? Сервера с PTP нераспространены и дороги.

Попробовал поработать с PTP-таймером STM32F407. Он состоит из двух счетчиков:

1) счетчик секунд uint32_t

2) счетчик субсекунд uint32_t c верхним значением 0x7FFFFFFF или 999999999 (зависит от настроек),

при этом теоретическое разрешение по времени равно:

1) 1/(0x7FFFFFFF+1) = 0.465 наносекунды.

2) 1/(999999999+1) = 1 наносекунда.

А правктически этот счетчик инкрементируется на определенное значение каждый период HCLK, которая у меня равна 168 МГц - максимальное по DataSheet.

 

PTP-clock инициализируем (хоть с нуля) и включаем, они идут даже без подключения к сети Ethernet.

Особенность у часов такая: каждый клок HCLK значение счетчика субсекунд увеличивается на заранее заданное значение в регистре ETH_PTPSSIR (Ethernet PTP subsecond increment register).

 

Для случая, когда максимальное значение счетчка субсекнд равно 0x7FFFFFFF и тактовая частота равна HCLK равна 168 МГц значение ETH_PTPSSIR должно быть равно: 0x7FFFFFFF / 168000000 = 12,78 округляем до 13-ти.

 

Из-за этого округления прецизионные часы будут идти неточно без внешней синхронизации. Получается, чтобы они шли точно тактовая частота HCLK должна быть такой, чтобы значение 0x7FFFFFFF / HCLK было целым.

Не понимаю, почему так сделано. Ведь с микросхемы PHY LAN8720A на STM32F407 подается опорная частота 50МГц, почему бы не сделать тактирование PTP clock от этой частоты. Переключаем счетчик на верхнее значение 999999999 и выбираем частоту 50 МГц и часы бы шли более менее точно.

 

PS: Получается, что никакого смысла использовать PTP-clock совместно с SNTP-клиентом нет, тем более, что формат меток времени NTP-timestamp не совместим с PTP-timestamp (для NTP субсекунды 0...0xFFFFFFFF, для PTP субсекунды 0...7FFFFFFF или 0...999999999). Я-то думал, что форматы меток совпадают и можно копировать метку из NTP в PTP, а здесь еще дополнительные преобразования нужны. Буду использовать системный таймер, в нем тактировать UnixTime и счетчик миллисекунд.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для случая, когда максимальное значение счетчка субсекнд равно 0x7FFFFFFF и тактовая частота равна HCLK равна 168 МГц значение ETH_PTPSSIR должно быть равно: 0x7FFFFFFF / 168000000 = 12,78 округляем до 13-ти.

 

Из-за этого округления прецизионные часы будут идти неточно без внешней синхронизации. Получается, чтобы они шли точно тактовая частота HCLK должна быть такой, чтобы значение 0x7FFFFFFF / HCLK было целым.

Не понимаю, почему так сделано. Ведь с микросхемы PHY LAN8720A на STM32F407 подается опорная частота 50МГц, почему бы не сделать тактирование PTP clock от этой частоты. Переключаем счетчик на верхнее значение 999999999 и выбираем частоту 50 МГц и часы бы шли более менее точно

Виноват, товарищи!

Это я использовал один из режимов работы PTP-clock, а там есть еще один, как раз с учетом отношения частот 168/50=3,36 и тогда часы идут очень хорошо.

Вот код инициализации:

void InitPtpClockStm32F407(void)
{
ETH->PTPTSAR = 0x4C30C30C; // 2^32/(168/50) = 2^32/3.36 = 1278264076.19 округляем 0x4C30C30C
ETH->PTPSSIR = 20; // 20 наносекунд.
/* In Fine update mode, the value in this register is added to the system time whenever the accumulator gets an overflow.
Fine update mode: значение ETH->PTPSSIR добавляется к системному времени каждый раз когда аккумулятор переполняется. */        
ETH->PTPTSCR |= ETH_PTPTSCR_TSE;     // Time stamp enable.
ETH->PTPTSCR |= ETH_PTPTSCR_TSSTI;   // Time stamp initialize.
ETH->PTPTSCR |= ETH_PTPTSCR_TSFCU;   // Fine update method.
ETH->PTPTSCR |= ETH_PTPTSCR_TSARU;   // Addend register update. Если закомментировать, то часы не идут.
ETH->PTPTSCR |= ETH_PTPTSCR_TSSSR;   // digital rollover control, 0 - 999 999 999.
ETH->PTPTSCR |= ETH_PTPTSCR_TSPTPPSV2E; // Time stamp PTP packet snooping for version2 format enable. 
ETH->PTPTSCR |= ETH_PTPTSCR_TSSIPV4FE;  // Time stamp snapshot for IPv4 frames enable.
}

Эти регистры хранят секунды и наносекунды.

sprintf(LCD.line_1,"%d%c%d",ETH->PTPTSHR, '_',ETH->PTPTSLR);

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

на самом деле значение регистра ETH->PTPTSAR вычисляется так

ETH->PTPTSAR = 2^63 / ( ETH->PTPSSIR * HCLK )

эта формула приведена в Application note AN3411

если ETH->PTPSSIR = 20; и частота HCLK (AHB шина) равна 168МГц то

ETH->PTPTSAR = 0xA39E2840

Изменено пользователем IgorKossak
бездумное цитирование

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...