Перевод апноута AVR271: USB Keyboard Demonstration on megaAVR with USB [1], рассказывающий про демонстрационный код устройства USB HID - компьютерная клавиатура, подключаемая через USB. Исходный код и документацию можно скачать по ссылке [2].
Особенности проекта клавиатуры:
• Клавиатура стандартная, т. е. она работает с любым компьютером PC, на котором установлена операционная система (Windows® 98SE или более свежая, Linux® или Mac OS®). • Не требуется установка драйвера для поддержки клавиатуры. • При подключении клавиатура отображает простое текстовое сообщение. • Не реализована поддержка управления светодиодами клавиатуры.
Исходный код можно скачать по ссылке [2] (см. папку USB Keybord).
Прим. переводчика: в библиотеке LUFA также есть готовый проект клавиатуры USB HID с исходным кодом, который можно скомпилировать на любой микроконтроллер AVR с аппаратным интерфейсом USB (см. [2], папки LUFA-130901\Demos\Device\ClassDriver\Keyboard и LowLevel\Keyboard архива). Проекты из LUFA удобнее тем, что их можно скомпилировать практически под любую макетную плату, имеющуюся на рынке. Все примеры кода из архива [2] можно с успехом запустить на макетных платах AVR-USB162, AVR-USB162MU, userial, AVR-USB32U4 [6].
[1. Введение]
Традиционно клавиатура подключалась к компьютеру через интерфейс PS/2. Но интерфейс PS/2 уже устарел, и постепенно исчезает с новых моделей компьютеров PC и ноутбуков. Его место с успехом заменяет интерфейс USB, который становится стандартным типом подключения для всех периферийных устройств PC. Такое изменение на рынке касается разработчиков устройств ввода/вывода, потому что необходимо иметь возможность реализовать интерфейс USB, чтобы обеспечить простое подключение разрабатываемых устройств к новым компьютерам.
Этот апноут описывает простой проект клавиатуры, подключаемой к компьютеру через USB. Цель документа - показать на примере стартеркита STK525, как запустить тестовый пример реализации клавиатуры USB HID (прим. переводчика: вместо STK525 можно применить макетные платы AVR-USB162, AVR-USB162MU, userial, AVR-USB32U4). Подразумевается, что читатель знаком с библиотекой USB Software Library for AT90USBxxx Microcontrollers [3] (поставляется бесплатно на CD-ROM, и её также можно скачать с сайта Atmel) и со стандартом USB HID [4].
Прим. переводчика: за разъяснением специфических терминов стандарта USB (конечная точка endpoint, polling, request, report, хост USB, устройство USB и т. д.) лучше обратиться к документу USB in a Nutshell [7].
[2. Требования к аппаратуре]
Приложение firmware для клавиатуры USB требует следующую аппаратуру:
• Отладочную плату с микроконтроллером AVR USB (STK525, AT90USBKey, STK526, или это может быть Ваша собственная плата). • Стандартный кабель USB, если он нужен для подключения к Вашей плате (например, на одной стороне должен быть стандартный коннектор типа A, а на другой коннектор типа Mini B). • Компьютер, на котором установлена операционная система Windows (98SE, ME, 2000, XP и т. д.), Linux или MAC OS, поддерживающие хост USB стандартов USB 1.1 или USB 2.0.
Firmware клавиатуры USB Вы также можете запустить на макетных платах AVR-USB162, AVR-USB162MU, userial, AVR-USB32U4.
[3. Как можно запрограммировать Ваш чип AVR USB]
Для того, чтобы прошить память микроконтроллера, Вы можете использовать следующие методы:
• Интерфейс JTAG, для этого нужен аппаратный отладчик JTAGICE mkII(2). • Интерфейс ISP (SPI), для этого можно использовать программаторы AVRISP mkII, AVR Dragon (прим. переводчика: и множество других программаторов [5]) и отладчик JTAGICE mkII(2). • Интерфейс USB, благодаря прошитому в память микроконтроллера (это уже сделано на заводе Atmel) DFU bootloader и программному обеспечению FLIP(1). Этот способ наиболее практичен и удобен. • Параллельное программирование, для этого нужны программаторы STK®500 или STK600.
Примечания:
(1) Программа-утилита FLIP предоставляется компанией Atmel, чтобы позволить пользователю прошить устройства AVR USB (и другие) через подключение USB, что не требует никакой дополнительной аппаратуры типа отладчиков и программаторов. Прием данных через USB и перепрошивку памяти программ берет на себя бутлоадер DFU, заранее прошитый в память чипа на заводе Atmel. (2) При использовании JTAGICE MKII будьте осторожны с галочкой "erase before programming" (очистить перед программированием) в утилите программатора AVR Studio®. Если эта галочка установлена, то это приведет к стиранию как программы пользователя, так и к стиранию бутлоадера DFU. Прим. переводчика: при необходимости бутлоадер всегда можно восстановить с помощью ISP-программатора, бинарник бутлоадера можно скачать с сайта Atmel.
Пожалуйста обратитесь к содержимому справки FLIP для того, чтобы узнать, как установить драйвер USB и как запрограммировать микроконтроллер ATmega32U4 через интерфейс USB.
Прим. переводчика: простые указания на русском языке по установке драйвера USB и перепрошивке микроконтроллера через FLIP можно получить из статьи "Макетная плата AVR-USB32U4" [6].
[4 Быстрый старт]
Как только прошили Ваш микроконтроллер (например ATmega32U4) файлом usb_keyboard.a90 проекта USB Keybord [2], Вы можете запустить демонстрацию работы клавиатуры. Проверьте, что Ваше устройство USB успешно прошло энумерацию как клавиатура (см. скриншот окна Диспетчера Устройств), и теперь Вы может использовать Вашу плату как клавиатуру, чтобы отправить компьютеру символы клавиатурных нажатий.
На рисунке ниже показан джойстик платы STK525.
Для отправки клавиатурных нажатий используйте джойстик. Контакты джойстика просто подключены к портам ввода вывода AVR как замыкатели на землю. Уже упоминалось, что могут быть использованы и другие стартер-киты и отладочные платы, в этом случае см. по исходному коду проекта, какие порты микроконтроллера нужно замкнуть на GND, чтобы получить эффект клавиатурных нажатий. Чтобы посмотреть, как клавиатура работает:
1. Запустите программу текстового редактора (Блокнот, Notepad и т. п.). 2. Переключитесь на английскую раскладку клавиатуры (QWERTY), иначе Вы можете увидеть в текстовом редакторе не те символы, которые ожидалось. 3. Подключите через USB плату STK525 (или другу Вашу плату), прошитую файлом usb_keyboard.a90. 4. Понажимайте кнопки джойстика.
В результате увидите экран наподобие следующего:
[5. Обзор приложения firmware клавиатуры USB HID]
Программа микроконтроллера (firmware), которая ведет себя как клавиатура USB, использует простейший обмен данными с компьютером PC. Компьютер постоянно опрашивает клавиатуру с интервалом P (поллинг или опрос, polling interval time) на предмет наличия новый данных, и клавиатура будет отправлять эти данные, если они имеются. Если данных нет, то клавиатура будет посылать в ответ NAK (No Acknowledge, нет подтверждения). В этом отношении клавиатура USB HID ведет себя точно так же, как USB HID мышь (различия только в формате отправляемых данных).
Данные, которыми обмениваются клавиатура и компьютер PC через USB, называются репортом (report). Репорт, содержащий клавиатурные нажатия, называется report IN (данные передаются в сторону PC). Репорт, который содержит состояние светодиодов клавиатуры (NUM LOCK, CAPS LOCK, SCROLL LOCK...), называется report OUT (данные передаются от PC). На рисунке ниже показана структура этих репортов.
Рис. 5-1. Структура USB репортов клавиатуры.
Примечание: этот демонстрационный пример [2] поддерживает только report IN (обработка report OUT и изменение состояния светодиодов не поддерживается).
Рис. 5-2. Как работает приложение клавиатуры.
[6. Организация кода firmware]
Код firmware клавиатуры USB базируется на USB Software Library for AT90USBxxx Microcontrollers [3], и поэтому имеет ту же самую архитектуру.
Рис. 6-1. Архитектура программного обеспечения USB Keyboard
Эта секция посвящена только работе модуля клавиатуры (как опрашивается джойстик и кнопка). После этого будет описана настройка файлов, чтобы дать пользователю возможность построить собственное приложение клавиатуры USB на основе проекта [2].
6.1 keyboard_task.c
Этот файл содержит функции для инициализации аппаратуры, используемой в клавиатуре, для сбора данных репорта и копирование данных репорта в стек FIFO конечной точки (endpoint FIFO), чтобы репорт был готов к отправке в сторону компьютера PC.
Рис. 6-2. Приложение клавиатуры.
6.1.1 keyboard_task_init
Эта функция выполняете инициализацию параметров клавиатуры и её аппаратных ресурсов (порты GPIO микроконтроллера, используемые для джойстика).
6.1.2 kbd_test_hit
Эта функция проверяет, нажата ли в настоящий момент кнопка, и если нажата, устанавливает переменную key_hit в значение true.
6.1.3 keyboard_task
Эта функция определяет, была ли нажата кнопка (key_hit == true). Если кнопка была нажата, то report IN заполняется соответствующими величинами, и загружается в FIFO конечной точки USB, чтобы данные были отправлены хосту PC.
6.2 stk_52x.c
Этот файл содержит все подпрограммы, касающиеся управления ресурсами платы STK52x (джойстик, потенциометр, термодатчик, светодиоды...). Пользователю не нужно модифицировать этот файл, если он использует плату STK52x. Иначе на основе файла stk_52x.c. нужно сделать свой собственный файл для управления аппаратными ресурсами Вашей платы.
6.3 Как добавить поддержку светодиодов клавиатуры (CAPS, NUMLOCK...)
Светодиоды (LED), расположенные на клавиатуре (CAPS, NUMLOCK...), управляются хостом, когда была нажата соответствующая кнопка. Т. е. когда хост получил код клавиши (keycode) CAPS или NUMLOCK, или Scroll Lock, то хост отправляет запрос Set_Report request (Out Report), чтобы включить/выключить соответствующий LED на клавиатуре.
Этот запрос отправляется через конечную точку 0 (endpoint 0, или управляющая конечная точка, или конечная точка по умолчанию, обслуживающая специальные передачи для управления control transfer), и этот запрос обрабатывается как Set_Configuration request, что показано ниже. Сначала хост отправляет set_report:
bmRequestType |
00100001 |
bRequest |
SET_REPORT (0x09) |
wValue |
Report Type (0x02) и Report ID 0x00) |
wIndex |
Interface (0x00) |
wLength |
Report Length (длина репорта в байтах, 0x0004) |
Data |
Данные репорта, 1 байт. |
Этот запрос специфичен для устройств USB класса HID, поэтому он не обрабатывается в модуле usb_standard_request.c, но обрабатывается в модуле usb_specific_request.c. В файле usb_specific_request.c запрос декодирует следующее значение bmRequest и bRequest, используя функцию usb_user_read_request(). Тип репорта report type (0x02) соответствует Out Report. Для обработке этого запроса функция usb_user_read_request() вызовет функцию hid_set_report(). Эта функция в свою очередь подтвердит setup request, и тем самым позволит пользователю получить 1 байт данных (Вы можете проверить размер данных с помощью параметра wLength) и по нему узнать, какой LED нужно включить или выключить (пожалуйста, обратитесь к спецификации HID, чтобы узнать подробности значений для установки LED).
void hid_set_report (void)
{
U16 wLength;
U8 CAPS_LED = 0;
U8 REPORT_ID;
LSB(wInterface)=Usb_read_byte();
MSB(wInterface)=Usb_read_byte();
LSB(wLength) = Usb_read_byte(); //!< прочитать wLength
MSB(wLength) = Usb_read_byte();
Usb_ack_receive_setup();
while(!Is_usb_receive_out());
REPORT_ID = Usb_read_byte();
CAPS_LED = Usb_read_byte(); // получить значение отправленного
// хостом состояния CAPS LED
Usb_ack_receive_out();
Usb_send_control_in();
while(!Is_usb_in_ready());
//Отправка репорта для очистки запроса CAPS request
Usb_select_endpoint(EP_KBD_IN);
Usb_write_byte(0); // байт 0: модификатор
Usb_write_byte(0); // байт 1: зарезервировано
Usb_write_byte(0); // байт 2: Keycode 0
Usb_write_byte(0); // байт 3: Keycode 1
Usb_write_byte(0); // байт 4: Keycode 2
Usb_write_byte(0); // байт 5: Keycode 3
Usb_write_byte(0); // байт 6: Keycode 4
Usb_write_byte(0); // байт 7: Keycode 5
Usb_ack_in_ready();
//Включить/выключить светодиод в соответствии с запросом хоста
if(CAPS_LED == 0)
Led3_off();
else
Led3_on();
}
6.4 Как переделать устройство USB из "незагрузочного" (non-bootable device) в "загрузочное" (bootable device)
Пожалуйста имейте в виду, что устройства USB HID могут быть bootable или non-bootable. По умолчанию демонстрационные примеры от Atmel поставляются как non-bootable устройства. Если Ваше приложение требует поддержки bootable, то нужно модифицировать параметр подкласса (sub-class parameter) в файле usb_descriptors.h:
// USB Interface descriptor Keyboard (дескриптор интерфейса USB клавиатуры)
#define INTERFACE_NB_KEYBOARD 0
#define ALTERNATE_KEYBOARD 0
#define NB_ENDPOINT_KEYBOARD 1
#define INTERFACE_CLASS_KEYBOARD 0x03 // HID Class
#define INTERFACE_SUB_CLASS_KEYBOARD 0x00 // Non-bootable
#define INTERFACE_PROTOCOL_KEYBOARD 0x01 //Клавиатура
#define INTERFACE_INDEX_KEYBOARD 0
Установите INTERFACE_SUB_CLASS_KEYBOARD в значение 1, чтобы клавиатура стала bootable device.
[7. Программное обеспечение для компьютера (PC Software)]
Приложение мыши USB не нуждается ни в каком специальном программном обеспечении на хосте, потому что все поддержка (драйвер) мыши USB уже встроена в операционную систему компьютера.
Демонстрационное приложение клавиатуры USB HID [2], предоставленное Atmel, не поддерживает обработку OUT report. Вы можете самостоятельно добавить код для поддержки этой возможности, см. раздел 6.3.
[Ссылки]
1. AVR271: USB Keyboard Demonstration on megaAVR with USB site:atmel.com. 2. 131122AVR270_AVR271_AVR272_AVR273.zip. 3. AVR276: USB Software Library for AT90USBxxx Microcontrollers. 4. HID Related Specifications site:usb.org. 5. Программаторы для AVR. 6. Макетная плата AVR-USB32U4. 7. USB in a NutShell - путеводитель по стандарту USB. |