In my last blog, we looked implementing the Zynq SoC’s TTC (Triple Timer Counter) by defining the hardware within Vivado. In this blog post, we’ll use the SDK to drive the TTC. Obviously the first thing we need to do is export the hardware to SDK to ensure that the software environment has the most up-to-date definition.
Exporting hardware to the SDK is always the first thing to do. This step pulls in the required functions and macros provided by the operating system. These can be accessed by:
We also need to include Xscugic.h and Xil_exception.h so that we can use the interrupt controller.
The next step, as always, is is to use the xparamters.h file to obtain the TTC device ID, TTC Interrupt ID and Interrupt controller device ID.
Unlike our previous example using the Zynq SoC’s private timer, we need to declare a data structure to contain the output frequency, interval, pre-scaler, and TTC options.
u32 OutputHz; /* Output frequency */
u16 Interval; /* Interval value */
u8 Prescaler; /* Prescaler value */
u16 Options; /* Option settings */
This data structure makes driving the TTC very easy. I’ve also used this structure to define a pre-configured settings table:
This settings table initially sets the output frequency to 10Hz while initializing everything else to zero.
After initialization and device configuration, we need to define the options mode for TTC operation. Helpfully defined within xttcps.h are all of the options for the timer control register. We can therefore configure the TTC by ORing the options together. For this example I will be running the timer in interval mode with the external wave disabled.
Having defined the TTC options and set them into the control register, we can call a function to calculate and set the interval for the desired output frequency as defined within the timer set-up structure.
The next step in using the TTC is to connect it to the interrupt controller and enable interrupts. There are several interrupts to choose from for each TTC. I have enabled only the interval interrupt in this instance:
The file xttcps_hw.h, which is called up by xttcps.h, includes definitions for all possible TTC interrupts allowing them to be enabled as desired using the above function. Having set up the interrupt, I then start the timer and connect the MicroZed to my laptop so that I can see a message printed out each time the interrupt occurrs.
Within the interrupt service routine, I have simply read back the interrupt status register to determine which interrupt occurred and then cleared it. Reading of the interrupt status register within the ISR is important because there are several different interrupts possible. In a more complex use of the TTC, we would want to ensure we take the correct action depending upon the interrupt.
From this basic example (see attached code) you can add in the use of the match registers or more complex functions. We’ll look at that next time.
Please see the previous entries in this MicroZed series by Adam Taylor: