andy_shev

Baud rate calculator for Freescale DSPI

Apr 2nd, 2015
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.82 KB | None | 0 0
  1. #!/usr/bin/python -tt
  2. # -*- coding: UTF-8 -*-
  3. # vim: ts=4 sw=4 et ai si
  4.  
  5. import sys
  6. import os
  7. import operator
  8.  
  9. import math
  10. import fractions
  11.  
  12. __author__ = "Andy Shevchenko"
  13. __license__ = "GPL v2"
  14.  
  15. PROG = os.path.basename(sys.argv[0])
  16.  
  17. FSYS = 64000000
  18.  
  19. #
  20. # Fssp = Fsys / PBR
  21. # Baud rate = Fsclk = Fssp * (1 + DBR) / BR)
  22. #
  23.  
  24. # Baud rate, DDS_CLK_RATE, SCR
  25. TABLE = [
  26.     [50000000,  8388608,    0],
  27.     [40020000,  -1,         -1],
  28.     [40000000,  6710886,    0],
  29.     [39980000,  -1,         -1],
  30.     [25000000,  4194304,    0],
  31.     [20000000,  6710886,    1],
  32.     [16667000,  8388608,    2],
  33.     [13333000,  6710886,    2],
  34.     [12500000,  2097152,    0],
  35.     [10000000,  8388608,    4],
  36.     [8000000,   6710886,    4],
  37.     [6250000,   4194304,    3],
  38.     [5000000,   4194304,    4],
  39.     [4350000,   -1,         -1],
  40.     [4000000,   6710886,    9],
  41.     [3333000,   -1,         -1],
  42.     [3140500,   524288,     -1],
  43.     [3125000,   524288,     0],
  44.     [3109500,   524288,     -1],
  45.     [2500000,   4194304,    9],
  46.     [2000000,   6710886,    19],
  47.     [1563000,   262144,     0],
  48.     [1250000,   2097152,    9],
  49.     [1006000,   -1,         -1],
  50.     [1000000,   4194304,    24],
  51.     [994000,    -1,         -1],
  52.     [800000,    6710886,    49],
  53.     [781250,    131072,     0],
  54.     [625000,    2097152,    19],
  55.     [500000,    4194304,    49],
  56.     [400000,    6710886,    99],
  57.     [390625,    65536,      0],
  58.     [250000,    4194304,    99],
  59.     [200000,    6710886,    199],
  60.     [205313,    32768,      -1],
  61.     [195313,    32768,      0],
  62.     [185313,    32768,      -1],
  63.     [125000,    1048576,    49],
  64.     [100700,    -1,         -1],
  65.     [100000,    2097152,    124],
  66.     [99300,     -1,         -1],
  67.     [50000,     1048576,    124],
  68.     [25000,     524288,     124],
  69.     [10066,     131072,     -1],
  70.     [10016,     131072,     77],
  71.     [9966,      131072,     -1],
  72.     [5065,      131072,     -1],
  73.     [5040,      131072,     154],
  74.     [5015,      131072,     -1],
  75.     [1007,      32768,      -1],
  76.     [1002,      32768,      194],
  77.     [997,       32768,      -1],
  78. ]
  79.  
  80. PBR_TBL = [
  81.     2, 3, 5, 7
  82. ]
  83.  
  84. BRS = [
  85.     2,      4,      6,      8,
  86.     16,     32,     64,     128,
  87.     256,    512,    1024,   2048,
  88.     4096,   8192,   16384,  32768,
  89. ]
  90.  
  91. def orig_go(clkrate, speed_hz):
  92.     minscale = 2**31 - 1;
  93.     scale_needed = clkrate / speed_hz
  94.     for i,br in enumerate(BRS):
  95.         for j,pbr in enumerate(PBR_TBL):
  96.             scale = br * pbr
  97.             if scale >= scale_needed:
  98.                 if scale < minscale:
  99.                     minscale = scale
  100.                     ibr = i
  101.                     jpbr = j
  102.                 break
  103.     if minscale == 2**31 - 1:
  104.         print "Can not find valid baud rate"
  105.         ibr = len(BRS) - 1
  106.         jpbr = len(PBR_TBL) - 1
  107.  
  108.     br = BRS[ibr]
  109.     pbr = PBR_TBL[jpbr]
  110.     est = clkrate / pbr / br
  111.     print "%-8d %d %-2d %-5d %d %d %d %d" % (speed_hz, 0, ibr, br, jpbr, pbr, est, abs(est - speed_hz))
  112.  
  113. def orig_go_mod1(clkrate, speed_hz):
  114.     r = 2**31 - 1;
  115.     for i,br in enumerate(BRS):
  116.         for j,pbr in enumerate(PBR_TBL):
  117.             tmp = abs(clkrate / pbr / br - speed_hz)
  118.             if tmp < r:
  119.                 r = tmp
  120.                 ibr = i
  121.                 jpbr = j
  122.     if r == 2**31 - 1:
  123.         print "Can not find valid baud rate"
  124.         ibr = len(BRS) - 1
  125.         jpbr = len(PBR_TBL) - 1
  126.  
  127.     br = BRS[ibr]
  128.     pbr = PBR_TBL[jpbr]
  129.     est = clkrate / pbr / br
  130.     print "%-8d %d %-2d %-5d %d %d %d %d" % (speed_hz, 0, ibr, br, jpbr, pbr, est, abs(est - speed_hz))
  131.  
  132. def orig_go_mod2(clkrate, speed_hz):
  133.     minscale = 2**31 - 1;
  134.     for dbr in (0, 1):
  135.         for i,br in enumerate(BRS):
  136.             for j,pbr in enumerate(PBR_TBL):
  137.                 r = abs(clkrate / pbr * (1 + dbr) / br - speed_hz)
  138.                 if r < minscale:
  139.                     minscale = r
  140.                     ibr = i
  141.                     jpbr = j
  142.                     k = dbr
  143.     if minscale == 2**31 - 1:
  144.         print "Can not find valid baud rate"
  145.         ibr = len(BRS) - 1
  146.         jpbr = len(PBR_TBL) - 1
  147.         k = 0
  148.  
  149.     br = BRS[ibr]
  150.     pbr = PBR_TBL[jpbr]
  151.     est = clkrate / pbr * (1 + k) / br
  152.     print "%-8d %d %-2d %-5d %d %d %d %d" % (speed_hz, k, ibr, br, jpbr, pbr, est, abs(est - speed_hz))
  153.  
  154. def go(fref, baud):
  155.     dsd = dict()
  156.     for dbr in (0, 1):
  157.         for i,br in enumerate(BRS):
  158.             for j,pbr in enumerate(PBR_TBL):
  159.                 scale = br * pbr / (dbr + 1)
  160.                 if scale not in dsd:
  161.                     dsd[scale] = (dbr, i, j)
  162.  
  163.     ss = sorted(dsd.keys())
  164.  
  165.     prev = ss[0]
  166.     for scale in ss:
  167.         if scale * baud >= fref:
  168.             break
  169.         prev = scale
  170.  
  171.     r1 = abs(fref / prev - baud)
  172.     r2 = abs(fref / scale - baud)
  173.  
  174.     if r2 >= r1:
  175.         scale = prev
  176.  
  177.     dbr, ibr, jpbr = dsd[scale]
  178.  
  179.     br = BRS[ibr]
  180.     pbr = PBR_TBL[jpbr]
  181.     est = fref / pbr * (1 + dbr) / br
  182.  
  183.     print "%-8d %d %-2d %-5d %d %d %d %d" % (baud, dbr, ibr, br, jpbr, pbr, est, abs(est - baud))
  184.  
  185. def usage():
  186.     sys.stdout.write("Usage %s [ALGO [CUSTOM_BAUD_RATE]]\n" % PROG)
  187.  
  188. def toint(value):
  189.     try:
  190.         return int(value)
  191.     except ValueError:
  192.         usage()
  193.         raise SystemExit("Invalid argument")
  194.  
  195. ALGORITHMS = [
  196.     orig_go,
  197.     orig_go_mod1,
  198.     orig_go_mod2,
  199.     go,
  200. ]
  201.  
  202. def main(argv):
  203.     algo = 0
  204.     if len(argv) > 1:
  205.         algo = toint(argv[1])
  206.  
  207.     custom = 0
  208.     if len(argv) > 2:
  209.         custom = toint(argv[2])
  210.  
  211.     try:
  212.         func = ALGORITHMS[algo]
  213.     except IndexError:
  214.         usage()
  215.         raise SystemExit("Invalid argument")
  216.  
  217.     if custom:
  218.         func(FSYS, custom)
  219.     else:
  220.         for item in TABLE:
  221.             func(FSYS, operator.itemgetter(0)(item))
  222.  
  223. if __name__ == "__main__":
  224.     sys.exit(main(sys.argv))
Advertisement
Add Comment
Please, Sign In to add comment