Как я уже упоминал, вместе с выходом Arduino 1.0 мы получим также и плату Arduino Leonardo:
Доподлинно известно, что на этой плате будет всего один чип ATmega32u4 с кварцем 16МГц. Ранее мы могли наблюдать, как старый добрый мост FT232RL был заменен на ATmega8u2 с нативной поддержкой интерфейса USB и прошивкой конвертера USB-TTL. Делалось это под флагом "преврати свой Arduino Uno во что угодно", но креатив USB-части должен был обязательно уложиться в 8К флеш-памяти. Идею продолжил Leonardo - памяти больше, но чипов меньше.
Сама идея не так уж и нова - платы на
ATmega32u4 в роли единственного и главного чипа существуют уже сейчас - это и
Teensy, и
ATmega32u4 breakout, и
Freeduino ATmega32u4 made by MK90.RU. Появление поддержки в ArduinoIDE перемещает эти платы на принципиально новый уровень - теперь можно использовать "родное" ядро Arduino, которое отныне включает поддержку ATmega32u4. Схема загрузки скетчей остается прежней - через бутлоадер, который принимает скетч по USB и записывает в основную память, а затем передает ему управление. Откомпилированный скетч по-прежнему содержит внутри библиотеку-"ядро" Arduino, и, в случае компиляции под ATmega32u4, туда добавляется поддержка USB.
ArduinoIDE позволяет выбирать, какое именно USB-устройство должен эмулировать Leonardo - по умолчанию это последовательный порт через драйвер CDC, в качестве альтернативы доступны мышь и клавиатура.
Бутлоадер гарантированно активируется нажатием на кнопку сброса. Замечу, что в большинстве случаев нажимать ее не придется, ограничиваясь командой Upload из меню File ArduinoIDE. Перед началом загрузки среда инициирует сброс через USB, но тут есть тонкий момент - чтобы это сработало в плате с единственным MCU, необходима поддержка в функционирующем в данный момент скетче.
В принципе - все логично. Если раньше старт бутлоадера осуществлялся через линию DTR, физически подключенную к линии сброса MCU, то теперь такой возможности нет: если скетч завис намертво (предусмотрительно запретив перед этим прерывания), придется вам все-таки нажать на кнопку сброса руками. Однако, если до этого момента туда был загружен и нормально работал какой угодно скетч - встроенный в ядро Arduino обработчик самосброса "подхватит" запрос по USB и вызовет бутлоадер. В документации на ATmega32u4 сообщается, что передача управления бутлоадеру возможна и при обнаружении сброса шины USB, но Arduino использует создание магической ситуации "открытый на 1200 бод порт был закрыт".
Приглядимся повнимательнее к самому MCU (разумеется, при помощи даташита). ATMEL выпустил его только в SMD-исполнении, но зато сразу в корпусе TQFP44, что по сравнению с текущим Arduino UNO SMD на ATmega328P-AU в корпусе TQFP32 дает надежду на некий прирост числа пинов.
Чтобы окончательно расставить точки над ё, я набросал небольшую таблицу:
Параметр | ATmega328P-AU | ATmega32u4-AU |
Flash | 32K | 32K |
SRAM | 2K | 2.5K |
EEPROM | 1K | 1K |
Пины
универсальные | 23 | 26 |
JTAG | нет | есть |
USB | программный/Low Speed | аппаратный 2.0 Full/Low Speed |
PLL | нет | 32..96 МГц, таймер |
Таймер 8-битный | 2 | 1 |
Таймер 16-битный | 1 | 2 |
ШИМ | 6 каналов | 4+4+6 |
АЦП | 8 каналов | 12 каналов |
USART | 1 | 1 |
SPI | есть | есть |
Как видите - и вправду чуть лучше. Массу новых функций привносит USB - в частности, на кристалле поселился PLL. Его можно заставить работать вместе со скоростным таймером или ШИМ-каналом.
Под программным USB для ATmega328 я понимаю
V-USB от Objective Development, о которой я неоднократно
писал. С одной стороны - нельзя сказать, что программный USB уж такой игрушечный, но и аппаратная поддержка FullSpeed - довольно неплохо, особенно в плане совместимости.
ШИМ-каналы у 32u4 могут быть не только строго 8-битными, но произвольной разрядности от 2 до 16 бит. Запись 4+4+6 символизирует 4 восьмибитных, 4 шестнадцатибитных и шесть высокоскоростных 10-битных каналов. Если рассматривать это с точки зрения Arduino - мы получаем в Leonardo плюс один PWM-пин.
Забегая вперед, обращаю внимание на то, что USART и USB естественным образом занимают разные пины - в отличие от Duemilanova или UNO, где обмен по USART автоматически означает прием/передачу по USB.
Кстати, все контроллеры прошиваются бутлоадером еще на заводе, что в принципе - удобно, можно запрограммировать когда угодно, не заботясь о вилке для программирования через JTAG или ISP.
Вроде бы основные общие моменты кратко разобраны. В сущности, платы MKBoard / Metaboard - это некие предшественники ATmega32U4-плат, построенные по тому же принципу. Перед тем, как переходить к Leonardo, рассмотрим чуть подробнее существующие платы на ATmega32u4.
Teensy
Сейчас существуют два варианта Teensy, все они строятся на MCU ATMEL с поддержкой USB - Teensy 2.0 на 32u4, а Teensy++ 2.0 - на AT90USB1286:
Teensy поставляется с
собственным прошитым bootloader-ом, исходников к которому - нет. Зато есть описание протокола обмена и исходники
утилиты командной строки, которая по этому протоколу взаимодействует с бутлоадером. Сам бутлоадер занимает всего 512 байт, так что для скетчей остается 32256 байт свободного места.
Светодиод на этой плате подключен к пину PD6 - он же будет digitalPin6 в режиме совместимости с ArduinoIDE. При этом нумерация пинов для скетчей будет следующей:
Не считая казуса с закрытыми исходниками бутлоадера, это отличная плата - поддерживается работа USB в режиме последовательного порта, мыши, клавиатуры, джойстика, MIDI, MASS STORAGE. Поскольку появилась она раньше остальных, то уже успела приобрести расширения синтаксиса по сравнению со стандартными библиотеками Arduino, например Serial.dtr() или Serial.rts(). Да и поддержка Arduino 1.0 уже есть, а значит проект более чем жив ;)
По сути - это копия платы
ATmega32u4 Breakout board+ от ladyada, немного улучшенная в схеме подключения к USB. Идея - та же, что и у Teensy, но применяется бутлоадер с
открытым исходным кодом. Видимо, по этой же причине он занимает все
4К и требует для активизации
обязательного нажатия на кнопку. В бутлоадере реализован протокол avr109 - соответственно, для его программирования можно использовать avrdude. После нажатия, в течение ~10 секунд бутлоадер будет готов к приему скетча, сообщая об этом при помощи светодиода "BOOT", подключенного к
PE6 (второй светодиод просто включен в цепь питания).
Положительный момент - загрузка происходит практически моментально, программирование всей свободной памяти занимает около 2 сек. И если 28К все-таки не хватает, авторы предлагают воспользоваться программатором (отлично подойдет, например,
USBasp) - благо присутствует вилка программирования ISP6.
Для работы с платой в ArduinoIDE можно инсталлировать окружение Teensy, слегка изменив boards.txt, переписав avrdude более свежей копией, и заменой для порядка VID/PID и дескриптора USB. Подробно про это написано
здесь. Забегая вперед, замечу, что процесс добавления платы в окружение ArduinoIDE 1.0 значительно проще.
На всеобщее обозрение в блоге Arduino была вывешена эта картинка:
Вот так выглядит увеличенный Леонардо:
Стандартный форм-фактор Arduino, но присмотритесь внимательнее: число пинов на верхней левой колодке увеличилась с 8 до 10, а на нижней левой - с 6 до 8. То есть - и сверху, и снизу добавлено по два пина. Да и в ширину плата добавила пару-тройку миллиметров...
Попытки расширить нижнюю левую колодку уже предпринималась командной Seeedstudio - они поместили туда два дополнительных входа АЦП, которые присутствуют в SMD-корпусе ATmega328:
Не думаю, что Arduino-вцы скопируют это решение, поскольку заявленное число аналоговых пинов - по-прежнему шесть (см. последнее число на картинке, однако на той же картинке написана откровенная ерунда - например, что в 32u4 SRAM размером 3.3К).
Бутлоадер Arduino Leonardo занимает 2К.
С точки зрения ArduinoIDE, Leonardo имеет 18 цифровых универсальных пинов и 6 аналоговых. Пины с аппаратной поддержкой I2C переехали - теперь это digital3 (SCL) и digital2 (SDA). Пины с поддержкой SPI - с 14 по 17, логично что они и должны попасть на колодку ISP6, за исключением пина №14 - (PB0 или SS), к которому подключен светодиод. Светодиодов у Leonardo более чем достаточно: RX, TX, L - расположенные на портах B0, D5 и C7 соответственно. L по-прежнему подключен на digital13, RX - к digital14, а вот TX почему-то не имеет соответствия в таблице пинов. Неясно, связано ли это как-то с присутствием пинов на внешних колодках; но быть может что-то прояснится после оглашения "изменений в стандартной раскладке колодок Arduino" - найти текущее расположение на официальном сайте не удалось, а все существующие знания приходилось черпать напрямую из board layout-ов официально выпущенных плат.
С точки зрения программирования, для обмена через USB по-прежнему используется Serial. Но USART в этом участия уже не принимает - чтобы обмениваться именно через пины RX/TX, надо использовать Serial1. Разделение USB и USART - одно из существенных преимуществ платы, по сравнению с Duemilanova и Uno.
При обмене через USB постоянно помаргивают светодиоды RX/TX, но сам факт того, что RX одновременно закреплен за SS, никак не влияет на работу SPI - поддержка этой шины в ArduinoIDE просто инициализирует пин SS в OUTPUT/HIGH и больше "не трогает" - если необходимо организовывать обмен с несколькими slave-устройствами, роль SS может исполнить любой цифровой пин.
Leonardизация Freeduino 32u4
А что, вообщем-то, мешает превратить Freeduino 32u4 (или любую другую плату с одним 32u4 "на борту") в Leonardo? По большому счету - ничего. Гораздо удобнее не нажимать на сброс всякий раз при загрузке скетча и иметь в запасе два лишних килобайта памяти программ.
Теоретически, для этого надо всего лишь создать правильную раскладку-соответствие пинов Freeduino 32u4 и Leonardo:
Свой выбор именно такой раскладки я объясняю двумя моментами: цифровые пины 0 и 1 всегда закреплялись за последоватльным портом, а пин 13 - за светодиодом L. Поскльку нет светодиодов RX и TX, можно задействовать PD5 и а) получить дополнительно еще один цифровой пин 18 б) сохранить функции и нумерацию пинов SPI как в Leonardo в) сохранить последовательную нумерацию пинов с 13 по 18. Взамен приходится "жертвовать" пином 12, который неожиданно занял место между последним (digital18) и первым (digital0). Тем не менее, если кому-то захочется все исправить и нарисовать более удобное расположение - милости прошу в
форум ;)
Нужно распаковать файл в arduino-1.0/hardware/arduino и исправить boards.txt, добавив туда содержимое файла boards.txt.add:
leonardo1.name=Freeduino 32u4
leonardo1.upload.protocol=arduino
leonardo1.upload.maximum_size=30720
leonardo1.upload.speed=1200
leonardo1.bootloader.low_fuses=0xde
leonardo1.bootloader.high_fuses=0xda
leonardo1.bootloader.extended_fuses=0xcb
leonardo1.bootloader.path=diskloader
leonardo1.bootloader.file=DiskLoader-Leonardo.hex
leonardo1.bootloader.unlock_bits=0x3F
leonardo1.bootloader.lock_bits=0x2F
leonardo1.build.mcu=atmega32u4
leonardo1.build.f_cpu=16000000L
leonardo1.build.core=arduino
leonardo1.build.variant=freeduino32u4
Но есть одна несостыковка, которую надо пофиксить именно в ядре - это касается аппаратного ШИМ, который для ATmega32u4 не будет работать на трех пинах из заявленных семи. Причина - ошибки в ядре, которые, видимо, будут исправлены синхронно с выпуском новой платы. Чтобы решить задачу в рамках текущей ArduinoIDE, надо загрузить исправленное core:
freeduino32u4-core-arduino1.0rc1.tar.gz и распаковать его в
arduino-1.0rc1/hardware/arduino/, заменив существующее cores/arduino на новое.
Все, готово! Мы получили возможность поработать с Leonardo еще до выхода оригинальной платы. Если бы не публикация ArduinoIDE RC1, это было бы невозможно, за что моя отдельная признательность авторам ;)