Post Go back to editing

How to check AD9364 is initialized or not

Thread Summary

The user successfully initialized the AD9364 and read register values indicating correct Device ID, BBPLL lock, and ENSM in alert state. The final answer confirms these values and suggests checking RF PLL lock status, calibration status, and RF gain table loading. For FDD operation, use ad9361_set_en_state() to transition ENSM from alert to Rx or Tx state.
AI Generated Content
Category: Software
Product Number: AD9364

Hi,

I have successfully integrated my SPI functions into the no-OS library, and the initialization of the AD9364 completes without errors. However, I am not sure how to verify whether the device has been configured correctly after initialization.

From various sources, I found that the following checks are recommended:

  • Read the Device ID

  • Check the BBPLL lock bit

  • Verify the ENSM (Enable State Machine) state

  • Check the calibration status register bits

Below are the register values I have read:

  • Device ID → Register 0x37 = 0x0A

  • Register 0x17 = 0x1A

  • Register 0x5E = 0x80

Can someone please confirm whether these values indicate that the initialization and configuration are successful? Also, are there any additional registers or status bits I should verify to ensure the device is properly configured?

struct ad9361_rf_phy *phy;

AD9361_InitParam init = {
/* Device selection */
.dev_sel = ID_AD9364,

/* Reference Clock */
.reference_clk_rate = 40000000UL,

/* Base Configuration */
.two_rx_two_tx_mode_enable = 0, // AD9364 = 1R1T only
.one_rx_one_tx_mode_use_rx_num = 1, // Use RX1
.one_rx_one_tx_mode_use_tx_num = 1, // Use TX1

.frequency_division_duplex_mode_enable = 1, // FDD mode (recommended)
.frequency_division_duplex_independent_mode_enable = 0,

.tdd_use_dual_synth_mode_enable = 0, // Not needed for FDD
.tdd_skip_vco_cal_enable = 0, // Keep calibration enabled

.tx_fastlock_delay_ns = 0, // Not using fastlock
.rx_fastlock_delay_ns = 0,

.rx_fastlock_pincontrol_enable = 0,
.tx_fastlock_pincontrol_enable = 0,

.external_rx_lo_enable = 0, // Internal LO
.external_tx_lo_enable = 0,

.dc_offset_tracking_update_event_mask = 5, // Recommended default
.dc_offset_attenuation_high_range = 6,
.dc_offset_attenuation_low_range = 5,
.dc_offset_count_high_range = 0x28,
.dc_offset_count_low_range = 0x32,

.split_gain_table_mode_enable = 0, // Normal gain table

.trx_synthesizer_target_fref_overwrite_hz = MAX_SYNTH_FREF, // Use default ref

.qec_tracking_slow_mode_enable = 0, // Normal QEC tracking

/* ENSM Control */
.ensm_enable_pin_pulse_mode_enable = 0, // Use SPI control
.ensm_enable_txnrx_control_enable = 0, // SPI controls ENSM


/* LO Control */
.rx_synthesizer_frequency_hz = 2400000000ULL,
.tx_synthesizer_frequency_hz = 2400000000ULL,
.tx_lo_powerdown_managed_enable = 0,

/* Rate & BW Control */
.rx_path_clock_frequencies[0] = 983040000UL, // BBPLL
.rx_path_clock_frequencies[1] = 245760000UL,
.rx_path_clock_frequencies[2] = 122880000UL,
.rx_path_clock_frequencies[3] = 61440000UL,
.rx_path_clock_frequencies[4] = 30720000UL,
.rx_path_clock_frequencies[5] = 30720000UL, // Sample rate

.tx_path_clock_frequencies[0] = 983040000UL,
.tx_path_clock_frequencies[1] = 245760000UL,
.tx_path_clock_frequencies[2] = 122880000UL,
.tx_path_clock_frequencies[3] = 61440000UL,
.tx_path_clock_frequencies[4] = 30720000UL,
.tx_path_clock_frequencies[5] = 30720000UL,

.rf_rx_bandwidth_hz = 20000000UL,
.rf_tx_bandwidth_hz = 20000000UL,


.rx_rf_port_input_select = 0, // RX1A
.tx_rf_port_input_select = 0, // TX1A

.tx_attenuation_mdB = 10000, // 10 dB
.update_tx_gain_in_alert_enable = 0,

.xo_disable_use_ext_refclk_enable = 0, // Use internal crystal
.dcxo_coarse_and_fine_tune[0] = 8,
.dcxo_coarse_and_fine_tune[1] = 5920,
.clk_output_mode_select = 0, // Disable clock out

/* Gain Control */
.gc_rx1_mode = RF_GAIN_MGC,

.gc_adc_large_overload_thresh = 58,
.gc_adc_ovr_sample_size = 4,
.gc_adc_small_overload_thresh = 47,
.gc_dec_pow_measurement_duration = 8192,

.gc_dig_gain_enable = 0,
.gc_lmt_overload_high_thresh = 800,
.gc_lmt_overload_low_thresh = 704,
.gc_low_power_thresh = 24,
.gc_max_dig_gain = 15,
.gc_use_rx_fir_out_for_dec_pwr_meas_enable = 0,

.mgc_dec_gain_step = 2,
.mgc_inc_gain_step = 2,
.mgc_rx1_ctrl_inp_enable = 0,
.mgc_rx2_ctrl_inp_enable = 0,
.mgc_split_table_ctrl_inp_gain_mode = 0,

.agc_adc_large_overload_exceed_counter = 10,
.agc_adc_large_overload_inc_steps = 2,
.agc_adc_lmt_small_overload_prevent_gain_inc_enable = 0,
.agc_adc_small_overload_exceed_counter = 10,
.agc_dig_gain_step_size = 4,
.agc_dig_saturation_exceed_counter = 3,
.agc_gain_update_interval_us = 1000,

.agc_immed_gain_change_if_large_adc_overload_enable = 0,
.agc_immed_gain_change_if_large_lmt_overload_enable = 0,

.agc_inner_thresh_high = 10,
.agc_inner_thresh_high_dec_steps = 1,
.agc_inner_thresh_low = 12,
.agc_inner_thresh_low_inc_steps = 1,

.agc_lmt_overload_large_exceed_counter = 10,
.agc_lmt_overload_large_inc_steps = 2,
.agc_lmt_overload_small_exceed_counter = 10,

.agc_outer_thresh_high = 5,
.agc_outer_thresh_high_dec_steps = 2,
.agc_outer_thresh_low = 18,
.agc_outer_thresh_low_inc_steps = 2,

.agc_attack_delay_extra_margin_us = 1,
.agc_sync_for_gain_counter_enable = 0,

/* Fast AGC */
.fagc_dec_pow_measuremnt_duration = 64,
.fagc_state_wait_time_ns = 260,

/* Fast AGC - Low Power */
.fagc_allow_agc_gain_increase = 0,
.fagc_lp_thresh_increment_time = 5,
.fagc_lp_thresh_increment_steps = 1,

/* Fast AGC - Lock Level */
.fagc_lock_level_lmt_gain_increase_en = 1,
.fagc_lock_level_gain_increase_upper_limit = 5,

/* Final Settling */
.fagc_lpf_final_settling_steps = 1,
.fagc_lmt_final_settling_steps = 1,
.fagc_final_overrange_count = 3,

/* Final Power Test */
.fagc_gain_increase_after_gain_lock_en = 0,

/* Unlocking */
.fagc_gain_index_type_after_exit_rx_mode = 0,
.fagc_use_last_lock_level_for_set_gain_en = 0,
.fagc_rst_gla_stronger_sig_thresh_exceeded_en = 0,
.fagc_optimized_gain_offset = 5,
.fagc_rst_gla_stronger_sig_thresh_above_ll = 10,
.fagc_rst_gla_engergy_lost_sig_thresh_exceeded_en = 0,
.fagc_rst_gla_engergy_lost_goto_optim_gain_en = 0,
.fagc_rst_gla_engergy_lost_sig_thresh_below_ll = 10,
.fagc_energy_lost_stronger_sig_gain_lock_exit_cnt = 3,
.fagc_rst_gla_large_adc_overload_en = 0,
.fagc_rst_gla_large_lmt_overload_en = 0,
.fagc_rst_gla_en_agc_pulled_high_en = 0,
.fagc_rst_gla_if_en_agc_pulled_high_mode = 0,
.fagc_power_measurement_duration_in_state5 = 8192,
.fagc_large_overload_inc_steps = 2,

.rssi_delay = 1,
.rssi_duration = 1000,
.rssi_restart_mode = 3,
.rssi_unit_is_rx_samples_enable = 0,
.rssi_wait = 1,

.aux_adc_decimation = 256,
.aux_adc_rate = 40000000UL,

.aux_dac_manual_mode_enable = 0,

.aux_dac1_default_value_mV = 0,
.aux_dac1_active_in_rx_enable = 0,
.aux_dac1_active_in_tx_enable = 0,
.aux_dac1_active_in_alert_enable = 0,
.aux_dac1_rx_delay_us = 0,
.aux_dac1_tx_delay_us = 0,

.aux_dac2_default_value_mV = 0,
.aux_dac2_active_in_rx_enable = 0,
.aux_dac2_active_in_tx_enable = 0,
.aux_dac2_active_in_alert_enable = 0,
.aux_dac2_rx_delay_us = 0,
.aux_dac2_tx_delay_us = 0,

.temp_sense_decimation = 256,
.temp_sense_measurement_interval_ms = 1000,
.temp_sense_offset_signed = 0,
.temp_sense_periodic_measurement_enable = 1,

.ctrl_outs_enable_mask = 0x00,
.ctrl_outs_index = 0,

.elna_settling_delay_ns = 0,
.elna_gain_mdB = 0,
.elna_bypass_loss_mdB = 0,
.elna_rx1_gpo0_control_enable = 0,
.elna_rx2_gpo1_control_enable = 0,
.elna_gaintable_all_index_enable = 0,

.digital_interface_tune_skip_mode = 0,
.digital_interface_tune_fir_disable = 0,

.pp_tx_swap_enable = 0,
.pp_rx_swap_enable = 0,
.tx_channel_swap_enable = 0,
.rx_channel_swap_enable = 0,

.rx_frame_pulse_mode_enable = 0,
.two_t_two_r_timing_enable = 0,
.invert_data_bus_enable = 0,
.invert_data_clk_enable = 0,
.fdd_alt_word_order_enable = 0,
.invert_rx_frame_enable = 0,
.fdd_rx_rate_2tx_enable = 0,
.swap_ports_enable = 0,
.single_data_rate_enable = 0, // DDR mode
.lvds_mode_enable = 1, // LVDS
.half_duplex_mode_enable = 0,
.single_port_mode_enable = 0,
.full_port_enable = 1,
.full_duplex_swap_bits_enable = 0,

.delay_rx_data = 0,
.rx_data_clock_delay = 0,
.rx_data_delay = 0,
.tx_fb_clock_delay = 0,
.tx_data_delay = 0,

.lvds_bias_mV = 150,
.lvds_rx_onchip_termination_enable = 1,

.rx1rx2_phase_inversion_en = 0,
.lvds_invert1_control = 0,
.lvds_invert2_control = 0,

/* GPO Control */
.gpo_manual_mode_enable = 0,
.gpo_manual_mode_enable_mask = 0x0,

.gpo0_inactive_state_high_enable = 0,
.gpo1_inactive_state_high_enable = 0,
.gpo2_inactive_state_high_enable = 0,
.gpo3_inactive_state_high_enable = 0,

.gpo0_slave_rx_enable = 0,
.gpo0_slave_tx_enable = 0,
.gpo1_slave_rx_enable = 0,
.gpo1_slave_tx_enable = 0,
.gpo2_slave_rx_enable = 0,
.gpo2_slave_tx_enable = 0,
.gpo3_slave_rx_enable = 0,
.gpo3_slave_tx_enable = 0,

.gpo0_rx_delay_us = 0,
.gpo0_tx_delay_us = 0,
.gpo1_rx_delay_us = 0,
.gpo1_tx_delay_us = 0,
.gpo2_rx_delay_us = 0,
.gpo2_tx_delay_us = 0,
.gpo3_rx_delay_us = 0,
.gpo3_tx_delay_us = 0,

/* Tx Monitor Control */
.low_high_gain_threshold_mdB = 37000,
.low_gain_dB = 0,
.high_gain_dB = 24,

.tx_mon_track_en = 0,
.one_shot_mode_en = 0,
.tx_mon_delay = 511,
.tx_mon_duration = 8192,

.tx1_mon_front_end_gain = 2,
.tx2_mon_front_end_gain = 2,

.tx1_mon_lo_cm = 0x3F,
.tx2_mon_lo_cm = 0x3F,

.spi_param = spi_init,
.gpio_resetb = gpio_reset,

.ad9361_rfpll_ext_recalc_rate = NULL,
.ad9361_rfpll_ext_round_rate = NULL,
.ad9361_rfpll_ext_set_rate = NULL,

.rx_adc_init = NULL,
.tx_dac_init = NULL,
};

Thanks, 

Regards,

Veerappan P.

  • HI  

    As per the register values provided. It is showing correct Device ID, BBPLL locked, ENSM state is in alert state. 

    These are good to use in the cases of sanity check and device status check for further actions in your application. Additionally, you can check RF PLL lock status, check calibration status(calibration control complete status to move to next steps), RF gain table loading status also.

    After all this check if you are operating in FDD, ENSM transition into Rx: call API to check ad9361_set_en_state() to move the state from alert state to either Tx or Rx based on your need.

    Regards,

    SJ