Każdy, kto rozważa przesiadkę z ośmiobitowego mikrokontrolera na coś mocniejszego i o większych możliwościach naraża się na pewien problem, który łatwo przegapić, bo przy ośmiu bitach pojawia się sporadycznie. Ale pomnóżmy liczbę bitów przez dwa, cztery, albo i osiem, i zaczynają się schody. Problem ten to błędy w krzemie.
Kilka lat temu zaprojektowałem płytkę pod mikrokontrolery PIC24, dsPIC i PIC32 wykorzystując fakt, iż wiele modeli w obudowach TQFP-64 ma tę samą "pinologię". Projekt przeleżał w skrzynce, bo zwyczajnie nie byłem w stanie przylutować układu na swoje miejsce. Teraz projekt odkopałem i będę go kontynuował - w prototypie znajdzie się układ dsPIC33EP512GP506. Rzuciłem więc okiem do noty katalogowej, by sobie odświeżyć, co ten układ potrafi. A potem otworzyłem erratę...
To nie działa, tamto nie działa. To też nie działa. A o tym to szkoda nawet wspominać...
Czytanie errat, zwłaszcza co bardziej rozbudowanych mikrokontrolerów, pozwala nam doświadczyć uczucia rozczarowania i kompletnej daremności pracy. Szczególnie, gdy układ peryferyjny lub jego konkretna funkcjonalność, ze względu na które wybraliśmy dany układ nie działa prawidłowo, albo wcale, i nic nie da się z tym zrobić. Sytuacja staje się jeszcze gorsza, gdy dany układ peryferyjny ma więcej problemów. Wiele szesnastobitowych układów z serii dsPIC jest stworzonych z myślą o kontroli różnego rodzaju silników i przetwornic. Dlatego posiadają bardzo rozbudowane moduły PWM z wieloma użytecznymi funkcjami. Dlatego odradzam używania układów z serii dsPIC33EPXXXGP/MC20x/50x do takich zastosowań - problemy z PWM stanowią ponad 38% wszystkich problemów. Jeszcze gorzej się robi, gdy problemy dotyczą wszystkich mikrokontrolerów w danej rodzinie, we wszystkich wersjach krzemu. Jeśli do tego układ nie jest popularny, to nie należy spodziewać się poprawionej wersji w przyszłości.
Problemy przedstawione w erratach można podzielić na trzy kategorie:
1. Błędy nierozwiązywalne.
2. Błędy z rozwiązaniem programowym.
3. Błędy rzadkie, niespotykane lub nietypowe.
Omówię wszystkie rodzaje na przykładach z errat różnych mikrokontrolerów.
1. Błędy nierozwiązywalne.
Czyli problemy sprzętowe, których nie da się zwyczajnie rozwiązać w żaden sposób. Dla przykładu parametry AC/DC wbudowanego wzmacniacza operacyjnego i współpracującego z nim układu ADC mogą być inne, niż podane w nocie. W najgorszym razie oznacza to konieczność użycia zewnętrznego wzmacniacza operacyjnego - dla hobbysty to nie problem. W masowej produkcji jednak to dodatkowe koszty. Drugim, nierozwiązywalnym problemem może być sytuacja, gdy układ zasilany napięciem 3,3V ma piny tolerujące 5V, z wyjątkiem tych kilku, co jednak nie tolerują go, choć miały. Przykładowo dla dsPIC33EP512GP506 są to piny RC3, RC4, RC5 i RA9. Nie ma na to obejścia, więc lepiej ich nie "katować" wyższym napięciem.
Wspomniałem wcześniej o module PWM w rodzinie dsPIC33EPxxxGP/MC20x/50x. Jedną z teoretycznych funkcjonalności jest aktualizacja rejestru wypełnienia cykl po cyklu. Ale w jednym z trybów pracy aktualizacja nastepuje tylko co drugi cykl, i nie da się z tym nic zrobić. To drobiazg w porównaniu z wieloma innymi problemami tego modułu. Innym drobiazgiem jest to, iż aktualizacja rejestru fazy modułu zadziała z opóźnieniem dwóch cykli modułu. Chyba że użyjemy trybu natychmiastowej aktualizacji w trakcie bieżącego cyklu, a nie po jego zakończeniu. Trudno mi sobie wyobrazić sytuację, gdy ten drobiazg wpłynąłby negatywnie na realizowany projekt, chyba tylko gdy chcemy sterować serwomotorem sprzężonym z enkoderem kwadraturowym, do którego układ zapewnia osobny moduł peryferyjny. Moduł, który też nie działa.
Jednym z fajniejszych modułów w wielu PICach jest CTMU, czyli moduł mierzenia czasu ładowania kondensatora. Pozwala na precyzyjny pomiar pojemności i jej zmian czy na pomiar rezystancji, i na wiele więcej. W przypadku jednak wybranego przeze mnie dsPICa moduł nie działa z ADC ustawionym na konwersję dwunastobitową. Czasem też trafia się problem, do którego nie ma wyjaśnienia. Dla przykładu we wszystkich układach z rodziny dsPIC33EPXXX(GP/MC/MU)806/810/814 i PIC24EPXXX(GP/GU)810/814 moduł BOR (Brown Out Reset) musi być zawsze włączony. Dlaczego? Nie wiadomo. Co się stanie, jak się nie posłuchamy? Nie napisali. Boję się sprawdzić, by mi układ przypadkiem papieża nie wybrał. Ale żeby nie było, iż tylko szesnastobitowe układy mają problemy, to rzućmy okiem na inny mikrokontroler, który posiadam: PIC32MM0064GPL028. Ta rodzina ma relatywnie krótką erratę, bo tylko 18 problemów, z czego 9 udało się rozwiązać do rewizji B3, ale i tu są ciekawostki. Na przykład pinu MCRL nie można używać, by trzymać układ w stanie resetu celem zaoszczędzenia energii, bo pobiera wtedy więcej prądu, niż podaje specyfikacja. Obejścia brak. W układach w wersjach krzemu B1 i B2 moduł ADC też pobiera za dużo prądu, więc errata sugeruje wyłączać go, gdy nie jest potrzebny.
2. Błędy z rozwiązaniem programowym.
To największa grupa problemów wskazanych w erratach. Zależnie od rodzaju problemu rozwiązanie jest przedstawione w formie prostej porady, całej procedury opisanej w punktach albo procedury z przykładowym kodem źródłowym. Rozwiązania "jednozdaniowe" to na przykład porada, by problem CPU ze sprzętowym dzieleniem liczb ze znakiem (polecenie DIV SD) nie ustawiającym bitu przepełnienia w razie przepełnienia rozwiązać sprawdzając, czy mogłoby dojść do przepełnienia po dzieleniu. Implementację zostawiono jako ćwiczenie dla programisty. Biorąc pod uwagę, jak często operacja dzielenia ze znakiem przydaje się w funkcjach DSP to trochę upośledza istotną funkcjonalność ALU. Problem ten występuje w kilku rodzinach 16-bitowych PICów. W dsPICach serii 810 i pokrewnych moduł ECAN ma błąd nietypowy: jeden z bitów w jednym z rejestrów działa odwrotnie, niż powinien, więc rozwiązanie polega na zapamiętaniu tego faktu przy konfiguracji rejestru. Moduł ma też problem z generowaniem przerwania w razie ogólnego błędu łączności. Rozwiązanie to użycie przerwania "błędna wiadomość". Moduł USB, który sam z siebie zasługuje na całą serię artykułów, ma ciekawy problem, gdy układ działa jako host, a urządzenie low-speed jest podłączone do niego przez hub USB hi-speed. Rozwiązanie: nie używaj huba. Moduł ADC w rodzinie 20x/50x ma też ciekawy problem - bit DONE sygnalizujący koniec konwersji nie zmienia się, jeśli konwersja jest wyzwalana zewnętrznym przerwaniem. Rozwiązanie to albo sprawdzanie flagi ogólnego przerwania ADxIF, albo ustawienie tego przerwania jako aktywne. Moduł ma też problem gdy chcemy uzyskać prędkość 1,1Msps na wejściach AN0 i AN3 przy łączeniu kanałów CH0 i CH1 w programie. Rozwiązanie to fizyczne połączenie wskazanych pinów ze sobą - inaczej wyniki z CH1 nie będą prawidłowe. Czasem problemem jest sam dostęp do pamięci programu, i tak próby odczytu lub zapisu pamięci w obszarze adresów 0x001 do 0x200 prowadzi do wystąpienia błędu niespodziewanego adresu, jeśli w tle pojawi się jedno lub więcej przerwań. Trzeba zatem wyłączyć przerwania, gdy chcemy bezpośrednio wybrać adres w tym obszarze. Co ciekawe, to jeden z tych problemów, których możemy nawet nie zauważyć jeśli nie sprawdzimy, co kompilator robi, gdy konwertuje język wysokiego poziomu na assemblera, a potem na język maszynowy. Nie jestem tego pewien, ale wydaje mi się, że Microchip dostarcza programowych "łatek" do takich problemów dla poszczególnych rodzin układów. Trudno mi to potwierdzić, bo nie mam wielkiego doświadczenia w programowaniu rodzin 16-bitowych.
Wspominałem o problemach z PWM. Jednym z nich jest funkcjonalność "czasu martwego", bardzo przydatna przy budowaniu przetwornic. Oczywiście elektroniczne "stare wygi" będą pisać, że przetwornic na mikrokontrolerach się nie buduje, ale co tam oni wiedzą. Do brzegu, jak to moja żona mówi: "czas martwy" to odstęp między załączeniem jednego wyjścia, gdy drugie zostaje wyłączone w topologiach półmostkowych i pełnomostkowych, który to chroni przed przypadkowym jednoczesnym otwarciem górnego i dolnego tranzystora i wyborem papieża przez któryś z nich. Zatem to raczej porażka po stronie producenta, gdy przynajmniej dwa problemy wymagają całkowitego wyłączenia funkcji "czasu martwego" by moduł prawidłowo pracował.
We wspomnianej rodzinie 32-bitowych PICów moduł ADC jest bardzo rozbudowany, i jedną z jego funkcji jest sprzętowe formatowanie danych do formatów 16-bitowych ze znakiem i 32-bitowych ze znakiem. Teoretycznie, bo w praktyce oba są sformatowane tak samo, więc errata radzi zrobić konwersję w programie. Może to się przydać, jak kumulujemy wiele wyników celem oversamplingu.
Sporo problemów ma rozwiązania w formie nie tylko opisu, ale też wycinka kodu. Dla przykładu we wspomnianym już 32-bitowcu układ przełączania oscylatora na zewnętrzny ma wbudowany timer odliczający czas do uzyskania stabilnej częstotliwości, który to timer źle działa i sygnalizuje gotowość układu przed czasem. Przełączanie na zewnętrzny kwarc to rzecz, ktorą niemal zawsze robi się w pierwszej kolejności,. jeszcze przed konfiguracją innych peryferiów. Obejście przedstawione jako wycinek kodu zakłada użycie jednego z peryferiów, by to ono zażądało zmianę zegara na XT lub HS, a następnie ożycie wbudowanej funkcji by odczekać 9 milisekund zanim przełączy się układ zegarowy.
Ciekawy problem mają układy dsPIC33EPXXXGP/MC/MU806/810/814, jeśli użyje się w nich dwóch zagnieżdżonych instrukcji assemblerowych DO, nie będą pracować prawidłowa, gdy wewnetrzna pętla ma licznik równy 0. Obejście polega na dodaniu instrukcji NOP, jednej do pętli wewnętrznej, dwóch do zewnętrznej. Dokument zapewnia też kod xródłowy.
Cofnijmy się do rodziny dsPIC 20x/50x i beznadziejnie zabugowanego modułu PWM. Jednym z problemów w specyficznym trybie pracy jest ustawienie wypełnienia na 100%, ale tylko gdy wartosć w rejestrze PDCx jest mniejsza niż połowa wartości w rejestrze ALTDTRx. Dostajemy więc polecenie sprawdzanie tej wartości i aktualizowanie jej w miarę potrzeby, wraz z krótkim kawałkiem kodu.
3. Błędy rzadkie, niespotykane lub nietypowe.
To przypadki, gdzie czytając erratę trzeba się zatrzymać i zastanowić, w jaki sposób ktoś doszedł do tego problemu. Do tej kategorii zaliczyć też można problemy dyskwalifikujące jakiś moduł lub jego funkcję z użycia. Wróćmy do rodziny PIC32MM0064GPL036 i modułu ADC. W trybie 12-bitowym następujące odczytane wartości po prostu zwyczajnie nie występują:
• wariant B0: 1023, 2046, 2047, 3070 oraz 3071
• wariant B2: 1022, 1023, 2046, 2047, 3070 oraz 3071
Jak to możliwe, tego nie wiedzą nawet egipscy górale. Rozwiązanie to użyć trybu 10-bitowego. Co ciekawe, errata wskazuje też problemy z wariantem B3, ale dla niego nie ma podanych brakujących wartości.
Ten sam układ ma problem z jednym z bazowych modułów, BOR czyli Brown Out Reset. Układ ten ma za zadanie wstrzymać pracę mikrokontrolera, gdy napięcie jest za niskie by mógł prawidłowo pracować, i zresetować go po powrocie właściwego napięcia zasilania, sygnalizując przy tym przyczynę resetu. W naszym wypasionym 32-bitowcu ten układ zwyczajnie nie działa, i jedyne rekomendacje erraty to albo użyć zewnętrznego układu nadzorczego, albo nie dopuścić do spadku napięcia poniżej minimalnych, rekomendowanych wartości. To dziwne, bo moduł ten występuje we wszystkich układach PIC. To tak, jakby producent samochodów spalinowych wypuścił model bez rozrusznika i możliwości jego montażu, a potem umieścił w instrukcji, iż rekomenduje nigdy nie gasić silnika po odpaleniu, i odpalać go "na pych", trzymając "siłę napędową" w bagażniku.
Obie wspomniane rodziny 16-bitowe mają ten sam, specyficzny problem związany z dostępem do pamięci danych. Obie erraty zawierają dokładny opis warunków, które muszą się zdarzyć, by wystąpił problem polegający na błędnym wykonaniu kolejnych instrukcji. Zestaw warunków wygląda tak:
Pytanie za 10 punktów: jak często takie warunki mogą się pojawić? Jak rozpoznać taką sytuację, jeśli nie programujemy układu w assemblerze?
Na koniec prawdziwa "wiśniówka na torcie", czyli problem-widmo:
A może coś nowego?
Do tej pory oglądaliśmy erraty układów, które mają już kilka lat. A jak to wygląda w przypadku układów nowych? Weźmy na warsztat najnowszą rodzinę PICów z rdzeniem MIPS, PIC32MZ z FPU, MMU, DSP i paroma innymi skrótami. Układy posiadają nawet interfejsy szeregowy i równoległy do dołączania zewnętrznych pamięci - bajer. Osobiście wybrałbym PIC32MZ1024EFK064 w obudowie TQFP-64, jeśli by miał taką samą "pinologię", co układy 16-bitowe wspomniane wcześniej - mam pod nie płytki. Przejdźmy zatem do erraty i zobaczmy, co znajdziemy.
Problemów jest sporo, i tylko niektóre zostały rozwiązane. Ba, jest jeden problem, który dodano w najnowszej wersji krzemu, i kilka co najpierw zniknęły, a potem wróciły. Na 45 punktów tylko 12 jest rozwiązanych w wersji krzemu B2. Prawie 27%. Jakie więc problemy znajdziemy? Na początek dzielnik częstotliwości w obwodzie PLL zegara systemowego nie działa, gdy częstotliwość wejściowa wynosi więcej niż 100MHz. To nie jest wielki problem, bo spokojnie można użyć rezonatora o niższej częstotliwości, a układ PLL zrobi resztę. Gorzej, że w pierwszych dwóch wersjach krzemu obwód generatora kwarcowego nie działa w ogóle, a w trzeciej producent gwarantuje działanie tylko dla rezonatorów 8MHz, 12MHz i 24MHz. To ciekawy problem, bo to podstawowy komponent wszystkich mikrokontrolerów PIC. Oscylator pomocniczy w pier2szch dwóch wersjach krzemu też nie działa. W sytuacjach problemów z działaniem generatorów producent radzi użycie zewnętrznego układu generatora zegarowego. Dalej, UART nie rozpoznaje automatycznie prędkości transmisji, USB nie działa, jeśli na czas snu mikrokontrolera uśpimy też sprzętowy interfejs - nie obudzi układu po wykryciu połączenia lub komunikatu. Zdalne budzenie przez USB nie działa wcale, i trzeba tę informację umieścić w deskryptorach. W trybie hosta USB nie CPU nie budzi się po podłączeniu urządzenia. ADC w trybie różnicowym dla wartości 3072 dolicza błąd DNL +3(?!), a gdy napięcie zasilania ADC jest poniżej 2,5V i w użyciu jest pompa ładunkowa wewnątrz układu, to tylko jeden rdzeń ADC może być użyty. Czujnik temperatury nie czuje temperatury, wcale. Moduł SPI zmienia stan bitu sygnalizującego zakończenie transmisji przed zakończeniem transmisji, dlatego trzeba używać tutaj przerwania zamiast sprawdzać jego stan. Zbyt szybkie usypianie CPU po poprzedniej pobudce może go zawiesić aż do następnego wyłączenia i włączenia zasilania. Nie da się też wykorzystać w pełni funkcji samoprogramowania, bo nie działa programowanie słów konfiguracyjnych. Inaczej pisząc bootloader nie będzie działać z tym układem poprawnie.
To tylko przykładowe problemy występujące we wszystkich wersjach krzemu dla najnowszego układu PIC32. Ktoś ciekawski może się zapytać, dlaczego nie wymieniłem jeszcze ani jednego ośmiobitowego układu. Głównie dlatego, że generalnie układy ośmiobitowe nie miewają aż tylu problemów, co inne rodziny. Ba, wśród układów 16-bitowych są takie, co też nie miewają problemów, jak na przykład dsPIC33FJ16GP102-I/SP, który pozyskałem ze względu na obudowę DIP, z przeznaczeniem do zabaw w DSP i w emulację PDP-8 czy starszych maszyn. Errata ma tylko sześć punktów, z czego dwa to standardowe problemy z SPI, dwa to standardowe problemy z UART, a dwa ostatnie dotyczą rdzenia: jeden to znane dzielenie ze znakiem, a drugi dotyczy polecenia DISI wyłączającego czasowo przerwania i rejestru DISICNT. DISI #n wyłącza przerwania na n cykli procesora. Rejestr DISICNT zawiera bieżący stan licznika cykli. Wg. erraty nie można pisać do tego rejestru bezpośrednio, bo się zablokuje do ponownego uruchomienia całego układu. Zamiast tego ten rejestr można aktualizować tylko poleceniem DISI. Szczerze pisząc to nawet nie wiedziałem, iż te układy posiadają aż tak specyficzne instrukcje.
Ło, panie, kto to panu tak skopał?!
Skąd się biorą w mikrokontrolerach takie problemy? Dlaczego podobne problemy pojawiają się w wielu różnych układach i rodzinach układów? Kto za to odpowiada?
Nowe układy są projektowane z wykorzystaniem gotowych modułów. Te moduły są też projektowane przez grupy inżynierów. Cały ten proces zachodzi z użyciem specjalizowanego oprogramowania. Gdy układ jest zaprojektowany, wykonuje się klisze litograficzne potrzebne w procesie produkcji układów scalonych. To jest kosztowny proces, dlatego układy najpierw testuje się wirtualnie, a dopiero potem robi klisze. Dodatkowo im bardziej złożony układ i im szybciej ma działać, tym mniejszy proces produkcyjny jest używany, co przekłada się na koszty przygotowania do produkcji. Jeśli tylko partia testowa działa, to produkuje się 100-200 tysięcy sztuk, a potem wymienia się klisze i robi partię innych układów.
Tutaj pojawia się wielka różnica między firmami pokroju Intel, AMD czy Qualcomm, a Microchip czy STMicroelectronics. Intel i AMD projektują kilka układów scalonych wysokiej skali integracji, i zainwestowały ogromne pieniądze by móc produkować małe partie testowe i je testować przed finalizacją projektu. Przy czym w każdej rodzinie, na przykład procesorów projektowany jest układ "topowy". Dlaczego? Bo w czasie produkcji układy o słabszych parametrach w automatycznych testach są konfigurowane jako tańsze modele. I tak każdy procesor Intela czy AMD ma orygunalnie 16 rdzeni, ale część "nie wyszła" z różnych powodów, to je wyłączamy i sprzedajemy jako procesory ośmio- czy czterordzeniowe. Nie do końca wyszły wewnętrzne połączenia i układ nie może osiągnąć wyśrubowanych częstotliwości pracy? Zablokuje się mnożnik do wartości bezpiecznych i się sprzeda jako tańszy model.
Microchip tak nie może zrobić. Produkują za dużo różnorodnych układów mając ograniczoną liczbę linii produkcyjnych, by poświęcać czas i pieniądze na perfekcyjne projekty. Dlatego jeśli mikrokontroler ma kilka(-dziesiąt) różnych problemów, ale wyprodukowano już pierwsze 20 tysięcy sztuk, to lepiej jest wydać pieniądze na napisanie erraty, niż znacznie większe pieniądze na poprawę projektu i nową partię. Inżynierowie i tak będa poprawiać zarówno poszczególne komponenty układu, z których nowe mikrokontrolery będą składane, jak i samo złożenie tych części składowych. Gdy partia się wyprzeda, a okazała się być popularna, to układ doczeka się nowej, poprawionej wersji. Zresztą patrząc po oznaczeniach wersji w erratach można stwierdzić, że poza kilkoma wariantami produkcyjnymi jest nieznana liczba wariantów, które im nie wyszły wcale.
Warto też wspomnieć, że układy ośmiobitowe mają zdecydowanie mniej problemów, niż bardziej zaawansowane modele. Głównie dlatego, że generalnie są prostsze i wolniejsze, przez co są produkowane z użyciem starszych procesów i linii przy niższych kosztach.
Zakończenie
Mylić się jest rzeczą ludzką. Dlatego warto docenić, że producenci mikrokontrolerów starają się ułatwić życie publikując erraty. Są to dokumenty moim zdaniem tak samo ważne, jak noty katalogowe, jeśli wręcz nie ważniejsze. Dlatego gdy będziecie wybierać układ do nowego projektu, to sprawdźcie oba dokumenty, by przypadkiem się nie okazało na etapie prototypu, że moduł peryferyjny, na którym Wam zależy jednak nie działa prawidłowo.
Warto tez wspomnieć o tym, że błędy w oprogramowaniu jest bardzo łatwo poprawić, choć nie zawsze jest to szybki proces. Błędy na PCB można poprawić za pomocą cięcia ścieżek i lutowania przewodów je poprawiających. Błędy w krzemie trzeba jednak poprawiać przez przygotowanie nowej wersji klisz i wyprodukowanie nowej partii układów. Dlatego jeśli problem w krzemie można poprawić na poziomie oprogramowania lub w ostateczności przez modyfikację projektu układu i PCB, to nie warto czekać, aż firma poprawi scalak. Chyba że też reprezentujemy wielką korporację i planujemy zamówić układy za setki tysięcy dolarów, albo i miliony. Ale o to czytelników raczej nie posądzam.
A Wam zdarzyło sie pominąć lekturę erraty, co się na Was zemściło? Które rodziny mikrokontrolerów maja najgrubsze erraty, a które zaawansowane układy działają bezproblemowo? Chcielibyście nawiązać bliższe kontakty z układami 16-bitowymi lub 32-bitowymi od Microchip? Jak zawsze zapraszam do komentowania.
Kilka lat temu zaprojektowałem płytkę pod mikrokontrolery PIC24, dsPIC i PIC32 wykorzystując fakt, iż wiele modeli w obudowach TQFP-64 ma tę samą "pinologię". Projekt przeleżał w skrzynce, bo zwyczajnie nie byłem w stanie przylutować układu na swoje miejsce. Teraz projekt odkopałem i będę go kontynuował - w prototypie znajdzie się układ dsPIC33EP512GP506. Rzuciłem więc okiem do noty katalogowej, by sobie odświeżyć, co ten układ potrafi. A potem otworzyłem erratę...
To nie działa, tamto nie działa. To też nie działa. A o tym to szkoda nawet wspominać...
Czytanie errat, zwłaszcza co bardziej rozbudowanych mikrokontrolerów, pozwala nam doświadczyć uczucia rozczarowania i kompletnej daremności pracy. Szczególnie, gdy układ peryferyjny lub jego konkretna funkcjonalność, ze względu na które wybraliśmy dany układ nie działa prawidłowo, albo wcale, i nic nie da się z tym zrobić. Sytuacja staje się jeszcze gorsza, gdy dany układ peryferyjny ma więcej problemów. Wiele szesnastobitowych układów z serii dsPIC jest stworzonych z myślą o kontroli różnego rodzaju silników i przetwornic. Dlatego posiadają bardzo rozbudowane moduły PWM z wieloma użytecznymi funkcjami. Dlatego odradzam używania układów z serii dsPIC33EPXXXGP/MC20x/50x do takich zastosowań - problemy z PWM stanowią ponad 38% wszystkich problemów. Jeszcze gorzej się robi, gdy problemy dotyczą wszystkich mikrokontrolerów w danej rodzinie, we wszystkich wersjach krzemu. Jeśli do tego układ nie jest popularny, to nie należy spodziewać się poprawionej wersji w przyszłości.
Problemy przedstawione w erratach można podzielić na trzy kategorie:
1. Błędy nierozwiązywalne.
2. Błędy z rozwiązaniem programowym.
3. Błędy rzadkie, niespotykane lub nietypowe.
Omówię wszystkie rodzaje na przykładach z errat różnych mikrokontrolerów.
1. Błędy nierozwiązywalne.
Czyli problemy sprzętowe, których nie da się zwyczajnie rozwiązać w żaden sposób. Dla przykładu parametry AC/DC wbudowanego wzmacniacza operacyjnego i współpracującego z nim układu ADC mogą być inne, niż podane w nocie. W najgorszym razie oznacza to konieczność użycia zewnętrznego wzmacniacza operacyjnego - dla hobbysty to nie problem. W masowej produkcji jednak to dodatkowe koszty. Drugim, nierozwiązywalnym problemem może być sytuacja, gdy układ zasilany napięciem 3,3V ma piny tolerujące 5V, z wyjątkiem tych kilku, co jednak nie tolerują go, choć miały. Przykładowo dla dsPIC33EP512GP506 są to piny RC3, RC4, RC5 i RA9. Nie ma na to obejścia, więc lepiej ich nie "katować" wyższym napięciem.
Wspomniałem wcześniej o module PWM w rodzinie dsPIC33EPxxxGP/MC20x/50x. Jedną z teoretycznych funkcjonalności jest aktualizacja rejestru wypełnienia cykl po cyklu. Ale w jednym z trybów pracy aktualizacja nastepuje tylko co drugi cykl, i nie da się z tym nic zrobić. To drobiazg w porównaniu z wieloma innymi problemami tego modułu. Innym drobiazgiem jest to, iż aktualizacja rejestru fazy modułu zadziała z opóźnieniem dwóch cykli modułu. Chyba że użyjemy trybu natychmiastowej aktualizacji w trakcie bieżącego cyklu, a nie po jego zakończeniu. Trudno mi sobie wyobrazić sytuację, gdy ten drobiazg wpłynąłby negatywnie na realizowany projekt, chyba tylko gdy chcemy sterować serwomotorem sprzężonym z enkoderem kwadraturowym, do którego układ zapewnia osobny moduł peryferyjny. Moduł, który też nie działa.
Jednym z fajniejszych modułów w wielu PICach jest CTMU, czyli moduł mierzenia czasu ładowania kondensatora. Pozwala na precyzyjny pomiar pojemności i jej zmian czy na pomiar rezystancji, i na wiele więcej. W przypadku jednak wybranego przeze mnie dsPICa moduł nie działa z ADC ustawionym na konwersję dwunastobitową. Czasem też trafia się problem, do którego nie ma wyjaśnienia. Dla przykładu we wszystkich układach z rodziny dsPIC33EPXXX(GP/MC/MU)806/810/814 i PIC24EPXXX(GP/GU)810/814 moduł BOR (Brown Out Reset) musi być zawsze włączony. Dlaczego? Nie wiadomo. Co się stanie, jak się nie posłuchamy? Nie napisali. Boję się sprawdzić, by mi układ przypadkiem papieża nie wybrał. Ale żeby nie było, iż tylko szesnastobitowe układy mają problemy, to rzućmy okiem na inny mikrokontroler, który posiadam: PIC32MM0064GPL028. Ta rodzina ma relatywnie krótką erratę, bo tylko 18 problemów, z czego 9 udało się rozwiązać do rewizji B3, ale i tu są ciekawostki. Na przykład pinu MCRL nie można używać, by trzymać układ w stanie resetu celem zaoszczędzenia energii, bo pobiera wtedy więcej prądu, niż podaje specyfikacja. Obejścia brak. W układach w wersjach krzemu B1 i B2 moduł ADC też pobiera za dużo prądu, więc errata sugeruje wyłączać go, gdy nie jest potrzebny.
2. Błędy z rozwiązaniem programowym.
To największa grupa problemów wskazanych w erratach. Zależnie od rodzaju problemu rozwiązanie jest przedstawione w formie prostej porady, całej procedury opisanej w punktach albo procedury z przykładowym kodem źródłowym. Rozwiązania "jednozdaniowe" to na przykład porada, by problem CPU ze sprzętowym dzieleniem liczb ze znakiem (polecenie DIV SD) nie ustawiającym bitu przepełnienia w razie przepełnienia rozwiązać sprawdzając, czy mogłoby dojść do przepełnienia po dzieleniu. Implementację zostawiono jako ćwiczenie dla programisty. Biorąc pod uwagę, jak często operacja dzielenia ze znakiem przydaje się w funkcjach DSP to trochę upośledza istotną funkcjonalność ALU. Problem ten występuje w kilku rodzinach 16-bitowych PICów. W dsPICach serii 810 i pokrewnych moduł ECAN ma błąd nietypowy: jeden z bitów w jednym z rejestrów działa odwrotnie, niż powinien, więc rozwiązanie polega na zapamiętaniu tego faktu przy konfiguracji rejestru. Moduł ma też problem z generowaniem przerwania w razie ogólnego błędu łączności. Rozwiązanie to użycie przerwania "błędna wiadomość". Moduł USB, który sam z siebie zasługuje na całą serię artykułów, ma ciekawy problem, gdy układ działa jako host, a urządzenie low-speed jest podłączone do niego przez hub USB hi-speed. Rozwiązanie: nie używaj huba. Moduł ADC w rodzinie 20x/50x ma też ciekawy problem - bit DONE sygnalizujący koniec konwersji nie zmienia się, jeśli konwersja jest wyzwalana zewnętrznym przerwaniem. Rozwiązanie to albo sprawdzanie flagi ogólnego przerwania ADxIF, albo ustawienie tego przerwania jako aktywne. Moduł ma też problem gdy chcemy uzyskać prędkość 1,1Msps na wejściach AN0 i AN3 przy łączeniu kanałów CH0 i CH1 w programie. Rozwiązanie to fizyczne połączenie wskazanych pinów ze sobą - inaczej wyniki z CH1 nie będą prawidłowe. Czasem problemem jest sam dostęp do pamięci programu, i tak próby odczytu lub zapisu pamięci w obszarze adresów 0x001 do 0x200 prowadzi do wystąpienia błędu niespodziewanego adresu, jeśli w tle pojawi się jedno lub więcej przerwań. Trzeba zatem wyłączyć przerwania, gdy chcemy bezpośrednio wybrać adres w tym obszarze. Co ciekawe, to jeden z tych problemów, których możemy nawet nie zauważyć jeśli nie sprawdzimy, co kompilator robi, gdy konwertuje język wysokiego poziomu na assemblera, a potem na język maszynowy. Nie jestem tego pewien, ale wydaje mi się, że Microchip dostarcza programowych "łatek" do takich problemów dla poszczególnych rodzin układów. Trudno mi to potwierdzić, bo nie mam wielkiego doświadczenia w programowaniu rodzin 16-bitowych.
Wspominałem o problemach z PWM. Jednym z nich jest funkcjonalność "czasu martwego", bardzo przydatna przy budowaniu przetwornic. Oczywiście elektroniczne "stare wygi" będą pisać, że przetwornic na mikrokontrolerach się nie buduje, ale co tam oni wiedzą. Do brzegu, jak to moja żona mówi: "czas martwy" to odstęp między załączeniem jednego wyjścia, gdy drugie zostaje wyłączone w topologiach półmostkowych i pełnomostkowych, który to chroni przed przypadkowym jednoczesnym otwarciem górnego i dolnego tranzystora i wyborem papieża przez któryś z nich. Zatem to raczej porażka po stronie producenta, gdy przynajmniej dwa problemy wymagają całkowitego wyłączenia funkcji "czasu martwego" by moduł prawidłowo pracował.
We wspomnianej rodzinie 32-bitowych PICów moduł ADC jest bardzo rozbudowany, i jedną z jego funkcji jest sprzętowe formatowanie danych do formatów 16-bitowych ze znakiem i 32-bitowych ze znakiem. Teoretycznie, bo w praktyce oba są sformatowane tak samo, więc errata radzi zrobić konwersję w programie. Może to się przydać, jak kumulujemy wiele wyników celem oversamplingu.
Sporo problemów ma rozwiązania w formie nie tylko opisu, ale też wycinka kodu. Dla przykładu we wspomnianym już 32-bitowcu układ przełączania oscylatora na zewnętrzny ma wbudowany timer odliczający czas do uzyskania stabilnej częstotliwości, który to timer źle działa i sygnalizuje gotowość układu przed czasem. Przełączanie na zewnętrzny kwarc to rzecz, ktorą niemal zawsze robi się w pierwszej kolejności,. jeszcze przed konfiguracją innych peryferiów. Obejście przedstawione jako wycinek kodu zakłada użycie jednego z peryferiów, by to ono zażądało zmianę zegara na XT lub HS, a następnie ożycie wbudowanej funkcji by odczekać 9 milisekund zanim przełączy się układ zegarowy.
Ciekawy problem mają układy dsPIC33EPXXXGP/MC/MU806/810/814, jeśli użyje się w nich dwóch zagnieżdżonych instrukcji assemblerowych DO, nie będą pracować prawidłowa, gdy wewnetrzna pętla ma licznik równy 0. Obejście polega na dodaniu instrukcji NOP, jednej do pętli wewnętrznej, dwóch do zewnętrznej. Dokument zapewnia też kod xródłowy.
Cofnijmy się do rodziny dsPIC 20x/50x i beznadziejnie zabugowanego modułu PWM. Jednym z problemów w specyficznym trybie pracy jest ustawienie wypełnienia na 100%, ale tylko gdy wartosć w rejestrze PDCx jest mniejsza niż połowa wartości w rejestrze ALTDTRx. Dostajemy więc polecenie sprawdzanie tej wartości i aktualizowanie jej w miarę potrzeby, wraz z krótkim kawałkiem kodu.
3. Błędy rzadkie, niespotykane lub nietypowe.
To przypadki, gdzie czytając erratę trzeba się zatrzymać i zastanowić, w jaki sposób ktoś doszedł do tego problemu. Do tej kategorii zaliczyć też można problemy dyskwalifikujące jakiś moduł lub jego funkcję z użycia. Wróćmy do rodziny PIC32MM0064GPL036 i modułu ADC. W trybie 12-bitowym następujące odczytane wartości po prostu zwyczajnie nie występują:
• wariant B0: 1023, 2046, 2047, 3070 oraz 3071
• wariant B2: 1022, 1023, 2046, 2047, 3070 oraz 3071
Jak to możliwe, tego nie wiedzą nawet egipscy górale. Rozwiązanie to użyć trybu 10-bitowego. Co ciekawe, errata wskazuje też problemy z wariantem B3, ale dla niego nie ma podanych brakujących wartości.
Ten sam układ ma problem z jednym z bazowych modułów, BOR czyli Brown Out Reset. Układ ten ma za zadanie wstrzymać pracę mikrokontrolera, gdy napięcie jest za niskie by mógł prawidłowo pracować, i zresetować go po powrocie właściwego napięcia zasilania, sygnalizując przy tym przyczynę resetu. W naszym wypasionym 32-bitowcu ten układ zwyczajnie nie działa, i jedyne rekomendacje erraty to albo użyć zewnętrznego układu nadzorczego, albo nie dopuścić do spadku napięcia poniżej minimalnych, rekomendowanych wartości. To dziwne, bo moduł ten występuje we wszystkich układach PIC. To tak, jakby producent samochodów spalinowych wypuścił model bez rozrusznika i możliwości jego montażu, a potem umieścił w instrukcji, iż rekomenduje nigdy nie gasić silnika po odpaleniu, i odpalać go "na pych", trzymając "siłę napędową" w bagażniku.
Obie wspomniane rodziny 16-bitowe mają ten sam, specyficzny problem związany z dostępem do pamięci danych. Obie erraty zawierają dokładny opis warunków, które muszą się zdarzyć, by wystąpił problem polegający na błędnym wykonaniu kolejnych instrukcji. Zestaw warunków wygląda tak:
Pytanie za 10 punktów: jak często takie warunki mogą się pojawić? Jak rozpoznać taką sytuację, jeśli nie programujemy układu w assemblerze?
Na koniec prawdziwa "wiśniówka na torcie", czyli problem-widmo:
A może coś nowego?
Do tej pory oglądaliśmy erraty układów, które mają już kilka lat. A jak to wygląda w przypadku układów nowych? Weźmy na warsztat najnowszą rodzinę PICów z rdzeniem MIPS, PIC32MZ z FPU, MMU, DSP i paroma innymi skrótami. Układy posiadają nawet interfejsy szeregowy i równoległy do dołączania zewnętrznych pamięci - bajer. Osobiście wybrałbym PIC32MZ1024EFK064 w obudowie TQFP-64, jeśli by miał taką samą "pinologię", co układy 16-bitowe wspomniane wcześniej - mam pod nie płytki. Przejdźmy zatem do erraty i zobaczmy, co znajdziemy.
Problemów jest sporo, i tylko niektóre zostały rozwiązane. Ba, jest jeden problem, który dodano w najnowszej wersji krzemu, i kilka co najpierw zniknęły, a potem wróciły. Na 45 punktów tylko 12 jest rozwiązanych w wersji krzemu B2. Prawie 27%. Jakie więc problemy znajdziemy? Na początek dzielnik częstotliwości w obwodzie PLL zegara systemowego nie działa, gdy częstotliwość wejściowa wynosi więcej niż 100MHz. To nie jest wielki problem, bo spokojnie można użyć rezonatora o niższej częstotliwości, a układ PLL zrobi resztę. Gorzej, że w pierwszych dwóch wersjach krzemu obwód generatora kwarcowego nie działa w ogóle, a w trzeciej producent gwarantuje działanie tylko dla rezonatorów 8MHz, 12MHz i 24MHz. To ciekawy problem, bo to podstawowy komponent wszystkich mikrokontrolerów PIC. Oscylator pomocniczy w pier2szch dwóch wersjach krzemu też nie działa. W sytuacjach problemów z działaniem generatorów producent radzi użycie zewnętrznego układu generatora zegarowego. Dalej, UART nie rozpoznaje automatycznie prędkości transmisji, USB nie działa, jeśli na czas snu mikrokontrolera uśpimy też sprzętowy interfejs - nie obudzi układu po wykryciu połączenia lub komunikatu. Zdalne budzenie przez USB nie działa wcale, i trzeba tę informację umieścić w deskryptorach. W trybie hosta USB nie CPU nie budzi się po podłączeniu urządzenia. ADC w trybie różnicowym dla wartości 3072 dolicza błąd DNL +3(?!), a gdy napięcie zasilania ADC jest poniżej 2,5V i w użyciu jest pompa ładunkowa wewnątrz układu, to tylko jeden rdzeń ADC może być użyty. Czujnik temperatury nie czuje temperatury, wcale. Moduł SPI zmienia stan bitu sygnalizującego zakończenie transmisji przed zakończeniem transmisji, dlatego trzeba używać tutaj przerwania zamiast sprawdzać jego stan. Zbyt szybkie usypianie CPU po poprzedniej pobudce może go zawiesić aż do następnego wyłączenia i włączenia zasilania. Nie da się też wykorzystać w pełni funkcji samoprogramowania, bo nie działa programowanie słów konfiguracyjnych. Inaczej pisząc bootloader nie będzie działać z tym układem poprawnie.
To tylko przykładowe problemy występujące we wszystkich wersjach krzemu dla najnowszego układu PIC32. Ktoś ciekawski może się zapytać, dlaczego nie wymieniłem jeszcze ani jednego ośmiobitowego układu. Głównie dlatego, że generalnie układy ośmiobitowe nie miewają aż tylu problemów, co inne rodziny. Ba, wśród układów 16-bitowych są takie, co też nie miewają problemów, jak na przykład dsPIC33FJ16GP102-I/SP, który pozyskałem ze względu na obudowę DIP, z przeznaczeniem do zabaw w DSP i w emulację PDP-8 czy starszych maszyn. Errata ma tylko sześć punktów, z czego dwa to standardowe problemy z SPI, dwa to standardowe problemy z UART, a dwa ostatnie dotyczą rdzenia: jeden to znane dzielenie ze znakiem, a drugi dotyczy polecenia DISI wyłączającego czasowo przerwania i rejestru DISICNT. DISI #n wyłącza przerwania na n cykli procesora. Rejestr DISICNT zawiera bieżący stan licznika cykli. Wg. erraty nie można pisać do tego rejestru bezpośrednio, bo się zablokuje do ponownego uruchomienia całego układu. Zamiast tego ten rejestr można aktualizować tylko poleceniem DISI. Szczerze pisząc to nawet nie wiedziałem, iż te układy posiadają aż tak specyficzne instrukcje.
Ło, panie, kto to panu tak skopał?!
Skąd się biorą w mikrokontrolerach takie problemy? Dlaczego podobne problemy pojawiają się w wielu różnych układach i rodzinach układów? Kto za to odpowiada?
Nowe układy są projektowane z wykorzystaniem gotowych modułów. Te moduły są też projektowane przez grupy inżynierów. Cały ten proces zachodzi z użyciem specjalizowanego oprogramowania. Gdy układ jest zaprojektowany, wykonuje się klisze litograficzne potrzebne w procesie produkcji układów scalonych. To jest kosztowny proces, dlatego układy najpierw testuje się wirtualnie, a dopiero potem robi klisze. Dodatkowo im bardziej złożony układ i im szybciej ma działać, tym mniejszy proces produkcyjny jest używany, co przekłada się na koszty przygotowania do produkcji. Jeśli tylko partia testowa działa, to produkuje się 100-200 tysięcy sztuk, a potem wymienia się klisze i robi partię innych układów.
Tutaj pojawia się wielka różnica między firmami pokroju Intel, AMD czy Qualcomm, a Microchip czy STMicroelectronics. Intel i AMD projektują kilka układów scalonych wysokiej skali integracji, i zainwestowały ogromne pieniądze by móc produkować małe partie testowe i je testować przed finalizacją projektu. Przy czym w każdej rodzinie, na przykład procesorów projektowany jest układ "topowy". Dlaczego? Bo w czasie produkcji układy o słabszych parametrach w automatycznych testach są konfigurowane jako tańsze modele. I tak każdy procesor Intela czy AMD ma orygunalnie 16 rdzeni, ale część "nie wyszła" z różnych powodów, to je wyłączamy i sprzedajemy jako procesory ośmio- czy czterordzeniowe. Nie do końca wyszły wewnętrzne połączenia i układ nie może osiągnąć wyśrubowanych częstotliwości pracy? Zablokuje się mnożnik do wartości bezpiecznych i się sprzeda jako tańszy model.
Microchip tak nie może zrobić. Produkują za dużo różnorodnych układów mając ograniczoną liczbę linii produkcyjnych, by poświęcać czas i pieniądze na perfekcyjne projekty. Dlatego jeśli mikrokontroler ma kilka(-dziesiąt) różnych problemów, ale wyprodukowano już pierwsze 20 tysięcy sztuk, to lepiej jest wydać pieniądze na napisanie erraty, niż znacznie większe pieniądze na poprawę projektu i nową partię. Inżynierowie i tak będa poprawiać zarówno poszczególne komponenty układu, z których nowe mikrokontrolery będą składane, jak i samo złożenie tych części składowych. Gdy partia się wyprzeda, a okazała się być popularna, to układ doczeka się nowej, poprawionej wersji. Zresztą patrząc po oznaczeniach wersji w erratach można stwierdzić, że poza kilkoma wariantami produkcyjnymi jest nieznana liczba wariantów, które im nie wyszły wcale.
Warto też wspomnieć, że układy ośmiobitowe mają zdecydowanie mniej problemów, niż bardziej zaawansowane modele. Głównie dlatego, że generalnie są prostsze i wolniejsze, przez co są produkowane z użyciem starszych procesów i linii przy niższych kosztach.
Zakończenie
Mylić się jest rzeczą ludzką. Dlatego warto docenić, że producenci mikrokontrolerów starają się ułatwić życie publikując erraty. Są to dokumenty moim zdaniem tak samo ważne, jak noty katalogowe, jeśli wręcz nie ważniejsze. Dlatego gdy będziecie wybierać układ do nowego projektu, to sprawdźcie oba dokumenty, by przypadkiem się nie okazało na etapie prototypu, że moduł peryferyjny, na którym Wam zależy jednak nie działa prawidłowo.
Warto tez wspomnieć o tym, że błędy w oprogramowaniu jest bardzo łatwo poprawić, choć nie zawsze jest to szybki proces. Błędy na PCB można poprawić za pomocą cięcia ścieżek i lutowania przewodów je poprawiających. Błędy w krzemie trzeba jednak poprawiać przez przygotowanie nowej wersji klisz i wyprodukowanie nowej partii układów. Dlatego jeśli problem w krzemie można poprawić na poziomie oprogramowania lub w ostateczności przez modyfikację projektu układu i PCB, to nie warto czekać, aż firma poprawi scalak. Chyba że też reprezentujemy wielką korporację i planujemy zamówić układy za setki tysięcy dolarów, albo i miliony. Ale o to czytelników raczej nie posądzam.
A Wam zdarzyło sie pominąć lekturę erraty, co się na Was zemściło? Które rodziny mikrokontrolerów maja najgrubsze erraty, a które zaawansowane układy działają bezproblemowo? Chcielibyście nawiązać bliższe kontakty z układami 16-bitowymi lub 32-bitowymi od Microchip? Jak zawsze zapraszam do komentowania.
Fajne? Ranking DIY
