No cóż. Jak widać zainteresowanie tematem jest dość skromne, jakby nikt nigdy tego nie robił lub była to jakaś wielka tajemnica. Poradziłem sobie sam.
Podziękowania dla movzx za to, że w ogóle podjął jakąkolwiek próbę i dyskusję.
Postanowilem zamieścić na forum kilka uwag w tym temacie. Nie będę tutaj wszystkiego dokładnie opisywał bo nie ma to najmniejszego sensu skoro nie ma większego zainteresowania, a pisać jest o czym.
Moim celem było podłączenie pojedynczego układu pamięci SDRAM do mikrokontrolera z rodziny AVR. Układ pamięci został wylutowany z całej kości pamięci do PC'ta [jeśli ktoś ma zdolności to powiem że idzie wylutować zwykłą transformatorówką bez uszkadzania układu i wlutować we własną elektronikę tym samym sposobem, ale to tak na marginesie dla tych którzy sądzą że do tego potrzeba stacji na gorące powietrze, którą nie każdy ma].
Układ pamięci to: HY57V658020B
Procesor: Atmega128
Układ pamięci powinien być łatwo dostępny bo był jednym z najczęsciej powtarzających się układów na kościach które posiadam. Procesor został wybrany nie przypadkowo, pojemność pamięci również. Są one obecnie częścią wiekszej płyty i to na tej większej płycie przy okazji SDRAM został wypróbowany.
Warto również zapoznać się z opisem układów tej serii MT48LC4M4A1. Opisy są dość dokładne z wykresami czasowymi i opis ten jest dość zgodny z układem, który ja użyłem.
Jeśli chodzi o moje uwagi to po pierwsze proces inicjalizacji pamięci powinien przebiegać według określonych regul i nie powinien od nich odbiegać, bo potem rozmowa z pamięcią będzie nie możliwa [proces inicjalizacji widoczny na wykresach w opisie powyższego układu].
Ważne jest odpowiednie skonfigurowanie rejestru pamięci bo od tego będzie zależało w jaki sposób dogadamy się z pamięcią.
Taktowanie. Wyjście clk można traktować jako wyjście synchronizacyjne, czyli nie jest konieczny nieustanny i stabilny cykl zegarowy na tym wyjściu.
Odświeżanie. Pamięć SDRAM niestety wymaga odświeżania, ale są też dobre wiadomości. Dostępne są dwa tryby AUTO-REFRESH i SELF-REFRESH. Rozsądne wydawanie tych komend zapewnia odpowiednie odświeżanie. Jeśli mamy pamięć taką jak moja to musimy odświeżyć 4096 wierszy w 64ms czyli średnio jeden wiersz co 15.625us. Nie jest to takie staszne
, ponieważ mamy tryb SELF-REFRESH. Jeśli pracujemy z pamięcią np. odczytujemy i zapisujemy itp i cykl tych działań nie trwa dłużej niż 15.625us to po zakończonej pracy spokojnie możemy wydać komende SELF-REFRESH i przestać się martwić o odświeżanie. Jeśli zaś działania trwają dłużej, bo np. odczytywaliśmy cały wiersz to wtedy musimy wydać odpowiednią ilość komend AUTO-REFRESH. Czyli jeśli działania trwały 10us to wydajemy SELF-REFRESH i po sprawie. Jeśli trwały 300us to wydajemy komende AUTO-REFRESH min ok 20-22 (300us/15us). Wydawanie tych komend wbrew pozorom nie zajmuje nam wiele cykli procesora, gdyż przy wolnym zegarze do 16MHz nie musimy się martwić zbyt mocno o opóźnienia wynikające z działania samej pamięci. Oznacza to, że raz ustawiamy komende AUTO-REFRESH a potem generujemy 20-22 cykle zegara dla pamięci i problem z głowy. Potem wydajemy komende SELF-REFRESH i przestajemy się martwić o cokolwiek.
Czas odczytu i zapisu. Niestety SDRAM z tego co się orientuje nie jest obsługiwany przez AVRy, bo i po co miałby być skoro taki Atmega przewiduje zaledwie 64kB... więc taki sterownik musi być sterownikiem programowym lub sprzętowym jeśli takowy zrobimy. W moim przypadku sterownik jest programowy. Podłączenie pamięci i procesora niestety nie jest zbyt logiczne
więc niektóre operacje są dłuższe niż w normalnie być powinny [np. linie A0-A11 wiszą na 3 portach i jeszcze w dodatku porozrzucane]. Prawidłowe i LOGICZNE rozmieszczenie SDRAMu może przyspieszyć troszkę czasy odczytu i zapisu. Niewątpliwie jednak najkorzystniej wypada odczyt większymi porcjami danych [podobnie zapis]. W moim przypadku [tym przypadku gdzie porty są porozwalane
] odczyt i zapis porcji 8 bajtów był na poziomie ok 26 cykli zegara na bajt, czyli dość sporo. Jednak w urządzeniu, który składam najlepiej dane wczytywać większymi partiami, a nawet całymi wierszami. W takim przypadku odczyt i zapis jest znacznie szybszy wychodzi średnio zaledwie 7.8 cykla na bajt. Jest to wynik nienajgorszy i mnie osobiście zadawala. Podsumowując: najbardziej opłaca się wczytywać dane większymi porcjami i od razu lepiej przemyśleć architekturę urządzenia, które składamy, pod względem samej pamięci.
Inne moje uwagi to:
Przerywania. Ważne żeby nie zapomnieć o WYŁĄCZENIU przerwań podczas odczytu i zapisu do pamięci. Nie może być tak, że program odczytuje z pamięci i nagle dostaje przerywanie które również zamierza korzystać z pamięci lub nie będzie korzystać ale np. będzie się wykonywało 200us. Na czas odczytu i zapisu przerywania powinny być wyłączone, chyba że ktoś odważny napisze przerywanie w taki sposób że będzie potrafiło przywrócić aktualny stan procesu odczytu/zapisu co może być nieco skomplikowane.
Napięcie zasilania. Niestety SDRAM raczej nie pójdzie chętnie ze zbyt wysokiego napięcia. Mój ma przedział 3.3V - 4.6V. Jeśli procesor będzie szedł z tym samym napięciem co pamięć i napięcie będzie w tych granicach to nie ma problemu. Niestety w moim przypadku pamięć biegnie z napięciem 3.8V a procesor 5V. W takim przypadku zalecam stosowanie oporników nie mniejszych niż 42 Ohm [tak gdzieś podali]. Przy niższych napięciach pamięci rzędu 3.3V i 5V procek może być konieczne zastosowanie bufora, bo może być problem z rozróżnianiem stanów przez procesor. W moim przypadku zapobiegawczo znalazł się bufor [nie chciałem dwukrotnie trawić płytki
]
Cóż jeszcze można dodać? Chyba warto jeszcze wziąć pod uwagę plusy i minusy takiego rozwiązania.
Do minusów niewątpliwie należy:
- Konieczność napisania własnego sterownika [w moim przypadku kod powstawał w C ale operacje na pamięci to wstawki asm]
- Trochę zabawy z testowaniem
- Nie zbyt szybkie odczyty przy małych porcjach danych i średnie [jak dla mnie] odczyty dla dużych porcji danych, czyli coś za coś, mało i długo kontra szybko i dużo
- Nie zbyt przyjemny sposób adresowania, który nie pozwala na traktowanie pamięci jako ciągłości bajtów
- Konieczność dbania o prawidłowe odświeżanie podczas pisania funkcji współpracujących z pamięcią
- Mało literatury w tej sprawie, a po polsku w sumie w ogóle nie ma nic sensownego
Do plusów można zaliczyć:
- Cena... w wielu przypadkach to 0zł za całe kość
- Duża pojemność
- W zależności od zastosowania warto się pobawić. W moim przypadku SDRAM służy jako bufor dla większej ilości danych [rzędu nawet kilku GB], które mogą napływać w różnych odstępach czasu a przetwarzane muszą być w równych odstępach... i co najważniejsze mogę bez problemu posługiwać się całymi wierszami
i większą ilością na raz, więc będę miał te krótsze czasy odczytu.
No cóż... plusów wydaje się mniej, niemniej jednak pobawić się zawsze można. Łącząc SDRAM i SRAM [nawet głupie 4KB wewnątrz Atmega128] można uzyskać więcej pamięci niskim kosztem i o wystarczająco wysokiej wydajności, bo przecież czasami taki większy bufor może się przydać kiedy robimy sterownik do jakiejś maszyny. Wówczas w buforze możemy przechowywać dane z komputera itd itd itd...
W moim przypadku był to dobry wybór.
Pozdrawiam.
PS. tylko nie krytykujcie, bo chętnych do wypowiedzienia się w tej sprawie było wieeeeeeeeeeelu... trzy dni liczyć można... ale ludzi, którzy skrytykują pewnie nie zabraknie hehe