Czym jest V-USB?V-USB jest to biblioteka napisana z myślą o procesorach ATMEL umożliwiająca oprogramowanie komunikacji poprzez interfejs USB. Wprawny programista może spróbować przerobić bibliotekę pod inne procesory. Bibliotekę można ściągnąć ze strony projektu
http://www.obdev.at/products/vusb/index.html. W tym miejscu dowiesz się jak obsługiwać USB od strony projektu opartego na procesorze ATMEL oraz od strony środowiska systemu operacyjnego Twojego PC.
Schematy podłączeń
Zgodnie z zaleceniami końcówki D+ i D- powinny być podłączone do nóżek odpowiedzialnych za przerwania procesora (INT0, INT1) aczkolwiek łącze D+ interfejsu podłączone być powinno zawsze do nóżki INT0 natomiast D- może być podłączone gdzie chcemy. Dodatkowo ważnym jest aby napięcie wychodzące z łączy D+ i D- było na poziomie 3.6V co można uzyskać na kilka sposobów (patrz schematy poniżej). Zaleca się też podłączenie rezystora pull-up 1.5k do D- oraz pull-up lub pull-down 1M do D+ żeby uniknąć interferencji kiedy USB nie jest podłączone.
Jako, że USB zasilane jest napięciem 5V do jego obniżenia można użyć diody Zenera
Podłączenie 1Podłączenie 2Podłączenie 3Rys 1. Sposoby obniżenia napięcia na wyjściu USB
Rys 2. Schemat wtyczki
Przygotowanie do pracyZanim zaczniemy należy przygotować stanowisko pracy. Nie piszę już o samym układzie ale bardziej mam na myśli przygotowanie środowiska programistycznego tj. ściągnięcie biblioteki i przygotowanie jej do pracy z naszym programem.
Po ściągnięciu biblioteki rozpakowujemy ją do wybranego katalogu. Należy też ściągnąć sterowniki USB dla ©MS WINDOWS, dzięki którym będziemy mogli "rozmawiać" z naszym układem. Można to zrobić ze strony projektu libusb-win32. Moduł ten umożliwi nam skompilowanie sterowników dedykowanych dla naszego układu. Ale o tym później.
Kopiujemy folder usbdrv do naszego katalogu projektu. Wchodzimy do katalogu i tworzymy kopię pliku usbconfig_prototype.h jako usbconfig.h. Lokalizujemy linie definiującą porty IO oraz taktowanie zegara i jeśli to potrzebne uaktualniamy je do odpowiednich danych. W tym miejscu chciałbym zaznaczyć, że nasz procesor
MUSI byś taktowany jedną z wartości: 12 MHz, 15 MHz, 16 MHz oraz 20 MHz lub 12.8 MHz w ostateczności 16.5 MHz +/- 1%. Inne wartości taktowania spowodują, że nie będzie możliwości używania naszego urządzenia.
Dlatego należy używać zewnętrznych kwarców i oczywiście odpowiednio obliczyć i ustawić FUSE BITy. (ja ustawiam low =
AF high =
DF ext. =
01)
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Wstawiamy:
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Powinniśmy też skonfigurować nazwę naszego urządzenia oraz numer, przez który będzie nas rozpoznawać nasz sterownik WINDOWS.
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Przydaje się także informacja o tym czy nasze urządzenie korzysta z zasilania USB czy nie
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Tak naprawdę plik usbconfig.h jest na tyle dobrze opisany, że można samemu zaglądnąć do środka i zorientować się co jeszcze można ustawić. Zapraszam do lektury.
Czas na main.cPoniżej mamy podstawowy szkielet programu dla μprocesora obsługującego protokół i łącze USB
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Co tu mamy? Jak to działa? Małe wytłumaczenie
Zaimplementujmy funkcję
usbFunctionSetup() obsługującą wywołania USB (co i jak opiszę później)
W częsci głównej programu ustawiamy watchdog na 1 s, która zresetuje procesor jeśli coś pójdzie nie tak i nie zostanie wywołana funkcja
wdt_reset() w czasie 1000 ms. To zabezpiecza program przed jakimiś nietypowymi zachowaniami i pozwala uniknąć użytkownikowi odłączania i ponownego przyłączania urządzenia jeśli stanie się coś dziwnego.
Wywołajmy
usbInit() - funkcję inicjującą działąnie biblioteki V-USB.
Wymuśmy przenumerowanie USB poprzez użycie
usbDeviceDisconnect(), a następnie po 500ms
usbDeviceConnect(). Na wypadek resetu Watchdog.
Włączamy przerwania
Na sam koniec nieskończona pętla resetująca watchdog i wywołująca funkcję obsługi USB
usbPool().
Jak dotąd wszystko wygląda chyba prosto. Zatem wypadałoby napisać jak urządzenie ma odpowiadać na zewnętrzne wywołanie.
Aby lepiej zrozumieć w jaki sposób procesor odpowiada na zewnętrzne wywołania USB należy przybliżyć działanie trzech podstawowych funkcji. Ale to w następnej części
------------------------ [ Dodano po: 16 minutach ]Dwie funkcjeJak wspominałem w części poprzedniej aby zacząć pisanie programów do komunikacji USB należy poznać dwie, no może trzy podstawowe funkcje służące do komunikacji
URZĄDZENIE-KOMPUTER.Pierwszą funkcją, która musi być zawsze zdefiniowana jest
usbFunctionSetup(uchar dane[8]). Wywołując wezwanie USB z poziomu komputera uruchamiana jest zawsze ta funkcja. Jej wywołanie z poziomu procesora jest następujące:
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
usbRequest jest zdefiniowany następująco
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Wszystkie dane są przekazywane od strony komputera poprzez funkcje wywołującą działanie programu poprzez USB ale co i jak napiszę w kolejnej części. W tej chwili zajmiemy się tylko funkcjami usbFunctionSetup, usbFunctionRead oraz usbFunctionWrite.
bmRequestType - informuje sterownik o tym czy chcemy dane przesyłać z czy do urządzenia
bRequest - rodzaj wywołania (zazwyczaj ustalane przez programiste)
twValue - wartość przesyłana do urządzenia
twIndex - index (w rzeczywistości kolejna wartość wysyłana przez programistę)
twLength - ilość danych
Funckie
usbFunctionSetup możemy wykorzystać do wysyłania danych statycznych. Jeśli chcemy przesyłać dane odczytywane "w locie" winnismy użyć funkcji
usbFunctionRead.Przyszedł zatem czas na napisanie przykładowego programu służącego do zapalenia i gaszenia diody i przy okazji przesłania jakiegoś krótkiego tekstu np nazwy urządzenia. Ponieważ już wiadomo jak skonfigurować sterownik (patrz USB - AVR - biblioteka VUSB - część I) więc ten etap pominę.
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Mam nadzieję, że choć trochę rozjaśniłem sposoby komunikacji URZĄDZENIE<-->KOMPUTER poprzez USB. W następnej części wytłumaczę jak można przekazywać większą ilość danych niż 8 znaków (w dwie strony) oraz jak porozumiewać się z naszym procesorem z poziomu komputera (WIN/LINUX). Napiszę też trochę informacji na temat numerowania VENDOR/DEVICE aby pozostać legalnym.