STM32Butterfly2: obsługa kart SD w trybie SPI

Podczas wykonywania funkcji mmcHwInit() ustawiany jest odpowiedni stan linii CS oraz przeprowadzana jest konfiguracja kontrolera SPI do pracy w trybie full duplex, jako master z 8 bitami danych. Za konfigurację tą odpowiada funkcja spi_cfg, która jako parametr przyjmuje dzielnik zegara taktującego kontroler SPI.

Po skonfigurowaniu linii realizowana jest inicjalizacja karty poprzez wysyłanie odpowiednich komend oraz reagowanie na zwracane odpowiedzi.

Po zakończeniu inicjalizacji karty SD, wywoływana jest funkcja printp, która wyświetla informacje o rodzaju karty. W rzeczywistości jest to definicja, pod którą ukrywa się kod przedstawiony poniżej.

#define printp(line,…) do { nlcd_set_position(0,line); tiny_printf(__VA_ARGS__); } while (0) 

Przedstawiona definicja, dla początkującego, zapewne wydaje się bardzo skomplikowana. Rozkładając definicje można zauważyć, iż mamy w niej kod pętli do { … } while (0). Pętla ta grupuje oba polecenia, wywoływane w ramach pętli, w całość. Ze względu na zadany warunek pętla wykona się jednokrotnie. Pierwszym działaniem jest ustawienie pozycji kursora na wyświetlaczu, używany jest do tego celu podawany parametr – line. Następnie wywoływana jest funkcja tiny_printf, która przyjmuje jako parametr pozostałe argumenty. Funkcja ta wypisuje sformatowany tekst i dane na wyświetlaczu, wykorzystując do tego celu wcześniej przygotowany wskaźnik na funkcję wypisującą znak na wyświetlaczu.

W przypadku niepowodzenia inicjalizacji karty (zwracana wartość poniżej 0) program przechodzi do nieskończonej pętli blokując dalsze działanie. W przypadku powodzenia inicjalizacji karty SD program wyświetla informacje o pojemności karty SD, wyrażoną w MB. Pojemność uzyskiwana jest dzięki funkcji mmcCapacity().

W kolejnym kroku wywoływana jest funkcja print_partrecord(), która odczytuje pierwszy sektor, zawierającego informacje o partycji, oraz wyświetla informacje: o typie partycji, pierwszym sektorze LBA oraz o rozmiarze sektora.

Po uzupełnieniu wyświetlacza o dodatkowe informacje program przechodzi do oczekiwania na wyjęcie karty z gniazda, realizuje to funkcja card_wait4remove(). Jej działanie sprowadza się do zapętlenia programu do czasu zmiany stanu na odpowiedniej linii na stan wysoki.

Jak można zauważyć, w programie głównym brakuje kodu odpowiedzialnego za konfigurację między innymi zegarów mikrokontrolera. Ta czynność i pozostałe inicjalizujące mikrokontroler do pracy jest wykonywana w ramach obsługi przerwania wywoływanego przez reset mikrokontrolera. Podczas obsługi przerwania wywoływana jest między innymi funkcja main().

Do pobrania

O autorze