Po zakończeniu fazy wstępnej, w kolejnych odcinkach przystąpimy do omówienia istotnych składników układów PSoC, przy czym nacisk kładziony będzie na możliwie szerokie, a nie głębokie, omówienie zagadnienia. W trzeciej, ostatniej fazie cyklu priorytety ulegną odwróceniu i wówczas skupimy się na szczegółach wybranych, bardziej zaawansowanych tematów.
Taki rozkład materiału umożliwi Czytelnikom szybkie podjęcie samodzielnego poznawania tajników rodziny PSoC. Nieco wbrew tytułowi (PLD), sporo uwagi zostanie też poświęcone analogowej części układów 5LP, bo od ścisłego trzymania się formuły ważniejsze jest dla mnie dostarczenie Czytelnikom potężnej platformy do własnych eksperymentów. Cała siła naszych układów tkwi bowiem w rzadko spotykanej możliwości elastycznego łączenia bloków cyfrowych z analogowymi, tj. w rozwiązaniach hybrydowych.
Ze względu na duże możliwości i niską cenę zestawu ewaluacyjnego nasze eksperymenty będziemy prowadzić na wspomnianej w marcowym artykule płytce CY8CKIT-059 (fotografia 1). Jeżeli ktoś jednak woli posługiwać się pięciokrotnie droższym zestawem FreeSoC2 (fotografia 2) i jego stosownie większymi możliwościami, to zapewniam, że nada się on do naszych celów równie dobrze. Oba zestawy zawierają taki sam procesor CY8C5888; ten na droższej płytce udostępnia jedynie więcej pinów IO, a kit umożliwia pracę wielonapięciową.
Poza tym zakładam, że Czytelnik dysponuje podstawową wiedzą w zakresie układów cyfrowych oraz programowania w języku C. PSoC5LP zawiera procesor, którym jest pojedynczy 32-bitowy rdzeń ARM Cortex M3, stąd nieodłącznym elementem każdego projektu będzie jego zaprogramowanie. Naszym celem nie jest jednak powielanie cyklu o Arduino, a poznanie tego, co odróżnia układy hybrydowe od typowego mikrokontrolera. Stąd sam ARM rzadko będzie kluczowym elementem omawianych konstrukcji. Dlatego wystarczy zupełnie podstawowa znajomość języka C, w sporej części nawet na poziomie biernym, tj. czytania ze zrozumieniem treści gotowych, krótkich programów.
Platforma sprzętowa - konstrukcja układów PSoC
Konstrukcja sprzętowa układów PSoC (rysunek 3) jest bardzo ciekawa w porównaniu z typowymi, być może znanymi już Czytelnikowi mikrokontrolerami. Uwagę zwraca nie tylko duża liczba dostępnych peryferii (w tym analogowych), lecz przede wszystkim konsekwentna architektura, która wznosi koncepcję programowalności na zupełnie nowy poziom.
Nieco zaskakujące może być pozorne ubóstwo cyfrowych składowych mikrokontrolera: interfejsów komunikacyjnych, timerów i innych specjalizowanych bloków. Inne układy chwalą się np. trzema interfejsami SPI i dwoma I2C, a tymczasem PSoC5LP sprzętowy blok I2C ma tylko jeden, a SPI nie ma wcale.
Wyjaśnienie jest proste: to nie PSoC jest ubogi, lecz jedynie zasoby te nie zostały przez konstruktorów uznane za byty podstawowe i do ich zbudowania należy wykorzystać bardziej fundamentalne bloki. Bloki te nazywają się UDB (Universal Digital Block) i składają się z ośmiu jednobitowych programowalnych funkcji logicznych (PLD), bardzo prostego 8-bitowego procesora (Datapath), dwóch jednokierunkowych kolejek FIFO, 8-bitowego rejestru sterującego (tylko do zapisu z punktu widzenia głównego procesora) i rejestru stanu (tylko do odczytu).
Układ na naszej płytce zawiera 24 identyczne kopie bloku UDB. W rozumieniu najprostszym daje nam to wspomniane w marcu 24*8=192 programowalne, w pełni sprzętowe funkcje logiczne. Już to samo w sobie pozwala na wiele, ale dopiero wykorzystanie bloków Datapath umożliwia na pełne wykorzystanie możliwości układu. Wymaga ono jednak dobrego opanowania podstawowych możliwości bloków PLD, więc do samodzielnego programowania Datapath wrócimy dopiero w późniejszych odcinkach.
Słowo „samodzielnego” wyróżniłem nie bez przyczyny. Choć elementy elektroniczne co do jednego składają się z atomów, to rzadko jest to poziom abstrakcji, którym posługujemy się, myśląc o nich. Dokładnie tak samo jest tutaj: UDB nie jest poziomem, który należy mieć nieustannie przed oczami, bo w większości przypadków jest on szczelnie obudowany w bloczek, który spełnia jakąś konkretną, „namacalną” funkcję. Bloczek ten nazywamy komponentem.
Kiedyś nauczymy się samodzielnie wytwarzać komponenty, ale na początek wystarczą nam gotowe, dostępne w bibliotece instalowanej z pakietem PSoC Creator. Zawiera ona zarówno komponenty elementarne, jak np. bramka OR, jak i bardzo złożone funkcjonalności, np. wspomniany interfejs SPI czy zaawansowany timer. Wystarczy wybrać taki komponent z dostępnej palety i umieścić w swoim projekcie, bo za wskazanie zasobów niskopoziomowych i ich odpowiednie połączenie zadbał autor komponentu.
Podejście takie ma w mojej ocenie głęboki sens, bo w odróżnieniu od typowych mikrokontrolerów PSoC nie musi marnować miejsca na sprzętowe bloki, które tylko potencjalnie i raczej rzadko mogą zostać w pełni wykorzystane, np. 6 interfejsów SPI. A jeśli my akurat potrzebujemy 7, za to UART-ów nie potrzebujemy wcale? Chciałoby się mieć możliwość łatwego przesunięcia niepotrzebnych zasobów do realizacji pożądanych przez nas funkcji i właśnie taką możliwość rodzina PSoC daje.
Układ zawiera też bardzo rozbudowany, wielokanałowy kontroler DMA, więc wymiana danych pomiędzy wszystkimi powyższymi blokami może odbywać się bez interwencji głównego procesora. Oprócz możliwości znanych ze zwykłych mikrokontrolerów wyposażonych w DMA, każdy kanał przyjmuje też i wytwarza pewne sygnały sprzętowe (np. informacja o zakończeniu transmisji), których można dowolnie używać, m.in na poziomie logiki programowalnej lub wyprowadzać na piny układu. Przydaje się to bardzo podczas debugowania, bo do pinu można podłączyć oscyloskop i sprawdzać za jego pomocą poprawność zakładanej sekwencji zdarzeń.
Ponadto w naszym chipie mamy blok DFB (Digital Filter Block), który jest niezależnym (aż do poziomu własnej pamięci kodu i dwuportowej pamięci danych) procesorem VLIW wyspecjalizowanym w cyfrowym przetwarzaniu sygnałów. Tak jak poprzednio, można korzystać z niego zarówno poprzez gotowe komponenty, jak i programować samodzielnie. Niestety jego konstrukcja jest zoptymalizowana pod kątem niskiego poboru energii, co znajduje swoje odbicie w architekturze: ręczne programowanie tego bloku jest wyjątkowo trudne. Za to efekty bywają spektakularne.
Ostatnim, choć kluczowym składnikiem cyfrowej części układów PSoC jest programowalna sieć połączeń elektrycznych DSI (Digital Signal Interconnect). Bloki logiki programowalnej, DMA, DFB, piny oraz pozostałe elementy układu wytwarzają na swoich wyjściach i przyjmują na wejścia sygnały niosące pożądane informacje. Ale jak te bloki ze sobą powiązać i sprawić, by potrzebne sygnały płynęły między nimi bez udziału procesora, i to płynęły wydajnie?
Właśnie za pomocą „przewodów” DSI.
Ciekawą implikacją istnienia DSI jest rozdzielenie funkcji bloku cyfrowego od sposobu jego komunikacji ze światem zewnętrznym. W zwykłych mikrokontrolerach zdarza się to stosunkowo rzadko; tam włączenie określonej funkcji (np. UART-u) wymusza pojawienie się jej sygnałów na wskazanych w dokumentacji pinach (lub, w niektórych luksusowych przypadkach, na pinach alternatywnych).
W PSoC bloki funkcjonalne (z wyjątkiem interfejsu USB) nie mają kontaktu ze światem zewnętrznym, a piny są niezależnymi bytami i nic nie wiedzą o funkcjach. Oba te światy spina właśnie DSI, co w praktyce oznacza, że trzeba samodzielnie narysować połączenia między wybranym pinem a wybranym wejściem/wyjściem bloku funkcjonalnego. Syntezator zrobi resztę. A skoro role poszczególnych dostępnych na obudowie pinów można określić samodzielnie, to Czytelnik z łatwością domyśli się, jak bardzo upraszcza to proces projektowania płytki drukowanej.
Można zacząć domyślać się już, że koordynacja działań składowych układu jest niezwykle elastyczna. Istotnie, możemy zrobić to metodą „klasyczną” (zachodzi zdarzenie, zgłaszane jest przerwanie, procesor je obsługuje i uaktywnia następny element w sekwencji), automatycznie w oparciu na DMA (zachodzi zdarzenie, uaktywnia kanał DMA, a on zapisuje, co trzeba, gdzie trzeba), a także czysto sprzętowo, w oparciu na UDB i DSI. I nie musi to być wybór wyłączny, w zależności od potrzeb powyższe składniki możemy mieszać w dowolnych odpowiadających nam proporcjach.
Na zakończenie tego wprowadzenia dodam, że procesor na obu płytkach prototypowych może być taktowany częstotliwością do 80MHz, a logika programowalna do 67MHz, więc w porównaniu do popularnych mikrokontrolerów 8-bitowych dostępnej mocy obliczeniowej jest sporo.
Różne serie produktów PSoC - omówienie
Warto też krótko omówić istniejące serie produktów PSoC, bo jest to bardzo pomocne przy wyborze odpowiedniego układu oraz przy wyszukiwaniu przykładów kodu źródłowego. Skoro interesujący nas układ należy do rodziny PSoC5LP, to zapewne istnieją też członkowie rodziny oznaczeni innymi numerami. Tak jest istotnie, protoplastą tej architektury jest seria PSoC1, która dziś ma znaczenie wyłącznie historyczne. PSoC5 (bez liter LP!) z kolei należy uznać za nieudany debiut z powodu liczby błędów i ograniczeń występujących w tej wersji krzemu, więc rozważając zakup procesora, trzeba zwrócić uwagę na wspomniany szczegół w oznaczeniu i unikać wersji bez sufiksu LP.
Z kolei seria PSoC3 to pod względem peryferii niemal dokładnie to samo, co PSoC5LP, ale zamiast rdzenia ARM układ jest wyposażony w znacznie mniej wydajny, 8-bitowy procesor zgodny z prehistorycznym MCS51. Ponieważ różnica w cenie jest pomijalna, oczywiste jest, że będziemy chcieli użyć wersji z ARM-em i serię 3 również potraktujemy jako konstrukcję historyczną.
Z jedną ważną różnicą: uderzające podobieństwo konstrukcyjne serii 3 i 5LP powoduje, że zdecydowana większość dostępnych w Internecie przykładów i gotowych konstrukcji na PSoC3 da się wprost lub z niewielkimi tylko modyfikacjami wykorzystać na PSoC5LP. Dlatego jeśli nie wiemy, jak zrobić coś na układzie z serii 5LP, ale znaleźliśmy przykład, jak zrealizować PSoC3, to sprawa jest załatwiona. Podkreślam to, bo zdarzyło mi się kilkukrotnie korzystać z tego faktu w praktyce.
Jeśli zaś chodzi o serię PSoC4, to – wbrew pozorom – nie jest ona formą pośrednią pomiędzy seriami 3 i 5LP, lecz zupełnie oddzielną rodziną, przeznaczoną do zastosowań niskobudżetowych. Jest ona wyposażona w rdzeń ARM Cortex M0 i ma znacznie mniej pamięci oraz innych zasobów niż układy z serii 3 i 5LP.
Wiele układów z tej rodziny nie ma nawet jednego bloku logiki programowalnej UDB, więc z punktu widzenia naszych obecnych potrzeb nie jest ona atrakcyjna. Do jej zalet należy natomiast znacznie bogatszy zakres i przyjazność dostępnych obudów: PSoC5LP występuje jedynie w wariantach beznóżkowych QFN oraz stosunkowo dużych, za to możliwych do przylutowania w warunkach amatorskich obudowach TQFP.
Dla dopełnienia obrazu należy dodać, że niedawno pojawiła się seria PSoC6 (wyposażona w transceiver Bluetooth Low Energy). Seria PSoC7 jest dopiero projektowana i owiana tajemnicą, a PSoC2… nie istnieje. W dalszej części cyklu nasze zainteresowanie ograniczymy więc tylko do układów serii 5LP.
W następnym odcinku zainstalujemy pakiet PSoC Creator i nauczymy się tworzyć projekty. Rozpoczniemy też eksperymenty z prawdziwym układem, stąd niezbędny stanie się zakup wybranej przez siebie płytki. Jeżeli będzie to zestaw CY8CKIT-059, to przypominam, że wlutowanie goldpinów w przygotowane do tego celu złocone otwory na płytce dramatycznie ułatwi nam dalsze eksperymenty. Warto też zaopatrzyć się w przedłużacz USB.
W materiałach dodatkowych (dostępnych w Elportalu) umieściłem dokumentację zestawu CY8CKIT-059 oraz układów PSoC5LP.