1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
|
#!/usr/bin/env python
#
# Copyright 2010 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 <http://www.gnu.org/licenses/>.
#
########################################################################
# 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
a_counter 0x013[5:0] 0
b_counter_lsb 0x014[7:0] 3
b_counter_msb 0x015[4:0] 0
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, 2_9ns
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_ref2 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
########################################################################
#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::uint8_t get_reg(boost::uint16_t addr){
boost::uint8_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::uint8_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__,
)
|