‮Сдвиг по фазе (kincajou) wrote,
‮Сдвиг по фазе
kincajou

worklog: AC'97

Несмотря на то, что этот стандарт придумал Intel, он понятно описан и довольно таки прост для реализации (во всяком случае, на низком уровне). Я, конечно, только начал его реализовывать и наверняка впереди будет масса неприятных неожиданностей, но всё равно он мне нравится даже больше, чем I2S (хотя бы потому, что для управления кодеком и передачи аудиоданных используется одна и та же шина, а не две разных!).

Совершил уже два открытия, как раз из разряда не самых ожидаемых:
1) кодек CS4202 на холостом ходу кушает почти 50мА. С другой стороны, там же усилитель для наушников. Причём, скорее всего, никакой не D-класс -- а значит, ток холостого хода "вынь да полож". Впрочем, не исключаю какой-то баг в схеме или на плате.
2) в ПЛИС надо было заводить сигнал AC97_BCLK не на первый попавшийся пин, а на тот, через который можно заводить тактовую частоту (там внутри есть специальные выделенные буферы, разводящие высокоскоростные клоки по кристаллу.. у "general purpose" пинов таких буферов нет). Впрочем, оно даже так работает - щас накидал простейший скелетик будущего модуля, принимает BCLK (12,288МГц) и выводит из него фреймовый синхросигнал 48кГц. Перебрасывать данные между системой и кодеком придётся через ресинхронизатор, иначе никак.

Upd скелетик оброс регистрами. Я уже могу записать команды в кодек! Процесс, вкратце, выглядит так:

1) микроконтроллер формирует управляющую посылку для блока управления, реализованного в ПЛИС. Протокол простейший: сначала шлём 8 бит, определяющий направление данных, затем 24 бит адрес регистра и далее либо пишем, либо читаем 16 бит данных.
2) Внутри ПЛИС эти биты раскидываются по системной шине, конечный автомат дёргает строб готовности данных и, учуяв его, к шине адреса подключается дешифратор адреса.
3) Если дешифратор "сработал", т.е. в его таблице есть совпадение с указанным адресом, к шине данных подключается соответствующий регистр - либо он выдаёт содержимое (если мы читаем), либо принимает (если пишем). Всё просто.
4) Чтобы передать команду в кодек, нужно пройти по нескольким стадиям преобразования данных:
4а) сначала от микроконтроллера получаем ИНДЕКС команды; он содержит адрес какого-либо внутреннего регистра кодека. Взводится флажок "Индекс принят"
4б) затем получаем ДАННЫЕ команды (если пишем.. чтение из кодека я пока не реализовал). Взводится флажок "Данные приняты". Так сделано потому, что это две разные, разнесённые во времени, транзакции. Впрочем, регистры находятся один за другим и можно воспользоваться автоинкрементом индекса (пока я не полностью уверен, что он работает).
4в) оба этих флажка проходят через синхронизатор и переносятся из домена 100МГц (системная частота) в домен 12,288 МГц (частота интерфейса AC'97). Отдельный процесс получает эти флажки и, если они оба взведены (кодек требует "атомарную передачу", индекс должен идти только вместе с данными... логично, чо уж), переносит данные из регистров системы в свои внутренние переменные, для последующих преобразований.
4г) контроллер AC'97 дожидается начала следующего кадра и записывает в сдвиговый регистр тэг-слот, в котором уже взведены флаги "Слот 1 готов" и "Слот 2 готов" (индекс и данные, соответственно) и флаг "Фрейм готов".
4д) тэг-слот выщёлкивается бит за битом и, когда его последний бит уже в пути, в сдвиговый регистр закладывается содержимое ИНДЕКС... когда он ушёл, тогда закладывается новое значение ДАННЫЕ и, наконец, сбрасываются оба вышеупомянутых флажка (т.к. нет никакого смысла пересылать эту команду снова и снова).
4е) фрейм полностью передан, начинается новый цикл...

Всё это крутится по кругу, синхронизируется (только на запись и только команд, до аудиоданных и до чтения чего-либо я пока ещё не дошёл) между двумя некратными тактовыми частотами и даже кое-что полезное делает: я убедился в этом, записав хитрую константу 0x800F по хитрому индексу 0x26 -- это регистр управления питанием кодека (и я этой константой включил пин разрешения работы внешнего усилителя). Пин в самом деле установился в высокий уровень. Записав 0x000F, я этот пин выключил. Реакция совершенно та самая, что мне нужна.

Вывод: интерфейс, несмотря на зачаточную стадию своего развития, уже работает!

Учитывая, что я полный профан и дилетант в области HDL-дизайна и пишу на VHDL "со словарём", даже этот скромный результат -- уже поразительный :)
Tags: радио
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 3 comments