AD9545 no-OS Driver
See drivers/frequency/ad9545 (doxygen) for the Doxygen documentation.
Supported Devices
Overview
The AD9545 is a quad-input, 10-output, dual DPLL/IEEE 1588 synchronizer and jitter cleaner designed for telecommunications and networking applications. It supports existing and emerging ITU standards for the delivery of frequency, phase, and time of day over service provider packet networks, including ITU-G.8262, ITU-T G.812, ITU-T G.813, and ITU-T G.8273.2. The 10 clock outputs are synchronized to any one of up to four input references, with the digital phase-locked loops reducing timing jitter associated with the external references. The digitally controlled loop and holdover circuitry continuously generate a low jitter output signal, even when all reference inputs fail. Key features include programmable reference switching, fast DPLL locking, dual independent auxiliary NCOs for IEEE 1588 servo feedback, and optional use of a crystal resonator or oscillator for frequency stability. The AD9545 operates from a single 1.8 V power supply with internal regulation and is available in a 48-lead LFCSP package, operating over the -40°C to +85°C temperature range.
Applications
Global positioning system (GPS), PTP (IEEE 1588), and synchronous Ethernet (SyncE) jitter cleanup and synchronization
Optical transport networks (OTN), synchronous digital hierarchy (SDH), and macro and small cell base stations
Small base station clocking, including baseband and radio Stratum 2, Stratum 3e, and Stratum 3 holdover, jitter cleanup, and phase transient control
JESD204B support for analog-to-digital converter (ADC) and digital-to-analog converter (DAC) clocking
Cable infrastructures
Carrier Ethernet
AD9545 Device Configuration
Driver Initialization
In order to be able to use the device, you will have to provide the
support for the communication protocol (SPI or I2C) via the
comm_type field in the initialization parameter structure.
The first API to be called is ad9545_init. Make sure that it returns
0, which means that the driver was initialized correctly. After
initialization, ad9545_setup must be called to configure system
clocks, input references, auxiliary NCOs, TDCs, and DPLLs.
PLL Configuration
The AD9545 features two independent DPLLs that can be configured for
different operating modes. The driver supports active closed-loop
operation, holdover, and free-run modes via ad9545_set_pll_mode.
Translation profiles define the relationship between input references
and output frequencies, with automatic or manual profile selection modes
available.
Clock Management
Clock management functions, including ad9545_in_clk_recalc_rate and
ad9545_get_nco_freq_hz, manage recalibration of clock rates and
frequency settings. The R dividers and Q dividers can be configured via
ad9545_set_r_div and ad9545_set_q_div respectively, while NCO
center frequencies are set with ad9545_set_nco_center_freq.
Auxiliary Features
Auxiliary setup functions such as ad9545_aux_dpll_setup and
ad9545_aux_tdcs_setup configure additional components like DPLLs and
TDCs. Two independent auxiliary NCOs provide frequency output from 1 Hz
to 65,535 Hz, suitable for IEEE 1588 Version 2 servo feedback in PTP
applications.
Communication Protocol
The driver supports both SPI and I2C communication interfaces. Key
functions such as ad9545_spi_reg_read, ad9545_spi_reg_write,
ad9545_i2c_reg_read, and ad9545_i2c_reg_write handle register
access. Low-level register operations via ad9545_read_reg,
ad9545_write_reg, and ad9545_write_mask enable precise control
over device registers.
Driver Initialization Example
#include "ad9545.h"
struct no_os_spi_init_param ad9545_spi_ip = {
.device_id = 0,
.max_speed_hz = 1000000,
.mode = NO_OS_SPI_MODE_0,
.platform_ops = SPI_OPS,
.chip_select = 0,
.extra = SPI_EXTRA
};
struct ad9545_init_param ad9545_ip = {
.spi_init = &ad9545_spi_ip,
.comm_type = SPI,
};
int main(void)
{
int32_t ret;
struct ad9545_dev *dev;
ret = ad9545_init(&dev, &ad9545_ip);
if (ret)
goto error;
ret = ad9545_setup(dev);
if (ret)
goto error_remove;
/* Device is ready for use. */
ad9545_remove(dev);
return 0;
error_remove:
ad9545_remove(dev);
error:
return ret;
}