### Example CLI Command Registration Source: https://github.com/epagris/flexptp/blob/master/manual/cli.dox An example demonstrating how to use the CLI_REG_CMD and CMD_FUNCTION macros to register a 'ptp priority' command. This includes the hint line, argument counts, and the callback function definition. ```C ptp priority [ ] Print or set clock priority fields ``` -------------------------------- ### Default Logging Output Example Source: https://github.com/epagris/flexptp/blob/master/manual/monitoring.dox This snippet shows an example of the output generated by the default logging feature in slave clock mode. It displays synchronization cycle variables like reception times, time error, addend, tuning, correction, path delay, and sync period. ```text 1750245425 776292333 1750245425 331768083 0 -27 -4 4260879975 57.835724 3414 1000057519 1750245426 776299212 1750245426 456768081 0 3 0 4260879881 -22.133024 3395 1000006879 1750245427 776371852 1750245427 581767839 0 45 7 4260879708 -40.697857 3381 1000072640 1750245428 776412971 1750245428 706767677 0 -19 -3 4260879921 50.216988 3380 1000041119 1750245429 776659935 1750245428 706767677 0 21 3 4260879779 -33.560795 3380 1000246964 1750245430 776686174 1750245429 831767675 0 -16 -2 4260879907 30.222692 3412 1000026239 1750245431 776744493 1750245430 956767513 0 8 1 4260879826 -19.040367 3385 1000058319 1750245432 776754491 1750245432 081767431 0 14 2 4260879794 -7.616276 3391 1000009998 1750245433 776922094 1750245433 206767028 0 39 6 4260879679 -27.130424 3369 1000167603 1750245434 776946172 1750245434 331767266 0 -92 -15 4260880170 115.426010 3436 1000024078 1750245435 776998572 1750245435 456767104 0 75 12 4260879586 -137.089859 3359 1000052400 1750245436 777026330 1750245436 581767582 0 -32 -5 4260879943 84.012680 3412 1000027758 1750245437 777052969 1750245437 706766780 0 69 11 4260879566 -88.535973 3338 1000026639 ``` -------------------------------- ### Example CMake Configuration for flexPTP Source: https://github.com/epagris/flexptp/blob/master/manual/building.dox This configuration sets up flexPTP to use the bundled STM32F407 hardware port with lwIP bindings, the bundled lwIP network stack driver, and the bundled PID controller as the clock servo. ```cmake set(FLEXPTP_HWPORT "F407_LWIP") set(FLEXPTP_NSD "LWIP") set(FLEXPTP_SERVO "PID") ``` -------------------------------- ### Initialize Ethernet Network Interface Source: https://github.com/epagris/flexptp/blob/master/manual/ethernetif_modifications.dox Initializes the Ethernet network interface. This function should be called at the beginning of the program and passed to netif_add(). It relies on low_level_init() for hardware setup. ```c /** * @brief Should be called at the beginning of the program to set up the * network interface. It calls the function low_level_init() to do the * actual setup of the hardware. * * This function should be passed as a parameter to netif_add(). * * @param netif the lwip network interface structure for this ethernetif * @return ERR_OK if the loopif is initialized * ERR_MEM if private data couldn't be allocated * any other err_t on error */ ``` -------------------------------- ### Get ADDEND Hardware Clock Time Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Method to fetch the current time directly from the hardware clock. ```c #define PTP_HW_GET_TIME(pt) hw_clock_get_time(pt) ``` -------------------------------- ### Configure Ethernet MAC Speed and Duplex Source: https://github.com/epagris/flexptp/blob/master/manual/ethernetif_modifications.dox Sets the Ethernet MAC configuration for speed and duplex mode based on status. Ensures the MAC is configured correctly before starting transmission. ```c case LAN8742_STATUS_10MBITS_HALFDUPLEX: duplex = ETH_HALFDUPLEX_MODE; speed = ETH_SPEED_10M; break; default: duplex = ETH_FULLDUPLEX_MODE; speed = ETH_SPEED_100M; break; } /* Get MAC Config MAC */ HAL_ETH_GetMACConfig(&EthHandle, &MACConf); MACConf.DuplexMode = duplex; MACConf.Speed = speed; HAL_ETH_SetMACConfig(&EthHandle, &MACConf); HAL_ETH_Start_IT(&EthHandle); netif_set_up(netif); netif_set_link_up(netif); } } ``` -------------------------------- ### Get PHY Driver Tick Source: https://github.com/epagris/flexptp/blob/master/manual/ethernetif_modifications.dox Retrieves the time in milliseconds used for internal PHY driver processes. ```c int32_t ETH_PHY_IO_GetTick(void) { return HAL_GetTick(); } ``` -------------------------------- ### Registering a CLI Command Source: https://github.com/epagris/flexptp/blob/master/manual/cli.dox Illustrates the registration of a CLI command using the CLI_REG_CMD macro. This macro defines the command's hint line, argument count, and callback function. ```C #define CLI_REG_CMD(cmd_hintline, n_cmd, n_min_arg, cb) ``` -------------------------------- ### Get HLT Hardware Clock Time Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Method to fetch the current time directly from the HLT hardware clock. ```c #define PTP_HW_GET_TIME(pt) hlt_clock_get_time(pt) ``` -------------------------------- ### ADDEND-interface Get Time Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Obtains the current time from the hardware clock using the ADDEND-interface. The time is stored in a ptp_timespec structure. ```c struct ptp_timespec pt; PTP_HW_GET_TIME(&pt); ``` -------------------------------- ### FlexPTP CLI Commands Source: https://github.com/epagris/flexptp/blob/master/manual/index.dox This is a list of available commands for the flexPTP library's Command Line Interface (CLI). These commands allow runtime manipulation of PTP operation modes, servo parameters, logging, and transport settings. ```bash ptp servo params [Kp Kd] Set or query K_p and K_d servo parameters ptp servo log internals {on|off} Enable or disable logging of servo internals ptp reset Reset PTP subsystem ptp servo offset [offset_ns] Set or query clock offset ptp log {def|corr|ts|info|locked|bmca} {on|off} Turn on or off logging time [ns] Print time ptp master [[un]prefer] [clockid] Master clock settings ptp info Print PTP info ptp domain [domain] Print or set PTP domain ptp addend [addend] Print or set addend <--- ADDEND interface ONLY ptp tuning [tuning] Print or set tuning <--- HLT interface ONLY ptp transport [{ipv4|802.3}] Set or get PTP transport layer ptp delmech [{e2e|p2p}] Set or get PTP delay mechanism ptp transpec [{def|gPTP}] Set or get PTP transportSpecific field (majorSdoId) ptp profile [preset []] Print or set PTP profile, or list available presets ptp tlv [preset [name]|unload] Print or set TLV-chain, or list available TLV presets ptp pflags [] Print or set profile flags ptp period [|matched] Print or set log. periods ptp coarse [threshold] Print or set coarse correction threshold ptp priority [ ] Print or set clock priority fields ``` -------------------------------- ### PHY IO Initialization Source: https://github.com/epagris/flexptp/blob/master/manual/ethernetif_modifications.dox Initializes the MDIO (Management Data Input/Output) interface for PHY communication. It assumes that the necessary GPIO configuration is already performed in ETH_MspInit and proceeds to set the MDIO clock range. ```c int32_t ETH_PHY_IO_Init(void) { /* We assume that MDIO GPIO configuration is already done in the ETH_MspInit() else it should be done here */ /* Configure the MDIO Clock */ HAL_ETH_SetMDIOClockRange(&EthHandle); return 0; } ``` -------------------------------- ### Initialize PTP Servo Controller Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Function to initialize the PTP servo controller algorithm. This is called once during system startup. ```c #define PTP_SERVO_INIT() servo_init() ``` -------------------------------- ### Add Doxygen Documentation Target Source: https://github.com/epagris/flexptp/blob/master/CMakeLists.txt Creates a custom CMake target named 'flexptp-docs' that executes the 'doxygen' command to generate project documentation. ```cmake add_custom_target( flexptp-docs COMMAND doxygen WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} ) ``` -------------------------------- ### Create flexPTP Static Library Source: https://github.com/epagris/flexptp/blob/master/CMakeLists.txt Adds a static library target for flexPTP using the defined source files and configures its include directories, compile options, definitions, and linked libraries. ```cmake add_library(${FLEXPTP_TARGET} STATIC ${FLEXPTP_SRC}) target_include_directories(${FLEXPTP_TARGET} PRIVATE ${FLEXPTP_INCLUDES} ${FLEXPTP_LOCAL_INCLUDES}) target_compile_options(${FLEXPTP_TARGET} PRIVATE ${FLEXPTP_CPU_PARAMS}) target_compile_definitions(${FLEXPTP_TARGET} PRIVATE ${FLEXPTP_COMPILE_DEFS}) target_link_libraries(${FLEXPTP_TARGET} m) ``` -------------------------------- ### Network Stack Driver Selection Logic Source: https://github.com/epagris/flexptp/blob/master/CMakeLists.txt This section configures the source files and network stack library name based on the FLEXPTP_NSD variable. It supports LWIP, ETHERLIB, and LINUX network stacks, with a fallback for custom drivers. ```cmake # Selecting Network Stack Driver set(FLEXPTP_NSD_OK 1) if (FLEXPTP_NSD STREQUAL "LWIP") set(FLEXPTP_NSD_SRC port/example_netstack_drivers/nsd_lwip.c ) set(FLEXPTP_NETWORK_STACK lwipcore) elseif(FLEXPTP_NSD STREQUAL "ETHERLIB") set(FLEXPTP_NSD_SRC port/example_netstack_drivers/nsd_etherlib.c ) set(FLEXPTP_NETWORK_STACK etherlib) elseif (FLEXPTP_NSD STREQUAL "LINUX") set(FLEXPTP_NSD_SRC port/example_netstack_drivers/nsd_linux.c port/example_netstack_drivers/nsd_linux.h ) set(FLEXPTP_NETWORK_STACK) else() set(FLEXPTP_NSD_OK 0) endif() if (FLEXPTP_NSD_OK) message("flexPTP: '" ${FLEXPTP_NSD} "' network stack driver selected") list(TRANSFORM FLEXPTP_NSD_SRC PREPEND "${FLEXPTP_SRC_DIR}/ ") else() if (FLEXPTP_NSD_SRC) message("flexPTP: custom network stack driver defined") else() message("flexPTP: Unknown or undefined network stack driver: '" ${FLEXPTP_NSD} "', " "please populate FLEXPTP_NSD_SRC with the files of your custom network stack " "driver and FLEXPTP_NETWORK_STACK with the name of the custom network stack " "library or pick a predefined one!") endif() endif() ``` -------------------------------- ### Low-Level Ethernet Initialization Source: https://github.com/epagris/flexptp/blob/master/manual/ethernetif_modifications.dox Initializes the Ethernet peripheral, including MAC configuration, DMA descriptors, and network interface settings. This function is called from ethernetif_init(). ```c static void low_level_init(struct netif *netif) { uint32_t idx, duplex, speed = 0; int32_t PHYLinkState; ETH_MACConfigTypeDef MACConf; uint8_t macaddress[6]= {ETH_MAC_ADDR0, ETH_MAC_ADDR1, ETH_MAC_ADDR2, ETH_MAC_ADDR3, ETH_MAC_ADDR4, ETH_MAC_ADDR5}; EthHandle.Instance = ETH; EthHandle.Init.MACAddr = macaddress; EthHandle.Init.MediaInterface = HAL_ETH_RMII_MODE; EthHandle.Init.RxDesc = DMARxDscrTab; EthHandle.Init.TxDesc = DMATxDscrTab; EthHandle.Init.RxBuffLen = ETH_RX_BUFFER_SIZE; /* configure ethernet peripheral (GPIOs, clocks, MAC, DMA) */ HAL_ETH_Init(&EthHandle); /* set MAC hardware address length */ netif->hwaddr_len = ETH_HWADDR_LEN; /* set MAC hardware address */ netif->hwaddr[0] = ETH_MAC_ADDR0; netif->hwaddr[1] = ETH_MAC_ADDR1; netif->hwaddr[2] = ETH_MAC_ADDR2; netif->hwaddr[3] = ETH_MAC_ADDR3; netif->hwaddr[4] = ETH_MAC_ADDR4; netif->hwaddr[5] = ETH_MAC_ADDR5; /* maximum transfer unit */ netif->mtu = ETH_MAX_PAYLOAD; /* device capabilities */ /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP; for(idx = 0; idx < ETH_RX_DESC_CNT; idx ++) { HAL_ETH_DescAssignMemory(&EthHandle, idx, Rx_Buff[idx], NULL); } /* Initialize the RX POOL */ LWIP_MEMPOOL_INIT(RX_POOL); memset(&TxConfig, 0 , sizeof(ETH_TxPacketConfig)); TxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD; TxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC; TxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT; /* create a binary semaphore used for informing ethernetif of frame reception */ RxPktSemaphore = xSemaphoreCreateBinary(); /* create the task that handles the ETH_MAC */ osThreadDef(EthIf, ethernetif_input, osPriorityRealtime, 0, INTERFACE_THREAD_STACK_SIZE); osThreadCreate (osThread(EthIf), netif); /* Set PHY IO functions */ LAN8742_RegisterBusIO(&LAN8742, &LAN8742_IOCtx); /* Initialize the LAN8742 ETH PHY */ LAN8742_Init(&LAN8742); PHYLinkState = LAN8742_GetLinkState(&LAN8742); /* Get link state */ if(PHYLinkState <= LAN8742_STATUS_LINK_DOWN) { netif_set_link_down(netif); netif_set_down(netif); } else { switch (PHYLinkState) { case LAN8742_STATUS_100MBITS_FULLDUPLEX: duplex = ETH_FULLDUPLEX_MODE; speed = ETH_SPEED_100M; break; case LAN8742_STATUS_100MBITS_HALFDUPLEX: duplex = ETH_HALFDUPLEX_MODE; speed = ETH_SPEED_100M; break; case LAN8742_STATUS_10MBITS_FULLDUPLEX: duplex = ETH_FULLDUPLEX_MODE; speed = ETH_SPEED_10M; break; ``` -------------------------------- ### Define FLEXPTP_OSLESS for No-OS Operation Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Define this macro to enable the no-OS operation mode. Requires manual provision of critical section management. ```c #define FLEXPTP_OSLESS ``` -------------------------------- ### FlexPTP CLI Commands Source: https://github.com/epagris/flexptp/blob/master/README.md A comprehensive list of command-line interface commands available for controlling and querying the flexPTP module during runtime. These commands allow manipulation of servo parameters, logging, PTP settings, and more. ```bash ptp servo params [Kp Kd] Set or query K_p and K_d servo parameters ptp servo log internals {on|off} Enable or disable logging of servo internals ptp reset Reset PTP subsystem ptp servo offset [offset_ns] Set or query clock offset ptp log {def|corr|ts|info|locked|bmca} {on|off} Turn on or off logging time [ns] Print time ptp master [[un]prefer] [clockid] Master clock settings ptp info Print PTP info ptp domain [domain] Print or set PTP domain ptp addend [addend] Print or set addend ptp transport [{ipv4|802.3}] Set or get PTP transport layer ptp delmech [{e2e|p2p}] Set or get PTP delay mechanism ptp transpec [{def|gPTP}] Set or get PTP transportSpecific field (majorSdoId) ptp profile [preset []] Print or set PTP profile, or list available presets ptp tlv [preset [name]|unload] Print or set TLV-chain, or list available TLV presets ptp pflags [] Print or set profile flags ptp period [|matched] Print or set log. periods ptp coarse [threshold] Print or set coarse correction threshold ptp priority [ ] Print or set clock priority fields ``` -------------------------------- ### ADDEND-interface Initialization Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Initializes the hardware clock driver using the ADDEND-interface. Requires defining PTP_INCREMENT_NSEC and PTP_MAIN_OSCILLATOR_FREQ_HZ. ```c #define PTP_INCREMENT_NSEC 10000 #define PTP_MAIN_OSCILLATOR_FREQ_HZ 100000000 PTP_HW_INIT(PTP_INCREMENT_NSEC, 0x80000000); ``` -------------------------------- ### Define flexPTP Source Files Source: https://github.com/epagris/flexptp/blob/master/CMakeLists.txt Lists all source and header files for the flexPTP library, including files from subdirectories and additional sources from variables. ```cmake set(FLEXPTP_SRC cli_cmds.c cli_cmds.h clock_utils.c clock_utils.h common.c common.h config.c config.h critical.h event.c event.h format_utils.c format_utils.h logging.c logging.h master.c master.h msg_buf.c msg_buf.h msg_utils.c msg_utils.h network_stack_driver.h profiles.c profiles.h ptp_core.c ptp_core.h ptp_defs.c ptp_defs.h ptp_profile_presets.c ptp_profile_presets.h ptp_servo_types.h ptp_sync_cycle_data.h ptp_types.h bmca.c bmca.h servo settings_interface.c settings_interface.h slave.c slave.h stats.c stats.h task_ptp.c task_ptp.h timeutils.c timeutils.h tlv.c tlv.h port/osless/fifo.c port/osless/fifo.h ) list(TRANSFORM FLEXPTP_SRC PREPEND "${FLEXPTP_SRC_DIR}/") list(APPEND FLEXPTP_SRC ${FLEXPTP_HWPORT_SRC} ${FLEXPTP_NSD_SRC} ${FLEXPTP_SERVO_SRC}) ``` -------------------------------- ### Initialize ADDEND Hardware Clock Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Method to initialize the hardware clock with a given increment and initial frequency tuning (addend). ```c #define PTP_HW_INIT(increment, addend) hw_clock_init(increment, addend) ``` -------------------------------- ### Ethernet MSP Initialization (RMII Mode) Source: https://github.com/epagris/flexptp/blob/master/manual/ethernetif_modifications.dox Initializes the Microcontroller Support Package (MSP) for the Ethernet peripheral in RMII mode. This includes enabling GPIO clocks, configuring Ethernet pins, and setting up the interrupt controller. ```c void HAL_ETH_MspInit(ETH_HandleTypeDef *heth) { GPIO_InitTypeDef GPIO_InitStructure; /* Ethernett MSP init: RMII Mode */ /* Enable GPIOs clocks */ __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); /* Ethernet pins configuration ************************************************/ /* RMII_REF_CLK ----------------------> PA1 RMII_MDIO -------------------------> PA2 RMII_MDC --------------------------> PC1 RMII_MII_CRS_DV -------------------> PA7 RMII_MII_RXD0 ---------------------> PC4 RMII_MII_RXD1 ---------------------> PC5 RMII_MII_RXER ---------------------> PG2 RMII_MII_TX_EN --------------------> PG11 RMII_MII_TXD0 ---------------------> PG13 RMII_MII_TXD1 ---------------------> PB13 */ /* Configure PA1, PA2 and PA7 */ GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; GPIO_InitStructure.Pull = GPIO_NOPULL; GPIO_InitStructure.Alternate = GPIO_AF11_ETH; GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7; HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure PB13 */ GPIO_InitStructure.Pin = GPIO_PIN_13; HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); /* Configure PC1, PC4 and PC5 */ GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5; HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); /* Configure PG2, PG11, PG13 and PG14 */ GPIO_InitStructure.Pin = GPIO_PIN_2 | GPIO_PIN_11 | GPIO_PIN_13; HAL_GPIO_Init(GPIOG, &GPIO_InitStructure); /* Enable the Ethernet global Interrupt */ HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0); HAL_NVIC_EnableIRQ(ETH_IRQn); /* Enable Ethernet clocks */ __HAL_RCC_ETH1MAC_CLK_ENABLE(); __HAL_RCC_ETH1TX_CLK_ENABLE(); __HAL_RCC_ETH1RX_CLK_ENABLE(); } ``` -------------------------------- ### Define FLEXPTP_FREERTOS for FreeRTOS Interface Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Define this macro to allow the library to directly call the FreeRTOS API. ```c #define FLEXPTP_FREERTOS ``` -------------------------------- ### Set flexPTP Include Directories Source: https://github.com/epagris/flexptp/blob/master/CMakeLists.txt Defines the local include directory for flexPTP sources and exports it for use by other targets. ```cmake set(FLEXPTP_LOCAL_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/src) set(FLEXPTP_INCLUDE_EXPORT ${FLEXPTP_LOCAL_INCLUDES} PARENT_SCOPE) # Export the location of the flexPTP headers ``` -------------------------------- ### HLT-interface Initialization Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Initializes the hardware clock driver using the High-Level Tuning (HLT) interface. This treats the clock as a black-box device. ```c PTP_HW_INIT(); ``` -------------------------------- ### Select ADDEND Hardware Clock Interface Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Define this macro to select the ADDEND-based hardware clock management interface. ```c #define PTP_ADDEND_INTERFACE ``` -------------------------------- ### Define FLEXPTP_LINUX for Linux Interface Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Define this macro to use the standard Linux API for operating system interaction. This is an experimental feature. ```c #define FLEXPTP_LINUX ``` -------------------------------- ### Initialize HLT Hardware Clock Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Method to initialize the HLT hardware clock. No parameters are typically required for basic initialization. ```c #define PTP_HW_INIT() hlt_clock_init() ``` -------------------------------- ### Kalman Filter Servo Definitions Source: https://github.com/epagris/flexptp/blob/master/manual/servo.dox Defines the macros to integrate the Kalman filter servo with the flexPTP core. Ensure the Kalman filter is enabled via CMake. ```c #include #define PTP_SERVO_INIT() kalman_filter_init() #define PTP_SERVO_DEINIT() kalman_filter_deinit() #define PTP_SERVO_RESET() kalman_filter_reset() #define PTP_SERVO_RUN(d, pscd) kalman_filter_run(d, pscd) ``` -------------------------------- ### Hardware Port Selection Logic Source: https://github.com/epagris/flexptp/blob/master/CMakeLists.txt This block configures the source files and base name for the hardware port based on the FLEXPTP_HWPORT variable. It supports predefined ports like STM32H743, STM32F407, CH32F207, Tiva TM4C1294, and Linux, with fallback for custom ports. ```cmake cmake_minimum_required(VERSION 3.15) set(FLEXPTP_SRC_DIR ${CMAKE_CURRENT_LIST_DIR}/src/flexptp) # Hardware port selection set(FLEXPTP_HWPORT_OK 1) if (FLEXPTP_HWPORT MATCHES "^H74[35]_LWIP$") set(FLEXPTP_HWPORT_SRC port/example_ports/ptp_port_stm32h743_lwip.c port/example_ports/ptp_port_stm32h743_lwip.h ) set(FLEXPTP_HWPORT_BASE "H743_LWIP") elseif(FLEXPTP_HWPORT MATCHES "^H74[35]_ETHERLIB$") set(FLEXPTP_HWPORT_SRC port/example_ports/ptp_port_stm32h743_etherlib.c port/example_ports/ptp_port_stm32h743_etherlib.h ) set(FLEXPTP_HWPORT_BASE "H743_ETHERLIB") elseif(FLEXPTP_HWPORT MATCHES "^F[47][0-9][0-9]_LWIP$") # STM32F4xx set(FLEXPTP_HWPORT_SRC port/example_ports/ptp_port_stm32f407_lwip.c port/example_ports/ptp_port_stm32f407_lwip.h ) set(FLEXPTP_HWPORT_BASE "F407_LWIP") elseif(FLEXPTP_HWPORT MATCHES "^F[47][0-9][0-9]_ETHERLIB$") set(FLEXPTP_HWPORT_SRC port/example_ports/ptp_port_stm32f407_etherlib.c port/example_ports/ptp_port_stm32f407_etherlib.h ) set(FLEXPTP_HWPORT_BASE "F407_ETHERLIB") elseif(FLEXPTP_HWPORT STREQUAL "CH32F207_ETHERLIB") set(FLEXPTP_HWPORT_SRC port/example_ports/ptp_port_ch32f207_etherlib.c port/example_ports/ptp_port_ch32f207_etherlib.h ) set(FLEXPTP_HWPORT_BASE "CH32F207_ETHERLIB") elseif(FLEXPTP_HWPORT STREQUAL "TM4C1294_LWIP") set(FLEXPTP_HWPORT_SRC port/example_ports/ptp_port_tiva_tm4c1294.c port/example_ports/ptp_port_tiva_tm4c1294.h ) set(FLEXPTP_HWPORT_BASE "TM4C1294_LWIP") elseif(FLEXPTP_HWPORT STREQUAL "LINUX") set(FLEXPTP_HWPORT_SRC port/example_ports/ptp_port_linux.c port/example_ports/ptp_port_linux.h ) set(FLEXPTP_HWPORT_BASE "LINUX") else() set(FLEXPTP_HWPORT_OK 0) endif() if (FLEXPTP_HWPORT_OK) message("flexPTP: '" ${FLEXPTP_HWPORT} "' hardware port selected") if (NOT FLEXPTP_HWPORT STREQUAL FLEXPTP_HWPORT_BASE) message("flexPTP: hardware port is automatically derived from '${FLEXPTP_HWPORT_BASE}'") endif() list(TRANSFORM FLEXPTP_HWPORT_SRC PREPEND "${FLEXPTP_SRC_DIR}/ ") else() if (FLEXPTP_HWPORT_SRC) message("flexPTP: custom hardware port defined") else() message("flexPTP: Unknown or undefined hardware port: '" ${FLEXPTP_HWPORT} "', " "please populate FLEXPTP_HWPORT_SRC with the files of your custom " "hardware port or pick a predefined one!") endif() endif() ``` -------------------------------- ### Register CLI Commands Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Optional function to register custom command-line interface commands. The parameters define command hints, argument counts, and callback functions. ```c #define CLI_REG_CMD(cmd_hintline, n_cmd, n_min_arg, cb) cli_register_command(cmd_hintline, n_cmd, n_min_arg, cb) ``` -------------------------------- ### Define SPRINTF for String Formatting Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Implement this macro or function as a basic `snprintf()` equivalent, supporting at least the same formatting marks as `MSG(...)`. ```c #define SPRINTF(str,n,...) snprintf(str, n, __VA_ARGS__) ``` -------------------------------- ### Run PTP Servo Controller Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Function that invokes the servo controller algorithm. It takes the time error and auxiliary context, and returns a tuning value in PPB. ```c #define PTP_SERVO_RUN(d, pscd) servo_run(d, pscd) ``` -------------------------------- ### HLT-interface Set Tuning (PPB) Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Tunes the hardware clock using the HLT interface, specifying the tuning value in Parts Per Billion (PPB). ```c PTP_SET_TUNING(1000); ``` -------------------------------- ### Ethernet Interface Initialization Source: https://github.com/epagris/flexptp/blob/master/manual/ethernetif_modifications.dox Initializes the LwIP network interface structure for Ethernet. This includes setting the hostname, SNMP variables, interface names, and assigning output functions for ARP and low-level data transmission. It also calls the low-level hardware initialization. ```c err_t ethernetif_init(struct netif *netif) { LWIP_ASSERT("netif != NULL", (netif != NULL)); #if LWIP_NETIF_HOSTNAME /* Initialize interface hostname */ netif->hostname = "lwip"; #endif /* LWIP_NETIF_HOSTNAME */ /* * Initialize the snmp variables and counters inside the struct netif. * The last argument should be replaced with your link speed, in units * of bits per second. */ MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS); netif->name[0] = IFNAME0; netif->name[1] = IFNAME1; /* We directly use etharp_output() here to save a function call. * You can instead declare your own function an call etharp_output() * from it if you have to do some checks before sending (e.g. if link * is available...) */ netif->output = etharp_output; netif->linkoutput = low_level_output; /* initialize the hardware */ low_level_init(netif); return ERR_OK; } ``` -------------------------------- ### PID Controller Servo Definitions Source: https://github.com/epagris/flexptp/blob/master/manual/servo.dox Defines the macros to integrate the PID controller servo with the flexPTP core. Ensure the PID controller is enabled via CMake. ```c #include #define PTP_SERVO_INIT() pid_ctrl_init() #define PTP_SERVO_DEINIT() pid_ctrl_deinit() #define PTP_SERVO_RESET() pid_ctrl_reset() #define PTP_SERVO_RUN(d, pscd) pid_ctrl_run(d, pscd) ``` -------------------------------- ### Define FLEXPTP_CMSIS_OS2 for CMSIS OS2 Interface Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Define this macro to utilize the CMSIS OS2 bindings for operating system integration. ```c #define FLEXPTP_CMSIS_OS2 ``` -------------------------------- ### Capture Reception Timestamp in pbuf Source: https://github.com/epagris/flexptp/blob/master/manual/ethernetif_modifications.dox This snippet shows how to copy the reception timestamp from the Rx descriptor into the pbuf structure within the `pbuf_low_level_input` function. ```c /* Store timestamp */ p->time_s = RxBuff->ts_sec; p->time_ns = RxBuff->ts_nsec; ``` -------------------------------- ### ADDEND-interface Set Clock Time Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Sets the hardware clock's time using the ADDEND-interface. Time is provided in seconds and nanoseconds. ```c PTP_SET_CLOCK(100, 500000000); ``` -------------------------------- ### Define MSG for Basic Formatted Printing Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Implement this macro or function as a basic formatted printing routine similar to `printf()`. It supports standard formatting specifiers. ```c #define MSG(...) printf(__VA_ARGS__) ``` -------------------------------- ### Set ADDEND Hardware Clock Time Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Method to set the hardware clock to a specific UNIX time (seconds and nanoseconds). ```c #define PTP_SET_CLOCK(s, ns) hw_clock_set_time(s, ns) ``` -------------------------------- ### Master P2P Mode Timestamps Source: https://github.com/epagris/flexptp/blob/master/manual/monitoring.dox Logs Peer-Delay Mechanism-related timestamps in master mode, along with correction fields. Use this to diagnose peer delay calculations. ```text T1: 1750245156.806319789 <- PDelay_Req TX (master) T2: 1750245156.806323241 <- PDelay_Req RX (slave) T3: 1750245156.806762292 <- PDelay_Resp TX (slave) T4: 1750245156.806765637 <- PDelay_Resp RX (master) 000000000 -- 000000000 <- CF in PDelay_Resp and ..._Follow_Up ``` -------------------------------- ### BMCA State Transitions Source: https://github.com/epagris/flexptp/blob/master/manual/monitoring.dox Logs the state transitions of the Best Master Clock Algorithm (BMCA). Use this to monitor the PTP clock's role and operational status. ```text INITIALIZING -> LISTENING LISTENING -> PRE_MASTER PRE_MASTER -> MASTER ``` -------------------------------- ### P2P Mode Timestamps Source: https://github.com/epagris/flexptp/blob/master/manual/monitoring.dox Logs six timestamps per synchronization cycle in Peer-to-Peer (P2P) PTP mode. This includes timestamps for both sync messages and peer delay requests/responses. ```text T1: 1750244937.371576883 <- Sync TX (master) T2: 1750244937.371583093 <- Sync RX (slave) t1: 1750244936.716173459 <- PDel_Req TX (our clock) t2: 1750244936.716174083 <- PDel_Req RX (their clock) t3: 1750244936.716270563 <- PDel_Resp TX (their clock) t4: 1750244936.716276743 <- PDel_Resp RX (our clock) ``` -------------------------------- ### Set ADDEND Hardware Clock Frequency Tuning Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Method to set the hardware clock's frequency tuning word (addend). ```c #define PTP_SET_ADDEND(addend) hw_clock_set_addend(addend) ``` -------------------------------- ### Debug Servo Definitions Source: https://github.com/epagris/flexptp/blob/master/manual/servo.dox Defines the macros to integrate the Debug servo with the flexPTP core. Ensure the Debug servo is enabled via CMake. ```c #include #define PTP_SERVO_INIT() debug_servo_init() #define PTP_SERVO_DEINIT() debug_servo_deinit() #define PTP_SERVO_RESET() debug_servo_reset() #define PTP_SERVO_RUN(d, pscd) debug_servo_run(d, pscd) ``` -------------------------------- ### ADDEND-interface Set Addend (Frequency Tuning) Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Tunes the hardware clock's frequency by setting the addend value using the ADDEND-interface. The addend is a 32-bit code word. ```c PTP_SET_ADDEND(0xFFFFFFFF); ``` -------------------------------- ### E2E Mode Timestamps Source: https://github.com/epagris/flexptp/blob/master/manual/monitoring.dox Logs four timestamps per synchronization cycle in End-to-End (E2E) PTP mode. These are crucial for calculating network delay and clock offset. ```text seqID: 26 T1: 1750245349.770584019 <- Sync TX (master) T2: 1750245349.770584664 <- Sync RX (slave) T3: 1750245348.831767544 <- Del_Req TX (slave) T4: 1750245348.831776389 <- Del_Req RX (master) ``` -------------------------------- ### PTP Slave Recognition States Source: https://github.com/epagris/flexptp/blob/master/manual/monitoring.dox Logs the states of slave recognition and Mean Path Delay values in P2P mode. States indicate the progress of establishing a synchronization path with a slave clock. ```text NONE -> CANDIDATE CANDIDATE -> ESTABLISHED ``` -------------------------------- ### Select HLT Hardware Clock Interface Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Define this macro to select the HLT (Hardware Latency Timer) based hardware clock management interface. ```c #define PTP_HLT_INTERFACE ``` -------------------------------- ### System Time Synchronization Source: https://github.com/epagris/flexptp/blob/master/manual/ethernetif_modifications.dox Provides the current time in milliseconds. This function is used when LWIP_TIMERS is enabled and NO_SYS is set to 1, typically for bare-metal or RTOS-less environments. ```c u32_t sys_now(void) { return HAL_GetTick(); } ``` -------------------------------- ### Complete low_level_input Function with Timestamp Capture Source: https://github.com/epagris/flexptp/blob/master/manual/ethernetif_modifications.dox The complete `low_level_input` function, including the modifications to capture reception timestamps and allocate a custom pbuf. ```c static struct pbuf * low_level_input(struct netif *netif) { struct pbuf *p = NULL; ETH_BufferTypeDef RxBuff[ETH_RX_DESC_CNT]; uint32_t framelength = 0, i = 0;; struct pbuf_custom* custom_pbuf; memset(RxBuff, 0 , ETH_RX_DESC_CNT*sizeof(ETH_BufferTypeDef)); for(i = 0; i < ETH_RX_DESC_CNT -1; i++) { RxBuff[i].next=&RxBuff[i+1]; } if(HAL_ETH_GetRxDataBuffer(&EthHandle, RxBuff) == HAL_OK) { HAL_ETH_GetRxDataLength(&EthHandle, &framelength); /* Build Rx descriptor to be ready for next data reception */ HAL_ETH_BuildRxDescriptors(&EthHandle); /* Invalidate data cache for ETH Rx Buffers */ SCB_InvalidateDCache_by_Addr((uint32_t *)RxBuff->buffer, framelength); custom_pbuf = (struct pbuf_custom*)LWIP_MEMPOOL_ALLOC(RX_POOL); if(custom_pbuf != NULL) { custom_pbuf->custom_free_function = pbuf_free_custom; p = pbuf_alloced_custom(PBUF_RAW, framelength, PBUF_REF, custom_pbuf, RxBuff->buffer, framelength); /* Store timestamp */ p->time_s = RxBuff->ts_sec; p->time_ns = RxBuff->ts_nsec; } } return p; } ``` -------------------------------- ### Clock Servo Selection Logic Source: https://github.com/epagris/flexptp/blob/master/CMakeLists.txt This block selects the clock servo module based on the FLEXPTP_SERVO variable, supporting PID, KALMAN, and DEBUG servo types. It defines the source files for the chosen servo. ```cmake # Selecting the Servo set(FLEXPTP_SERVO_OK 1) if (FLEXPTP_SERVO STREQUAL "PID") set(FLEXPTP_SERVO_SRC servo/pid_controller.c servo/pid_controller.h) elseif (FLEXPTP_SERVO STREQUAL "KALMAN") set(FLEXPTP_SERVO_SRC servo/kalman_filter.c servo/kalman_filter.h) elseif (FLEXPTP_SERVO STREQUAL "DEBUG") set(FLEXPTP_SERVO_SRC servo/debug_servo.c servo/debug_servo.h) else() set(FLEXPTP_SERVO_OK 0) endif() if (FLEXPTP_SERVO_OK) message("flexPTP: '" ${FLEXPTP_SERVO} "' clock servo selected") list(TRANSFORM FLEXPTP_SERVO_SRC PREPEND "${FLEXPTP_SRC_DIR}/ ") else() if (NOT FLEXPTP_SERVO_SRC) message("flexPTP: WARNING! No clock servo defined! If this is a mistake, then " "populate FLEXPTP_SERVO_SRC with the list of the clock servo module.") endif() endif() ``` -------------------------------- ### Set HLT Hardware Clock Tuning Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Method to set the HLT hardware clock's tuning value in Parts Per Billion (PPB). ```c #define PTP_SET_TUNING(tuning) hlt_clock_set_tuning(tuning) ``` -------------------------------- ### Info Notifications Source: https://github.com/epagris/flexptp/blob/master/manual/monitoring.dox Logs informational messages and exceptions encountered during PTP operation in slave mode. This helps in identifying and troubleshooting unexpected events. ```text Time difference has exceeded the coarse correction threshold [-1652684253ns], executing coarse correction! ``` -------------------------------- ### Define CLILOG for Maskable Printing Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Implement this macro or function as a maskable printing routine. If the enable flag is true, it behaves like `MSG(...)`. ```c #define CLILOG(en,...) if (en) MSG(__VA_ARGS__) ``` -------------------------------- ### Ethernet PHY IO Context Definition Source: https://github.com/epagris/flexptp/blob/master/manual/ethernetif_modifications.dox Defines the context for Ethernet PHY Input/Output operations, mapping specific functions to the LAN8742 driver. ```c lan8742_IOCtx_t LAN8742_IOCtx = { ETH_PHY_IO_Init, ETH_PHY_IO_DeInit, ETH_PHY_IO_WriteReg, ETH_PHY_IO_ReadReg, ETH_PHY_IO_GetTick }; ``` -------------------------------- ### Define and Customize flexPTP Target Name Source: https://github.com/epagris/flexptp/blob/master/CMakeLists.txt Sets the base target name and conditionally appends a tag to create a custom target name. A message is printed if a custom target is defined. ```cmake set(FLEXPTP_TARGET flexptp) if (FLEXPTP_TARGET_TAG) set(FLEXPTP_TARGET "${FLEXPTP_TARGET}_${FLEXPTP_TARGET_TAG}") message("Custom flexPTP target: ${FLEXPTP_TARGET}") endif() ``` -------------------------------- ### CLI Command Callback Function Signature Source: https://github.com/epagris/flexptp/blob/master/manual/cli.dox Defines the expected signature for a command callback function used with flexPTP's CLI. The function receives command arguments and their count, returning an integer status. ```C #define CMD_FUNCTION(name) int (name) (const char ** ppArgs, uint8_t argc) ``` -------------------------------- ### Define FLEXPTP_OSLESS_LOCK for OS-less Critical Sections Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox In OS-less mode, this macro must provide a method to enter and leave critical sections, typically by disabling/enabling interrupts. ```c #define FLEXPTP_OSLESS_LOCK FifoLockFn ``` -------------------------------- ### Zero-copy RX PBUF Pool Declaration Source: https://github.com/epagris/flexptp/blob/master/manual/ethernetif_modifications.dox Declares a memory pool for zero-copy receive PBUF structures, essential for efficient packet handling in LwIP. ```c LWIP_MEMPOOL_DECLARE(RX_POOL, 10, sizeof(struct pbuf_custom), "Zero-copy RX PBUF pool"); ``` -------------------------------- ### PHY IO De-Initialization Source: https://github.com/epagris/flexptp/blob/master/manual/ethernetif_modifications.dox De-initializes the MDIO interface. This function currently returns 0, indicating success, without performing any specific de-initialization actions. ```c int32_t ETH_PHY_IO_DeInit (void) { return 0; } ``` -------------------------------- ### Procedure to Write Back Transmit Timestamps Source: https://github.com/epagris/flexptp/blob/master/manual/ethernetif_modifications.dox This procedure iterates through transmit descriptors, checks for completed transmissions with timestamps, and writes the timestamps back to the associated pbuf and application-defined addresses. It also handles callback invocation. ```c void ethernetif_write_back_tx_timestamps() { /* store timestamps for transmitted frames */ for (size_t j = 0; j < ETH_TX_DESC_CNT; j++) { ETH_DMADescTypeDef * pDesc = &DMATxDscrTab[j]; struct pbuf * pPBuf = ppWriteBackPBufs[j]; if ((pPBuf != NULL) && (!(pDesc->DESC3 & ETH_DMATXNDESCWBF_OWN)) && (pDesc->DESC3 & ETH_DMATXNDESCWBF_LD) && (pDesc->DESC3 & ETH_DMATXNDESCWBF_TTSS)) { //MSG("* "); pPBuf->time_s = pDesc->DESC1; pPBuf->time_ns = pDesc->DESC0; ppWriteBackPBufs[j] = NULL; pDesc->DESC3 &= ~ETH_DMATXNDESCWBF_TTSS; if (pPBuf->ts_writeback_addr[0] != NULL) { *pPBuf->ts_writeback_addr[0] = pPBuf->time_s; } if (pPBuf->ts_writeback_addr[1] != NULL) { *pPBuf->ts_writeback_addr[1] = pPBuf->time_ns; } if (pPBuf->tx_cb) { pPBuf->tx_cb(pPBuf); } pPBuf->tx_cb = NULL; pPBuf->ts_writeback_addr[0] = NULL; pPBuf->ts_writeback_addr[1] = NULL; } } } void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef * heth) { ethernetif_write_back_tx_timestamps(); } ``` -------------------------------- ### Conditional Network Library Linking Source: https://github.com/epagris/flexptp/blob/master/CMakeLists.txt Conditionally links a network stack library to the flexPTP target if FLEXPTP_NETWORK_STACK is defined and FLEXPTP_DONT_LINK_NETWORK_LIB is not set. Otherwise, it prints a message indicating that no network stack is defined. ```cmake if (FLEXPTP_NETWORK_STACK) message("flexPTP: linking against '" ${FLEXPTP_NETWORK_STACK} "' network library") if (NOT FLEXPTP_DONT_LINK_NETWORK_LIB) target_link_libraries(${FLEXPTP_TARGET} ${FLEXPTP_NETWORK_STACK}) endif() elseif() message("flexPTP: No network stack defined to link against! " "Please set FLEXPTP_NETWORK_STACK to a chosen network stack library!") endif() ``` -------------------------------- ### Define Main Oscillator Frequency for ADDEND Interface Source: https://github.com/epagris/flexptp/blob/master/manual/porting.dox Specifies the frequency of the main oscillator driving the hardware clock in Hz. ```c #define PTP_MAIN_OSCILLATOR_FREQ_HZ 100000000 ``` -------------------------------- ### Custom Rx pbuf Free Callback Source: https://github.com/epagris/flexptp/blob/master/manual/ethernetif_modifications.dox A custom callback function for freeing Rx (receive) pbufs. It casts the generic pbuf to a custom pbuf type and frees it from the RX_POOL memory. ```c void pbuf_free_custom(struct pbuf *p) { struct pbuf_custom* custom_pbuf = (struct pbuf_custom*)p; LWIP_MEMPOOL_FREE(RX_POOL, custom_pbuf); } ```