Перейти к содержанию

Как прошить AVR: ISP, высоковольтный режим, UPDI и загрузчики

Какими способами записывают программу в AVR и когда какой нужен: ISP по SPI для классических ATmega и ATtiny, высоковольтный режим для «закирпиченных» кристаллов, debugWIRE и JTAG для отладки, PDI, TPI и UPDI для XMEGA, ATtiny4–10 и новых серий, загрузчики вроде Optiboot. С командами протокола ISP, таблицей задержек и примерами для avrdude.

Обновлено Редакция GAW

Записать программу в AVR можно несколькими способами, и какой из них доступен, зависит от семейства и от состояния фьюзов. Классические ATmega и ATtiny прошивают по SPI — это ISP; если ISP отключён фьюзами, остаётся высоковольтный режим. XMEGA, ATtiny4–10 и новые серии используют свои интерфейсы — PDI, TPI и UPDI, а платы Arduino прошиваются через загрузчик по UART. Ниже — все варианты по даташитам Microchip и документации avrdude, с акцентом на ATmega328P.

Коротко

  • ISP — SPI-выводы MOSI, MISO, SCK и низкий уровень на RESET; у ATmega328P это PB3, PB4, PB5. Работает, только если кристалл тактируется, фьюз SPIEN запрограммирован (так с завода), а RSTDISBL — нет.
  • Скорость ISP ограничена тактовой частотой: уровни SCK длиннее 2 тактов процессора (3 тактов при 12 МГц и выше). Новый ATmega328P работает на 1 МГц.
  • Высоковольтное программирование (11,5–12,5 В на RESET) спасает кристалл с отключённым ISP.
  • debugWIRE — отладка по одному проводу через RESET; JTAG — у многовыводных ATmega; PDI — у XMEGA; TPI — у ATtiny4–10; UPDI — у tinyAVR 0/1/2, megaAVR 0 и AVR Dx/Ex.
  • Загрузчик в конце Flash позволяет обновлять программу по UART без программатора — так работает Arduino.

Интерфейсы программирования AVR

ИнтерфейсВыводыКристаллыЧем прошивают
ISP (SPI)MOSI, MISO, SCK, RESETклассические ATmega и ATtinyUSBasp, USBtinyISP, AVRISP mkII, Arduino с ArduinoISP, STK500
Высоковольтный параллельный (HVPP)12 В на RESET, шина данных, управляющие выводыATmega с достаточным числом выводов, например ATmega328PSTK500, STK600, AVR Dragon
Высоковольтный последовательный (HVSP)12 В на RESET и несколько выводовATtiny с малым числом выводов, например ATtiny85STK500, AVR Dragon
debugWIRERESETATmega328P, многие ATtinyAtmel-ICE, JTAGICE3, AVR Dragon
JTAGTCK, TMS, TDI, TDOATmega128, ATmega2560, ATmega32U4, часть XMEGAAtmel-ICE, JTAG ICE mkII, AVR Dragon
PDIPDI_DATA, RESET/PDI_CLKвсе XMEGAAtmel-ICE, AVR Dragon, STK600
TPITPIDATA, TPICLK, RESETATtiny4/5/9/10AVRISP mkII, STK600, PICkit 4/5
UPDIодин вывод UPDItinyAVR 0/1/2, megaAVR 0, AVR Dx/ExSerialUPDI, jtag2updi, Atmel-ICE, PICkit 4/5

Поддержка программаторов указана по документации avrdude 8.3, кристаллов — по их даташитам и описаниям в avrdude.conf. Разъёмы ISP на 6 и 10 контактов, UPDI и TPI с назначением выводов показаны на странице «Распиновка AVR ISP».

ISP: последовательное программирование по SPI

Пока на RESET низкий уровень, Flash, EEPROM, фьюзы и биты защиты доступны через SPI: данные в кристалл передаются по MOSI и защёлкиваются по фронту SCK, из кристалла читаются по MISO по спаду (DS40002061B, раздел 28.8). Последовательность такая:

  1. Подать питание при RESET = 0 и SCK = 0; если программатор не может удержать SCK в нуле при включении, дать на RESET положительный импульс длиной не меньше двух тактов.
  2. Подождать не меньше 20 мс и послать команду Programming Enable — AC 53 00 00. Если связь синхронна, второй байт (53) возвращается эхом при передаче третьего. Нет эха — импульс на RESET и повтор.
  3. Стереть кристалл (Chip Erase), загрузить страницу Flash по словам — младший байт раньше старшего — и записать её командой Write Program Memory Page; следующую страницу посылать после окончания записи.
  4. Проверить записанное командами чтения и отпустить RESET.
КомандаБайты 1–4
Programming EnableAC 53 00 00
Chip Erase (Flash и EEPROM)AC 80 00 00
Poll RDY/BSYF0 00 00 — ответ в 4-м байте, младший бит 1 = занято
Load Program Memory Page, low / high byte40 / 48, 00, адрес в странице, данные
Write Program Memory Page4C, старший и младший байты адреса, 00
Read Program Memory, low / high byte20 / 28, старший и младший байты адреса — ответ в 4-м байте
Read Signature Byte30 00 номер байта — ответ в 4-м байте
Read Fuse / Fuse High / Extended Fuse50 00 00, 58 08 00, 50 08 00 — ответ в 4-м байте
Write Fuse / Fuse High / Extended FuseAC A0 00, AC A8 00, AC A4 00 — данные в 4-м байте
Read / Write Lock bits58 00 00 / AC E0 00

Без опроса RDY/BSY после каждой операции нужно выждать: запись страницы Flash — 4,5 мс, байта EEPROM — 3,6 мс, стирание — 9,0 мс, запись фьюзов — 4,5 мс (таблица 28-18). Адреса Flash в командах — в словах, а не в байтах. Запись EEPROM по ISP сама стирает ячейку перед записью.

Частота SCK и фьюзы

Низкий и высокий уровни SCK должны длиться больше 2 тактов процессора при частоте ниже 12 МГц и больше 3 тактов при 12 МГц и выше, поэтому SCK — меньше четверти частоты кристалла. ATmega328P поставляется с внутренним генератором 8 МГц и запрограммированным фьюзом CKDIV8, то есть работает на 1 МГц — и SCK для нового кристалла должна быть меньше 250 кГц. В avrdude её задаёт опция -B: период в микросекундах или частота с суффиксом kHz.

ISP требует работающего тактового генератора: если фьюзами выбран внешний кварц, которого на плате нет, кристалл не отвечает, пока на XTAL1 не подать внешний тактовый сигнал. Если запрограммирован фьюз RSTDISBL, вывод RESET становится обычным выводом PC6, и войти в ISP уже нельзя. Фьюз SPIEN, наоборот, через ISP случайно не выключить — в последовательном режиме он недоступен. В обоих случаях выручает высоковольтное программирование, а заранее ошибок помогает избежать калькулятор фьюзов AVR.

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

В параллельном режиме на RESET подают 11,5–12,5 В, а команды и данные передают по восьмибитной шине и нескольким управляющим выводам (DS40002061B, раздел 28.7). Этот режим работает независимо от фьюзов RSTDISBL и SPIEN и тактового генератора — тактирует программатор через XTAL1, — поэтому им восстанавливают кристаллы, у которых ISP отключён. У ATtiny с малым числом выводов, например ATtiny25/45/85, вместо параллельного есть высоковольтный последовательный режим (HVSP). Оба режима поддерживают STK500 со второй версией прошивки (типы stk500pp и stk500hvsp в avrdude), STK600 и AVR Dragon.

debugWIRE и JTAG

debugWIRE — однопроводной интерфейс отладки: при запрограммированном фьюзе DWEN вывод RESET превращается в двунаправленную линию с открытым стоком и подтяжкой, через которую отладчик останавливает программу, читает регистры и программирует память (DS40002061B, глава 25). Ограничения: подтяжка на RESET не меньше 10 кОм, конденсаторы и внешние источники сброса нужно отключить, RESET нельзя подключать прямо к питанию. Точки останова реализуются записью команды BREAK во Flash, поэтому каждая их смена перезаписывает страницу и расходует ресурс Flash. Пока DWEN запрограммирован, генератор работает и во сне, увеличивая ток, — фьюз выключают, когда отладка закончена.

У многовыводных ATmega — ATmega128, ATmega2560, ATmega32U4 — и у части XMEGA есть JTAG с четырьмя линиями TCK, TMS, TDI и TDO. Через него можно и программировать, и отлаживать. У ATmega32U4 встроенную отладку выключают фьюзом OCDEN или JTAGEN либо записью единицы в бит JTD регистра MCUCR — включённая отладка, как и debugWIRE, держит генератор работающим во сне.

PDI, TPI и UPDI

  • PDI — двухпроводный интерфейс XMEGA: данные по PDI_DATA, такт по выводу RESET (подробнее — в статье о XMEGA).
  • TPI — интерфейс ATtiny4/5/9/10 из трёх выводов: RESET разрешает программирование, TPICLK — такт, TPIDATA — данные в обе стороны. Память этих кристаллов программируется только при напряжении 5 В.
  • UPDI — интерфейс tinyAVR 0/1/2, megaAVR 0 и AVR Dx/Ex: однопроводный полудуплексный UART со скоростью до 0,9 Мбит/с, через который доступны и программирование, и отладка. У ATmega4809 под UPDI отведён отдельный вывод, не занимающий ни одной линии ввода-вывода (DS40002173C, глава 30). Простейший программатор SerialUPDI — переходник USB–UART, диод и пара резисторов; avrdude поддерживает его как тип serialupdi, а также программатор jtag2updi на плате с AVR.

Загрузчики

AVR могут записывать собственную Flash командой SPM. У ATmega328P для загрузчика отводится секция в конце Flash, размер которой задают фьюзы BOOTSZ, а фьюз BOOTRST переносит вектор сброса в её начало (DS40002061B, таблица 27-13):

BOOTSZ1:0Размер секцииНачало секции (адрес слова)
11256 слов (512 байтов)0x3F00
10512 слов (1 КБ)0x3E00
011024 слова (2 КБ)0x3C00
002048 слов (4 КБ)0x3800

Загрузчик после сброса некоторое время слушает UART и, если пришла новая программа, записывает её во Flash, а иначе передаёт управление основной программе. Optiboot на Arduino Uno понимает урезанный протокол STK500 версии 1 — в avrdude это тип arduino, на Uno он работает на 115 200 бод. Загрузчик Arduino Mega 2560 использует протокол STK500 версии 2 — тип wiring, тоже 115 200 бод. Перевод платы в режим загрузки делает импульс на линиях DTR и RTS переходника USB–UART, сбрасывающий кристалл: avrdude переключает их при открытии порта, если не указан параметр noautoreset. Более компактные загрузчики urboot совместимы с протоколом STK500 v1 и обслуживаются типом urclock. Как устроена загрузка у плат Arduino, рассказано на странице «Arduino на AVR».

avrdude: типичные команды

Запись программы в ATmega328P программатором USBasp с пониженной частотой SCK для нового кристалла:

avrdude -c usbasp -p m328p -B 8 -U flash:w:main.hex:i

Загрузка в Arduino Uno через загрузчик:

avrdude -c arduino -p m328p -P COM3 -b 115200 -U flash:w:main.hex:i

Прошивка ATmega4809 через SerialUPDI:

avrdude -c serialupdi -p m4809 -P COM5 -U flash:w:main.hex:i

Опция -c выбирает тип программатора, -p — кристалл (m328p, m4809, t85 и так далее по avrdude.conf), -P — порт, -b — скорость UART, а -U память:операция:файл:формат описывает операцию: flash:w:main.hex:i — записать во Flash файл в формате Intel HEX, lfuse:r:lfuse.txt:h — прочитать младший фьюз в текстовый файл в шестнадцатеричном виде. Остальные опции и режимы программы описаны на странице avrdude.

Частые вопросы

Почему новый ATmega328P не прошивается программатором?

Чаще всего — из-за скорости SCK. С завода ATmega328P работает от внутреннего генератора 8 МГц с запрограммированным фьюзом CKDIV8, то есть на 1 МГц, а низкий и высокий уровни SCK должны длиться дольше двух тактов процессора. Значит, частота SCK должна быть меньше 250 кГц. В avrdude её снижают опцией -B, например -B 8 (период 8 мкс). Другие причины — неправильное подключение, отсутствие питания на кристалле и выбранный фьюзами внешний генератор, которого нет на плате.

Как восстановить AVR после неправильных фьюзов?

Если ошибка в фьюзах тактирования, кристаллу достаточно подать внешний тактовый сигнал на вывод XTAL1 и прошить фьюзы заново по ISP. Если запрограммирован RSTDISBL, вывод RESET стал обычным выводом и войти в ISP нельзя — поможет только высоковольтное параллельное программирование: 11,5–12,5 В на RESET и параллельный обмен данными, например программатором STK500 или AVR Dragon. Фьюз SPIEN, разрешающий ISP, по самому ISP изменить нельзя: в последовательном режиме он недоступен.

Чем Arduino Uno прошивается без программатора?

Загрузчиком Optiboot, который занимает конец Flash и после сброса некоторое время слушает UART. Он понимает подмножество протокола STK500 версии 1, поэтому в avrdude выбирают программатор типа arduino на скорости 115 200 бод. Сброс перед загрузкой делает сигнал DTR преобразователя USB–UART.

Что такое UPDI и чем его прошить?

Однопроводный интерфейс программирования и отладки новых AVR — tinyAVR 0/1/2, megaAVR 0, AVR Dx и Ex. Это полудуплексный UART на одном выводе; у ATmega4809 под него отведён отдельный вывод. Самый простой программатор — SerialUPDI: обычный переходник USB–UART, диод и пара резисторов, программа avrdude с типом serialupdi. Подойдут и фирменные Atmel-ICE, PICkit 4/5, а также плата Arduino с прошивкой jtag2updi.

Источники

  1. Microchip. ATmega48A/PA/88A/PA/168A/PA/328/P Data Sheet (DS40002061B) — гл. 25 — debugWIRE; гл. 27 — загрузчик и самопрограммирование, таблица 27-13 (BOOTSZ); гл. 28 — параллельное программирование (11,5–12,5 В на RESET), последовательное программирование: таблицы 28-17 (выводы), 28-18 (задержки), 28-19 (команды), SPIEN недоступен в последовательном режиме; заводская частота 1 МГц (CKDIV8); RSTDISBL
  2. Microchip. ATmega4808/4809 Data Sheet (DS40002173C) — гл. 30 — UPDI: однопроводный полудуплексный UART до 0,9 Мбит/с на отдельном выводе
  3. Atmel. ATtiny4/5/9/10 Data Sheet (8127H) — гл. 15 — TPI: три вывода (RESET, TPICLK, TPIDATA), программирование только при 5 В
  4. AVRDUDE 8.3: руководство avrdude.1 и файл avrdude.conf (github.com/avrdudes/avrdude) — типы программаторов: STK500 v1/v2, arduino (Optiboot), urclock, wiring, usbasp, serialupdi, jtag2updi, Atmel-ICE, PICkit 4/5, AVR Dragon; опции -c, -p, -P, -b, -B, -U и форматы файлов; noautoreset
  5. Atmel. ATmega16U4/32U4 Datasheet (7766J) — отключение встроенной отладки: фьюзы OCDEN и JTAGEN, бит JTD
  6. Arduino. ArduinoCore-avr: boards.txt — Uno — протокол arduino на 115200 бод, Mega 2560 — протокол wiring на 115200 бод

Нашли ошибку?