Zephyr TTCPS Counter Driver Implementation

This page provides details on the implementation of the TTC counter Zephyr driver.

Driver Implementation

The counter_xlnx_ttc driver maps TTC hardware operations onto the Zephyr counter subsystem callbacks and driver hooks. The implementation supports:

  • Counter start and stop operations

  • Current counter value reads

  • Alarm programming for relative or absolute ticks

  • Top value handling consistent with Zephyr counter semantics

  • Interrupt processing for timer events

  • Callback delivery to application code

Where interrupts are shared across TTC channels, the interrupt service routine checks the relevant timer instances and dispatches event handling only for the channel that raised the event.

For a full list of features supported by this IP, refer to the Versal Gen 2 Technical Reference Manual (AM026).

Counter Layer

The driver uses the counter framework header counter.h to call the driver API.

Probe Data From Node

In the driver, DT_DRV_COMPAT is assigned the driver compatible string so that whenever the compatible string matches one of the DT nodes with a status property of okay, the driver registers its API with the counter framework using a framework structure.

DT_DRV_COMPAT

  • This macro holds the compatible string of the driver xlnx_ttc_counter.

DT_INST_FOREACH_STATUS_OKAY

  • This macro instantiates the driver on every node with compatible DT_DRV_COMPAT and status okay. Each TTC timer channel described in the Device Tree is registered as an independent counter device.

DEVICE_DT_INST_DEFINE

  • This macro defines a device structure that is automatically configured by the kernel during system initialization. The initialization routine connects the channel interrupt, programs the prescaler, and registers the counter driver API with the subsystem.

Counter Subsystem

The counter subsystem defines the following structure, which any counter driver needs to expose.

Subsystem Structure

__subsystem struct counter_driver_api {
        counter_api_start start;
        counter_api_stop stop;
        counter_api_get_value get_value;
        counter_api_get_value_64 get_value_64;
        counter_api_set_alarm set_alarm;
        counter_api_cancel_alarm cancel_alarm;
        counter_api_set_top_value set_top_value;
        counter_api_get_pending_int get_pending_int;
        counter_api_get_top_value get_top_value;
        counter_api_get_guard_period get_guard_period;
        counter_api_set_guard_period set_guard_period;
        counter_api_get_freq get_freq;
};

Functional Implementation

start

  • Counter callback to start the timer channel.

stop

  • Counter callback to stop the timer channel.

get_value

  • Counter callback that returns the current counter value of the channel.

set_alarm

  • Counter callback that programs a hardware match register to generate an alarm at a relative or absolute tick value.

cancel_alarm

  • Counter callback that cancels a previously programmed alarm.

set_top_value

  • Counter callback that sets the top (wrap) value of the channel and, optionally, registers an overflow callback.

get_freq

  • Counter callback that returns the effective counting frequency of the channel after the prescaler is applied.