#!/usr/bin/env python # # Copyright 2010-2011 Ettus Research LLC # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # ######################################################################## # Template for raw text data describing registers # name addr[bit range inclusive] default optional enums ######################################################################## REGS_TMPL="""\ sdo_active 0x000[7] 0 sdio, sdo_sdio lsb_first_addr_incr 0x000[6] 0 msb, lsb soft_reset 0x000[5] 0 mirror 0x000[3:0] 0 readback_active_registers 0x004[0] 0 buffer, active pfd_polarity 0x010[7] 0 pos, neg cp_current 0x010[6:4] 7 0_6ma, 1_2ma, 1_8ma, 2_4ma, 3_0ma, 3_6ma, 4_2ma, 4_8ma cp_mode 0x010[3:2] 3 high_imp, force_source, force_sink, normal pll_power_down 0x010[1:0] 1 normal=0, async=1, sync=3 r_counter_lsb 0x011[7:0] 1 r_counter_msb 0x012[5:0] 0 ~r_counter r_counter_lsb, r_counter_msb a_counter 0x013[5:0] 0 b_counter_lsb 0x014[7:0] 3 b_counter_msb 0x015[4:0] 0 ~b_counter b_counter_lsb, b_counter_msb set_cp_pin_to_vcp_2 0x016[7] 0 normal, vcp_2 reset_r_counter 0x016[6] 0 reset_a_and_b_counters 0x016[5] 0 reset_all_counters 0x016[4] 0 b_counter_bypass 0x016[3] 0 normal, div1 prescaler_p 0x016[2:0] 6 div1, div2, div2_3, div4_5, div8_9, div16_17, div32_33, div3 status_pin_control 0x017[7:2] 0 antibacklash_pulse_width 0x017[1:0] 0 2_9ns, 1_3ns, 6_0ns enb_cmos_ref_input_dc_off 0x018[7] 0 lock_detect_counter 0x018[6:5] 0 5cyc, 16cyc, 64cyc, 255cyc digital_lock_detect_window 0x018[4] 0 high_range, low_range disable_digital_lock_detect 0x018[3] 0 normal, disabled vco_calibration_divider 0x018[2:1] 3 div2, div4, div8, div16 vco_calibration_now 0x018[0] 0 r_a_b_counters_sync_pin_rst 0x019[7:6] 0 nothing, async, sync r_path_delay 0x019[5:3] 0 n_path_delay 0x019[2:0] 0 enable_status_pin_divider 0x01A[7] 0 ref_freq_monitor_threshold 0x01A[6] 0 1_02mhz, 6khz ld_pin_control 0x01A[5:0] 0 enable_vco_freq_monitor 0x01B[7] 0 enable_ref2_freq_monitor 0x01B[6] 0 enable_ref1_freq_monitor 0x01B[5] 0 refmon_pin_control 0x01B[4:0] 0 disable_switchover_deglitch 0x01C[7] 0 select_ref 0x01C[6] 0 ref1, ref2 use_ref_sel_pin 0x01C[5] 0 register, ref_sel enb_auto_ref_switchover 0x01C[4] 0 manual, auto stay_on_ref2 0x01C[3] 0 return_ref1, stay_ref2 enable_ref2 0x01C[2] 0 enable_ref1 0x01C[1] 0 enable_differential_ref 0x01C[0] 0 enb_stat_eeprom_at_stat_pin 0x01D[7] 1 enable_xtal_osc 0x01D[6] 0 enable_clock_doubler 0x01D[5] 0 disable_pll_status_reg 0x01D[4] 0 enable_ld_pin_comparator 0x01D[3] 0 enable_external_holdover 0x01D[1] 0 enable_holdover 0x01D[0] 0 external_zero_delay_fcds 0x01E[4:3] 0 enable_external_zero_delay 0x01E[2] 0 enable_zero_delay 0x01E[1] 0 ######################################################################## vco_calibration_finished 0x01F[6] 0 holdover_active 0x01F[5] 0 ref2_selected 0x01F[4] 0 vco_freq_gt_thresh 0x01F[3] 0 ref2_freq_gt_thresh 0x01F[2] 0 ref1_freq_gt_thresh 0x01F[1] 0 digital_lock_detect 0x01F[0] 0 ######################################################################## #for $i in range(12) #set $addr = ($i + 0x0F0) out$(i)_format $(addr)[7] 0 lvds, cmos out$(i)_cmos_configuration $(addr)[6:5] 3 off, a_on, b_on, ab_on out$(i)_polarity $(addr)[4:3] 0 lvds_a_non_b_inv=0, lvds_a_inv_b_non=1, cmos_ab_non=0, cmos_ab_inv=1, cmos_a_non_b_inv=2, cmos_a_inv_b_non=3 out$(i)_lvds_diff_voltage $(addr)[2:1] 1 1_75ma, 3_5ma, 5_25ma, 7_0ma out$(i)_lvds_power_down $(addr)[0] 0 #end for ######################################################################## #for $i in reversed(range(8)) csdld_en_out_$i 0x0FC[$i] 0 ignore, async #end for ######################################################################## #for $i in reversed(range(4)) csdld_en_out_$(8 + $i) 0x0FD[$i] 0 ignore, async #end for ######################################################################## #set $default_val = 0x7 #for $i in range(4) #set $addr0 = hex($i*3 + 0x190) #set $addr1 = hex($i*3 + 0x191) #set $addr2 = hex($i*3 + 0x192) divider$(i)_low_cycles $(addr0)[7:4] $default_val divider$(i)_high_cycles $(addr0)[3:0] $default_val divider$(i)_bypass $(addr1)[7] 0 divider$(i)_ignore_sync $(addr1)[6] 0 divider$(i)_force_high $(addr1)[5] 0 divider$(i)_start_high $(addr1)[4] 0 divider$(i)_phase_offset $(addr1)[3:0] 0 channel$(i)_power_down $(addr2)[2] 0 disable_divider$(i)_ddc $(addr2)[0] 0 #set $default_val /= 2 #end for ######################################################################## vco_divider 0x1E0[2:0] 2 div2, div3, div4, div5, div6, static, div1 power_down_clock_input_sel 0x1E1[4] 0 power_down_vco_clock_ifc 0x1E1[3] 0 power_down_vco_and_clock 0x1E1[2] 0 select_vco_or_clock 0x1E1[1] 0 external, vco bypass_vco_divider 0x1E1[0] 0 disable_power_on_sync 0x230[3] 0 power_down_sync 0x230[2] 0 power_down_dist_ref 0x230[1] 0 soft_sync 0x230[0] 0 io_update 0x232[0] 0 soft_eeprom 0xB02[1] 0 enable_eeprom_write 0xB02[0] 0 reg2eeprom 0xB03[0] 0 """ ######################################################################## # Template for methods in the body of the struct ######################################################################## BODY_TMPL="""\ boost::uint32_t get_reg(boost::uint16_t addr){ boost::uint32_t reg = 0; switch(addr){ #for $addr in sorted(set(map(lambda r: r.get_addr(), $regs))) case $addr: #for $reg in filter(lambda r: r.get_addr() == addr, $regs) reg |= (boost::uint8_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); #end for break; #end for } if (addr == 0){ //mirror 4 bits in register 0 reg |= ((reg >> 7) & 0x1) << 0; reg |= ((reg >> 6) & 0x1) << 1; reg |= ((reg >> 5) & 0x1) << 2; reg |= ((reg >> 4) & 0x1) << 3; } return reg; } void set_reg(boost::uint16_t addr, boost::uint32_t reg){ switch(addr){ #for $addr in sorted(set(map(lambda r: r.get_addr(), $regs))) case $addr: #for $reg in filter(lambda r: r.get_addr() == addr, $regs) $reg.get_name() = $(reg.get_type())((reg >> $reg.get_shift()) & $reg.get_mask()); #end for break; #end for } } boost::uint32_t get_write_reg(boost::uint16_t addr){ return (boost::uint32_t(addr) << 8) | get_reg(addr); } boost::uint32_t get_read_reg(boost::uint16_t addr){ return (boost::uint32_t(addr) << 8) | (1 << 23); } """ if __name__ == '__main__': import common; common.generate( name='ad9522_regs', regs_tmpl=REGS_TMPL, body_tmpl=BODY_TMPL, file=__file__, )