Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 12 gru 2024, o 16:13


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 5 ] 
Autor Wiadomość
PostNapisane: 29 lip 2018, o 17:02 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 mar 2014
Posty: 1475
Pomógł: 167

W wątku z opisem dotyczącym programu SQP-I2Cscan napisanym w C# pojawiły się głosy, by tą wersje programu także opisać, więc poznęcam się nad Wami i to zrobię :mrgreen:.

Drugim programem, który powstał ramach Mirkowego konkursu (i dla Was na szczęście ostatnim, dzięki czemu więcej nie będę opisywał ;)) dotyczącego API dla ATB-USBasp 4.2 to program SQP-I2Cscan. Tak, tak, dla zmyłki to program o tej samej nazwie co wcześniej opisywana wersja z GUI https://forum.atnel.pl/topic21023.html, ale tym razem jest to wersja konsolowa, czyli bez GUI, napisana w C. Wykorzystuje on natywną bibliotekę libusb. Wymagane pliki są do pobrania ze strony https://sourceforge.net/projects/libusb/ (dołączone są też do archiwum projektu).

Jest to prosty program, realizujący tylko jedną praktyczną funkcję - skanuje magistralę I2C wykorzystując ATB-USBasp 4.2 (plus jeden bonus, o którym na końcu opisu). Wynik skanowania I2C prezentowany jest tekstowo podając adresy znalezionych urządzeń w formacie dziesiętnym i szesnastkowym zarówno w konwencjach adresów 7-bitowego i 8-bitowego.

Obrazek

Dzięki temu, że biblioteka libusb dostępna jest zarówno dla Windows jak i Linux, aplikacja poprawnie kompilującej się, bez jakichkolwiek przeróbek, zarówno pod Windows jak i pod Linux.
Oczywiście należy pamiętać aby w Makefile dodać odpowiednie podlinkowanie plików nagłówkowych oraz bibliotecznych libusb.

Cały kod udostępniam na licencja GNU GPL v. 3.0, czyli dostępny jest kod źródłowy z pełnymi prawami do samodzielnej modyfikacji i rozpowszechniania.
Kod programu znajduje się w wątku konkursowym https://forum.atnel.pl/topic20920.html#p209345. Jest on w tym samym archiwum co wersja w C# z GUI, ale w katalogu o nazwie SQP-I2Cscan (Console).
Dla lubiących narzędzia do wersjonowania, to ostateczną wersję wrzuciłem też do publicznego repozytorium https://bitbucket.org/rskup/sqp-i2cscan/.

Program pod Windows pisany był w darmowym przyjemnym i lekkim narzędziu Dev-C++, a w archiwum, dla chcących je szybko otworzyć, dorzucone są od razu pliki projektu z tego narzedzia (SQP-I2Cscan.dev).

Po tym wstępie przejdźmy do szczegółów programu :)

Projekt składa się z funkcji umieszczonych w trzech grupach plików:
- main.c / main.h - funkcje związane z uruchamianiem / kończeniem programu, sprawdzaniem parametrów wejściowych i wywołaniem głównych funkcji programu
- usbasp.c / usbasp.h - funkcje realizujące logikę działania programu związane z komunikacją z ATB-USBasp
- usb.c / usb.h - funkcje odpowiadające za komunikację po USB (korzystające z biblioteki libusb)


usbasp.c to główny trzon tego programu. Mamy w nim trzy podstawowe funkcje (o czwartej później ;) ):
1. Pierwsza funkcja setI2CBitrate(), służy do ustawiania prędkości na szynie I2C. W której na początku wypełniamy odpowiednio dane w strukturze TusbControlPacket, która wygląda następująco:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Oczywiście przypisujemy do pól w strukturze TusbControlPacket wartości zgodnie z informacjami podanymi w dokumentacji dla API ATB-USBasp, a następnie wywołujemy funkcję wysłania danych poprzez funkcje usb:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


2. Druga funkcja checkI2CDevice() sprawdza obecność urządzenia na szynie I2C o wskazanym adresie. Także tutaj należy wypełnić strukturę TusbControlPacket zgodnie z API ATB-USBasp i wywołać funkcję usbSendControlData(). Przy sprawdzaniu obecności urządzenia dostajemy odpowiedź w formie tekstu OK lub ERROR, dlatego po wysłaniu danych sprawdzamy jeszcze co dostaliśmy w odpowiedzi i zgodnie z tym zwracamy przy kończeniu funkcji odpowiednią wartość (ERROR / SUCCESS / DEVICE_NO_FOUND):
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


3. Trzecia funkcja scanI2C(), jest funkcją realizującą skanowanie na I2C urządzeń o kolejnych adresach (korzystając z wcześniej opisanej funkcji checkI2CDevice()). Skanowanie wykonywane jest to w pętli dla kolejnych adresów od adresu początkowego I2C_7BIT_ADDRESS_MIN do adresu I2C_7BIT_ADDRESS_MAX (obie wartości zdefiniowane są w pliku usbasp.h).
We wszystkich bibliotekach i poradnikach Mirka, także w API ATB-USBasp stosowany jest adres w notacji 8 bitowej (wartość łącznie z bitem R/W na najmłodszej pozycji), dlatego przy skanowaniu nie wysyłamy kolejnych wartości, tylko z przeskokiem co dwa.
Ale ja, na przekór :twisted:, lubię stosować notację 7-bitową, i taką używam w programie. Dlatego wartości zakresów adresów do skanowania zdefiniowane w stałych są 7 bitowe (I2C_7BIT_ADDRESS_MIN / I2C_7BIT_ADDRESS_MAX) a wartość wysyłana poprzez API jest przesunięta o jeden bit w lewo:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Zgodnie ze specyfikacją I2C, nie wszystkie adresy przeznaczone są dla normalnych urządzeń. Dlatego nie skanujemy całego zakresu a tylko jego część. Początek i koniec jest zdefiniowany we wspominanych wcześniej stałych I2C_7BIT_ADDRESS_MIN (najmniejszy adres) oraz I2C_7BIT_ADDRESS_MAX (największy adres).
Gdy wywoływana funkcja checkI2CDevice() zwróci nam SUCCESS, co jest wynikiem odpowiedzi OK przez API ATB-USBasp, oznacza to że zostało wykryte urządzenie o tym adresie. Wypisujemy wtedy na ekranie informacje o tym adresie w postaci szesnastkowej oraz dziesiętnej zarówno w notacji 7-bitowej jak i 8-bitowej.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



W pliku usb.c mamy funkcje związane z komunikacją po USB. A dokładnie to są to tylko 3 funkcje:
1. otwarcie urządzenia funkcją openUSB(), gdzie następuje otwarcie urządzenia korzystając z wartości VID i PID zdefiniowanych dla USBasp:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


2. wysłanie danych kanałem kontrolnym usbSendControlData(), gdzie następuje fizyczne wysłanie danych poprzez wywołanie funkcji libusb_control_transfer() z biblioteki libusb z odpowiednimi otrzymanymi jako argumenty danymi:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

3. fukncji której nie mogło zabraknąć, czyli zamknięcie naszego urządzenia:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Ostatnim plikiem z kodem programu jest plik main.c. Funkcja main() zasadniczo (bo o pewnych dodatkach za chwilę) ma proste działanie:
- wykonać otwarcie urządzenia ATB-USBasp, używając wcześniej wspominanej funkcji openUSB()
- sprawdzić czy podany został parametr przy wywołaniu a jak tak i jest prawidłową wartością, to ustawić zgodnie z nim prędkość na szynie I2C, korzystając z wcześniej opisanej funkcji setI2CBitrate()
- wywołać skanowanie szyny I2C poprzez także wcześniej opisywaną funkcję scanI2C()
- zamknąć połączenie z urządzeniem USB poprzez funkcję closeUSB()

I to cała logika skanowania I2C :D. Prawda, że proste?

To teraz jeszcze napiszę o dwóch elementach znajdujących się w kodzie, która mogą przeglądającym lekko go zaciemniać:

1. Jako, że program ma działać poprawnie po skompilowaniu zarówno pod Windows jak i Linux, zostały dodane pewne elementy wymagane w systemie Linux.
W Windows naciśnięcie CTRL-C zabija automatycznie program. W Linux zdefiniowane są sygnały jakie wysyłane są do programu. Dlatego dodane zostało przechwytywanie sygnału SIGINT i SIGTERM
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Otrzymanie tych sygnałów powoduje, oprócz wypisania komunikatów, ustawienie zmiennej globalnej receivedTermSignal. Zmienna ta jest sprawdzana w pętali skanowania i jej ustawienie powoduje przerwanie skanowania.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



2. Drugim elementem jest dodatek w kodzie zmieniający całkowicie jego działanie. Jest to część, która wcześniej została specjalnie ominięta w opisie zawartych w plikach funkcji.
Jeżeli przeglądaliście kod to w funkcji main() zauważyliście, że wywołanie sprawdzanie parametru wejściowego i skanowanie I2C zawarte jest w dyrektywie:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

To właśnie ten dodatek, który możemy włączyć poprzez zdefiniowanie wartości TOGGLE_I2C_PINS powoduje wyłączenie skanowania a włączenie w czasie kompilacji wywołania funkcji toggleI2CPins():
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Co więc robi ta funkcja?
Zamiast programu skanującego szynę I2C dostajemy program zmieniającymi cyklicznie wartości na wyjściach dedykowanych dla I2C: SDA i SCL - po podłączeniu diod mamy cykliczne ich miganie.
Funkcja na początku przełącza tryb ATB-USBasp w tzw. tryb bit bang a potem w pętli ustawia i kasuje odpowiednio wyjścia SDA i SCL aż do momentu przerwania tego przez nas (klawiszem CTRL-C):
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Aby wywołać kompilację programu w wersji SQP-TogglePins musimy zdefiniować wartość TOGGLE_I2C_PINS, co możemy zrobić na jeden z trzech sposobów:
- w kodzie poprzez dodanie #define TOGGLE_I2C_PINS
- w pliku Makefile poprzez dodanie -DTOGGLE_I2C_PINS
- odpowiednio w środowisku w zmiennych kompilacji, dla Dev-C++ wygląda to tak:
Obrazek

Dzięki parametrowi -D w Makefile możemy zrobić kompilację od razu obu wersji programu, jak to się dzieje przy użyciu załączonego Makefile.

I to byłoby na tyle. Jak macie pytania i niejasności, to piszcie. Jak nie, to także piszcie, ale swoje kody i testujcie działanie ATB-USBasp >= 4.2 :).

--
Pozdrawiam,
Robert



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 lip 2018, o 17:04 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27315
Lokalizacja: Szczecin
Pomógł: 1041

Panie - panie! takie "kwiatki" to się wrzuca do DIY ;) bo to fajna inspiracja dla innych

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 lip 2018, o 17:05 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 mar 2014
Posty: 1475
Pomógł: 167

mirekk36 napisał(a):
Panie - panie! takie "kwiatki" to się wrzuca do DIY ;) bo to fajna inspiracja dla innych
Jakie DIY, to tylko seria odpowiednio ułożonych bitów ;).

--
Pozdrawiam,
Robert



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 lip 2018, o 21:01 
Offline
Użytkownik

Dołączył(a): 25 lip 2013
Posty: 2587
Pomógł: 128

Świetna robota Robert! Dziękuję!



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 lip 2018, o 11:22 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 mar 2014
Posty: 1475
Pomógł: 167

kalani napisał(a):
Do kompletu brakuje tylko skanowania General Call.
Tylko zwrócona przez to informacja nic nie wnosi w kwestii rozpoznawania urządzeń. A i tak skanujemy wszystkie adresy, więc dowiemy się czy są urządzenia i w dodatku jakie :).
Ale jak kto chce, to co za problem dodać jako osobną funkcję lub przed pętlą skanująca adresy? :D

--
Pozdrawiam,
Robert



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 5 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 0 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
cron
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO