Programming the Si5381 on a ZCU670 board
This page describes the process to program the Si5381 clock device on the Xilinx ZCU670 board.
Table of Contents
Introduction
The ZCU670 board incorporates a Si5381 device for clock generation and the device is currently only programmed using the System Controller. The ability to program the Si5381 from an application or FSBL allows users improved system integration. At this time, Linux user space for run-time configuration is not supported but is being considered for the future.
Si5381 Details
The Si5381 is a complex device with many registers to be programmed. The ClockBuilder Pro tool, https://pages.silabs.com/clockbuilder-pro-software.html, allows a user to set up all of the clocks of the device and then create an output file with the register settings in a C header file. This generated header file can then be integrated into an application running on MPSoC to program the device. A set of four example header files based on specific clock configurations are provided for user integration such that using the ClockBuilder Pro tool is not required.
Header File Details
The ClockBuilder Pro tool can create a number of different file formats including a C header file. The following code snippet illustrates the format of the generated header file.
/*
* Si5381A Rev E Configuration Register Export Header File
*
* This file represents a series of Skyworks Si5381A Rev E
* register writes that can be performed to load a single configuration
* on a device. It was created by a Skyworks ClockBuilder Pro
* export tool.
*
* Part: Si5381A Rev E
* Design ID: test1
* Includes Pre/Post Download Control Register Writes: Yes
* Created By: ClockBuilder Pro v4.4 [2022-03-30]
* Timestamp: 2022-07-08 13:49:41 GMT-05:00
*
* A complete design report corresponding to this export is included at the end
* of this header file.
*
*/
#ifndef SI5381A_REVE_REG_CONFIG_HEADER
#define SI5381A_REVE_REG_CONFIG_HEADER
#define SI5381A_REVE_REG_CONFIG_NUM_REGS 832
typedef struct
{
unsigned int address; /* 16-bit register address */
unsigned char value; /* 8-bit register data */
} si5381a_reve_register_t;
si5381a_reve_register_t const si5381a_reve_registers[SI5381A_REVE_REG_CONFIG_NUM_REGS] =
{
/* Start configuration preamble */
{ 0x0B24, 0xC0 },
{ 0x0B25, 0x04 },
{ 0x0540, 0x01 },
/* End configuration preamble */
/* Delay 625 msec */
/* Delay is worst case time for device to complete any calibration */
/* that is running due to device state change previous to this script */
/* being processed. */
/* Start configuration registers */
{ 0x0006, 0x00 },
{ 0x0007, 0x00 },
...
{ 0x0C0C, 0x00 },
/* End configuration registers */
/* Start configuration postamble */
{ 0x0514, 0x01 },
{ 0x001C, 0x01 },
{ 0x0540, 0x00 },
{ 0x0B24, 0xC3 },
{ 0x0B25, 0x06 },
/* End configuration postamble */
};
ZCU670 Details
As with many Xilinx boards, the ZCU760 incorporates a complex I2C bus structure which incorporates an I2C switch (U20) referred to as a multiplexer (Mux).
The I2C Mux must be setup prior to programming the Si5381 device. The following schematic snippet illustrates the Si5381 being the 2nd device (SD1/SC1) on the I2C Mux and using I2C bus 1 from MPSoC.
The I2C Mux at U20 must be addressed on I2C 1 bus at address 0x74 (A0 & A1 pulled down, A2 pulled up). The following snippet illustrates the I2C address based on the pin configuration.
The following schematic snippet illustrates the configuration of the Si5381 (U43) on the ZCU670 with the device being configured for I2C communication (I2C_SEL pin pulled high) with I2C address 0x68 (A0_CSB and A1_SDO pins pulled low).
The following snippet from the Si5381 Reference Manual illustrates the I2C configuration.
Programming the Si5381
A bare metal application is provided which can be used for bare metal projects or incorporated into the FSBL. The application includes the header file that can be generated from the ClockBuilder Pro tool.
The source code provides lower level functions to read and write the registers of the Si5381 device as well as a higher level function that sets up the I2C communication on the board including initialization of the I2C mux.
The following sub-paragraphs describe some significant areas of the source code.
ClockBuilder Pro Header File Integration
The source code includes a set of four different header files for different clock configurations. The user must alter the C source file to include the appropriate header file or any other generated header files. The following illustrates the default header file which is included.
/* The following header file is the output from the ClockBuilder Pro tool
* and is a custom name which must be altered when using new generated output.
*/
#include "Si5381A-zcu670_DAC-ADC-REFCLK_122M88_03302021-Registers.h"
I2C Board Details
The following code snippet illustrates the I2C details that might need to change for a custom board.
/* The following are valid for the ZCU670 board, there is a mux to get to the
* i2c device
*/
#define I2C_MUXADDR (0x74)
#define SI5381_MUXVAL (0x2)
#define SI5381_ADDR (0x68)
#define SI5381_ID (0x5381)
#define I2C_SCLK_RATE_I2CMUX (400000U)
#define SI5381_I2C_DEVICE (XPAR_XIICPS_1_DEVICE_ID)
The following code snippet illustrates setting up the Mux so that the Si5381 device is the active device.
Si5381 Registers and Pages
The Si5381 device utilizes a paging scheme to allow all registers to be addressed. The page must be set in a separate command prior to reading or writing to a specific register. The function which writes to a register takes care of converting a register address to the appropriate page and register address.
Header File Data Processing
The ClockBuilder Pro header file included with the C source file provides the data structures that the function uses to read/write to the device registers. There is a point in the data where there is an expected time delay which is at a fixed location and handled as an exception to the normal flow.
The following code snippet illustrates iterating over the register data structure to write to each register.
System Integration
The provided source code can be built into a bare metal application which is started by the FSBL or it can be incorporated into the FSBL. The FSBL can be built in Vitis as shown at Zynq UltraScale+ FSBL. The ProgramSi5381() function is called from the XFsbl_HookBeforeHandoff() function of the FSBL such that the code runs last in FSBL. The following code snippet illustrates the changes required to incorporate it into the xfsbl_hooks.c source file of the FSBL.
Source Code
The source code for this project is provided in the zcu670-si5381 directory of https://github.com/Xilinx-Wiki-Projects/software-prototypes.
© Copyright 2019 - 2022 Xilinx Inc. Privacy Policy