Cześć
W związku z tym, że w miejscu w którym pracuję istnieje potrzeba programowania pamięci SPI których wsad jest taki sam, stwierdziłem że zbuduję urządzenie, które będzie kopiowało zawartość jednej kości do drugiej. Niby nic, ale z czasem chciałbym zająć się zawodowo projektowaniem oraz programowaniem mikrokontrolerów, więc jako pierwszy projekt wydaje się to być ciekawym ćwiczeniem, tym bardziej że będzie często używany komercyjnie.
Oczywiście, można używać programatora/programatorów do masowej produkcji, ale tutaj mamy jedną płytkę, która nie wymaga podłączania do PC i uruchamiania czegokolwiek. Przyłączamy dwie kości, wciskamy przycisk i to tyle. Prędkość zapisywania kości jest taka sama jak w przypadku np. programatora RT809.
Jest to też w sumie mój pierwszy projekt, który ukończyłem na tyle, że nadaje się do publikacji, choć jeszcze nie jest zrobiony w 100%
Jako procesor wykorzystałem STM32G431KBT6. Cały projekt stworzony jest w STM32CubeIDE z wykorzystaniem CMSIS, bez użycia HAL. W tym miejscu bardzo chciałbym podziękować koledze, który stworzył poradnik, który znaleźć można na elektrodzie, dotyczący programowania STM32 "na rejestrach". Poradnik przerabiałem chwilę temu, dzięki niemu bardzo dużo się nauczyłem i przesiadka na jakikolwiek mikrokontroler z rodziny STM32 nie stanowi żadnego problemu.
Sam układ jest bardzo ciekawy. Moim największym zaskoczeniem w serii G4 była prędkość taktowania rdzenia,170 MHz, bez użycia rezonatora kwarcowego w układzie w obudowie LQFP32, który kosztuje 4 Euro (w czasie kryzysu). Sam procesor posiada m.in. 3 interfejsy SPI, dzięki czemu LCD oraz kości target i source mogą być na osobnych interfejsach. Korzystając z tego oraz z DMA, podczas zapisu kości zapełniam też bufor (1 sektor- 4 kB) ze źródła, tak aby w momencie kiedy zapis jest zakończony, bufor był wypełniony i zapis następnego sektora może rozpocząć się natychmiastowo. W założeniach miało to przyspieszyć proces zapisu, tak też jest. Szybko okazało się jednak, że czas samego zapisywania kości target jest na tyle długi, iż możliwym był by odczyt następnego sektora ze źródła, aby przygotować już bufor nawet gdyby kości były na jednym interfejsie. Zostałoby jeszcze nawet trochę czasu, aby np. pomigać diodą
Podczas programowania prototypu używałem nawet pamięci w trybie QuadSPI, ale okazało się to kompletnie bez sensu, bo różnice w czasie, ze względu na czas programowania, są znikome. Prędkość zegara SPI dla kości flash to 20 MHz, dla wyświetlacza jest to 40 MHz.
Zastosowany LCD to ILI9341. Bibliotekę do obsługi wyświetlacza znalazłem i zmodyfikowałem dawno temu. Moje zmiany to między innymi obsługa DMA bez HAL. Dodałem także obsługę wyświetlania grafik (tablice generowane przy użyciu Image2Bitmap.exe) oraz obsługę czcionek zaimportowanych z Windowsa poprzez program GLCDFontCreator2 oraz kilka funkcji jak np. progress bary. Jak wspominałem, zrobiłem to dawno i kod bywa brzydki i mało zrozumiały, ale w myśl zasady "jeżeli coś działa, to nie dotykaj", chyba nie bardzo mam ochotę na jakiekolwiek poprawki.
Kość target można zaprogramować z poziomu PC używając dedykowanego programu, który napisałem w Visual Studio. Dane są wysyłane w pakietach 4100 bajtów. 4096 bajtów to jeden sektor, 4 bajty to suma kontrolna, która jest sprawdzana przy każdej transmisji. Wysyłany plik musi mieć taki sam rozmiar jak kość włożona w podstawkę source, jest to sprawdzane przez program, ponieważ informacje o pojemności kości source są wysyłane przy inicjalizacji transmisji. Jeżeli suma kontrolna się nie zgadza, sektor wysyłany jest ponownie, jeżeli suma kontrolna jest ok, sektor jest programowany. Na samym końcu wysyłana jest nazwa pliku oraz suma kontrolna całości. Jeżeli suma kontrolna całości się zgadza, crc32 oraz nazwa pliku jest zapisywana w pamięci flash mikrokontrolera. Przy każdym uruchomieniu kość source jest odczytywana i CRC jest sprawdzane, pozwala to na weryfikację czy pamięć SPI została uszkodzona lub podmieniona. Aby zapisać nowy checksum do mikrokontrolera, kość należy zaprogramować ponownie używając programu na PC. Samo obliczanie sum kontrolnych po stronie programatora odbywa się poprzez sprzętowy blok CRC.
Komunikacja z programatorem odbywa się poprzez wirtualny port COM oparty na układzie MCP2221. Jest to dość stary układ, w obudowie DIP14, jednak na chwilę zamawiania komponentów tylko taki układ był dostępny w rozsądnej cenie. Sporym ograniczeniem jest tutaj prędkość transmisji, maksymalny baudrate to 115200 przez co programowanie kości 8 MB lub większych chwilę trwa. Podczas tworzenia prototypu korzystałem z adaptera opartego na układzie PL2303, gdzie prędkość transmisji to 921600, co bardzo przyspieszało operację zapisu nowego pliku. Sporadycznie przy takiej prędkości pojawiały się błędy przesyłu, jednak sprawdzanie sumy kontrolnej co sektor, sprawia że to nie problem. Ogólnie wolny transfer to nie jest duży kłopot, programatory będą 4, każdy będzie miał wstawiony flash z innym plikiem, więc programowanie będzie odbywało się tylko raz. Gdyby istniała potrzeba używania USB częściej, to dzięki temu że MCP jest w obudowie DIP, można zastosować szybszy mostek zamontowany na adapterze.
Samo programowanie „offline” jak wspominałem wcześniej, opiera się na dwóch buforach wielkości 1 sektora 4096 kB. W momencie zapisywania, gdy dane są pobierane z bufora 1, przeprowadzany jest odczyt kolejnego sektora z kości source poprzez DMA do bufora 2. Po zapisie każdego sektora (stronami po 256 B każda), dane z bufora 2 są zapisywane do kości, zaś bufor 1 zostaje ponownie zapełniony nowymi danymi. Na samym końcu suma kontrolna kości target jest porównywalna z sumą kontrolną zapisaną w pamięci flash mikrokontrolera. Możliwym jest używanie kości o większym rozmiarze jako target, samo CRC jest sprawdzane tylko dla rozmiaru kości source.
Sama płytka jest bardzo prosta, 2-warstwowa ze sporą ilością wolnego miejsca. Same podstawki mogły by być trochę dalej wyświetlacza, w zależności jakiego adaptera używamy, może on być blisko wyświetlacza. Na programatorze znajdują się także podstawki dla pamięci na I2C, nie jest to obecnie używane, z czasem gdy okaże się to potrzebne, dodam ich obsługę. Schemat utworzony był w Altium Designer, jestem na etapie nauki tego programu
Schemat:
Kod źródłowy dla mikrokontrolera dostępny jest na github: https://github.com/perpuchaty/SPI-Programmer
Kod źródłowy dla aplikacji na Windows: https://github.com/perpuchaty/SPI-Programmer-WIN

W związku z tym, że w miejscu w którym pracuję istnieje potrzeba programowania pamięci SPI których wsad jest taki sam, stwierdziłem że zbuduję urządzenie, które będzie kopiowało zawartość jednej kości do drugiej. Niby nic, ale z czasem chciałbym zająć się zawodowo projektowaniem oraz programowaniem mikrokontrolerów, więc jako pierwszy projekt wydaje się to być ciekawym ćwiczeniem, tym bardziej że będzie często używany komercyjnie.
Oczywiście, można używać programatora/programatorów do masowej produkcji, ale tutaj mamy jedną płytkę, która nie wymaga podłączania do PC i uruchamiania czegokolwiek. Przyłączamy dwie kości, wciskamy przycisk i to tyle. Prędkość zapisywania kości jest taka sama jak w przypadku np. programatora RT809.
Jest to też w sumie mój pierwszy projekt, który ukończyłem na tyle, że nadaje się do publikacji, choć jeszcze nie jest zrobiony w 100%

Jako procesor wykorzystałem STM32G431KBT6. Cały projekt stworzony jest w STM32CubeIDE z wykorzystaniem CMSIS, bez użycia HAL. W tym miejscu bardzo chciałbym podziękować koledze, który stworzył poradnik, który znaleźć można na elektrodzie, dotyczący programowania STM32 "na rejestrach". Poradnik przerabiałem chwilę temu, dzięki niemu bardzo dużo się nauczyłem i przesiadka na jakikolwiek mikrokontroler z rodziny STM32 nie stanowi żadnego problemu.
Sam układ jest bardzo ciekawy. Moim największym zaskoczeniem w serii G4 była prędkość taktowania rdzenia,170 MHz, bez użycia rezonatora kwarcowego w układzie w obudowie LQFP32, który kosztuje 4 Euro (w czasie kryzysu). Sam procesor posiada m.in. 3 interfejsy SPI, dzięki czemu LCD oraz kości target i source mogą być na osobnych interfejsach. Korzystając z tego oraz z DMA, podczas zapisu kości zapełniam też bufor (1 sektor- 4 kB) ze źródła, tak aby w momencie kiedy zapis jest zakończony, bufor był wypełniony i zapis następnego sektora może rozpocząć się natychmiastowo. W założeniach miało to przyspieszyć proces zapisu, tak też jest. Szybko okazało się jednak, że czas samego zapisywania kości target jest na tyle długi, iż możliwym był by odczyt następnego sektora ze źródła, aby przygotować już bufor nawet gdyby kości były na jednym interfejsie. Zostałoby jeszcze nawet trochę czasu, aby np. pomigać diodą

Zastosowany LCD to ILI9341. Bibliotekę do obsługi wyświetlacza znalazłem i zmodyfikowałem dawno temu. Moje zmiany to między innymi obsługa DMA bez HAL. Dodałem także obsługę wyświetlania grafik (tablice generowane przy użyciu Image2Bitmap.exe) oraz obsługę czcionek zaimportowanych z Windowsa poprzez program GLCDFontCreator2 oraz kilka funkcji jak np. progress bary. Jak wspominałem, zrobiłem to dawno i kod bywa brzydki i mało zrozumiały, ale w myśl zasady "jeżeli coś działa, to nie dotykaj", chyba nie bardzo mam ochotę na jakiekolwiek poprawki.
Kość target można zaprogramować z poziomu PC używając dedykowanego programu, który napisałem w Visual Studio. Dane są wysyłane w pakietach 4100 bajtów. 4096 bajtów to jeden sektor, 4 bajty to suma kontrolna, która jest sprawdzana przy każdej transmisji. Wysyłany plik musi mieć taki sam rozmiar jak kość włożona w podstawkę source, jest to sprawdzane przez program, ponieważ informacje o pojemności kości source są wysyłane przy inicjalizacji transmisji. Jeżeli suma kontrolna się nie zgadza, sektor wysyłany jest ponownie, jeżeli suma kontrolna jest ok, sektor jest programowany. Na samym końcu wysyłana jest nazwa pliku oraz suma kontrolna całości. Jeżeli suma kontrolna całości się zgadza, crc32 oraz nazwa pliku jest zapisywana w pamięci flash mikrokontrolera. Przy każdym uruchomieniu kość source jest odczytywana i CRC jest sprawdzane, pozwala to na weryfikację czy pamięć SPI została uszkodzona lub podmieniona. Aby zapisać nowy checksum do mikrokontrolera, kość należy zaprogramować ponownie używając programu na PC. Samo obliczanie sum kontrolnych po stronie programatora odbywa się poprzez sprzętowy blok CRC.
Komunikacja z programatorem odbywa się poprzez wirtualny port COM oparty na układzie MCP2221. Jest to dość stary układ, w obudowie DIP14, jednak na chwilę zamawiania komponentów tylko taki układ był dostępny w rozsądnej cenie. Sporym ograniczeniem jest tutaj prędkość transmisji, maksymalny baudrate to 115200 przez co programowanie kości 8 MB lub większych chwilę trwa. Podczas tworzenia prototypu korzystałem z adaptera opartego na układzie PL2303, gdzie prędkość transmisji to 921600, co bardzo przyspieszało operację zapisu nowego pliku. Sporadycznie przy takiej prędkości pojawiały się błędy przesyłu, jednak sprawdzanie sumy kontrolnej co sektor, sprawia że to nie problem. Ogólnie wolny transfer to nie jest duży kłopot, programatory będą 4, każdy będzie miał wstawiony flash z innym plikiem, więc programowanie będzie odbywało się tylko raz. Gdyby istniała potrzeba używania USB częściej, to dzięki temu że MCP jest w obudowie DIP, można zastosować szybszy mostek zamontowany na adapterze.
Samo programowanie „offline” jak wspominałem wcześniej, opiera się na dwóch buforach wielkości 1 sektora 4096 kB. W momencie zapisywania, gdy dane są pobierane z bufora 1, przeprowadzany jest odczyt kolejnego sektora z kości source poprzez DMA do bufora 2. Po zapisie każdego sektora (stronami po 256 B każda), dane z bufora 2 są zapisywane do kości, zaś bufor 1 zostaje ponownie zapełniony nowymi danymi. Na samym końcu suma kontrolna kości target jest porównywalna z sumą kontrolną zapisaną w pamięci flash mikrokontrolera. Możliwym jest używanie kości o większym rozmiarze jako target, samo CRC jest sprawdzane tylko dla rozmiaru kości source.
Sama płytka jest bardzo prosta, 2-warstwowa ze sporą ilością wolnego miejsca. Same podstawki mogły by być trochę dalej wyświetlacza, w zależności jakiego adaptera używamy, może on być blisko wyświetlacza. Na programatorze znajdują się także podstawki dla pamięci na I2C, nie jest to obecnie używane, z czasem gdy okaże się to potrzebne, dodam ich obsługę. Schemat utworzony był w Altium Designer, jestem na etapie nauki tego programu





Schemat:


Kod źródłowy dla mikrokontrolera dostępny jest na github: https://github.com/perpuchaty/SPI-Programmer
Kod źródłowy dla aplikacji na Windows: https://github.com/perpuchaty/SPI-Programmer-WIN
Cool? Ranking DIY