Pokażę tu pierwsze próby i prosty "Hello world" dla procesora ALI M3801 na przykładzie starego tunera Comsat TE 1050 HD w oparciu o projekt ali_sdk z GitHub. Następnie spróbuję dopisać do niego nową funkcjonalność - obsługę GPIO. Pokazany tu projekt nie jest pełnym SDK Linuxowym, lecz wręcz przeciwnie - stanowi zbudowane od zera minimalistyczne demko do którego dopiero trzeba dodać większość funkcji.
Organizacja środowiska pracy
Zacząć trzeba od metody programowania. Korzystam z CH341, klips się u mnie nie sprawdził - nie widzi pamięci. Po stronie komputera odpalam NeoProgrammer.
ALI M3801 oparty jest o architekturę MIPS. Firmware kompiluję na Ubuntu, zgodnie z readme od autora demka (michal4132):
Próbowałem te demo skompilować pod Cygwin i WSL - bezskutecznie. Jedynie na Ubuntu się udało. Dodatkowo i tak toolchain musiałem kompilować przez crosstool-NG - trochę to zajęło, przy samym GCC mieliło ponad pół godziny.
Hello World od autora
Prezentowane repozytorium zawiera proste Hello World oferujące wyświetlanie informacji na UART oraz minimalistyczny system linii komend:
Kod: C / C++
Program u mnie poprawnie się uruchamia, lecz nie odbiera danych z RealTerm:
Na razie ten problem zostawię, ale później do niego wrócę.
Obsługa GPIO - przyciski
Obsługę GPIO dodałem samodzielnie, przedstawię tutaj metodykę działania. Po prostu szukałem po rejestrach - w projekcie jest już użyty rejestr UART - 0xb8018300 - wyszukiwanie po nim na GitHubie prowadzi do interesujących projektów. Nie są one kompletne, ale można podejrzeć inne rejestry:
https://github.com/search?q=0xb8018300&type=code
W ten sposób trafiłem na pliki m36_gpio.h i m36_gpio.c:
https://github.com/qttest1/PDK_GoBian/blob/a3...rs/aliminirpc/inc/asm/mach-ali/m36_gpio.h#L53
Widać tu, jak zorganizowane są piny na platformie M36XX - na M3801 może być podobnie.
Najpierw mamy czterobajtowe słowa dla każdego z portów.
Kod: C / C++
Potem mamy mechanizm doboru rejestru dla indeksu pinu - indeksy są bezwzględne, od 0. Przykładowo, do włączenia GPIO:
Kod: C / C++
Z daleka widać, że pinów jest dość dużo. Potwierdza to stała GPIO_PORT_MAX:
Kod: C / C++
Przeniosłem te funkcje do prezentowanego programu i udało się zrobić prosty skaner pinów. 8 pinów jest pakowanych do jednego bajtu, a wyniki są wyświetlane na ekranie w pętli.
Kod: C / C++
Odczyt GPIO działa - widać reakcje na przyciski:
Odczyt chip id (identyfikatora układu)
Przejrzałem inne SDK i zobaczyłem ciekawy fragment odczytujący ID układu. Wszystko tu działa podobnie jak w przypadku pinów - jest do tego specjalny adres.
Kod: C / C++
Co dziwne, zwrócona wartość nie jest przekazywana dalej bezpośrednio, tylko jest tłumaczona na inne stałe.
Kod: C / C++
Dla siebie przygotowałem bez tłumaczenia na stałe:
Kod: C / C++
Rezultat:
Mam ALI M3801 a otrzymałem 0x3811, ale może to jakaś wewnętrzna rewizja układu.
Lepszy skan przycisków
Chciałem też ulepszyć skan GPIO tak, by wyświetlał co się zmieniło. Na początek użyłem następującego kodu:
Kod: C / C++
To nie ruszyło - otrzymuję tylko "Booting... M" na UART i cisza. Być może tablica nie zmieściła się na stosie.
Zoptymalizowałem więc kod tak, aby jeden pin to był jeden bit:
Kod: C / C++
Bingo - widać już na których pinach są przyciski od programów. Co ciekawe, główny przycisk on/off nie jest widziany:
Kontynuacja testów z UART
Zupełny brak komunikacji UART na linii komputer -> urządzenie nie dawał mi spokoju. Zacząłem od weryfikacji pinów, czy aby rzeczywiście dobrze określiłem, gdzie jest RX mikroprocesora.
Wszystko się zgadza. Mamy kolejno: TX, RX, 5 V i masa. Próbowałem usuwać też rezystory pull up (widać je na zdjęciu pod pinami RX/TX), ale bezskutecznie.
Ostatecznie zainteresowała mnie sama konfiguracja UART. Przecież ustawiony jest w niej bit parzystości - tryb even. Dość nietypowy ustawienie. Spróbowałem je wyłączyć:
Od razu jest o wiele lepiej, ale wciąż są problemy:
Przejrzałem informacje w sieci o CH341 którego używam i dochodzę do wniosków, że:
- CH341 nie obsługuje poprawnie bitów parzystości
- a dokładniej, dane z bitem even nie są wysyłane poprawnie (odbiornik je odrzuca - zła parzystość lub jej brak?)
- ale co ciekawe, gdy urządzenie wysyła do CH341 dane z tym bitem, to CH341 mimo to je poprawnie odbiera, więc poniekąd wprowadza mnie w błąd wywołując wrażenie, że wszystko jest ok...
Chyba będę musiał sprawdzić to analizatorem logicznym. Nie mam nawet innych konwerterów USB na UART by porównać.
Dalsze plany
Ten UART nie działa zbyt stabilnie a dodatkowo odbieranie jest rozwiązane w sposób blokujący dla procesora, a zbyt wolne odpytywanie powoduje gubienie znaków. Koniecznie trzeba uruchomić to w oparciu o przerwania, tylko jak? W sieci informacje są szczątkowe, nie ma pełnej dokumentacji jakie rejestry ustawić.
Spróbuję wyszukać o tym ile się da informacji, i potencjalnie będę testować - trzeba dodać ISR (funkcję do obsługi przerwania) i sprawdzać, czy się wywołuje. Może zwiększać w niej zmienną volatile i w głównej pętli wykrywać zmianę. Do tego dodać prostą obsługę menu, skoro moje przyciski już działają, i mieć różne funkcje ustawiające rejestry, by móc szybko testować różne opcje.
Materiały do dalszej analizy i wyszukiwań
Adres rejestrów UART - 0xb8018300 i 0xb8001600:
https://github.com/search?q=0xb8018300+&type=code
https://github.com/search?q=0xb8001600+&type=code
Adres bazowy ALI_SOC_BASE - 0xb8000000:
https://github.com/search?q=ALI_SOC_BASE+&type=code
https://github.com/search?q=0xb8000000+&type=code
Inne typy układów (mojego 0x3811 tu nie ma):
Kod: C / C++
Przerwania?
https://github.com/zhe2lucifer/linux-kernel-z...s/modules/aliarch/mips/ali/m36/m36_irq.c#L327
https://github.com/zhe2lucifer/linux-kernel-z...b/6.8.3.2-dev/arch/mips/kernel/irq_cpu.c#L101
Podsumowanie
Znaleziony projekt jest obiecujący, ale wymaga koniecznie implementacji przerwań dla UART a potem prostego bootloadera. Może to być dość trudne przez brak dokumentacji w tym temacie, ale spróbuję z tym ruszyć i wkrótce przedstawię rezultaty.
Podjąłem też próby z symulacją rdzenia Mips w oparciu o biblioteki z Pythona - potrafię już wykonywać w ten sposób assembler, ale nie symuluje to nic oprócz instrukcji, więc to raczej tylko ciekawostka. Przedstawię to w osobnym temacie.
Czy ktoś z Was ma ten lub podobny układ Ali i byłby chętny spróbować swoich sił z jego programowaniem? Wszelka pomoc mile widziana, na bieżąco próbuję z tym ruszyć dalej i szukam podobnych tunerów.
Fajne? Ranking DIY Pomogłem? Kup mi kawę.