Wiki

This version is outdated by a newer approved version.DiffThis version (29 Aug 2014 13:05) is a draft.
Approvals: 0/1
The Previously approved version (24 Jul 2014 15:12) is available.Diff

This is an old revision of the document!


AD9361 No-OS Software

Introduction

This document describes the No-OS software used to control the AD9361 part.

AD9361 No-OS API

An API is available to be used on systems without OS to interact with the AD9361 and provides all the necessary functions to control it.

Below is presented a short description of all the functions provided in the API:

Device Global Settings
struct ad9361_rf_phy *ad9361_init
(AD9361_InitParam *init_param)
Initializes the FMCOMMS2 board. Receives as parameter a structure that contains the AD9361 initial parameters. Returns a structure that contains the AD9361 current state in case of success, negative error code otherwise.
int32_t ad9361_set_en_state_machine_mode
(struct ad9361_rf_phy *phy, uint32_t mode)
Sets the Enable State Machine (ENSM) mode. Receives as parameters a structure that contains the AD9361 current state and the ENSM mode (SLEEP, ALERT, FDD, PINCTRL). Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_get_en_state_machine_mode
(struct ad9361_rf_phy *phy, uint32_t *mode)
Gets the Enable State Machine (ENSM) mode. Receives as parameters a structure that contains the AD9361 current state and a variable to store the selected ENSM mode. Returns 0 in case of success, negative error code otherwise.
Receive Chain Settings
int32_t ad9361_set_rx_rf_gain
(struct ad9361_rf_phy *phy, uint8_t ch, int32_t gain_db)
Sets the receive RF gain for the selected channel. Receives as parameters a structure that contains the AD9361 current state, the desired channel number (1, 2) and the RF gain. Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_get_rx_rf_gain
(struct ad9361_rf_phy *phy, uint8_t ch, int32_t *gain_db)
Gets current receive RF gain for the selected channel. Receives as parameters a structure that contains the AD9361 current state, the desired channel (1, 2) and a variable to store the RF gain. Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_set_rx_rf_bandwidth
(struct ad9361_rf_phy *phy, uint32_t bandwidth_hz)
Sets the RF bandwidth. Receives as parameters a structure that contains the AD9361 current state and the desired bandwidth in Hz. Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_get_rx_rf_bandwidth
(struct ad9361_rf_phy *phy, uint32_t *bandwidth_hz)
Gets current RF bandwidth. Receives as parameters a structure that contains the AD9361 current state and a variable to store the bandwidth value in Hz. Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_set_rx_sampling_freq
(struct ad9361_rf_phy *phy, uint32_t sampling_freq_hz)
Sets the sampling frequency. Receives as parameters a structure that contains the AD9361 current state and the desired frequency in Hz. Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_get_rx_sampling_freq
(struct ad9361_rf_phy *phy, uint32_t *sampling_freq_hz)
Gets current sampling frequency. Receives as parameters a structure that contains the AD9361 current state and a variable to store the frequency value in Hz. Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_set_rx_lo_freq
(struct ad9361_rf_phy *phy, uint64_t lo_freq_hz)
Sets the LO frequency. Receives as parameters a structure that contains the AD9361 current state and the desired frequency in Hz. Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_get_rx_lo_freq
(struct ad9361_rf_phy *phy, uint64_t *lo_freq_hz)
Gets current LO frequency. Receives as parameters a structure that contains the AD9361 current state and a variable to store the frequency value in Hz. Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_get_rx_rssi
(struct ad9361_rf_phy *phy, uint8_t ch, struct rf_rssi *rssi)
Gets the RSSI for the selected channel. Receives as parameters a structure that contains the AD9361 current state, the desired channel (1, 2) and a variable to store the RSSI. Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_set_rx_gain_control_mode
(struct ad9361_rf_phy *phy, uint8_t ch, uint8_t gc_mode)
Sets the gain control mode for the selected channel. Receives as parameters a structure that contains the AD9361 current state, the desired channel (1, 2) and the gain control mode (GAIN_MGC, GAIN_FASTATTACK_AGC, GAIN_SLOWATTACK_AGC, GAIN_HYBRID_AGC). Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_get_rx_gain_control_mode
(struct ad9361_rf_phy *phy, uint8_t ch, uint8_t *gc_mode)
Gets the gain control mode for the selected channel. Receives as parameters a structure that contains the AD9361 current state, the desired channel (1, 2) and a variable to store the gain control mode. Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_set_rx_fir_config
(struct ad9361_rf_phy *phy, AD9361_RXFIRConfig fir_cfg)
Sets the FIR filter configuration. Receives as parameters a structure that contains the AD9361 current state and the FIR filter configuration. Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_set_rx_fir_en_dis
(struct ad9361_rf_phy *phy, uint8_t en_dis)
Enables/disables the FIR filter. Receives as parameters a structure that contains the AD9361 current state and the option (ENABLE, DISABLE). Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_get_rx_fir_en_dis
(struct ad9361_rf_phy *phy, uint8_t *en_dis)
Gets the status of the FIR filter. Receives as parameters a structure that contains the AD9361 current state and the enable/disable status buffer. Returns 0 in case of success, negative error code otherwise.
Transmit Chain Settings
int32_t ad9361_set_tx_attenuation
(struct ad9361_rf_phy *phy, uint8_t ch, uint32_t attenuation_mdb)
Sets the transmit attenuation for the selected channel. Receives as parameters a structure that contains the AD9361 current state, the desired channel number (1, 2) and the attenuation in dB. Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_get_tx_attenuation
(struct ad9361_rf_phy *phy, uint8_t ch, uint32_t *attenuation_mdb)
Gets current transmit attenuation for the selected channel. Receives as parameters a structure that contains the AD9361 current state, the desired channel (1, 2) and a variable to store the attenuation value in dB. Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_set_tx_rf_bandwidth
(struct ad9361_rf_phy *phy, uint32_t  bandwidth_hz)
Sets the RF bandwidth. Receives as parameters a structure that contains the AD9361 current state and the desired bandwidth in Hz. Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_get_tx_rf_bandwidth
(struct ad9361_rf_phy *phy, uint32_t *bandwidth_hz)
Gets current RF bandwidth. Receives as parameters a structure that contains the AD9361 current state and a variable to store the bandwidth value in Hz. Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_set_tx_sampling_freq
(struct ad9361_rf_phy *phy, uint32_t sampling_freq_hz)
Sets the sampling frequency. Receives as parameters a structure that contains the AD9361 current state and the desired frequency in Hz. Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_get_tx_sampling_freq
(struct ad9361_rf_phy *phy, uint32_t *sampling_freq_hz)
Gets current sampling frequency. Receives as parameters a structure that contains the AD9361 current state and a variable to store the frequency value in Hz. Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_set_tx_lo_freq
(struct ad9361_rf_phy *phy, uint64_t lo_freq_hz)
Sets the LO frequency. Receives as parameters a structure that contains the AD9361 current state and the desired frequency in Hz. Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_get_tx_lo_freq
(struct ad9361_rf_phy *phy, uint64_t *lo_freq_hz)
Gets current LO frequency. Receives as parameters a structure that contains the AD9361 current state and a variable to store the frequency value in Hz. Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_set_tx_fir_config
(struct ad9361_rf_phy *phy, AD9361_TXFIRConfig fir_cfg)
Sets the FIR filter configuration. Receives as parameters a structure that contains the AD9361 current state and the FIR filter configuration. Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_set_tx_fir_en_dis
(struct ad9361_rf_phy *phy, uint8_t en_dis)
Enables/disables the FIR filter. Receives as parameters a structure that contains the AD9361 current state and the option (ENABLE, DISABLE). Returns 0 in case of success, negative error code otherwise.
int32_t ad9361_get_tx_fir_en_dis
(struct ad9361_rf_phy *phy, uint8_t *en_dis)
Gets the status of the FIR filter. Receives as parameters a structure that contains the AD9361 current state and the enable/disable status buffer. Returns 0 in case of success, negative error code otherwise.

Notes: 1. Below is defined the AD9361_ParamInit structure used by the ad9361_init() function:

For more details on each of the struct members please see here: AD9361 Device Driver Customization

	typedef struct
	{
		/* Mode Setup */
		uint8_t		two_rx_two_tx_mode_enable;
		uint8_t		frequency_division_duplex_mode_enable;
		uint8_t		split_gain_table_mode_enable;
		uint8_t		tdd_use_fdd_vco_tables_enable;
		uint8_t		tdd_use_dual_synth_mode_enable;
		uint32_t	dcxo_coarse_and_fine_tune[2];
		uint8_t		ensm_enable_pin_pulse_mode_enable;
		uint8_t		ensm_enable_txnrx_control_enable;
		uint32_t	rx_rf_port_input_select;
		uint32_t	tx_rf_port_output_select;
		uint32_t	rx_path_clock_frequencies[6];
		uint32_t	tx_path_clock_frequencies[6];
		uint64_t	rx_synthesizer_frequency_hz;
		uint64_t	tx_synthesizer_frequency_hz;
		uint32_t	rf_rx_bandwidth_hz;
		uint32_t	rf_tx_bandwidth_hz;
		uint8_t		update_tx_gain_in_alert_enable;
		int32_t		tx_attenuation_mdB;
		/* Gain Control */
		uint8_t		gc_rx1_mode;
		uint8_t		gc_rx2_mode;
		uint8_t		gc_adc_ovr_sample_size;
		uint8_t		gc_adc_small_overload_thresh;
		uint8_t		gc_adc_large_overload_thresh;
		uint16_t	gc_lmt_overload_high_thresh;
		uint16_t	gc_lmt_overload_low_thresh;
		uint8_t		gc_analog_settling_time;
		uint16_t	gc_dec_pow_measurement_duration;
		uint8_t		gc_low_power_thresh;
		uint8_t		gc_dig_gain_enable;
		uint8_t		gc_max_dig_gain;
		/* Manual Gain Control Setup */
		uint8_t		mgc_rx1_ctrl_inp_enable;
		uint8_t		mgc_rx2_ctrl_inp_enable;
		uint8_t		mgc_inc_gain_step;
		uint8_t		mgc_dec_gain_step;
		uint8_t		mgc_split_table_ctrl_inp_gain_mode;
		/* Automatic Gain Control Setup */
		uint8_t		agc_attack_delay_us;
		uint8_t		agc_settling_delay;
		uint8_t		agc_outer_thresh_high;
		uint8_t		agc_outer_thresh_high_dec_steps;
		uint8_t		agc_inner_thresh_high;
		uint8_t		agc_inner_thresh_high_dec_steps;
		uint8_t		agc_inner_thresh_low;
		uint8_t		agc_inner_thresh_low_inc_steps;
		uint8_t		agc_outer_thresh_low;
		uint8_t		agc_outer_thresh_low_inc_steps;
		uint8_t		agc_adc_small_overload_exceed_counter;
		uint8_t		agc_adc_large_overload_exceed_counter;
		uint8_t		agc_adc_large_overload_inc_steps;
		uint8_t		agc_adc_lmt_small_overload_prevent_gain_inc_enable;
		uint8_t		agc_lmt_overload_large_exceed_counter;
		uint8_t		agc_lmt_overload_small_exceed_counter;
		uint8_t		agc_lmt_overload_large_inc_steps;
		uint8_t		agc_dig_saturation_exceed_counter;
		uint8_t		agc_dig_gain_step_size;
		uint8_t		agc_sync_for_gain_counter_enable;
		uint32_t	agc_gain_update_counter;
		uint8_t		agc_immed_gain_change_if_large_adc_overload_enable;
		uint8_t		agc_immed_gain_change_if_large_lmt_overload_enable;
		/* RSSI */
		uint8_t		rssi_restart_mode;
		uint8_t		rssi_unit_is_rx_samples_enable;
		uint32_t	rssi_delay;
		uint32_t	rssi_wait;
		uint32_t	rssi_duration;
		/* Control Outputs */
		uint8_t		ctrl_outs_index;
		uint8_t		ctrl_outs_enable_mask;
		/* AuxADC Temp Sense Control */
		uint16_t	temp_sense_measurement_interval_ms;
		int8_t		temp_sense_offset_signed;
		uint8_t		temp_sense_periodic_measurement_enable;
	}AD9361_InitParam;

2. Below is defined the rf_rssi structure used by the ad9361_get_rx_rssi() function:

	struct rf_rssi {
		u32 ant;	// Antenna number for which RSSI is reported
		u32 symbol;	// Runtime RSSI
		u32 preamble;	// Initial RSSI
		s32 multiplier;	// Multiplier to convert reported RSSI
		u8 duration;	// Duration to be considered for measuring
	};

3. Below is defined the AD9361_RXFIRConfig structure used by the ad9361_set_rx_fir_config() function:

	typedef struct
	{
		uint32_t rx;		// 1, 2, 3(both)
		int32_t rx_gain;	// -12, -6, 0, 6
		uint32_t rx_dec;	// 1, 2, 4
		int16_t rx_coef[64];
	}AD9361_RXFIRConfig;

4. Below is defined the AD9361_TXFIRConfig structure used by the ad9361_set_tx_fir_config() function:

	typedef struct
	{
		uint32_t tx;		// 1, 2, 3(both)
		int32_t tx_gain;	// -6, 0
		uint32_t tx_int;	// 1, 2, 4
		int16_t tx_coef[64];
	}AD9361_TXFIRConfig;

AD9361 Doxygen Documentation

Generic Platform

The AD9361 No-OS Software together with the Generic Platform Driver can be used as a base for any microprocessor platform.

The Platform Driver implements the communication with the device and hides the actual details of the communication protocol to the AD9361 driver. When the desired type of processor is chosen, the specific communication functions have to be implemented.

Code Size Information

The following information was obtained compiling the AD9361 project (with the Generic Platform Driver integrated) using the xilinx-2012.03-79-arm-xilinx-linux-gnueabi and the Optimize for size (-Os) option enabled.

 text	   data	    bss	    dec	    hex	filename
39514	   3256	      8	  42778	   a71a	ad9361.elf

Note: The source code from the GitHub SHA b7f6419ed5ab2ec67431312b814e7ac3fe8afb13 was used for calculating the code size information (https://github.com/analogdevicesinc/no-OS/tree/b7f6419ed5ab2ec67431312b814e7ac3fe8afb13/ad9361/sw).

Xilinx Platform

This guide provides some quick instructions on how to setup the AD-FMCOMMS2-EBZ on either:


The ML605 XPS project remain on this website only for legacy purposes. The support for XPS projects has been discontinued.

Software Setup for Vivado

Example for a ZC702 board:

  • After building the project in Vivado for the used FPGA board, a SDK_Export folder will be created in ../fmcomms2_board.sdk/SDK
  • Open the Xilinx SDK for Vivado. When the SDK starts it asks to provide a folder where to store the workspace. Any folder can be provided.
  • Go to File→New→Application project

 New Application Project

  • Use a new hardware platform, so choose Create new in Hardware Platform

 New Platform

  • In Target Hardware Specification browse the location of SDK_Export\hw\system.xml and click Finish

 New Hardware Project

  • Then give a name to the project and click Next

 Project Name

  • In the next window choose Empty Application and click Finish

 Available Templates

  • Now the project without source code looks like this

 Empty Project

  • Then the source code must be added from Github to src folder(the AD9361 No-OS Software and the Xilinx Platform Driver are mandatory. The Console Commands Driver is optional).

 SDK Project

  • The Project Explorer window now shows the projects that exist in the workspace and the files for each project. The SDK should automatically build the projects and the Console window will display the the result of the build. If the build is not done automatically select the Project→Build Automatically menu option.

 Project Explorer

  • To be able to use the Xilinx platform, you should uncomment #define XILINX_PLATFORM from Macros and Constants Definitions section in main. And if you use the console commands, then #define CONSOLE_COMMANDS should be also uncommented in main.

 Project Explorer

  • At this point the software project setup is complete, the FPGA can be programmed and the software can be downloaded into the system. You can program the FPGA by going to Xilinx Tools.

 Program FPGA

  • Then choose this bitstream and press Program

 Program FPGA with bitstream

  • This window will appear next.

 Program FPGA progress

  • Afterwards a Run Configuration must be created and then press Run

 Run Configuration

  • The output of the example program can be viewed in the SDK console by enabling the Connect STDIO Console option and setting the baud rate of the UART port to 115200.

 STDIO configuration

As an alternative an UART terminal can be used to capture the output of the example program. The number of used UART port depends on the computer's configuration. The following settings must be used in the UART terminal:

  • Baud Rate: 115200bps
  • Data: 8 bit
  • Parity: None
  • Stop bits: 1 bit
  • Flow Control: none

After running the example program the system is configured to generate a sinewave on each of the 2 channels and send it over the air using a 2.4GHz carrier. The signal is received back, brought to baseband again and digitized by the 2 ADCs(one for each channel) on the FMCOMMS2. The I and Q samples generated by the ADCs can be viewed using the Vivado Hardware Manager. These are the steps than need to be followed to view the sine waves:

  • First make sure that the board is programmed and the program is currently running
  • Then open Vivado and go to Flow→Open Hardware Manager

 Open Hardware Manager

  • In the new window select Open a new hardware target

 Open New Hardware Target

  • Then click Next 4 times and then Finish

 Open New Hardware Target Server name Select Target  Set Properties Open New Hardware Target

  • This is how the Vivado Hardware Manager looks like. Now go to Probes file.

 Device Properties

  • And browse for the folder where the project was complied ../fmcomms2_board.runs/impl_1/debug_nets.ltx

 Specify Probes File

  • Then do a right click on the active target and choose Refresh Device

 Refresh Device

  • Afterwards do another right click on the active target and choose Run Trigger

 Run Trigger

  • This is how the 48 digital signals look like. Now we have to compose the sinewaves.

 ILA Signals

  • First select the first 12 signals, do a right click and choose New Virtual Bus

 New Virtual Bus

  • Then give a name to that virtual bus

 Specify Virtual Bus Name

  • In order to see a sinewave you have to right click on the name of the virtual bus, choose Analog for Waveform Style option.

 Analog Waveform Style

  • Now you can see a sinewave, but the radix is not the good one. In order to have the right radix, you must choose Signed Decimal for Radix.

 Signed Decimal Radix

  • Now the signal looks like a sinewave

 One Virtual Bus Sinewave

  • And after you did the same steps for the other 3×12 remaining signals, you should have 4 sinewaves composed of 48 signals. ON FMCOMMS2 there are 2 channels, each channel with 2 signals (I and Q).

 4 Virtual Buses Sinewaves

Console Commands Driver

The Console Commands Driver is optional for the project. It was created in addition to the AD9361 driver to control the part using some console commands.

AD9361 Reference Project Serial Commands

The following commands were implemented for controlling the AD9361:

Command Description
help? Displays all available commands.
register? Gets the specified register value.
tx_lo_freq? Gets current TX LO frequency [MHz].
tx_lo_freq= Sets the TX LO frequency [MHz].
tx_samp_freq? Gets current TX sampling frequency [Hz].
tx_samp_freq= Sets the TX sampling frequency [Hz].
tx_rf_bandwidth? Gets current TX RF bandwidth [Hz].
tx_rf_bandwidth= Sets the TX RF bandwidth [Hz].
tx1_attenuation? Gets current TX1 attenuation [mdB].
tx1_attenuation= Sets the TX1 attenuation [mdB].
tx2_attenuation? Gets current TX2 attenuation [mdB].
tx2_attenuation= Sets the TX2 attenuation [mdB].
tx_fir_en? Gets current TX FIR state.
tx_fir_en= Sets the TX FIR state.
rx_lo_freq? Gets current RX LO frequency [MHz].
rx_lo_freq= Sets the RX LO frequency [MHz].
rx_samp_freq? Gets current RX sampling frequency [Hz].
rx_samp_freq= Sets the RX sampling frequency [Hz].
rx_rf_bandwidth? Gets current RX RF bandwidth [Hz].
rx_rf_bandwidth= Sets the RX RF bandwidth [Hz].
rx1_gc_mode? Gets current RX1 GC mode.
rx1_gc_mode= Sets the RX1 GC mode.
rx2_gc_mode? Gets current RX2 GC mode.
rx2_gc_mode= Sets the RX2 GC mode.
rx1_rf_gain? Gets current RX1 RF gain.
rx1_rf_gain= Sets the RX1 RF gain.
rx2_rf_gain? Gets current RX2 RF gain.
rx2_rf_gain= Sets the RX2 RF gain.
rx_fir_en? Gets current RX FIR state.
rx_fir_en= Sets the RX FIR state.
dds_tx1_f1_freq? Gets current DDS TX1 F1 frequency [MHz].
dds_tx1_f1_freq= Sets the DDS TX1 F1 frequency [MHz].
dds_tx1_f2_freq? Gets current DDS TX1 F2 frequency [MHz].
dds_tx1_f2_freq= Sets the DDS TX1 F2 frequency [MHz].
dds_tx1_f1_phase? Gets current DDS TX1 F1 phase [degrees].
dds_tx1_f1_phase= Sets the DDS TX1 F1 phase [degrees].
dds_tx1_f2_phase? Gets current DDS TX1 F2 phase [degrees].
dds_tx1_f2_phase= Sets the DDS TX1 F2 phase [degrees].
dds_tx1_f1_scale? Gets current DDS TX1 F1 scale.
dds_tx1_f1_scale= Sets the DDS TX1 F1 scale.
dds_tx1_f2_scale? Gets current DDS TX1 F2 scale.
dds_tx1_f2_scale= Sets the DDS TX1 F2 scale.
dds_tx2_f1_freq? Gets current DDS TX2 F1 frequency [MHz].
dds_tx2_f1_freq= Sets the DDS TX2 F1 frequency [MHz].
dds_tx2_f2_freq? Gets current DDS TX2 F2 frequency [MHz].
dds_tx2_f2_freq= Sets the DDS TX2 F2 frequency [MHz].
dds_tx2_f1_phase? Gets current DDS TX2 F1 phase [degrees].
dds_tx2_f1_phase= Sets the DDS TX2 F1 phase [degrees].
dds_tx2_f2_phase? Gets current DDS TX2 F2 phase [degrees].
dds_tx2_f2_phase= Sets the DDS TX2 F2 phase [degrees].
dds_tx2_f1_scale? Gets current DDS TX2 F1 scale.
dds_tx2_f1_scale= Sets the DDS TX2 F1 scale.
dds_tx2_f2_scale? Gets current DDS TX2 F2 scale.
dds_tx2_f2_scale= Sets the DDS TX2 F2 scale.
Executing a Command Example

Commands can be executed using a serial terminal connected to the UART peripheral of the development board.

The following image shows an example of how the TX LO frequency can be set to 2.4 GHz using the corresponding command.

 UART

Downloads

The source code of the no-OS software, the scripts and the Chipscope projects can be downloaded from the Analog Devices github.

no-OS Software

HDL Reference Designs

More Information

resources/eval/user-guides/ad-fmcomms2-ebz/software/baremetal.1409310309.txt.gz · Last modified: 29 Aug 2014 13:05 by Lucian Sin