Kompozytowe urządzenia USB na mikrokontrolerach z serii LPC134x

Deskryptor urządzenia w przykładowym programie

Polami deskryptora urządzenia definiującymi urządzenie są: klasa urządzenia, podklasa i protokół (patrz: fragment kodu poniżej zaznaczony na czerwono). Pola te tworzą Multi-Interface Function Class Code, a ich wartości wynoszą odpowiednio 0xEF, 0x02 i 0x01.  Stała USB_DEVICE_CLASS_MISCELLANEOUS ma wartość 0xEF.

/* Standardowy deskryptor urządzenia USB */

const uint8_t USB_DeviceDescriptor[] = {

USB_DEVICE_DESC_SIZE,               /* bLength */

USB_DEVICE_DESCRIPTOR_TYPE,         /* bDescriptorType */

WBVAL(0x0200), /* 2.0 */            /* bcdUSB */

USB_DEVICE_CLASS_MISCELLANEOUS,     /* bDeviceClass */

0x02,                               /* bDeviceSubClass */

0x01,                               /* bDeviceProtocol */

USB_MAX_PACKET0,                    /* bMaxPacketSize0 */

WBVAL(USB_VENDOR_ID),               /* idVendor */

WBVAL(USB_PROD_ID),                 /* idProduct */

WBVAL(USB_DEVICE), /* 1.00 */       /* bcdDevice */

0x01,                               /* iManufacturer */

0x02,                               /* iProduct */

0x03,                               /* iSerialNumber */

0x01                                /* bNumConfigurations: jedna możliwa konfiguracja*/

};

Deskryptor przypisania interfejsu w przykładowym programie

Interface Association Descriptor (IAD) przypisuje kilka interfejsów do jednej funkcji lokalnej. W omawianym przypadku mamy dwa interfejsy CDC (komunikacja i dane) i pojedynczą funkcję logiczną, odpowiadającą klasie urządzeń CDC.

Gdyby urządzenie to nie było urządzeniem kompozytowym, kod klasy urządzenia zdefiniowany w deskryptorze urządzenia byłby ustawiony na USB_DEVICE_CLASS_MISCELLANEOUS, co daje automatyczne przypisanie i nie byłoby potrzeby używania deskryptora IAD. System operacyjny próbowałby wtedy załadować osobne sterowniki dla każdego z interfejsów CDC.

      /* deskryptor IAD służący do przypisania interfejsów CDC */

USB_INTERFACE_ASSOCIATION_DESC_SIZE, /* bLength */

USB_ASSOCIATION_DESCRIPTOR_TYPE,    /* bDescriptorType */

USB_CDC_CIF_NUM,                    /* bFirstInterface */

2,                                  /* bInterfaceCount */

USB_DEVICE)CLASS_COMMUNICATIONS,    /* bFunctionClass */

CDC_ABSTRACT_CONTROL_MODEL,         /* bFunctionSubClass */

0,                                  /* bFunctionProtocol */

0,                                  /* iFunction (indeks deskryptora znakowego opisującego tę funkcję */

Przedstawiony IAD przypisuje dwa interfejsy nadając polu bFirstInterface wartość USB_CDC_CIF_NUM będącą numerem pierwszego interfejsu, a polu bInterfaceCount (odpowiedzialnemu za liczbę interfejsów) wartość dwa.

UWAGA: Przypisanie wielu interfejsów jest możliwe tylko dla interfejsów numerowanych kolejno, a przedstawiony powyżej deskryptor IAD musi zostać umieszczony bezpośrednio przed interfejsami, do których się odnosi.

 

Załączony przykładowy program

 

Kod załączonego przykładu znajduje się w folderze usbcomp_msd_cdc. Zawiera funkcję main() z nieskończoną pętlą oraz zestaw bibliotecznych funkcji wspomagających i implementujących podstawowy stos urządzenia USB oraz obsługę klas CDC/ACM oraz MSD.

Funkcja main() przeprowadza jednorazowo inicjalizację stosu USB i klas, a następnie przechodzi do pętli, w której przetwarzane są znaki z kanału komunikacyjnego. Obsługa pamięci masowej oraz nadawanie i odbiór znaków są oparte na przerwaniach.

Funkcje odczytu i pisania do pamięci masowej pracują na buforze RAM o rozmiarze tylko 4kB, wbudowana pamięć flash nie jest używana.

Aby uruchomić przykładowy kod należy podłączyć do płytki LPCXpresso przewód USB i zaprogramować mikrokontroler na płytce. Po zaprogramowaniu i uruchomieniu programu, komputer rozpozna najpierw urządzenie USB typu pamięć masowa i zamontuje nowy napęd dyskowy zawierający plik tekstowy. Następnie rozpozna urządzenie USB typu „VCOM” i zapyta o sterownik. Należy wskazać systemowi plik .inf znajdujący się w folderze usbcomp_msd_cdc, a Windows zainstaluje domyślny sterownik szeregowy USB.

W tym momencie na nowo zamontowanym dysku powinno się dać zapisywać i odczytywać pliki, a jednocześnie przez wirtualny port COM wysyłać i odbierać znaki. Szybkość transmisji powinna być taka, jak zostało to skonfigurowane dla portu CDC.

Jedynym problemem, jaki może wystąpić przy próbie użycia przykładowego programu jest instalacja sterowników w systemie Windows. Jako że wszystkie przykładowe projekty wykorzystują te same identyfikatory Vendor ID oraz Product ID, jeśli najpierw próbujemy uruchomić przykład urządzenia HID (Human Interface Device), a następnie urządzenia CDC, Windows może spróbować zastosować sterownik HID dla urządzenia CDC. Aby sobie z tym poradzić, należy odinstalować urządzenie HID w Menadżerze Urządzeń Windows, odłączyć płytkę od komputera i podłączyć ją ponownie. Windows powinien wtedy zidentyfikować urządzenie poprawnie i zainstalować prawidłowy sterownik.

Opisywany projekt wykorzystuje kod z biblioteki CMSISv1p30_LPC13xx (dla plików CMSIS 1.30) i projekt zawierający tę bibliotekę musi istnieć w tej samej przestrzeni pracy (workspace), aby niniejszy projekt mógł się skompilować poprawnie. Dodatkowe informacje można znaleźć w komentarzach pliku config.h.

Szczegóły obsługi przykładowego programu w systemie Windows

Znajdujący się w folderze usbcomp_msd_cdc plik lpc14x-vcom.inf istnieje, aby pomagać przy ładowaniu właściwych sterowników USB w systemie Windows dla opisywanego urządzenia, co umożliwia mu pracę jako wirtualny port COM.

W pliku znajduje się linia zatytułowana [DeviceList], która wygląda następująco:

%DESCRIPTION%=LPC134xUSB, USB\VID_1FC9&PID_0003&MI_01

Linia ta przypisuje urządzeniu CDC plik systemowy sterownika usbser.sys i sprawia, że system ładuje ten sterownik w czasie procesu wyliczania (enumeration).

VID_1FC9 oraz PID_0003 to identyfikatory producenta i produktu dla tego urządzenia. Fragment MI_01 (MI oznacza Multiple Interface – wiele interfejsów) odnosi się do drugiego interfejsu w urządzeniu i mówi systemowi, aby przypisał ten interfejs ze sterownikiem, który jest ładowany. Urządzenie CDC jest drugim interfejsem, jego deskryptor interfejsu był drugi w kolejności po deskryptorze konfiguracji, jak to było opisane wcześniej.

Bibliografia

  1. Nota aplikacyjna NXP AN11018: USB composite device on the LPC134; 2010
  2. http://www.beyondlogic.org/usbnutshell/usb5.shtml#DeviceDescriptors
  3. USB Interface Association Descriptor Device Class Code and Use Model; 2003
  4. Specyfikacja USB 2.0
  1. Interface Association Descriptors Engineering Change Notice

Do pobrania

O autorze