Yalong Liu | 1df8437 | 2018-01-24 17:10:12 +0800 | [diff] [blame^] | 1 | #!/usr/bin/env python2 |
| 2 | # Copyright 2015 The Chromium OS Authors. All rights reserved. |
| 3 | # Use of this source code is governed by a BSD-style license that can be |
| 4 | # found in the LICENSE file. |
| 5 | |
| 6 | import sys |
| 7 | |
| 8 | # Things seem to magically change in the tables at these TMDS rates. |
| 9 | # Specifically looking at NO pixel repetition in the table: |
| 10 | # |
| 11 | # 0 - 44.9 - output divider is 0b11 |
| 12 | # 49.5 - 90.0 - output divider is 0b10 |
| 13 | # 94.5 - 182.75 - output divider is 0b01 |
| 14 | # 185.625 - - output divider is 0b00 |
| 15 | # |
| 16 | # You can also notice that MPLL charge pump settings change at similar times. |
| 17 | |
| 18 | RATE1 = 46000000 |
| 19 | RATE2 = 92000000 |
| 20 | RATE3 = 184000000 |
| 21 | |
| 22 | |
| 23 | def make_mpll(rate, depth, pixel_rep=0): |
| 24 | assert pixel_rep == 0, "Untested with non-zero pixel rep and probably wrong" |
| 25 | |
| 26 | tmds = (rate * depth) / 8. * (pixel_rep + 1) |
| 27 | |
| 28 | if depth == 8: |
| 29 | prep_div = 0 |
| 30 | elif depth == 10: |
| 31 | prep_div = 1 |
| 32 | elif depth == 12: |
| 33 | prep_div = 2 |
| 34 | elif depth == 16: |
| 35 | prep_div = 3 |
| 36 | |
| 37 | # Rates higher than 340MHz are HDMI 2.0 |
| 38 | # From tables, tmdsmhl_cntrl is 100% correlated with HDMI 1.4 vs 2.0 |
| 39 | if tmds <= 340000000: |
| 40 | opmode = 0 # HDMI 1.4 |
| 41 | tmdsmhl_cntrl = 0x0 |
| 42 | else: |
| 43 | opmode = 1 # HDMI 2.0 |
| 44 | tmdsmhl_cntrl = 0x3 |
| 45 | |
| 46 | # Keep the rate within the proper range with the output divider control |
| 47 | if tmds <= RATE1: |
| 48 | n_cntrl = 0x3 # output divider: 0b11 |
| 49 | elif tmds <= RATE2: |
| 50 | n_cntrl = 0x2 # output divider: 0b10 |
| 51 | elif tmds <= RATE3: |
| 52 | n_cntrl = 0x1 # output divider: 0b01 |
| 53 | else: |
| 54 | n_cntrl = 0x0 # output divider: 0b00 |
| 55 | |
| 56 | # Need to make the dividers work out |
| 57 | # |
| 58 | # This could be done algorithmically, but let's not for now. We show the |
| 59 | # math to make this work out below as an assert. |
| 60 | if n_cntrl == 0x3: |
| 61 | if depth == 8: |
| 62 | fbdiv2_cntrl = 0x2 # feedback div1: / 2 (no +1) |
| 63 | fbdiv1_cntrl = 0x3 # feedback div2: / 4 |
| 64 | ref_cntrl = 0x0 # input divider: / 1 |
| 65 | elif depth == 10: |
| 66 | fbdiv2_cntrl = 0x5 # feedback div1: / 5 (no +1) |
| 67 | fbdiv1_cntrl = 0x1 # feedback div2: / 2 |
| 68 | ref_cntrl = 0x0 # input divider: / 1 |
| 69 | elif depth == 12: |
| 70 | fbdiv2_cntrl = 0x3 # feedback div1: / 3 (no +1) |
| 71 | fbdiv1_cntrl = 0x3 # feedback div2: / 4 |
| 72 | ref_cntrl = 0x0 # input divider: / 1 |
| 73 | elif depth == 16: |
| 74 | # Guess: |
| 75 | fbdiv2_cntrl = 0x4 # feedback div1: / 4 (no +1) |
| 76 | fbdiv1_cntrl = 0x3 # feedback div2: / 4 |
| 77 | ref_cntrl = 0x0 # input divider: / 1 |
| 78 | |
| 79 | elif n_cntrl == 0x2: |
| 80 | if depth == 8: |
| 81 | fbdiv2_cntrl = 0x1 # feedback div1: / 1 (no +1) |
| 82 | fbdiv1_cntrl = 0x3 # feedback div2: / 4 |
| 83 | ref_cntrl = 0x0 # input divider: / 1 |
| 84 | elif depth == 10: |
| 85 | fbdiv2_cntrl = 0x5 # feedback div1: / 5 (no +1) |
| 86 | fbdiv1_cntrl = 0x0 # feedback div2: / 1 |
| 87 | ref_cntrl = 0x0 # input divider: / 1 |
| 88 | elif depth == 12: |
| 89 | fbdiv2_cntrl = 0x2 # feedback div1: / 2 (no +1) |
| 90 | fbdiv1_cntrl = 0x2 # feedback div2: / 3 |
| 91 | ref_cntrl = 0x0 # input divider: / 1 |
| 92 | elif depth == 16: |
| 93 | fbdiv2_cntrl = 0x2 # feedback div1: / 2 (no +1) |
| 94 | fbdiv1_cntrl = 0x3 # feedback div2: / 4 |
| 95 | ref_cntrl = 0x0 # input divider: / 1 |
| 96 | |
| 97 | elif n_cntrl == 0x1: |
| 98 | if depth == 8: |
| 99 | fbdiv2_cntrl = 0x1 # feedback div1: / 1 (no +1) |
| 100 | fbdiv1_cntrl = 0x1 # feedback div2: / 2 |
| 101 | ref_cntrl = 0x0 # input divider: / 1 |
| 102 | elif depth == 10: |
| 103 | fbdiv2_cntrl = 0x5 # feedback div1: / 5 (no +1) |
| 104 | fbdiv1_cntrl = 0x0 # feedback div2: / 1 |
| 105 | ref_cntrl = 0x1 # input divider: / 2 |
| 106 | elif depth == 12: |
| 107 | fbdiv2_cntrl = 0x1 # feedback div1: / 1 (no +1) |
| 108 | fbdiv1_cntrl = 0x2 # feedback div2: / 3 |
| 109 | ref_cntrl = 0x0 # input divider: / 1 |
| 110 | elif depth == 16: |
| 111 | fbdiv2_cntrl = 0x1 # feedback div1: / 1 (no +1) |
| 112 | fbdiv1_cntrl = 0x3 # feedback div2: / 4 |
| 113 | ref_cntrl = 0x0 # input divider: / 1 |
| 114 | |
| 115 | elif n_cntrl == 0x0: |
| 116 | if depth == 8: |
| 117 | fbdiv2_cntrl = 0x1 # feedback div1: / 1 (no +1) |
| 118 | fbdiv1_cntrl = 0x0 # feedback div2: / 1 |
| 119 | ref_cntrl = 0x0 # input divider: / 1 |
| 120 | elif depth == 10: |
| 121 | fbdiv2_cntrl = 0x5 # feedback div1: / 5 (no +1) |
| 122 | fbdiv1_cntrl = 0x0 # feedback div2: / 1 |
| 123 | ref_cntrl = 0x3 # input divider: / 4 |
| 124 | elif depth == 12: |
| 125 | fbdiv2_cntrl = 0x1 # feedback div1: / 1 (no +1) |
| 126 | fbdiv1_cntrl = 0x2 # feedback div2: / 3 |
| 127 | ref_cntrl = 0x1 # input divider: / 2 |
| 128 | elif depth == 16: |
| 129 | fbdiv2_cntrl = 0x1 # feedback div1: / 1 (no +1) |
| 130 | fbdiv1_cntrl = 0x1 # feedback div2: / 2 |
| 131 | ref_cntrl = 0x0 # input divider: / 1 |
| 132 | |
| 133 | # Double check with math; this formula derived from the table. |
| 134 | total_div = (fbdiv2_cntrl * (fbdiv1_cntrl + 1) * (1 << (3 - n_cntrl)) / |
| 135 | (ref_cntrl + 1)) |
| 136 | assert depth == total_div, \ |
| 137 | "Error with rate=%d, tmds=%d, depth=%d, n_cntrl=%d, pixel_rep=%d" % ( |
| 138 | rate, tmds, depth, n_cntrl, pixel_rep) |
| 139 | |
| 140 | # Could be done by math, but this makes it more obvious I think... |
| 141 | if n_cntrl == 3: |
| 142 | gmp_cntrl = 0 |
| 143 | elif n_cntrl == 2: |
| 144 | gmp_cntrl = 1 |
| 145 | elif n_cntrl == 1: |
| 146 | gmp_cntrl = 2 |
| 147 | elif n_cntrl == 0: |
| 148 | gmp_cntrl = 3 |
| 149 | |
| 150 | return ((n_cntrl << 0) | |
| 151 | (ref_cntrl << 2) | |
| 152 | (fbdiv1_cntrl << 4) | |
| 153 | (fbdiv2_cntrl << 6) | |
| 154 | (opmode << 9) | |
| 155 | (tmdsmhl_cntrl << 11) | |
| 156 | (prep_div << 13), |
| 157 | gmp_cntrl) |
| 158 | |
| 159 | def do_mpll_loop(): |
| 160 | mpll_cfg_table = {} |
| 161 | last_mpll_cfg = None |
| 162 | last_rate = None |
| 163 | |
| 164 | for rate in xrange(13500000, 600001000, 1000): |
| 165 | for8bpp = make_mpll(rate, 8) |
| 166 | for10bpp = make_mpll(rate, 10) |
| 167 | for12bpp = make_mpll(rate, 12) |
| 168 | |
| 169 | mpll_cfg = (for8bpp, for10bpp, for12bpp) |
| 170 | if (mpll_cfg != last_mpll_cfg) and (last_rate is not None): |
| 171 | mpll_cfg_table[last_rate] = last_mpll_cfg |
| 172 | |
| 173 | last_rate = rate |
| 174 | last_mpll_cfg = mpll_cfg |
| 175 | |
| 176 | mpll_cfg_table[last_rate] = last_mpll_cfg |
| 177 | |
| 178 | print "\t", |
| 179 | for rate in sorted(mpll_cfg_table.keys()): |
| 180 | print ("{\n" |
| 181 | "\t\t%d, {\n" |
| 182 | "\t\t\t{ %#06x, %#06x },\n" |
| 183 | "\t\t\t{ %#06x, %#06x },\n" |
| 184 | "\t\t\t{ %#06x, %#06x },\n" |
| 185 | "\t\t},\n" |
| 186 | "\t}, ") % ( |
| 187 | rate, |
| 188 | mpll_cfg_table[rate][0][0], mpll_cfg_table[rate][0][1], |
| 189 | mpll_cfg_table[rate][1][0], mpll_cfg_table[rate][1][1], |
| 190 | mpll_cfg_table[rate][2][0], mpll_cfg_table[rate][2][1]), |
| 191 | print |
| 192 | |
| 193 | def CLK_SLOP(clk): return ((clk) / 1000) |
| 194 | def CLK_PLUS_SLOP(clk): return ((clk) + CLK_SLOP(clk)) |
| 195 | def CLK_MINUS_SLOP(clk): return ((clk) - CLK_SLOP(clk)) |
| 196 | |
| 197 | def make_cur_ctr(rate, depth, pixel_rep=0): |
| 198 | assert pixel_rep == 0, "Untested with non-zero pixel rep and probably wrong" |
| 199 | |
| 200 | tmds = (rate * depth) / 8. * (pixel_rep + 1) |
| 201 | |
| 202 | adjust_for_jittery_pll = True |
| 203 | |
| 204 | # If the PIXEL clock (not the TMDS rate) is using the special 594 PLL |
| 205 | # and is slow enough, we can use normal rates... |
| 206 | if ((CLK_MINUS_SLOP(74250000) <= rate <= CLK_PLUS_SLOP(74250000)) or |
| 207 | (CLK_MINUS_SLOP(148500000) <= rate <= CLK_PLUS_SLOP(148500000))): |
| 208 | adjust_for_jittery_pll = False |
| 209 | |
| 210 | # If rate is slow enough then our jitter isn't a huge issue. |
| 211 | # ...allowable clock jitter is 362.3 or higher and we're OK there w/ plenty of |
| 212 | # margin as long as we're careful about our PLL settings. |
| 213 | if rate <= 79000000: |
| 214 | adjust_for_jittery_pll = False |
| 215 | |
| 216 | if not adjust_for_jittery_pll: |
| 217 | # This is as documented |
| 218 | if tmds <= RATE1: # 46000000 |
| 219 | return 0x18 |
| 220 | elif tmds <= RATE2: # 92000000 |
| 221 | return 0x28 |
| 222 | |
| 223 | # I have no idea why the below is true, but it is the simplest rule I could |
| 224 | # come up with that matched the tables... |
| 225 | if depth == 8: |
| 226 | if tmds <= 340000000: |
| 227 | # HDMI 1.4 |
| 228 | return 0x38 |
| 229 | # HDMI 2.0 |
| 230 | return 0x18 |
| 231 | elif depth == 16: |
| 232 | if tmds < 576000000: |
| 233 | return 0x38 |
| 234 | return 0x28 |
| 235 | else: |
| 236 | return 0x38 |
| 237 | |
| 238 | # The output of rk3288 PLL is the source of the HDMI's MPLL. Apparently |
| 239 | # the rk3288 PLL is too jittery. We can lower the PLL bandwidth of MPLL |
| 240 | # to compensate. |
| 241 | # |
| 242 | # Where possible, we try to use the MPLL bandwidth suggested by Synopsis |
| 243 | # and we just use lower bandwidth when testing has shown that it's needed. |
| 244 | # We try to stick to 0x28 and 0x18 since those numbers are present in |
| 245 | # Synopsis tables. We go down to 0x08 if needed and finally to 0x00. |
| 246 | |
| 247 | if rate <= 79000000: |
| 248 | # Supposed to be 0x28 here, but we'll do 0x18 to reduce jitter |
| 249 | return 0x18 |
| 250 | elif rate <= 118000000: |
| 251 | # Supposed to be 0x28/0x38 here, but we'll do 0x08 to reduce jitter |
| 252 | return 0x08 |
| 253 | # Any higher clock rates go to bandwidth = 0 |
| 254 | return 0 |
| 255 | |
| 256 | def do_curr_ctrl_loop(): |
| 257 | cur_ctrl_table = {} |
| 258 | last_cur_ctrl = None |
| 259 | last_rate = None |
| 260 | |
| 261 | for rate in xrange(13500000, 600001000, 1000): |
| 262 | for8bpp = make_cur_ctr(rate, 8) |
| 263 | for10bpp = make_cur_ctr(rate, 10) |
| 264 | for12bpp = make_cur_ctr(rate, 12) |
| 265 | |
| 266 | cur_ctrl = (for8bpp, for10bpp, for12bpp) |
| 267 | if (cur_ctrl != last_cur_ctrl) and (last_rate is not None): |
| 268 | cur_ctrl_table[last_rate] = last_cur_ctrl |
| 269 | |
| 270 | last_rate = rate |
| 271 | last_cur_ctrl = cur_ctrl |
| 272 | |
| 273 | cur_ctrl_table[last_rate] = last_cur_ctrl |
| 274 | |
| 275 | print "\t", |
| 276 | for rate in sorted(cur_ctrl_table.keys()): |
| 277 | print ("{\n" |
| 278 | "\t\t%d, { %#06x, %#06x, %#06x },\n" |
| 279 | "\t}, ") % ( |
| 280 | rate, |
| 281 | cur_ctrl_table[rate][0], |
| 282 | cur_ctrl_table[rate][1], |
| 283 | cur_ctrl_table[rate][2]), |
| 284 | print |
| 285 | |
| 286 | |
| 287 | |
| 288 | # From HDMI spec |
| 289 | VPH_RXTERM = 3.3 |
| 290 | RXTERM = 50 |
| 291 | |
| 292 | def get_phy_preemphasis(symon, traon, trbon): |
| 293 | if (symon, traon, trbon) == (0, 0, 0): |
| 294 | assert False, "Not valid?" |
| 295 | elif (symon, traon, trbon) == (1, 0, 0): |
| 296 | preemph = 0.00 |
| 297 | elif (symon, traon, trbon) == (1, 0, 1): |
| 298 | # Numbers match examples better if I assume .25 / 3 rather than .08 |
| 299 | preemph = 0.25 / 3 |
| 300 | elif (symon, traon, trbon) == (1, 1, 0): |
| 301 | # Numbers match examples better if I assume .50 / 3 rather than .17 |
| 302 | preemph = 0.50 / 3 |
| 303 | elif (symon, traon, trbon) == (1, 1, 1): |
| 304 | preemph = 0.25 |
| 305 | else: |
| 306 | assert False, "Not valid" |
| 307 | |
| 308 | return preemph |
| 309 | |
| 310 | def phy_lvl_to_voltages(lvl, preemph, rterm): |
| 311 | v_lo = VPH_RXTERM - (.772 - 0.01405 * lvl) |
| 312 | v_swing = ((VPH_RXTERM - v_lo) * (1 - preemph) / |
| 313 | (1 + (RXTERM * (1 + preemph)) / (2 * rterm))) |
| 314 | v_hi = v_lo + v_swing |
| 315 | |
| 316 | return v_lo, v_swing, v_hi |
| 317 | |
| 318 | def print_phy_config(symbol, term, vlev): |
| 319 | ck_symon = bool(symbol & (1 << 0)) |
| 320 | tx_trbon = bool(symbol & (1 << 1)) |
| 321 | tx_traon = bool(symbol & (1 << 2)) |
| 322 | tx_symon = bool(symbol & (1 << 3)) |
| 323 | |
| 324 | slopeboost = { |
| 325 | 0: "no slope boost", |
| 326 | 1: " 5-10% decrease on TMDS rise/fall times", |
| 327 | 2: "10-20% decrease on TMDS rise/fall times", |
| 328 | 3: "20-35% decrease on TMDS rise/fall times", |
| 329 | }[(symbol >> 4) & 0x3] |
| 330 | |
| 331 | override = bool(symbol & (1 << 15)) |
| 332 | |
| 333 | rterm = (50, 57.14, 66.67, 80, 100, 133, 200)[term] |
| 334 | |
| 335 | sup_ck_lvl = (vlev >> 0) & 0x1f |
| 336 | sup_tx_lvl = (vlev >> 5) & 0x1f |
| 337 | |
| 338 | preemph = get_phy_preemphasis(tx_symon, tx_traon, tx_trbon) |
| 339 | |
| 340 | print "symbol=%#06x, term=%#06x, vlev=%#06x" % (symbol, term, vlev) |
| 341 | for name, lvl in [("ck", sup_ck_lvl), ("tx", sup_tx_lvl)]: |
| 342 | v_lo, v_swing, v_hi = phy_lvl_to_voltages(lvl, preemph, rterm) |
| 343 | print " %s: lvl = %2d, term=%3d, vlo = %.2f, vhi=%.2f, vswing = %.2f, %s" % ( |
| 344 | name, lvl, rterm, v_lo, v_hi, v_swing, slopeboost) |
| 345 | |
| 346 | #def calc_ideal_phy_lvl(swing_mv, preemph, rterm): |
| 347 | #"""Get the ideal "lvl" for the given swing, preemph, and termination. |
| 348 | |
| 349 | #This might not be integral, but and might not fit the 0-31 range. |
| 350 | #""" |
| 351 | #v_lo = (VPH_RXTERM - |
| 352 | #v_swing / (1 - preemph) - |
| 353 | #(v_swing * RXTERM * (1 + preemph)) / (2 * rterm * (1 - preemph))) |
| 354 | #lvl = (.772 - (VPH_RXTERM - v_lo)) / 0.01405 |
| 355 | |
| 356 | #return lvl |
| 357 | |
| 358 | def do_phy_config_list(rate=16500000): |
| 359 | # From HDMI spec |
| 360 | VPH_RXTERM = 3.3 |
| 361 | RXTERM = 50 |
| 362 | |
| 363 | # Set to True to print even things that don't meet requirements. |
| 364 | print_invalid = False |
| 365 | |
| 366 | # Totally a guess based on what's in IMX6DQRM |
| 367 | if rate <= 165000000: |
| 368 | symon = 1 # tx_symon |
| 369 | traon = 0 # tx_traon |
| 370 | trbon = 0 # tx_trbon |
| 371 | else: |
| 372 | symon = 1 # tx_symon |
| 373 | traon = 0 # tx_traon |
| 374 | trbon = 1 # tx_trbon |
| 375 | |
| 376 | print "Guessing symon, traon, trbon based on rate: (%d, %d, %d)" % ( |
| 377 | symon, traon, trbon) |
| 378 | |
| 379 | preemph = get_phy_preemphasis(symon, traon, trbon) |
| 380 | |
| 381 | # Notes: |
| 382 | # - swing needs to be between .4 and .6 |
| 383 | # - If <= 165MHz, vhi is (VPH_RXTERM + .01) thru (VPH_RXTERM - .01) |
| 384 | # - If > 165MHz, vhi is (VPH_RXTERM + .01) thru (VPH_RXTERM - .2) |
| 385 | # - If <= 165MHz, vlo is (VPH_RXTERM - .4) thru (VPH_RXTERM - .6) |
| 386 | # - If > 165MHz, vlo is (VPH_RXTERM - .4) thru (VPH_RXTERM - .7) |
| 387 | # |
| 388 | # TODO: I'm not sure we can actually reach vhi of 3.3 +/- .01 |
| 389 | # TODO: How do we pick amongst all of these? |
| 390 | |
| 391 | if rate <= 165000000: |
| 392 | v_hi_min = 3.19 # Should be (VPH_RXTERM - .01), but not possible? |
| 393 | v_hi_max = (VPH_RXTERM + .01) |
| 394 | v_lo_min = (VPH_RXTERM - .6) |
| 395 | v_lo_max = (VPH_RXTERM - .4) |
| 396 | else: |
| 397 | v_hi_min = (VPH_RXTERM - .2) |
| 398 | v_hi_max = (VPH_RXTERM + .01) |
| 399 | v_lo_min = (VPH_RXTERM - .7) |
| 400 | v_lo_max = (VPH_RXTERM - .4) |
| 401 | |
| 402 | for lvl in xrange(0, 31): |
| 403 | for rterm in (50, 57.14, 66.67, 80, 100, 133, 200): |
| 404 | v_lo, v_swing, v_hi = phy_lvl_to_voltages(lvl, preemph, rterm) |
| 405 | |
| 406 | if (print_invalid or |
| 407 | ((.4 <= v_swing <= .6) and |
| 408 | (v_hi_min <= v_hi <= v_hi_max) and |
| 409 | (v_lo_min <= v_lo <= v_lo_max))): |
| 410 | print "lvl = %2d, term=%3d, vlo = %.2f, vhi=%.2f, vswing = %.2f" % ( |
| 411 | lvl, rterm, v_lo, v_hi, v_swing) |
| 412 | |
| 413 | # Examples: |
| 414 | # |
| 415 | # $ ./rk3288_hdmitables.py mpll |
| 416 | # $ ./rk3288_hdmitables.py curr |
| 417 | # $ ./rk3288_hdmitables.py phy_list 165000000 |
| 418 | # $ ./rk3288_hdmitables.py phy_list 600000000 |
| 419 | # $ ./rk3288_hdmitables.py phy_print 0x8009, 0x0005, 0x01ad |
| 420 | |
| 421 | def main(todo, *args): |
| 422 | if todo == "mpll": |
| 423 | do_mpll_loop() |
| 424 | elif todo == "curr": |
| 425 | do_curr_ctrl_loop() |
| 426 | elif todo == "phy_list": |
| 427 | (rate,) = args |
| 428 | rate = int(rate, 0) |
| 429 | do_phy_config_list(rate) |
| 430 | elif todo == "phy_print": |
| 431 | (symbol, term, vlev) = args |
| 432 | symbol = int(symbol.rstrip(","), 0) |
| 433 | term = int(term.rstrip(","), 0) |
| 434 | vlev = int(vlev.rstrip(","), 0) |
| 435 | |
| 436 | print_phy_config(symbol, term, vlev) |
| 437 | |
| 438 | # These ought to match the tables in the docs. They are close, but not |
| 439 | # perfect. ...but my math is definitely right since v_lo doesn't match |
| 440 | # and v_lo should be very simple. Even if we try to find more significant |
| 441 | # digits for 0.772 and 0.01405 we still can't make it match, so I'm assuming |
| 442 | # that they rounded somewhere in their math... |
| 443 | |
| 444 | #print "%.3f, %.3f, %.3f" % phy_lvl_to_voltages(19, get_phy_preemphasis(1, 0, 0), 100) |
| 445 | #print "%.3f, %.3f, %.3f" % phy_lvl_to_voltages(10, get_phy_preemphasis(1, 0, 0), 100) |
| 446 | #print "%.3f, %.3f, %.3f" % phy_lvl_to_voltages( 6, get_phy_preemphasis(1, 0, 1), 100) |
| 447 | |
| 448 | #print "%.3f, %.3f, %.3f" % phy_lvl_to_voltages(21, get_phy_preemphasis(1, 0, 0), 133) |
| 449 | #print "%.3f, %.3f, %.3f" % phy_lvl_to_voltages(13, get_phy_preemphasis(1, 0, 0), 133) |
| 450 | #print "%.3f, %.3f, %.3f" % phy_lvl_to_voltages( 8, get_phy_preemphasis(1, 0, 1), 133) |
| 451 | |
| 452 | |
| 453 | if __name__ == '__main__': |
| 454 | main(*sys.argv[1:]) |