Для того, чтобы эффективно разрабатывать под Flipper, надо не только понимать, как писать код, но и понимать, что внутри у него.
На «больших» компьютерах есть куча уровней абстракции и аппаратных средств сделать жизнь пользователя и разработчика проще. В итоге, даже если вы пишете на голом си, вас все равно не волнует как конкретно по PCI передается информация, как работает система питания процессора и какая там микросхема используется для хранения BIOS/UEFI.
Тут все не так, слишком уж близко к железу происходит разработка. Статья — это краткий экскурс в то, как устроен Flipper с железной точки зрения. Поехали.
Для начала, давайте его разберем. В принципе, разборка довольно проста, сильно проще, чем некоторые ноутбуки. Но некоторые тонкости все же есть.
Для начала, стоит вытащить microSD-карту и отключить флиппер (Settings-Power-Power OFF-OFF):
Первое действие напрашивается само собой — 4 винта сзади (красные пометки, 1). Тут подстерегает первая тонкость — нужна длинная отвертка, глубина залегания винтов — примерно 12мм.
После выкручивания винтов настает черед двух защелок — в местах, отмеченных синими стрелками, 2. Они легко отщелкиваются, если ногтем расширить щель между половинками корпуса. Главное не перестараться — пины для iButton (зеленое, 3) проходят внутри длинной трубки в задней половинке корпуса для защиты от механического воздействия вбок, но ей же очень удобно их и выломать, если поднять с сильным перекосом. Поэтому отщелкиваем защелки по одной и снимаем вертикально вверх половинку. Бояться не надо, оно не настолько хрупкое, как вам сейчас представилось, но и поднимать под 90° половинку со стороны USB-разъёма тоже не стоит.
Откладываем половинку в сторону. Там расположены две антенны, 125kHz и 13MHz RFID, но плата с ними приклеена к корпусу, и посмотреть на них не удастся.
Зато у нас есть другая половинка:
Для дальнейшего разбора — отщелкиваем узкий шлейф:
Выкручиваем один утопленный винт:
И второй, крепящий маленькую плату плату с пружинными пинами:
Теперь ее можно достать:
На ней: три IR-светодиода, один IR-приемник, iButton-пины:
И динамик:
Ну и некоторое количество обвязки, куда же без нее.
Теперь, когда плата больше не мешает, можно выкрутить еще один винт:
И вытащить основной модуль из второй половинки корпуса (вот тут пригодится заранее вытащенная microSD-карта, если ее не вытащить, на этом шаге она будет мешать):
Кстати, разработчики флиппера — обманщики. Я был уверен, что вокруг отверстий GPIO — корпуса самих гнезд PBS:
А оказывается, это просто их имитация в пластике корпуса.
Еще на этой половинке — окошко с IR-фильтром. В отличии от стекла экрана закреплено не УЗ-сваркой, а просто на плавящемся пине:
Разбираем дальше внутренний модуль. Для этого отсоединяем оставшийся шлейф:
И теперь надо освободить плату из защелок. В принципе, ее можно и не доставать, дальнейшей разборке она не мешает, но если уж начал, остановиться трудно.
Сдвигаем плату по направлению к нижним защелкам, а затем поднимаем плату «наверх» (перпендикулярно модулю) в точке один, освобождая ее от одной защелки, и сдвигаем в точке два по направлению к верхним защелкам, освобождая нижние.
Теперь так же, сдвигая плату вниз (точка три), освобождаем верхнюю защелку и вытаскиваем (точка 4) из боковой защелки. Оп, плата свободна:
Кстати, оцените, что для уменьшения толщины в пластике сделаны отверстия под наиболее высокие компоненты:
Кстати, одно из отверстий осталось, судя по всему, от предыдущего дизайна платы — напротив него на плате пустота. Спросил разработчиков, так и оказалось. Более того, операционников два тоже поэтому — когда возникла нужда переделать схемотехнику этой части, механика уже была зафиксирована и пресс-форму переделывать уже было нельзя, поэтому любые изменения в схемотехнике приходилось согласовывать с корпусом. Вот тут проще было поставить счетверенный ОУ, но не получилось, пришлось ставить два двойных.
Продолжаем разбирать оставшуюся часть. Вот этот винт так и просится быть открученным для дальнейшей разборки, но это не так: он просто крепит оранжевую деталь
Кстати, оцените, какая красота:
Эта деталька одновременно держалка ремешка и направляющая для карты памяти, одной деталькой, чтобы меньше делать пресс-форм.
В общем, пусть шуруп вас не обманывает и остается там, где был. Для дальнейшего не нужна отвертка, достаточно просто раскрыть две половинки внутреннего модуля как книжку, со стороны GPIO. Там небольшая защелка (синяя стрелка), но ее сломать сложно.
Разделиться частям мешает провод к батарее, его надо отключить:
Осторожнее со шлейфом, его надо аккуратно вытащить через отверстие в корпусе.
И у нас две половинки:
Давайте отсоединим шлейф (запоминайте, как он установлен, ничего вам не помешает вставить его потом вверх ногами и удивляться, почему не работает):
Кстати, помните маленькую плату? Которая с пинами для домофона. Я сначала подумал, что там какой-то мусор прилип к плате. А потом присмотрелся:
И знаете, что? Нифига это не мусор. Это крохотный TVS-диод для защиты от статики в корпусе WLCSP — Wafer Level Chip Scale Package. То есть, это самая натуральная кремниевая вафля, нарезанная на отдельные компоненты и напаянная прям так на плату, без корпуса.
На основной плате тоже такие есть:
Я даже специально пошел на кухню, нашел спичку и положил рядом. Мне кажется, штук 50 по объёму в спичечную головку поместится.
Продолжаем разбирать. Отсоединяем пластиковую накладку с клавиатурой от основной платы.
Для этого выкручиваем два винта (синие), и разделяя со стороны USB-разъёма, освобождаем защелку (красная)
Рассматриваем сложную конструкцию клавиатуры:
О, дельфинчик. Вместо глазика — дырочка.
Хотя на самом деле там дырочка не просто так, а для штифта:
Но в таком виде его почти никто и почти никогда не видит, потому что это штифт от рамки, на которой крепится аккумулятор, а когда вы снимаете накладку с клавиатурой, рамка с аккумулятором уже снята.
Отдельное спасибо тому конструктору, который использовал во флиппере всего два типоразмера винтов: длинные и короткие. Короткие используются при прикручивании рамки с клавиатурой к плате, для крепления оранжевой детали и платы с IR и iButton:
В целом, все, мы разобрали флиппер:
Однако, не сильно продвинулись в понимании того, из чего он состоит. Давайте это исправим.
В процессе ковыряния в даташитах и задавания вопросов разработчикам, нарисовалась вот такая схема:
Она страшная и непонятная, но это только на первый взгляд. Давайте рассматривать ее внимательно и с комментариями.
Для начала, есть основной микроконтроллер, на котором строится устройство, STM32WB55.
У него есть два ядра. Одно основное, Cortex M4, FPU, до 64 MHz, даже MPU есть (MMU нет конечно), 219.48 баллов CoreMark. Для сравнения, у любимой ардуинщиками ATmega2560 — 4.25 баллов, у ESP8266 — 191 балла. Впрочем, в embedded пузомерки едва ли играют хоть какую-то роль, выбор идет скорее по периферии, режимам сна и потреблению в них, цене и в новых реалиях — по наличию на складах. А чистая способность процессора пережевывать числа пригождается редко.
Второе ядро — Cortex M0+, но в целом, всем абсолютно было бы безразлично, если оно было M1, M2, M-1, M√(-1), потому что разработчик к нему доступа не имеет. Ядро целиком отдано под управление радио-стеком, и все что может сделать разработчик — это загрузить туда одну из нескольких версий бинарника, отличающимися разными фичами, отправлять туда команды, пересылать и принимать данные для радио.
Бинарники есть разные: BLE peripheral, BLE central, BLE peripheral+central, Thread, Zigbee, чистый 802.15.4, BLE+Zigbee, BLE+Thread, BLE+802.15.4, и так далее. Недавно вот перешли с BLE peripheral+central на BLE peripheral ради экономии памяти, но теперь флиппер не умеет подключаться к другим устройствам как мастер, только как ведомое. Впрочем, задач, в которых к нему надо подключить BLE-клавиатуру, было, скажем прямо, мало.
Занимательный факт: ST именует бинари для второго ядра как «copro», и что самое страшное, разработчики с этим соглашаются. Бинарники зашифрованы, и расшифровываются загрузчиком непосредственно на чипе. Поэтому ловля в них багов — очень увлекательная вещь. Например, одна из предыдущих версий бинарника при определенных условиях и долгой работе выжигала что-то в тракте BLE, в самом кремнии, от чего он переставал работать на прием. После капанья на мозги ST они признали баг и выпустили апдейт. И таких ситуаций, мелких и не очень — вагон за все время разработки.
Во многом это еще происходит потому, что контроллер новый, и пустая страница ERRATA вовсе не означает, что ошибок нет, она означает, что заполнять ее будут первые пользователи.
С процессором разобрались, идем дальше. Питание. О, питание это сложно!
У нас есть разъем, с которого приходит 5в, у нас есть аккумулятор, который выдает 2.8-4.2в и контроллеры, которые хотят не больше 3.3в.
В общем, есть bq25896 — контроллер зарядки батареи, который умеет ее заряжать. Он же умеет делать из напряжения батареи 5в (в основном для того, чтобы питать другие устройства через тот же USB, типа, как работает в телефонах: вставили зарядку, заряжается, вставили клавиатуру/флешку/мышку — на нее подалось 5в и она начала работать). Разработчики решили не делать из флиппера повербанк, но зато сделали из этой фичи управляемые 5в на гребенке. Управляемые они условно, потому что при подключении флиппера по USB они там все равно появятся, хотите вы того или нет. Но зато при питании от аккумулятора, их можно отключать.
Этот самый bq25896 управляется по I2C, и может включать-выключать свой Step-Up по желанию пользователя.
Идеальный диод, указанный на схеме — это конструкция из мосфета, которая ведет себя как диод, но в отличии от него, не просаживает на себе пол-вольта. Вот он:
В устройстве это выглядит вот так:
Большой мосфет и два транзистора в одном корпусе ниже.
Еще у bq25896 есть забавная фича — shipping mode.
На кнопку «назад» повешен не только GPIO процессора, но и один из контактов bq25896, который запускает его из выключенного состояния. Т.е. на фабрике в контроллер заливается прошивка, делаются необходимые тесты, потом контроллер совершает харакири — просит bq25896 выключиться, тот выключается и обрубает контроллеру питание (кроме RTC, про это чуть ниже), и теперь устройство может очень долго лежать в коробочке, не тратя заряд, тот самый shipping mode (когда в начале статьи мы делали Settings-Power-Power OFF-OFF, то это как раз оно). Но по долгому нажатию (~1с) кнопки «назад» bq25896 просыпается и включает устройство. А по очень долгому (~15с) он перезагружает весь девайс по питанию. У процессора есть, конечно, способ ресета (и программного, и аппаратного), но долгое нажатие — это способ перезагрузить вообще ВСЕ, все равно что аккумулятор отсоединить.
Кроме bq25896 (Charger) есть еще bq27220 (Gauge). Т.е. измеритель.
У него есть шунт, он считает ток, напряжение, процент заряда, циклы зарядки, живость батареи и так далее.
Подключается так же, по I2C и отдает это контроллеру.
Вот этот экран в Setting-Power-Info — это и есть данные с гаужа.
Несмотря на то, что измеряет он батарею, в отличии от контроллера зарядки питается он не от нее, а от общей линии 3.3 (про нее будет ниже), так что при отключенном устройстве ничего не потребляет.
Вот он, на плате, рядом с шунтом, который раз в восемь его больше:
В части измерения заряда, его, конечно можно заменить, на ADC микроконтроллера, который измеряет напряжение батареи. Но лишнего ADC, по словам разработчиков, не было, поэтому было решено поставить гаудж.
Вот кусочек гербера, на котором видно, как подключен шунт — по четырехпроводной схеме, которую еще называют «схемой кельвина».
Это делается для того, чтобы падение напряжение на проводниках к сопротивлению не прибавлялось к падению напряжения на самом сопротивлении. Особенно важно это, когда сопротивление измерительного шунта сравнимо с сопротивлением проводников на печатной плате.
Вот, например, как рекомендуют разводить шунты:
Еще от батареи напрямую запитан RS3221 — это малопотребляющий линейный регулятор, который делает 3.3в для работы RTC основного контроллера.
RTC потребляет крайне мало, поэтому потери на линейном стабилизаторе некритичны, но зато часы флиппера не сбиваются при отключении питания и пока он едет в посылке к пользователю.
Теперь про все остальное. Дальше идут устройства, которые хотят не более 3.3в, поэтому для них есть два DC-DC стабилизатора, LM3281. На одном стабилизаторе висят 3.3в на гребенке и SD-карта, на втором — все остальное: bq27220 (Gauge), lp5562 (драйвер светодиода и подсветки экрана), ST25R3916 (NFC), CC1101 (трансивер SubGhz), FAN48610 (DC-DC для RFID и NFC), и собственно STM32WB55
Стабилизаторы эти Step-Down, поэтому при понижении напряжения на батарее ниже 3.3, на этих шинах будет напряжение батареи, а не 3.3, т.е. до 2.8в.
Два стабилизатора потому что SD-карта. Она, во-первых, по-хорошему требует управления питанием при инициализации, а во-вторых, оказалось, что есть экземпляры, которые могут невзначай просадить питание и повесить или перезагрузить процессор, если будет на основной шине. Ну и 3.3 на доступных пользователю контактах по той же причине — если он подключит что-то сильно потребляющее, и напряжение просядет, не дело вешать пол-устройства. А еще
Кстати, по этой же причине, при вставке карты, на 3.3в пине гребенки может кратковременно пропадать напряжение — вместо отдельного транзистора для SD, процессор управляет входом ENABLE самого стабилизатора периферийной шины.
От батареи напрямую питается динамик (чтобы был громче, чтобы не шумел на основной линии питания и не нагружал DC-DC), IR-светодиоды и вибромотор (по тем же причинам), IR-приемник (TSOP753) (потому что ему пофиг, он 2.5-5.5 V, а разводить удобнее):
Еще есть один DC-DC (FAN48610), на этот раз повышающий:
Он повышает 3.3 до 5в, и отдает эти 5в на антенны NFC и RFID. Передатчик RFID — это просто ключ, которым дергает процессор, а у ST25R3916 есть специальный вход для напряжения питания передатчика. Смысл в том, чтобы повысить напряженность поля и дальность работы.
Раз уж мы начали про радио, давайте рассмотрим его подробнее.
Как я уже сказал, RFID на 125КГц — это не микросхема, как для 13МГц, а просто GPIO процессора — одним он дергает антенну, на втором после усилителя на четырех операционных усилителях он смотрит на поле. На самом деле там сложнее, но заинтересовавшихся отправляю к докам:
Вот как выглядит это на плате:
Правды ради, RFID, несмотря на слово «Radio» в сокращении, нифига не радио (посчитайте размеры радио-антенны для 125КГц, да), а скорее индуктивная — две антенны, считывателя и карты образуют собой трансформатор с воздушным зазором. Отсюда и маленькая дальность, и возможность передавать ощутимую мощность.
Дальше у нас NFC:
NFC тут — это отдельная микросхема в отличии от RFID, ST25R3916, поэтому там все проще, антенна просто подключена к выводам микросхемы.
Ну ладно, не так уж и просто. Но хотя бы без операционных усилителей!
Вот как это выглядит на плате:
Выше в углу можно увидеть как раз DC-DC, который делает 5в: от него идет дорожка, на которой есть тестпоинт 5V_1.
Антенны на той плате, что приклеена к задней части корпуса, а подключаются они специальными пружинными контактами.
Вот тут на одной плате контакты, а на второй — контактные площадки.
Кстати, о контактных площадках. На всех платах есть куча круглых тестпоинтов. Это сделано для максимального покрытия тестами на производстве. Например, вот ключ, управляющий вибромотором:
Казалось бы, зачем ему тестпоинты, он же простой. Ан нет, целых три:
По ним можно проверить корректность пайки и работу компонентов: один из них (VBR03) это приходящее питание, которое тестирует пайку токоограничивающего резистора, второй (VBR02) — проверяет работу ключа, а первый (VBR01) — пайку разъёма для шлейфа.
В схеме это выглядит вот так:
Т.е. на этапе тестирования плат можно хорошо снизить вероятность брака, который иначе пришлось бы выявлять вручную, тестированием «а делает ли вибромотор бззз». Заинтересовавшихся отправляю к статье разработчиков про тестирование.
Переходим к SubGHz трансиверу, CC1101. Это универсальный приемопередатчик на частоты 300-348 МГц, 387-464 МГц, 779-928 МГц. Конкретная частота настраивается программно. В общем-то, это почти SDR, достаточно посмотреть на структурную схему:
Но вот только I/Q семплы он не отдает наружу, а обрабатывает их внутри себя в соответствии с настройками, которые ему передает микроконтроллер (частота, полоса, модуляция, etc) по SPI. Поэтому из плюсов — в основном, конфигурируемость.
Однако, несмотря на то, что сам приемник может принимать и передавать на разных частотах, остается вопрос согласования, фильтров и антенны. Для того, чтобы флиппер мог работать на всех этих частотах, потребовалось сделать дополнительно три переключаемых цепочки фильтров:
Вот как это выглядит «в железе»:
По сравнению с этим радиочасть на 2,4 выглядит совсем просто, она напрямую идет в основной процессор:
Так же и на плате, просто дорожка вверх с балуном и парой деталек, заканчивающаяся растопыренной в разные стороны антенной, прячущейся за разъёмами GPIO:
Что еще у нас осталось? Средства взаимодействия с пользователем: экран и RGB-светодиод.
Они подключены хитро: есть lp5562, четырёхканальный драйвер светодиодов, управляемый под I2C, к которому по трем каналам подключен светодиод, а по четвертому — подсветка экрана.
Он, кстати, не просто ключ с управлением по I2C, а в него можно еще и загружать краткие программы, типа плавного изменения яркости. Плавное гашение и зажигаение подсветки сделано именно так.
Сам экран подключен по SPI.
Кстати, интерфейсы. У контроллера их больше, но задействовано на внутренние нужды три: два SPI и один I2C. На внутреннем I2C сидят: питание (зарядник и гауж) и контроллер светодиода и подсветки.
Еще есть два SPI — R и D. SPI-D это экран и microSD-карта. SPI-R это NFC и RFID:
Однако, у контроллера для каждой шины есть несколько GPIO, на которые можно ее переключать. Полной матрицы коммутации, как у некоторых контроллеров от TI тут нет, но можно отключить SPI-R от NFC/RFID и переключить его на пины GPIO, чтобы можно было поработать с чем-то внешним по SPI. Конечно, при этом не будет работать NFC и RFID, поэтому методика такая: запускаем приложение, которое надо работать с внешним устройством, переключаем SPI, работаем с внешним устройством, при выходе из приложения переключаем обратно.
Поэтому и две шины: с одной стороны, SD-карта, которая не совсем SPI-устройство (это помимо ее приколов с питанием): не отпустить MISO даже после снятия с нее chip select — норма. Но на этой шине кроме нее только дисплей, у которого MISO (Master In, Slave out, т.е. передачи данных от дисплея к контроллеру в данном случае) нет. Но дисплей нужен всегда, его шину отключать нельзя, а вот NFC/RFID можно и временно отключить от управления.
Кажется все. А, нет, не все, осталась клавиатура. С одной стороны, сами кнопки достаточно простые — это просто GPIO контроллера. С другой стороны, там есть еще несколько хитростей, помимо упомянутого выше соединения кнопки «назад» с контроллером заряда.
Например, это «железная» перезагрузка по долгому удержанию «назад» и «влево». Прям реально железная — там задержка на конденсаторах, потом элемент AND, выход которого заведен на вход RESET микроконтроллера. Таким образом, при нажатии и удержании этих двух кнопок контроллер сбросится, в каком бы программном состоянии он не находился, даже если у него запрещены все прерывания.
Однако, не всегда панацея: в некоторых странных состояниях при отладке оно может все-таки не сработать. А еще может зависнуть не контроллер, а что-то из периферии. Тогда спасет только долгое нажатие «назад» для перезагрузки по питанию.
Еще надо объяснить два разных способа входа в DFU. Напомню, в первой статье были описаны два разных способа это сделать: долгое нажатие «назад» и «влево», после чего кнопка «влево» остается зажатой, и долгое нажатие «назад», «влево» и «ок», после чего остается зажатой кнопка «ок».
Дело в том, что аппаратный способ захода в DFU всего один — зажатая кнопка «ок» при старте устройства: она висит на PH3-BOOT0, высокий уровень на котором при запуске контроллера заставляет его перейти в DFU.
Однако, возможно перейти в DFU программно — это и делает загрузчик, если замечает при своем запуске нажатую кнопку «влево».
Соответственно, «назад» и «влево» всего лишь перезапускают контроллер. Тоже самое, вы можете сделать отключив и подключив аккумулятор. А дальше, при старте контроллера имеет значение только то, нажата ли кнопка «назад» или «ок» — для входа в DFU аппаратно или программно соответственно.
На «больших» компьютерах есть куча уровней абстракции и аппаратных средств сделать жизнь пользователя и разработчика проще. В итоге, даже если вы пишете на голом си, вас все равно не волнует как конкретно по PCI передается информация, как работает система питания процессора и какая там микросхема используется для хранения BIOS/UEFI.
Тут все не так, слишком уж близко к железу происходит разработка. Статья — это краткий экскурс в то, как устроен Flipper с железной точки зрения. Поехали.
Для начала, давайте его разберем. В принципе, разборка довольно проста, сильно проще, чем некоторые ноутбуки. Но некоторые тонкости все же есть.
Для начала, стоит вытащить microSD-карту и отключить флиппер (Settings-Power-Power OFF-OFF):
Первое действие напрашивается само собой — 4 винта сзади (красные пометки, 1). Тут подстерегает первая тонкость — нужна длинная отвертка, глубина залегания винтов — примерно 12мм.
После выкручивания винтов настает черед двух защелок — в местах, отмеченных синими стрелками, 2. Они легко отщелкиваются, если ногтем расширить щель между половинками корпуса. Главное не перестараться — пины для iButton (зеленое, 3) проходят внутри длинной трубки в задней половинке корпуса для защиты от механического воздействия вбок, но ей же очень удобно их и выломать, если поднять с сильным перекосом. Поэтому отщелкиваем защелки по одной и снимаем вертикально вверх половинку. Бояться не надо, оно не настолько хрупкое, как вам сейчас представилось, но и поднимать под 90° половинку со стороны USB-разъёма тоже не стоит.
Откладываем половинку в сторону. Там расположены две антенны, 125kHz и 13MHz RFID, но плата с ними приклеена к корпусу, и посмотреть на них не удастся.
Зато у нас есть другая половинка:
Для дальнейшего разбора — отщелкиваем узкий шлейф:
Выкручиваем один утопленный винт:
И второй, крепящий маленькую плату плату с пружинными пинами:
Теперь ее можно достать:
На ней: три IR-светодиода, один IR-приемник, iButton-пины:
И динамик:
Ну и некоторое количество обвязки, куда же без нее.
Теперь, когда плата больше не мешает, можно выкрутить еще один винт:
И вытащить основной модуль из второй половинки корпуса (вот тут пригодится заранее вытащенная microSD-карта, если ее не вытащить, на этом шаге она будет мешать):
Кстати, разработчики флиппера — обманщики. Я был уверен, что вокруг отверстий GPIO — корпуса самих гнезд PBS:
А оказывается, это просто их имитация в пластике корпуса.
Еще на этой половинке — окошко с IR-фильтром. В отличии от стекла экрана закреплено не УЗ-сваркой, а просто на плавящемся пине:
Разбираем дальше внутренний модуль. Для этого отсоединяем оставшийся шлейф:
И теперь надо освободить плату из защелок. В принципе, ее можно и не доставать, дальнейшей разборке она не мешает, но если уж начал, остановиться трудно.
Сдвигаем плату по направлению к нижним защелкам, а затем поднимаем плату «наверх» (перпендикулярно модулю) в точке один, освобождая ее от одной защелки, и сдвигаем в точке два по направлению к верхним защелкам, освобождая нижние.
Теперь так же, сдвигая плату вниз (точка три), освобождаем верхнюю защелку и вытаскиваем (точка 4) из боковой защелки. Оп, плата свободна:
Кстати, оцените, что для уменьшения толщины в пластике сделаны отверстия под наиболее высокие компоненты:
Кстати, одно из отверстий осталось, судя по всему, от предыдущего дизайна платы — напротив него на плате пустота. Спросил разработчиков, так и оказалось. Более того, операционников два тоже поэтому — когда возникла нужда переделать схемотехнику этой части, механика уже была зафиксирована и пресс-форму переделывать уже было нельзя, поэтому любые изменения в схемотехнике приходилось согласовывать с корпусом. Вот тут проще было поставить счетверенный ОУ, но не получилось, пришлось ставить два двойных.
Продолжаем разбирать оставшуюся часть. Вот этот винт так и просится быть открученным для дальнейшей разборки, но это не так: он просто крепит оранжевую деталь
Кстати, оцените, какая красота:
Эта деталька одновременно держалка ремешка и направляющая для карты памяти, одной деталькой, чтобы меньше делать пресс-форм.
В общем, пусть шуруп вас не обманывает и остается там, где был. Для дальнейшего не нужна отвертка, достаточно просто раскрыть две половинки внутреннего модуля как книжку, со стороны GPIO. Там небольшая защелка (синяя стрелка), но ее сломать сложно.
Разделиться частям мешает провод к батарее, его надо отключить:
Осторожнее со шлейфом, его надо аккуратно вытащить через отверстие в корпусе.
И у нас две половинки:
Давайте отсоединим шлейф (запоминайте, как он установлен, ничего вам не помешает вставить его потом вверх ногами и удивляться, почему не работает):
Кстати, помните маленькую плату? Которая с пинами для домофона. Я сначала подумал, что там какой-то мусор прилип к плате. А потом присмотрелся:
И знаете, что? Нифига это не мусор. Это крохотный TVS-диод для защиты от статики в корпусе WLCSP — Wafer Level Chip Scale Package. То есть, это самая натуральная кремниевая вафля, нарезанная на отдельные компоненты и напаянная прям так на плату, без корпуса.
На основной плате тоже такие есть:
Я даже специально пошел на кухню, нашел спичку и положил рядом. Мне кажется, штук 50 по объёму в спичечную головку поместится.
Продолжаем разбирать. Отсоединяем пластиковую накладку с клавиатурой от основной платы.
Для этого выкручиваем два винта (синие), и разделяя со стороны USB-разъёма, освобождаем защелку (красная)
Рассматриваем сложную конструкцию клавиатуры:
О, дельфинчик. Вместо глазика — дырочка.
Хотя на самом деле там дырочка не просто так, а для штифта:
Но в таком виде его почти никто и почти никогда не видит, потому что это штифт от рамки, на которой крепится аккумулятор, а когда вы снимаете накладку с клавиатурой, рамка с аккумулятором уже снята.
Отдельное спасибо тому конструктору, который использовал во флиппере всего два типоразмера винтов: длинные и короткие. Короткие используются при прикручивании рамки с клавиатурой к плате, для крепления оранжевой детали и платы с IR и iButton:
В целом, все, мы разобрали флиппер:
Однако, не сильно продвинулись в понимании того, из чего он состоит. Давайте это исправим.
В процессе ковыряния в даташитах и задавания вопросов разработчикам, нарисовалась вот такая схема:
Она страшная и непонятная, но это только на первый взгляд. Давайте рассматривать ее внимательно и с комментариями.
Для начала, есть основной микроконтроллер, на котором строится устройство, STM32WB55.
У него есть два ядра. Одно основное, Cortex M4, FPU, до 64 MHz, даже MPU есть (MMU нет конечно), 219.48 баллов CoreMark. Для сравнения, у любимой ардуинщиками ATmega2560 — 4.25 баллов, у ESP8266 — 191 балла. Впрочем, в embedded пузомерки едва ли играют хоть какую-то роль, выбор идет скорее по периферии, режимам сна и потреблению в них, цене и в новых реалиях — по наличию на складах. А чистая способность процессора пережевывать числа пригождается редко.
Второе ядро — Cortex M0+, но в целом, всем абсолютно было бы безразлично, если оно было M1, M2, M-1, M√(-1), потому что разработчик к нему доступа не имеет. Ядро целиком отдано под управление радио-стеком, и все что может сделать разработчик — это загрузить туда одну из нескольких версий бинарника, отличающимися разными фичами, отправлять туда команды, пересылать и принимать данные для радио.
Бинарники есть разные: BLE peripheral, BLE central, BLE peripheral+central, Thread, Zigbee, чистый 802.15.4, BLE+Zigbee, BLE+Thread, BLE+802.15.4, и так далее. Недавно вот перешли с BLE peripheral+central на BLE peripheral ради экономии памяти, но теперь флиппер не умеет подключаться к другим устройствам как мастер, только как ведомое. Впрочем, задач, в которых к нему надо подключить BLE-клавиатуру, было, скажем прямо, мало.
Занимательный факт: ST именует бинари для второго ядра как «copro», и что самое страшное, разработчики с этим соглашаются. Бинарники зашифрованы, и расшифровываются загрузчиком непосредственно на чипе. Поэтому ловля в них багов — очень увлекательная вещь. Например, одна из предыдущих версий бинарника при определенных условиях и долгой работе выжигала что-то в тракте BLE, в самом кремнии, от чего он переставал работать на прием. После капанья на мозги ST они признали баг и выпустили апдейт. И таких ситуаций, мелких и не очень — вагон за все время разработки.
Во многом это еще происходит потому, что контроллер новый, и пустая страница ERRATA вовсе не означает, что ошибок нет, она означает, что заполнять ее будут первые пользователи.
С процессором разобрались, идем дальше. Питание. О, питание это сложно!
У нас есть разъем, с которого приходит 5в, у нас есть аккумулятор, который выдает 2.8-4.2в и контроллеры, которые хотят не больше 3.3в.
В общем, есть bq25896 — контроллер зарядки батареи, который умеет ее заряжать. Он же умеет делать из напряжения батареи 5в (в основном для того, чтобы питать другие устройства через тот же USB, типа, как работает в телефонах: вставили зарядку, заряжается, вставили клавиатуру/флешку/мышку — на нее подалось 5в и она начала работать). Разработчики решили не делать из флиппера повербанк, но зато сделали из этой фичи управляемые 5в на гребенке. Управляемые они условно, потому что при подключении флиппера по USB они там все равно появятся, хотите вы того или нет. Но зато при питании от аккумулятора, их можно отключать.
Этот самый bq25896 управляется по I2C, и может включать-выключать свой Step-Up по желанию пользователя.
Идеальный диод, указанный на схеме — это конструкция из мосфета, которая ведет себя как диод, но в отличии от него, не просаживает на себе пол-вольта. Вот он:
В устройстве это выглядит вот так:
Большой мосфет и два транзистора в одном корпусе ниже.
Еще у bq25896 есть забавная фича — shipping mode.
На кнопку «назад» повешен не только GPIO процессора, но и один из контактов bq25896, который запускает его из выключенного состояния. Т.е. на фабрике в контроллер заливается прошивка, делаются необходимые тесты, потом контроллер совершает харакири — просит bq25896 выключиться, тот выключается и обрубает контроллеру питание (кроме RTC, про это чуть ниже), и теперь устройство может очень долго лежать в коробочке, не тратя заряд, тот самый shipping mode (когда в начале статьи мы делали Settings-Power-Power OFF-OFF, то это как раз оно). Но по долгому нажатию (~1с) кнопки «назад» bq25896 просыпается и включает устройство. А по очень долгому (~15с) он перезагружает весь девайс по питанию. У процессора есть, конечно, способ ресета (и программного, и аппаратного), но долгое нажатие — это способ перезагрузить вообще ВСЕ, все равно что аккумулятор отсоединить.
Кроме bq25896 (Charger) есть еще bq27220 (Gauge). Т.е. измеритель.
У него есть шунт, он считает ток, напряжение, процент заряда, циклы зарядки, живость батареи и так далее.
Подключается так же, по I2C и отдает это контроллеру.
Вот этот экран в Setting-Power-Info — это и есть данные с гаужа.
Несмотря на то, что измеряет он батарею, в отличии от контроллера зарядки питается он не от нее, а от общей линии 3.3 (про нее будет ниже), так что при отключенном устройстве ничего не потребляет.
Вот он, на плате, рядом с шунтом, который раз в восемь его больше:
В части измерения заряда, его, конечно можно заменить, на ADC микроконтроллера, который измеряет напряжение батареи. Но лишнего ADC, по словам разработчиков, не было, поэтому было решено поставить гаудж.
Вот кусочек гербера, на котором видно, как подключен шунт — по четырехпроводной схеме, которую еще называют «схемой кельвина».
Это делается для того, чтобы падение напряжение на проводниках к сопротивлению не прибавлялось к падению напряжения на самом сопротивлении. Особенно важно это, когда сопротивление измерительного шунта сравнимо с сопротивлением проводников на печатной плате.
Вот, например, как рекомендуют разводить шунты:
Еще от батареи напрямую запитан RS3221 — это малопотребляющий линейный регулятор, который делает 3.3в для работы RTC основного контроллера.
RTC потребляет крайне мало, поэтому потери на линейном стабилизаторе некритичны, но зато часы флиппера не сбиваются при отключении питания и пока он едет в посылке к пользователю.
Теперь про все остальное. Дальше идут устройства, которые хотят не более 3.3в, поэтому для них есть два DC-DC стабилизатора, LM3281. На одном стабилизаторе висят 3.3в на гребенке и SD-карта, на втором — все остальное: bq27220 (Gauge), lp5562 (драйвер светодиода и подсветки экрана), ST25R3916 (NFC), CC1101 (трансивер SubGhz), FAN48610 (DC-DC для RFID и NFC), и собственно STM32WB55
Стабилизаторы эти Step-Down, поэтому при понижении напряжения на батарее ниже 3.3, на этих шинах будет напряжение батареи, а не 3.3, т.е. до 2.8в.
Два стабилизатора потому что SD-карта. Она, во-первых, по-хорошему требует управления питанием при инициализации, а во-вторых, оказалось, что есть экземпляры, которые могут невзначай просадить питание и повесить или перезагрузить процессор, если будет на основной шине. Ну и 3.3 на доступных пользователю контактах по той же причине — если он подключит что-то сильно потребляющее, и напряжение просядет, не дело вешать пол-устройства. А еще
Кстати, по этой же причине, при вставке карты, на 3.3в пине гребенки может кратковременно пропадать напряжение — вместо отдельного транзистора для SD, процессор управляет входом ENABLE самого стабилизатора периферийной шины.
От батареи напрямую питается динамик (чтобы был громче, чтобы не шумел на основной линии питания и не нагружал DC-DC), IR-светодиоды и вибромотор (по тем же причинам), IR-приемник (TSOP753) (потому что ему пофиг, он 2.5-5.5 V, а разводить удобнее):
Еще есть один DC-DC (FAN48610), на этот раз повышающий:
Он повышает 3.3 до 5в, и отдает эти 5в на антенны NFC и RFID. Передатчик RFID — это просто ключ, которым дергает процессор, а у ST25R3916 есть специальный вход для напряжения питания передатчика. Смысл в том, чтобы повысить напряженность поля и дальность работы.
Раз уж мы начали про радио, давайте рассмотрим его подробнее.
Как я уже сказал, RFID на 125КГц — это не микросхема, как для 13МГц, а просто GPIO процессора — одним он дергает антенну, на втором после усилителя на четырех операционных усилителях он смотрит на поле. На самом деле там сложнее, но заинтересовавшихся отправляю к докам:
Вот как выглядит это на плате:
Правды ради, RFID, несмотря на слово «Radio» в сокращении, нифига не радио (посчитайте размеры радио-антенны для 125КГц, да), а скорее индуктивная — две антенны, считывателя и карты образуют собой трансформатор с воздушным зазором. Отсюда и маленькая дальность, и возможность передавать ощутимую мощность.
Дальше у нас NFC:
NFC тут — это отдельная микросхема в отличии от RFID, ST25R3916, поэтому там все проще, антенна просто подключена к выводам микросхемы.
Ну ладно, не так уж и просто. Но хотя бы без операционных усилителей!
Вот как это выглядит на плате:
Выше в углу можно увидеть как раз DC-DC, который делает 5в: от него идет дорожка, на которой есть тестпоинт 5V_1.
Антенны на той плате, что приклеена к задней части корпуса, а подключаются они специальными пружинными контактами.
Вот тут на одной плате контакты, а на второй — контактные площадки.
Кстати, о контактных площадках. На всех платах есть куча круглых тестпоинтов. Это сделано для максимального покрытия тестами на производстве. Например, вот ключ, управляющий вибромотором:
Казалось бы, зачем ему тестпоинты, он же простой. Ан нет, целых три:
По ним можно проверить корректность пайки и работу компонентов: один из них (VBR03) это приходящее питание, которое тестирует пайку токоограничивающего резистора, второй (VBR02) — проверяет работу ключа, а первый (VBR01) — пайку разъёма для шлейфа.
В схеме это выглядит вот так:
Т.е. на этапе тестирования плат можно хорошо снизить вероятность брака, который иначе пришлось бы выявлять вручную, тестированием «а делает ли вибромотор бззз». Заинтересовавшихся отправляю к статье разработчиков про тестирование.
Переходим к SubGHz трансиверу, CC1101. Это универсальный приемопередатчик на частоты 300-348 МГц, 387-464 МГц, 779-928 МГц. Конкретная частота настраивается программно. В общем-то, это почти SDR, достаточно посмотреть на структурную схему:
Но вот только I/Q семплы он не отдает наружу, а обрабатывает их внутри себя в соответствии с настройками, которые ему передает микроконтроллер (частота, полоса, модуляция, etc) по SPI. Поэтому из плюсов — в основном, конфигурируемость.
Однако, несмотря на то, что сам приемник может принимать и передавать на разных частотах, остается вопрос согласования, фильтров и антенны. Для того, чтобы флиппер мог работать на всех этих частотах, потребовалось сделать дополнительно три переключаемых цепочки фильтров:
Вот как это выглядит «в железе»:
По сравнению с этим радиочасть на 2,4 выглядит совсем просто, она напрямую идет в основной процессор:
Так же и на плате, просто дорожка вверх с балуном и парой деталек, заканчивающаяся растопыренной в разные стороны антенной, прячущейся за разъёмами GPIO:
Что еще у нас осталось? Средства взаимодействия с пользователем: экран и RGB-светодиод.
Они подключены хитро: есть lp5562, четырёхканальный драйвер светодиодов, управляемый под I2C, к которому по трем каналам подключен светодиод, а по четвертому — подсветка экрана.
Он, кстати, не просто ключ с управлением по I2C, а в него можно еще и загружать краткие программы, типа плавного изменения яркости. Плавное гашение и зажигаение подсветки сделано именно так.
Сам экран подключен по SPI.
Кстати, интерфейсы. У контроллера их больше, но задействовано на внутренние нужды три: два SPI и один I2C. На внутреннем I2C сидят: питание (зарядник и гауж) и контроллер светодиода и подсветки.
Еще есть два SPI — R и D. SPI-D это экран и microSD-карта. SPI-R это NFC и RFID:
Однако, у контроллера для каждой шины есть несколько GPIO, на которые можно ее переключать. Полной матрицы коммутации, как у некоторых контроллеров от TI тут нет, но можно отключить SPI-R от NFC/RFID и переключить его на пины GPIO, чтобы можно было поработать с чем-то внешним по SPI. Конечно, при этом не будет работать NFC и RFID, поэтому методика такая: запускаем приложение, которое надо работать с внешним устройством, переключаем SPI, работаем с внешним устройством, при выходе из приложения переключаем обратно.
Поэтому и две шины: с одной стороны, SD-карта, которая не совсем SPI-устройство (это помимо ее приколов с питанием): не отпустить MISO даже после снятия с нее chip select — норма. Но на этой шине кроме нее только дисплей, у которого MISO (Master In, Slave out, т.е. передачи данных от дисплея к контроллеру в данном случае) нет. Но дисплей нужен всегда, его шину отключать нельзя, а вот NFC/RFID можно и временно отключить от управления.
Кажется все. А, нет, не все, осталась клавиатура. С одной стороны, сами кнопки достаточно простые — это просто GPIO контроллера. С другой стороны, там есть еще несколько хитростей, помимо упомянутого выше соединения кнопки «назад» с контроллером заряда.
Например, это «железная» перезагрузка по долгому удержанию «назад» и «влево». Прям реально железная — там задержка на конденсаторах, потом элемент AND, выход которого заведен на вход RESET микроконтроллера. Таким образом, при нажатии и удержании этих двух кнопок контроллер сбросится, в каком бы программном состоянии он не находился, даже если у него запрещены все прерывания.
Однако, не всегда панацея: в некоторых странных состояниях при отладке оно может все-таки не сработать. А еще может зависнуть не контроллер, а что-то из периферии. Тогда спасет только долгое нажатие «назад» для перезагрузки по питанию.
Еще надо объяснить два разных способа входа в DFU. Напомню, в первой статье были описаны два разных способа это сделать: долгое нажатие «назад» и «влево», после чего кнопка «влево» остается зажатой, и долгое нажатие «назад», «влево» и «ок», после чего остается зажатой кнопка «ок».
Дело в том, что аппаратный способ захода в DFU всего один — зажатая кнопка «ок» при старте устройства: она висит на PH3-BOOT0, высокий уровень на котором при запуске контроллера заставляет его перейти в DFU.
Однако, возможно перейти в DFU программно — это и делает загрузчик, если замечает при своем запуске нажатую кнопку «влево».
Соответственно, «назад» и «влево» всего лишь перезапускают контроллер. Тоже самое, вы можете сделать отключив и подключив аккумулятор. А дальше, при старте контроллера имеет значение только то, нажата ли кнопка «назад» или «ок» — для входа в DFU аппаратно или программно соответственно.