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, and SCLK frequency of the SPI interface are configurable by software

    • The 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:

  1. read the current value from the configuration register

  2. Reset all bits that encode what the Configuration Value Register holds (bit 5 to 7)

  3. Set the bit pattern to 001 to indicate that the value is the conversion factor

  4. Write the spi master and channel number to the AXI registers of the ADC channel that has to be changed

  5. Write the conversion factor to Configuration Value Register

  6. Write the configuration to the configuration register

  7. 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:

Listing 169 Initialization of 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:

Listing 170 Change trigger mode#
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.

Listing 171 Set conversion factor and offset#
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.

Public Members

float conversion_factor#

Factor with which the sum of the offset and the raw value is multiplied

int offset#

Offset that is added to the raw value before the multiplication

struct uz_adcLtc2311_spi_master_config_t#

Configuration struct that holds parameters that are adjustable on a per SPI master basis.

Public Members

uint32_t samples#

Number of samples that shall be taken on a single trigger

uint32_t sample_time#

Minimal number of system clock cycles for sample and hold

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

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)

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.

../../_images/architecture.svg

Fig. 313 Architecture of the ADC IP core.#

Configuration Registers#

Control Register#

Address offset: 0x0

Software control register of the IP core.

Table 88 ADC_CR#

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 ADC_VALUE register is the offset

Signed two’s complement

0

0

1

Read/Write

The value in the ADC_VALUE register is the conversion factor

Signed two’s complement

0

1

0

Read/Write

The value in the ADC_VALUE register is the number of samples per trigger

Unsigned integer

0

1

1

Read/Write

The value in the ADC_VALUE register is the number of sample time

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.

Table 89 ADC_SPI_CR#

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. SPI_SS_N_STATUS and SPI_SCLK_STATUS are only valid when SPI_CONTROL is true and the selected channels are not busy.

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.

Table 90 ADC_SPI_CFGR#

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:

  1. 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.

  2. 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.

Table 91 ADC_MASTER_CHANNEL#

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.

Table 92 ADC_CHANNEL#

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.

Table 93 ADC_MASTER_FINISH#

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.

Table 94 ADC_MASTER_SI_FINISH#

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.

Table 95 ADC_MASTER_BUSY#

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.

Table 96 ADC_VALUE#

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.

Table 97 ADC_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#

Table 98 Generics#

Parameter Name

Allowable Values

Default Values

VHDL Type

Description

DATA_WIDTH

1 - 24

16

natural

Data output width of the connected SPI slave (i.e. ADC)

CHANNELS_PER_MASTER

1 - 32

8

natural

Number of SPI slaves that are controlled synchronously by one SPI master

SPI_MASTER

1 - 32

1

natural

Number of independent SPI masters

OFFSET_WIDTH

1 - DATA_WIDTH

16

natural

Bit width of the offset value which is added to the raw value

CONVERSION_WIDTH

1 - 18

18

natural

Bit width of the conversion value the sum of the offset and the raw value is multiplied with

RES_LSB

0 - DATA_WIDTH + CONVERSION_WIDTH - 1

6

natural

LSB of the result vector of the DSP48 block which is connected to the IP core SI_VALUE output

RES_MSB

0 - DATA_WIDTH + CONVERSION_WIDTH - 1

23

natural

MSB of the result vector of the DSP48 block which is connected to the IP core SI_VALUE output

DIFFERENTIAL

true false

true

boolean

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.

../../_images/adc_ip_core_concept.svg

Fig. 314 Example interfaces for IP-Core configuration with 8 Channels and 3 SPI-Master. Note that is not the way the IP-Core is used in the default case!#

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#

Table 99 I/O Interface#

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 DIFFERENTIAL = true

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 DIFFERENTIAL = true

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 DIFFERENTIAL = false

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 DIFFERENTIAL = true

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.

../../_images/ltc_v3_vivado.png

Fig. 315 ADC LTC2311 IP-Core.#

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:

\[\begin{split}offset = \frac{-2^{16}}{4} = -16384\\ conversion factor = \frac{100}{2^{16}} = 0.001526\end{split}\]

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.

Listing 172 Initialization of ADC-Core driver instances#
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.

../../_images/adc_ip_core_config_vivado.png

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.

../../_images/slicing_graphic.png

Fig. 316 Slicing of the SI-Value output vector#

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.

../../_images/Si_Slicing.png

Fig. 317 Slicing of the SI_VALUE output vector in vivado#

Downloads#

Detailed project description

Sample waveforms captured with Vivado ILA

Designed by#

Thilo Wendt, Institut ELSYS @ Technische Hochschule Nürnberg, 04/2021