
Witajcie, dzisiaj przedstawię jak okiełznać kolejny chiński mikrokontroler WiFi+Bluetooth, a dokładniej W800-C400 od WinnerMicro. Na ten moment można go kupić za około 10 zł, z kolei płytkę startową z nim już za 25 zł i obie te ceny uwzględniają już przesyłkę. Oczywiście nie będę tu korzystać z takiej płytki, tylko kontynuując moją tradycję użyję urządzenia IoT/Tuya właśnie zbudowanego na W800-C400, a konkretniej kontrolera paska LED RGB.
Same układy od WinnerMicro były już kilka razy wspominane w sekcji "Newsy" naszego forum, możecie zapoznać się też z tymi tematami:
Płyta HLK-W801 z mikrokontrolerem oparty na rdzeniu Alibaba Xuantie XT804
Air602 - Moduł z Wi-Fi na SoC Winner Micro W600
W806 - płytka prototypowa z WinnerMicro W806 za 8 zł
UWAGA - temat zakłada podstawową znajomość C i zasadniczo skupia się na samym uruchomieniu W800-C400, bez tłumaczenia podstaw. Dodatkowo też oczekuję, że użytkownik umie w miarę sam poszukać sobie w kodzie lub w internecie jak np. na tej platformie utworzyć wątek i tak dalej...
Użyty kontroler paska LED RGB
Na początek polecam zapoznać się z poprzednim tematem z serii:
Pasek LED WiFi/IR - WX300P - tryb muzyczny - ukryte przyciski [W800-C400]
Dla przypomnienia, fotki płytki:





Co jeszcze będzie potrzebne?
Jak kupujemy normalną płytkę startową to tego nie trzeba (gdyż jest na pokładzie płytki), ale że ja będę programować go "na dziko", to muszę mieć jeszcze zewnętrzny konwerter USB na UART. Zasadniczo tak jak w ESP i wszystkich podobnych mikrokontrolerach...

Oto niezbędne podłączenia:
- RX konwertera do TX PCB
- TX konwertera do RX PCB
- masa do masy
- zasilanie 5V z USB na wejście zasilania płytki (nie na 3.3V, bo to płytkę spali. Na płytce jest przetwornica step down, to na jej wejście daję 5V)
- dodatkowo na tym konwerterze UART USB daję zworkę między VDD a 3.3V by wybrać poziomy logiczne 3.3V
- [opcjonalnie] możemy też przylutować kabelek do padu RESET z płytki i resetować płytkę poprzez dotknięcie nim do masy, to wykona reboot, ale można też resetować po prostu przez odłączenie zasilania...
Tak to wygląda w praktyce:




Przypomnę - 5V biorę bezpośrednio z USB, a nie z pinu "5V" na tym dongle, gdyż pin 5V tam służy do wyboru poziomów logicznych i nigdy nie chciał mi rzetelnie działać jako źródło zasilania.
Repozytorium SDK z Githuba
SDK W800 dostępne jest za darmo w sieci. Wystarczy je pobrać. Użyłem SDK dostępnego pod adresem:
https://github.com/List-View/wm_sdk_w800
Tam też jest program do wgrywania wsadu - skompilowany, wm_tool.exe.
Do pobrania repozytorium użyłem wizualnej nakładki na GIT - SourceTree.
IDE i kompilator W800-C400
Oprócz SDK trzeba pobrać osobno kompilator i środowisko do programowania.
Wszystko mamy gotowe w postaci jednego instalatora na Windowsa. IDE stanowi po prostu nakładkę na Eclipse, które może być znany już Wam z innych mikrokontrolerów bądź chociażby z pisania aplikacji w Javie.
IDE to tzw. CDS i pobrać je można stąd:
https://occ.t-head.cn/community/download
Wymaga to rejestracji!
Pobrany przeze mnie plik nazywał się: cds-windows-mingw-elf_tools-V5.2.11-20220512-2012.zip
Po instalacji powinnyśmy uzyskać ścieżkę tego typu:
W:\C-Sky\CDS
Zawartość folderów:

Otwieramy folder IDEs:

cds-wb-win32.exe uruchamia nasze środowisko do programowania.
Dla formalności, użyta przeze mnie wersja CDS to:

Quote:
C-Sky Development Suite for CK-CPU C/C++ Developers (V5.2.11 B20220512)
csky-elf-tools Version: gcc version 6.3.0 (T-HEAD C-SKY Tools V3.10.29 Minilibc abiv1 B20210423)
csky-elfabiv2-tools Version: gcc version 6.3.0 (T-HEAD C-SKY Tools V3.10.29 Minilibc abiv2 B20210423)
riscv64-unknown-elf-tools Version: gcc version 10.2.0 (Xuantie-900 elf newlib gcc Toolchain V2.4.0 B-20220427)
cskysim Version: cskysim v3.8.15 (QEMU V6.1.0) B20220414
CPF Version: cpf version 3.4.4 B20220414
DebugServer Version: 5.14.03(Build: May 12 2022)
Copyright (c) 2010-2022 Hangzhou C-Sky Microsystems Co.,ltd. All rights reserved.
Visit https://occ.t-head.cn/
Pierwsza kompilacja w CDS
Mamy już otwarte IDE - teraz otwieramy projekt.
Project->Open Multi Project Workspace
Otwieramy plik projektu z pobranego SDK: W:\GIT\wm_sdk_w800\tools\w800\projects\SDK_Project\project\CDS
Projekt się zaimportuje i otrzymamy taki efekt:

W Project Explorer możemy już przeglądać pliki z kodem C:

Kompilujemy poprzez build:

Powinno pójść bez problemów:

Oto rezultaty:

Wgrywanie wsadu przez wm_tool.exe
wm_tool.exe jest w folderze tools z pobranego SDK.
Jest to rzecz jasna narzędzie linii komend.
To taki "esptool.py", można by powiedzieć, w dużym uproszczeniu, jak ktoś zna ESP.
Pozwala on m. in. wgrać wsad przez UART.
Oto jego help:

Aby wgrać wsad dajemy ścieżkę do pliku FLS oraz wybieramy nasz port COM (wirtualny):
wm_tool.exe -c COM9 -dl W:\GIT\wm_sdk_w800\bin\w800\w800.fls
Więc wykonujemy tę komendę i otrzymujemy:

Teraz trzeba wykonać reboot urządzenia - albo poprzez sygnał RESET, albo poprzez odcięcie i podłączenie zasilania.
Programuje się:

Nie ma co się martwić tym 0% widocznym przez cały czas programowania, po prostu program nie odświeża tego licznika.
Gotowe:
Struktura projektu demonstracyjnego
Przeanalizujmy po kolei co i gdzie się dzieje.
Oczywiście przed "main" nie wykraczamy, gdyż tu opisuję same podstawy.
main wywołuje CreateDemoTask:

CreateDemoTask jest w wm_demo_console_task.c:

To jest zasadniczo linia komend UART z której poziomu można odpalać demka.
W wm_demo_console_task.c też jest jej parsing, tokenizacja komend, i tak dalej.
Z kolei w wm_demo_console.h jest tablica wszystkich demek i ich komend:

Jest jeszcze plik konfiguracyjny - wm_demo.h.
I tu UWAGA - domyślnie demka są wyłączone, trzeba je włączyć zmieniając jedno OFF na ON:

Tu ma być DEMO_ON, domyślnie jest OFF. Bez tego konsola demek się nie uruchomi!
Trzeba też uruchomić osobno poszczególne dema, te które nas interesują:

Pora skompilować ponownie wsad i wgrać na W800.
Program demonstracyjny
Po wgraniu wsadu należy wykonać RESET (reboot), aby program zaczął działać.
Z urządzeniem komunikujemy się na baud 115200.
Na starcie otrzymujemy:

(no może poza komunikatem hello world, sam go dopisałem w main() dla testu)
Wyślijmy komendę "demohelp", jednakże bez CRLF (znaki nowej linii, cofnięcia karetki):

No cóż, to ten sam komunikat, ale działa.
Spróbujmy t-scan:

Działa!
Z ciekawości - kod demka jest w wm_scan_demo.c.
Oto najważniejszy fragment:
Code: c
Spróbujmy uruchomić demo utworzenia access point WiFi:

Czyżby problem? Tak, ale komunikat tego nie wyjaśnia.
Rzut oka na tabelkę demek pokazuje nam, że trzeba jeszcze podać argumenty:

Zajrzyjmy do odpowiedniego pliku, co to za argumenty są...

Trochę tego jest. Jeszcze trzeba przewinąć w dół by poznać dokładnie co musimy podać, co oznaczają kolejne wartości liczbowe np. parametru encrypt:
Code: c
Zostało wywołać komendę, ale to też nie jest takie proste.
Próbowałem tak:
t-softap MyTestWiFi Password123 25 0 0
Ale nie działało.
Rzut oka do parsingu komend wyjaśnił wszystko. Nawiasy i przecinki:
t-softap(MyTestWiFi,Password123,25,0,0)
Bardzo ciekawy format komendy, nie spotykam takiego często.

Działa:

GPIO, PWM, Flash i inne
Tu nawet nie ma co się rozpisywać, do wszystkiego są gotowe demka. Bardzo wygodne.
Przykładowo, wm_gpio_demo.c:
Code: c
Albo wm_flash_demo.c:
Code: c
Albo można też spojrzeć do innych SDK, chociażby dla portu pod Arduino, tutaj:
https://github.com/w600/arduino/blob/master/cores/w600/core_w600_wiring_pwm.c
(To jest dla W600 ale te platformy są w pewnym stopniu podobne)
Aktualizacja firmware przez WiFi
Ostatnią rzeczą jaką pokażę jest aktualizacja firmware przez WiFi, czyli tzw. OTA - Over The Air upgrade.
W tym przypadku klient OTA jest gotowy, jest to dokładniej klient HTTP, który pobiera plik z firmware z danego adresu URL.
Musimy mieć zatem jakiś serwer. Można by użyć chociażby pakietu Xampp z Apache, ale po co komplikować?
Wygodniejszą opcją jest Node-red, gdyż można go oskryptować tak, by serwował nam plik bezpośrednio z folderu z kompilacją poprzez wirtualną ścieżkę.
Samego Node-red nie będę tu opisywać, ale tak wyglądają moje nodes:

Node łapie żądanie GET a potem je przetwarza w węźle Function:

Wyciągam tu ze ścieżki nazwę pliku i pobieram go z dysku. Ważne jest, by węzeł ReadFile czytał go jako bufor binarny, a nie np. UTF8:

Po zmianach w Node-Red trzeba pamiętać, by kliknąć Deploy.
Od teraz, na mojej maszynie, chodzi serwer HTTP Node-red i po wejściu na adres:
http://192.168.0.118:1880/w800/w800_ota.img
zwraca mi dany plik z folderu z SDK.
Teraz pytanie co po stronie SDK... wystarczy jedna funkcja:
Code: c
System automatycznie pobierze aktualizację i uruchomi ponownie W800.
Gotowe!
Rady praktyczne
Samego programowania w C nie będę tu omawiać, ale jest kilka rzeczy o których warto wspomnieć. Przede wszystkim, SDK to opiera się o FreeRTOS, któremu w ich wersji brakuje kilku rzeczy - warto je samodzielnie skonfigurować.
- w FreeRTOSConfig.h polecam włączyć mutexy - #define configUSE_MUTEXES 1
- w FreeRTOSConfig.h polecam włączyć zarządzanie stertą, gdyż bez tego musimy sami dawać wskaźnik do sterty przy tworzeniu wątku - #define configUSE_HEAP2 1
- lepszy jednak byłby algorytm heap_4 (z defragmentacją) a nie obecny w SDK heap_2, ale ten z kolei nie jest dostępny... jeśli często alokujemy pamięć to warto byłoby przenieść SDK na nowsze FreeRTOS
- w FreeRTOSConfig.h polecam zwiększyć rozmiar buforu do alokacji sterty - #define configTOTAL_HEAP_SIZE ( ( size_t ) 48 * 1024 )
- w SDK jest biblioteka lwip2.0.3 (Lightweight TCP/IP stack), ale używane są z niej tylko podstawowe funkcjonalności takie jak sockety, DHCP. Jeśli chcemy użyć z niej np. klienta MQTT, to należy go osobno dodać do źródeł
- pamiętajmy, że jak mamy IDE (te CDS magiczne) to nie musimy edytować Makefile, wystarczy, że dodamy plik do projektu w CDS to on już jest zawarty w kompilacji
- MQTT z lwip 2.0.3 (czy tam 2.0.2) ma tą wspomnianą już przeze mnie kilka razy w innych tematach niedoróbkę, że nie uwzględnia hasła/nazwy użytkownika MQTT. Należy dopisać kilka brakujących linijek bądź skopiować poprawioną wersję ode mnie:
https://raw.githubusercontent.com/openshwprojects/OpenBK7231T/2c3af1f719cb5d52f3a9442bc0ec4439cac1d389/platforms/bk7231t/bk7231t_os/beken378/func/lwip_intf/lwip-2.0.2/src/apps/mqtt/mqtt.c
- konfiguracja kompilacji WinnerMicro jest w wm_config.h
Port W800 dla OpenBeken
Oczywiście mój firmware (zamiennik Tasmoty/Esphome) dla innych platform WiFi spotykanych w urządzeniach IoT już został przeportowany pod W800. Nie było z tym dużo problemów. Na ten moment prezentuje się tak:

Działa tez konfigurator pinów, MQTT:

No i OTA:

Port mojego firmware na tą platformę jest w tej chwili w pełni funkcjonalny
Podsumowanie
Kolejny mikrokontroler WiFi/Bluetooth uruchomiony - i tym razem wcale nie było tak ciężko. Co prawda nie znam żadnego rzetelnego angielskojęzycznego źródła na jego temat, ale i tak w SDK nie mieli aż takiego bałaganu by nie dało się tego uruchomić. Nawet udało się ogarnąć aktualizację wsadu przez WiFi, a to już jest coś.
Spodobało mi się to, że nie było kłopotów z kompilatorem i toolchainem, wszystko gotowe było w jednej instalce, razem z IDE.
Pokrewny W600 posiada też swój port dla Arduino, dostępny tutaj:
https://github.com/w600/arduino
ale tego jeszcze nie testowałem i nie wiem również na ile W600 się różni od W800. Nie mniej jednak, planuję również dodać wsparcie W600 do mojego firmware, wszystko w swoim czasie.
To na razie tyle, a teraz zapytam, czy ktoś bawił się już platformami W600 lub W800? Sam chyba nie zamierzam w nie dalej brnąć, opracowałem W800 tylko w takim stopniu, by móc sparować mój pasek LED WX300P z Home Assistant, ale kto wie...
Dołączam kilka ciekawych materiałów na temat W800/W600, w tym spakowane repo wraz z flasherem (wm_tool.exe) w zip, jak również materiały od producenta, których tu nie opisywałem, w tym nieco nowsze SDK (2021 12 03)
Cool? Ranking DIY