#!/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 write registers
# name addr[bit range inclusive] default optional enums
########################################################################
REGS_TMPL="""\
########################################################################
## Note: offsets given from perspective of data bits (excludes address)
########################################################################
##
########################################################################
##  ID_byte_1 (0x00) Read
########################################################################
## reserved as 1       0x00[7]       1
ident_14_8            0x00[0:6]     0
########################################################################
##  ID_byte_2 (0x01) Read
########################################################################
ident_7_0             0x01[0:7]     0
##~ident                ident_7_0, ident_14_8
########################################################################
##  ID_byte_3 (0x02) Read
########################################################################
major_rev             0x02[4:7]     0
minor_rev             0x02[0:3]     0
########################################################################
##  Thermo_byte_1 (0x03) Read
########################################################################
## reserved            0x03[7]       0
## 22-127deg C junction temp
tm_d                  0x03[0:6]     0
########################################################################
##  Thermo_byte_2 (0x04) Write
########################################################################
## reserved            0x04[1:7]     0
tm_on                 0x04[0]       0   sensor_off, sensor_on
########################################################################
##  Power_state_byte_1 (0x05) Read
########################################################################
## reserved            0x05[2:7]     0
por                   0x05[1]       0   read, reset
lo_lock               0x05[0]       0   unlocked, locked
########################################################################
## Standby modes
##  Power_state_byte_2 (0x06) Read/Write
########################################################################
## reserved            0x06[4:7]     0
sm                    0x06[3]       0   normal, standby
sm_pll                0x06[2]       0   on, off
sm_lna                0x06[1]       0   on, off
##resevered as 0      0x06[0]       0
## (sm, sm_pll, sm_lna) only valid values are 000, 100, 110, and 111
########################################################################
##  Input_Power_Level_byte (0x07) Read
########################################################################
## reserved            0x07[7]       0
## 40dB_Vrms to 110dB_Vrms
power_level           0x07[0:6]     0
## Trigger power level calculation with MSM_byte_1 and MSM_byte_2
########################################################################
##  IRQ_status (0x08) Read/Write
########################################################################
irq_status            0x08[7]       0   cleared, set
## reserved            0x08[6]       0
irq_xtalcal_end       0x08[5]       0   false, true
irq_rssi_end          0x08[4]       0   false, true
irq_localc_end        0x08[3]       0   false, true
irq_rfcal_end         0x08[2]       0   false, true
irq_ircal_end         0x08[1]       0   false, true
irq_rccal_end         0x08[0]       0   false, true
########################################################################
##  IRQ_enable (0x09) Read/Write
########################################################################
irq_enable            0x09[7]       1   false, true
## reserved            0x09[6]       0
irq_xtalcal_enable    0x09[5]       0   false, true
irq_rssi_enable       0x09[4]       0   false, true
irq_localc_enable     0x09[3]       0   false, true
irq_rfcal_enable      0x09[2]       0   false, true
irq_ircal_enable      0x09[1]       0   false, true
irq_rccal_enable      0x09[0]       0   false, true
########################################################################
##  IRQ_clear (0x0a) Read/Write
########################################################################
irq_clear             0x0a[7]       0   false, true
## reserved            0x0a[6]       0
irq_xtalcal_clear     0x0a[5]       0   false, true
irq_rssi_clear        0x0a[4]       0   false, true
irq_localc_clear      0x0a[3]       0   false, true
irq_rfcal_clear       0x0a[2]       0   false, true
irq_ircal_clear       0x0a[1]       0   false, true
irq_rccal_clear       0x0a[0]       0   false, true
########################################################################
##  IRQ_set (0x0b) Read
########################################################################
irq_set               0x0b[7]       0   false, true
## reserved            0x0b[6]       0
irq_xtalcal_set       0x0b[5]       0   false, true
irq_rssi_set          0x0b[4]       0   false, true
irq_localc_set        0x0b[3]       0   false, true
irq_rfcal_set         0x0b[2]       0   false, true
irq_ircal_set         0x0b[1]       0   false, true
irq_rccal_set         0x0b[0]       0   false, true
########################################################################
##  AGC1_byte_1 (0x0c) Read/Write
########################################################################
lt_enable             0x0c[7]       0
agc1_6_15db           0x0c[6]       1
## reserved            0x0c[4:5]     0
agc1_top              0x0c[0:3]     0
########################################################################
##  AGC2_byte_1 (0x0d) Read
########################################################################
## reserved            0x0d[5:7]     0
agc2_top              0x0d[0:4]     0xf
########################################################################
##  AGCK_byte_1 (0x0e) Read/Write
########################################################################
agcs_up_step_assym    0x0e[6:7]     3
agcs_up_step          0x0e[5]       1
pulse_shaper_disable  0x0e[4]       0   vsync_pulse, 500us_pulse
agck_step             0x0e[2:3]     0
agck_mode             0x0e[0:1]     1   analog_tv=1, digital_tv=2
########################################################################
##  RF_AGC_byte_1 (0x0f) Read/Write
########################################################################
pd_rfagc_adapt        0x0f[7]       0   on, off
rfagc_adapt_top       0x0f[5:6]     0
rfagc_low_bw          0x0f[4]       1
## FIXME
rf_atten_3db          0x0f[3]       0   0db, 3db
agc3_top              0x0f[0:2]     1
########################################################################
##  IR_MIXER_byte_1 (0x10) Read/Write
########################################################################
## reserved            0x10[4:7]     0
agc4_top              0x10[0:3]     1
########################################################################
##  AGC5_byte_1 (0x11) Read/Write
########################################################################
## reserved            0x11[7]       0
agcs_do_step_assym    0x11[5:6]     2
agc5_hpf              0x11[4]       1   off, on
agc5_top              0x11[0:3]     1
########################################################################
##  IF_AGC_byte (0x12) Read/Write
########################################################################
## reserved            0x12[3:7]     0
if_level              0x12[0:2]     0   0_5vpp=7, 0_6vpp=6, 0_7vpp=5, 0_85vpp=4, 0_8vpp=3, 1_0vpp=2, 1_25vpp=1, 2_0vpp=0
########################################################################
##  IF_byte_1 (0x13) Read/Write
########################################################################
if_hp_fc              0x13[6:7]     0   0_4mhz, 0_85mhz, 1_0mhz, 1_5mhz
if_atsc_notch         0x13[5]       0   off, on
lp_fc_offset          0x13[3:4]     0   0_percent, m4_percent, m8_percent, forbidden
lp_fc                 0x13[0:2]     3   1_7mhz=4, 6_0mhz=0, 7_0mhz=1, 8_0mhz=2, 10_0mhz=3
########################################################################
##  Reference_byte (0x14) Read/Write
########################################################################
i2c_clock_mode        0x14[7]       0
digital_clock         0x14[6]       1   spread_off, spread_on
## reserved            0x14[5]       0
xtalosc_anareg_en     0x14[4]       0
## reserved            0x14[2:3]     0
xtout                 0x14[0:1]     0   no=0, 16mhz=3
########################################################################
##  IF_Frequency_byte (0x15) Read/Write
########################################################################
## IF frequency = if_freq*50 (kHz)
if_freq               0x15[0:7]     0
########################################################################
##  RF_Frequency_byte_1 (0x16) Read/Write
########################################################################
## reserved           0x16[4:7]     0
rf_freq_19_16         0x16[0:3]     0
########################################################################
##  RF_Frequency_byte_2 (0x17) Read/Write
########################################################################
rf_freq_15_8          0x17[0:7]     0
########################################################################
##  RF_Frequency_byte_3 (0x18) Read/Write
########################################################################
rf_freq_7_0           0x18[0:7]     0
~rf_freq              rf_freq_7_0, rf_freq_15_8, rf_freq_19_16
## RF Frequency = rf_freq (kHz)
########################################################################
##  MSM_byte_1 (0x19) Read/Write
########################################################################
rssi_meas             0x19[7]       0
rf_cal_av             0x19[6]       0
rf_cal                0x19[5]       0
ir_cal_loop           0x19[4]       0
ir_cal_image          0x19[3]       0
ir_cal_wanted         0x19[2]       0
rc_cal                0x19[1]       0
calc_pll              0x19[0]       0
########################################################################
##  MSM_byte_2 (0x1a) Read
########################################################################
## reserved           0x1a[2:7]     0
xtalcal_launch        0x1a[1]       0
msm_launch            0x1a[0]       0
########################################################################
##  PSM_byte_1 (0x1b) Read
########################################################################
psm_agc1              0x1b[6:7]     0
psm_stob              0x1b[5]       0
psmrfpoly             0x1b[4]       0
psm_mixer             0x1b[3]       0
psm_ifpoly            0x1b[2]       0
psm_lodriver          0x1b[0:1]     0
########################################################################
##  DCC_byte_1 (0x1c) Read
########################################################################
dcc_bypass            0x1c[7]       0
dcc_slow              0x1c[6]       0
dcc_psm               0x1c[5]       0
## reserved           0x1c[0:4]     0
########################################################################
##  FLO_Max_byte (0x1d) Read
########################################################################
## reserved           0x1d[6:7]     0
fmax_lo               0x1d[0:5]     0xA
########################################################################
##  IR_Cal_byte_1 (0x1e) Read
########################################################################
ir_loop               0x1e[6:7]     0
ir_target             0x1e[3:5]     0
ir_gstep              0x1e[0:2]     0
########################################################################
##  IR_Cal_byte_2 (0x1f) Read
########################################################################
ir_corr_boost         0x1f[7]       0
ir_freqlow_sel        0x1f[6]       0
ir_mode_ram_store     0x1f[5]       0
ir_freqlow            0x1f[0:4]     0
########################################################################
##  IR_Cal_byte_3 (0x20) Read
########################################################################
## reserved           0x20[5:7]     0
ir_freqmid            0x20[0:4]     0
########################################################################
##  IR_Cal_byte_4 (0x21) Read
########################################################################
## reserved           0x21[5:7]     0
coarse_ir_freqhigh    0x21[4]       0
ir_freqhigh           0x21[0:3]     0
########################################################################
##  Vsync_Mgt_byte (0x22) Read
########################################################################
pd_vsync_mgt          0x22[7]       0
pd_ovld               0x22[6]       0
pd_udld               0x22[5]       0
agc_ovld_top          0x22[2:4]     0
agc_ovld_timer        0x22[0:1]     0
########################################################################
##  IR_MIXER_byte_2 (0x23) Read/Write
########################################################################
ir_mixer_loop_off     0x23[7]       0
ir_mixer_do_step      0x23[5:6]     0
## reserved            0x23[2:4]     0
## FIXME Logic Unclear
hi_pass               0x23[1]       0   disable, enable
if_notch              0x23[0]       1   on, off
########################################################################
##  AGC1_byte_2 (0x24) Read
########################################################################
agc1_loop_off         0x24[7]       0
agc1_do_step          0x24[5:6]     2
force_agc1_gain       0x24[4]       0
agc1_gain             0x24[0:3]     8
########################################################################
##  AGC5_byte_2 (0x25) Read
########################################################################
agc5_loop_off         0x25[7]       0
agc5_do_step          0x25[5:6]     0
## reserved            0x25[4]       0
force_agc5_gain       0x25[3]       0
## reserved            0x25[2]       0
agc5_gain             0x25[0:1]     2
########################################################################
##  RF_Cal_byte_1 (0x26) Read
########################################################################
rfcal_offset_cprog0   0x26[6:7]     0
rfcal_freq0           0x26[4:5]     0
rfcal_offset_cprog1   0x26[2:3]     0
rfcal_freq1           0x26[0:1]     0
########################################################################
##  RF_Cal_byte_2 (0x27) Read
########################################################################
rfcal_offset_cprog2   0x27[6:7]     0
rfcal_freq2           0x27[4:5]     0
rfcal_offset_cprog3   0x27[2:3]     0
rfcal_freq3           0x27[0:1]     0
########################################################################
##  RF_Cal_byte_3 (0x28) Read
########################################################################
rfcal_offset_cprog4   0x28[6:7]     0
rfcal_freq4           0x28[4:5]     0
rfcal_offset_cprog5   0x28[2:3]     0
rfcal_freq5           0x28[0:1]     0
########################################################################
##  RF_Cal_byte_4 (0x29) Read
########################################################################
rfcal_offset_cprog6   0x29[6:7]     0
rfcal_freq6           0x29[4:5]     0
rfcal_offset_cprog7   0x29[2:3]     0
rfcal_freq7           0x29[0:1]     0
########################################################################
##  RF_Cal_byte_5 (0x2a) Read
########################################################################
rfcal_offset_cprog8   0x2a[6:7]     0
rfcal_freq8           0x2a[4:5]     0
rfcal_offset_cprog9   0x2a[2:3]     0
rfcal_freq9           0x2a[0:1]     0
########################################################################
##  RF_Cal_byte_6 (0x2b) Read
########################################################################
rfcal_offset_cprog10  0x2b[6:7]     0
rfcal_freq10          0x2b[4:5]     0
rfcal_offset_cprog11  0x2b[2:3]     0
rfcal_freq11          0x2b[0:1]     0
########################################################################
##  RF_Filter_byte_1 (0x2c) Read
########################################################################
rf_filter_bypass      0x2c[7]       0
## reserved as 0       0x2c[6]       0
agc2_loop_off         0x2c[5]       0
force_agc2_gain       0x2c[4]       0
rf_filter_gv          0x2c[2:3]     2
rf_filter_band        0x2c[0:1]     0
########################################################################
##  RF_Filter_byte_2 (0x2d) Read
########################################################################
rf_filter_cap         0x2d[0:7]     0
########################################################################
##  RF_Filter_byte_3 (0x2e) Read
########################################################################
agc2_do_step          0x2e[6:7]     2
gain_taper            0x2e[0:5]     0
########################################################################
##  RF_Band_Pass_Filter_byte (0x2f) Read
########################################################################
rf_bpf_bypass         0x2f[7]       0
## reserved            0x2f[3:6]     0
rf_bpf                0x2f[0:2]     0
########################################################################
##  CP_Current_byte (0x30) Read
########################################################################
## reserved            0x30[7]       0
n_cp_current          0x30[0:6]     0x68
########################################################################
##  AGC_Det_Out_byte (0x31) Read
########################################################################
up_agc5               0x31[7]       0
do_agc5               0x31[6]       0
up_agc4               0x31[5]       0
do_agc4               0x31[4]       0
up_agc2               0x31[3]       0
do_agc2               0x31[2]       0
up_agc1               0x31[1]       0
do_agc1               0x31[0]       0
########################################################################
##  RF_AGC_Gain_byte_1 (0x32) Read
########################################################################
## reserved            0x32[6:7]     0
agc2_gain_read        0x32[4:5]     3   m11db, m8db, m5db, m2db
<% lna_gain_names = ', '.join(map(lambda x: {0: '', 1: 'm'}[3*x-12 < 0] + str(abs(3*x-12)) + 'db=' + str(x), range(0,10))) %>\
agc1_gain_read        0x32[0:3]     9   ${lna_gain_names}
########################################################################
##  RF_AGC_Gain_byte_2 (0x33) Read
########################################################################
## reserved            0x33[3:7]     0
<% top_agc3_read_names = ', '.join(map(lambda x: str(int(round(1.92*x+94))) + 'dbuvrms=' + str(x), range(0,8))) %>\
top_agc3_read         0x33[0:2]     0   ${top_agc3_read_names}
########################################################################
##  IF_AGC_Gain_byte (0x34) Read
########################################################################
## reserved            0x34[5:7]     0
<%
    lpf_gain_names = ', '.join(map(lambda x: str(3*x) + 'db=' + str(x), range(0,4)))
    ir_mixer_names = ', '.join(map(lambda x: str(3*x+2) + 'db=' + str(x), range(0,5)))
%>\
agc5_gain_read        0x34[3:4]     3   ${lpf_gain_names}
agc4_gain_read        0x34[0:2]     4   ${ir_mixer_names}
########################################################################
##  Power_byte_1 (0x35) Read
########################################################################
rssi                  0x35[0:7]     0
########################################################################
##  Power_byte_2 (0x36) Read
########################################################################
## reserved           0x36[6:7]     0
rssi_av               0x36[5]       0
## reserved           0x36[4]       0
rssi_cap_reset_en     0x36[3]       1
rssi_cap_val          0x36[2]       1
rssi_ck_speed         0x36[1]       0
rssi_dicho_not        0x36[0]       1
########################################################################
##  Misc_byte_1 (0x37) Read/Write
########################################################################
rfcal_phi2            0x37[6:7]     1
dds_polarity          0x37[5]       0
rfcal_deltagain       0x37[1:4]     1
irq_polarity          0x37[0]       0   raised_vcc, raised_low
########################################################################
##  rfcal_log_1 (0x38) Read
########################################################################
rfcal_log_1           0x38[0:7]     0
########################################################################
##  rfcal_log_2 (0x39) Read
########################################################################
rfcal_log_2           0x39[0:7]     0
########################################################################
##  rfcal_log_3 (0x3a) Read
########################################################################
rfcal_log_3           0x3a[0:7]     0
########################################################################
##  rfcal_log_4 (0x3b) Read
########################################################################
rfcal_log_4           0x3b[0:7]     0
########################################################################
##  rfcal_log_5 (0x3c) Read
########################################################################
rfcal_log_5           0x3c[0:7]     0
########################################################################
##  rfcal_log_6 (0x3d) Read
########################################################################
rfcal_log_6           0x3d[0:7]     0
########################################################################
##  rfcal_log_7 (0x3e) Read
########################################################################
rfcal_log_7           0x3e[0:7]     0
########################################################################
##  rfcal_log_8 (0x3f) Read
########################################################################
rfcal_log_8           0x3f[0:7]     0
########################################################################
##  rfcal_log_9 (0x40) Read
########################################################################
rfcal_log_9           0x40[0:7]     0
########################################################################
##  rfcal_log_10 (0x41) Read
########################################################################
rfcal_log_10          0x41[0:7]     0
########################################################################
##  rfcal_log_11 (0x42) Read
########################################################################
rfcal_log_11          0x42[0:7]     0
########################################################################
##  rfcal_log_12 (0x43) Read
########################################################################
rfcal_log_12          0x43[0:7]     0
##
##
########################################################################
## FORBIDDEN ACCESS to 0x50-0x67 and 0xFE-0xFF
########################################################################
########################################################################
##  xtal_cal_dac (0x65) Write
########################################################################
magic                 0x43[7]       1   untouched, xtal_cal_dac
"""

########################################################################
# Template for methods in the body of the struct
########################################################################
BODY_TMPL="""\
uint8_t get_reg(uint8_t addr){
    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 |= (uint8_t(${reg.get_name()}) & ${reg.get_mask()}) << ${reg.get_shift()};
        % endfor
        break;
    % endfor
    }
    return uint8_t(reg);
}

void set_reg(uint8_t addr, uint8_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()});
        % endfor
        break;
    % endfor
    }
}
"""

if __name__ == '__main__':
    import common; common.generate(
        name='tda18272hnm_regs',
        regs_tmpl=REGS_TMPL,
        body_tmpl=BODY_TMPL,
        file=__file__,
    )