logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED

p.kaczmarek2 25 Lip 2023 14:50 3729 2
REKLAMA
MediaMarkt Black Week
  • Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Dzisiaj będziemy rozpracowywać zupełnie nieznany protokół I2C kontrolera LED RGBCW poprzez przechwytywanie i analizę jego pakietów. Użyjemy do tego analizatora stanów logicznych Sigrok, oczywiście zapewniając całemu układowi odpowiednią separację galwaniczną gdyż analizowane urządzenie pracuje na napięciu sieciowym. Potem wykorzystamy zebrane informacje do zaimplementowania własnego sterownika tych LEDów w języku C, w naszym firmware. Cały proces postaram się pokazać krok po kroku, a zabawa będzie o tyle ciekawe, że odszyfrowywany przez nas protokół rzeczywiście nie jest publicznie udokumentowany.

    Temat powstał przy współpracy z kolegą @DeDaMrAz . Część sprzętową wykonywał kolega. Ja zająłem się dowodzeniem, analizą i częścią implementacyjną.

    Tytułowa animacja przedstawia omawianą lampkę w trakcie testów; na jednym z monitorów widać przechwytywanie komunikacji I2C na żywo.

    Plan działania
    Na początek wypada zrobić jakiś plan kroków, które podejmiemy w tym temacie. Oto one, to jest to, co mniej więcej musimy zrobić by zaimplementować wsparcie nieznanego kontrolera LED bez posiadania jego dokumentacji:
    - wstępna analiza wnętrza urządzenia (schemat, podłączenia)
    - analiza wsadu z modułu WiFi (jesteśmy w stanie wyciągnąć z niego konfiguracje Tuya w JSON, tam mogą być jakieś informacje)
    - przygotowanie stanowiska do przechwycenia pakietów analizatorem logicznym (zapewnienie izolacji galwanicznej między lampą a PC)
    - wykonanie przechwycenia pakietów w trakcie określonych operacji na aplikacji mobilnej od lampki (osobno ustawianie barw, sciemnianianie od 100% do 0%, podjaśnienie od 0% do 100%, wyłączenie, itd)
    - analiza pakietów (ile bajtów przypada na pakiet, jaki jest jego format, co oznacza dany bajt, czy jest jakaś suma kontrolna)
    - implementacja w C wysyłania pakietów zgodnie ze standardem
    - (opcjonalne) werfikacja wysyłania pakietów jeszcze na Windowsie, "na sucho", bez urządzenia, po prostu zapis bajtów do pliku
    - finalne testy naszej implementacji sterownika na fizycznym urządzeniu (po wgraniu naszego kodu na moduł WiFi)
    - ewentualne poprawki
    Postaram się ten cały proces opisać w tym temacie.


    Pacjent z tematu
    Temat dotyczy tzw. lampki "smart", czyli sterowanej przez WiFi, poprzez aplikację mobilną. My staramy się opracowywać własne, alternatywne oprogramowanie dla takich urządzeń, w pełni open source, by móc uwalniać je od chmury i od serwerów producenta. Z tego powodu wzięła się cała potrzeba analizowania protokołu.
    Analizowana lampka LED była przedstawiona przez naszego użytkownika tutaj:
    https://www.elektroda.com/rtvforum/topic3985037.html
    swpharis napisał:

    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED

    Lampka opiera się na module WiFi CB2L, na którego można wgrać OpenBeken:
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Spoiler:

    Pin numberSymbolI/O typeFunction
    1P8I/OSupport hardware PWM
    2P7I/OSupport hardware PWM
    3P6I/OSupport hardware PWM
    4P26I/OSupport hardware PWM
    5P24I/OSupport hardware PWM
    6GNDPPower supply reference ground
    73V3PPower supply 3V3


    Jak sama nazwa wskazuje, jest to moduł przeznaczony dla oświetlenia (Lighting), i ma wyprowadzone same piny PWM, ale czy one są tu używane? Zobaczymy...
    Zaczęliśmy od zgrania wsadu modułu WiFi:
    swpharis napisał:

    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED

    Wsad, a dokładniej konfiguracja JSON z Tuya, już sugerowała, że kontroler LED nie jest znany:
    Kod: JSON
    Zaloguj się, aby zobaczyć kod

    Wsad oczywiście zgraliśmy i odkodowaliśmy moim narzędziem:
    https://github.com/openshwprojects/BK7231GUIFlashTool
    Te klucze to pewnie namiary na GPIO I2C:
    Kod: JSON
    Zaloguj się, aby zobaczyć kod

    Klucze poniżej to indeksy kanałów RGBCW (nie zawsze są po kolei):
    Kod: JSON
    Zaloguj się, aby zobaczyć kod

    Z kolei klucze poniżej to ustawiania prądu dla różnych trybów prac kontrolera, jak również jakieś inne niezbyt znane mi parametry:
    Kod: JSON
    Zaloguj się, aby zobaczyć kod

    W środku zdaje się być jakiś układ KP58.
    Tak też jest w rzeczywistości:
    swpharis napisał:
    It’s a KP18058esp.
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED

    Obecność tylko dwóch linii komunikacji przy jednoczesnej wiedzy, że lampka to RGBCW (aż pięć kanałów) już sugeruje, że tu nie ma sterowania poprzez PWM, lecz użyty jest I2C bądź zbliżony protokół.
    swpharis napisał:

    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED

    KP18058, udało mi się znaleźć szczątkową dokumentację tego układu. Tu mamy przykładowo cały poglądowy schemat takiej lampki:
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    AC/DC to tutaj nieizolowana przetwornica step down. "Tajemniczy" bloczek to moduł WiFI.

    Abyśmy mogli dowiedzieć się więcej, kolega z Serbii zamówił tą samą lampkę którą miał użytkownik i wziął ją na warsztat.

    Nieco lepszy schemat
    Po przybyciu paczki na początek postanowiliśmy naszkicować jak to wygląda w praktyce:
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Zasadniczo wszystko jest tak jak pisałem. Jedynie warto zwrócić uwagę, że to jest produkt na 120V, a mimo to kondensatory na wejściu są na 400V. Natomiast ten kondensator od LEDów jest na 200V, hmm...
    Ale to już poza tematem i nie ma większego znaczenia to, że ta lampa jest 120V - po prostu musieliśmy ją zasilić przez transformator 230V/120V.

    Stanowisko pracy i przechwytywanie danych
    Jak już zapewne widzieliście na ogólnym schemacie urządzenia, ta lampa nie posiada żadnej izolacji galwanicznej. Moduł WiFi zasila mała nieizolowana przetwornica step down a sam kontroler LEDów jest zasilany bezpośrednio z sieci.
    Dodatkowym problem tutaj jest to, że produkt z tematu pracuje na 120V a u kolegi jest 230V... więc zaczęliśmy od transformatora obniżającego napięcie:
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    To już zapewnia izolację, ale w ruch też poszły izolatory od Analog Devices, ADuM1201:
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Trzeba przecież jakoś podłączyć Sigroka.
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Bardzo tanie są, raptem jakieś 2$ (wliczająć przesyłkę):
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Podłączenie:
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    A dopiero za nimi podłączony został analizator Sigrok:
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED

    Analiza danych w Pulseview
    Znajomy wykonał różne operacje na lampce (przez aplikację mobilną) i zebrał wysyłane wtedy pakiety. Otrzymałem od niego pliki SR z danymi z linii SCL i SDA:
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Pliki SR można otworzyć darmowym PulseView:
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Po otwarciu mamy tylko sam widok cyfrowy danych, który można powiększać:
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    PulseView nie wie, że to I2C. Trzeba dodać odpowiedni dekoder:
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Potem trzeba się wklikać w jego ustawienia i wybrać która linia to SCL, a która to SDA:
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Wtedy zobaczymy wartości bajtów:
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    No i tu jest pierwsza mała niedogodność - okazuje się, że zasadniczo nie jest to protokół I2C, gdyż tu nie ma na początku bajtu adresu, a dokładniej 7 bitów adresu z bitem R lub W, określającym czy wykonujemy odczyt czy zapis...
    Analizator się tego spodziewa i dopisuje nam "DR", że niby Data Read, ale to nie jest prawda.
    Tu wszystko wysyła moduł WiFi, układ KP tylko odbiera.

    Dla wygody można wyłączyc wyświetlanie rzekomego adresu urządzenia z przesunięciem (bo bit R/W jest najmłodszy) w ustawianiach przechwytywania:
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Przejrzałem te pakiety i określiłem, że jest tylko jeden typ pakietu, który zawsze ma długość 14 bajtów. Kilka przykładów:
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Potem w programie graficznym przyrównałem sobie pakiety od poszczególnych kolorów, tak aby określić które bajty za nie odpowiadają:
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Wygląda na to, że są dwa bajty na kolor. Przy 5 kolorach (RGBCW), to jest 10 bajtów. Zostają 4 bajty, gdzie dwa to chyba limity prądów trybu RGB i CW (ale tylko zgaduję) a pierwszy może być komendą lub trybem pracy.

    Dodatkowo zobaczyłem, że pierwszy bajt się zmienia w zależności od tego czy światło jest włączone. Wygląda na to, że jak lampa jest zapalona to jest to 0xE1 (ale nie zawsze?), a jak zgaszona to 0x81.

    Natomiast sama analiza tych dwóch bajtów kolorów wstępnie pokazuje, że ich wartości zmieniają się od 0x00 do 0x3F, co sugeruje, że tylko 6 młodszych bitów z bajtu jest używane. Wartości zapalają się kolejno, co sugeruje, że wartość jednego koloru to 12 bitów. Czyżbyśmy mieli tu rozdzielczość aż wspierającą 4096 różnych wartości na kanał? SM2135 ma tylko 256 wartości na kanał, a SM2235 tylko 1024...


    Wstępna implementacja
    Ostatecznie w C napisałem coś takiego:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Jak już wspominałem, nie jest to jednak protokół I2C, gdyż nie uwzględnia adresu ich urządzenia, z tego powodu musiałem sztucznie wsadzić pierwszy bajt jako pozorny adres do funkcji Soft_I2C_Start. Oprócz tego chyba kod powinien być jasny, w pętli wybieram wartości z koloru RGBCW (ledRemap pozwala zmienić kolejność kolorów, bo producenci nie mają jednego standardu), mapuję je z typu float na unsigned short (od 0 do 4095 włącznie), a potem rozdzielam je poprzez bitowe AND (&) oraz przesunięcie (>>). Wkładam pierwsze 6 bitów do pierwszego bajtu, a drugie 6 bitów do drugiego.

    Próba "na sucho", na Windowsie
    Moje środowisko można też uruchomić na Windowsie, mam nawet wbudowany do tego symulator urządzenia IoT:
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Pozwala mi to potestować wygodnie trochę rzeczy i wyeliminować proste błędy przed wrzucaniem wsadu na urządzenie.
    Postanowiłem, dla weryfikacji, napisać prostą pętle for która wypisze utworzone bajty do pliku, reprezentujące proces ściemniania koloru od 0 do 255.0 (dość niefortunnie te 255 wygląda, bo początkowo miałem kolory jako bajty, bo SM2135 wspiera tylko 8-bitowe wartości, ale potem pojawił się SM2235 z 10-bitowymi kolorami i zmieniłem typ na float a zakres 0-255 został):
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    I sama obsługa jednego pakietu:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Oto rezultat - wygląda poprawnie?
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED



    Zmiana wsadu modułu WiFi
    W tym momencie uznałem, że mamy wystarczająco danych, by zakończyć przechwytywanie i zmienić wsad na module WiFi na OpenBeken. Potem będzie łatwo aktualizować oprogramowanie zdalnie przez OTA. Tylko raz trzeba wgrać go przewodowo. Moduł został wylutowany:
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Potem trafił na stanowisko szpilkowe - standardowo podłączamy się do RX, TX, 3.3V i GND:
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Wszystko wedle instrukcji mojego Flashera:
    https://github.com/openshwprojects/BK7231GUIFlashTool
    W trakcie programowania:
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED

    A miało być tak pięknie...
    Ostatecznie odpaliliśmy mój kod na urządzeniu i otrzymaliśmy taki rezultat:



    Swoją drogą, na tym filmie poniżej widać przechwytywanie pakietów I2C na żywo (na jednym z monitorów):



    Niby ściemnianie działa, ale co chwila lampa się wyłącza - co jest nie tak?
    Odpowiedź w spoilerze. Spróbujcie najpierw sami rozwiązać zagadkę.
    Spoiler:

    Po krótkiej analizie zebranych pakietów okazało się, że to wcale nie jest 6 bitów na bajt, nie jest to również 12 bitów na kolor. Niektóre kombinacje bitów są pominięte. Teraz tylko pytanie z jakiego powodu...
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Po porównaniu wielu pakietów, można zobaczyć, najmłodszy bit jest zawsze jedynką gdy suma pozostałych bitów jest nieparzysta, w przeciwieństwie jest zerem.
    Jest to tzw. bit parzystości (parity bit).
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Można powiedzieć, że to taka najprostsza, jednobitowa, suma kontrolna.
    Ten bit pozwala wykryć błędy przesyłania i musi być poprawnie ustawiony przy wysyłaniu.
    Poprawiłem kod, tak by go liczyć:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    I wszystko pięknie ruszyło.



    Podsumowanie
    Miało to trwać jeden wieczór, ale trwało dwa - wszystko przez ten problem opisany w ostatnim akapicie. Nie spodziewałem się tego, żaden z podobnych sterowników (SM2135, SM2235, BP1658CJ czy nawet BP5758D) nie posiada takiego mechanizmu. Mimo wszystko - udało się. Wygląda na to, że jako pierwsi mamy wsparcie KP18058, oczywiście nie licząc producentów urządzeń.
    Co do samego protokołu - znowu jednak odbiega on od standardu poprzez brak wsparcia adresacji urządzeń, ale pewnie dla producentów nie jest to problem. Oprócz tego przypomina trochę SM2235, czyli mamy 10 bitów na kanał. To troszkę lepiej niż SM2135, który ma tylko 8 bitów na kanał i może to być odczuwalne dla niektórych użytkowników.
    Zostało nam jeszcze określić jak dokładnie są ustawiane limity prądu. Wszystkie podobne sterowniki pozwalają ustawić limity pradu, osobno dla RGB i osobno dla CW. To pewnie są te dwa bajty, które zawsze miały tę samą wartość. Limit prądu na danym urządzeniu się nie zmienia. Chyba będziemy musieli zgadywać i eksperymentować. A może po prostu pojawi się za jakiś czas nota katalogowa tego układu i problem się rozwiąże...
    Podsumowując, w ten oto sposób mamy kolejne urządzenie uwolnione od chmury a kolejny nasz użytkownik jest zadowolony.

    Fajne? Ranking DIY
    Pomogłem? Kup mi kawę.
    O autorze
    p.kaczmarek2
    Moderator Smart Home
    Offline 
  • REKLAMA
    MediaMarkt Black Week
  • #2 20699441
    p.kaczmarek2
    Moderator Smart Home
    Ktoś z Githuba niedawno dołożył swoją cegiełkę do tego sterownika:
    https://github.com/openshwprojects/OpenBK7231T_App/pull/906/files
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Inżynieria wsteczna nieznanego protokołu I2C z analizatorem Sigrok na przykładzie kontrolera LED
    Nie analizowałem tych zmian jeszcze, ale umieszczam je tu informacyjnie.
    Pomogłem? Kup mi kawę.
  • #3 20971009
    p.kaczmarek2
    Moderator Smart Home
    W ramach aktualizacji mogę dodać, że omawiany sterownik KP18058 z OpenBeken został też przetestowany z KP18068 (z lampki Spectrum Smart E27 1500 lm 13W WOJ14473) i też działa. Wygląda na to, że KP18068 i KP18058 mają ten sam protokół komunikacji.
    Pomogłem? Kup mi kawę.
REKLAMA