RSS
people

Mazda MP3 Player — Продолжение 2

Ну что же, дорогие мои читатели. Вот вы и дождались продолжение нашего сериала о плеере  для Автомобиля Mazda.

Продолжим мы описанием прошивки для плейера и успеем еще послушать краткое описание протокола M-Bus, точнее того, что я смог найти в интернете, а так же того, чего сам видел на своей магнитоле.

И так, структура прошивки:

Блоксхема прошивки

При старте прошивки происходит обычная процедура инициализации всего микроконтроллера и сканирование дисков, что бы заполнить базу данных файлов информацией о том, где файлы находятся, их стартовые кластера и смещения в них, для быстрого доступа к файлам. Так же происходит поиск плейлистов в корневых папках дисков — это будут наши «диски» для Магнитолы.

Инициализация плеера и сканирование дисков

Для справки — прошивка на текущий момент  может переварить следующие «большие количества»:

  • Максимальное число файлов в одной папке — 496
  • Максимальное количество файлов на всех дисках вообще — 12412
  • Максимальное количество плейлистов *.M3U — 112
  • Максимальное количество файлов в одном плейлисте — 3276

Так вот.  База данных файлов это несколько банков памяти с информацией о расположении файлов на дисках.

Files Manager — это своего рода Интерфейс пользователя (HMI, MMI, GUI и т.д.). Т.е. наш плейер может не только в связке с автомагнитолой работать, но и как самостоятельный плеер, дайте только питание.

Естественно, менеджер файлов общается с модулем Button Driver, что бы знать, чего хочет от него пользователь, и общается так же с базой файлов, потому как на то он и менеджер файлов, показывать то ему надо что-то.

Так же с базой общается и другой модуль, Player Control. Этот модуль определяет, какой файл играть следующим, в зависимости от того, проигрывается сейчас какая-то папка, или же список всех файлов, или какой то плейлист. После определения того, какой файл играть, берет, значит, этот контроллер этот самый файл и скармливает его другому модулю - MP3 Playback Control.

Это  само сердце проигрывателя, т.е. он проигрывает какой-то конкретный файл. Управляется он через наш контроллер, а информацию о проигрывании дает как контроллеру, так и еще одному GUI — Player Frontend. Это окошко с кнопочками пауза, стоп, назад и вперед, регулятором громкости, ну и и с самой информацией о том, какой плейлист играет, какой файл, какой порядковый номер на рукаве, ой, по порядку, т.е. Заслушался я, прям, Цоя.

Ну и замое интересное — подключение к внешнему миру — Unilink Interface Module.

Но многие сейчас возразят, что мол, в Мазде же нету Unilink'а, тем более Sony, и будут правы! Нету там этого.

Но если вы внимательно читали предыдущие статейки на эту тему, то наверное заметили, что я там говорил, что этот плеер написан на основе уще существующей моей разработки для автомагнитолы Sony c протоколом Unilink.

Так вот, я, что бы не разбирать на запчасти работающую систему, и побыстрее запустить плеер, просто надстроил модуль M-Bus над Unilink'ом. И, надо сказать, довольно таки неплохо получилось, и с минимальными доработками можно этот же плейер запустить и на магнитоле Sony. Надо только подключить Unilink модуль, о котором я расскажу как нибудь в следующий раз.

И так, основные модули разглядели — начнем углубляться. И углубляться мы будем в протокол M-Bus. Потому как в самой прошивке опять же ничего особенного, много строчек кода и все.

Значит так. На вот этом сайте — http://mazda.davidoshea.homelinux.net/radio/ есть, в принципе, вся основная информация об электрических и временных параметрах шины. Данные передаются последовательно по одному проводу. Напряжение на шине от 0 до 5 вольт. Нули и единицы кодируются длинной «нулевого» импульса.

  • 0 — 0.5 — 0.6 милисекунд
  • 1 — 1.7 — 1.9 милисекунд
  • Длина одного бита — 2.9 — 3.0 милисекунды.

Там же описаны основные команды и параметры команд, которые бегают по шине.

В исходниках прошивки в файле MBus.c и MBus.h можно тоже найти куски кода, из которых можно выдрать информацию о том, какая команда и для чего служит. Но более полная информация пришла ко мне от уже упоминавшегося участника форума Mazda 3 с ником Slider. А именно — исходники проекта MBus Monitor. В этом проекте есть файл MBusProtocol.cpp, в котором есть вот такой вот кусок кода:

  1. static const tEntry aCodetable[] =
  2. {
  3.  { rPing, "58", "Ping" },
  4.  { cPingOK, "D8", "Ping OK" },
  5.  { cAck, "DF0000f", "Ack/Wait" }, // f0=0|1|6|7|9
  6.  { cPreparing,  "D9 1t ti im ms sf f0 f", "Preparing" }, //f0=0:normal, f0=4:repeat one, f0=8:repeat all
  7.  { cStopped,    "D92ttiimmssff0f", "Stopped" }, //f1=0:normal, f1=2:mix, f1=8:scan
  8.  { cPaused,     "D93ttiimmssff0f", "Paused" }, // f3=1: play mode, f3=2:paused mode, f3|=8: stopped
  9.  { cPlaying,    "D94ttiimmssff0f", "Playing" },
  10.  { cSpinup,     "D95ttiimmssff0f", "Spinup" },
  11.  { cForwarding, "D96ttiimmssff0f", "FF" },
  12.  { cReversing,  "D97ttiimmssff0f", "FR" },
  13.  { rPlay,    "51101", "Play" },
  14.  { rPause,   "51102", "Pause" },
  15.  { rStop,    "51140", "Stop" },
  16.  { rScnStop, "51150", "ScanStop" },
  17.  { rPlayFF,  "51105", "Play FF start" },
  18.  { rPlayFR,  "51109", "Play FR start" },
  19.  { rPauseFF, "51106", "Pause FF start" },
  20.  { rPauseFR, "5110A", "Pause FR start" },
  21.  { rResume,  "51181", "Play from current pos." },
  22.  { rResumeP, "51182", "Pause from current pos." },
  23. //  { rNextMix, "5130A314", "next random" },
  24. //  { rPrevMix, "5130B314", "previous random" },
  25.  { rSelect,  "513dttff", "Select" }, // f0=1:playing, f0=2:paused, f1=4:random
  26.  { rRepeatOff, "51400000", "Repeat Off" },
  27.  { rRepeatOne, "51440000", "Repeat One" },
  28.  { rRepeatAll, "51480000", "Repeat All" },
  29.  { rScan,      "51408000", "Scan" },
  30.  { rMix,       "51402000", "Mix" },
  31.  { cPwrUp, "DA0000000000", "some powerup?" },
  32.  { cLastInfo,  "DB0dttfff0f", "last played" }, // f0=0:done, f0=1:busy, f0=8:eject, //f1=4: repeat1, f1=8:repeat all, f2=2:mix
  33.  { cChanging4, "DB8d00fff0f", "Changing Phase 4" },
  34.  { cChanging,  "DB9dttfff0f", "Changing" },
  35.  { cNoMagzn,   "DBAd00f00ff", "No Magazin" },
  36.  { cChanging2, "DBBd00fff0f", "Changing Phase 2" },
  37.  { cChanging3, "DBCd00fff0f", "Changing Phase 3" },
  38.  { cChanging1, "DBDd00fff0f", "Changing Phase 1" },
  39.  { cStatus, "DCd01ttmmssf", "Disk Status" },
  40.  { cStat1, "DD000fffff", "some status?" },
  41.  { cStat2, "DE0000000", "some more status?" },
  42.  // also seen:
  43.  // 11191
  44. };

Эта таблица используется в программе для составления и посылки команд магнитоле. Нас же интересует не сам процесс посылки — о нем я расскажу чуть позже, а именно сами команды. В таблице они немного «закодированы», и в программе потом происходит их парсинг, и подставновка нужных параметров в замен латинских буков нижнего регистра.

Автор был настолько любезен, что оставил комментарии с описанием основных параметров. От себя лишь добавлю, что тут команды приведены без последнего полбайта с проверочной суммой, потому как ее надо считать для каждого конкретного случая.

Ок. Основные команды у нас есть. Теперь бы поглядеть, что происходит на самом деле на шине! Для таких особо любопытных читателей я снял логи с шины с помощью своего плеера и привожу их здесь.

Разберемся с ними.

Первым делом мы включаем магнитолу с помощью поворота ключа зажигания в положение ACC ON, и на шине происходит следующее (строки, начинающиеся с «MBus R» — это то, что плеер получает по шине, а те, что начинаются с «MBus S» — это то, что мы шлем сами на шину) :

  1. MBus R: |58E|
  2. MBus S: |D86|
  3. MBus R: |780|
  4. MBus R: |28B|
  5. MBus R: |59D|
  6. MBus S: |DB94000000C8|
  7. MBus S: |DD123456000000FC05|
  8. MBus S: |DC40000000006|
  9. MBus S: |D9000040000000CD|
  10. MBus R: |5110127|
  11. MBus S: |D9501040000000C9|
  12. MBus S: |DC401999999FC|
  13. MBus S: |D940104000000015|
  14. MBus S: |D940104000100015|
  15. MBus S: |D940104000200017|

«Голова» шлет всем пинг. Но он адресный. т.е. в первом полубайте стоит адрес получателя. Адрес нашего плеера 0×5. Адрес «головы» — 0xD. Итак, получив команду 0×58, мы отсылаем ответ 0xD8. Последний полубайт — это CRC (Строки 1 и 2).

Затем, если наш ответ на пинг был правильно понят «головой», то она нам когда нибудь пришлет команду Wake Up — 0×59. На что мы ей отвечаем набором из команд 0xDB94000000C, 0xDD123456000000FC0,  0xDC4000000000, 0xD9000040000000C (строки 5,6,7,8,9).

Смотрим, что они означают:

Команда 0xDB9, если смотреть на листинг таблицы команд вверху, означает Changing. Но как по мне, то мне так кажется — что это команда готовности. Потому как CD Changer, который встроенный в машину, тоже шлет такие команды, когда его играть попросят. И команда эта означает, что мы готовы играть диск с номером n, в нашем случае 4.

Далее, в команде 0xDD мы говорим, какие диски у нас есть (Строка 7). 123456 означает, что все диски на месте. По идее, эти цифры говорят «голове», какие диски вставлены в магазин, что бы зажечь соответсвтующий значек на дисплее. Я не пробовал выключить какой нибудь. Если кто попробует, отпишитесь в комментах. Я сам как нибудь тоже попробую.

Следующая команда 0xDC (Строка 8). Этой командой именно в этом месте мы говорим голове, что есть такой диск, но мы его пока что не играем, и как подтверждение этого факта шлем команду 0xD9 (Строка 9) в которой указан только номер диска 4.

После всех этих команд, если они посланы в правильной последовательности и с правильными промежутками времени, мы должны, по идее, получить от «головы» команду Play — 0×511012 (строка 10).

Как только мы ее получили — говорим голове, что мы «раскручиваемся», командой SpinUp — 0xD95aabb (строка 11), где aa — номер дорожки bb — номер диска.

Далее посредством команды 0xDC сообщаем параметры диска. В данном случае я говорю «голове», что у меня диск с номером 4 имеет номер первой дорожки, равный 1, последней — 99. Продолжительность диска — 99 минут 99 секунд.

И далее, раз в секунду, выдаю команду статуса 0xD94 с номером дорожки 1, номером диска 4, и временем проигрывания.

Все номера записаны в формате BCD, это означает, что, например в полубайтах времени, один полубайт может принимать максимальное значение — 9, а не 0xF, как мы привыкли.

Вот такие вот дела.

Пару слов о задержках. Между командами желательно делать задержки около 15-20 милисекунд. После приема команды от головы, которая требует ответа, необходимо так же выдержать те же 15-20 милисекунд перед ответом.

Ну и тут вот архивчик с логами с моего плеера. По названиям файлов, в принципе, понятно, когда и как они делались:

  1. 20090224213754_MBus_ACC_On.log — Последовательность команд после перевода ключа зажигания в АСС ON.
  2. 20090224213841_MBus_NextTrack.log —  Нажата кнопка — Следующая дорожка на магнитоле или на руле.
  3. 20090224213915_MBus_PrevTrack.log — Соответственно — Предыдущая дорожка.
  4. 20090224213946_MBus_NextDisk.log — Следующий диск
  5. 20090224214014_MBus_PrevDisk.log — Предыдущий диск
  6. 20090224214041_MBus_FF.log — Нажата кнопка перемотки вперед
  7. 20090224214119_MBus_REW.log — Перемотка назад
  8. 20090224214142_MBus_Rpt.log — Выбор режима повтора дорожки
  9. 20090224214210_MBus_Rpt_vsCDIn.log — Кнопка режима повтора во время проигрывания CD.
  10. 20090224214310_MBus_Rdm_vsCDIn.log — Кнопка выбора режима Случайной дорожки во время проигрывания CD.
  11. 20090224214348_MBus_FF_vsCDIbn.log — Кнопка перемотки вперед  во время проигрывания CD.
  12. 20090224214431_MBus_Rew_vsCDIn.log — и, соответственно, назад.
  13. 20090224214508_MBus_CDtoExt.log —  процес смены от проигрывания дисков к проигрыванию плеера, т.е. нажали кнопку CD еще раз.
  14. 20090224214542_MBus_ExttoCD.log —  процес смены от проигрывания плеера к проигрыванию диска, т.е. нажали кнопку CD еще раз.

Опишу некоторые моменты, точнее некоторые грабли, которые могут встретиться на пути покорения "головы"

И так —  если «голова» не поймет команду 0xDC, то клавиши смены дорожки не будут работать. Почему так? Для начала рассмотрим команду смены дорожки. В приниципе смена дорожки или диска запрашивается одной командой 0x513abb1, в которой указывается номер диска a, или номер дорожки bb, которые играть надо. Узнать, что именно запросили, довольно просто. Поскольку у нас все диски и дорожки нумеруются от 1, то то, что менять не надо, будет равно 0. И если «голова» не знает параметров диска, т.е. не была принята по какой то причине команда 0xDC, то при нажатии кнопок смены дорожки никаких команд слаться не будет.

Вот. Теперь самое интересное. Куда менять — определяем по номеру того, что нас просят сыграть. Т.е. в команде будет указан конкретный номер диска или дорожки.

Отсюда можно догадаться, что количество дисков ограничено 9-ю, а количество дорожек — 99-ю. Как быть? Ведь я в начале статьи писал количество плейлистов, которые у нас вытупают в качестве дисков для головы, там было что то около 112! Я особо долго не думал, и сделал просто — делю номер текущего плейлиста на максимальное количество дисков, которые переваривает голова, и прибавляю остаток — так получаем номер диска, который надо подсветить. То же самое делаю с номером файла, так как у нас намного больше файлов, чем 99.

Преимущества такого метода заключаются в том, что голова «думает», что мы играем какой то из дисков, А мы можем точно сказать, о каком номере думает «голова», и соответственно, когда прийдет команда на смену диска или дорожки, мы точно можем сказать, немного посчитав на калькуляторе, куда нам листать диски/дорожки, вперед или назад.

Еще одно преимущество такого метода перед многим известными  приставками XCarLink and Co. в том, что мы не ограничены 6ю дисками и не ограничены 99 файлами.

Есть, правда, один недостаток. Глядя на дисплей от магнитолы нельзя точно сказать, какой именно «диск» (читай, плейлист) играет, и какая именно дорожка в нем. Для этого можно будет глянуть на дисплей плеера — на него я вывожу название плейлиста, номер и название файла во время проигрывания.

Немного про кнопку режима повтора проигрывания ( к кнопке режима Случайной дорожки это тоже относится).

Когда я записывал логи, я сначала записал реакцию этой кнопки в момент, когда играл плеер. У меня пока нету никакой обработки этой кнопки, и после нажатия ее, «голова» выдала ее три раза с интервалом в 3 секунды. Я уже заметил, что если «голове» что то не нравится, она повторяет последнюю команду три раза.

Так было и тут: я записал нажатие этой кнопки в момент проигрывания CD, и увидел, что голова ожидала от меня изменения флага в команде статуса:

  1. MBus R: |E940802032600010|
  2. MBus R: |61440008|
  3. MBus R: |E94080203264001C|
  4. MBus R: |E95080200004001E|
  5. MBus R: |E94080200004001D|
  6. MBus R: |E94080200014001E|
  7. MBus R: |E94080200024001F|
  8. MBus R: |E940802000340010|
  9. MBus R: |E940802000440019|
  10. MBus R: |61400004|
  11. MBus R: |E94080200040001D|

Как вы видите из полубайтов времени (выделены жирным), песенка была уже почти спета, но тут мы нажали кнопку Repeat, и она пошла с начала, но уже один бит (подчеркнут) выдавался не так как раньше. Повторное нажатие привело к тому, что бит был сброшен. Вот именно этого бита и ожидала от моего плеера «голова», и я теперь знаю, что мне надо делать!

Примерно так же я определил, что делать при нажатии кнопки перемотки вперед.

  1. MBus R: |E940102003500018|
  2. MBus R: |E940102003600015|
  3. MBus R: |6110421|
  4. MBus R: |E960102003600008|
  5. MBus R: |E960102003700007|
  6. MBus R: |E96010200380000A|
  7. MBus R: |E960102003900009|
  8. MBus R: |E960102004100008|
  9. MBus R: |E960102004200005|
  10. MBus R: |E960102004400003|
  11. MBus R: |E96010200480000F|
  12. MBus R: |6110126|
  13. MBus R: |E960102005000008|
  14. MBus R: |E940102005300018|
  15. MBus R: |E940102005400011|

В данном случае клавиша перемотки была нажата и удерживалась некоторое время. Момент нажатия виден в строке 3. А отпустил я ее в строке 12. Между этими событиями от CD проигрывателя к голове шла команда 0xE96 и статус с быстро меняющимся временем.

Процесс смены проигрывателя, т.е. если играл CD и была нажата кнопка CD, то будет включен чейнджер, в нашем случае наш плеер, и на оборот можно посмотреть в логах.

Еще одно замечание. Если какие то команды шлются не в свое время, или с большой задержкой, то «голова» постоянно норовит отключить аудио вход. Когда я разбирался с задержками, я еще не знал, что их надо слать именно через 15, максимум 20 мс. И слал их примерно через 100 мс, так «голова» не понимала мою команду конфигурации диска, и отключала кнопки перемотки дорожек. Я все думал, в чем же дело и решил попробовать послать эту команду два раза подряд. Так вот — это «голове» категорически не нравилось и она, сначала включив аудиовход, тут же его выключала, но потом, видя, что вроде процесс шел нормально, включала снова.

Но сейчас такого уже не наблюдается.

Ну и для затравки пара фоток того, как выглядит дисплей с включенным входом от чейнджера. Здесть надо сказать «Та Даааа!»:

Аудиовход Чейнджера активирован!

Аудиовход Чейнджера активирован!

А вон там вон в коробочке живет мой плеер. Корпуса пока что нету.

Плеер в коробочке

Плеер в процессе

Где то в статье я обещался рассказать про то, каким образом мы в программе посылаем команды, и каким — принимаем. Об этом в следующий раз, а то тут довольно много текста получилось. Немного терпения!

Напоследок список файлов, описанных в статье:

4 комментария к “Mazda MP3 Player — Продолжение 2”

  1. kindrat пишет:

    Небольшой вопрос по M-BUS'у. Решил себе спаять переходник с M-BUS на iPhone для цивика (там родная магнитола Alpine с M-BUS). M-BUS по идее однопроводной, но в разъеме чейнджера два контакта — Tx+ Tx- . По идее, тот что минус должен быть землей, но он с землей не связан. Если мерить мультиметром, то при подаче питания на магнитолу на Тх+ и Тх- по 2 вольта относительно земли, если подать еще 12 вольт на контакт «АСС» в разъеме чейнджера, то на Тх+ Тх- по 4 с мелочью вольта. Пробовал подсоединять к ком-порту (подключал Тх- на землю, Тх+ на UART ардуины) — тишина, даже мусора никакого не ловится... Куда копать чтоб оживить выход чейнджера?

    Сейчас вот думаю купить мегу 128-ю, спаять логический анализатор и им поглядеть.

    P.S. Распиновка магнитолы s15.radikal.ru/i189/1005/25/c8581e926d06.gif

  2. MasterAlexei пишет:

    Я тут с коллегой посоветовался и мы думаем, что это все же дифференциальный вход/выход.

    Чего с ним делать, таже не представляю. Вам надо посмотреть именно осциллографом на него. Мультиметр все импульсы просто сглаживает.

    Так что — осциллограф — наше все :)

  3. kindrat пишет:

    Осцилографа, к сожалению, нет :( А логический анализатор тут не поможет?

  4. MasterAlexei пишет:

    Теоретически — ЛогАнализатор поможет. Практически — нужно знать, сколько вольт там у сигнала логические уровни (простой вольтметр этого НЕ покажет).

    Потому что, например, у мазды там логическая 1 — 12 вольт. Так что там скорее всего делитель надо сделать вам. Ну и посмотреть оба сигнала TX+ TX- относительно земли. Скорее всего на один из них будет инвертирован относительно другого.

Оставить комментарий или два

Пожалуйста, зарегистрируйтесь для комментирования.