ISIXRTOS v3 mini system operacyjny dla mikrokontrolerów rodziny M0/M3/M4/M7 (8). Panel dotykowy

ISIXRTOS v3 mini system operacyjny dla mikrokontrolerów rodziny M0/M3/M4/M7 (8). Panel dotykowy
Pobierz PDF Download icon

W poprzednim odcinku uruchomiliśmy wyświetlacz graficzny oraz przykładowe demo pokazujące możliwości graficzne biblioteki libgfx, jednak jak łatwo zauważyć brakuje nam jeszcze warstwy wejściowej, umożliwiającej wprowadzenie danych.

Wyświetlacz zestawu ewaluacyjnego STM32F469I-DISCO posiada pojemnościowy panel dotykowy, który możemy użyć jako źródło wprowadzania danych. Sercem panelu zintegrowanego z zestawem jest kontroler FT6x06 zapewniający następującą funkcjonalność:

  • obsługa bezwzględnych współrzędnych x, y,
  • obsługę gestów oraz wielodotyku,
  • wsparcie dla auto kalibracji, której zadaniem jest dostosowanie panelu dotykowego do warunków środowiskowych.

Od strony elektrycznej dostęp do rejestrów kontrolera dotykowego możliwy jest za pośrednictwem magistrali I2C oraz dodatkowej linii przerwań zewnętrznych, umożliwiającej zgłaszanie zdarzeń bez konieczności ciągłego sprawdzania zawartości rejestrów układu. Budowę wewnętrzną układu przedstawiono na rysunku 1.

Blok AFE stanowi część sprzętową i odpowiedzialny jest za interakcję z panelem dotykowym. Zawiera on blok generatora sygnałów szybkozmiennych oraz analogową część odbiorczą, umożliwiającą detekcję dotyku opartą o zmiany pojemności. Mikrokontroler z wbudowaną pamięcią ROM zawiera program zajmujący się obsługą panelu oraz odciążający procesor główny od monotonnej czynności ciągłego skanowania panelu. Komunikacja z hostem zewnętrznym odbywa się za pomocą magistrali I2C. Sposób podłączenia kontrolera do mikrokontrolera w zestawie ewaluacyjnym przedstawiono na rysunku 2.

Linie SDA i SCL panelu dotykowego zostały dołączone do portów PB8, PB9, które w trybie alternatywnym stanowią interfejs magistrali I2C1 mikrokontrolera. Linia przerwania informująca o wystąpieniu zdarzenia została podłączona do portu PJ5, który może być używany przez kontroler przerwań zewnętrznych EXTI. Sposób dołączenia panelu dotykowego do kontrolera odbywa się w sposób klasyczny, tak jak w przypadku każdego urządzenia z magistralą I2C.

Oprogramowanie

Za obsługę i generowanie zdarzeń od urządzeń peryferyjnych w bibliotece libgfx odpowiedzialny jest podsystem input. Hierarchię klas tego podsystemu przedstawiono na rysunku 3. Klasę bazową dla wszystkich klas pochodnych stanowi klasa input_dev umożliwiająca wstrzykiwanie zdarzeń do podsystemu graficznego. Z klasy bazowej dla urządzeń wejściowych dziedziczą poszczególne kategorie urządzeń takie jak: panel dotykowy, klawiatura oraz myszka. Tworząc sterownik urządzenia wejściowego dla biblioteki graficznej należy dziedziczyć z wybranej kategorii urządzenia wejściowego. W przypadku panelu dotykowego klasa ft6x06_touchpad odpowiedzialna za obsługę panelu dotykowego zestawu a jej jedynym publicznym interfejsem jest jej konstruktor oraz metoda start() umożliwiająca uruchomienie wątku odpowiedzialnego za obsługę kontrolera (listing 1).

Konstruktor przyjmuje szereg argumentów potrzebnych do działania sterownika i są to odpowiednio: nazwa panelu konfiguracyjnego, która jest później wykorzystywana przez podsystem DTS do odczytu parametrów konfiguracyjnych, referencja do obiektu kontrolera I2C oraz referencja do klasy frame, która odpowiedzialna jest za rysowanie elementów na ekranie. Za obsługę zdarzeń oraz odczyt danych z kontrolera odpowiedzialna jest metoda thread() (listing 2).

Metoda ta rozpoczyna pracę od wywołania metody intialize() odpowiedzialnej za konfiguracje układu ft6x06. W przypadku gdy inicjalizacja przebiegła pomyślnie wykonywana jest pętla nieskończona, która w cyklu 50 ms odczytuje z rejestrów konfiguracyjnych status kontrolera a jako wynik zwraca ilość zdarzeń jaka została wykryta. W przypadku wykrycia jakiegokolwiek zdarzenia wywoływana jest metoda print_touch() wypisująca na ekranie aktualnie wykryte zdarzeniem oraz metoda report_touch(). Zadaniem tej metody jest przekazanie zdarzeń dotykowych do klasy frame zarządzającej oknami na wyświetlaczu. Wspomniane wyżej funkcje jako jedyny argument przyjmują strukturę touch_tag, która opisuje zdarzenie dotykowe i pozwala później poszczególnym widżetom podjąć reakcję na poszczególne zdarzenia (listing 3). Do najważniejszych elementów tej struktury należą: pozycja bezwzględną wskazującą miejsce, gdzie ekran został dotknięty, szerokość obszaru dotknięcia oraz identyfikator gestu realizowanego za pomocą wielodotyku np. podniesienie okna, rozciągnięcie okna, zbliżenie oddalenie itp.

Wróćmy teraz na chwilę do funkcji inicjalizującej sterownik panelu dotykowego (listing 4). W metodzie tej w pierwszej kolejności wywoływana jest metoda detect_device(), której zadaniem jest stwierdzenie obecności dołączenia kontrolera do magistrali I2C. Działanie tej metody sprowadza się do odczytania zawartości rejestru identyfikacyjnego i porównaniu go z danym wzorcem. Jeśli wartość odczytana będzie różna od wartości wzorcowej lub nie uda się odczytać zawartości rejestru, zgłoszony będzie błąd, w wyniku czego wątek sterownika zakończy działanie. W przypadku, gdy stwierdzimy iż kontroler został prawidłowo podłączony do magistrali, z bazy DTS odczytywana będzie aktualna rozdzielczość ekranu dotykowego. Rozdzielczość ta potrzebna jest metodzie touch_enable(), której zadaniem jest odpowiednie skonfigurowanie układu (listing 5).

W pierwszej kolejności sprawdzamy w jakiej orientacji pracuje wyświetlacz i w przypadku, gdy stwierdzimy, że znajduje się on w orientacji poziomej, ustawiane są dodatkowe bity konfiguracyjny zamieniające oś X z osią Y, które w późniejszym etapie będą przesłane do odpowiedniego rejestru. W kolejnym kroku wywoływana jest metoda calibrate(), której zadaniem jest kalibracja panelu dotykowego, tak aby dostosować go aktualnych warunków środowiskowych, a następnie wywoływana jest metoda disable_int(), której zadaniem jest wyłączenie zgłaszania przerwań na linii INT kontrolera, ponieważ w aktualnej implementacji sterownik pracuje w trybie odpytywania bez systemu przerwań.

Najważniejszą metodą wywoływaną w pętli głównej w cyklu 50 ms jest metoda get_state(), której zadaniem sprawdzenie czy wystąpiło zdarzenie oraz odczytanie informacji o typach zdarzeń dotykowych z rejestrów układu a następnie odpowiednie wypełnienie struktury przechowującej informację o zdarzeniu (listing 6).

W pierwszej kolejności wywoływana jest metoda get_touch(), która z rejestrów kontrolera odczytuje ilość zdarzeń jaka została wykryta. W przypadku gdy liczba zdarzeń jest większa od 0,wówczas w pętli odczytywana jest pozycja (x,y) miejsca dotknięcia, jednak z uwagi iż wyświetlacz może być ustawiony w pozycji pionowej lub pionowej, odczytane z rejestrów układu współrzędne należy przeliczyć tak, aby odpowiadały one rzeczywistym współrzędnym ekranowym.

Po przeliczeniu współrzędnych wywoływana jest metoda get_info(), której zadaniem jest odczytanie dodatkowych informacji o zdarzeniu takich jak m.in. typ gestu czy obszar w jakim nastąpiło zdarzenie. W kolejnym kroku w pętli switch..case następuje przeliczenie wartości rejestru zawierającego kod zdarzenia na identyfikatory zdarzeń występujące w bibliotece graficznej libgfx.

Mamy już gotowy sterownik umożliwiający zgłaszanie zdarzeń. Pozostało nam jeszcze utworzenie instancji klasy jako składowej prywatnej w klasie tft_livedemo przedstawionej w poprzednim odcinku, co zrealizowano bezpośrednio pliku tft_livedemo.hpp

gfx::drv::ft6x06_touch m_touch { „display”, m_i2c, frame };

Jako pierwszy argument przekazujemy do konstruktora nazwę stanowiącą identyfikator urządzenia wyświetlacza, potrzebny do odczytania danych z konfiguracji DTS, referencję do sterownika magistrali I2C oraz referencję do klasy frame biblioteki graficznej, która odpowiedzialna jest za zarządzanie oknem głównym biblioteki graficznej.

Aby uruchomić powyższy przykład należy podłączyć do komputera zestaw stm32f469i-disco z wykorzystaniem kabla mini USB oraz pobrać kod źródłowy z repozytorium wpisując polecenie:

waf configure --crystal-hz=8000000 --debug waf
waf
waf program

Równocześnie do wirtualnego portu szeregowego utworzonego przez programator należy podłączyć dowolny program terminalowy oraz ustawiając następujące parametry transmisji: 115200,n,8,1.

Po wykonaniu powyższych czynności na wyświetlaczu powinno pojawić się okno z demonstracyjnymi widżetami biblioteki graficznej. Dotykając teraz poszczególnych elementów na ekranie na konsoli szeregowej będziemy mogli zaobserwować informację o pozycji dotknięcia, obszarze dotknięcia oraz ewentualnych gestach. Jednak nadal interfejs dotykowy w żaden sposób nie będzie reagował na zdarzenia. O tym jak zrobić, aby wspomniane elementy reagowały na dotyk, dowiemy się z kolejnego odcinka, gdy zostanie przedstawione więcej szczegółów na temat biblioteki libgfx.

Lucjan Bryndza, EP
lucjan.bryndza@boff.pl

Artykuł ukazał się w
Elektronika Praktyczna
listopad 2019
DO POBRANIA
Pobierz PDF Download icon
Zobacz też
Elektronika Praktyczna Plus lipiec - grudzień 2012

Elektronika Praktyczna Plus

Monograficzne wydania specjalne

Elektronik wrzesień 2020

Elektronik

Magazyn elektroniki profesjonalnej

Raspberry Pi 2015

Raspberry Pi

Wykorzystaj wszystkie możliwości wyjątkowego minikomputera

Świat Radio wrzesień 2020

Świat Radio

Magazyn użytkowników eteru

Automatyka Podzespoły Aplikacje wrzesień 2020

Automatyka Podzespoły Aplikacje

Technika i rynek systemów automatyki

Elektronika Praktyczna wrzesień 2020

Elektronika Praktyczna

Międzynarodowy magazyn elektroników konstruktorów

Praktyczny Kurs Elektroniki 2018

Praktyczny Kurs Elektroniki

24 pasjonujące projekty elektroniczne

Elektronika dla Wszystkich sierpień 2020

Elektronika dla Wszystkich

Interesująca elektronika dla pasjonatów