Как работает кнопка Mute на Яндекс Станции. Подробный разбор логики и схем

feadc99a12bd2a32121d676433f11c6d.png

Привет! На связи Геннадий «Крэйл» Круглов из команды, которая разрабатывает аппаратную часть Яндекс Станций. С кем-то из читателей Хабра мы уже могли познакомиться в рамках мероприятий Я.Железа, где делимся опытом разработки устройств.  

Последние несколько лет мы с командой вынашивали идею публичного рассказа об устройстве отдельной взятой части наших умных колонок — кнопки Mute. Эта тема вызывает живой интерес, поскольку напрямую касается приватности. Мы часто говорили о том, что Mute отключает микрофоны физически, но как именно это происходит — не рассказывали. В итоге вопросы копились, но руки, как это обычно бывает, до статьи не доходили. Пожалуй, вернём сегодня этот должок. 

В этом посте мы расскажем о нашем основном решении для кнопки Mute. Вы увидите, что у процессора устройства нет физической возможности управлять питанием микрофонов, а значит, обойти кнопку программным способом невозможно. Мы опубликуем схемы и расскажем, как они работают. Сначала на языке, который поймут коллеги-инженеры. В конце — резюмируем простыми словами для всех. Надеюсь, будет интересно и полезно. 

Начнём с простого. Почему кнопка, а не хардкорный рубильник, размыкающий цепь питания? Ответ на поверхности. Кнопка в среднем надёжнее механически и лучше защищена от грязи и пыли. Кроме того, на большинстве наших Станций кнопка Mute выполняет ещё одну дополнительную функцию: если зажать её дольше пяти секунд, то настройки Станции сбрасываются. Ну и в дизайн устройства кнопка вписывается, конечно же, легче.  

Идём дальше. Кнопка — это механический компонент. Главный вопрос: что делать с её сигналом? Проще и удобнее завести этот сигнал на процессор или микроконтроллер: он сможет отслеживать длительность нажатия, по короткому переключать состояние Mute, а по длинному — сбрасывать настройки. Но тогда поведение колонки в смысле отключения микрофонов будет зависеть от прошивки. Чтобы доказать, что у нас нет возможности менять поведение кнопки Mute, управление микрофонами реализовано без использования процессора/контроллера, на примитивных компонентах. Поэтому схема работы кнопки такая сложная. Если бы не эта необходимость, схема была бы проще в десятки раз, микрофоны всегда работали, а процессор просто не использовал их сигнал в режиме Mute.  

Чтобы наш рассказ был более предметным, рассмотрим логику работы кнопки на примере наиболее популярных современных моделей Яндекс Станций. 

Станция Миди (2023) 

Начнём с одной из самых популярных новинок прошлого года. Схема обвязки кнопки Mute на Станции Миди выглядит так:  

2e85863b2ae19281a2aeff72af8a79fa.png

Кстати, эта схема была опробована ещё в обновлённой Станции Мини (2021).  

Прежде чем двигаться дальше, давайте вспомним таблицу истинности триггера:  

4d811a8805472d91e9c2b44802ae7f55.png

Это скриншот из даташита. Строки первая и третья у нас не сработают, поскольку вход #PRE безальтернативно подтянут к питанию. 

При включении питания конденсатор C249 разряжен, на затворах VT6, VT7, VT8 — ноль, поэтому:  

  • VT6 закрыт, на линии MUTE_BUTTON логическая 1. 

  • VT7 открыт, VT8 закрыт, так что заряжается батарея конденсаторов C250, C252, C254. 

Далее через резистор R125 заряжается конденсатор C249. Он зарядится за время T = RC = 100к × 0,22 мкФ = 22 мс. После этого:  

  • Открывается транзистор VT6 и подаёт 0 на линию MUTE_BUTTON.  

  • Закрывается транзистор VT7, прекращается зарядка батареи конденсаторов. 

  • Открывается транзистор VT8 и разряжает батарею конденсаторов. 

  • После разрядки батареи конденсаторов закрывается транзистор VT9, через R130 начинает заряжаться конденсатор C253. 

Таким образом, на входе #CLR-триггера какое-то время присутствует 0, и триггер сбрасывается: на выходе Q появляется 0 (поскольку #PRE всегда 1), на выходе #Q — 1. На входе D через 10 мс (R131 = 100k, C255 = 0,1 мкФ => T = RC = 10 мс) появится 1. Но вход CLK остаётся в 0, поэтому триггер не переключится. Чуть ниже по тексту для наглядности приведён график переключений. 

 На линии MICENR (выход Q) присутствует 0, поэтому MUTE_STATE будет 1, а на MLED — 0. 

При нажатии кнопки Mute заряд перераспределяется между заряженным C249 и разряженным C251: поскольку ёмкость первого больше, на линии CLK появляется логическая 1. Она там ненадолго: конденсаторы разряжаются через R129 и разрядятся примерно за 0,3 мс. 

Таким образом, на вход CLK будет подан короткий единичный импульс. Поскольку на входе D логическая 1, то триггер переключится: на Q появится 1, а на #Q — 0. Через 10 мс 0 с выхода #Q окажется на входе D, но это ничего не изменит, поскольку опять же нет фронта на входе CLK. На линии MIC_EN_R появится 1, на MUTE_STATE — 0, а на MLED — 1. 

Вернёмся к левой части схемы. После того как конденсаторы C249+C251 будут разряжены:   

  • Закрывается транзистор VT6, на линию MUTE_BUTTON подаётся 1. 

  • Закрывается транзистор VT8, прекращается разрядка батареи конденсаторов. 

  • Открывается транзистор VT7, начинается зарядка батареи конденсаторов. 

Если кнопку держать дольше, то за это время успеет зарядиться батарея конденсаторов. Расчётное время зарядки до напряжения 0,7 от напряжения питания — 15 с (T = RC = (1 М + 100 к) × (4,7 мкФ × 3)). Однако в реальности транзистор откроется при меньшем напряжении, поэтому задержка тоже будет меньше — порядка 5 с. 

Транзистор VT9 откроется, на входе #CLR появится 0, и триггер сбросится в исходное состояние с Q = 0 и #Q = 1. Соответствующие выходные цепи тоже вернутся в начало. Если же кнопку отпустить раньше, то батарея конденсаторов не успеет зарядиться. Через 22 мс после отпускания кнопки зарядится конденсатор C249, и тогда:  

  • На линии MUTE_BUTTON снова окажется 0. 

  • Батарея конденсаторов снова будет разряжена. 

  • Состояние линий MUTE_STATE и MLED не изменится. 

При следующем нажатии кнопки на входе CLK снова появится единичный импульс, но на этот раз на входе D будет уже 0. Таким образом, триггер снова переключится: на Q появится 0, а на #Q — 1. Линии MUTE_STATE и MLED изменят своё состояние соответственно. 

Покажем переключения на графике:  

18be7c73b3c0866de4ff662735ae8ad5.png

Очевидно, что процессор не участвует в переключении состояния MUTE и никак не может повлиять на работу кнопки. 

Давайте посмотрим, куда идут выходные линии. MUTE_BUTTON и MUTE_STATE идут на GPIO процессора. Это подключение нужно, чтобы софт мог понять, в каком состоянии находится кнопка, и в каком — подсистема микрофонов. Это нужно, например, чтобы при долгом нажатии начать процесс возврата к заводским настройкам. 

Посмотрим на верхнеуровневую схему:  

4abef15f29973bffbed193a1fa4aa187.png

Ныряем глубже, внутрь квадратика справа внизу:  

9f7d5e78fcb5aebc681c9554e5f00e87.png

И ещё глубже:  

961378dcfa1f3b30b2ea770cb68bd3e0.png

GPIO процессора подключены к стокам транзисторов. Даже если эти GPIO переключить в режим выхода, подача логических сигналов на линии MUTE_BUTTON и MUTE_STATE не в состоянии переключить схему. 

Теперь проследим путь линии MLED. Нырнём в верхний правый квадратик верхнеуровневой схемы:  

e18894e6c09db2893d2655615df61ea4.png

Разъём X5 соединяет основную плату и плату микрофонов. 

Вот плата микрофонов:  

98ff4501753e7a392313d976f9a4aaf2.png

Сначала заглянем в квадратик Connector:  

5ce287ff1c73200d132bfceef95b0e6a.png

При 0 на MUTE_EN транзистор VT2 будет открыт, подавая питание +VDD_MIC, а при 1 — закрыт, и питание будет выключено. На верхнеуровневой схеме видно, что питание микрофонов идёт именно по цепи +VDD_MIC / +3V3_MIC. 

Заглянем в квадратик Mics.SchDoc, просто чтобы не оставлять белых пятен:  

3f9edef57cae6bc313df63d5bca21d4b.png

А теперь — в квадратик LED_Driver_Alice.SchDoc:  

760d1841395abc6dac4b3f8d7d7f9f1e.png

Тут видно, что при 1 на MUTE_EN транзистор открыт и включены красные каналы светодиодов.  

Станция 2 (2022) 

Схема обвязки кнопки в Станции 2 повторяет схему из Станции Миди, так что не будем на ней останавливаться:  

b8086fd73af19f6f0678642bc5f53ce3.png

Линии MHWEN и MSWDET подключены к GPIO процессора (опять же, процессор не в состоянии повлиять ими на схему переключения). А управляющий сигнал MLED поступает на плату микрофонов через шлейф. 

Посмотрим на схему подсистемы микрофонов. Сначала общий вид:  

413f8dd25b2c20106cd2f3c1cc0756de.png

Теперь схема подключения разъёма:  

697685ade0d3e79c732ad82c689ecb12.png

Посмотрим на схемы микрофона и светодиодов:  

908a161b61177f831f6ccf010ca6aeee.pngaa4ac68ba6758e4b198d32bba21b6f2d.png

В правой части расположен транзистор VT1, который включает красные каналы светодиодов при логической 1 на затворе.  

Как и написано: при логической 1 на MLED светодиоды светятся, а питание микрофонов отключено. И наоборот. 

Станция Макс (2020) 

Тут схема триггера проще, поскольку у Станции Макс есть две кнопки и нет необходимости использовать кнопку MUTE для сброса к заводским настройкам. 

aa69cb586df4a12d00945262edd2d362.png

При включении питания:  

  • Конденсатор C18 заряжается через R16. 

  • Конденсатор C17 заряжается через R20 за T = RC = 1 мкФ × 100 к = 100 мс. Триггер сбрасывается: на выходе Q появляется 0, а на #Q — 1.  

  • Конденсатор C28 заряжается через R15 за T = RC = 0,1 мкФ × 100 к = 10 мс, и на входе D появляется логическая 1. 

При нажатии на кнопку конденсатор C18 разряжается через R2 за T = RC = 0,1 мкФ × 1 к = 0,1 мс. На вход CLK подаётся единичный импульс. Поскольку на входе D — логическая 1, триггер переключается: на выходе Q появляется 1, а на #Q — 0. Через 10 мс на входе D появляется логический 0 с выхода #Q. 

При отпускании кнопки конденсатор C18 зарядится через 10 мс, так что повторно кнопку следует нажимать не раньше:) 

При повторном нажатии триггер снова переключится и сигналы MIC_EN и #MIC_EN поменяют свой уровень. 

Заметим, что светодиоды VD1 и VD2 горят, когда на #MIC_EN присутствует высокий уровень, а на MIC_EN — низкий. 

Сигнал MIC_EN подведён к разъёму, откуда далее идёт на GPIO процессора. Больше он нигде не используется. Процессор, даже переведя GPIO в режим выхода, не может никак переключить схему: триггер переключается только по CLK, а на него сигнал может подать только кнопка. 

dc342468b74ddd881ae7d7accd2eb918.png

Для управления микрофонами используется сигнал #MIC_EN:  

5693846622bd307d2a3213f6351f70e9.png

Здесь при логической 1 на #MIC_EN (микрофоны выключены) выключено питание микрофонов, а также запрещена работа буферов DD1 и DD2, которые подают тактирование на микрофоны:  

4f639b7234152697ca1826a144e6b97b.png

Так что тут отключены и питание, и тактирование. 

Итоги — простыми словами 

Итак, нажатие кнопки Mute отключает микрофоны без участия процессора и программного обеспечения: у них отключается питание, они перестают работать. Включить микрофоны обратно можно либо по кнопке Mute, либо через сброс питания всего устройства (грубо говоря, если выдернуть БП из розетки и воткнуть обратно). У процессора нет физической возможности управлять питанием микрофонов. Мы осознанно пошли на создание такой сложной схемы, чтобы добиться этого эффекта.  

Описанные в статье решения применяются в наших колонках уже несколько лет, ими пользуются миллионы пользователей. Мы считаем такие масштабы хорошим бенчмарком. Тем не менее понимаем, что идеальных решений не бывает. И поэтому хотим напомнить, что Яндекс Станции участвуют в «Охоте за ошибками». Недавно мы подняли максимальную сумму вознаграждения за найденные в устройствах уязвимости до миллиона рублей. Верим, что это поможет проверить устройства с Алисой на прочность и сделать их ещё надёжнее. 

© Habrahabr.ru