diff --git a/SynchronizationClock.md b/SynchronizationClock.md index 87671bd..557c4e5 100644 --- a/SynchronizationClock.md +++ b/SynchronizationClock.md @@ -1,28 +1,60 @@ -# Synchronization Clock Protocol (1.0) +# Synchronization Clock Protocol -## Introduction -The `Harp Synchronization Clock` is a dedicated bus that disseminates the current time to/across Harp devices. It is a serial communication protocol that relays the time information. The last byte in each message can be used as a trigger, and allows a `Device`` to align itself with the current `Harp` time. +This document provides the specification for the Harp Synchronization Clock, a dedicated bus used to synchronize the current time across Harp devices with sub-millisecond accuracy. -## Serial configuration +## Requirements Language -* The Baud rate used is 100kbps; -* The last byte starts *exactly* 672 us before the elapse of the current second (e.g.:) +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt). - !["SynchClockOscilloscope](./assets/SynchClockOscilloscope.png) +## Serial Interface -* The packet is composed of 6 bytes (`header[2]` and `timestamp_s[4]`): - - `header[2] = {0xAA, 0xAF)` - - `timestamp_s` is of type U32, little-endian, and contains the current second. +The Harp Synchronization Clock is a serial communication protocol for relaying time information over RS-232. Each message transmits the current time, in whole seconds. The transmission of the last byte in each message is used as a synchronization signal, allowing Harp devices to align their clocks with sub-millisecond accuracy. -> **Important** -> -> To avoid unexpected behaviors, only one bit at a time should be written to register `R_RESET_DEV`. +### Baud Rate + +The baud rate for all transmitted data MUST be 100 kbps. + +### Transmission Packet (6 bytes) + +Each transmission packet encodes the current time, in whole seconds. All Harp Synchronization Clock messages MUST use Little-Endian byte ordering and follow the structure below: + + + + + + + + + + + + + + + + + + + +
012345
0xAA0xAFU32
HeaderCurrent Time
+ +### Transmission Timing + +Transmission of the last byte MUST start exactly 672 μs before the current second lapses. + +Receivers MUST align their clocks so the next whole second starts exactly 672 μs following reception of the last byte, ensuring any fractional part of the timestamp is zero. Receivers MAY complete the initial alignment over a few transmission events, but thereafter MUST keep updating the whole second in sync with successfully transmitted Harp Synchronization Clock messages as long as the whole second is incremented sequentially. + +## Example Logic Trace + +Example traces of the transmission signals are shown below from both a logic analyzer and an oscilloscope: + + !["SynchClockLogicAnalyzer](./assets/SyncLogicTrace.png) ## Example code -Example of a microcontroller C code: +Example microcontroller C code dispatching the serialized data: ```C @@ -49,6 +81,7 @@ ISR(TCD0_OVF_vect, ISR_NAKED) case 7: USARTD1_DATA = *timestamp_byte2; break; + // The final byte is dispatched much later than the previous 5. case 1998: USARTD1_DATA = *timestamp_byte3; break; @@ -56,11 +89,45 @@ ISR(TCD0_OVF_vect, ISR_NAKED) } ``` -## Physical connection +Example of microcontroller C++ code for converting the four received encoded bytes to the timestamp: + +````C + #define HARP_SYNC_OFFSET_US (672) + + // Assume 4 bytes of timestamp data (without header) have been written to this array. + alignas(uint32_t) volatile uint8_t sync_data_[4]; -The physical connection is made by a simple audio cable. In the same folder of this file, you can find an [example](./PhysicalConnector.pdf) of the sender and the receiver. + // reinterpret 4-byte sequence as a little-endian uint32_t. + uint32_t encoded_sec = *(reinterpret_cast(self->sync_data_)); + // Convert received timestamp to the current time in microseconds. + // Add 1[s] per protocol spec since 4-byte sequence encodes the **previous** second. + uint64_t curr_us = ((static_cast(encoded_sec) + 1) * 1e6) - HARP_SYNC_OFFSET_US; +```` + +A full example demonstrating a state machine receiving the 6-byte sequence can be found in the [Pico Core](https://github.com/harp-tech/core.pico/blob/main/firmware/src/harp_synchronizer.cpp). + +## Physical Connection + +The physical connection for transmission of the Harp Synchronization Clock SHOULD be made by a 3.5 mm audio cable. + +The connector pinout for a device *receiving* the timestamp is shown below: + +!["SynchReceiverSchematic](./assets/HarpClockSyncReceiver.png) + +The device receiving the timestamp MUST provide 3.3V-5V (~10 mA) on the connector **R** pin. A TVS diode is RECOMMENDED for ESD protection. + +The schematic snippet for a device *sending* the timestamp is shown below: + +!["SynchSenderSchematic](./assets/HarpClockSyncSender.png) + +> [!NOTE] +> The device *sending* the timestamp MUST isolate each clock output port, preventing ground loops from forming when connecting the audio jack between sender and receiver. + +A supplementary PDF [example](./assets/PhysicalConnector.pdf) of the sender and the receiver is also available. The connector used is from `Switchcraft Inc.` with PartNo. `35RASMT2BHNTRX`. +A KiCAD schematic template for creating a Harp device based on the [RP2040](https://www.raspberrypi.com/products/rp2040/) microcontroller with circuitry for receiving the timestamp is provided through the [Pico Template](https://github.com/AllenNeuralDynamics/harp.device.pico-template). + ## Release Notes - v1.0 @@ -73,4 +140,4 @@ The connector used is from `Switchcraft Inc.` with PartNo. `35RASMT2BHNTRX`. * Adopt semantic versioning. - v1.1.1 - * Remove table of contents to avoid redundancy with doc generators. \ No newline at end of file + * Remove table of contents to avoid redundancy with doc generators. diff --git a/assets/HarpClockSyncReceiver.png b/assets/HarpClockSyncReceiver.png new file mode 100644 index 0000000..7417419 Binary files /dev/null and b/assets/HarpClockSyncReceiver.png differ diff --git a/assets/HarpClockSyncSender.png b/assets/HarpClockSyncSender.png new file mode 100644 index 0000000..a19f507 Binary files /dev/null and b/assets/HarpClockSyncSender.png differ diff --git a/PhysicalConnector.pdf b/assets/PhysicalConnector.pdf similarity index 100% rename from PhysicalConnector.pdf rename to assets/PhysicalConnector.pdf diff --git a/PhysicalConnector.sch b/assets/PhysicalConnector.sch similarity index 100% rename from PhysicalConnector.sch rename to assets/PhysicalConnector.sch diff --git a/assets/SyncLogicTrace.png b/assets/SyncLogicTrace.png new file mode 100644 index 0000000..e783e19 Binary files /dev/null and b/assets/SyncLogicTrace.png differ diff --git a/assets/SynchClockOscilloscope.png b/assets/SynchClockOscilloscope.png deleted file mode 100644 index d1cc135..0000000 Binary files a/assets/SynchClockOscilloscope.png and /dev/null differ