Приветствую.
Появилась необходимость написать драйвер для программируемого синтезатора частоты TI CDCE913.
Подогнать его для использования Linux Clock Framework ( http://kernel.org/doc/htmldocs/kernel-api/clk.html ) не выходит, ибо для того чтобы посчитать коэффициенты для PLL нужно провести относительно сложные вычисления с логарифмами, степенями, подбором коэф-ов и прочей мутотой. Тащить в модуль все эти вычисления даже в fixed point исполнении мысль не самая светлая. В связи с этим вопрос: как лучше всего в таком случае организовать userspace-интерфейс драйвера?
Пока что я это делаю через sysfs.
То бишь, если надо задать, например, значение какого-либо из делителей, то в файл pdiv натурально пишется особым образом сформированное шестнадцатиричное число. Но данный подход уж слишком не прозрачен.
Да, в широких диапазонах. От 100 до 200 МГц с шагом 0,5 МГц (пока что, потом может и точнее понадобится). Так что идею с таблицей пришлось сразу отбросить.
Мельком посмотрел на даташит - помоему там все быстро считается на целочисленке, логарифмы по основанию 2 и умножения на степени двойки - сплошные сдвиги, кроме пары делений и умножений целочисленных.
Ды проблема даже не совсем в этом, там же на все коэф-ы накладываются ограничения, все они должны лежать в определённых пределах. К тому же, получить одну частоту можно при разных коэф-ах, но с разной погрешностью, то бишь ещё нужно искать вариант коэф-ов при которых значение погрешности минимально. Но это в идеале, если плюнуть на погрешность и считать её незначительной, то можно получить значение коэф-ов относительно быстро. Может я уже туплю, завтра надо будет внимательно посмотреть на расчёты. Но в любом случае, прибор делается измерительный, чем точнее частота - тем лучше.
Я пока сам точно не знаю какая точность понадобится, шаг 0,5МГц был взят с потолка. Да у меня сейчас даже железки на руках нет =)
В любом случае это решение из разряда "прибить гвоздями", то есть ограничить возможности железки софтварно. Но как вариант вполне рассматривается, если уж совсем прижмёт.
Я знаю что здесь это вряд ли кому то интересно, но всё же...
Итак, я накидал простенькую программку, которая вычисляет значение коэффициентов по заданным N и M используя только целочисленную арифметику, а также проверяет значение полученных коэффициентов на попадание в допустимые диапазоны: https://github.com/Lampus/cdce913/blob/master/calc_coeff.c
Прошу сильно не закидывать тухлыми помидорами, коли что не так.
Теперь остаётся решить каким образом подобрать коэф-ы N и M имея заданную Fvco в минимальное количество итераций, таким образом, чтобы полученные коэф-ы попадали в заданные диапазоны и погрешность была минимальной.
Даташит лежит тут: http://focus.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=SCAS849&track=no
Итак, входные данные:
Из первой формулы ясно что N/M = Fvco/Fin. То есть нам известно соотношение между N и M, но одно и то же соотношение можно получить с разными коэф-ами N и M. Например, пусть N/M = 1,5, тогда возможны следующие варианты пар N и M: (3,2), (6,4), (12,8) и т.д. При некоторых значениях N и M полученные коэф-ы будут попадать в заданные диапазоны, а в некоторых нет. Я строил график зависимости погрешности от M - для валидных значений он имеет пилообразную форму. В общем, коли кому не лень - пните в нужном направлении =)