Sprzęt Aby zaimplementować interfejs USB w urządzeniu



Podobne dokumenty
Programator procesorów rodziny AVR AVR-T910

MultiTool instrukcja użytkownika 2010 SFAR

INSTRUKCJA INSTALACJI DRUKARKI. (Dla Windows CP-D70DW/D707DW)

LITEcompLPC1114. Zestaw ewaluacyjny z mikrokontrolerem LPC1114 (Cortex-M0) Sponsorzy:

PRZETWORNIK USB - RS232

PRZETWORNIK USB - RS232

dokument DOK wersja 1.0

inode instalacja sterowników USB dla adaptera BT 4.0

STM32Butterfly2. Zestaw uruchomieniowy dla mikrokontrolerów STM32F107

ZL2ARM easyarm zestaw uruchomieniowy dla mikrokontrolerów LPC2104/5/6 (rdzeń ARM7TDMI-S)

Zestaw uruchomieniowy z mikrokontrolerem LPC1114 i wbudowanym programatorem ISP

Instrukcja do oprogramowania ENAP DEC-1

OPTIMA PC v Program konfiguracyjny dla cyfrowych paneli domofonowy serii OPTIMA ELFON. Instrukcja obsługi. Rev 1

Sprawozdanie z projektu MARM. Część druga Specyfikacja końcowa. Prowadzący: dr. Mariusz Suchenek. Autor: Dawid Kołcz. Data: r.

ZL9ARM płytka bazowa dla modułów diparm z mikrokontrolerami LPC213x/214x

Vinculum scalony host USB

ZL24PRG. Interfejs JTAG dla mikrokontrolerów ARM

Tab. 1. Zestawienie najważniejszych parametrów wybranych mikrokontrolerów z rodziny LPC2100, które można zastosować w zestawie ZL3ARM.

INTERFEJS LPG/CNG FTDI USB INSTRUKCJA INSTALACJI ORAZ KONFIGURACJI URZĄDZENIA

AUTOMATYKA PRZEMYSŁOWA

Politechnika Gdańska Wydział Elektrotechniki i Automatyki Katedra Inżynierii Systemów Sterowania

ZL2ARM easyarm zestaw uruchomieniowy dla mikrokontrolerów LPC2104/5/6 (rdzeń ARM7TDMI-S)

ASMAX ISDN-TA 128 internal Instalacja adaptera w środowisku Windows 98 / ME

BF30 OCDLINK/USBASP ARM-JTAG/AVR-ISP Programmer-debugger Instrukcja obsługi

ZL25ARM. Płyta bazowa dla modułów diparm z mikrokontrolerami STR912. [rdzeń ARM966E-S]

BF20 JTAG dla ARM ów z interfejsem USB Instrukcja obsługi

Laboratorium ASCOM COLT-2

INSTRUKCJA UŻYTKOWANIA CZYTNIKA KART PROCESOROWYCH SYGNET 5v1 IU SY5

1. Opis. 2. Wymagania sprzętowe:

MOBOT-RCR v2 miniaturowe moduły radiowe Bezprzewodowa transmisja UART

Instalacja i uruchomienie karty TwinHan w Windows XP Media Center.

Instrukcja instalacji i konfiguracji bazy danych SQL SERVER 2008 EXPRESS R2. Instrukcja tworzenia bazy danych dla programu AUTOSAT 3. wersja 0.0.

Aktualizacja modemu LTE Speed 1000

Instalacja programu Synergia ModAgent. Legnica, r.

ADVANCE ELECTRONIC. Instrukcja obsługi aplikacji. Modbus konfigurator. Modbus konfigurator. wersja 1.1

Płytka uruchomieniowa XM64

Instrukcja dla instalatora systemu SMDP Enterprise/Professional

Instrukcja instalacji oraz konfiguracji sterowników. MaxiEcu 2.0

BLUETOOTH INSTRUKCJA PODŁĄCZENIA I KONFIGURACJI.

OPIS PROGRAMU APEK MULTIPLEKSER RX03

ZL29ARM. Zestaw uruchomieniowy dla mikrokontrolerów STM32F107

LabVIEW PLATFORMA EDUKACYJNA Lekcja 5 LabVIEW i Arduino konfiguracja środowiska i pierwszy program

Instalacja sterowników w systemie operacyjnym WINDOWS 8 ; 8.1 ; 10

ZL9AVR. Płyta bazowa dla modułów ZL7AVR (ATmega128) i ZL1ETH (RTL8019)

Pracownia internetowa w szkole ZASTOSOWANIA

Instrukcja użytkownika ARSoft-WZ1

1.1 Co to jest USBasp? Parametry techniczne Obsługiwane procesory Zawartość zestawu... 4

ZL5ARM. Zestaw uruchomieniowy dla mikrokontrolerów LPC2119/2129 (rdzeń ARM7TMDI-S) Kompatybilność z zestawem MCB2100 firmy Keil

ZL6ARM Zestaw uruchomieniowy dla mikrokontrolerów LPC213x. Tab. 1. Zestawienie najważniejszych parametrów wybranych mikrokontrolerów z rodziny LPC213x

Konfiguracja pakietu CrossStudio for MSP

Poradnik instalacyjny sterownika CDC-ACM Dla systemów Windows

PLUTO Sterownik bezpieczeństwa Skrócona Instrukcja obsługi oprogramowania. PlutoProgrammingManualPL_v7A.pdf 1

ZL8AVR. Płyta bazowa dla modułów dipavr

STM32 Butterfly. Zestaw uruchomieniowy dla mikrokontrolerów STM32F107

Laboratorium Procesorów Sygnałowych

INTERFEJS FIAT ECU SCAN USB INSTRUKCJA OBSŁUGI strona 1/17

INSTRUKCJA OBSŁUGI PROGRAMU INSTAR 1.0

Instrukcja dla: Icomsat v1.0 SIM900 GSM/GPRS shield for Arduino oraz dla GPRS Shield produkcji Seeedstudio.

INSTRUKCJA OBSŁUGI PRZYSTAWKI PEN-01 DO PENDRIVE A

Politechnika Łódzka. Instytut Systemów Inżynierii Elektrycznej

Kontrola topto. 1. Informacje ogólne. 2. Wymagania sprzętowe i programowe aplikacji. 3. Przykładowa instalacja topto. 4. Komunikacja.

SKRÓCONA INSTRUKCJA INSTALACJI MODEMU I KONFIGURACJA POŁĄCZENIA Z INTERNETEM NA WINDOWS 8 DLA AnyDATA ADU-520L

NPS-520. Serwer druku do urządzeń wielofukcyjnych. Skrócona instrukcja obsługi. Wersja 1.00 Edycja 1 11/2006

Instrukcja aktualizacji oprogramowania. Wersja dokumentu: 01i00 Aktualizacja:

Konfiguracja parametrów sondy cyfrowo analogowej typu CS-26/RS/U

Engenius/Senao EUB-362EXT IEEE802.11b/g USB Instrukcja Obsługi

ADAPTER USB INTERFEJS SZEREGOWY

INTERFEJS SUBARU USB INSTRUKCJA OBSŁUGI strona 1/14

ALNET USB - RS Konwerter USB RS 232/422/485 Instrukcja obsługi

Windows 10 - Jak uruchomić system w trybie

Szkolenia specjalistyczne

micro Programator ISP mikrokontrolerów AVR zgodny z STK500v2 Opis Obs³ugiwane mikrokontrolery Wspó³praca z programami Podstawowe w³aœciwoœci - 1 -

INSTRUKCJA UŻYTKOWNIKA MPCC

ZL27ARM. Zestaw uruchomieniowy dla mikrokontrolerów STM32F103

Motorola Phone Tools. Krótkie wprowadzenie

Seria wielofunkcyjnych serwerów sieciowych USB

Xesar. Pierwsze kroki

Rozdział 1. Zagadnienia podstawowe

Rozwiązywanie problemów z konfliktem driverów RFID czytnika 3M RTE8000 i Vicomp VPR600/610/620e

Obługa czujników do robota śledzącego linie. Michał Wendland czerwca 2011

UNIFON podręcznik użytkownika

Satel Integra FIBARO

Instrukcja instalacji systemu. CardioScan 10, 11 i 12

Laboratorium Komputerowe Systemy Pomiarowe

Rys. 1. Schemat ideowy karty przekaźników. AVT 5250 Karta przekaźników z interfejsem Ethernet

Site Installer v2.4.xx

PROGRAM TESTOWY LCWIN.EXE OPIS DZIAŁANIA I INSTRUKCJA UŻYTKOWNIKA

Instrukcja obsługi programatora AVR Prog USB v2

o Instalacja środowiska programistycznego (18) o Blink (18) o Zasilanie (21) o Złącza zasilania (22) o Wejścia analogowe (22) o Złącza cyfrowe (22)

CAN ANALIZATOR- TESTER

Instrukcja obsługi. PROGRAMATOR dualavr. redflu Tarnów

Seria wielofunkcyjnych serwerów sieciowych USB

ZL11ARM. Uniwersalna płytka bazowa dla modułów diparm

Electronic Infosystems

Zestaw Startowy EvB. Więcej informacji na stronie:

Laboratorium - Instalacja Virtual PC

1 Moduł Konwertera. 1.1 Konfigurowanie Modułu Konwertera

Instrukcja obsługi programatora AVR Prog USB v2

1. Tworzenie nowego projektu.

Połączenia. Obsługiwane systemy operacyjne. Instalowanie drukarki przy użyciu dysku CD Oprogramowanie i dokumentacja

Transkrypt:

USB na poważnie Temat USB był poruszany na łamach EP wielokrotnie. Przeważająca większość projektów opierała się na zastosowaniu któregoś z dostępnych układów mostów UART/USB. Układy te skutecznie oraz w efektowny (i efektywny) sposób pozwalają konstruktorom na wyposażanie swoich urządzeń w interfejs USB. Ale jest też druga strona medalu, którą możemy podzielić na dwie części: po pierwsze koszt urządzenia wzrasta, płytka drukowana musi zmieścić jeszcze jeden układ oraz dokładamy ryzyko potencjalnych problemów z uruchomieniem kolejnego ogniwa w łańcuchu transmisyjnym. Po drugie, pozostaje pewien niedosyt jak to możliwe, że implementacje tak zaawansowanego interfejsu zamknęliśmy w jednej kości? To już koniec? Ale jak to tak naprawdę działa? Niniejszy artykuł ma za zadanie pokazać, jak skonstruować urządzenie z USB w sposób tradycyjny i nie wymagający ogromnej wiedzy na temat samego interfejsu. Sprzęt Aby zaimplementować interfejs USB w urządzeniu będziemy naturalnie potrzebowali mikrokontroler wyposażony w sterownik USB. Zastosujemy układ z rdzeniem ARM7 LPC2148 produkowany przez firmę NXP. Podstawowe jego parametry zebrano w tab. 1, jednak nas najbardziej interesuje fakt, iż jest on wyposażony w kontroler USB zgodny ze specyfikacją 2.0 Full speed. Kontroler posiada 2 kb podręcznej pamięci RAM (przeznaczonej na bufory Endopointów USB) oraz dodatkowo 8 kb RAM-u wykorzystywanego przy pomocy mechanizmu DMA. Kontroler urządzenia USB w LPC2148 posiada pięć wyprowadzeń (rys. 1). D+ oraz D są właściwymi liniami transmisji danych USB. Linia VBUS dostarcza kontrolerowi informacji o obecności napięcia 5 V (po stronie hosta). Linia CON- NECT oraz UP_LED dzielą jedno fizyczne wyprowadzenie. Linia CONNECT jest odpowiedzialna za funkcję miękkiego dołączania urządzenia od komputera nadrzędnego. Aby host rozpoczął proces enumeracji (negocjacji połączenia z urządzeniem) linia danych D+ musi być podciągnięta do napięcia zasilającego urządzenia poprzez rezystor 1,5 kv. Innymi słowy, jeśli rezystor Rys. 1. Wyprowadzenia kontrolera USB w LPC2148 (w nawiasach podano numery wyprowadzeń układu) Tab. 1. Zestawienie podstawowych parametrów kontrolera LPC2148 Parametr Opis Rdzeń ARM7TDMI S Pamięć RAM 40 kb (32 kb + 8 kb USB RAM) Pamięć Flash 512 kb ISP In System Programming: Wbudowany bootloader umożliwiający programowanie Pamięci RAM/Flash poprzez układ UART IAP In Application Programming: Mechanizm umożliwiający programowanie wewnętrznej pamięci Flash z poziomu kodu aplikacji USB Kontroler urządzenia USB 2.0. Wyposażony jest w 2 kb RAM dla Endpointów USB. Kontroler posiada również 8 kb RAM dostępnej poprzez DMA Pozostałe interfejsy komunikacyjne UART, I 2 C, SPI ADC Dwa 10 bitowe przetworniki analogowo cyfrowe DAC 10 bitowy przetwornik DAC PWM Sześć kanałów Zegar Max 45 MHz Układ jest zasilany pojedynczym napięciem z zakresu 3...3,6 V. Wyposażony jest Zasilanie w układy zerowania (Power-on Reset) oraz detekcji spadku napięcia (Brown-out Detect). Ponadto kontroler posiada kilka trybów oszczędzania energii podciągający będzie nieobecny, komputer nie zareaguje na fakt włożenia wtyczki do gniazda USB. Rozwiązanie to może być wykorzystane do zasymulowania przez urządzenie wyjęcia i włożenia wtyczki do gniazda hosta (a tym samym wymuszenie procesu enumeracji). Mechanizm ten jest wykorzystywany w przypadku, gdy urządzenie chciałoby zmienić swoją konfigurację USB lub nawet zmienić klasę, jaką eksponuje po podłączeniu do komputera. Jest to powszechnie stosowana praktyka np. w telefonach komórkowych, kiedy to telefon może służyć jako modem (klasa USB Communication Device Class), a po wybraniu odpowiedniej opcji z menu może być widoczny jako urządzenie składujące (Mass Storage). Przełączenie się z jednej klasy do drugiej może w tym przypadku nastąpić bez fizycznego odłączania urządzenia od hosta. Schemat podłączenia linii CONNECT przedstawiono na rys. 2. Jeśli mechanizm miękkiego odłączania nie jest w urządzeniu niezbędny, wówczas możemy użyć funkcji UP_LED końcówki 17. Jest to tzw. USB GoodLink LED. Linia dostarcza informacji o tym, iż proces enumeracji zakończył się powodzeniem (oraz że endpointy transmisji danych zostały uaktywnione). W takim przypadku na linii panuje poziom niski. Gdy kontroler nie został prawidłowo skonfigurowany (wewnętrznie jako blok procesora, bądź podczas procesu enumeracji), wówczas na linii występuje poziom wysoki. Schemat podłączenia kontrolera USB w przypadku wykorzystania linii UP_LED przedstawiono na rys. 3. Należy zwrócić uwagę na to, iż linia D+ kontrolera jest na stałe podciągnięta do zasilania układu, tak więc jedyną metodą na wymuszenie na hoście ponownej enumeracji urządzenia będzie fizyczne odłączenie i ponowne podłączenie wtyczki USB. Wszystkie opisywane przykłady były testowane przy użyciu płyty ewaluacyjnej, ZL9ARM wyposażonej w moduł ZL10ARM_2148. Zestaw ten jest bardzo rozbudowany i nie będziemy wykorzystywać wszystkich jego peryferiów. Najważniejsze dla nas jest to, iż płyta bazowa jest wyposażona w gniazdo USB B (klient). Na płycie nie zastosowano żadnego z opisanych rozwiązań użycia końcówki 17. Linia D+ jest podłączona na stałe do zasilania. Firmware Do wykorzystania zasobów USB mikrokontrolera LPC2148 będziemy potrzebowali stosu USB. Do wyboru są dwie drogi: napisanie stosu samodzielnie, bądź skorzystanie z gotowych darmowych stosów dostępnych w sieci. Przykładem jest tutaj stos lpcusb, (http://wiki.sikken.nl/index.php?title=lpcusb). Stos ten jest 76 ELEKTRONIKA PRAKTYCZNA 1/2009

USB na poważnie Rys. 2. Sposób użycia funkcji CONNECT końcówki 17 Rys. 3. Sposób użycia funkcji UP_LED końcówki 17 List. 1. Fragment implementacji klasy CDC ACM w stosie lpcusb... // initialise stack USBInit(); // register descriptors USBRegisterDescriptors(abDescriptors); // register class request handler USBRegisterRequestHandler(REQTYPE_TYPE_CLASS, HandleClassRequest, abclassreqdata); // register endpoint handlers USBHwRegisterEPIntHandler(INT_IN_EP, NULL); USBHwRegisterEPIntHandler(BULK_IN_EP, BulkIn); USBHwRegisterEPIntHandler(BULK_OUT_EP, BulkOut); // register frame handler USBHwRegisterFrameHandler(USBFrameHandler); // enable bulk in interrupts on NAKs USBHwNakIntEnable(INACK_BI);... ELEKTRONIKA PRAKTYCZNA 1/2009 napisany w języku C, a do jego kompilacji autor używał kompilatora gcc dostarczonego w pakiecie GNUARM. Na początek pobierzmy źródła stosu lpcusb z http://sourceforge.net/projects/lpcusb. W chwili pisania tekstu najnowszą wersją stosu była v20070727. Archiwum nosi nazwę target- -20070727. Po rozpakowaniu archiwum możemy skompilować stos poleceniem make (wydanym w folderze głównym). Akcja ta spowoduje również wygenerowanie kodów wynikowych aplikacji przykładowych dostarczonych ze stosem. Skupimy się na dwóch z nich. Pierwszą będzie emulacja portu szeregowego, natomiast druga to implementacja prostego interfejsu komunikacyjnego opartego o endpointy typu Bulk. Wirtualny COM port Czytelnikom EP doskonale znane są układy firmy FTDI. Popularne mosty USB< >RS232 tak naprawdę dostarczają funkcjonalności wirtualnego portu szeregowego. Stos USB tych układów eksponuje urządzenie klasy CDC ACM (Communications Device Class Abstract Control Model) zapewniające emulację portu szeregowego przy komunikacji USB. Obsługa układów sprowadza się do połączenia ich z mikrokontrolerem przy pomocy układu UART. Po stronie komputera PC potrzebujemy jedynie odpowiedniego sterownika wirtualnego portu szeregowego (dostarczanego przez producenta układu). Identyczny efekt możemy uzyskać stosując stos lpcusb. W katalogu /examples znajdziemy przykład implementacji urządzenia CDC ACM. Znajduje się ona w pliku main_serial.c, którego fragment przedstawiono na list. 1. Pierwsza funkcja, która zostaje wywołana to USBInit(). Jej zadaniem jest inicjalizacja stosu, na którą składa się kilka elementów. W pierwszej kolejności funkcja konfiguruje wyprowadzenia P0.23 i P0.31, nadając im odpowiednio funkcje VBUS i CONNECT. Następnie funkcja włącza zasilanie bloku USB mikrokontrolera, po czym odbywa się konfiguracja sygnału zegarowego. Na samym końcu inicjalizowane są przerwania bloku USB. Kolejne czynności związane są już bezpośrednio z samym stosem USB. Funkcja konfiguruje tzw. endpoint zerowy (często nazywany też kontrolnym), którego zadaniem jest obsługa żądań napływających z hosta oraz wysyłanych do hosta. Konfiguracja ta polega na rejestracji odpowiedniej funkcji obsługującej dane żądanie oraz na zarezerwowaniu pamięci na bufory endpointów. Na samym końcu funkcja rejestruje procedurę obsługi samych żądań. Po inicjalizacji następuje wywołanie funkcji USBRegisterDescriptors(). Jak sugeruje nazwa, funkcja rejestruje deskryptory urządzenia oraz konfiguracji przypisując je do odpowiedniej zmiennej. Deskryptory definiują klasę urządzenia oraz kanały komunikacyjne. Do zrealizowania urządzenia klasy CDC-ACM potrzebne będą dwa endpointy typu bulk (po jednym w każdym kierunku transmisji danych) oraz jeden endpoint typu interrupt, niezbędny do sygnalizacji. W praktyce ma on znaczenie tylko przy obsłudze urządzeń modemowych. Dla rejestracji każdego z endpointów zostaje wywołana funkcja USB- HwRegisterEPIntHandler(), która w argumencie przyjmuje typ rejestrowanego endpointu, jak i funkcję wywoływaną, gdy w jego buforze znajdą się dane. Dla endpointu typu interrupt, w omawianej implementacji nie jest wywoływana żadna funkcja. Dwie kolejne linie w omawianym listingu odpowiedzialne są za inicjalizację przerwania w przypadku wystąpienia warunku NAK (Not Acknowledged) podczas transmisji danych. W następnej kolejności następuje konfiguracja modułu VIC odpowiedzialnego za przerwania w systemie oraz zostaje wywołana funkcja USBHwConnect() powodująca podłączenie urządzenia USB do hosta (w sensie dołączenia omawianego wcześniej rezystora 1,5 kv). Od tego momentu wszelkie zdarzenia USB będą obsługiwane w przerwaniach przy użyciu funkcji USBIntHandler(), która z kolei będzie wywoływać wszystkie niezbędne procedury obsługi, właśnie zarejestrowane. Program natomiast przechodzi do pętli głównej. W momencie nadania danych przez hosta (nie żądań konfiguracyjnych, ale wysłania danych) zostanie wywołana zarejestrowana wcze- 77

List. 2. Funkcja wywoływana w momencie odebrania danych z hosta /** Local function to handle incoming bulk data @param [in] bep @param [in] bepstatus */ static void BulkOut(U8 bep, U8 bepstatus) int i, ilen; if (fifo_free(&rxfifo) < MAX_PACKET_SIZE) // may not fit into fifo // get data from USB into intermediate buffer ilen = USBHwEPRead(bEP, abbulkbuf, sizeof(abbulkbuf)); for (i = 0; i < ilen; i++) // put into FIFO if (!fifo_put(&rxfifo, abbulkbuf[i])) // overflow... :( ASSERT(FALSE); break; Rys. 6. Urządzenia, których opisy znajdują się w przykładowym pliku.inf Rys. 4. Reakcja Windows XP na podłączenie płyty ZL10ARM_2148 z załadowanym przykładem serial.hex śniej funkcja callback (BulkOut()). Jej postać przedstawiono na list. 2. Funkcja, korzystając z utworzonej wcześniej kolejki fifo, odczytuje dane z bufora (USBHwEPRead()) endpointu i dopisuje je na koniec kolejki. Podobnie działa funkcja, która została zarejestrowana do obsługi endpointu typu IN. Funkcja po wystąpieniu warunku NAK sprawdza kolejkę fifo w poszukiwaniu danych do wysłania do hosta, i jeśli dane znajdują się w kolejce, następuje ich przepisanie do bufora endpointu, co spowoduje nadanie ich do hosta. Powróćmy teraz do pętli głównej przykładu. Jest tutaj wywoływana funkcja VCOM_getchar(), która sprawdza kolejkę fifo rx (danych przychodzących z hosta). Jeśli w kolejce znajduje się znak, wówczas zostanie wywołana funkcja VCOM_ putchar(), która spowoduje dopisanie znaku do kolejki fifo tx, a następnie odesłanie znaku do hosta. Innymi słowy, przykład realizuje funkcję ECHO dla wirtualnego portu szeregowego. Przejdźmy do strony PC systemu. Po podłączeniu urządzenia do hosta następuje proces enumeracji, którego jednym z etapów jest wysłanie przez hosta żądania przesłania deskryptorów urządzenia. W jednym z pól deskryptorów znajdują się numery Vendor ID oraz Product ID (VID & PID). Na ich podstawie host identyfikuje i ładuje potrzebny sterownik. W przypadku Windows XP sterownik wirtualnego portu szeregowego dostarczany jest wraz z systemem, jednak nie jest on domyślnie wyodrębniany z archiwów instalacyjnych. Konieczne jest jego ręczne wyodrębnienie poleceniem: C: WINDOWS Driver Cache i386>expand sp2.cab f:usbser.sys Dysponując plikiem sterownika usbser.sys można przystąpić do podłączenia urządzenia do hosta. Akcja ta spowoduje uaktywnienie się managera urządzeń (rys. 4) i prośbę o wskazanie pliku.inf (rys. 5). Plik ten wiąże numery VID i PID urządzenia z właściwym plikiem sterownika. Przykładowy plik.inf znajduje się w katalogu target examples i nosi nazwę usbser.inf. Po wskazaniu tego pliku system wyświetli urządzenia, które zostały w nim opisane (rys. 6) oraz poprosi o podanie lokalizacji pliku sterownika wirtualnego portu szeregowego (rys. 7). Jeśli proces instalacji sterownika przebiegnie poprawnie (rys. 8), wówczas w managerze urządzeń, w sekcji porty COM i LPT pojawi się nowy port COM (rys. 9). W celu szybkiego przetestowania funkcjonalności przykładu z pliku main_serial. c uruchommy HyperTermianal z odpowiednim numerem portu COM (parametry transmisji nie są istotne). Po wysłaniu kilku znaków z klawiatury powinniśmy otrzymać ich echo (rys. 10). Rys. 5. Prośba o wskazanie pliku.inf Rys. 7. Prośba o wskazanie pliku sterownika (usbser.sys) Mając taką wiedzę na temat działania stosu lpcusb, skonstruowanie urządzenia odpowiadającego funkcjonalnie kości FT232B, ale opartego o kontroler LPC2148 nie powinno być problemem. Co więcej, oprócz tej funkcjonalności mamy teraz do dyspozycji 32 bitowy rdzeń oraz wiele nieużytej pamięci programu przeznaczonej dla naszej aplikacji... Custom USB Co jednak, gdy nie chcemy interfejsu USB naszego urządzenia opierać o funkcjonalność wirtualnego portu szeregowego? Po stronie mikrokontrolera nie będzie to duży problem. Jak się zaraz przekonamy, w kolejnym przykładzie projekt własnego interfejsu komunikacyjnego (w sensie programowym) opartego o USB sprowadzi się tutaj do zmiany kilku linijek kodu. Po stronie PC wyzwanie jest trochę większe, ponieważ musimy stworzyć odpowiedni sterownik. Poniższy przykład pokaże jak poradzić sobie z tym problemem przy pomocy LabVIEW. Zacznijmy jednak od strony mikrokontrolera. Na list. 3 przedstawiono fragment kodu z pliku target/examples/main_cus- 78 ELEKTRONIKA PRAKTYCZNA 1/2009

USB na poważnie List. 3. Fragment przykładu kodu implementacji urządzenia USB własnej klasy // initialise stack USBInit(); // register device descriptors USBRegisterDescriptors(abDescriptors); // override standard request handler USBRegisterRequestHandler(REQTYPE_TYPE_VENDOR, HandleVendorRequest, abvendorreqdata); Rys. 8. Poprawnie zainstalowany wirtualny port szeregowy // register endpoints USBHwRegisterEPIntHandler(BULK_IN_EP, _HandleBulkIn); USBHwRegisterEPIntHandler(BULK_OUT_EP, _HandleBulkOut); DBG( Starting USB communication n ); // connect to bus USBHwConnect(TRUE); List. 4. Funkcja obsługi danych napływających z hosta static void _HandleBulkOut(U8 bep, U8 bepstatus) U8 bytecount = 0; U8 datarcvd[rcv_buff_size]; U8 nokstr[] = NOK n ; U8 okstr[] = OK n ; // get command bytecount = USBHwEPRead(bEP, datarcvd, RCV_BUFF_SIZE); if (bytecount < MIN_CMD_SIZE) USBHwEPWrite(BULK_IN_EP, nokstr, NOK_LENGTH); Rys. 9. Wirtualny port szeregowy widoczny w managerze urządzeń tom.c. Widzimy, że proces inicjalizacji stosu wygląda podobnie jak w przypadku urządzenia CDC ACM. Pierwszą czynnością jest rejestracja funkcji obsługującej kanał kontrolny USB (endpoint zerowy). Funkcja ta nosi nazwę Handle- VendorRequest() W naszym przykładzie ciało funkcji może pozostać puste. Nie będziemy sterować urządzeniem za pomocą endpointu zerowego. Właściwy interfejs komunikacyjny został ograniczony do dwóch endpointów typu bulk, po jednym dla każdego z kierunków transmisji. Kolejnym uproszczeniem (wprowadzonym przez autora stosu) jest obsługa wszystkich akcji przy pomocy mechanizmu poolingu (a nie jak w poprzednim przykładzie mechanizmu przerwań). Widzimy, że ISR obsługujący stos jest cyklicznie wywoływany w pętli głównej programu. Model komunikacyjny zakłada, iż urządzenie oczekuje Rys. 10. Test funkcjonalności ECHO opisywanego przykładu ELEKTRONIKA PRAKTYCZNA 1/2009 // execute command if(datarcvd[led_index] > 7) USBHwEPWrite(BULK_IN_EP, nokstr, NOK_LENGTH); else // perform LED action if(datarcvd[led_state] == 0) // led off LEDOff(dataRcvd[LED_INDEX]); else // led on LEDOn(dataRcvd[LED_INDEX]); // send ack USBHwEPWrite(BULK_IN_EP, okstr, OK_LENGTH); na komendy od programu sterującego (pracującego na hoście) i po każdej prawidłowej komendzie zwraca odpowiedź w postaci ciągu znaków OK n. Kiedy urządzenie otrzyma niewłaściwą komendę, wówczas zwróci ciąg NOK n. Zmodyfikujmy funkcję obsługującą dane przychodzące (_HandleBulkOut()) od hosta do urządzenia tak, aby wyglądała jak na list. 4. Jej ciało dostosowaliśmy do własnych potrzeb tak, aby sterować ośmioma diodami LED umieszczonymi na płycie ZL9ARM. Będziemy oczekiwać od hosta na ramkę komendy składającą się z dwóch bajtów. Pierwszy bajt to numer diody, na której ma zostać wykonana akcja. Drugi bajt określa czy dioda ma zostać włączona, czy nie. Po odebraniu danych z hosta, stos wywołuje funkcję _HandleBulkOut(). Dla nas jest to sygnał, iż w buforze endpointu znajdują się gotowe do 79

Rys. 11. Okno wyboru magistrali Rys. 12. Okno danych VID i PID oraz stringów, które będą widoczne w Managerze urządzeń odczytania dane. Wywołujemy, zatem funkcję USBHwEPRead(), która w argumencie otrzymuje lokalny bufor danych oraz maksymalną liczbę znaków do odczytu. Dysponując tymi danymi możemy przystąpić do analizy kolejnych bajtów ramki i przeprowadzić pożądane akcje. W rezultacie ich wykonania odsyłamy do hosta ciąg znaków potwierdzenia: OK. lub NOK (w przypadku błędnie skonstruowanej komendy). Do nadania danych do hosta używamy funkcji USBHwEPrite(), która zapisze dane do bufora nadawczego endopintu typu bulk in. Przejdźmy do strony hosta. Aby obsłużyć nasze spersonalizowane urządzenie USB będziemy potrzebowali sterownika dla systemu oraz jakiegoś programu sterującego. Skorzystamy przy tym z biblioteki VISA, którą uprzednio należy zainstalować. Najnowszą wersję biblioteki możemy pobrać z serwera National Instruments (ftp://ftp.ni.com, folder /support/visa/drivers/win32/4.3/visa430full. exe). Po instalacji z menu Start w grupie National instruments > VISA będzie widoczny kreator nowego sterownika VISA: VISA Driver Development Wizard. W pierwszej kolejności powinniśmy zobaczyć okno wyboru magistrali komunikacyjnej (rys. 11). Wybieramy oczywiście USB i klikamy przycisk Next. W następnym ekranie (rys. 12) musimy podać zestaw numerów VID i PID identyfikujących nasze urządzenie. W przypadku stosu lpcusb jego autor użył wartości odpowiednio 0xFFFF oraz 0x0004. Na potrzeby eksperymentów wartości te możemy zmieniać dowolnie w kodzie stosu (są one jednymi z pól deskryptorów). Rys. 13. Urządzenie Custom Comm Device gotowe do pracy Rys. 14. Panel czołowy aplikacji Ponadto mamy możliwość wpisania dowolnych nazw w pola Manfacturers Name i Model Name. Ciągi te będą identyfikowały urządzenie w managerze urządzeń. W oknie tym widnieje również opcja dla urządzeń, które eksponują dwa lub więcej interfejsów (compound devices). Pole to pozostawiamy niezaznaczone, jako że nasze urządzenie dysponuje tylko jednym interfejsem. W kolejnym kroku kreator wygeneruje plik.inf dla urządzenia, prosząc o jego nazwę oraz lokalizację. W ostatnim kroku kreator zapyta czy powinien zainstalować plik w systemie. Wybierzmy tę opcję tak, aby po detekcji nowego sprzętu, system Windows mógł samodzielnie odszukać plik.inf oraz powiązany plik sterownika. Otwórzmy teraz okno managera urządzeń i podłączmy nasze urządzenie do komputera (płytę ZL10ARM_2148 z załadowanym kodem). System uruchomi kreatora dodawania nowego sprzętu, w którym wybieramy opcję instalacji automatycznej. W tym momencie możemy obserwować akcje podejmowane przez instalatora w oknie managera urządzeń, aż do sytuacji przedstawionej na (rys. 13), kiedy to sterownik VISA dla naszego urządzenia został poprawnie zainstalowany i urządzenie jest gotowe do pracy. W tym momencie możemy uruchomić LabVIEW i przyjrzeć się aplikacji utworzonej do sterowania urządzeniem. Widok jej panelu czołowego przedstawiono na (rys. 14). Funkcjonalność programu możemy podzielić na trzy części. W pierwszej dokonujemy skanowania magistral komputera w poszukiwaniu urządzeń, dla których zainstalowany został sterownik VISA. Odpowiada za to przycisk Scan, a rezultat jest ładowany do rozwijanej listy Device. Widoczna na rys. 20 nazwa pozwoli nam odnaleźć urządzenie na podstawie numerów VID i PID. Konkretnie, nazwa nadana przez sterownik to: USB0::0xFFFF::0x0004::DEADC0DE::RAW. Po wybraniu właściwego urządzenia możemy przystąpić do próby otwarcia połączenia z jego sterownikiem. Kliknijmy zatem na przycisk Open, który spowoduje wywołanie VI VISA Open dostępnego w palecie Instrument I/O/VISA/VISA Advanced. Od tej chwili możemy nadawać komendy do urządzenia wpisując ich kolejne bajty w kontrolkę Command i klikając na przycisk Write. W indykatorze ACK możemy obserwować odpowiedź urządzenia. Czynność ta wykonywana jest przez kod widoczny na rys. 15. Widzimy tam dwa standardowe VI z palety VISA: Read i Write. VISA Write oprócz referencji do połączenia i ewentualnego błędu wejściowego przyjmuje tylko bufor danych do wysłania. Zaraz po tym następuje wywołanie VI VISA Read, który może odebrać maksymalnie 20 bajtów z urządzenia. Program posiada też funkcjonalność zamykania połączenia przy użyciu komponentu VISA Close. Komunikacja ta wygląda niemal identycznie jak w przypadku obsługi zwykłego portu COM. Ta unifikacja jest możliwa dzięki samej bibliotece VISA. W przykładzie nie był wykorzystany endopoint kontrolny (zerowy) interfejsu USB. Do jego obsługi służą dwa VI umieszczone w palecie VISA USB (Instrument I/O/VISA/VISA Advanced/Interface Specific/VISA USB). Są to VISA USB Control In oraz VISA USB Control Out. Komponenty te dopełniają funkcjonalności związanej z obsługą komunikacji USB w LabVIEW. Marcin Chrusciel, EP marcin.chrusciel@ep.com.pl Rys. 15. Kod wykonywany w celu wysłania nowej komendy do urządzenia i odbioru odpowiedzi 80 ELEKTRONIKA PRAKTYCZNA 1/2009