Digilent Pmod i STM32 (cz. 10) – PmodGYRO, PmodTMP3 i PmodWiFi
PmodWiFi
Ostatnim z przedstawianych modułów jest PmodWiFi, z wbudowanym modemem radiowym Wi-Fi MRF24WG0MA od firmy Microchip. Modem jest zgodny ze standardami IEEE 802.11b/g/n i umożliwia transmisję danych na odległość do 400 m, przy prędkości transmisji danych wynoszącej 1 lub 2 Mbps. Moduł PmodWiFi ma antenę PCB, dzięki czemu do jego użycia nie potrzebne są żadne dodatkowe komponenty. Do komunikacji z modemem służy interfejs SPI oraz generowane przez niego przerwania.
Połączenie z zestawem KAmeleon
PmodWiFi ma 12-pinowe złącze SPI z dodatkowymi sygnałami WP (Write-protected) i HIBERATE. Sygnały te są podłączone przez rezystory do masy, dzięki czemu nie muszą być obsługiwane przez mikrokontroler. W przykładzie nie są one używane ze względu na brak podłączonych do nich pinów mikrokontrolera na złączu Pmod-SPI. Podłączenie modułu PmodWiFi do mikrokontrolera za pośrednictwem złącza Pmod-SPI, użytego w przykładzie zaprezentowano w tabeli 3 i na fotografii 9.
Tabela 3. Sygnały PmodWiFi oraz odpowiadające im piny mikrokontrolera; w tabeli pominięto sygnały niepodłączone do mikrokontrolera (WP i HYBERNATE) oraz linie zasilania występujące na złączu Pmod
Sygnał | Numer pinu PmodWiFi (J1) | Pin STM32L496ZG (KAmeleon Pmod-SPI) |
CS | 1 | PB0 |
SDI | 2 | PA7 |
SDO | 3 | PE14 |
SCK | 4 | PA1 |
INT | 7 | PE12 |
RESET | 8 | PE13 |
Fotografia 9. Moduł PmodWiFi podłączony do zestawu KAmeleon
Sterownik modułu MRF24WG0MA
Do obsługi układu MRF24WG0MA firma Microchip udostępniła programowy stos TCP/IP przeznaczony dla mikrokontrolerów z rodziny PIC i dostępny na stronie www.microchip.com/wireless. Jednak z uwagi na to, że przykład został przygotowany dla mikrokontrolera z rodziny STM32, zastosowano stos CycloneTCP przygotowany przez firmę ORYX embedded i dostępny do pobrania ze strony www.oryx-embedded.com. Stos ten jest dostępny za darmo na licencji GPLv2 lub na jednej z licencji komercyjnych, a jego zaletą jest duża liczba wspieranych mikrokontrolerów oraz modemów. W przykładzie pokazano skanowanie widocznych sieci Wi-Fi, dlatego w katalogu Drivers znajduje się tylko sterownik modułu MRF24WG0MA (CycloneTCP_SSL_Crypto_Open_1_8_0/third_party/microchip/devices/mrf24wg/). Pozostałe źródła wchodzące w skład stosu są nieużywane, dlatego usunięto je z plików projektu.
Sterownik mrf24wg wymaga zdefiniowania kilku dodatkowych funkcji i definicji odpowiedzialnych za obsługę GPIO, SPI, przerwań oraz zliczania czasu. Zostały one umieszczone w plikach znajdujących się w katalogach inc i src w katalogu głównym projektu:
- wf_customize.h – konfiguracja sterownika, kolejności bajtów i komunikatów diagnostycznych,
- wf_eint_stub.c – konfiguracja i obsługa przerwań od pinu INT,
- wf_gpio_stub.c – obsługa pinu RESET,
- wf_spi_stub.c – konfiguracja i obsługa interfejsu SPI,
- wf_timer_stub.c – informacja o czasie systemowym.
Opisy funkcji
Opisy funkcji zaimplementowanych w powyższych plikach znajdują się w tabeli 4.
Tabela 4. Funkcje wymagane przez sterownik modemu mrf24wg
Funkcja | Opis |
WF_EintInit | Inicjalizacja przerwania od pinu INT aktywnego na zboczu opadającym. |
WF_EintEnable | Włączenie przerwania od pinu INT. |
WF_EintDisable | Wyłączenie przerwania od pinu INT. |
WF_isEintDisabled | Sprawdzenie stanu przerwania od pinu INT (włączone lub nie). |
ext1IrqHandler | Obsługa przerwania od pinu INT wyłączająca przerwania i wywołująca wewnętrzną funkcję sterownika odpowiedzialną za dalsze przetwarzanie przerwania. |
WF_GpioInit | Inicjalizacja pinu RESET. |
WF_GpioSetReset | Ustawienie żądanego stanu na pinie RESET. |
WF_GpioSetHibernate | Ustawienie żądanego stanu na pinie HIBERNATE. Funkcja jest wymagana przez sterownik, jednak w przykładzie jest pusta ze względu na niepodłączony sygnał HIBERNATE. |
WF_SpiInit | Inicjalizacja interfejsu SPI w trybie 0 (CPOL = 0, CPHA = 0) z programową obsługa pinu CS; inicjalizacja sygnałów SDI, SDO i SCK. |
WF_SpiEnableChipSelect | Ustawienie pinu CS w stanie niskim (aktywnym). |
WF_SpiDisableChipSelect | Ustawienie pinu CS w stanie wysokim (nieaktywnym). |
WF_SpiTxRx | Wysyłanie i odbiór danych przez interfejs SPI. |
WF_TimerInit | Inicjalizacja licznika dostarczającego liczbę milisekund od uruchomienia systemu. Funkcja jest pusta, ponieważ przykład używa licznika obsługiwanego przez bibliotekę STM32Cube. |
WF_TimerRead | Odczyt liczby milisekund od startu systemu. Funkcja wykorzystuje bibliotekę STM32Cube (HAL_GetTick). |
Kod przykładu
Mając zaimplementowane wszystkie funkcje wymagane przez sterownik układu MRF24WG0MA można przejść do kodu głównego przykładowej aplikacji. Inicjalizacja wszystkich modułów znajduje się w funkcji main, przedstawionej na listingu 6. Za konfigurację sterownika odpowiada funkcja biblioteczna WF_Init, która z kolei wywołuje niezbędne funkcje opisane wyżej. Dodatkowo, pętla główna programu wywołuje funkcję WF_Task napędzająca maszynę stanów sterownika odpowiedzialną za sterowanie modemem oraz przetwarzanie danych.
Listing 6. Funkcja main przykładowej aplikacji dla modułu PmodWiFi
int main(void) { HAL_Init(); SystemClock_Config(); Serial_Config(); WF_Init(); while(1) { WF_Task(); } }
Druga z funkcji w pliku main.c – HAL_GPIO_EXTI_Callback, wywołuje jedynie wspomnianą wcześniej funkcję ext1IrqHandler odpowiedzialną za obsługę przerwania od pinu INT.
Ostatnie dwie funkcje – WF_ProcessEvent oraz WF_RxPacketReady są wymagane przez sterownik. Pierwsza z nich, przedstawiona na listingu 7, obsługuje zgłaszane przez niego zdarzenia. W przykładzie są to: WF_EVENT_INITIALIZATION wysyłane po zakończeniu inicjalizacji i WF_EVENT_SCAN_RESULTS_READY wysyłane, gdy zakończy się skanowanie widocznych sieci Wi-Fi. Obsługa wszystkich zdarzeń zależy od aplikacji – w opisywanym programie wyniki skanowania są jedynie wypisywane na port szeregowy. Na listingu znajduje się także wywołanie DumpEventInfo, które wypisuje informacje diagnostyczne dotyczące otrzymanych zdarzeń. Druga z funkcji – WF_RxPacketReady nie jest używana w przykładzie, jednak jest wymagana przez sterownik, dlatego została pozostawiona pusta.
Listing 7. Obsługa zdarzeń dostarczanych przez sterownik mrf24wg
void WF_ProcessEvent(uint8_t eventType, uint32_t eventData) { DumpEventInfo(eventType, eventData); if(eventType == WF_EVENT_INITIALIZATION && eventData == WF_INIT_SUCCESSFUL) { WF_Scan(); } else if (eventType == WF_EVENT_SCAN_RESULTS_READY) { for(int i=0; i<eventData; i++) { t_scanResult res; WF_ScanResultGet(i, &res); res.ssid[res.ssidLen] = '\0'; printf("%d. [%s] RSSI:%d\r\n",i , res.ssid, res.rssi); } } }
Wypisywanie danych na port szeregowy
Do przykładu został dołączony plik tiny_printf.c zawierający proste implementacje funkcji printf, fprintf i sprintf. Są one używane przez stos CycloneTCP do wypisywania informacji diagnostycznych. Do poprawnego działania tych funkcji konieczne jest zaimplementowanie funkcji _write odpowiedzialnej za wypisywanie znaków na port szeregowy. W przykładzie użyto do tego celu funkcji Serial_Write, zaimplementowanej w pliku serial.c i obsługującej port LPUART1.