Однажды я испортил чип ATtiny85, да так «удачно», что даже высоковольтный последовательный программатор мне не помог. Пожалуй, с любым может случиться нечто подобное. Человек ушёл с головой в работу над каким-нибудь интересным проектом на ATtiny85. Внезапно микросхема перестаёт работать и её уже нельзя запрограммировать или записать на неё новый код.

Со мной это случилось во время возни с проектом The Skull (Череп). Это — новая аппаратная головоломка в стиле CTF (Capture The Flag) с леденящим душу сюжетом. Если честно, то в том, что случилось, была, отчасти, и моя вина. Я оставил некоторые пины подключёнными к плате Uno и пытался перепрошить чип. Вероятно, что-то вмешалось в этот процесс и чип «умер».



В общем — моя глупость стала причиной проблемы, а в моих руках оказался сломанный череп. Замечательно, что и говорить.

Расскажу о том, как мне удалось восстановить работоспособность ATtiny85. Кто знает — может и вы когда-нибудь «окирпичите» такой чип, а мой рассказ поможет вам этот чип спасти.

Проклятие фьюзов


Чипы ATtiny (и, в целом, микроконтроллеры семейства AVR) имеют конфигурационные биты, называемые фьюзами (fuse) или фьюз-битами. Они позволяют управлять различными параметрами микроконтроллера. Например — источником тактового сигнала (внутренний или внешний), возможностью перепрограммирования чипа, отладочным интерфейсом и многим другим.

Работая с чипом очень легко, как говорится, «выстрелить себе в ногу», отключив SPI (Serial Programming Interface, интерфейс последовательного программирования), пин сброса (который нужен для программирования), или просто выбрав неправильный источник тактового сигнала. Компания Microchip даже создала особую страницу, на которой описываются возможные проблемы такого рода.

Итак, фьюзы моего ATtiny, похоже, были прокляты неправильными значениями, что заблокировало возможность программирования чипа. Как снять это проклятие?

Высоковольтное программирование


К счастью, даже если с фьюзами что-то не так, с проблемой можно попытаться справиться, использовав особый интерфейс программирования, встроенный в чип. Это — HVSP (High-Voltage Serial Programming, интерфейс высоковольтного последовательного программирования). Я его обычно называю «режимом Бога». При работе в этом режиме перепрограммировать чип можно даже в том случае, если заблокирован пин сброса и стандартный интерфейс последовательного программирования.

Но для использования HVSP нужно особое оборудование, а именно, на пин сброса надо подать 12 В. Это напоминает небольшой «запасной выход», встроенный в чип, позволяющий исправить ситуацию в том случае, если что-то идёт не так и чип перестаёт реагировать на обычные воздействия.

Я — не первый, кто столкнулся с подобной ситуацией. Поэтому, поискав в интернете, я быстро нашёл хорошее руководство, в котором шла речь о том, как быстро собрать HVSP-программатор, состоящий из ещё одного чипа ATtiny, транзистора 2N3904, светодиода и нескольких резисторов. В том руководстве даже имелся код, предназначенный для сброса фьюзов в их исходное состояние.


Попытка снять проклятие с фьюзов ATtiny85

Восстановление чипа выполняется достаточно просто. Загружаем код на другой чип ATtiny (будем с этого момента называть его «HVSP-программатор»), подключаем его к «проклятому» чипу, подаём на транзистор 12В, включаем питание и смотрим на светодиод:

  • Если светодиод ненадолго включается, а потом выключается — это значит, что всё получилось.
  • Если светодиод медленно (с частотой 1 Гц) мигает, это значит, что чип ATtiny не может быть идентифицирован.
  • Если светодиод мигает быстро (5 Гц), это значит, что состояние фьюз-битов ATtiny не было корректно обновлено.

После того, как я подготовил второй чип ATtiny и собрал схему, я включил её и…

Всё получилось?


Нет — не получилось. Я столкнулся с неожиданным поведением системы. Светодиод просто горел, и я не знал о том, что это значит.

Когда я присмотрелся к светодиоду, оказалось, что он очень быстро мигает. Очевидно, у ATtiny, играющего роль программатора, неправильно была выставлена частота. Поэтому функция delay() работала не так, как можно было ожидать, что и приводило к очень быстрому миганию светодиода, выглядящему так, будто светодиод просто всё время включён.

Я это исправил, загрузил в программатор новый код и попробовал ещё раз. В этот раз светодиод мигал быстро, на частоте примерно 5 Гц. Это означало, что системе удалось идентифицировать чип, но фьюз-биты переписать не удалось.

Для того чтобы убедиться в правильности сборки системы я попытался восстановить другой чип ATtiny, который я специально «сломал», отключив пин сброса. В этот раз операция прошла успешно, на что указывало то, что светодиод ненадолго включился, а потом выключился.

Очевидно было то, что нечто странное происходит с чипом, вмонтированным в череп. HVSP-программатор может идентифицировать этот чип, но не способен перезаписать фьюз-биты.

Сравнение сигналов


В тот момент я решил посмотреть на то, какими данными обмениваются программатор и испорченный чип. Я использовал логический анализатор Saleae с интерфейсом USB для записи сигналов, что должно было мне позволить их проанализировать.

HVSP-программатор использует особый протокол, рассчитанный на применение 4 I/O-пинов:

  1. SDI — Serial Data Input — последовательный ввод данных.
  2. SII — Serial Instruction Input — последовательный ввод команд.
  3. SDO — Serial Data Output — последовательный вывод данных (именно так мы получаем данные с ATtiny)
  4. SCI — Serial Clock Input — последовательный ввод тактовых импульсов.

Каждый кадр, чтобы было веселее, имеет ширину 11 бит (это ещё можно описать как 8-битные кадры, передаваемые с использованием 11 тактовых импульсов).


Спасибо, Microchip, за креативность, проявленную при разработке протокола HVSP

Но самое интересное ещё впереди. Дело в том, что линия SDO играет ещё одну роль. Она не только отвечает за передачу данных от ATtiny к HVSP-программатору. Она ещё и указывает на то, что чип занят (когда находится в низком состоянии), и на то, что он готов принимать инструкции (когда находится в высоком состоянии).

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


Сигнал с чипа, который не удавалось восстановить


Сигнал с чипа, который восстановить удалось

Видно, что чип, который удалось восстановить, три раза переводит линию SDO в низкое состояние примерно на 4 мс (это — большие «ямы» на розовой линии). Было понятно и то, что программатор в это время перестаёт передавать тактовые импульсы (зелёная линия, отражающая высокочастотные колебания сигнала).

Если посмотреть на код HVSP-программатора, то можно узнать о том, что работает он так:

  1. Войти в режим HVSP-программирования.
  2. Прочитать байты, содержащие сигнатуру чипа (два байта, позволяющих идентифицировать модель чипа) и сравнить их со значениями, хранящимися в списке известных сигнатур.
  3. Если считанную сигнатуру распознать не удалось — остановить процесс и включить медленное (1 Гц) мигание светодиода.
  4. В противном случае записать три фьюз-байта, установив их значения такими, какие задают при изготовлении чипов.
  5. Прочесть значения фьюз-байтов и сравнить их с эталонными значениями. Если прочитанные значения соответствуют ожидаемым — выключить светодиод. В противном случае включить быстрое (5 Гц) мигание светодиода.

Вот как всё это выглядит на записи сигналов.


Процесс успешного восстановления ATtiny

Теперь внешний вид этих сигналов легче поддаётся осмыслению. Каждый раз, когда HVSP-программатор записывает фьюз-байт, чип ATtiny, который можно восстановить, на некоторое время переводит линию SDO в низкое состояние. Это — то время, которое нужно для записи соответствующего байта.

А вот чип, который мне восстановить не удалось, вёл себя иначе. Хотя он и реагировал на команды чтения сигнатуры (Read Signature) и чтения состояния фьюз-байтов (Read Fuse Values), он никогда не переводил линию SDO в низкое состояние после выполнения операций записи значений фьюз-байтов.


Работа с чипом, восстановить который не удалось

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

В этот момент мне захотелось узнать о том, что записано во фьюз-байты чипа, восстановить который мне не удалось.

Расшифровка фьюз-байтов


Я пользуюсь программой Saleae Logic 2, в ней имеется множество встроенных анализаторов протоколов. Но стандартного анализатора для протокола HVSP в ней нет. Поэтому я приступил к экспериментам с существующими анализаторами.

В итоге я нашёл интересный способ использования SPI-анализатора. Я настроил его на использование 11-битных кадров и, в качестве сигнала MISO, выбрал сигнал SDO, в качестве тактового сигнала указал SCI, настроил чтение данных по заднему фронту сигнала (CPHA=1).


Эти необычные настройки SPI позволили мне проанализировать сигнал

И ещё одна деталь. Мне пришлось сдвинуть декодированные значения вправо на 3 бита для того чтобы отбросить 3 тактовых импульса в конце каждого кадра. Вот как выглядели декодированные данные.


Декодирование байтов сигнатуры чипа (0x49F, 0x05F)

После того, как я получил два декодированных значения и сдвинул их вправо на 3 бита, оказалось, что это — 0x93 и 0x0B. Они совпадали с сигнатурными байтами ATtiny85.


Идеальное совпадение с сигнатурными байтами

После этого я применил ту же методику для декодирования фьюз-байтов.


Декодирование фьюз-байтов

Снова применив сдвиг на 3 бита, мы получаем 0x26 и 0x0f. Эти значения можно проверить здесь и узнать о том, что они означают.


Настройки чипа, который не удавалось привести в рабочее состояние

Видно, что сброс чипа (Reset) отключён, что выбран внешний источник низкочастотного тактового сигнала (External Low-Frequency Crystal), что включён отладочный интерфейс (Debug Wire). Все эти настройки мешают программированию чипа!

Но загадка оставалась неразгаданной. Почему мне не удавалось сбросить фьюз-байты с использованием собранного мной HVSP-программатора?

Раскрытие тайны фьюзов


Я зарылся в давно забытые ветки на форумах, посвящённых AVR и Arduino, почитал документацию и внезапно понял причину невозможности сброса фьюз-байтов.


У моего ATtiny — «синдром запертого человека»

Похоже, что я, «окирпичив» чип, задел ещё и биты блокировки (Lock Bits). Они запрещают перепрограммирование чипа и, в том числе, не позволяют менять фьюз-биты.

Но в документации, к моему счастью, упоминалось о способе выхода из подобных ситуаций. Это — команда стирания чипа (Chip Erase).


Команда Chip Erase

Команда Chip Erase и снятие проклятия


Теперь, сделав столь важную для меня находку, я разработал следующий план действий:

  1. Стирание чипа.
  2. Перезапись фьюзов.
  3. Успешное восстановление чипа.

Я снова заглянул в документацию и нашёл код команды Chip Erase в верхней части таблицы с набором инструкций HVSP.


Код команды Chip Erase

Я написал аккуратную Arduino-функцию, выполняющую стирание чипа:

// Таблица документации 20-16
void chipErase() {
  shiftOut(0b10000000, 0b01001100);
  shiftOut(0b00000000, 0b01100100);
  shiftOut(0b00000000, 0b01101100);
}

Эта функция вызывается сразу перед установкой фьюз-битов. Я записал новый код в HVSP-программатор, всё подключил, и…


4 «ямы» на графике SDO говорят об успешном восстановлении чипа

Как видите, сигнал SDO четыре раза переводится в низкое состояние. В первый раз он пребывает в этом состоянии достаточно много времени. Именно тогда чип ATtiny занят выполнением команды Chip Erase. Три следующих «ямы» указывают на моменты перезаписи фьюз-байтов. После этого нерабочий ATtiny85 снова заработал и The Skull восстал из пепла.

Итоги


Вот записи сигналов, сделанные с помощью логического анализатора. Вы можете с ними поэкспериментировать (попробовать фокус с SPI и прочее), воспользовавшись программой Saleae Logic 2 (для этого необязательно иметь сам анализатор).

Я, кроме того, решил опубликовать обновлённую прошивку для HVSP-программатора, в которую включил функцию для выполнения команды Chip Erase. Поэтому если кто-то ещё столкнётся с такой же проблемой, с которой столкнулся я, он сможет быстро привести свой ATtiny85 в рабочее состояние.

Теперь, когда мне удалось «оживить» чип, я могу продолжить эксперименты с прошивкой The Skull. Позволю себе продемонстрировать вам кое-какой код оттуда.


Клянусь, этот свиток найден в океанских глубинах

А вы когда-нибудь «окирпичивали» ATtiny85?