Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

SPI Clone - programator kości SPI

XS_Sowa 05 Jan 2023 13:11 2493 8
Altium Designer Computer Controls
  • 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% :P


    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 :)

    SPI Clone - programator kości SPI SPI Clone - programator kości SPI SPI Clone - programator kości SPI
    SPI Clone - programator kości SPI



    Schemat:
    SPI Clone - programator kości SPI
    SPI Clone - programator kości SPI

    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
    About Author
    XS_Sowa
    Level 13  
    Offline 
    Has specialization in: konsole, serwis laptopy, serwis apple
    XS_Sowa wrote 82 posts with rating 57, helped 6 times. Live in city Rotterdam. Been with us since 2014 year.
  • Altium Designer Computer Controls
  • #2
    ArturAVS
    Moderator HP/Truck/Electric
    Fajne! Są jakieś ograniczenia co do maksymalnej pojemności pamięci?
  • Altium Designer Computer Controls
  • #3
    tmf
    Moderator of Microcontroller designs
    Na wstępie gratuluję projektu, bardzo dobry. Tu nie ma jakiejś pomyłki?
    XS_Sowa wrote:
    Prędkość zegara SPI dla kości flash to 40 MHz, dla wyświetlacza jest to 80 MHz.


    Dla ILI9341 w trybie SPI 4-przewodowym okres zegara SPI to co najmniej 100 ns, a więc maksymalne taktowanie to 10 MHz. Piszesz, że masz 80 MHz, co jest jakby nierealne.
  • #4
    XS_Sowa
    Level 13  
    Quote:
    Fajne! Są jakieś ograniczenia co do maksymalnej pojemności pamięci?

    Dziękuje :) Kości powyżej 128 Mb wymagają dodatkowego bajtu przy adresowaniu, więc sprzętowo nie jest to ograniczenie, sam soft wymagał by ewentualnej przeróbki.

    Quote:
    Dla ILI9341 w trybie SPI 4-przewodowym okres zegara SPI to co najmniej 100 ns, a więc maksymalne taktowanie to 10 MHz. Piszesz, że masz 80 MHz, co jest jakby nierealne.

    Ogólnie ten wyświetlacz jest podatny na "overclocking" :) Ale tak, masz rację, popełniłem błąd w opisie i zegar SPI to 160 MHz/4 = 40 MHz.
  • #5
    ArturAVS
    Moderator HP/Truck/Electric
    tmf wrote:
    Piszesz, że masz 80 MHz, co jest jakby nierealne

    Też mnie to zaskoczyło :D Swoją drogą po co aż taki szybki zegar dla LCD? Przecież praktycznie wyświetla statyczny obraz.
  • #6
    XS_Sowa
    Level 13  
    Zgadza się, jednak przy wszelkich zmianach, czy to tekstu lub progress barów, przy wolniejszych zegarach mimo wszystko widać "w którym kierunku" obraz jest generowany. A że pobór prądu mnie nie interesuje w przypadku zasilania po USB, to rozkręciłem zegar jak to tylko było możliwe, co by user experience było na najwyższym poziomie :)
  • #7
    tmf
    Moderator of Microcontroller designs
    Jak ci to z nieznanych powodów przestanie w pewnym momencie działać to user experience będzie super :)
    Dla katalogowego taktowania 10 MHz, masz transfer rzędu 1,25 MB/s. Aż nadto, aby absolutnie płynnie wyświetlać fragmenty obrazu typu progress bar. Jeśli tak nie jest, to znaczy że masz coś nie tak z obsługą transmisji/tworzeniem grafiki. Kupiony LCD zapewne nie ma wyprowadzonego TE, żeby się zsynchronizować z tworzeniem ramki?
    Inna sprawa, że masz tyle wolnych pinów IO, że jeśli chcesz wyświetlać filmy na tym LCD podczas kopiowania wsadu, to możesz ten LCD podłączyć poprzez interfejs równoległy.
  • #8
    ArturAVS
    Moderator HP/Truck/Electric
    tmf wrote:
    to możesz ten LCD podłączyć poprzez interfejs równoległy.

    W tej wersji tylko SPI, mam kilka takich.
  • #9
    XS_Sowa
    Level 13  
    Quote:
    Jak ci to z nieznanych powodów przestanie w pewnym momencie działać to user experience będzie super :)
    Dla katalogowego taktowania 10 MHz, masz transfer rzędu 1,25 MB/s. Aż nadto, aby absolutnie płynnie wyświetlać fragmenty obrazu typu progress bar. Jeśli tak nie jest, to znaczy że masz coś nie tak z obsługą transmisji/tworzeniem grafiki. Kupiony LCD zapewne nie ma wyprowadzonego TE, żeby się zsynchronizować z tworzeniem ramki?
    Inna sprawa, że masz tyle wolnych pinów IO, że jeśli chcesz wyświetlać filmy na tym LCD podczas kopiowania wsadu, to możesz ten LCD podłączyć poprzez interfejs równoległy.

    Przy tak małych elementach fakt, nie ma wielkiej różnicy (choć w innym projekcie, w przypadku większej czcionki o wysokości 100 pixeli lub wypełniania kolorem jest to już bardziej widoczne), możliwe że ktoś nawet by tego nie zauważył a tylko ja jestem przeczulony. Tak czy siak, testowałem ten LCD na tej prędkości długi czas, nigdy nie miałem żadnych dziwnych problemów, ale na pewno będę miał to na uwadze, gdy coś nieprzewidzianego się zdarzy :) Sam LCD, jak wspomniał kolega ArturAVS, ma wyprowadzony tylko i wyłącznie interfejs SPI.