Autor: tmf
Redakcja: Dondu
RFM22B/23B są świetnymi modułami radiowymi, w stosunku do poprzendików (m.in. RFM12) więcej zadań jest realizowanych sprzętowo, dzięki czemu procesor ma mniej pracy. Niestety pewną wadą tych układów są dosyć kiepskie noty katalogowe – niby wszystko jest opisane, ale po ich przeczytaniu, miałem sporo pytań, na które nie znalazłem odpowiedzi. Nie muszę chyba dodawać, że były to pytania istotne.
Datasheet: RFM22B/23B
Jednak bestie te są warte okiełznania – przyzwoita prędkość transmisji, wygoda ich stosowania, prosty interfejs szeregowy łączący z mikrokontrolerem, rozsądna cena – to wszystko czyni je niezastąpionymi dla elektroników pragnących dodać nowy wymiar w komunikacji pomiędzy urządzeniami.
RFM22B/23B i FIFO
Jedną z ciekawych cech modułów RFM22/23B jest posiadanie przez nie dużych, 64-bajtowych, buforów FIFO – po jednym dla nadajnika i odbiornika. Dostęp do nich odbywa się niezależnie (operacje na buforze nadajnika nie mają wpływu na bufor odbiornika i vice versa). Dzięki temu po załadowaniu do bufora potrzebnych danych, moduł sam może je transmitować, bez jakiegokolwiek udziału procesora.
Podobnie przy odbiorze – odbierany pakiet trafia do bufora, skąd może być odczytany przez procesor w dowolnej chwili.
Czytając notę katalogową można zauważyć, że rejestry określające długość odebranego/nadawanego pakietu (rejestr 3Eh - Packet Length i rejestr 4Bh - Received Packet Length) są 8-bitowe – a więc transmitowane pakiety mogą mieć maksymalnie 255 bajtów długości. Jednak FIFO jest tylko 64-bajtowe, powstaje więc pytanie:
Jak nadać lub odebrać pakiety dłuższe niż 64-bajty w tyrybie automatycznym?
Niestety szukanie odpowiedzi na to pytanie w nocie raczej do rozwiązania nas nie przybliży – jej autorzy albo nie dostrzegli problemu, albo założyli, że czytelnik ma nadprzyrodzone zdolności dedukcji
Zobaczmy więc jak wygląda dostęp do FIFO.
Wszelkie operacje zapisu i odczytu FIFO realizowane są przy pomocy dwóch rejestrów – rejestru 08h (Operating Mode and Function Control 2), którego bity 0 i 1 umożliwiają zerowanie odpowiednio bufora nadajnika lub odbiornika, oraz rejestru 7Fh (FIFO Access) umożliwiającego dostęp do danych zawartych w FIFO. Pozostałe rejestry służą do ustawienia progów sygnalizujących stan bufora, ale o tym za chwilę.
Dostęp do FIFO opiszę na przykładzie bufora nadajnika – bufor odbiornika w dużej mierze działa podobnie. Dostęp do FIFO należy rozpocząć od jego zresetowania (ustawienia a następnie wyzerowania bitu 0 w rejestrze 08h). Po tej operacji wskaźnik zapisu do bufora jest zerowany (wskaźnik ten nie jest dostępny bezpośrednio programiście), a kolejne dane zapisywane są począwszy od pozycji 0.
Bezpośrednio zapisać można tylko 64-bajty danych – przy próbie zapisu większej ilości bajtów dojdzie do przepełnienia bufora – wynika z tego, że bezpośrednio transmitować można pakiety o długości do 64-bajtów (+bajty dodawane automatycznie – nagłówek, długość pakietu, CRC).
Dostęp do FIFO można realizować na dwa sposoby:
Pierwszy polega na aktywacji linii nSEL (aktywacja interfejsu SPI), następnie wybraniu numeru rejestru (7Fh) i kolejnych zapisach pod ten adres danych. Co ważne, w tym trybie sygnał nSEL musi pozostawać stale aktywny – kolejne zapisy/odczyty rejestru 7Fh, w przeciwieństwie do dostępu do innych rejestrów, nie powodują automatycznej zmiany zapisywanego/odczytywanego rejestru. Dzięki temu, w trakcie jednej transakcji SPI można odczytać/zapisać cały bufor FIFO. Tryb ten jest wygodny, gdyż efektywnie redukuje o połowę ilość przesyłanych po SPI danych, a co za tym idzie redukuje czas całej operacji.
W drugim trybie przy każdej operacji zapisu/odczytu FIFO transmitowany jest adres rejestru, a sygnał nSEL po każdym cyklu wraca do stanu 1.
Rys. 1 - Transmisja danych do modułu (tryb burst) Po wysłaniu numeru rejestru transmitowana jest seria danych wpisywanych do kolejnych rejestrów lub FIFO |
Rys. 2 - Tryb w którym transmitowane są tylko 2 bajty - nr rejestru i jego wartość. |
Co ważne, bufor nadajnika można tylko zapisywać, natomiast bufor odbiornika można tylko odczytywać – obie operacje polegają na zapisie/odczycie tego samego rejestru o adresie 7Fh.
Jak już pisałem, próba zapisu więcej niż 64 bajtów do rejestru nadajnika spowoduje błąd przepełnieina, z kolei próba odczytania z rejestru odbiornika większej liczby danych niż w nim się znajduje spowoduje zasygnalizowanie błędu niedomiaru – ustawienie bitu nr 7 rejestru 03h (Interrupt/Status 1).
Przejdźmy więc do sedna – jak wysłać/odebrać pakiet dłuższy niż 64-bajty?
Operację taką należy podzielić na kilka etapów. W pierwszym uzupełniamy bufor nadajnika danymi do wysłania (maksymalnie 64 bajty). Następnie włączamy nadajnik, co spowoduje rozpoczęcie transmisji danych. Kolejne transmitowane dane powodują inkrementację niedostępnego dla programisty wskaźnika odczytu FIFO, w efekcie zwalniając miejsce w buforze dla kolejnych danych – bufor FIFO zachowuje się jak bufor cykliczny. Na zwolnione pozycje można zapisać kolejne porcje danych, które zostaną przetransmitowane.
Powstaje tylko problem – skąd wiedzieć kiedy i ile bajtów można zapisać do FIFO, tak aby nie wywołać ponownie sytuacji nadmiaru?
Jak zwykle jest kilka sposobów – dosyć prostych i głupich, oraz nieco bardziej zawiłych, ale gwarantujących sukces.
Sposób "głupi" to odczekać pewien czas, zależny od wybranej prędkości transmisji, a następnie zapisać kolejne bajty danych.
Sposób "mądry" :-)
Na szczęście projektanci modułu dostarczają nam lepszych narzędzi. Tu z pomocą przychodzi rejestr 7Dh (TX FIFO Control 2). Umożliwia on ustawienie dowolnej wartości z zakresu 0-63 – jeśli ilość danych znajdujących się w buforze nadajnika (a więc danych które jeszcze nie zostały wysłane) będzie mniejsza niż wartość w rejestrze 7Dh zostanie ustawiona flaga ixtffaem rejestru 03h (TX FIFO Almost Empty).
W zależności od konfiguracji modułu, zmiana stanu tej flagi może wywołać przerwanie dla mikrokontrolera, dzięki czemu jej stanu nie musimy ciągle testować. Wartość rejestru 7Dh należy tak dobrać, aby zdążyć uzupełnić bufor nadajnika nowymi danymi, zanim zostanie on całkowicie opróżniony – jeśli nie zdążymy tego zrobić to transmisja danych zakończy się niepowodzeniem, co zasygnalizuje ustawienie flagi niedomiaru rejestru 03h (oraz bitu 6 rejestru 02 – jego odczyt umożliwia sprecyzowanie problemu).
Rys. 3 - Stan FIFO nadajnika w trakcie transmisji. |
Należy pamiętać, że rejestry definiujące odpowiednie progi w buforach nie określają bezwzględnego adresu komórki w buforze (jak to błędnie sugeruje nota katalogowa), lecz offset w stosunku do ukrytego przed programistą wskaźnika odczytu, który wskazuje na odczytywaną przez nadajnik/odbiornik komórkę bufora cyklicznego.
Ma to szczególne znaczenie dla bufora odczytu w trybie odbioru wielu pakietów – bufor po prostu „przekręca się” w trakcie kolejnych odczytów. W trybie tym nie należy bufora resetować – spowodowałoby to utratę zawartych w nich danych. Z kolei po odczytaniu wszystkich danych oczekujących jego resetowanie jest stratą czasu.
Podsumowanie
Jak widać, ten prosty mechanizm zapewnia łatwe nadawanie pakietów o dowolnej długości. Podobny trick należy zastosować przy odbiorze danych – w tym przypadku porcję danych z bufora odbiornika należy odczytać zanim dojdzie do jego przepełnienia. Odpowiedni poziom można ustawić poprzez rejestr 7Eh (RX FIFO Control) – jego osiągnięcie również może wygenerować przerwanie, w którym można dokonać odczytu częściowo odebranego pakietu danych.
Jak widać kluczowe dla sensownej współpracy z modułem RFM22B/23B jest poznanie mechanizmów obsługi przerwań w danym procesorze – praktycznie wszystkie operacje związane z nadawaniem i odbiorem pakietów będa realizowane w funkcji obsługi przerwania. No, ale to już całkiem inna historia. :-)
A dla niecierpliwych dobrym punktem wyjścia będzie rozdział 14 książki:
Język C dla mikrokontrolerów AVR.
Od podstaw do zaawansowanych aplikacji.
Na wstępie dziękuję autorom bloga za to co robicie, bo wiele osób na pewno na tym skorzysta.
OdpowiedzUsuńUważam, że dobrym pomysłem przy kontynuacji tego artykułu byłoby porównanie (np. na podstawie testów i złożoności nawiązania połączenia) opisanego modułu RFM22B/23B z modułami RFM12B oraz RFM01B+RFM02B. Przede wszystkim chodzi mi tutaj o stosunek jakość/cena.
Pozdrawiam i życzę powodzenia w rozwijaniu bloga!
Witam
OdpowiedzUsuńKiedy będzie można się spodziewać kolejnych porad dotyczących modułu RFM22B?
Pozdrawiam
PS. świetlny blog!
Jak będzie chwilka czasu. Wcześniej różne informacje (i gotowy stos) pojawią się w nowej książce, potem, w zależności od problemów, pewne rzeczy się umieści na blogu.
OdpowiedzUsuńA tak w ogóle, to sorki, że odpisuję po kilku miesiącach, ale automatyczne powiadamianie (z powodu awarii maila) nie działa :)
Kiedy się można spodziewać kolejnych artykułów związanych z modułami radiowymi?. Kiedy kolejny tom książki :)?
OdpowiedzUsuńMam nadzieję, że już wkrótce. Niestety praca odciąga mnie od pisania, ale postaram się to zmienić :)
OdpowiedzUsuńJakiś wstępny spis zawartości?
OdpowiedzUsuńczego się będzie można spodziewać w nowej książce?
Mam nadzieję, że wszystkiego dobrego :)
OdpowiedzUsuńSpisu treści na razie nie pokazuję, ale będzie tego sporo. Przykładowych programów też będzie naprawdę dużo, w tym o komunikacji, także radiowej. I coś dla miłośników robotyki. Finalnie będzie koło (a może ponad) 1000 stron, więc każdy coś dla siebie znajdzie :)
Mamy końcówkę stycznia. Pod koniec lutego obchodzę urodziny - czy książka się ukaże do tego momentu? Chętnie sprawiłbym sobie taki prezent :-)
OdpowiedzUsuńA kiedy masz imieniny?:)
OdpowiedzUsuńA na poważnie - kończę ją, ale to naprawdę dużo treści, setki przykładów, porządne sprawdzenie tego na różnych procesorach trochę trwa.
Witam, posiadam taki moduł w wersji z goldpinami, zrobiłem przelotke z 2mm na 2,54, wytrawiona, zlutowana, całkowicie zero zwarc i wszedzie przejscia (nawet pomierzona oporność połączeń), moduł po spieciu kablami działa, a bez przewodów w przelotce nie działa. czy ten moduł wymaga jakichś specjalnych zabiegów ?
OdpowiedzUsuńNie. Musisz mieć jakiś błąd.
UsuńA jest szansa na kurs pisania bibliotek do tych modułów? A najlepiej do RFM69CW? :)
OdpowiedzUsuńJeśli byłoby duże zainteresowanie to tak, ale ma...
Usuń