Делаем ISP-программатор из Arduino


Думаю, ни для кого не секрет, что первоначально программу в микроконтроллер заливают при помощи специального устройства — программатора. Конечно, ардуинщикам обычно не нужно об этом беспокоиться — у них есть bootloader (загрузчик), заранее прошитый в микроконтроллер, и прошивку он забирает по UART через COM-порт или через USB. Но чтобы прошить этот загрузчик или другую прошивку в «чистый» МК, нужен программатор.

Но в этой статье мы не будем рассматривать сборку и пайку программатора с нуля, а воспользуемся возможностями Arduino. Дело в том, что на большинстве плат Arduino до версии Uno есть микросхема FT232RL компании FTDI.


Эта микросхема представляет собой конвертор UART->USB, предоставляя операционной системе виртуальный COM-порт, работающий через USB. Но в данном случае нам нужна другая её возможность — управление отдельными выводам микросхемы, именуемое режимом bit-bang, которое позволяет «завернуть» произвольный протокол в USB. Задача состоит в том, завернуть в USB протокол прошивки МК.

Микроконтроллеры AVR, используемые в Arduino, прошиваются по уже знакомому нам протоколу SPI через разъём для внутрисхемного программирования — ISP (In-System Programming). Он так называется потому, что позволяет прошивать МК прямо в конечном устройстве. Вот как выглядит этот разъём на плате CraftDuino:

MISO, MOSI, SCK, RESET — это всё линии шины SPI, только вместо SS — RESET.

Но нам ещё нужен доступ выводам FT232RL, через которые будет осуществляться прошивка, и разработчики Arduino позаботились об этом, сделав разъём X3 (икс-три):

Если на вашей плате только контактные площадки для X3, нужно будет припаять кусок PLS-гребёнки самим.

Пины этого разъёма имеют следующее назначение для ISP-программатора:

  • 1 (CTS) — MISO
  • 2 (DSR) — SCK
  • 3 (DCD) — MOSI
  • 4 (RI) — RESET

А у CraftDuino вместо X3 есть стандартный разъём RS232, тоже соединённый с FT232RL, из которого нам нужны те же 4 вывода:

  • 1 (CD) — MOSI
  • 6 (DSR) — SCK
  • 8 (CTS) — MISO
  • 9 (RI) — RESET

Пораскинув мозгами, сделаем кабель для нашего импровизированного ISP-программатора:

С одного конца кабеля — разъёмы для Arduino X3/CraftDuino UART, и для питания:

А с другого конца — стандартный разъём ISP:

Обычно для прошивки AVR используется популярная утилита avrdude, которая поддерживает множество различных программаторов и моделей МК, её использует даже среда Arduino IDE для заливки скетча. Для этой утилиты есть патч, позволяющий прошивать МК через микросхему FT232RL, используя режим bit-bang. Нашлись добрые люди, которые уже пропатчили Windows-версию avrdude для работы с bit-bang-программатором на базе этой микросхемы, а я сделал то же и для Linux:

  • Патченая версия 5.3.1 для Windows.
  • Версия 5.10, deb-пакет для Linux i386 и amd64 (x86_64).
  • Архив с исходными кодами версии 5.10, библиотекой libftd2xx-1.0.4 с официального сайта FTDI и правлеными Makefile.in и avrdude.conf, чтобы всё это собиралось, корректно устанавливалось и работало. Проверял только на Ubuntu 11.04 (i386 и amd64).

Собственно, deb-пакеты собраны из выложенного тут патченого дистрибутива, но для параноиков есть другой вариант — пропатчить и собрать avrdude самолично, про это читайте тут. Только в avrdude.conf нужно добавить следующие строчки, а не то, что написано в статье по ссылке:

programmer
  id = "ftbb";
  desc = "FT232R Synchronous BitBang";
  type = ft245r;
  miso = 3; # CTS X3(1)
  sck = 5; # DSR X3(2)
  mosi = 6; # DCD X3(3)
  reset = 7; # RI X3(4)
;

Если вы работаете в Linux, придётся сделать ещё несколько действий (FTDI нас любит):

  • Убить драйвер ftdi_sio, который мешает avrdude открыть COM-порт FTDI:
    sudo rmmod ftdi_sio

    Если хотите, можете занести этот модуль ядра в чёрный список, внеся в /etc/modprobe.d/blacklist.conf строчку:

    blacklist ftdi_sio

    Только имейте ввиду, что для работы с виртуальным портом /dev/ttyUSB0 и т.п. (нужно Arduino IDE) этот модуль должен быть запущен. Это можно делать командой

    sudo modprobe ftdi_sio
  • По умолчанию, система при попытке avrdude открыть виртуальный COM-порт FTDI покажет ему кукиш, а он вам — не слишком информативное сообщение об ошибке. Нужно дать себе права на полный доступ к виртуальным COM-портам, создав в /etc/udev/rules.d/ файлик с именем 80-ftdi.rules следующего содержания:
    SYSFS{idVendor}=="0403", SYSFS{idProduct}=="6001", MODE="660", GROUP="ftdi-user"

    USB Vendor ID и Product ID можно для верности уточнить командой lsusb, если Arduino подключена к компу:

    ...
    Bus 005 Device 012: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC
    ...
    

    Потом нужно создать группу ftdi-user и добавить себя в неё:

    sudo addgroup ftdi-user
    sudo usermod -a -G ftdi-user <имя пользователя>

    после чего нужно перелогиниться.

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

    sudo udevadm trigger

В статье про программирование AVR на C товарищ noonv уже описал, как пользоваться avrdude, а я опишу лишь заливку загрузчика на Arduino Diecimila с ATmega168:

  1. Устанавливаем необходимые для быстрой прошивки загрузчика fuse-биты: кварц > 8 МГц, встроенный делитель на 8 выключен:
    avrdude -c ftbb -P ft0 -p m8 -B 9600 -U hfuse:w:0xdd:m -U lfuse:w:0xff:m
  2. Заливаем загрузчик:
    avrdude -c ftbb -P ft0 -p ATMega168 -B 19200 -U flash:w:ATmegaBOOT_168_diecimila.hex

Но консоль не всегда лучше гуя, особенно для задания fuse-битов, и есть гораздо более удобный и надёжный способ — воспользоваться программой SinaProg, разработанной иранскими программистами. Их сайт давно сдох, зато программа живёт и здравствует и по сей день. О её настройке подробно написано у Di Halt’а, ну а мы не будем терять времени и возьмём готовую настроенную сборку с пропатченным avrdude (в сборке Di Halt’а ошибка в одном из конфигов). Версии под Linux, увы, не существует.

В секции Hex file выбирается hex-файл, который нужно залить или считать. Записывать и считывать можно как память программ (Flash), так и энергонезависимую (EEPROM). В секции Device нужно указать конкретный МК, в секции Programmer — программатор (у нас это ftbb), порт (FTDI0) и скорость порта (9600).

Ну и то, ради чего стоит пользоваться этой программой — секция Fuses. В раскрывающемся списке можно выбрать предопределённые конфигурации fuse-битов, которые задаются в Fuse.txt. Но самое главное открывается нашему взору по нажатию кнопки Advanced:

Здесь можно набивать fuse-байты вручную, а можно нажимать на кнопки «C» рядом со значением байтов и выставлять фьюзы тыканием галочек с описаниями. Для заливки загрузчика сначала нажмём кнопку Read, чтобы считать текущие значения fuse, а затем настроим Low fuse: частота кварца — более 8 МГц, время старта МК — 65 мс, делитель на 8 выключен:

После настройки жмём кнопку Write и ждём появления надписи «Writing Fuses… OK».

Теперь можно в главном окне в секции Hex file выбирать файл загрузчика ATmegaBOOT_168_diecimila.hex и в секции Flash жать кнопку Program. Если в процессе будут возникать ошибки, то над индикатором прогресса есть кнопка «>», открывающая сбоку в окне лог работы avrdude.

А давайте-ка прошьём какой-нибудь другой МК — например, ATtiny13.

Поставим МК на макетку, подсоединим к ней все линии разъёма ISP от нашего bit-bang-программатора, прицепим светодиод через резистор на 500 Ом к 3-й ножке (DB4) и подтянем RESET к питанию резистором на 10 кОм:

Пишем в любимом текстовом редакторе простой код простой мигалки светодиодом в файл blink.c:

#include <avr/io.h>
#include <util/delay.h>

enum { LED_BIT = 1 << PORTB4 };

int main()
{
  DDRB |= LED_BIT;

  while (1)
  {
    PORTB |= LED_BIT;
    _delay_ms(500);
    PORTB &= ~LED_BIT;
    _delay_ms(500);
  }
}

Компилируем:

avr-gcc -DF_CPU=1200000 -Os -mmcu=attiny13 blink.c -o blink.out

Делаем hex-файл прошивки:

avr-objcopy -O ihex blink.out blink.hex

Заливаем на МК:

avrdude -c ftbb -P ft0 -p attiny13 -B 9600 -U flash:w:blink.hex

Загрузка пошла:

burjui@blackbox:~/tmp$ avrdude -c ftbb -P ft0 -p attiny13 -B 9600 -U flash:w:blink.hex
avrdude: BitBang OK
avrdude: pin assign miso 3 sck 5 mosi 6 reset 7
avrdude: drain OK

ft245r:  bitclk 4800 -> ft baud 2400
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9007
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
        To disable this feature, specify the -D option.
avrdude: erasing chip
ft245r:  bitclk 4800 -> ft baud 2400
avrdude: reading input file "blink.hex"
avrdude: input file blink.hex auto detected as Intel Hex
avrdude: writing flash (78 bytes):

Writing | ################################################## | 100% 0.64s



avrdude: 78 bytes of flash written
avrdude: verifying flash memory against blink.hex:
avrdude: load data flash data from input file blink.hex:
avrdude: input file blink.hex auto detected as Intel Hex
avrdude: input file blink.hex contains 78 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.50s



avrdude: verifying ...
avrdude: 78 bytes of flash verified

avrdude: safemode: Fuses OK

avrdude done.  Thank you.

Перевтыкаем Arduino в USB и наблюдаем мигание светодиода при условии, что нет ошибок подключения (:

Вот так, путём нехитрых манипуляций руками и мозгами, можно сделать себе USB ISP-программатор, так что не нужно париться с отсутствием LPT на современных компах и COM-порта почти на любом ноутбуке — уж USB-то есть везде.


7 комментариев на «“Делаем ISP-программатор из Arduino”»

  1. Спс!!! Как раз делаю клон мелкий на атмега8а для ночника (нашел по очень смешной цене в дип корпусе меньше 2$) а вот прошивкой никогда не занимался(((

    • Похоже, что нет, т.к. там вместо FT232RL установлен МК ATmega32U со спец прошивкой. Во всяком случае, для такого функционала придётся писать свою прошивку (мегагемор).

Добавить комментарий

Arduino

Что такое Arduino?
Зачем мне Arduino?
Начало работы с Arduino
Для начинающих ардуинщиков
Радиодетали (точка входа для начинающих ардуинщиков)
Первые шаги с Arduino

Разделы

  1. Преимуществ нет, за исключением читабельности: тип bool обычно имеет размер 1 байт, как и uint8_t. Думаю, компилятор в обоих случаях…

  2. Добрый день! Я недавно начал изучать программирование под STM32 и ваши уроки просто бесценны! Хотел узнать зачем использовать переменную типа…

3D-печать AI Arduino Bluetooth CraftDuino DIY Google IDE iRobot Kinect LEGO OpenCV Open Source Python Raspberry Pi RoboCraft ROS swarm ИК автоматизация андроид балансировать бионика версия видео военный датчик дрон интерфейс камера кибервесна манипулятор машинное обучение наше нейронная сеть подводный пылесос работа распознавание робот робототехника светодиод сервомашинка собака управление ходить шаг за шагом шаговый двигатель шилд юмор

OpenCV
Робототехника
Будущее за бионическими роботами?
Нейронная сеть - введение