ADC LTC2311 V3#
Introduction#
The IP core ADC_LVDS_LTC2311 in version 3 is designed to read the ADCs which are located on the analog adapter board and to further process the values obtained from the ADCs.
The IP core features an AXI4 Lite interface for settings and software control.
The conversion can be triggered by using the hardware port TRIGGER_CONV
for real-time control.
The IP-Core adds an offset value to the raw value and multiplies the result with a conversion factor, which in turn is available on the hardware port SI_VALUE
.
The raw value from the ADC and the processed value are std_logic_vectors
at the hardware interface of the IP core.
For a thorough project description please refer to the project report which is available in the Downloads section.
Features#
Up to 32 independent Serial Peripheral Interface (SPI) Masters with each up to 32 synchronous channels. In total up to 1024 individual ADCs are theoretically possible with one IP-Core instance.
Pipelined addition with an offset value and subsequent multiplication with a conversion factor with the following features:
Low resource footprint due to pipelined setup
Each individual SPI Master features one DSP48 block
The results from the synchronous SPI channels are piped through the DSP48 block. This leads to high throughput while maintaining a low resource footprint by not granting a single DSP48 block per ADC channel.
Offset and conversion factor are configurable by software individually for each ADC
Offset is set as an signed integer
COnversion factor is set as a fixed point value
Burst transfer of an adjustable number of samples
Continuous and triggered operation modes
Hardware trigger interface for real-time requirements and software trigger interface via AXI4 Lite for convenient usage in case of non time-critical applications
Software control:
Software trigger
Software reset
CPHA
,CPOL
, andSCLK
frequency of the SPI interface are configurable by softwareThe
SCLK
frequency scales with \(f_{SCLK} = \frac{ f_{SystemClock} }{2 \cdot (CLK\_DIV + 1)}\)
Read only SPI. Only a unidirectional communication from the ADC to FPGA is possible.
Single ended and differential operation modes. In order to interact with the analog adapter board, the interface must be set to differential. In this case, an LVDS buffer is instantiated inside the IP core.
Software Driver#
The configuration of the IP-Core settings by software use the control register, the SPI-Master, and the channel selection to distribute the configuration values from one AXI register to the internal configuration registers in the IP-Core.
The control register is used to set the trigger mode, trigger the conversion, reset the IP-Core or determine to which register in the IP-Core the value in the Configuration Value Register
AXI register should be written.
This control is facilitated by writing different bit patterns to the control register (see table ADC_CR).
To write a config value to a specific ADC channel, the number of the SPI master and the desired channel has to be written to the master channel selection and ADC channel selection AXI registers.
Furthermore, the control register has to be set to match the variable that is write to the Configuration Value Register
.
Effectively, the SPI master and channel selection as well as the configuration value register act as a switch to route the values from the AXI registers to the ADC channels.
To write a specific conversion factor to one of the ADC channels, the following steps are performed:
read the current value from the configuration register
Reset all bits that encode what the
Configuration Value Register
holds (bit 5 to 7)Set the bit pattern to
001
to indicate that the value is the conversion factorWrite the spi master and channel number to the AXI registers of the ADC channel that has to be changed
Write the conversion factor to
Configuration Value Register
Write the configuration to the configuration register
Call
uz_adcLtc2311_cr_wait_for_value_acknowledgement
which repeatedly reads the configuration register and waits for the acknowledgement of a successful data transfer
Configuration Procedure#
The test bench function below displays an example of how to configure and use the IP core. In this example the software trigger is used but instead the hardware trigger in the FPGA can be used as well. The functions are further explained in the section Representation in Software.
The following settings are set globally for each IP-Core instance:
base_address
ip_clk_frequency_Hz
pre_delay
post_delay
clk_div
cpha
cpol
max_attempts
mode (either triggered or continuous sampling)
The following settings are set on a per master basis within one IP-Core instance:
sleeping_spi_masters
napping_spi_masters
error_code
samples
sample_time
Trigger mode (software, PL, continuous)
The following settings are set on a per channel basis of one SPI master within an IP-Core instance:
conversion_factor
offset
Additionally, the trigger as well as the software trigger affects all ADC channels of one SPI master.
Example initialization of three IP-Core driver instances:
#define XPAR_A1_ADC_LTC2311_IP_CORE_FREQUENCY 100000000U
#define DEFAULT_CONVERSION_FACTOR 1.0f
#define DEFAULT_INTEGER_BITS 14
#define DEFAULT_FRACTIONAL_BITS 4
#define DEFAULT_OFFSET 0
void uz_adcLtc2311_ip_core_init(void)
{
struct uz_adcLtc2311_config_t default_configuration = {
.base_address = XPAR_A1_ADC_LTC2311_S00_AXI_BASEADDR,
.ip_clk_frequency_Hz = XPAR_A1_ADC_LTC2311_IP_CORE_FREQUENCY,
.channel_config = {
.conversion_factor = DEFAULT_CONVERSION_FACTOR,
.conversion_factor_definition = {
.is_signed = true,
.integer_bits = DEFAULT_INTEGER_BITS,
.fractional_bits = DEFAULT_FRACTIONAL_BITS},
.offset = DEFAULT_OFFSET,
},
.spi_master_config = {.samples = 1U, .sample_time = 6U, .trigger_mode=pl_trigger},
.cpol = 1U,
.cpha = 0U,
.napping_spi_masters = 0U,
.sleeping_spi_masters = 0U,
.master_select = UZ_ADCLTC2311_MASTER1,
.channel_select = UZ_ADCLTC2311_CH1 | UZ_ADCLTC2311_CH2 | UZ_ADCLTC2311_CH3 | UZ_ADCLTC2311_CH4 | UZ_ADCLTC2311_CH5 | UZ_ADCLTC2311_CH6 | UZ_ADCLTC2311_CH7 | UZ_ADCLTC2311_CH8,
.pre_delay = 0U,
.post_delay = 0U,
.clk_div = 0U,
.max_attempts = 10U};
// Apply the same configurations to all instances
uz_adcLtc2311_t *test_instance = uz_adcLtc2311_init(default_configuration);
default_configuration.base_address = XPAR_A2_ADC_LTC2311_S00_AXI_BASEADDR;
uz_adcLtc2311_t *test_instance_2 = uz_adcLtc2311_init(default_configuration);
default_configuration.base_address = XPAR_A3_ADC_LTC2311_S00_AXI_BASEADDR;
uz_adcLtc2311_t *test_instance_3 = uz_adcLtc2311_init(default_configuration);
}
Change trigger mode to triggered by software:
uz_adcLtc2311_change_trigger_mode(test_instance, software_trigger);
Change conversion factor of ADC1, ADC2, and ADC3 of SPI-Master 1 to 2.0
and ADC4 to 10.0
.
struct uz_adcLtc2311_channel_config_t adc_123_config={
.conversion_factor=2.0f,
.conversion_factor_definition={
.is_signed=true,
.fractional_bits=5,
.integer_bits=13
},
.offset=0
};
uz_adcLtc2311_set_channel_config(test_instance, UZ_ADCLTC2311_MASTER1, (UZ_ADCLTC2311_CH1 | UZ_ADCLTC2311_CH2 | UZ_ADCLTC2311_CH3), adc_123_config);
struct uz_adcLtc2311_channel_config_t adc_4_config={
.conversion_factor=10.0f,
.conversion_factor_definition={
.is_signed=true,
.fractional_bits=5,
.integer_bits=13
},
.offset=0
};
uz_adcLtc2311_set_channel_config(test_instance, UZ_ADCLTC2311_MASTER1, UZ_ADCLTC2311_CH4, adc_4_config);
Note
The conversion factor only affects the output of the IP-Core SI_VALUE
.
Additionally, the number of fractional bits of the conversion factor implicitly determine the number of fractional bits of the SI_VALUE
port.
Example: For Result LSB=0
and Result MSB=34
in the IP-Core settings and an conversion factor with 5 fractional bits, the lowest 5 bits of SI_VALUE
(for each output value) have to be interpreted as fractional bits.
Driver reference#
Representation in software#
-
typedef struct uz_adcLtc2311_t uz_adcLtc2311_t#
Data type for object adcLtc2311.
-
struct uz_adcLtc2311_channel_config_t#
Configuration struct that holds parameters that are adjustable on a per-channel basis.
-
struct uz_adcLtc2311_spi_master_config_t#
Configuration struct that holds parameters that are adjustable on a per SPI master basis.
-
enum uz_adcLtc2311_trigger_mode#
Enum to determine the trigger mode of a SPI-Master.
Values:
-
enumerator pl_trigger#
Conversion is only triggered by IP-Core PL port
-
enumerator software_trigger#
Conversion is only triggered by software
-
enumerator continuous_trigger#
Conversion is triggered continuously with the maximum frequency
-
enumerator pl_trigger#
-
struct uz_adcLtc2311_config_t#
Configuration struct for adcLtc2311.
Public Members
-
uint32_t base_address#
Base address of the IP-Core. No get or set function available
-
uint32_t ip_clk_frequency_Hz#
Clock frequency of the IP-Core. No get or set function available
-
uint32_t master_select#
One hot encoded variable to select the SPI masters that shall be configured
-
uint32_t channel_select#
One hot encoded variable to select the channels of the selected SPI masters shall be configured
-
uint32_t pre_delay#
See the SPI configuration register for explanation
-
uint32_t post_delay#
See the SPI configuration register for explanation
-
uint32_t clk_div#
See the SPI configuration register for explanation
-
uint32_t cpha#
SPI CPHA. Must be set to 0 for the LTC2311
-
uint32_t cpol#
SPI CPOL. Must be set to 1 for the LTC2311
-
uint32_t error_code#
One-Hot encoded error variable if the usage of nap or sleep mode fails
-
uint32_t max_attempts#
If non zero, the update of the operation parameters is tried max_attempts times. Otherwise it is tried infinitely (default)
-
uint32_t base_address#
Operation#
-
uz_adcLtc2311_t *uz_adcLtc2311_init(struct uz_adcLtc2311_config_t config)#
Initializes an instance of the adcLtc2311.
This function allocates an instance of the IP core and updates the operation parameters that are shipped with the given uz_adcLtc2311_config_t configuration struct
The function initializes the hardware by executing the following functions:
- Parameters:
config – Configuration values for the IP-Core
- Returns:
Pointer to initialized instance
-
uint32_t uz_adcLtc2311_update_conversion_factor(uz_adcLtc2311_t *self)#
Update the conversion factor of the indicated channels.
- Parameters:
self – Pointer to driver instance
- Returns:
UZ_FAILURE when the hardware did not acknowledge the update of the value within max_attempts. Otherwise, the function returns UZ_SUCCESS.
-
uint32_t uz_adcLtc2311_update_offset(uz_adcLtc2311_t *self)#
Update the offset of the indicated channels.
- Parameters:
self – Pointer to driver instance
- Returns:
UZ_FAILURE when the hardware did not acknowledge the update of the value within max_attempts. Otherwise, the function returns UZ_SUCCESS.
-
uint32_t uz_adcLtc2311_update_samples(uz_adcLtc2311_t *self)#
Update the samples per trigger event of the indicated channels.
- Parameters:
self – Pointer to driver instance
- Returns:
UZ_FAILURE when the hardware did not acknowledge the update of the value within max_attempts. Otherwise, the function returns UZ_SUCCESS.
-
uint32_t uz_adcLtc2311_update_sample_time(uz_adcLtc2311_t *self)#
Update the sample time of the indicated channels.
- Parameters:
self – Pointer to driver instance
- Returns:
UZ_FAILURE when the hardware did not acknowledge the update of the value within max_attempts. Otherwise, the function returns UZ_SUCCESS.
-
void uz_adcLtc2311_update_spi(uz_adcLtc2311_t *self)#
Updates the global SPI configuration of the IP core.
- Parameters:
self – Pointer to driver instance
-
void uz_adcLtc2311_set_triggered_mode(uz_adcLtc2311_t *self)#
Enable the triggered sampling mode.
- Parameters:
self – Pointer to driver instance
-
void uz_adcLtc2311_set_continuous_mode(uz_adcLtc2311_t *self)#
Enable the continuous sampling mode.
- Parameters:
self – Pointer to driver instance
-
void uz_adcLtc2311_software_trigger(uz_adcLtc2311_t *self, uint32_t spi_masters)#
Trigger the selected SPI Masters.
- Parameters:
self – Pointer to driver instance
spi_masters – If non zero, the argument is interpreted as a binary mask which masters shall be triggered. If zero, the master_select value from uz_adcLtc2311_config_t is considered instead.
-
void uz_adcLtc2311_software_reset(uz_adcLtc2311_t *self)#
Reset the IP core. This function has the same effect as applying a low pulse to the RESET_N pin of the IP core.
Nap and Sleep Mode#
-
uint32_t uz_adcLtc2311_enter_nap_mode(uz_adcLtc2311_t *self)#
Send the selected channels to nap mode.
The function depends on the master_select and the max_attempts setting in uz_adcLtc2311_config_t. master_select determines, which channels are sent to nap mode and max_attempts determines the maximum number of attempts to enter the manual control mode of the SPI. Adjust these settings before calling the function.
#defines for the error_code variable in case of failure are located in the uz_adcLtc2311.h file (public interface of this software module).
- Parameters:
self – Pointer to driver instance
- Returns:
UZ_FAILURE if the operation failed. Check the error_code from uz_adcLtc2311_config_t for details. Otherwise, return value is UZ_SUCCESS
-
uint32_t uz_adcLtc2311_leave_nap_mode(uz_adcLtc2311_t *self)#
Return the selected channels from nap mode to operation mode.
The function depends on the master_select and the max_attempts setting in uz_adcLtc2311_config_t. master_select determines, which channels leave nap mode and max_attempts determines the maximum number of attempts to enter the manual control mode of the SPI. Adjust these settings before calling the function.
#defines for the error_code variable in case of failure are located in the uz_adcLtc2311.h file (public interface of this software module).
- Parameters:
self – Pointer to driver instance
- Returns:
UZ_FAILURE if the operation failed. Check the error_code from uz_adcLtc2311_config_t for details. Otherwise, return value is UZ_SUCCESS
-
uint32_t uz_adcLtc2311_enter_sleep_mode(uz_adcLtc2311_t *self)#
Send the selected channels to sleep mode.
The function depends on the master_select and the max_attempts setting in uz_adcLtc2311_config_t. master_select determines, which channels are sent to sleep mode and max_attempts determines the maximum number of attempts to enter the manual control mode of the SPI. Adjust these settings before calling the function.
#defines for the error_code variable in case of failure are located in the uz_adcLtc2311.h file (public interface of this software module).
- Parameters:
self – Pointer to driver instance
- Returns:
UZ_FAILURE if the operation failed. Check the error_code from uz_adcLtc2311_config_t for details. Otherwise, return value is UZ_SUCCESS
-
uint32_t uz_adcLtc2311_leave_sleep_mode(uz_adcLtc2311_t *self)#
Return the selected channels from sleep mode to operation mode.
The function depends on the master_select and the max_attempts setting in uz_adcLtc2311_config_t. master_select determines, which channels leave sleep mode and max_attempts determines the maximum number of attempts to enter the manual control mode of the SPI. Adjust these settings before calling the function. According to the data sheet of the LTC2311, one must wait 10ms before operating the ADC again after exiting the sleep mode. This is not performed by this function. The user needs to take care about this.
#defines for the error_code variable in case of failure are located in the uz_adcLtc2311.h file (public interface of this software module).
- Parameters:
self – Pointer to driver instance
- Returns:
UZ_FAILURE if the operation failed. Check the error_code from uz_adcLtc2311_config_t for details. Otherwise, return value is UZ_SUCCESS
Parameter Adjustment#
Every parameter in configuration struct has a get and set function by default.
If a get or set function is not available it is mentioned explicitly.
The self
parameter is always a pointer to the instance representing the IP core in software.
The get function always asserts that self is not NULL and that the instance is ready and then it returns the demanded value.
If the set function is not further explained below, the value is not examined for validity. Otherwise, the performed asserts are mentioned below.
-
void uz_adcLtc2311_set_channel_config(uz_adcLtc2311_t *self, uint32_t master_select, uint32_t channel_select, struct uz_adcLtc2311_channel_config_t channel_config)#
Wrapper function to set the conversion factor and offset of specified channels of one or multiple SPI-Masters in a single function call.
- Parameters:
self – Pointer to driver instance
master_select – Bitmask to select SPI-Masters - use UZ_ADCLTC2311_MASTER defines
channel_select – Bitmask to select ADC-Channels - use UZ_ADCLTC2311_CH32 defines
channel_config – Config struct that is written to the IP-Core to change offset and conversion factor
-
void uz_adcLtc2311_change_trigger_mode(uz_adcLtc2311_t *self, enum uz_adcLtc2311_trigger_mode trigger_mode)#
Wrapper function to set the trigger mode for the driver instance.
- Parameters:
self – Pointer to driver instance
trigger_mode –
-
void uz_adcLtc2311_set_samples(uz_adcLtc2311_t *self, uint32_t value)#
Set the number of samples taken per trigger event. Asserts that the value is in a valid range.
- Parameters:
self – Pointer to driver instance
value – Number of samples taken per trigger event. Min: 1 Max: (2^31)-1 = 2147483647
-
void uz_adcLtc2311_set_sample_time(uz_adcLtc2311_t *self, uint32_t value)#
Set the minimum number of system clock cycles between two samples.
In this period, the sample and hold capacitor of the ADC is charged. The appropriate time depends on the driving strength of the signal. Asserts that the value is in a valid range.
- Parameters:
self – Pointer to driver instance
value – Minimum number of system clock cycles that the SS_N signal stays high. Max: (2^31)-1 = 2147483647
-
void uz_adcLtc2311_set_pre_delay(uz_adcLtc2311_t *self, uint32_t value)#
Asserts that not too many MSBs are set and that the value fits in the config register.
- Parameters:
self – Pointer to driver instance
value – Number of system clock cycles for the PRE_DELAY
-
void uz_adcLtc2311_set_post_delay(uz_adcLtc2311_t *self, uint32_t value)#
Asserts that not too many MSBs are set and that the value fits in the config register.
- Parameters:
self – Pointer to driver instance
value – Number of system clock cycles for the POST_DELAY
-
void uz_adcLtc2311_set_clk_div(uz_adcLtc2311_t *self, uint32_t value)#
Asserts that not too many MSBs are set and that the value fits in the config register.
- Parameters:
self – Pointer to driver instance
value – Clock divider to scale the SCLK signal
-
void uz_adcLtc2311_set_cpha(uz_adcLtc2311_t *self, uint32_t value)#
Set the edge, on which edge the first bit is sampled. Must be the first edge (a.k.a. CPHA = 0) for the LTC2311. Asserts, that the value is 0.
- Parameters:
self – Pointer to driver instance
value – If 0, the first bit is sampled on the first edge of SCLK. If non 0, the first bit is sampled on the second edge of SCLK.
-
void uz_adcLtc2311_set_cpol(uz_adcLtc2311_t *self, uint32_t value)#
Determines the IDLE state of SCLK. Must be the logic high (a.k.a. CPOL = 1) for the LTC2311. Asserts, that the value is non 0.
- Parameters:
self – Pointer to driver instance
value – If 0, the IDLE state of SCLK is 0. If non 0, the IDLE state of SCLK is 1.
Functional Description#
Architecture#
The IP core is hierarchically organized. The figure below shows the components of the IP core. Every component is a single VHDL file. The functionality, which is assigned to the component is also mentioned in the figure.
Configuration Registers#
Control Register#
Address offset: 0x0
Software control register of the IP core.
Bit(s) |
Name |
Default Value |
Access |
True (‘1’) |
False (‘0’) |
---|---|---|---|---|---|
0 |
MODE |
0 |
Read/Write |
Continuous mode: The core is triggered as frequent as possible |
Triggered mode: The core must be triggered by software or by hardware where hardware trigger is prioritized |
1 |
SW_TRIGGER_MODE |
Read/Write |
0 |
Trigger conversion in triggered mode only from software driver (AXI) |
Trigger conversion in triggered mode only from PL (TRIGGER_CNV) |
2 |
TRIGGER |
0 |
Read/Write |
Start conversion of the channels selected in ADC_MASTER_CHANNEL synchronously. If a selected channel is busy when the bit is set a new conversion is only started after the ongoing conversion has terminated. |
The bit is reset by hardware after the conversion has been started synchronously. |
3 |
SW_RESET |
0 |
Read/Write |
Trigger a reset of the IP core by software. All registers and ports are reset to their default values. |
Reset finished. Reading from this bit always returns 0. |
4 |
CONV_VALUE_VALID |
0 |
Read/Write |
Indicates that the value in ADC_VALUE is valid. After setting the bit the value will be updated in the selected channels as soon as the selected channels are not busy anymore. |
Reset by hardware after the value in ADC_VALUE is read. |
[5..7] |
CR_CONFIG_VALUE_[0..2] |
000 |
Read/Write |
See table below |
See table below |
By setting the bits 5 to 7 the meaning of the value in the ADC_VALUE
register is determined.
Bit 5 to 7 are interpreted as an unsigned integer.
7 |
6 |
5 |
Access |
Description |
Encoding |
---|---|---|---|---|---|
0 |
0 |
0 |
Read/Write |
The value in the |
Signed two’s complement |
0 |
0 |
1 |
Read/Write |
The value in the |
Signed two’s complement |
0 |
1 |
0 |
Read/Write |
The value in the |
Unsigned integer |
0 |
1 |
1 |
Read/Write |
The value in the |
Unsigned integer |
1 |
0 |
0 |
Read/Write |
Reserved |
|
1 |
0 |
1 |
Read/Write |
Reserved |
|
1 |
1 |
0 |
Read/Write |
Reserved |
|
1 |
1 |
1 |
Read/Write |
Reserved |
SPI Control Register#
Address offset: 0x4
The SPI interfaces can be controlled manually with this register in order to use sleep and nap modes of the ADC.
The signal SS_N
and SCLK
only can be controlled manually if the selected master channels are not busy.
Check ADC_MASTER_BUSY as a status indicator.
Furthermore, the clock polarity and the sample phase are set with this register. This setting applies globally to all SPI masters instantiated.
Bit(s) |
Name |
Default Value |
Access |
True (‘1’) |
False (‘0’) |
---|---|---|---|---|---|
0 |
SPI_SS_N |
0 |
Read/Write |
Set the SS_N signal to high |
Set the SS_N signal to low |
1 |
SPI_SS_N_STATUS |
0 |
Read/Write |
The SS_N signal is high |
The SS_N signal is low |
2 |
SPI_SCLK |
0 |
Read/Write |
Set the SCLK signal to high |
Set the SCLK signal to low |
3 |
SPI_SCLK_STATUS |
0 |
Read/Write |
The SCLK signal is high |
The SCLK signal is low |
4 |
SPI_CONTROL |
0 |
Read/Write |
Enable manual control of the SPI. |
Disable manual control of the SPI |
5 |
SPI_CONTROL_STATUS |
0 |
Read/Write |
Manual control of the SPI interface is possible. |
Manual control of the SPI interface is not possible. |
6 |
SPI_CPOL |
1 |
Read/Write |
IDLE state of the SCLK signal is logic high |
IDLE signal of the SCLK signal is logic low |
7 |
SPI_CPHA |
0 |
Read/Write |
Sample on the second edge of SCLK |
Sample on the first edge of SCLK |
SPI Configuration Register#
Address offset: 0x8
Setting for
DCNVSCKL (a.k.a PRE_WAIT)
DSCKLCNVH (a.k.a POST_WAIT)
Number of system clock cycles per half SCLK cycle - 1 (a.k.a CLK_DIV)
See figure 21 in the datasheet of the LTC2311 for illustration.
The values given indicate the number of system clock cycles for the time described.
Bit(s) |
Name |
Default Value |
Access |
Description |
Encoding |
---|---|---|---|---|---|
0 - 15 |
CLK_DIV |
0 |
Read/Write |
Number of system clock cycles per half SCLK period - 1 |
Unsigned integer (binary) |
16 - 23 |
PRE_WAIT |
0 |
Read/Write |
Number of system clock cycles between the falling edge of SS_N and first SCLK edge - 1. a.k.a DCNVSCKL |
Unsigned integer (binary) |
24 - 31 |
POST_WAIT |
0 |
Read/Write |
Number of system clock cycles between the last rising edge of SCLK and the rising edge of SS_N - 1. a.k.a DSCKLCNVH |
Unsigned integer (binary) |
Master Channel selection#
Address offset: 0xC
Encoding: One-Hot
This register is used for two different functions:
Update of the configuration values such as offset, conversion factor and number of samples per trigger. In order to specify which individual ADC channels shall be updated, the SPI master as well as the ADC which is controlled by the selected SPI master channel must be selected. The individual channel selection is done in ADC_CHANNEL.
Channel selection for software trigger: When setting the software trigger bit in the ADC_CR all channels selected in ADC_MASTER_CHANNEL are triggered by software. When using hardware trigger the content of this register is ignored.
Bit(s) |
Name |
Default Value |
Access |
True (‘1’) |
False (‘0’) |
---|---|---|---|---|---|
0 - 31 |
ADC_MASTER_0 - ADC_MASTER_31 |
0 |
Read/Write |
The master is selected for the specified operation |
The master is not selected for the specified operation |
ADC Channel selection#
Address offset: 0x10
Encoding: One-Hot
When updating the offset and conversion factor select the channel on the SPI masters selected in ADC_MASTER_CHANNEL that shall be updated.
Bit(s) |
Name |
Default Value |
Access |
True (‘1’) |
False (‘0’) |
---|---|---|---|---|---|
0 - 31 |
ADC_CH_0 - ADC_CH_31 |
0 |
Read/Write |
The individual ADC channel is selected for the specified operation |
The individual ADC channel is not selected for the specified operation |
Transmission ended register#
Address offset: 0x14
Encoding: One-Hot
This register indicates that an SPI master unit finished with the transmission of the raw value from the SPI master i.e. the value on the hardware port RAW_VALUE
is valid for the indicated channels.
Bit(s) |
Name |
Default Value |
Access |
True (‘1’) |
False (‘0’) |
---|---|---|---|---|---|
0 - 31 |
ADC_MASTER_0 - ADC_MASTER_31 |
0 |
Read only |
The transmission on the specified master channel finished |
There is a transmission ongoing on the master channel |
Addition and Multiplication ended register#
Address offset: 0x18
Encoding: One-Hot
This register indicates that an SPI master unit finished with the addition and the multiplication of the raw value i.e. the value on the hardware port SI_VALUE
is valid for the indicated channels.
Bit(s) |
Name |
Default Value |
Access |
True (‘1’) |
False (‘0’) |
---|---|---|---|---|---|
0 - 31 |
ADC_MASTER_0 - ADC_MASTER_31 |
0 |
Read only |
The processing the specified master channel finished |
There is processing ongoing on the master channel |
Conversion ongoing indicator#
Address offset: 0x1C
Encoding: One-Hot
The indicated master channels are currently busy i.e. a transmission or a multiplication is ongoing.
Bit(s) |
Name |
Default Value |
Access |
True (‘1’) |
False (‘0’) |
---|---|---|---|---|---|
0 - 31 |
ADC_MASTER_0 - ADC_MASTER_31 |
0 |
Read only |
The specified master channel is busy |
The specified master channel is not busy |
Configuration Value register#
Address offset: 0x20
Encoding: Depending on the value
The value for the offset and the conversion factor is given in this register. The distinction between the offset and the conversion factor is done in ADC_CR.
Bit(s) |
Name |
Default Value |
Access |
Description |
Encoding |
---|---|---|---|---|---|
0 - 31 |
CLK_DIV |
0 |
Read/Write |
Offset or conversion value |
Offset: Unsigned integer. Conversion: Signed integer two’s complement |
ADC Available indicator#
Address offset: 0x24
Encoding: One-Hot
The indicated master channels are currently not available because they are either in sleep mode or in nap mode. This register is set by software and used by the hardware in order to prohibit a trigger when an ADC is not available.
Bit(s) |
Name |
Default Value |
Access |
True (‘1’) |
False (‘0’) |
---|---|---|---|---|---|
0 - 31 |
ADC_MASTER_0 - ADC_MASTER_31 |
1 |
Read/Write |
The specified master channel is available |
The specified master channel is not available |
Design Parameters#
Parameter Name |
Allowable Values |
Default Values |
VHDL Type |
Description |
---|---|---|---|---|
DATA_WIDTH |
1 - 24 |
16 |
|
Data output width of the connected SPI slave (i.e. ADC) |
CHANNELS_PER_MASTER |
1 - 32 |
8 |
|
Number of SPI slaves that are controlled synchronously by one SPI master |
SPI_MASTER |
1 - 32 |
1 |
|
Number of independent SPI masters |
OFFSET_WIDTH |
1 - |
16 |
|
Bit width of the offset value which is added to the raw value |
CONVERSION_WIDTH |
1 - 18 |
18 |
|
Bit width of the conversion value the sum of the offset and the raw value is multiplied with |
RES_LSB |
0 - |
6 |
|
LSB of the result vector of the DSP48 block which is connected to the IP core |
RES_MSB |
0 - |
23 |
|
MSB of the result vector of the DSP48 block which is connected to the IP core |
DIFFERENTIAL |
|
|
|
If true differential buffers are instantiated for SCLK and MISO ports. Otherwise standard CMOS buffers are instantiated |
I/O Signals (Interface)#
Fig. 314 shows the interface of the IP-Core and the mapping of using multiple SPI-Master / Channels to the interface. ALl signals from the SPI-Master and individual channels are concated into one vector for each signal. For differential signals, all even bit number is the P signal, the odd bit numbers are the N signal.
Clock and Reset#
The IP core is globally clocked with the signal s00_axi_aclk
.
The global reset signal apart from the software reset is s00_axi_aresetn
.
The reset is synchronous and low active.
Keep this signal high for normal operation.
The IP core has been tested with a system clock frequency of up to 100MHz. The if the IP core is operated with a higher frequency, the PRE_DELAY and the POST_DELAY of the SPI must be adjusted according to the datasheet of the LTC2311. Besides that, the minimum sample time should be adjusted to a value, that meets the hardware requirements of the LTC2311 and suits the driving strength of the captured analog signal.
AXI Signals#
All signals with the prefix s00_axi
belong to the AXI4 Lite interface.
See the Xilinx AXI signal description for details.
Other I/O Signals#
Port Name |
Direction |
Port Definition |
Reset State |
Description |
---|---|---|---|---|
RAW_VALUE |
O |
std_logic_vector(DATA_WIDTH * CHANNELS_PER_MASTER * SPI_MASTER - 1 downto 0) |
‘0’ |
Raw value outputed by the ADC |
SI_VALUE |
O |
std_logic_vector((SPI_MASTER * CHANNELS_PER_MASTER * (RES_MSB - RES_LSB + 1) ) - 1 downto 0) |
‘0’ |
Converted Value = (RAW_VALUE + OFFSET) * CONVERSION |
RAW_VALID |
O |
std_logic_vector(SPI_MASTER - 1 downto 0) |
‘0’ |
The value on port RAW_VALUE is valid. High activ |
SI_VALID |
O |
std_logic_vector(SPI_MASTER - 1 downto 0) |
‘0’ |
The value on port SI_VALUE is valid. High activ |
TRIGGER_CNV |
I |
std_logic_vector(SPI_MASTER - 1 downto 0) |
– |
Hardware trigger input to trigger a conversion |
SCLK |
O |
std_logic_vector(SPI_MASTER - 1 downto 0) |
‘1’ |
SCLK signal for each individual SPI master. Only available if |
SCLK_DIFF |
O |
std_logic_vector(2 * SPI_MASTER - 1 downto 0) |
logic 1 |
Differential SCLK signal for each individual SPI master. Only available if |
SS_N |
O |
std_logic_vector(SPI_MASTER - 1 downto 0) |
‘0’ |
SS_N signal for each individual SPI master |
MISO |
I |
std_logic_vector(CHANNELS_PER_MASTER * SPI_MASTER - 1 downto 0) |
– |
Data input for each individual ADC. Only available if |
MISO_DIFF |
I |
std_logic_vector(2 * CHANNELS_PER_MASTER * SPI_MASTER - 1 downto 0) |
– |
Differential data input for each individual ADC. Only available if |
SAMPLE_COUNTER |
O |
std_logic_vector((SPI_MASTER * C_S00_AXI_DATA_WIDTH) - 1 downto 0) |
0 |
Number of the current sample in the ongoing burst. |
Terminology#
One-Hot Encoding#
One-Hot encoding means that every bit in a register controls a channel of the IP core. This channel can be either an SPI master instance with a DSP48 block or a channel (a.k.a. individual ADC) of that instance which is synchronously controlled with the other channels assigned to the SPI master instance. This distinction is done in the description of the individual register.
Example#
Example of using SI-Value output of ADC-IP-Core with sfix18_En11 output data type#
In this example the SI_VALUE
output vector of the ADC-IP-Core is used.
This vector contains the output values of all channels successively.
The fixed point datatype (the number of integer and fractional bits) of the SI-Values of each channel can be set in software on a per channel basis.
To get the output values of a single channel the output-vector needs to be sliced.
The length of the individual values is determined by the datatype with the length equaling the sum of integer and fractional bits.
The LSBs (of each output value) are the fractional bits.
In this example the datatype sfix18_En11
is required for the SI-values.
This datatype contains 7 integer bits and 11 fractional bits, so a total of 18 bits.
These values have to be configured in the IP-Core driver initialization.
The first value in the SI-Value-vector is contained in the bits 0 to 17.
The second value is in the bits 18 to 24, and so on for the rest of the values.
The number of bits per values depending on the configured datatype, in this case sfix18_En11
with a length of 18 bit.
Besides the datatype the conversion factor and offset have to be configured. The SI-Value is calculated by adding an offset to the raw-value of the ADC and afterwards multiplying the result with the conversion factor. The conversion factor and offset are also configured in the initialization of the ADC-IP-Core.
In this example following offset and conversion factor are used:
The Raw-value of the 16-Bit-ADC is between 0 and 65635. The measurement range of the ADC is from \(-5\,V`\) to \(5\,V\). As only the positive range of the ADC is used in this example the raw-value has to be offsetted by a quarter of the measurement range, -2.5V or \(\frac{-2^{16}}{4} = -16384\). For scaling is a factor of 100 necessary, which hast to be divided by \(2^{16}\) to get the correct conversion factor of \(\frac{100}{2^{16}}\).
In the listing the configuration for the IP-Core initialization can be seen. The configuration contains the discussed values of the conversion factor, offset and datatype with integer and fractional bits. All channels are configured with the same parameters.
void uz_adcLtc2311_ip_core_init(void)
{
struct uz_adcLtc2311_config_t default_configuration = {
.base_address = XPAR_UZ_ANALOG_ADAPTER_A1_ADAPTER_A1_ADC_LTC2311_S00_AXI_BASEADDR,
.ip_clk_frequency_Hz = XPAR_A1_ADC_LTC2311_IP_CORE_FREQUENCY,
.channel_config = {
.conversion_factor = 0.001526,
.conversion_factor_definition = {
.is_signed = true,
.integer_bits = 7,
.fractional_bits = 11},
.offset = -16384,
},
.spi_master_config = {.samples = 1U, .sample_time = 6U, .trigger_mode=pl_trigger},
.cpol = 1U,
.cpha = 0U,
.napping_spi_masters = 0U,
.sleeping_spi_masters = 0U,
.master_select = UZ_ADCLTC2311_MASTER1,
.channel_select = UZ_ADCLTC2311_CH1 | UZ_ADCLTC2311_CH2 | UZ_ADCLTC2311_CH3 | UZ_ADCLTC2311_CH4 | UZ_ADCLTC2311_CH5 | UZ_ADCLTC2311_CH6 | UZ_ADCLTC2311_CH7 | UZ_ADCLTC2311_CH8,
.pre_delay = 0U,
.post_delay = 0U,
.clk_div = 0U,
.max_attempts = 10U};
// Apply the same configurations to all instances
uz_adcLtc2311_init(default_configuration);
default_configuration.base_address = XPAR_UZ_ANALOG_ADAPTER_A2_ADAPTER_A2_ADC_LTC2311_S00_AXI_BASEADDR;
uz_adcLtc2311_init(default_configuration);
default_configuration.base_address = XPAR_UZ_ANALOG_ADAPTER_A3_ADAPTER_A3_ADC_LTC2311_S00_AXI_BASEADDR;
uz_adcLtc2311_init(default_configuration);
}
In the vivado block-design the SI_VALUE
output vector can be accessed and used. The structure of the vector depends on the ip-core configuration, that can be seen in the next figure.
The length of the vector depends on the number of channels and the length of the individual values of the channel (Result MSB - Result LSB +1).
In this example the length of the values is 18 bit according to the used datatype. With 8 channels the length of the SI_VALUE
vector is 144 bit.
In the vector the individual values are arranged one after the other.
The SI-Value-vector needs to be sliced, to access the individual values of the different ADC-channels. To get the first SI-Value the first 18 bit of the vector have to be slice, for the second value the next 18 etc.
In the Vivado block-design the SI_VALUE
can be sliced with Slice-IP-Cores to get access to the SI-Values of the ADC-channels.
In the next figure the slice-blocks can be seen. Each of them slices one value from the vector.
Downloads#
Sample waveforms captured with Vivado ILA
Designed by#
Thilo Wendt, Institut ELSYS @ Technische Hochschule Nürnberg, 04/2021