Atmega как usb host

Обновлено: 07.07.2024

Разработка различных устройств на основе микроконтроллеров — занятие, достойное настоящего компьютерного гика. Несомненно, полезной фишкой любого гаджета будет USB-интерфейс для подключения к компьютеру. Но что делать, если в микросхеме AVR не предусмотрена аппаратная поддержка USB?

V-USB: размер имеет значение

При разработке собственного гаджета часто встает проблема его подключения к компьютеру. Надо сказать, что порты LPT и COM — теперь экзотика на материнских платах ПК, не говоря о ноутбуках, у которых эти интерфейсы исчезли давным-давно. Поэтому у современных компьютеров практически не осталось альтернатив интерфейсу USB.

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

Для микроконтроллеров Atmel существует замечательный проект V-USB, который предлагает программную реализацию низкоскоростного устройства USB 1.1. Код V-USB будет работать на любом устройстве AVR, у которого есть хотя бы 2 Кб Flash-памяти и 128 байт ОЗУ, с тактовой частотой 12; 12,8; 15; 16; 16,8 или 20 МГц.

Использование продукта возможно как в рамках open source лицензии GPL, так и на коммерческой основе. Для того чтобы разрабатывать собственные USB-устройства, обычно также нужно покупать что-то вроде лицензии. Но ребята из V-USB позаботились и об этом, приобретя пару Vendor ID — Product ID и разрешив их использовать любому желающему.

Аппаратная обвязка для подключения USB-шины к микроконтроллеру очень простая. Если устройство потребляет не слишком много, то запитать его можно прямо от шины (считается, что линия питания USB компьютера способна отдавать ток до 500 мА). Так как информационные линии (D+ и D–) используют уровень сигнала 3,6 В, кроме токоограничивающих резисторов, необходимы стабилитроны для согласования с 5-вольтовой логикой чипа. Чтобы обозначить тип подключения, нужно «подтянуть» напряжение питания через сопротивление 1,5 кОм к линии D–.

Подключение USB к микроконтроллеру ATtiny2313

Подключение USB к микроконтроллеру ATtiny2313

Альтернативный вариант сопряжения по USB — снизить напряжение питания контроллера посредством соответствующей микросхемы стабилизации или просто парой диодов. Последнюю схему можно найти на сайте проекта V-USB.

Программатор USBtiny

Для микроконтроллеров AVR существует множество различных программаторов. USBtiny здесь упоминается, в частности, потому, что содержит программную реализацию USB, аналогичную V-USB. Схема этого программатора проста: версия 2 содержит две микросхемы, а первая версия — лишь одну (собственно чип ATtiny2313). Благодаря подробному описанию на сайте и простым комплектующим устройство легко сделать даже начинающему. USBtiny совместим с популярной программой avrdude, используемой для программирования микроконтроллеров AVR.

prog

Единственная проблема заключается в заливке прошивки в чип программатора — для этого нужен… программатор. Если есть компьютер с LPT-портом, то можно сделать один из вариантов FBPRG ака «пять проводков», который железно

Готовим санки

Программный инструментарий, необходимый для реализации простейшей прошивки USB-гаджета, предельно аскетичен: компилятор gcc-avr, библиотека avr-libc, программатор avrdude и набор binutils для AVR. В Debian/Ubuntu все, что нужно, устанавливается одной командой:

Работа с программатором avrdude

Работа с программатором avrdude

Чтобы воспользоваться лицензией V-USB для устройства, числовые идентификаторы производителя и устройства изменять не надо. А вот символьные имена можно выбрать по своему вкусу (они позволят отличить несколько устройств на основе V-USB, подключенных к одному и тому же компьютеру):

Разнообразные гаджеты

У тебя есть идея какого-нибудь устройства? Не спеши паять и кодить, а поищи, возможно, кто-то подобное уже делал. Если не получится воспользоваться готовыми схемами и исходниками, то хотя бы не придется начинать все с нуля.

Например, проект V-USB благодаря лицензионной политике накопил приличную базу готовых (в том числе и свободно распространяемых) решений. Здесь можно найти различные реализации клавиатур, USB-адаптеров для джойстиков, геймпадов (в том числе и раритетных, например SNES/NES, Nintendo 64, ZX Spectrum джойстик, Sony PlayStation 1/2) и тому подобное. Адаптеры DMX, виртуальные порты COM и UART, i2c, Servo, беспроводные интерфейсы DCF77, IR — все, что поможет подключить к ПК больше новых устройств. Логгеры, платформы для датчиков и сенсоров, адаптеры для LCD-дисплеев, программаторы и загрузчики также могут оказаться полезными в хозяйстве.

Программа для чипа — элементарно!

Создадим файл main.c на одном уровне с папкой usbdrv и опишем в нем необходимые заголовочные файлы, определения и переменные:

В main.c переопределим функцию usbFunctionSetup, которая вызывается автоматически при получении нового запроса:

Собственно, функция usbFunctionWrite занимается тем, что заполняет буфер replyBuf полученными данными.

Кстати, чтобы этот метод работал, нужно внести изменения в usbconfig.h:

Ну и последняя функция прошивки — main:

Задействуем USART/UART

Хорошая альтернатива программному/аппаратному USB — использование в чипе популярного интерфейса USART/UART со сторонним преобразователем этого протокола в USB, который можно выполнить, например, на основе микросхемы FT232RL.

Libusb: и не одетая, и не обнаженная

Ты спросишь: а придется ли писать драйвер для операционной системы компьютера, чтобы подключить USB-устройство? Если использовать libusb, то можно обойтись без реализации полноценного модуля ядра. Libusb — это open source библиотека, которая позволяет быстро запрограммировать, во-первых, поиск устройства на шине, а во-вторых — обмен данными с ним.

Под Linux библиотеку и необходимые заголовочные файлы можно получить из исходных кодов. А лучше воспользоваться стандартным репозиторием твоего дистрибутива. Для Debian/Ubuntu, например, так:

Существует также порт libusb под Windows — libusb-win32. Вопреки названию проекта, также поддерживаются 64-битные ОС от Microsoft (начиная с версии 1.2.0.0).

Но libusb — это отдельная тема разговора. Думаю, с программированием для ПК ты знаком и сможешь в этом разобраться сам. Поэтому буду краток. Создаем файл usbtest.c и начинаем наполнять его контентом. Сначала необходимые заголовочные файлы и определения:

Функция usbOpenDevice для инициализации устройства:

Как видно, параметрами usbOpenDevice выступают числовые идентификаторы производителя и устройства. В случае если устройство присутствует на шине, возвращается его дескриптор. Если устройств на V-USB будет несколько — придется дописать проверку символьных имен вендора и продукта.

И функция main консольной утилиты usbtest:

Proteus отдыхает

Всенародно любимый симулятор электрических схем Proteus ISIS бесполезен при разработке устройств с программной реализацией USB. Его эмулятор USB поддерживает только чипы с аппаратной поддержкой универсальной последовательной шины (например, AT90USB646 или AT90USB1286).

Собираем, прошиваем, тестируем

Ниже приведен небольшой, но очень полезный Makefile, c помощью которого командой make из main.c и usbtest.c легко получить прошивку для чипа — main.hex и бинарник утилиты usbtest:

Чтобы залить прошивку в микроконтроллер с помощью программатора usbtiny, набираем команду:

В avrdude фьюзы задаются не слишком наглядно, но их можно легко рассчитать в одном из online-калькуляторов.

Online-калькулятор фьюзов

Online-калькулятор фьюзов

Подключаем устройство к компьютеру и проверяем, как оно работает (usbtest c параметром out считывает строку, in — записывает указанную строку в буфер чипа):

Тестирование взаимодействия с ATtiny2313 по USB (заливаем в чип строку, а затем cчитываем ее)

Тестирование взаимодействия с ATtiny2313 по USB (заливаем в чип строку, а затем cчитываем ее)

Ложка дегтя

Софтовый USB не есть панацея. Программные реализации обычно имеют ряд упрощений, таких как отсутствие проверки контрольной суммы и симметричности канала, что отрицательно сказывается на помехозащищенности. Также обычно софтовые библиотеки используют низкоскоростные режимы работы USB. Да и код USB-библиотеки «кушает» и без того небольшую память чипа.

Подглядываем…

На уровне логики протокол USB — это, по сути, многоуровневая пакетная передача данных. В этом нетрудно убедиться (а заодно узнать много интересного про USB), воспользовавшись анализатором сетевых протоколов Wireshark. Предварительно необходимо загрузить драйвер USB-монитора:

Теперь в списке интерфейсов Wireshark можно выбирать шины USB. Посмотреть номер шины устройства можно, например, в логах.

Перехват USB-пакетов в Wireshark

Перехват USB-пакетов в Wireshark

  • Сайт проекта V-USB;
  • сайт проекта libusb;
  • сайт проекта libusb-win32; про V-USB и libusb (англ.);
  • статья про libusb, часть 1;
  • статья про libusb, часть 2; на основе V-USB;
  • сайт проекта USBtiny;
  • сайт проекта AVReAl; фьюзов.

Заключение

Надеюсь, после того, как ты научился пересылать данные между компьютером и микроконтроллером AVR, твоя страсть к электронике воспылает с новой силой, породив немало оригинальных и полезных устройств. Остается лишь пожелать тебе успехов на этом сложном, но интересном поприще.

Здесь приведен перевод документации Atmel AVR4950: ASF - USB Host Stack [1], посвященной библиотеке для реализации хоста USB с помощью микроконтроллеров AVR. Для этой библиотеки подойдут не все, а строго определенные модели микроконтроллеров AVR и AVR32, которые имеют на борту аппаратный интерфейс USB со встроенной поддержкой функции хоста USB. Список поддерживаемых микроконтроллеров приведен ниже во врезках.

[Поддержка только устройства USB]

AT90USB1286, AT90USB162, AT90USB646, AT90USB82, ATmega16U2, ATmega16U4, ATmega32U2, ATmega32U4, ATmega8U2, ATxmega128A1U, ATxmega128A3U, ATxmega128A4U, ATxmega128B1, ATxmega128B3, ATxmega128C3, ATxmega16A4U, ATxmega16C4, ATxmega192A3U, ATxmega192C3, ATxmega256A3BU, ATxmega256A3U, ATxmega256C3, ATxmega32A4U, ATxmega32C3, ATxmega32C4, ATxmega384C3, ATxmega64A1U, ATxmega64A3U, ATxmega64A4U, ATxmega64B1, ATxmega64B3, ATxmega64C3.

[Поддержка устройства USB и OTG]

Для удобного выбора различных моделей микроконтроллеров см. табличный селектор Atmel [3].

[Поддержка только устройства USB]

AT32UC3B1128, AT32UC3B1256, AT32UC3B1512, AT32UC3B164, ATUC128D3, ATUC128D4, ATUC128L3U, ATUC128L4U, ATUC256L3U, ATUC256L4U, ATUC64D3, ATUC64D4, ATUC64L3U, ATUC64L4U.

[Поддержка устройства USB и OTG]

AT32UC3A0128, AT32UC3A0128AU, AT32UC3A0256, AT32UC3A0256AU, AT32UC3A0512, AT32UC3A0512AU, AT32UC3A1128, AT32UC3A1256, AT32UC3A1256AU, AT32UC3A1512, AT32UC3A1512AU, AT32UC3A3128, AT32UC3A3128S, AT32UC3A3256, AT32UC3A3256AU, AT32UC3A3256S, AT32UC3A364, AT32UC3A364S, AT32UC3A4128, AT32UC3A4128S, AT32UC3A4256, AT32UC3A4256S, AT32UC3A464, AT32UC3A464S, AT32UC3B0128, AT32UC3B0128AU, AT32UC3B0256, AT32UC3B0512, AT32UC3B0512AU, AT32UC3B064, AT32UC3C0128C, AT32UC3C0256C, AT32UC3C0512C, AT32UC3C0512CAU, AT32UC3C064C, AT32UC3C1128C, AT32UC3C1256C, AT32UC3C1512C, AT32UC3C164C, AT32UC3C2128C, AT32UC3C2256C, AT32UC3C2512C, AT32UC3C264C.

Для удобного выбора различных моделей микроконтроллеров см. табличный селектор Atmel [3].

Основные возможности библиотеки:

Пока что альтернатив этой библиотеке практически нет, за исключением LUFA.

Стек USB хоста (библиотека), описываемый в этом документе, включен в фреймворк ASF Atmel® (сокращение от AVR Software Framework), и он предназначен для предоставления пользователю самого быстрого и простого пути построения приложения хоста USB на основе микроконтроллеров. Также этот стек хоста USB ориентирован на малый объем кода и низкое потребление энергии. Все непонятные термины и сокращения см. в разделе Словарик, к конце статьи.

[Документация по теме приложений хоста USB]

Компания Atmel предоставила несколько примеров приложений хоста USB. К каждому примеру имеется несколько апноутов (см. рисунок ниже).

ASF USB host appnotes fig3 1

Рис. 3-1. Апноуты примеров приложений хоста USB.

Для изучения этих апноутов требуются базовые знания по классам хоста USB (классы HID, CDC, MSC, PHDC, AUDIO). Для создания хоста USB для одного из предоставленных в ASF классов, обращайтесь напрямую к апноуту, посвященному соответствующему классу USB. Апноуты стека хоста USB и класса вендора хоста (USB host vendor class) разработаны для опытных разработчиков приложений USB.

[Обзор архитектуры библиотек]

Стек хоста USB функционально разделен на 3 части:

• USB Host Controller (UHC), предоставляющий совместимость со стандартном USB часть 9.
• USB Host Interface (UHI), предоставляющий совместимость с классом USB.
• USB Host Driver (UHD), предоставляющий интерфейс USB для каждого продукта Atmel (имеются в виду микроконтроллеры с аппаратным интерфейсом, имеющими поддержку хоста USB).

Примечание: драйверы хоста USB реализованы в режиме полной поддержки прерываний, так что этот UHD отличная база для создания драйвера USB для стеков USB от сторонних производителей. Это относится либо к пользовательскому интерфейсу, либо к интерфейсу OHCI/EHCI.

ASF USB host stack architecture fig4 1

Рис. 4-1. Архитектура стека хоста USB.

В случае двойного режима (устройство/хост) имеется описание стека устройства USB в апноуте "AVR4900: ASF – USB Device stack".

Затраты памяти на стек USB зависят от:

• Используемого ядра Atmel (megaAVR®, UC3).
• Версии аппаратуры USB.
• Используемого класса USB.
• Используемого компилятора и уровня оптимизации.

Различные комбинации этих параметров дают разные затраты на используемую память, но обычно стек хоста USB требует не больше 10 килобайт FLASH и 1 килобайт RAM при использовании самого высокого уровня оптимизации компилятора.

Файлы стека хоста USB. Примеры стека доступны в Atmel AVR Studio® 5, если запустить визард создания нового проекта (New Example Project wizard) и выбрать ASF Modules wizard. Можно выбрать примеры хоста из списка или ввести в поле поиска host. Совет: выберите раздел Technology USB чтобы уменьшить список отображаемых примеров в AVR Studio 5.

Примечание: имена примеров, включающих "From ASF V1" относятся к предыдущей реализации стека хоста USB из ASF v1.7, которая выходит за рамки этого апноута.

Файлы, общие для всех микроконтроллеров, описаны в таблице ниже.

Примечание *: эти файлы используются совместно со стеком устройств USB.

Файлы UHD, зависящие от выбранного микроконтроллера:

• avr32/drivers/usbb/usbb_host.c/h
• avr32/drivers/usbb/usbb_otg.h*
• avr32/drivers/usbc/usbc_host.c/h
• avr32/drivers/usbc/usbc_otg.h*

Примечание *: эти файлы используются совместно со стеком устройств USB.

Файл, относящийся к специфике каждого определенного приложения. Для конфигурации стека хоста USB используется файл приложения (см. часть "Конфигурация" и таблицу 5-3) usb_conf_host.h.

[API]

В этой части описывается все API, кроме UHI API, которому посвящен отдельный документ [4, 5].

ASF USB host modules fig5 1

Рис. 5-1. Модули USB.

Внешнее API от UHC. Внешнее UHC API позволяет приложению обслуживать общее поведение хоста USB и принимать общие события хоста USB. Это управление и обработка событий являются общими для всех приложений USB.

ASF USB host External API from UHC

Таблица 5-1. Внешнее API UHC – функции ввода.

Таблица 5-2. Внешнее API UHC – функции ввода, относящиеся к подключенным устройствам.

Все UHC callback-и являются опциональными, и для каждого приложения определяются пользователем в файле conf_usb_host.h.

Таблица 5-3. Внешнее API UHC – Callback-функции.

Внутреннее API. Следующие определения применяются для квалифицированных пользователей, которые нуждаются в разработке специфического хоста USB, который не предоставлен в ASF.

ASF USB host Internal API overview fig5 2

Рис. 5-2. Обзор внутреннего API хоста USB.

Примечание: цифры на рисунке относятся к таблицам ниже.

Таблица 5-4. Ввод UHI из UHC (1).

Примечание: UHI API сохранено в массиве USB_HOST_UHI, см. таблицу 7-1.

Таблица 5-5. Ввод UHC из UHD (3).

Таблица 5-6. Ввод UHD (4).

Таблица 5-7. UHD callback (5).

Таблица 5-8. Ввод UHD, только для совместимости с приложением High Speed (4).

Информация о подключенном устройстве USB. UHC обслуживает устройства через структуру uhc_device_t, которая сохраняет множество данных об устройствах, подключенных к дереву USB.

Глобальная переменная g_uhc_device_root содержит информацию о первом подключенном устройстве, и это первый элемент в списке устройств.

Приложение пользователя может читать этот список, чтобы получить информацию о текущем состоянии дерева USB.

Примечание: здесь нет ограничения на дерево USB, потому что список устройств и выделение памяти на поля дескрипторов USB динамические, и требуют наличия стандартной библиотеки для выделения памяти (например alloc()).

Структура uhc_device_t включает:

• Указатель на дескриптор устройства USB.
• Указатель на дескриптор конфигурации устройства USB.
• Адрес устройства USB.
• Скорость устройства USB.
• Указатели на родительское устройство хаба USB HUB (только для поддержки USB HUB).
• Номер порта HUB, с которым осуществлено соединение (только для поддержки USB HUB).

ASF USB host uhc device t definition fig5 3

Рис. 5-3. Определение uhc_device_t.

[Поведение стека хоста USB]

В этой части содержатся ответы на вопросы продвинутого использования USB, и здесь описано поведение стека хоста USB. Последующие секции описывают взаимодействие между разными слоями вот этих шагов:

• Управление двойной ролью USB.
• Управление USB VBUS.
• Управление соединением с устройством USB.
• Управление энумерацией устройств USB.

Двойные роли. Когда аппаратура USB может работать в режиме устройства USB и в режиме хоста USB, пользователь может реализовать приложение с двойной ролью. Это приложение будет переключаться задачами между устройства USB и хоста USB в зависимости от уровня на выводе идентификации (USB ID pin, в соответствии со стандартом USB OTG).

Стек хоста USB предоставляет 3 возможности управления двойной ролью: ручное, полуавтоматическое и автоматическое. Ручной вариант управления ролью должен использоваться тогда, когда нет вывода идентификации (ID pin). В этом случае процесс пользователя управляет выбором роли. Полуавтоматический и автоматический варианты должны использоваться тогда, когда ID pin обслуживается аппаратурой интерфейса USB.

Полуавтоматический вариант управления двойной ролью позволяет отложить запуск режима устройства USB и режима хоста USB, когда меняется состояние ID pin. Эта возможность разрешается, когда имеется определение UHD_START_MODE_MANUAL (см. таблицу 7-2).

ASF USB host manual dual role fig6 1

Рис. 6-1. Ручное управление двойной ролью USB.

ASF USB host semi automatic dual role fig6 2

Рис. 6-2. Полуавтоматическое управление двойной ролью USB.

ASF USB host automatic dual role fig6 3

Рис. 6-3. Автоматическое управление двойной ролью USB.

Управление VBUS.

ASF USB host VBUS management fig6 4

Рис. 6-4. Управление VBUS.

Соединение с устройством USB.

ASF USB host device connection fig6 5

Рис. 6-5. Соединение с устройством USB.

Примечание: эта последовательность одинакова для устройств, подключенных через хаб USB HUB, но события соединения и сброса управляются через запрос USB HUB setup. Когда энумерация устройства USB терпит неудачу 4 раза, сигнальная линия USB устройства устанавливается в режим приостановки (USB SUSPEND mode).

Энумерация устройства.

ASF USB host device enumeration single USB configuration fig6 6

Рис. 6-6. Энумерация устройства USB (одиночная конфигурация USB).

Примечание: здесь не определен callback UHC_DEVICE_CONF(), так что по умолчанию выбирается конфигурация 1 устройства.

ASF USB host device enumeration multiple USB configuration fig6 7

Рис. 6-7. Энумерация устройства USB (с несколькими конфигурациями USB).

Ниже приведен пример кода для поддержки известного устройства с несколькими конфигурациями:

[Конфигурация]

Конфигурации приложения определяются в файле conf_usb_host.h. Этот файл должен быть создан для каждого приложения, и это действие требует базовых знаний принципов работы USB.

Файл conf_usb_host.h определяет следующие конфигурации:

• Конфигурация хоста USB.
• Конфигурация интерфейса хоста USB.
• Конфигурация драйвера хоста USB.

Конфигурация хоста USB. Следующая конфигурация должна быть включена в файл conf_usb.h приложения, и здесь содержится основная конфигурация поддерживаемого устройства USB.

Таблица 7-1. Конфигурация хоста USB.

Конфигурация интерфейса хоста USB. Конфигурации UHI описаны в отдельных апноутах классов хоста USB.

Конфигурация драйвера хоста USB. Аппаратный интерфейс USB может предоставить отдельные возможности, что управляется файлами conf_usb_host.h, conf_board.h и опциями проекта.

Таблица 7-2. Конфигурация драйвера хоста USB в файле conf_usb_host.h.

Таблица 7-3. Конфигурация драйвера хоста USB в файле conf_board.h.

Таблица 7-4. Конфигурация драйвера хоста/устройства USB в проекте.

[Поддержка USB HUB]

Стек хоста USB может поддерживать дерево USB через функцию USB HUB. Однако аппаратура интерфейса USB, предоставленная в микроконтроллерах Atmel, может ограничить дерево USB.

Примечание (1): чтобы избежать ограничения на количество каналов (pipes), возможно их мультиплексирование. Однако в этом случае планирование передач должно осуществляться программно (драйвером UHD) вместо аппаратуры USB.

[Энергопотребление]

Режимы энергопотребления, доступные в микроконтроллерах Atmel, поддерживаются аппаратурой USB. Все драйверы USB реализуют эту возможность из службы sleepmgr. Таким образом, должна быть выполнена инициализация этой службы вызовом sleepmgr_init() из приложения перед любым вызовом API стека USB.

Ядро AVR32. Для ядра AVR32 такты и генераторы могут быть автоматически выключены в периодах ожидания (idle) при выполнении инструкции sleep процессора CPU.

Таблица 9-1. Уровни сна, поддерживаемые драйверами хоста USBB и USBC.

Примечание: режимы сна, перечисленные здесь, не могут быть запущены, если любой другой программный модуль, не относящийся к стеку USB, требует менее глубокого режима сна.

[Словарик]

ACK Acknowledge, положительное подтверждение по шине USB (подробнее см. [3]).

API Application programming interface, интерфейс программирования.

ASF AVR Software Framework, библиотека для реализации различных функций от Atmel.

CBW Command Block Wrapper, обертка блока команды (термин относится к Mass Storage Class устройств USB).

CDC Communication Device Class, класс CDC устройств USB, предназначенных для обмена данными.

CSW Command Status Wrapper, обертка статуса команды (термин относится к Mass Storage Class устройств USB).

DP или D+ один из сигналов дифференциальной линии данных USB.

DM или D- второй сигнал дифференциальной линии данных USB.

EHCI Enhanced Host Controller Interface, расширенный интерфейс контроллера хоста.

FS USB Full Speed (12 мегабит/сек).

HID Human interface device.

HS USB High Speed (480 мегабит/сек.

LS USB Low Speed (1.5 мегабит/сек).

IN ACK подтверждение передачи типа IN (подробнее см. [2]).

MSC Mass Storage Class, класс USB для устройств хранения данных (флешки, внешние жесткие диски).

OHCI Open Host Controller Interface, открытый интерфейс контроллера хоста.

OTG On The Go, переводится "на лету". Термин означает, что система может при подключении выбирать режим работы интерфейса USB - т. е. может работать либо в качестве устройства USB, либо как хост USB. Режим работы определяется уровнем напряжения на специальном выводе идентификации режима (ID pin) на коннекторе USB.

OUT ACK подтверждение передачи типа OUT (подробнее см. [2]).

PHDC Peripheral Health Device Class.

PIPE буфер данных для обслуживания передачи конечной точки в режиме хоста.

sleepmgr Sleep management service, служба управления режимом сна из библиотеки ASF.

UDC USB Device Controller, контроллер устройства USB.

UDD USB Device Descriptor, дескриптор устройства USB.

UDI USB Device Interface, интерфейс устройства USB.

UHC USB Host Controller, контроллер хоста USB.

UHD USB Host Descriptor, дескриптор хоста USB.

UHI USB Host Interface, интерфейс хоста USB.

USB Universal Serial Bus.

USBB версия аппаратного интерфейса USB для платформы 32-битного ядра Atmel.

USBC версия аппаратного интерфейса USB на языке C для платформы 32-битного ядра Atmel.

SOF Start Of Frame, начало фрейма.

STALL токен USB, используемый для остановки транзакции по шине USB.

ZLP Zero length packet, пакет нулевой длины.

VBUS шина питания +5V интерфейса USB.

Примечание: дополнительную информацию по протоколу USB и его терминологии см. в статье [2].

USB ФЛЕШКА НА ATMEGA8 И V-USB. ОТ ИДЕИ К ГОТОВОМУ УСТРОЙСТВУ… Много букв, Easyelectronics, Technobrother, Код, Своими руками, Avr, Atmega, Atmega8, Длиннопост

Далее от Автора :
Прочитав пару статей других пользователей, захотелось самому начеркать чего-то полезного для остальных. Как все поняли из названия, речь пойдет о создании USB mass storage device класса на програмной реализации V-USB.

Сразу оговорюсь, что все приведенные фотки моего девайса тока для ознакомления, потому как это платка мой программатор AVR по USB со своим бутом и прогой для апдейту. Схему я конечно выложу, но плату разводить, наверное, специально для этого проекта, не буду.

USB ФЛЕШКА НА ATMEGA8 И V-USB. ОТ ИДЕИ К ГОТОВОМУ УСТРОЙСТВУ… Много букв, Easyelectronics, Technobrother, Код, Своими руками, Avr, Atmega, Atmega8, Длиннопост

Проект выполнен на IAR’е, sPlan, SprintLayout, Device Monitoring Studio и утюге под пиво =) Ну, в путь!

Для начала, немного теории. MSD или Mass Storage Class это ничто иное, как один из стандартных классов USB для описания и взаимодействия с утройствами хранения информации. Реализаций и стандартов MSD довольно много и заморачиваться на каждом из них нет смысла. Опишу самый распространенный из них(он же самый простой на мой взгляд): Bulk-only или BBB.

В стандарте USB есть такое понятие, как конечная точка(end-point). Конечная точка — это часть USB-устройства, которая имеет уникальный идентификатор и является получателем или отправителем информации, передаваемой по шине USB. Проще говоря, это буфер, сохраняющий несколько байт. Обычно это блок данных в памяти или регистр микроконтроллера. Данные, хранящиеся в конечной точке, могут быть либо принятыми данными, либо данными, ожидающими передачу. Хост также имеет буфер для приема и передачи данных, но хост не имеет конечных точек.

Конечная точка имеет следующие основные параметры:

1 - Частота доступа к шине

2 - Допустимая величина задержки обслуживания

3 - Требуемая ширина полосы пропускания канала

4 - Номер конечной точки

5 - Способ обработки ошибок

6 - Максимальный размер пакета, который конечная точка может принимать или отправлять;

7 - Используемый конечной точкой тип посылок

8 - Направление передачи данных

Любое USB-устройство имеет конечную точку с нулевым номером (Endpoint Zero). Эта точка позволяет хосту опрашивать устройство с целью определения его типа и параметров, выполнять инициализацию и конфигурирование устройства.

Кроме нулевой точки, устройства, обычно, имеют дополнительные конечные точки, которые используются для обмена данными с хостом. Дополнительные точки могут работать либо только на прием данных от хоста (входные точки, IN), либо только на передачу данных хосту (выходные точки, OUT). Число дополнительных конечных точек устройств определяется режимом передачи.

Для низкоскоростных устройств допускается наличие одной или двух дополнительных конечных точек, а для высокоскоростных — до 15 входных и 15 выходных дополнительных точек.

Но это тока теория, которая выглядит довольно абстрактно. Будем считать, что конечная точка, это ничто иное как фунция в языке C, которая тока принимает параметры, или только возвращает значения.

Так вот, мы строим устьройство, отвечающее спецификации bulk-only. И тут самое приятное: все события делятся на три фазы:

1 - Прием команды от хоста(копьютера)(CBW)

2 - Прием/Передача запрашиваемых данных(DATA)

3 - Передача хосту результата выполнения принятой комманды(STATUS)

USB ФЛЕШКА НА ATMEGA8 И V-USB. ОТ ИДЕИ К ГОТОВОМУ УСТРОЙСТВУ… Много букв, Easyelectronics, Technobrother, Код, Своими руками, Avr, Atmega, Atmega8, Длиннопост

Здесь видно, что мы принимаем данные и отправляем данные, значит мы имеем 2 конечные точки (от хоста к устройству и наоборот), а, исходя из выбранной спецификации, эти точки используют bulk передачу данных.

Следовательно мы должны сконфигурировать библиотеку V-USB соответсвующим образом:

1 - Описываем конечную точку-in

2 - Конечную точку-out

3 - Указываем v-USB, что мы используем 2 конечные точки помимо основной (control-endpoint)

4 - Задаем класс устройсва USB — Mass Storage Class Bulk-only (Не пугайтесь, все это легко видно из файлов прошивки).

На этом весь процесс создания устройства MSD bulk-only закончен и мы приступаем к тому, что принимаем от хоста комманды и соответсвенно реагируем на них!

Теперь вкратце о тех самых коммандах от хоста. Их не так много и большинство из низ поступают только пару раз. Итак хост может попросить от нас следующее:

Теперь далее. Пересмотрев массу устройств хранения информации (EEPROM, nand и т.д.) я выбрал, наверное, самое распространненое SD/MMC карту памяти. Подключение ее к AVRке давно известно, а протокол хорошо разжеван. Еще один плюс в том, что эти карты могут читать/писать по 512 байт данных, что очень подходит для данной задачи.

Так, основными коммандами MSD bulk-only устройстве являются чтение и запись блоков информации. Драйвер Windows (да простят меня пользователи Linux) обращается к нашему устройству по принципу LBA, то есть адрес логического блока (или его номер, что одно и тоже) и их количество.

В нашем случае один логический блок это сектор размером в 512 байт. Так если ОС запросит у нас данные из 20-го LBA, то мы просто умножим 20 на 512 и получим линейный адрес на устройстве носителя. Затем прочитем/запишем нужное число блоков и все! Знать что-то о данных на устройстве хранения информации и способе их размещения AVR не должна. Наша задача обеспечить возможность чтения и записи этих самых блоков из/на устроство хранения информации, а остальное сделает ОС.)

Теперь я представлю Вам мою схемку. Сразу оговорюсь, делал на быструю руку, так как печатку делал из головы (схема не сложная):

USB ФЛЕШКА НА ATMEGA8 И V-USB. ОТ ИДЕИ К ГОТОВОМУ УСТРОЙСТВУ… Много букв, Easyelectronics, Technobrother, Код, Своими руками, Avr, Atmega, Atmega8, Длиннопост

Многие заметят, что практически стандартная схема для устройств на V-USB, и что я немного перемудрил с ней, на я повторюсь, что собрал флешку из моего программатора, поэтому здесь немного изврата присутствует. Перемычка JP2 предназначена для прошивки нашего устройства и должна быть установлена только во время обновления прошивки устройства(разъем Х2). Диоды D1 и D2 предназначены для задания рабочего напряжения питания

3.6V. Можно обойтись и одним(проверено неоднократно), хотя при грамотном подходе лучше сделать не так как я=)

USB ФЛЕШКА НА ATMEGA8 И V-USB. ОТ ИДЕИ К ГОТОВОМУ УСТРОЙСТВУ… Много букв, Easyelectronics, Technobrother, Код, Своими руками, Avr, Atmega, Atmega8, Длиннопост

Здесь мы указали, что порт, к которому подключены дифференциальные сигналы D+ и D-, это порт PORTD, а выводы, к которым они подключены, соответсвенно 3 и 2. Частота кварцевого резонатора равна 16 Мгц. Затем мы описали, что мы сами управляем процессом подключения нашего устройства к шине USB. Для этого мы сделали следующее:

USB ФЛЕШКА НА ATMEGA8 И V-USB. ОТ ИДЕИ К ГОТОВОМУ УСТРОЙСТВУ… Много букв, Easyelectronics, Technobrother, Код, Своими руками, Avr, Atmega, Atmega8, Длиннопост

Это видно из схемы: резистор R7, подключенный к выводу 1 порта PORTD. Далее в программе нам это понадобиться для того, чтобы произвести подключение к хосту в момент времени, который нам более всего подходит. (напомню, что Хост определяет наличие подключения устройства к шине в случае подтягивания линии D- к Vdd. Это я для низкоскоростных устройств).

В рекомендации от V-USB сказано, что линия D+ должна быть подключена к INT0, но я внес некоторые изменения и подключил ее к INT1, что в принципе не запрещено (подключают к IN0 т.к. прерывание INT0 имеет наивысший приоритет в системе прерываний AVR. прим. DH), поэтому я указываю на соответствующие изменения в следующих строках:

USB ФЛЕШКА НА ATMEGA8 И V-USB. ОТ ИДЕИ К ГОТОВОМУ УСТРОЙСТВУ… Много букв, Easyelectronics, Technobrother, Код, Своими руками, Avr, Atmega, Atmega8, Длиннопост

В принципе, в описании аппаратной части USB это все.

В этом же файле мы указываем, что класс и подкласс устройства определяется классом и подклассом интерфейса (это я про то, что мы используем стандартный интерфейс MSD bulk-only). Это делается следующим образом:

USB ФЛЕШКА НА ATMEGA8 И V-USB. ОТ ИДЕИ К ГОТОВОМУ УСТРОЙСТВУ… Много букв, Easyelectronics, Technobrother, Код, Своими руками, Avr, Atmega, Atmega8, Длиннопост

Так же мы помним, что мы имеем 2 конечные точки (т.к. мы принимаем и отправляем данные от хоста), значит мы указываем на это библиотеке V-USB:

USB ФЛЕШКА НА ATMEGA8 И V-USB. ОТ ИДЕИ К ГОТОВОМУ УСТРОЙСТВУ… Много букв, Easyelectronics, Technobrother, Код, Своими руками, Avr, Atmega, Atmega8, Длиннопост

USB ФЛЕШКА НА ATMEGA8 И V-USB. ОТ ИДЕИ К ГОТОВОМУ УСТРОЙСТВУ… Много букв, Easyelectronics, Technobrother, Код, Своими руками, Avr, Atmega, Atmega8, Длиннопост

Поскольку мы использовали стандартный класс USB MSD, то и описать устройство это класса обязаны мы. Позже я вернусь к этим строкам, а пока мы оставим их в покое.

В принципе в этом файле вроде как и все, но я оговорюсь для наиболее дотошных (как я=): я не пират и не пытался нарушить чьета права? использовав VID/PID, которые в моем файле usbconfig.h. Мало того, я даже не знаю чье они, просто первые попавшиеся под руку==)

Пожалуй, распишу немного процесс инициализации устройства на V-USB.

Немного выше я определил небольшой макрос USB_CFG_PULLUP_IOPORTNAME в соответствии со схемой, что в свою очередь дало мне возможность производить подключение и отключение от шины USB в произвольные моменты времени. Так вот, для подключения к шине используется макрос

usbDeviceConnect();

при вызове которого происходит подтяжка линии D- к напряжению питания устройства. Хост определяет это событие и начинает процедуру конфигурации устройства USB: Сброс девайса, присвоение адреса и т.д.

Во всей этой рутинной суете главное для нас это этап запроса дескриптора устройства, который в свою очередь содержит поддерживаемую версию USB, максимальный размер пакета для control конечной точки, идентификаторы устройства и производителя VID/PID, версию устройсва, строковые номера индексов(если таковые присутсвуют) и количество конфигураций нас родимых.

USB ФЛЕШКА НА ATMEGA8 И V-USB. ОТ ИДЕИ К ГОТОВОМУ УСТРОЙСТВУ… Много букв, Easyelectronics, Technobrother, Код, Своими руками, Avr, Atmega, Atmega8, Длиннопост

USB ФЛЕШКА НА ATMEGA8 И V-USB. ОТ ИДЕИ К ГОТОВОМУ УСТРОЙСТВУ… Много букв, Easyelectronics, Technobrother, Код, Своими руками, Avr, Atmega, Atmega8, Длиннопост

USB ФЛЕШКА НА ATMEGA8 И V-USB. ОТ ИДЕИ К ГОТОВОМУ УСТРОЙСТВУ… Много букв, Easyelectronics, Technobrother, Код, Своими руками, Avr, Atmega, Atmega8, Длиннопост

Хочу отметить, что в дескрипторе кофигурации мы встраиваем дескриптор интерфейса и дескрипторы конечных точек. Этот (или эти, если хотите) дескриптор передается V-USB благодаря ранее описанному определению

В этом же десрипторе (usbDescriptorConfiguration) мы указали, пожалуй, самую важную информацию для нашего устройства, а именно:

USB_PUBLIC void usbFunctionWriteOut(unsigned char* ucData, unsigned char ucLen)

которая будет принимать все interrupt/bulk передачи данных от хоста к нашему устройству для всех конечных точек, кроме 0 (это control точка). Напомню, что максимальное количество байт, которое может быть принято через usbFunctionWriteOut за один вызов равно 8 байтам (это ограничение V-USB). Ну вот, теперь мы готовы принимать поступающие от хоста байты =))) И на этом этапе мы перейдем к следующему этапу — разделение потока байт от хоста на вменяемые пакеты, которые несут нам полезную информацию. Как мы узнали ранее, хост может направлять в MSD устройство толька комманды и данные. Теперь мы сделаем следующее:

Для того, чтобы воплотить в жизнь написанное чуть выше, давайте разберемся с несколькими положениями, которые касаются Mass Storage Class в целом и bulk-only в частности. Как я уже оговаривал, Mass Storage Class(MSC) не подразумевает того, что устройство, которое работает согласно этой спецификации, занет что-либо о фойловой системе на своем насителе. Оснойвной задачей такого устройсва является предостваление запрашиваемой информации с носителя в нужном объеме и с нужного адреса. Это, с одной стороны, облегчает работу нам с вами, с другой стороны позволяет строить устройства, не привязанные к конкретным накопителям. Все, что мы должны уметь, это выполнить требуемое хостом действие. А действия эти не так уж и сложны(если не вдаваться во все мелочи данного протокола) — выполнять команды из набора SCSI. Я описал все необходимые из них ранее.

Но что-то меня опять понесло в теорию=) Давайте все-таки опишем этот самы загадочный CBW:

USB ФЛЕШКА НА ATMEGA8 И V-USB. ОТ ИДЕИ К ГОТОВОМУ УСТРОЙСТВУ… Много букв, Easyelectronics, Technobrother, Код, Своими руками, Avr, Atmega, Atmega8, Длиннопост

Мы помним, что в MSD bulk-only все транзакции делятся максинум на три этапа. Так вот, приняли мы CBW и выделили из него нужную нам информацию. Это и есть первый этап: так называемый command transport. Из приведенной блок-схемы выше мы видим, что следующим этапом в нашишем диалоге могжут быть передача данных хосту (либо прием их от него) или передача статуса обработки принятого CBW. Так вот, передача того самого статуса являестя обязательным этапом для любой комманды. Этот этап как бы подтвердает тот факт, что мы приняли от хоста CBW с номером dCBWTag и выполнили ее(вне зависимости от результата ее выполненя). Этот этап называется status transport, а данные передаются определенным блоком, имя которому CSW. Давайте опишем и его:

USB ФЛЕШКА НА ATMEGA8 И V-USB. ОТ ИДЕИ К ГОТОВОМУ УСТРОЙСТВУ… Много букв, Easyelectronics, Technobrother, Код, Своими руками, Avr, Atmega, Atmega8, Длиннопост

Эта небольшая структурка как бы является завершением транзакции MSD вида коммандв->данные->статус. Поля этой структуры означают следующее: dCSWSignature — сигнатура блока CSW (это константа, в char это USBS), dCSWTag — номер блока(должен совпадать с номером CBW, для которого высылается статус), dCSWDataResidue — разности между ожидаемым чилом байт от хоста dCBWDataTransferLength в блоке CBW и реально принятыми(при OUT передаче) и наобоот, между запрошенным чилов байт в dCBWDataTransferLength и переданным хосту. Ну и наконец bCSWStatus — результат выполнения комманды с тегом dCSWTag. Нуль — значит все впорядке, другие значения — смотрим в спецификации =))).

Ну и на последок в этапах транзакций осталась стадия передачи данных(data transport). Напомню, что этот этап не всегда присутствует в процессе общения MSD с хостом. Есть энное количество комманд, которые не требуют передачи данных. Но все же этот этап присутствует и мы его сейчас рассмотрим. Мы знаем, что данные могут передаваться как от хоста к MSD, так и наоборот(мы же помним, что мы описали 2 конечные токи in и out). Так вот, в данной реализации MSD от хоста к MSD могут передаваться только данные для записи на носитель информации, а от MSD к хосту как данные прочитанные с носителя, так и запрашиваемые хостом параметры нашего устройства.

В принципе про этапы передачи информации MSD наверное и все. Теперь я коснусь реализации всего написанного выше. Примем исходное сосояние(назовем его RxCBW)=) Хост нам не передал не байта и мы ожидаем от него CBW. Размер этого блока мы занем, а следовательно первые sizeof(CBW) приятых байт и будут CBW. Как только мы приняли CBW мы начинаем его анализировать. Анализ блока CBW начинается с того, что мы распознаем комманду, которая находиться в USB_MSD_CBW.CBWCB[0]. Значение этого байта и есть комманда, которую хост просит нас выполнить. На этом этапе, в зависимости от предложенной нам комманды, устройство может перейти в одно из нескольких состояний: прием данных от хоста(RxData), передача данных хосту(TxData) или передача статуса(TxStatus). При переходе в состояние RxData мы принимаем от хоста n байт информации, записываем ее на носитель и переходим в состояние TxStatus. При переходе в состояние TxData мы передаем хосту запрошенную информацию n байт и переходим в состояние TxStatus. Из состояния TxStatus, передав блок CSW хосту, переходим в состояние RxCBW и ожидаем новые байты от хоста. Сейчас попробую предстваить это во временной диаграмме.

USB ФЛЕШКА НА ATMEGA8 И V-USB. ОТ ИДЕИ К ГОТОВОМУ УСТРОЙСТВУ… Много букв, Easyelectronics, Technobrother, Код, Своими руками, Avr, Atmega, Atmega8, Длиннопост

Ну как-то так (я понимаю, что не все, наверное, понятно, так что готов ответить на вопросы).

Множество микроконтроллеров Atmel AVR со встроенным контроллером USB предоставляют богатые функциональные возможности и периферию, как профессионалам, так и любителям, однако дополнительная сложность разработки программного обеспечения для микроконтроллера и Host-устройства (персональный компьютер) является высоким барьером для любого желающего освоить процесс коммуникации по интерфейсу USB. Хотя на сегодняшний день имеются средства, упрощающие разработку ПО для микроконтроллера с USB интерфейсом, к примеру, это USB стек LUFA с открытым исходным кодом, они все равно требуют определенных знаний о программе для микроконтроллеров AVR, для Windows, а также о физическом аппаратном уровне для поддержки приложений. В данной статье решается эта проблема и предоставляется готовая структура, на базе которой пользователи могут разрабатывать свои приложения и USB устройства.

Вебинар «Особенности применения литиевых батареек Fanso (EVE) в популярных решениях» (30.11.2021)

USB Generic HID структура для Atmel AVR и Windows

Мы рассмотрим базовую разработку аппаратной части, базовый проект программного обеспечения для микроконтроллера, DLL библиотеку для Windows и тестовое Host-приложение для ПК. Предоставляя проверенную и рабочую основу для разработки USB приложений, структура значительно упрощает задачу изучения USB интерфейса и построения USB устройств.

USB Generic HID протокол предоставляет очень гибкий интерфейс без требований к пользовательским USB драйверам на Host-устройстве, т.к. устройства класса HID поддерживаются всеми ОС MS Windows, начиная с Windows 98SE, а также MACOS, Linux и пр., благодаря встроенным драйверам.

Аппаратная часть

Отладочная плата на базе микроконтроллера ATmega32U4 для разработки USB приложений

Аппаратная часть для нашего проекта – это своего рода отладочная плата на базе микроконтроллера ATmega32U4 с интерфейсом USB.

Микроконтроллер ATmega32U4 содержит 32 КБайт внутрисистемно-программируемой флэш-памяти с возможностями чтения во время записи, 1 КБайт ЭСППЗУ, 2.5 КБайт статического ОЗУ, 26 линий ввода-вывода общего назначения (КМОП-выходы и LVTTL-входы), 32 рабочих регистра общего назначения, четыре конфигурируемых таймера-счетчика с режимами сравнения и ШИМ, еще один высокоскоростной таймер-счетчик с режимами сравнения и программируемой ФАПЧ в качестве тактового источника, один УСАПП (с выводами аппаратного управления потоком CTS/RTS), байт-ориентированный 2-проводной последовательный интерфейс, 12-канальный 10-битный АЦП с опциональным дифференциальным входным каскадом (программируемое усиление), встроенный откалиброванный датчик температуры, программируемый сторожевой таймер с отдельным встроенным генератором, последовательный интерфейс SPI, совместимый с IEEE 1149.1 отладочный интерфейс JTAG (доступ к встроенной отладочной системе и программирование) и шесть программно-выбираемых экономичных режимов работы.

Принципиальная схема платы представлена ниже.

Из периферии на плате установлены 4 светодиода, 2 кнопки, кнопка сброса и потенциометр 10 кОм. Питание плата может получать или от интерфейса USB, или от внешнего источника. Выбор источника осуществляется с помощью перемычки (или переключателя) SV1. При питании от внешнего источника используется регулятор напряжения типа LM1117 с выходным напряжением 5 В и выходном токе 800 мА. Для индикации присутствия напряжения питания установлены два светодиода.

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

Для совместимости с различными USB загрузчиками на плате установлен резистор 1 кОм, подключенный к порту PE2 (HWB) микроконтроллера через джампер.

Сигналы линий ввода/вывода микроконтроллера выведены на коннекторы, которые располагаются по периметру платы.

Вид печатной платы

Загрузки

Принципиальная схема и печатная плата отладочной платы (Eagle) – скачать

Часть 2 – прошивка микроконтроллера, демонстрационное ПО, приложения для Windows
Часть 3 – USB Generic HID библиотека коммуникационных функций и ее использование

Читайте также: