This project implements the TCLK (Tevatron Clock) protocol for the Raspberry Pi Pico using the Programmable Input/Output (PIO) feature. It captures and timestamps input signals with a resolution of 50ns and implements the bi-phase (modified Manchester) encoding for TCLK as described in the TCLK_Paper.pdf.
- TCLK Protocol Implementation: An implementation of the Fermilab Tevatron Clock protocol
- Uses bi-phase (modified Manchester) coding at 10 MHz
- Transition at each bit cell boundary
- Additional transition at mid-cell if bit is 1, no transition if bit is 0
- Word length is 12 bits:
- 1 start bit (always 0)
- 8 data bits
- 1 parity bit (odd parity)
- 2 guaranteed '1's after each event
- PIO-based Implementation:
- tclkIN: Listens to an input clock signal and timestamps transitions with a resolution of 50ns
- tclkDecode: Processes the timestamps and decodes data according to the TCLK protocol
- tclkEncode: Encodes data according to the TCLK protocol and generates timestamps
- tclkOUT: Generates an output clock signal based on the encoded timestamps
- Docker-based Build Environment: Encapsulates the entire build environment for easy setup and reproducibility
- Multi-core Processing: Uses both cores of the Raspberry Pi Pico for efficient processing
pico-clock/
├── cmake/ # CMake modules
│ └── pico_sdk_import.cmake
├── include/ # Header files
│ └── tclk.h # TCLK protocol header
├── pio/ # PIO programs
│ ├── tclkIN.pio # TCLK input program
│ ├── tclkDecode.pio # TCLK decoding program
│ ├── tclkEncode.pio # TCLK encoding program
│ └── tclkOUT.pio # TCLK output program
├── scripts/ # Build and flash scripts
│ ├── build.sh
│ └── flash.sh
├── src/ # Source files
│ ├── main.cpp # Main application
│ └── tclk.cpp # TCLK implementation
├── build/ # Build artifacts (generated)
├── CMakeLists.txt # CMake configuration
├── Dockerfile # Docker configuration
└── README.md # This file
- Docker
- USB access to Raspberry Pi Pico
-
Build the Docker image:
docker build -t pico-clock-builder . -
Run the Docker container and build the project:
docker run --rm -v $(pwd):/app/project pico-clock-builder /app/scripts/build.shThis will create the build artifacts in the
builddirectory, includingpico-clock.uf2which can be flashed to the Raspberry Pi Pico.
-
Connect your Raspberry Pi Pico to your computer.
-
Run the Docker container with USB device access:
docker run --rm -v $(pwd):/app --device=/dev/ttyACM0 pico-clock-builder /app/scripts/flash.sh /dev/ttyACM0Replace
/dev/ttyACM0with the actual device path of your Raspberry Pi Pico.
-
Connect your Raspberry Pi Pico to your computer while holding the BOOTSEL button.
-
The Pico will appear as a USB mass storage device.
-
Copy the
build/pico-clock.uf2file to the Pico:cp build/pico-clock.uf2 /media/YOUR_USERNAME/RPI-RP2/
Replace
YOUR_USERNAMEwith your actual username. -
The Pico will automatically reboot and run the program.
- Connect a TCLK signal source to GPIO pin 16 (default) of the Raspberry Pi Pico.
- Connect a TCLK signal output device to GPIO pin 17 (default) of the Raspberry Pi Pico.
- Connect the Pico to your computer via USB for power and debugging output.
- For testing, you can jumper the output pins to the corresponding input pins to create a loopback.
The TCLK protocol is a 10 MHz serial signal that uses bi-phase (modified Manchester) coding for reliable data transmission:
-
Bi-phase Encoding:
- Transition at each 100ns bit cell boundary (regardless of bit value)
- Additional transition at mid-cell (after 50ns) if the bit is '1'
- No mid-cell transition if the bit is '0'
-
Word Structure (12 bits total):
- 1 start bit (always '0')
- 8 data bits
- 1 parity bit (odd parity)
- 2 guaranteed '1's after each event
-
Default State: Between clock events, the signal appears as a continuous series of '1's (10 MHz square wave).
-
Signal Characteristics:
- Self-clocking (no separate clock signal needed)
- When clock event activity is low, the signal appears as a 10 MHz square wave with occasional bursts of bi-phase patterns
- During high activity, the signal has no repeatable pattern
This implementation follows the protocol as described in the Fermilab paper "Time and Data Distribution Systems at the Fermilab Accelerator" by David G. Beechy and Robert J. Ducar.
- To change the TCLK input/output pins, modify the
TCLK_INPUT_PINandTCLK_OUTPUT_PINdefinitions insrc/main.cpp.
- To adjust the TCLK timestamp resolution or transition threshold, modify the constants in the TCLK PIO programs.
The program outputs debug information via USB serial. You can view this output using:
minicom -D /dev/ttyACM0 -b 115200Or any other serial terminal program.
This project is open source and available under the MIT License.