# flexPTP ## Flexible, low-resource IEEE1588 PTP slave-only implementation designed for MCU-based systems [implemented on TI TM4C1294 Connected LaunchPad] ### Prerequests In order to compile the CCS project found in this repository the following tools are required: - TI Code Composer Studio 9.3.0.00012 or higher, - TI TivaWare peripheral library (this package can be aquired through CCS), - Some modification of vendor provided drivers and files (see below). To run the project you will need: - a TI Connected LaunchPad, - a network featuring a master clock. ### Binary image If you don't want to compile the project for yourself, a precompiled binary can be downloaded from here. This binary image can be flashed easily using CCS. ### Serial console The project is equipped with a moderately interactive command line interface accessible through the virtual serial port (e.g. `/dev/ttyACMx` on Linux) emulated by the development board. Serial port configuration: `115200-8-N-1`. After the device and software has come up, type `?` to print help, a list of terminal commands. Some commands will only be available if the Ethernet network is connected. Sample command list: ? Print this help ptp servo params [Kp Kd] Set or query K_p and K_d servo parameters ptp reset Reset PTP subsystem ptp servo offset [offset_ns] Set or query clock offset ptp log {def|corr} {on|off} Turn on or off logging ### Usage To try it out, just connect the Connected LaunchPad to a live Ethernet network being connected to a master clock. After the node has established connection to the network logs and servo settings are acessible through CLI. 1PPS output is accessible on pin PG0. ### Project modules The project is buit up from multiple modules, the following are designed to be easy to replace or modify: - servo: implementing the clock servo - hw_port: containing setup functions for specific timestamp hardware Instructions on how to replace the current modules can be found in `ptp.h`. ### Network driver modifications Original netif driver (located in `third_party/lwip-1.4.1/ports/netif/tiva-tm4c129.c`) has been modified so that trasmitted packets being timestamped and timestamps being written back into pbufs. Enabling TX timestamping in `tivaif_transmit(...)` ... pDesc->Desc.ui32CtrlStatus |= (DES0_TX_CTRL_IP_ALL_CKHSUMS | DES0_TX_CTRL_CHAINED); #if LWIP_PTPD pDesc->Desc.ui32CtrlStatus |= (1 << 25); // set TTSS flag #endif /* Decrement our descriptor counter, move on to the next buffer in the * pbuf chain. */ ui32NumChained--; pBuf = pBuf->next; ... Enabling timestamp writeback in `tivaif_process_transmit(...)` ... tDescriptorList *pDescList; uint32_t ui32NumDescs; #if LWIP_PTPD struct pbuf * pPBuf; struct tEMACDMADescriptor * pDesc; #endif ... /* Yes - free it if it's not marked as an intermediate pbuf */ if(!((uint32_t)(pDescList->pDescriptors[pDescList->ui32Read].pBuf) & 1)) { pbuf_free(pDescList->pDescriptors[pDescList->ui32Read].pBuf); DRIVER_STATS_INC(TXBufFreedCount); } #if LWIP_PTPD pPBuf = pDescList->pDescriptors[pDescList->ui32Read].pBuf; pDesc = &pDescList->pDescriptors[pDescList->ui32Read].Desc; // Write timestamp back pPBuf->time_s = pDesc->ui32IEEE1588TimeHi; pPBuf->time_ns = pDesc->ui32IEEE1588TimeLo; #endif pDescList->pDescriptors[pDescList->ui32Read].pBuf = NULL; ... Another modification has been made to enbale multicast message transmission and reception: (line 328:) psNetif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_IGMP; ### UARTprintf modification To enable task switching while waiting for new data to arrive on serial port, insert some (OS managed) delay into `UARTgets(...)` in `uartstdio.c` ... // // Process characters until a newline is received. // while(1) { // // Read the next character from the receive buffer. // vTaskDelay(pdMS_TO_TICKS(10)); if(!RX_BUFFER_EMPTY) { ...