Pomysł stworzenia od podstaw urządzenia USB narodził z chęci zrozumienia zasady działania i dokładniejszego poznania standardu USB 2.0. Kiedyś najpopularniejszym standardem do komunikacji z urządzeniami peryferyjnymi był interfejs RS232C. Obecnie najpopularniejszym interfejsem jest interfejs USB, i warto go dobrze poznać, jak również posiadać własne autorskie oprogramowanie do jego obsługi. Producenci mikrokontrolerów udostępniają biblioteki do obsługi różnych interfejsów komunikacyjnych, między innymi USB. Biblioteki te są jednak tworzone w sposób uniwersalny, pozwalający wykorzystać je do różnych rodzin mikrokontrolerów. Miałem okazję "rzucić okiem" na jedną z takich bibliotek napisanych w języku C. Po krótkiej analizie zdecydowałem się na samodzielne stworzenie kodu w języku C od podstaw.
Standardowo jak ma to miejsce w przypadku projektowania układów elektronicznych praca została rozpoczęta od projektowania obwodu drukowanego. Płytka drukowana została zaprojektowana w programie KiCad. Z uwagi na prototypowy charakter projektu i dostępne od ręki elementy przewlekane zdecydowałem się na samodzielne wykonanie obwodu drukowanego z elementami przewlekanymi. Głównym celem projektu było stworzenie oprogramowania obsługi USB w mikrokontrolerze. Generalnie cała trudność tego przedsięwzięcia polegała właśnie na tworzeniu oprogramowania firmware dla mikrokontrolera. Z uwagi na zdobyte już doświadczenie z mikrokontrolerami PIC jak i dostępne zasoby, zastosowany został mikrokontroler PIC18LF2550. Mikrokontroler wyposażony jest w moduł obsługi interfejsu USB w dokumentacji nazwany jest SIE (english → Serial Interface Engine). Moduł do komunikacji poprzez USB troszkę robi "za nas", ale trzeba go odpowiednio skonfigurować i napisać oprogramowanie do jego obsługi. Ponieważ w standardzie USB dla trybu full-speed/low-speed zdefiniowana jest ramka (english → frame) o okresie T=1[ms] oczywistą sprawą było zastosowanie systemu przerwań. Moduł USB mikrokontrolera wywołuje w nim szereg różnych przerwań, co jest niezmiernie przydatne podczas obsługi interfejsu USB. Po wytrawieniu płytki i lutowaniu elementów poddana została ona sprawdzeniu czy nie ma żadnych zwarć.
Oprogramowanie dla mikrokontrolera zostało stworzone w środowisku MPLAB X IDE v1.51 z zastosowanie kompilatora MPLAB C18 v3.40. Cały program napisany został w języku C. W programie skonstruowana została obsługa przerwań oraz napisane zostały funkcje niezbędne do uruchomienia komunikacji poprzez USB. Moduł USB wykrywa identyfikatory pakietów na magistrali USB. Dokumentacja USB 2.0 wyróżnia kilka pakietów, moduł USB udostępnia informacje o wystąpieniu trzech z nich:
• SETUP TOKEN - transakcja z Hosta USB do urządzenia USB (Host USB → urządzenie USB)
• OUT TOKEN - transakcja z Hosta USB do urządzenia USB (Host USB → urządzenie USB)
• IN TOKEN - transakcja z urządzenia USB do Hosta USB (urządzenie USB → Host USB)
Pojedyncza transakcja na magistrali USB składa sie z maksymalnie trzech faz (SETUP/OUT, IN, STATUS). Każdy faza podzielona na jest na minimalnie trzy etapy.
Przykładowa transakcja wygląda następująco:
• faza 1 - wysłanie danych z hosta USB do urządzenia USB
· host USB wysyła do urządzenia USB pakiet oznaczony jako SETUP TOKEN lub OUT TOKEN
· host USB wysyła do urządzenia USB pakiet lub pakiety oznaczone jako DATA0/DATA1
· urządzenie USB wysyła do hosta USB pakiet ACK lub NAK
• faza 2 - wysłanie danych z urządzenia USB do hosta USB
· urządzenie USB wysyła do hosta USB pakiet IN TOKEN
· urządzenie USB wysyła do hosta USB pakiet lub pakiety oznaczone jako DATA0/DATA1
· host USB wysyła do urządzenia USB pakiet ACK lub NAK
• faza 3 - status
· host USB wysyła do urządzenia USB pakiet oznaczony jako OUT TOKEN
· host USB wysyła do urządzenia USB pakiet DATA1 bez danych - oznacza to akceptację otrzymanych informacji od urządzenia USB
· urządzenie USB wysyła do hosta USB pakiet ACK lub NAK (ACK - jak otrzymany pakiet był bez błędów, NAK - jak wystąpiły błędy)
Przedstawiona powyżej wymiana danych pomiędzy hostem USB a urządzeniem USB zawiera dziewięć zdarzeń. Taka przykładowa transakcja wywoła w mikrokontrolerze trzy przerwania, które trzeba w sposób zgodny z standardem USB 2.0 zinterpretować.
Skonstruowane urządzenie jest kompatybilne z USB 2.0. Moje urządzenie USB pracuje jako full-speed device.