Программирование AVR: работа с USB AVR328: стандартная (generic) реализация устройства USB HID Thu, November 21 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.


AVR328: стандартная (generic) реализация устройства USB HID Печать
Добавил(а) Марат   

В статье дан перевод даташита AVR328 Atmel (AVR328: USB Generic HID Implementation), рассказывающего, как можно самому изготовить, запрограммировать устройство USB HID и управлять им программой компьютера. Автор перевода Marat Galyamov.

Особенности предлагаемой реализации USB HID:

• Поддерживается всеми ОС MS Windows, начиная с Windows® 98 SE и более поздними
• Простой интерфейс для программы на компьютере (ПО хоста) с функциями Чтения/Записи
• До 64 кбайт/с в полнодуплексном режиме обмена (данные передаются в обоих направлениях)
• Работает на всех AVR USB микроконтроллерах (имеющих аппаратный интерфейс USB)

1. Введение

Цель этого документа – описание, с чего начать и как реализовать USB приложение, основанное на классе HID для передачи данных между ПК и USB-устройством пользователя.

2. Описание

Интерфейс USB становится очень сложным, когда пользовательские данные не соответствуют стандартным классам USB (CDC, Mass Storage, Audio, Video...). Для таких устройств USB должны быть разработаны специальные драйверы, требующие существенного количества времени разработки.

Atmel разработала решение, экономящее время и усилия по разработке. Это решение основано на классе HID и гарантирует полнодуплексную передачу между устройством и ПК (скорость до 64 кбайт/с в обе стороны). Добавляя данные к обмену, это приложение позволяет пользователю обновлять встроенное микропрограммное обеспечение без какой-либо предварительной настройки аппаратуры.

Устройства класса HID поддерживаются всеми ОС MS Windows, начиная с Windows 98SE и более поздними. Также поддерживается большинством других ОС, запускаемых на ПК (на момент публикации).
 
Предполагается, что вы уже знакомы с библиотекой программного обеспечения USB для микроконтроллеров AT90USBxxx  (Документ 7675, включенный в USB CD-ROM и имеющийся на сайте Atmel) и спецификацией HID, см. Ссылки [1].

Примечание - намного полезней ознакомиться с документом USB in the NutShell, см. Ссылки [2].

AVR328-01.PNG

3. Аппаратные требования

Универсальное, стандартное (generic) приложение HID требует наличия следующих ресурсов:

1. Оценочная плата AVR USB (STK525, AT90USBKey, STK526 или другие).

Примечание - макетных плат с чипами Atmel на которых заработает упоминающееся здесь программное обеспечение, очень много - семейство Teensy, AVRopendous, Benito, userial, Dorkboard, Bumbie-b, AVR-USB162 и многие другие. См. Ссылки [3].

2. Микроконтроллер AVR USB
3. USB-кабель (стандартный, например из типа A в тип Mini B)
4. В качестве USB-хоста ПК под управлением Windows (98SE, ME, 2000, XP), поддерживающий стандарт USB 1.1 или 2.0

4. Внутрисхемное программирование (ISP) и обновление встроенного в микроконтроллер программного обеспечения (firmware)

Записывать firmware в микроконтроллер можно через:

• JTAG-интерфейс, используя JTAGICE MKII (используется редко, в основном профессионалами)
• SPI-интерфейс, используя AVRISP MKII (ISP, In System Programming) и многие  другие популярные программаторы, см. Ссылки [4]. Этот способ программирования используется довольно часто
• USB-интерфейс, благодаря зашитому на заводе загрузчику (фирменный DFU bootloader компании Atmel) и программе Flip (ПО хоста). Наиболее простой для пользователя способ программирования
• Параллельное программирование, используя отладочные комплекты STK500 или STK600 (используется довольно редко, так как обычно требует выпайки чипа из платы)

Обращайтесь к руководству пользователя платы, которой Вы пользуетесь (если Вы используете стартовый набор Atmel) чтобы понять, как программировать устройство, используя эти способы. Обратитесь к системе помощи программы Flip(1), чтобы понять, как установить драйвер USB и программировать устройство через USB-интерфейс.

Примечание: 1. Flip – это программа Atmel, позволяющая пользователю программировать устройства AVR USB через USB-интерфейс (при этом не требуется дополнительное внешнее оборудование типа программатора), благодаря зашитому на заводе фирменному загрузчику (поддерживающему протокол DFU).

5. Быстрый старт

Как только ваше устройство будет запрограммировано hex-файлом стандартного HID, вы сможете запустить демо стандартного HID.

Примечание. В оригинальном апноуте AVR328 даже не попытались объяснить - где же взять этот hex-файл для "стандартного HID", чтобы прошить свое USB-устройство на чипе AVR? Оказывается, этот hex-файл берется при компиляции проекта из AVR276: USB Software Library for megaAVR with USB Microcontrollers (ищите на сайте Atmel, или см. Ссылки [5], там же найдете ссылки на закачку исходников проекта и уже скомпилированных прошивок для чипов AT90USB162 и AT90USB647). Вы можете также самостоятельно скомпилировать прошивки для Вашего чипа AVR USB, если возьмете за основу код firmware из проектов USB Device-Host Library\series2-usb_software_library_template-2_0_1-doc.zip, series4-usb_software_library_template-2_0_1-doc.zip, series6_7-usb_software_library_template-2_0_2-doc.zip. См. также раздел 7 Firmware.

Убедитесь, что Ваше устройство прошло энумерацию как HID-устройство (см. рисунок 5-1), после этого запустите приложение на ПК (см. рисунок 5-2) и запустите обмен данными между ПК и встроенным микропрограммным кодом (приложением).

Рисунок 5-1: так должно выглядеть подключенное USB-устройство в Диспетчере Устройств.

AVR328-02.PNG

Этот пример демонстрирует, как сделать полнодуплексную связь между USB-устройством и USB-хостом.

Передача типа IN заключается в передаче данных из устройства в хост. Эти данные передаются, когда вы двигаете джойстиком на starter-ките (нажимаете кнопки на макетной плате, или подаете сигналы на входные порты микроконтроллера). Приложение ПК (см. рисунок ниже) позволяет вам отправлять данные в устройство, включая/выключая светодиоды на Вашем starter-ките (макетной плате).

Рисунок 5-2 показывает графический интерфейс пользователя, используемый приложением ПК:

AVR328-03.PNG

Пожалуйста, обратитесь к Application note USB PC Drivers Based on Generic HID Class для дополнительной информации относительно приложения ПК.

6. Краткий обзор приложения

Стандартное (generic) HID-приложение демонстрирует простой обмен данными между программой на ПК (ПО хоста) и устройством USB.

Обмен данными для этого приложения основан на двух конечных точках типа INTERRUPT (одна IN и одна OUT).

ПК запрашивает устройство, доступны ли новые данные каждые P раз (интервал времени опроса), устройство отправляет данные, если они есть, в противном случае отправляет сигнал NAK (Нет Подтверждения) сообщая ПК, что нет доступных данных. Блок данных, отправленный устройством в ПК, называется репортом типа IN.
Чтобы отправить данные устройству, ПК проверяет, есть ли новые доступные данные для приложения каждые P раз (интервал времени опроса). Как только данные доступны, ПК отправляет их в устройство. Этот блок данных называется репортом типа OUT.
Эти репорты содержат ряд байтов, которые могут использоваться пользовательским приложением, чтобы передать данные - в зависимости от требований.

В этом примере используются репорт типа IN и репорт типа OUT со структурой, показанной ниже.

Структура репорта IN:

AVR328-04.PNG

• Значение светодиодов (LEDs value): этот байт содержит текущее состояние (ВКЛ/ВЫКЛ) светодиодов.
• Значение джойстика (Joystick value): этот байт содержит состояние джойстика (Активен/Пассивен) и направление указателя.
• Значение потенциометра (Potentiometer value): этот байт содержит значение потенциометра.
• Значение температуры (Temperature value): этот байт содержит значение температурного сенсора.

Структура репорта OUT:

AVR328-05.PNG

Значение светодиодов (LEDs value): Этот байт содержит новое состояние светодиодов.

Примечание: в этом приложении мы используем 8 байт для размера репортов типа IN/OUT. Этот размер может быть изменен пользователем. Размер репорта не ограничен, но за один раз могут быть переданы только 64 байта (см. секцию "Firmware").

Стандартное HID-устройство позволяет пользователю отправлять данные через конечную точку с номером 0, используя функцию 'setFeature'. Эта функция отправляет Feature-репорт c 4 байтами (длина может быть изменена пользователем, обратитесь к секции 7.3).

Репорт Feature:

AVR328-06.PNG

Общий обзор приложения:

AVR328-07.PNG

7. Firmware (встроенное в микроконтроллер программное обеспечение)

Как написано в документе USB Software Library for AT90USBxxx Microcontrollers (Библиотека программного обеспечения USB для микроконтроллеров AT90USBxxx, документ 7675, включенный в USB CD-ROM, см. Ссылки [5]) все пакеты встроенного микропрограммного обеспечения USB основаны на одинаковой архитектуре (обратитесь к этому документу за более подробной информацией).

Архитектура firmware USB-устройства Generic HID:

AVR328-08.PNG

Легенда:
Красный фон – модифицировать файлы не нужно
Оранжевый фон – могут быть изменены пользователем
Голубой фон - добавлены пользователем

Здесь описывается только модуль HID. Настройка файлов, описанных здесь, позволяет пользователю создавать свое Generic (универсальное, стандартное) приложение HID:

• hid_task.c
• usb_descriptor.h

7.1 hid_task.c

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

AVR328-09.PNG

7.1.1 hid_task_init

Эта функция выполняет инициализацию параметров устройства и аппаратных ресурсов. (джойстик, потенциометр...).

7.1.2 (*start_bootloader)

Этот указатель на функцию позволяет запускать загрузчик.

7.1.3 hid_task

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

7.2 stk_52x.c

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

7.3 Изменение длины репорта

Как указано в разделе 6 Краткий обзор приложения, пользователь может изменить длину репортов IN и OUT. Длина репортов IN и OUT определена в файле usb_descriptor.h:

#define LENGTH_OF_REPORT_IN 8 
#define LENGTH_OF_REPORT_OUT 8

Обратите внимание, что длина репорта должна быть равна или меньше чем размер конечной точки. Если репорт больше, чем размер конечной точки, вы должны передать репорт в несколько этапов.

Для изменения размера конечной точки (максимум 64 байта, т.к. класс HID использует передачи типа INTERRUPT), Вы должны изменить следующие параметры в файле usb_descriptors.c:

#define EP_IN_LENGTH 8 
#define EP_OUT_LENGTH 8

Еще нужно изменить параметры SIZE_n в файле usb_specific_request.c, и особенно в функции usb_user_endpoint_init():

usb_configure_endpoint(EP _HID_IN,    \
                       TYPE_INTERRUPT,    \
                       DIRECTION_IN, \
                       SIZE_8,    \
                       ONE_BANK,    \
                       NYET_ENABLED); 
usb_configure_endpoint(EP_HID_OUT,    \
                       TYPE_INTERRUPT,    \
                       DIRECTION_OUT, \
                       SIZE_8,    \
                       ONE_BANK,    \
                       NYET_ENABLED);

Параметр SIZE_n может иметь следующие значения:

SIZE_8: 8 байт
SIZE_16: 16 байт
SIZE_32: 32 байт
SIZE_64: 64 байт
SIZE_128: 128 байт
SIZE_256: 256 байт
SIZE_512: 512 байт
SIZE_1024: 1024 байт

Для изменения FEATURE-репорта, необходимо изменить следующий параметр в файле usb_descriptor.h:

#define LENGTH_OF_REPORT_FEATURE 4

Как и репортов IN/OUT, этот репорт не имеет ограничений по длине. Если его длина равна или меньше чем размер нулевой конечной точки, он будет передан за один раз, иначе Вы должны передать его в несколько этапов. Возможно Вам придется изменить длину нулевой конечной точки (которая имеет номер 0), чтобы отправить репорт бОльшего размера. Чтобы сделать это, необходимо изменить следующий параметр в файле usb_descriptors.h:

#define EP_CONTROL_LENGTH 8

Максимальный размер нулевой конечной точки – 64 байта (по спецификации USB).

7.4 Как обработать запрос setFeature

Функция setFeature() предоставляется DLL (фирменная DLL Atmel), позволяющей пользователю отправлять управляющие команды устройству. Эти команды отправляются через нулевую конечную точку и должны быть обработаны как запрос set_report (обратитесь к спецификации HID для более полной информации). Запрос set_report должен быть обработан встроенным микро-ПО как передача типа Сontrol.

Сначала хост отправит set_report как показано ниже:

bmRequestType             00100001
bRequest                  SET_REPORT (0x09)
wValue                    Report Type (0x03) and Report ID 0x00)
wIndex                    Interface (0x00)
wLength                   Report Length (0x0004)
Data                      Report (4 bytes)

Этот запрос специфичен для класса HID, поэтому обрабатывается НЕ файлом usb_standard_request.c, а файлом usb_specific_request.c. В этом файле запрос декодируется с учетом значений bmRequest и bRequest, используя функцию usb_user_read_request(). Тип репорта (0x03) соответствует репорту Set_Feature_Report. Обработка этого запроса в usb_user_read_request() вызывает функцию usb_set_feature() . Эта функция будет подтверждать прием запроса типа Setup (запроса установки) и позволяет Вам получить отправленные данные (Dы можете проверить размер, используя параметр wLength).

void usb_set_feature(void) 
{
   U16 wInterface; 
   U16 wLength; 
   U8 tab[];
   LSB(wInterface)=Usb_read_byte(); 
   MSB(wInterface)=Usb_read_byte(); 
   LSB(wlength)=Usb_read_byte(); 
   MSB(wLength)=Usb_read_byte();
   Usb_ack_receive_setup();      //Очищаем флаг Setup
   while(!Is_usb_receive_out()); //Ожидание данных 
   for(i=0;i<wLength;i++)
      tab[i] = Usb_read_byte()   //Читаем данные, отправленные хостом,
                                 // используя setFeature.
   Usb_ack_receive_out();
   Usb_send_control_in();        //отправка пакета нулевой длины для подтверждения 
   while(!Is_usb_in_ready()); 
}

Примечание: setFeature используется для отправки запроса из ПК в устройство, чтобы перейти к загрузчику.

7.5 Как изменить интервал опроса каждой конечной точки

Так как стандартный HID использует передачу типа INTERRUPT для обеих конечных точек, каждая конечная точка должна иметь свой интервал опроса (указывается в дескрипторе конечной точки). Чтобы изменить этот параметр для соответствия требованиям Вашего приложения, Вы должны изменить следующие значения в файле usb_descriptors.c:

// USB Endpoint 1 descriptor FS
#define ENDPOINT_NB_1 (EP_HID_IN | 0x80)
#define EP_ATTRIBUTES_1 0x03 // BULK = 0x02, INTERRUPT = 0x03
#define EP_IN_LENGTH 8
#define EP_SIZE_1 EP_IN_LENGTH
#define EP_INTERVAL_1 20 //interrupt pooling from host

// USB Endpoint 2 descriptor FS 
#define ENDPOINT_NB_2 (EP_HID_OUT)
#define EP_ATTRIBUTES_2 0x03 // BULK = 0x02, INTERRUPT = 0x03
#define EP_OUT_LENGTH 8
#define EP_SIZE_2 EP_OUT_LENGTH
#define EP_INTERVAL_2 20 //interrupt pooling from host

Допустимое значение должно лежать в диапазоне 1 .. 255 (мс)

8. Программное обеспечение компьютера (ПО хоста)

Как показано на рис. 6-4, приложение стандартного HID требует пакета ПО.
Этот пакет содержит DLL (Dynamic Link Library) и пользовательское приложение (фирменная DLL компании Atmel, без исходников). DLL позволяет пользователю взаимодействовать через интерфейс с драйверами USB-хоста и избежать трудоемкой разработки. Эта DLL содержит 5 функций, описанных ниже.

HID DLL:

AVR328-10.PNG

8.0.1 findHidDevice

Функция возвращает TRUE и создает идентификатор, если правильное устройство найдено (VID & PID корректны). В противном случае возвращает FALSE.

Параметры:
VID: Vendor ID устройства
PID: Product ID устройства.

8.0.2 readData

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

Параметры:
*buffer: Указатель на буфер, в котором сохранены данные.

8.0.3 writeData

Эта функция обеспечивает отправку данных из ПК в устройство. Также обеспечивает отправку команды DFU (старт загрузчика).

Параметры :
*buffer: Указатель на буфер данных.

8.0.4 setFeature

Эта функция позволяет пользователю отправлять управляющие (контрольные) данные в устройство через нулевую конечную точку.

Параметры:
*buffer: Указатель на буфер данных

8.0.5 closeHandles

Эта функция закрывает все идентификаторы и потоки. Должна быть вызвана, когда вы закрываете приложение.

Параметры: отсутствуют.

Пожалуйста, обратитесь к  Application note USB PC Drivers Based on Generic HID Class для дополнительной информации относительно USB HID DLL.

9. Документы по этой теме:

AVR USB Datasheet (doc 7593)
USB Software Library for AT90USBxxx Microcontrollers (doc 7675, см. Ссылки [5])
USB HID class specification (см. Ссылки [1]).

[Ссылки]

1. HID Information site:usb.org - стандарт USB HID, описание на английском.
2. USB in the NutShell, русский перевод.
3. Макетная плата AVR-USB162.
4. Программаторы для AVR.
5. AVR276: USB Software Library for megaAVR with USB Microcontrollers - перевод на русский язык.
6. LUFA - бесплатная библиотека USB для микроконтроллеров Atmel AVR - альтернативный способ создавать свои собственные USB-устройства на AVR с аппаратным интерфейсом USB (библиотека с открытыми исходниками).

 

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


Защитный код
Обновить

Top of Page