initial commit

This commit is contained in:
kamil
2026-04-07 17:22:17 +03:00
commit 0e90ba6a1b
20 changed files with 10143 additions and 0 deletions

167
x502tstp.h Normal file
View File

@ -0,0 +1,167 @@
#ifndef E502TSTP_H
#define E502TSTP_H
#include "x502api.h"
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup tstpfunc_list Функции для работы с метками времени
@{ **/
/***************************************************************************//**
@addtogroup tstptype_list Константы и перечисления
@{
*****************************************************************************/
/** Тип данных для хранения времени
* Время хранится в секундах прошедшее с начала этой эпохи (00:00:00 UTC, 1 Января 1970 года)
* Дробный формат хранения 32.31: 32 целых бит, 31 дробных бит,
* старшие 32 бита - секунды, младшие 31 бит - доли секунды (SubSecond) = 1 / (1<<31) секунд
*/
typedef uint64_t t_x502_tstptime;
#define TSP_NSEC_PER_SEC (1000000000)
/** длина в битах для SubSecond в WRD1 слове метки времени */
#define TSP_WRD1_SSEC_LEN (24)
/** длина в битах для SubSecond в WRD2 слове метки времени */
#define TSP_WRD2_SSEC_LEN (7)
/** длина в битах для Second в WRD2 слове метки времени */
#define TSP_WRD2_SEC_LEN (19)
/** длина в битах для Second в WRD3 слове метки времени */
#define TSP_WRD3_SEC_LEN (13)
/** общая длина в битах для SubSecond в t_x502_tstptime (дробный формат 32.31) */
#define TSP_SSEC_WIDTH (TSP_WRD1_SSEC_LEN + TSP_WRD2_SSEC_LEN)
/** Номер слова с меткой времени 0..3 */
#define TSP_WRD_NUM(wrd) (((wrd) >> 26) & 3)
/** Счетчик преобразования АЦП в WRD0 слове с меткой времени */
#define TSP_WRD0_ADC_CLK_NUM_MASK (0x3ffffff)
/** Признак захвата времени от PTP сервера */
#define TSP_WRD1_LOCK_MASK (1 << 25)
/** Признак первой метки после перехода GO в активное состояние */
#define TSP_WRD1_FMARK_MASK (1 << 24)
/** битовая маска для SubSecond в WRD1 */
#define TSP_WRD1_SSEC_MASK ((1 << TSP_WRD1_SSEC_LEN) - 1)
/** битовая маска для Second в WRD2 */
#define TSP_WRD2_SEC_MASK (0x3ffff80)
/** битовая маска для SubSecond в WRD2 */
#define TSP_WRD2_SSEC_MASK ((1 << TSP_WRD2_SSEC_LEN) - 1)
/** битовая маска для Second + SubSecond в WRD2 */
#define TSP_WRD2_SECSSEC_MASK ((1 << (TSP_WRD2_SEC_LEN + TSP_WRD2_SSEC_LEN)) - 1)
/** битовая маска для Second в WRD3 */
#define TSP_WRD3_SEC_MASK ((1 << TSP_WRD3_SEC_LEN) - 1)
/** макрос для проверки выставлен ли признак первой метки для слова WRD1 */
#define TSP_WRD1_IS_FMARK(wrd) (!!((wrd) & TSP_WRD1_FMARK_MASK))
/** макрос для проверки выставлен ли признак lock для слова WRD1 */
#define TSP_WRD1_IS_LOCK(wrd) (!!((wrd) & TSP_WRD1_LOCK_MASK))
/** макрос для получения SubSecond из слова WRD1 */
#define TSP_WRD1_GET_SSEC(wrd) ((wrd) & TSP_WRD1_SSEC_MASK)
/** макрос для получения Second + SubSecond из слова WRD2 */
#define TSP_WRD2_GET_SECSSEC(wrd) ((uint64_t)((wrd) & TSP_WRD2_SECSSEC_MASK) << TSP_WRD1_SSEC_LEN)
/** макрос для получения SubSecond из слова WRD2 */
#define TSP_WRD2_GET_SSEC(wrd) ((wrd) & TSP_WRD2_SSEC_MASK)
/** макрос для получения Second из слова WRD3 */
#define TSP_WRD3_GET_SEC(wrd) ((uint64_t)((wrd) & TSP_WRD3_SEC_MASK) << (TSP_WRD1_SSEC_LEN + TSP_WRD2_SSEC_LEN + TSP_WRD2_SEC_LEN))
/** максимально возможное значение SubSecond */
#define SSEC_MAX (0x7fffffff)
/** перевод SubSecond в наносекунды */
#define TSTP_SSEC_TO_NSEC(time) (time > 0 ? ((uint32_t)((((double)((time) & SSEC_MAX)) / (1U << TSP_SSEC_WIDTH)) * TSP_NSEC_PER_SEC)) : ((uint32_t)((((double)((time*(-1)) & SSEC_MAX)) / (1U << TSP_SSEC_WIDTH)) * TSP_NSEC_PER_SEC)))
/** получение целых секунд из t_x502_tstptime */
#define TSTP_SECSSEC_TO_SEC(time) (time > 0 ? (uint32_t)((time) >> TSP_SSEC_WIDTH) : (uint32_t)((time * -1) >> TSP_SSEC_WIDTH))
/** перевод в секунды с плавающей запятой из t_x502_tstptime */
#define TSTP_SECSSEC_TO_SEC_DOUBLE(time) (((double)(time)) / (1U << TSP_SSEC_WIDTH))
/** перевод секунд в t_x502_tstptime */
#define TSTP_SEC_TO_SSEC(time) (((uint64_t)(time)) << TSP_SSEC_WIDTH)
/** Структура для хранения контекста при обработке потока слов "на ввод" с включенными метками времени */
typedef struct {
/** значение слов последней метки времени */
uint32_t wrd[4];
/** частота АЦП */
uint32_t adc_freq;
/** частота DIN */
uint32_t din_freq;
/** время первой метки времени */
t_x502_tstptime tstp_start_time;
/** признак, что первая метка времени получена */
bool tstp_mark_rcvd;
/** значение текущего обрабатываемого слова */
uint32_t cur_wrd;
/** кол-во обработанных слов из потока */
uint32_t processed_wrds;
/** кол-во слов АЦП после последней метки времени */
uint32_t adcwrds_after_tstp;
/** кол-во слов DIN после последней метки времени */
uint32_t dinwrds_after_tstp;
/** общее кол-во слов после последней метки времени */
uint32_t wrds_after_tstp;
/** время последней метки времени */
t_x502_tstptime last_tstp_time;
} t_x502_tstp_state;
/** @} */
/***************************************************************************//**
@addtogroup func_tstp Функции для работы с метками времени
@{
*******************************************************************************/
/***************************************************************************//**
@brief Инициализация tstp_state, в нем хранится текущий контекст для операций с метками времени из потока "на ввод"
Данная функция инициализирует структуру в которой хранится контекст для работы с метками времени
Необходимо указывать на частоту АЦП и DIN т.к. время для слов между двумя метками
будет считаться в зависимости от частоты.
@param[in] tstp_state Указатель на существующую струтуру t_x502_tstp_state
@param[in] adc_freq Частота АЦП
@param[in] din_freq Частота DIN
*******************************************************************************/
X502_EXPORT(void) X502_tstp_init(t_x502_tstp_state *tstp_state, uint32_t adc_freq, uint32_t din_freq);
/** @brief Обработать очередное слово wrd из потока "на ввод"
*
* Функция должна быть вызвана только один раз и последовательно для каждого слова полученного из X502_Recv
*
* @param[in] tstp_state Указатель на струтуру t_x502_tstp_state предварительно инициализированную через tstp_init()
* @param[in] wrd Слово из потока "на ввод"
*/
X502_EXPORT(void) X502_tstp_process_wrd(t_x502_tstp_state *tstp_state, uint32_t wrd);
/** @brief Узнать время текущего обработанного слова
*
* Узнать время текущего слова которое до этого было обработано функцией tstp_process_wrd()
* Формат времени: 32бита - секунды, 31 бит сабсекунды = 1 / (1<<31) секунд
*
* @param[in] tstp_state Указатель на струтуру t_x502_tstp_state предварительно инициализированную через tstp_init()
* @param[in] ret Указатель на t_x502_tstptime по которому будет сохранено расчитанное значение времени для текущего слова
*/
X502_EXPORT(void) X502_tstp_get_curwrd_time(t_x502_tstp_state *tstp_state, t_x502_tstptime *ret);
/** @brief Возвращает признак того что часы синхронизированы
*
* Возвращает признак "захват PTP" для текущего обработанного слова
*
* @param[in] tstp_state Указатель на струтуру t_x502_tstp_state предварительно инициализированную через tstp_init()
*
* @return true: присутствует признак "захват PTP" для текущего обработанного слова, false: признак "захват PTP" отсутствует
*/
X502_EXPORT(bool) X502_tstp_get_lock(t_x502_tstp_state *tstp_state);
/** @} */
/** @} */
#ifdef __cplusplus
}
#endif
#endif //E502TSTP_H