USB PD w STM32 (2). UCPD i eksperymenty z STM32G071B-DISCO

Udostępnij

Z punktu widzenia konstruktora możliwość negocjacji parametrów zasilania portu USB-C PD oznacza ścisłą współpracę układu zasilania z oprogramowaniem: zmiana napięcia wymaga wymiany komunikatów, sprawdzenia warunków i potwierdzenia gotowości źródła. Podczas uruchamiania urządzenia niezbędna okazuje się możliwość obserwowania całej tej sekwencji, a także aktywnego testowania poszczególnych komend. Zadania te można zrealizować z użyciem zestawu STM32G071B-DISCO.

Zanim jednak przejdziemy do opisu praktycznych eksperymentów z zestawem STM32G071B-DISCO, przyjrzyjmy się bliżej temu, w jaki sposób została zaimplementowana funkcjonalność Power Delivery w mikrokontrolerach STM32. Jako przykład posłuży nam układ STM32G071 zastosowany w opisywanym urządzeniu.

Implementacja kontrolera UCPD w STM32G071

Mikrokontroler STM32G071 zawiera – co ciekawe – aż dwie instancje interfejsu UCPD. Każda integruje analogową warstwę fizyczną, układy obsługi połączenia Type-C oraz dwa cyfrowe tory: nadawczy i odbiorczy. W części analogowej znajdują się wewnętrzne terminacje Rp/Rd, detektory poziomów napięcia na liniach CC1 i CC2 oraz obwody współpracujące z sygnalizacją dead battery. Wybór aktywnej linii CC wiąże komunikację z wykrytą orientacją połączenia – przypomnijmy, że wymiana danych odbywa się zawsze tylko na jednej z dwóch linii CC, podczas gdy druga może zostać użyta np. do zasilania wewnętrznej elektroniki przewodu USB Type-C.

Poniżej przedstawiono schemat blokowy interfejsu UCPD obecnego w wybranych układach z rodziny STM32G0.

Schemat blokowy bloku UCPD w mikrokontrolerach z serii STM32G0 (źródło: STMicroelectronics, RM0444)

Nadajnik dołącza preambułę, sekwencję początku pakietu i zakończenie, oblicza CRC oraz realizuje kodowanie 4b5b i BMC. Z kolei odbiornik odzyskuje sygnał taktowania, rozpoznaje sekwencje specjalne, dekoduje dane i sprawdza CRC odebranych pakietów. Wewnętrzny interfejs cyfrowy współpracuje z kolei z przerwaniami i kontrolerem DMA. Osobne obwody obsługują zdarzenia Type-C, sygnalizację FRS (Fast Role Swap) oraz wybudzanie z trybu Stop.

Schemat blokowy nadajnika UCPD (źródło: STMicroelectronics, RM0444)
Schemat blokowy odbiornika UCPD (źródło: STMicroelectronics, RM0444)

Biblioteka LL i stos USBPD

Oryginalny projekt oprogramowania fabrycznie wgranego do pamięci mikrokontrolera w zestawie STM32G071B-DISCO jest publicznie dostępny i stanowi doskonały, choć dość rozbudowany punkt wyjścia do własnej implementacji obsługi UCPD. Całość można znaleźć w oficjalnym repozytorium STMicroelectronics na GitHubie:

Projects/STM32G071B-DISCO/Demonstrations/USBPD_Analyzer

Co ciekawe, choć projekt stanowi część środowiska STM32CubeG0, to bezpośrednia obsługa UCPD jest udostępniona przez warstwę LL, a nie – jak w przypadku większości peryferiów sprzętowych STM32 – przez warstwę abstrakcji sprzętowej (HAL). Pliki stm32g0xx_ll_ucpd.h i stm32g0xx_ll_ucpd.c zawierają m.in. tak podstawowe funkcje jak:

  • LL_UCPD_Init() – inicjalizacja interfejsu na podstawie struktury konfiguracyjnej,
  • LL_UCPD_Enable() – uruchomienie bloku UCPD,
  • LL_UCPD_SetSNKRole() – ustawienie roli układu jako odbiornika energii (Sink),
  • LL_UCPD_SetCCPin() – wybór używanej linii CC za pomocą makra LL_UCPD_CCPIN_CC1 lub LL_UCPD_CCPIN_CC2,
  • LL_UCPD_RxEnable() – włączenie odbiornika UCPD.

Nad warstwą sprzętową pracują: PRL (Protocol Layer), PE (Policy Engine) i funkcje wykrywania połączenia CAD (CAble Detection). Decyzje aplikacyjne należą natomiast do DPM (Device Policy Manager): to tutaj oceniane są możliwości źródła, wybierane parametry żądania i obsługiwane powiadomienia. Z dość oczywistych przyczyn realizacja zadań związanych ze sprzętową obsługą przepływu energii w torze zasilania (pomiarem napięcia, sterowaniem elementami wykonawczymi, etc.) musi być samodzielnie zrealizowana przez konstruktora.

W funkcji StartDefaultTask(), znajdującej się w pliku main.c, można prześledzić wywołania USBPD_DPM_InitCore(), GUI_Init(), USBPD_DPM_UserInit() oraz USBPD_DPM_InitOS(). Aplikacja demonstracyjna korzysta z systemu FreeRTOS. Główne ustawienia i definicje zachowania portu znajdują się natomiast w plikach usbpd_dpm_conf.h, usbpd_pdo_defs.h, usbpd_dpm_user.c i usbpd_pwr_if.c.

W tej konkretnej aplikacji żądanie nowego profilu realizuje funkcja USBPD_DPM_RequestMessageRequest(). Jeżeli odebrany drugi obiekt PDO opisuje stałe napięcie 9 V, a ustawienia odbiornika dopuszczają użycie tego profilu, wywołanie ma postać:

/* port 0, pozycja PDO liczona od 1, napięcie w mV. */
USBPD_StatusTypeDef status;
status = USBPD_DPM_RequestMessageRequest(0U, 2U, 9000U);

Funkcja sprawdza dopasowanie profilu, buduje obiekt żądania (RDO) i przekazuje go do funkcji USBPD_PE_Send_Request(). Zakończenie negocjacji jest następnie zgłaszane przez stos. Opisane wywołanie dobrze pokazuje poziom abstrakcji, na którym pracuje aplikacja użytkownika: wybiera konkretne warunki zasilania, podczas gdy niższe warstwy zajmują się prowadzeniem całej transmisji i sekwencją protokołu.

Budowa zestawu STM32G071B-DISCO

Zestaw bazuje na układzie STM32G071 (z końcówką RBT6) i jest wyposażony w niewielki wyświetlacz OLED 128 × 64 px, joystick oraz wbudowany programator ST-LINK/V2-1 z osobnym złączem micro USB. Przewód zakończony wtykiem USB-C i gniazdo USB-C umożliwiają włączenie urządzenia pomiędzy źródło i odbiornik.

Zestaw STM32G071B-DISCO (fot. HardwareDesigner.pl)

Gniazdo osłania przesuwana klapka z magnesem, której pozycję wykrywa niewielki kontaktron. W ten sposób urządzenie może automatycznie przełączać się pomiędzy dwoma trybami pracy:

  • Klapka zamknięta: tryb Standalone Sink – zestaw pracuje jako samodzielny odbiornik prowadzący negocjacje ze źródłem poprzez interfejs UCPD mikrokontrolera STM32G071.
  • Klapka otwarta: tryb Spy – zestaw jest „przezroczysty” dla komunikacji na liniach CC i rejestruje transmisję pomiędzy dwoma zewnętrznymi urządzeniami USB-C.
Gniazdo USB-C widoczne po odsłonięciu blokady mechanicznej (fot. HardwareDesigner.pl)

Trzy układy monitorujące INA230 służą do pomiaru napięcia i prądu na linii VBUS oraz napięć na liniach CC1 i CC2. Komunikacja z komputerem przebiega przez interfejs UART i korzysta z wirtualnego portu szeregowego udostępnianego przez wbudowany interfejs ST-LINK. Zasilanie zestawu może być dostarczane zarówno przez złącze micro USB, jak i linię VBUS portu USB-C. Wewnętrzna przetwornica DC/DC wytwarza napięcie potrzebne do zasilania elektroniki zestawu. Jej zakres wejściowy wynosi 3…20 V, o czym trzeba pamiętać podczas eksperymentów – próba wymuszenia wyższego napięcia mogłaby się zakończyć uszkodzeniem zestawu. Dlatego też testy warto ograniczyć do trybu SPR (maksymalnie 20 V), nawet jeżeli zewnętrzne źródło energii jest w stanie udostępnić wyższe napięcie.

Schemat blokowy zestawu ewaluacyjnego STM32G071B-DISCO (źródło: STMicroelectronics, UM2546)

W trybie Standalone Sink pracuje pełny stos USBPD, dzięki czemu zarówno z poziomu komputera, jak i wbudowanego interfejsu użytkownika (joystick i wyświetlacz OLED) można wydawać polecenia, np. resetu czy wyboru trybu zasilania. W trybie nasłuchu (Spy) aplikacja dekoduje „podsłuchane” pakiety, ale nie korzysta z nadajnika UCPD.

Odbiornik energii i zmiana napięcia

Do tego oraz kolejnego ćwiczenia potrzebne będą:

  • zestaw STM32G071B-DISCO,
  • przewód micro-USB z transmisją danych,
  • zasilacz lub power bank z portem USB-C PD oferujący przynajmniej dwa profile zasilania (np. 5 V i 9 V),
  • przewód USB-C – USB-C,
  • dodatkowy odbiornik USB-C PD – w tej roli może wystąpić np. smartfon.

Zalecana kolejność przygotowania stanowiska w przypadku, gdy zestaw STM32G071B-DISCO ma wgrane oryginalne (fabryczne) oprogramowanie, jest następująca:

  1. Zainstaluj aplikację STM32CubeMonitor-UCPD oraz STM32CubeProgrammer. W systemie Windows może być potrzebny sterownik ST-LINK STSW-LINK009; instalator linuksowy monitora wymaga natomiast środowiska Java.
  2. Połącz port micro-USB zestawu z komputerem. To połączenie będzie wykorzystywane w obydwu ćwiczeniach i powinno być aktywne cały czas, aby rejestrator działał także podczas odłączania badanego zasilania. Jeżeli klapka gniazda USB-C jest otwarta, zamknij ją.
  3. Uruchom aplikację CubeMonitor-UCPD. W Board Selection odśwież listę przyciskiem Refresh list of connected boards i wybierz zestaw STM32G071B-DISCO, a następnie kliknij Next.

Następnie wybierz używany przez niego port w sekcji Port Selection i ponownie kliknij Next.

Po nawiązaniu połączenia z płytką otworzy się zakładka Port Communication.

Przy zamkniętej klapce podłącz wtyk USB-C zestawu do zasilacza. W zakładce Port Communication odczytaj zawartość pola Distant Capabilities. W sekcji SRC PDO zanotuj pozycję profilu 9 V – na powyższym zrzucie ekranu jest to SRC 2. Liczba i parametry poszczególnych pozycji wynikają rzecz jasna z oferty konkretnego źródła zasilania. W sekcji Measurement ustaw okres odświeżania wykresu (np. 200 ms) i naciśnij Start, co spowoduje uruchomienie wykresu napięcia i prądu mierzonych na linii VBUS.

Następnie w panelu Message Selector odszukaj komendę Request Power Profile. Ustaw RDOPosition według odczytanej listy (w naszym przykładzie jest to pozycja 2) i RequestedVoltage na wartość 9000 mV, po czym kliknij przycisk Send message to connected Port. Spowoduje to przestawienie wartości napięcia zasilania, co zostanie zasygnalizowane zarówno na wykresie w sekcji Measurement, jak i w odczytach na ekranie zestawu DISCO.

Zauważ, że w rejestrze komunikacji po prawej stronie okna pojawiają się zdekodowanie komunikaty przesyłane po linii CC. Odszukaj w logu zapisy Request, Accept i PS_RDY, a wynik zestaw ze wskazaniem VBUS.

Przyjrzyj się wartościom wszystkich pól. Postaraj się samodzielnie rozszyfrować jak najwięcej z nich. Dla potwierdzenia wykonaj zadanie jeszcze raz, tym razem zmieniając profil np. na 5 V. Zapisy uzyskane w naszym przypadku możesz zobaczyć na poniższych zrzutach ekranu.

Eksperymentowanie przy użyciu zestawu STM32G071B-DISCO w trybie Standalone Sink niesie ze sobą sporą wartość poznawczą, pozwala bowiem poznać realny przebieg komunikacji w dość ściśle kontrolowanych warunkach. Prawdziwą przydatność zestawu ewaluacyjnego można jednak odczuć dopiero podczas korzystania z niego w roli „sniffera” do nasłuchu komunikacji pomiędzy dowolnym źródłem i dowolnym odbiornikiem USB-C PD.

Nasłuch komunikacji na linii CC w trybie Spy

Tym razem odłącz źródło zasilania USB-C i otwórz klapkę, pozostawiając cały czas podłączone zasilanie micro-USB. Wtyk zestawu połącz ze źródłem energii (np. power bankiem lub kompatybilną z PD ładowarką z gniazdem USB-C).

Uwaga! W trybie Spy nie da się połączyć z zestawem, korzystając z opisanego wcześniej trybu wyboru płytki i portu. W celu nawiązania połączenia z zestawem trzeba rozwinąć listę Select Tracer Port i wybrać interesujący nas wirtualny port szeregowy.

Poprawne połączenie z zestawem ewaluacyjnym spowoduje przełączenie w tryb śledzenia. Jeżeli do gniazda USB-C, odsłoniętego po przesunięciu klapki, nie jest jeszcze podłączony żaden odbiornik, okno loga powinno być puste.

Na poniższym zrzucie ekranu pokazano fragment negocjacji pomiędzy power bankiem a smartfonem. Tutaj także warto dokładnie przeanalizować zawartość poszczególnych pól, aby lepiej zrozumieć przebieg komunikacji. Zawartość okna można kopiować do schowka lub zapisywać do plików na potrzeby późniejszej analizy offline.

Podsumowanie

Z pozoru prosta komunikacja USB-C Power Delivery, choć odbywa się z relatywnie niewielką szybkością bitową i to tylko za pośrednictwem pojedynczej linii CC, w rzeczywistości jest bardzo rozbudowanym standardem zapewniającym współczesnym systemom wbudowanym pełną elastyczność w zakresie negocjacji parametrów zasilania. Obecność bloku UCPD w niektórych modelach mikrokontrolerów STM32 (w tym STM32G071) oraz gotowy, certyfikowany stos i komplet bibliotek znakomicie upraszczają implementację PD we własnych projektach, ale wciąż nie czynią tego zadania banalnym – błędy mogą wkraść się praktycznie na każdym etapie projektu. Dlatego też próby wykonywane z użyciem zestawu STM32G071B-DISCO w trybach Sink oraz Spy pozwalają prześledzić zależności między poleceniami aplikacji, wymianą pakietów i zmianami realnego napięcia na linii VBUS. Przy przenoszeniu rozwiązania do własnego projektu warto rozpocząć od jednej roli energetycznej i niewielkiej liczby profili, a następnie powiązać powiadomienia DPM z obsługą zasilania urządzenia. Warto przy tym skorzystać z udostępnianych przez firmę STMicroelectronics przykładów – w tym opisanego w niniejszym artykule projektu USBPD_Analyzer.

Bibliografia

  1. STMicroelectronics, RM0444 Rev. 6
  2. STMicroelectronics, stm32g071xx.h
  3. STMicroelectronics, stm32g0xx_ll_ucpd.h, stm32g0xx_ll_ucpd.c
  4. STMicroelectronics, UM2552 Rev. 2
  5. STMicroelectronics, projekt USBPD_Analyzer, STM32CubeG0
  6. STMicroelectronics, usbpd_dpm_user.c, USBPD_Analyzer
  7. STMicroelectronics, STM32G071B-DISCO
  8. STMicroelectronics, UM2401 Rev. 1
  9. STMicroelectronics, UM2546 Rev. 2
  10. STMicroelectronics, STM32CubeMonUCPD
  11. STMicroelectronics, UM2468 Rev. 5
  12. STMicroelectronics, ST Wiki: Introduction to USB Power Delivery with STM32

Sponsorem artykułu jest firma Masters

Masters jest Oficjalnym Dystrybutorem STMicroelectronics w Polsce, Czechach, Słowacji, Ukrainie i Mołdawii. Współpracujemy nieprzerwanie od 2003 roku. Dowiedz się więcej o produktach, usługach i warsztatach, które wspólnie tworzymy na www.masters.com.pl

Przemysław
Przemysław
Redaktor Naczelny portalu HardwareDesigner.pl. Konstruktor elektronik i programista embedded z ponad 20-letnim doświadczeniem w projektowaniu PCB. Z wykształcenia elektronik medyczny i elektroradiolog, specjalizuje się w projektowaniu i badaniach aparatury medycznej, laboratoryjnej i pomiarowej.

Czytaj więcej

Wybrane dla Ciebie