Skip to content

Instantly share code, notes, and snippets.

@andy-shev
Last active June 24, 2016 09:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andy-shev/bcbae34a676d7456c61f5ee3e313264e to your computer and use it in GitHub Desktop.
Save andy-shev/bcbae34a676d7456c61f5ee3e313264e to your computer and use it in GitHub Desktop.
Fractional divider for LPSS PWM
#!/usr/bin/python -tt
# -*- coding: UTF-8 -*-
# vim: ts=4 sw=4 et ai si
import sys
import os
import operator
import math
import fractions
__author__ = "Andy Shevchenko"
__license__ = "GPL v2"
PROG = os.path.basename(sys.argv[0])
FSYS = 19200000
# Test date (pertiod, duty cycle)
TABLE = [
[100, 50],
[300, 250],
[1000, 250],
[50000, 10000],
[100000, 75000],
[300000, 50000],
[500000, 250000],
[20000000, 10000000],
[1, 1],
[53, 1],
[104, 1],
[256, 1],
[FSYS - 2, 1],
[FSYS - 1, FSYS - 2],
[FSYS, 1],
[FSYS, FSYS - 1],
]
def go(fref, period, duty):
freq = 10**9 / period
#
# The equation is:
# base_unit = round(base_unit_range * freq / c)
#
bur = 2**22
freq *= bur;
bu = freq / fref;
if duty > 0:
d = duty
else:
d = 1
otd = 255 * d
otd /= period
otd = 255 - otd
bul = bu & (bur - 1)
r = (bul << 8) + otd
pf = fref * bul * 1.0 / bur
dp = otd * 100.0 / 256
print "%d %d(%d): div: %d bu: %#x(%#x) -> %#x out freq: %.1f duty: %.2f(%.2f)%%" % (
period, duty, d, otd, bu, bul, r, pf, dp, duty * 100.0 / period
)
def usage():
sys.stdout.write("Usage %s [period [duty]]\n" % PROG)
def toint(value):
try:
return int(value)
except ValueError:
usage()
raise SystemExit("Invalid argument")
def main(argv):
fref = FSYS
if len(argv) > 1:
period = toint(argv[1])
if len(argv) > 2:
duty = toint(argv[2])
else:
duty = period / 2
go(fref, period, duty)
else:
for item in TABLE:
go(fref, operator.itemgetter(0)(item), operator.itemgetter(1)(item))
if __name__ == "__main__":
sys.exit(main(sys.argv))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment