„Stare” pamięci dynamiczne SIMM30 z czasów komputerów PC klasy i386/i486 i PENTIUM. Któż z nas nie stanął w świecie mikrokontrolerów przed problemem braku pamięci RAM. Oto bardzo proste i tanie rozwiązanie. Okazuje się, że obsługa popularnych niegdyś modułów pamięci SIMM jest bardzo prosta a moduły tanie.

Oczywiście, nie jest tak, że pamięci te to same zalety, posiadają także wady. Nie mniej jednak, w zastosowaniach mikrokontrolerowych spisują się świetnie.

Rzućmy więc okiem na pewne cechy tych modułów pod kontem wykorzystania ich w świecie mikrokontrolerów.

Zalety:

  • Niska cena
  • Łatwość użycia (zaledwie trzy sygnały sterujące)
  • „Olbrzymia” pojemność (od 256KB do 16MB na moduł)
  • Możliwość łączenia „dowolnej” liczby modułów, zwiększając ilość dostępnej w ten sposób pamięci

Wady:

  • Praca w domenie napięciowej 5V
  • Konieczność odświeżania zawartości
  • „Duża” bryła samego modułu
  • Coraz większy problem z dostępnością

Skoro można w prosty sposób wyposażyć nasz mikrokontroler w taką pamięć i zapewnić jej sprawną obsługę, to można wysnuć (słuszny) wniosek, iż wymienione tu wady, można sprowadzić w większości wypadków do zaledwie drobnych uciążliwości.

Piny modułu SIMM30

Jak widać na powyższym rysunku, podłączenie modułu do mikrokontrolera, nie jest specjalnie problematyczne. Jeśli nasz mikrokontroler pracuje w domenie napięciowej 5V, możemy moduł pamięci podłączyć bezpośrednio do mikrokontrolera. Jeśli jednak nasz mikrokontroler pracuje w domenie 3,3V, bezpośrednio możemy połączyć magistrale adresową oraz sterującą. W przypadku magistrali danych, musimy zapewnić odpowiednią konwersję poziomów tych sygnałów.

Podłączenie modułu do mikrokontrolera.

Aby podłączyć moduł do mikrokontrolera należy podłączyć 3 magistrale:

  1. Magistrala danych. Jest to dwukierunkowa – trójstanowa magistrala umożlwiająca zarówno odczyt z pamięci, jak i zapis do pamięci. Zgodność bitów na tej magistrali nie musi być zachowana z bitami portu mikrokontrolera, podłączamy ją tak, jak nam najwygodniej poprowadzić ścieżki. Gdy używamy mikrokontrolera pracującego z sygnałami w innym standardzie, niż TTL 5V, musimy na liniach tej magistrali zastosować konwertery poziomów napięć.
  2. Magistrala adresowa. Jest to jednokierunkowa magistrala umożliwiająca wybór adresu pamięci z którego będziemy odczytywać, bądź pod który będziemy zapisywać dane. Nie musimy wykorzystywać pełnej szerokości tej magistrali, ale tutaj zgodność bitowa musi być zachowana. Pamięci SIMM30 posiadają 12 linii adresowych oznaczonych od A0 do A11. Podłączając tę magistralę do mikrokontrolera, możemy podłączyć dowolną ilość jej linii, ale poczynając od linii A0 wzwyż. Linię A0 należy też podłączyć pod bit 0 magistrali adresowej mikrokontrolera.
  3. Magistrala sterująca. Jest to jednokierunkowa magistrala umożliwiająca sterowanie modułem/modułami pamięci SIMM30. W skład tej magistrali wchodzą 3 linie: /WR, /CAS, /RAS. Linie te służą do:
  • /WR (WRite): stan tej linii umożliwia wybór operacji. ZAPIS lub ODCZYT.
  • /CAS (Column Address Save): Stan niski na tej linii powoduje zatrzaśnięcie w pamięci adresu kolumny wybieranego adresu.
  • /RAS (Row Address Save): Stan niski na tej linii powoduje zatrzaśnięcie w pamięci adresu wiersza wybieranego adresu.

Wszystkie linie tej magistrali muszą być podłączone do mikrokontrolera.

Sposób podłączenia modułu SIMM30 do mikrokontrolera pokazano na rysunku poniżej:

Zwiększając ilość użytych modułów, zwiększamy dostępną pojemność pamięci.

Moduły pamięci SIMM30 są modułami 8 bitowymi. Używając wielu modułów, zwiększamy ilość dostępnej pamięci, która wypadkowo jest sumą wszystkich użytych modułów. Większą ilość modułów możemy do mikrokontrolera podłączyć na 3 sposoby:

  1. Zwiększając dostępną pamięć w organizacji 8 bitowej. Przy takim podłączeniu, moduły mogą być różnej pojemności.
  2. Rozszerzając szerokość magistrali danych o wielokrotność liczby 8. Wszystkie moduły składające się na magistralę danych powinny być tej samej pojemności i organizacji (takie same). Jeśli nie zapewnimy tego warunku, dostępna ilość pamięci będzie wielokrotnością najmniej pojemnego modułu z zestawu.

    (OT) Właśnie dlatego komputery klasy i486 wymagały minimum 4 takich samych modułów SIMM, gdyż ich szyna danych miała szerokość 32 bitów. Komputery klasy i386, wymagały obsadzania banków pamięci dwójkami, gdyż ich zewnętrzna szyna danych była 16 bitowa.
  3. Rozszerzając zarówno szerokość szyny danych jak i zwiększając ilość dostępnej pamięci. W tym wypadku, ilość modułów potrzebnych do osiągnięcia żądanej szerokości magistrali danych powinna być jednakowa. Innymi słowy, jeśli rozszerzamy szerokość magistrali do 16 bitów, to moduły powinny być dobierane parami (1 para identycznych kości, 2 para identycznych kości, aczkolwiek nie koniecznie takich samych jak w parze 1, itd…).

Poniższe kilka rysunków przedstawia sposób podłączenia modułów na różne sposoby:

Podłączenie wielu modułów o szerokości magistrali danych 8 bitów

Podłączenie dwóch modułów do 16 bitowej magistrali danych

Podłączenie czterech modułów do 16 bitowej magistrali danych.


Płytka testowa

W celu przetestowania współpracy z pamięciami SIMM30, przygotowałem sobie płytkę PCB, obsługującą do 4 modułów SIMM30 w konfiguracji ośmiobitowej magistrali danych. Schemat do wykonania płytki wygląda następująco:

Jeśli ktoś chciałby sobie wykonać podobną płytkę, poniżej znajduje się projekt dla programu KiCAD.


Sterowanie

Sterowanie sygnałami w celu obsługi pamięci dynamicznej SIMM30 prezentują poniższe przebiegi czasowe. Zaprezentowane są na nich trzy operacje wykonywane na pamięci: zapis bajtu, odczyt bajtu i odświeżanie zawartości. W prezentowanej bibliotece nie jest wykorzystywany wspierany przez większość modułów tryb BRUST. Dlatego nie będziemy go tutaj prezentować.

Cykl odczytu

Opis słowny pseudo kodem:

  1. Ustawiamy na magistrali adresowej adres wiersza
  2. Zmieniamy stan linii RAS na niski
  3. Zmieniamy stan linii WR na wysoki
  4. Ustawiamy na magistrali adresowej adres kolumny
  5. Zmieniamy stan linii CAS na niski
  6. Odczytujemy bajt z magistrali danych
  7. Zmieniamy stan linii CAS i RAS na wysoki

Cykl zapisu

Opis słowny pseudo kodem:

  1. Ustawiamy na magistrali adresowej adres wiersza
  2. Zmieniamy stan linii RAS na niski
  3. Ustawiamy na linii WR stan niski.
  4. Ustawiamy kierunek magistrali danych na wyjściowy
  5. Ustawiamy na magistrali danych bajt do zapisania
  6. Ustawiamy na magistrali adresowej adres kolumny
  7. Zmieniamy stan linii CAS na niski
  8. Zmieniamy stan linii CAS i RAS na wysoki
  9. Zmieniamy kierunek magistrali danych na wejściowy

Cykl odświeżania pamięci

Opis słowny pseudo kodem.

Zauważmy, że przy operacji zapisu i odczytu, najpierw ustawiamy adres wiersza. Co za tym idzie przy zmianie linii RAS na niski, stan linii CAS jest wysoki. Jeśli jednak przy zmianie linii RAS na niski, stan linii CAS także będzie niski, pamięć wykona cykl odświeżania jednego bitu. Dlatego aby odświeżyć zawartość pamięci należy wykonać następujące kroki:

  1. Powtórz 32 razy:
    • Zmieniamy stan linii CAS na niski
      • Powtórz 8 razy:
        • Zmieniamy stan linii RAS na niski
        • Zmieniamy stan liniii RAS na wysoki
    • Zmieniamy stan linii CAS na wysoki

Oprogramowanie

Wersja dla języka C

Biblioteka dla języka C składa się z dwóch plików. Pliku nagłówkowego simm30.h oraz pliku kodu simm30.c. Biblioteka ta obsługuje do 8 modułów pamięci SIMM z wykorzystaniem 8 bitowej magistrali danych. Najmniejszą jednostką transmisji danych z/do pamięci jest bajt. Biblioteka jest uniwersalna, a to oznacza, że funkcje niskopoziomowe dostępu do wykorzystywanych pinów mikrokontrolera musi dostarczyć użytkownik.

Funkcje udostępniane przez bibliotekę:


simm30init

void simm30init (uint8_t Count, void(*setAddress)(uint16_t), void(*setWR)(_Bool), void(*setDataDir)(_Bool), void(*setData)(uint8_t), uint8_t(*getData)(), void(*setCAS)(uint8_t), void(*setRAS)(uint8_t));

Opis:
Funkcja inicjuje bibliotekę obsługi modułów SIMM30.

Parametry:
uint8_t Count – Ilość podłączonych modułów, od 0 do 8.
void(*setAddress)(uint16_t) – Wskaźnik na funkcję użytkownika ustawiającą podany adres na pinach adresowych.
void(*setWR)(_Bool) – Wskaźnik na funkcję użytkownika, która ustawia stan linii WR w stan niski (dla argumentu false) i w stan wysoki (dla argumentu true).
void(*setDataDir)(_Bool) – wskaźnik na funkcję użytkownika, która ustala kierunek magistrali danych. Dla argumentu false – jako wejście, dla true – jako wyjście.
void(*setData)(uint8_t) – Wskaźnik na funkcję użytkownika, która ma za zadanie na magistrali danych wystawić wartość argumentu.
uint8_t(*getData)() – Wskaźnik na funkcję użytkownika, która ma za zadanie zwrócić odczytaną z magistrali danych wartość.
void(*setCAS)(uint8_t) – Wskaźnik na funkcję użytkownika, która ma za zadanie ustalić stan poszczególnych linii CAS. Najmłodszy bit odpowiada za linię CAS do pierwszego modułu. Wartość bitu 1 ustala linię w stan wysoki, wartość 0 w stan niski.
void(*setRAS)(uint8_t) – Wskaźnik na funkcję użytkownika, która ma za zadanie ustalić stan poszczególnych linii RAS. Najmłodszy bit odpowiada za linię RAS do pierwszego modułu. Wartość bitu 1 ustala linię w stan wysoki, wartość 0 w stan niski.

Zwracana wartość:
Niedotyczy.


simm30detect

struct TSIMM30UNIT simm30detect (uint8_t Unit);

Opis:
Funkcja dokonuje rozpoznania pojemności i struktury podłączonych modułów.

Parametry:
uint8_t Unit – Numer modułu do przetestowania. dozwolone wartości z zakresu od 0 do 8. Podanie wartości 0 sprawdza wszystkie podłączone moduły w tym wypadku zwracane są dane ostatniego modułu.

Zwracana wartość:
Charakterystyka badanego modułu w postaci struktury:

struct TSIMM30UNIT {
   uint16_t ROWS;
   uint16_t COLS;
   uint32_t CAPACITY;
   uint32_t BASE;
   _Bool ERRORS;
}

Znaczenie pól struktury TSIMM30UNIT:

uint16_t ROWS – Ilość wierszy w module.
uint16_t COLS – Ilość kolumn w module.
uint32_t CAPACITY – Pojemność modułu w bajtach.
uint32_t BASE – Adres bazowy modułu. Czyli adres pierwszego bajtu w ciągłej przestrzeni adresowej.
_Bool – Jeśli true – moduł zawiera błędy, jeśli false – wszystkie komórki modułu są sprawne.


simm30check

struct TSIMM30UNIT simm30check (uint8_t Num; void(*CHECK)(_Bool, uint32_t), uint32_t PERIOD);

Opis:
Funkcja dokonuje sprawdzenia każdej komórki wskazanego modułu lub wszystkich modułów. Co określoną ilość sprawdzonych komórek wywołać funkcję zwrotną użytkownika z bieżącym statusem sprawdzania.

Parametry:
int8_t Num – Numer modułu do sprawdzenia. Wartość z zakresu od 0 do 8. Gdy poda się wartość 0, sprawdzane są wszystkie moduły a przestrzeń adresowa traktowana jest jak ciągły obszar.
void(*CHECK)(_Bool, uint32_t) – wskaźnik na funkcję użytkownika, która będzie cyklicznie wywoływana podczas przeprowadzania testu. Jeśli pierwszy parametr ma wartość TRUE, oznacza to, iż w module wykryto błędy. Drugi argument informuje o tym, ile bajtów przetestowano. Podanie wartości NULL wyłącza obsługę funkcji zwrotnej.
uint32_t PERIOD – co ile bajtów należy wywoływać funkcję użytkownika. Podanie wartości 0 wyłącza obsługę funkcji zwrotnej.

Zwracana wartość:
Charakterystyka badanego modułu w postaci struktury TSIMM30UNIT. Jeśli jako numer modułu podano 0, charakterystyka dotyczy ostatniego modułu.


simm30getInfo

struct TSIMM30UNIT getInfo (uint8_t Unit);

Opis:
Zwraca informacje o module.

Parametry:
uint8_t Unit – Numer modułu, którego informacji żądamy. Wartość od 1 do 8.

Zwracana wartość:
Parametry modułu w postaci struktury TSIMM30UNIT.


simm30getTotal

uint32_t simm30getTotal ();

Opis:
Funkcja wraca całkowitą pojemność podłączonej pamięci uwzględniając uszkodzone moduły.

Parametry:
Brak

Zwracana wartość:
Ilość całkowitej pamięci podłączonej do mikrokontrolera obniżonej o objętość uszkodzonych modułów.


simm30refresh ()

void simm30refresh ();

Opis:
Funkcja dokonuje odświeżenia zawartości pamięci wszystkich modułów. Należy ją uruchomiać nie rzadziej, niż co 60ms. W przeciwnym razie może dojść do uszkodzenia zawartości pamięci.

Paramatery:
Brak

Zwracana wartość:
Nie dotyczy


simm30writeByte

void simm30writeByte (uint32_t Address, uint8_t Data);

Opis:
Funkcja zapisuje pod wskazany adres podaną wartość.

Parametry:
uint32_t Address – Adres, pod jaki dokonujemy zapisu. Obliczenie numeru modułu i adresu w module uwzględnia wyłączenie uszkodzonych modułów.
uint8_t Data – Bajt, do zapisania w pamięci.

Zwracana wartość:
Nie dotyczy


simm30writeWord

void simm30writeWord (uint32_t Address, uint16_t Data);

Opis:
Funkcja zapisuje pod wskazany adres podaną wartość.

Parametry:
uint32_t Address – Adres, pod jaki dokonujemy zapisu. Obliczenie numeru modułu i adresu w module uwzględnia wyłączenie uszkodzonych modułów.
uint16_t Data – Słowo, do zapisania w pamięci. Młodsza połówka zapisywana jest pod adresem Address, starsza pod adresem Address + 1. Jeśli Address wskazuje ostatnią dostępną komórkę, starszy bajt zostanie zapisany pod adresem 0.

Zwracana wartość:
Nie dotyczy


simm30writeBlock

void simm30writeBlock (const uint8_t* Source, uint32_t Destination, size_t Count);

Opis:
Funkcja Przepisuje blok pamięci z pamięci RAM mikrokontrolera do pamięci SIMM30. Jeśli podczas przepisywania zostanie osiągnięty ostatni dostępny bajt, reszta bloku zostanie przepisana od adresu 0.

Parametry:
const uint8_t* Source = Wskaźnik na dane do przepisania.
uint32_t Destination – Adres pod jaki należy zapisać blok.
size_t Count – Ilość bajtów do przepisania.

Zwracana wartość:
Nie dotyczy


simm30readByte

uint8_t simm30readByte (uint32_t Address);

Opis:
Funkcja odczytuje bajt danych z pod podanego adresu.

Parametry:
uint32_t Address – Adres z pod którego należy odczytać bajt danych.

Zwracana wartość:
uint8_t – Odczytany z pamięci bajt.


simm30readWord

uint16_t simm30readWord (uint32_t Address);

Opis:
Funkcja odczytuje słowo danych z pod podanego adresu.

Parametry:
uint32_t Address – Adres z pod którego należy odczytać słowo danych.

Zwracana wartość:
uint16_t – Odczytane z pamięci słowo. Młodszy bajt odczytany jest z pod adresu Address, starszy z pod adresu Address + 1. Jeśli podany adres wskazuje na ostatnią komórkę, do starszy bajt będzie odczytany z pod adresu 0.

Zwracana wartość:
Nie dotyczy.


simm30readBlock

void simm30readBlock (uint32_t Source, uint8_t* Destination, size_t Count);

Opis:
Funkcja przepisuje z pamięci zewnętrznej do pamięci RAM mikrokontrolera blok danych. Jeśli podczas przepisywania osiągnięta zostanie ostatnia komórka pamięci, dalsza część bloku zostanie przepisana z pod adresu 0.

Parametry:
uint32_t Source – Adres w pamięci zewnętrznej z pod którego należy przepisać dane.
uint8_t* Destination – Wskaźnik na obszar pamięci RAM, pod które należy przepisać dane.
size_t Count – Ilość bajtów, które należy przepisać.

Zwracana wartość:
Nie dotyczy.


simm30copy

void simm30copy (uint32_t Source, uint32_t Destination, uint32_t Count);

Opis:
Funkcja powoduje skopiowanie bloku danych w obrębie pamięci zewnętrznej. Jeśli podczas kopiowania, któryś z dresów (źródłowy i/lub docelowy) osiągnie maksymalną wartość, to przy obsłudze następnego bajtu zostanie wyzerowany (przekręci się).

Parametry:
uint32_t Source – Adres z pod którego należy skopiować blok danych.
uint32_t Destination – Adres pod który należy skopiować blok danych.
uint32_t Count – Ilość bajtów, jaką należy skopiować.

Zwracana wartość:
Nie dotyczy.


simm30compare

size_t simm30compare (const uint8_t* A1, uint32_t A2, size_t Count);

Opis:
Funkcja porównuje obszar pamięci RAM mikrokontrolera z obszarem w pamięci SIMM30.

Parametry:
const uint8_t* A1 – Wskaźnik na obszar w pamięci RAM mikrokontrolera.
uint32_t A2 – Adres w obszarze pamięci zewnętrznej.
size_t Count – Ilość bajtów do porównania.

Zwracana wartość:
0 – oznacza, że porównywane bloki pamięci zawierają te same dane.
Wartość inna niż zero wskazuje numer pierwszego bajtu, względem początku obszaru, który różni się zawartością.


simm30compareSS

int32_t simm30compareSS (uint32_t A1, uint32_t A2, uint32_t Count);

Opis:
Funkcja porównuje obszar dwa obszary pamięci zewnętrznej.

Parametry:
uint32_t A1 – Adres pierwszego obszaru w pamięci zewnętrznej.
uint32_t A2 – Adres drugiego obszaru w pamięci zewnętrznej.
uint32_t Count – Ilość bajtów do porównania.

Zwracana wartość:
0 – oznacza, że porównywane bloki pamięci zawierają te same dane.
Wartość inna niż zero wskazuje numer pierwszego bajtu, względem początku obszaru, który różni się zawartością.


simm30strcmp

int8_t simm30strcmp (const char* A1, uint32_t A2);

Opis:
Funkcja porównuje łańcuch znaków z pamięci RAM mikrokontrolera oraz z pamięci zewnętrznej.

Parametry:
const char* A1 – wskaźnik na łańcuch znaków w pamięci RAM.
uint32_t A2 – Adres łańcucha znaków w pamięci zewnętrznej. Wartość 0xFFFFFFFF jest odpowiednikiem wskaźnika NULL.

Zwracana wartość:
-1 – Gdy łańcuch w RAM jest mniejszy (alfabetycznie) od łańcucha w pamięci zewnętrznej.
0 – Gdy oba łańcuchy są jednakowe.
1 – Gdy łańcuch znaków w pamięci zewnętrznej jest mniejszy (alfabetycznie) od łańcucha w pamięci RAM.


simm30strcmpSS

int8_t simm30strcmpSS (uint32_t A1, uint32_t A2);

Opis:
Funkcja porównuje łańcuchy znaków zapisanych w pamięci zewnętrznej.

Parametry:
uint32_t A1 – Adres łańcucha znaków w pamięci zewnętrznej. Wartość 0xFFFFFFFF jest odpowiednikiem wskaźnika NULL.
uint32_t A2 – Adres łańcucha znaków w pamięci zewnętrznej. Wartość 0xFFFFFFFF jest odpowiednikiem wskaźnika NULL.

Zwracana wartość:
-1 – Gdy łańcuch z pod A1 jest mniejszy (alfabetycznie) od łańcucha z pod A2.
0 – Gdy oba łańcuchy są jednakowe.
1 – Gdy łańcuch z pod A2 jest mniejszy (alfabetycznie) od łańcucha z pod A1.


simm30strLen

uint32_t simm30strLen (uint32_t Address);

Opis:
Funkcja zwraca długość łańcucha znaków zapisanego w pamięci zewnętrznej pod adresem wskazywanym przez Address.

Parametry:
uint32_t Address – Adres, pod którym znajduje się badany łańcuch znaków zakończony wartością 0. Wartość 0xFFFFFFFF odpowiada wartości NULL.

Zwracana wartość:
uint32_t – Długość łańcucha znaków w pamięci zewnętrznej.


simm30memSet

void simm30memSet (uint32_t Address, uint8_t Value, uint32_t Count);

Opis:
Funkcja wypełnia obszar pamięci zewnętrznej podaną wartością.

Parametry:
uint32_t Address – Adres w pamięci zewnętrznej, od którego należy rozpocząć wypełnianie.
uint8_t Value – Wartość, jaką należy wypełnić pamięć.
uint32_t Count – Ilość bajtów do zapisania.

Zwracana wartość:
Nie dotyczy.


simm30version

uint16_t simm30version();

Opis:
Funkcja zwraca numer wersji biblioteki.

Parametry:
Brak

Zwracana wartość:
Numer wersji biblioteki. W starszej połówce zwracany jest numer wersji, w młodszej numer podwersji.


Pliki do pobrania


Wersja dla języka C++

Biblioteka dla języka C++ składa się z dwóch plików. Pliku nagłówkowego simm30.hpp oraz pliku kodu simm30.cpp. Biblioteka ta obsługuje do 8 modułów pamięci SIMM z wykorzystaniem 8 bitowej magistrali danych. Najmniejszą jednostką transmisji danych z/do pamięci jest bajt. Biblioteka jest uniwersalna, a to oznacza, że funkcje niskopoziomowe dostępu do wykorzystywanych pinów mikrokontrolera musi dostarczyć użytkownik. Biblioteka ta udostępnia klasę CSIMM30. A poprzez tę klasę następujące metody:

Konstruktor CSIMM30

CSIMM30::CSIMM30 (uint8_t Count, void(*setAddress)(uint16_t), void(*setWR)(bool), void(*setDataDir)(bool), void(*setData)(uint8_t), uint8_t(*getData)(), void(*setCAS)(uint8_t), void(*setRAS)(uint8_t));

Opis:
Konstruktor inicjuje bibliotekę obsługi modułów SIMM30

Parametry:
unsigned char Count – Ilość podłączonych modułów, od 0 do 8.
void(*setAddress)(uint16_t) – Wskaźnik na funkcję użytkownika ustawiającą podany adres na pinach adresowych.
void(*setWR)(_Bool) – Wskaźnik na funkcję użytkownika, która ustawia stan linii WR w stan niski (dla argumentu false) i w stan wysoki (dla argumentu true).
void(*setDataDir)(_Bool) – wskaźnik na funkcję użytkownika, która ustala kierunek magistrali danych. Dla argumentu false – jako wejście, dla true – jako wyjście.
void(*setData)(unsigned char) – Wskaźnik na funkcję użytkownika, która ma za zadanie na magistrali danych wystawić wartość argumentu.
unsigned char(*getData)() – Wskaźnik na funkcję użytkownika, która ma za zadanie zwrócić odczytaną z magistrali danych wartość.
void(*setCAS)(unsigned char) – Wskaźnik na funkcję użytkownika, która ma za zadanie ustalić stan poszczególnych linii CAS. Najmłodszy bit odpowiada za linię CAS do pierwszego modułu. Wartość bitu 1 ustala linię w stan wysoki, wartość 0 w stan niski.
void(*setRAS)(unsigned char) – Wskaźnik na funkcję użytkownika, która ma za zadanie ustalić stan poszczególnych linii RAS. Najmłodszy bit odpowiada za linię RAS do pierwszego modułu. Wartość bitu 1 ustala linię w stan wysoki, wartość 0 w stan niski.

Zwracana wartość:
Niedotyczy.


detect

TSIMM30UNIT CSIMM30::detect (uint8_t Unit);

Opis:
Funkcja dokonuje rozpoznania pojemności i struktury podłączonych modułów.

Parametry:
uint8_t Unit – Numer modułu do przetestowania. dozwolone wartości z zakresu od 0 do 8. Podanie wartości 0 sprawdza wszystkie podłączone moduły w tym wypadku zwracane są dane ostatniego modułu.

Zwracana wartość:
Charakterystyka badanego modułu w postaci struktury:

struct TSIMM30UNIT {
   uint16_t ROWS;
   uint16_t COLS;
   uint32_t CAPACITY;
   bool ERRORS;
}

Znaczenie pól struktury TSIMM30UNIT:

uint16_t ROWS – Ilość wierszy w module.
uint16_t COLS – Ilość kolumn w module.
uint32_t CAPACITY – Pojemność modułu w bajtach.
bool – Jeśli true – moduł zawiera błędy, jaśli false – wszystkie komórki modułu są sprawne.


check

TSIMM30UNIT CSIMM30::check (uint8_t Num; void(*CHECK)(bool, uint32_t), uint32_t PERIOD);

Opis:
Funkcja dokonuje sprawdzenia każdej komórki wskazanego modułu lub wszystkich modułów. Co określoną ilość sprawdzonych komórek wywołać funkcję zwrotną użytkownika z bieżącym statusem sprawdzania.

Parametry:
int8_t Num – Numer modułu do sprawdzenia. Wartość z zakresu od 0 do 8. Gdy poda się wartość 0, sprawdzane są wszystkie moduły a przestrzeń adresowa traktowana jest jak ciągły obszar.
void(*CHECK)(bool, uint32_t) – wskaźnik na funkcję użytkownika, która będzie cyklicznie wywoływana podczas przeprowadzania testu. Jeśli pierwszy parametr ma wartość TRUE, oznacza to, iż w module wykryto błędy. Drugi argument informuje o tym, ile bajtów przetestowano. Podanie wartości NULL wyłącza obsługę funkcji zwrotnej.
uint32_t PERIOD – co ile bajtów należy wywoływać funkcję użytkownika. Podanie wartości 0 wyłącza obsługę funkcji zwrotnej.

Zwracana wartość:
Charakterystyka badanego modułu w postaci struktury TSIMM30UNIT. Jeśli jako numer modułu podano 0, charakterystyka dotyczy ostatniego modułu.


getInfo

TSIMM30UNIT CSIMM30::getInfo (uint8_t Unit);

Opis:
Zwraca informacje o module.

Parametry:
uint8_t Unit – Numer modułu, którego informacji żądamy. Wartość od 1 do 8.

Zwracana wartość:
Parametry modułu w postaci struktury TSIMM30UNIT.


getTotal

uint32_t CSIMM30::getTotal ();

Opis:
Funkcja wraca całkowitą pojemność podłączonej pamięci uwzględniając uszkodzone moduły.

Parametry:
Brak

Zwracana wartość:
Ilość całkowitej pamięci podłączonej do mikrokontrolera obniżonej o objętość uszkodzonych modułów.


Refresh ()

void CSIMM30::Refresh ();

Opis:
Funkcja dokonuje odświeżenia zawartości pamięci wszystkich modułów. Należy ją uruchomiać nie rzadziej, niż co 60ms. W przeciwnym razie może dojść do uszkodzenia zawartości pamięci.

Paramatery:
Brak

Zwracana wartość:
Nie dotyczy


writeByte

void CSIMM30::writeByte (uint32_t Address, uint8_t Data);

Opis:
Funkcja zapisuje pod wskazany adres podaną wartość.

Parametry:
uint32_t Address – Adres, pod jaki dokonujemy zapisu. Obliczenie numeru modułu i adresu w module uwzględnia wyłączenie uszkodzonych modułów.
uint8_t Data – Bajt, do zapisania w pamięci.

Zwracana wartość:
Nie dotyczy


writeWord

void CSIMM30::writeByte (uint32_t Address, uint16_t Data);

Opis:
Funkcja zapisuje pod wskazany adres podaną wartość.

Parametry:
uint32_t Address – Adres, pod jaki dokonujemy zapisu. Obliczenie numeru modułu i adresu w module uwzględnia wyłączenie uszkodzonych modułów.
uint16_t Data – Słowo, do zapisania w pamięci. Młodsza połówka zapisywana jest pod adresem Address, starsza pod adresem Address + 1. Jeśli Address wskazuje ostatnią dostępną komórkę, starszy bajt zostanie zapisany pod adresem 0.

Zwracana wartość:
Nie dotyczy


writeBlock

void CSIMM30::writeBlock (const uint8_t* Source, uint32_t Destination, size_t Count);

Opis:
Funkcja Przepisuje blok pamięci z pamięci RAM mikrokontrolera do pamięci SIMM30. Jeśli podczas przepisywania zostanie osiągnięty ostatni dostępny bajt, reszta bloku zostanie przepisana od adresu 0.

Parametry:
const uint8_t* Source = Wskaźnik na dane do przepisania.
uint32_t Destination – Adres pod jaki należy zapisać blok.
size_t Count – Ilość bajtów do przepisania.

Zwracana wartość:
Nie dotyczy


readByte

uint8_t CSIMM30::readByte (uint32_t Address);

Opis:
Funkcja odczytuje bajt danych z pod podanego adresu.

Parametry:
uint32_t Address – Adres z pod którego należy odczytać bajt danych.

Zwracana wartość:
uint8_t – Odczytany z pamięci bajt.


readWord

uint16_t CSIMM30::readWord (uint32_t Address);

Opis:
Funkcja odczytuje słowo danych z pod podanego adresu.

Parametry:
uint32_t Address – Adres z pod którego należy odczytać słowo danych.

Zwracana wartość:
uint16_t – Odczytane z pamięci słowo. Młodszy bajt odczytany jest z pod adresu Address, starszy z pod adresu Address + 1. Jeśli podany adres wskazuje na ostatnią komórkę, do starszy bajt będzie odczytany z pod adresu 0.

Zwracana wartość:
Nie dotyczy.


readBlock

void CSIMM30::readBlock (uint32_t Source, uint8_t* Destination, size_t Count);

Opis:
Funkcja przepisuje z pamięci zewnętrznej do pamięci RAM mikrokontrolera blok danych. Jeśli podczas przepisywania osiągnięta zostanie ostatnia komórka pamięci, dalsza część bloku zostanie przepisana z pod adresu 0.

Parametry:
uint32_t Source – Adres w pamięci zewnętrznej z pod którego należy przepisać dane.
uint8_t* Destination – Wskaźnik na obszar pamięci RAM, pod które należy przepisać dane.
size_t Count – Ilość bajtów, które należy przepisać.

Zwracana wartość:
Nie dotyczy.


copy

void CSIMM30::copy (uint32_t Source, uint32_t Destination, uint32_t Count);

Opis:
Funkcja powoduje skopiowanie bloku danych w obrębie pamięci zewnętrznej. Jeśli podczas kopiowania, któryś z dresów (źródłowy i/lub docelowy) osiągnie maksymalną wartość, to przy obsłudze następnego bajtu zostanie wyzerowany (przekręci się).

Parametry:
uint32_t Source – Adres z pod którego należy skopiować blok danych.
uint32_t Destination – Adres pod który należy skopiować blok danych.
uint32_t Count – Ilość bajtów, jaką należy skopiować.

Zwracana wartość:
Nie dotyczy.


compare

size_t CSIMM30::compare (const uint8_t* A1, uint32_t A2, size_t Count);

Opis:
Funkcja porównuje obszar pamięci RAM mikrokontrolera z obszarem w pamięci SIMM30.

Parametry:
const uint8_t* A1 – Wskaźnik na obszar w pamięci RAM mikrokontrolera.
uint32_t A2 – Adres w obszarze pamięci zewnętrznej.
size_t Count – Ilość bajtów do porównania.

Zwracana wartość:
0 – oznacza, że porównywane bloki pamięci zawierają te same dane.
Wartość inna niż zero wskazuje numer pierwszego bajtu, względem początku obszaru, który różni się zawartością.


compareSS

int32_t CSIMM30::compareSS (uint32_t A1, uint32_t A2, uint32_t Count);

Opis:
Funkcja porównuje obszar dwa obszary pamięci zewnętrznej.

Parametry:
uint32_t A1 – Adres pierwszego obszaru w pamięci zewnętrznej.
uint32_t A2 – Adres drugiego obszaru w pamięci zewnętrznej.
uint32_t Count – Ilość bajtów do porównania.

Zwracana wartość:
0 – oznacza, że porównywane bloki pamięci zawierają te same dane.
Wartość inna niż zero wskazuje numer pierwszego bajtu, względem początku obszaru, który różni się zawartością.


strcmp

int8_t CSIMM30::strcmp (const char* A1, uint32_t A2);

Opis:
Funkcja porównuje łańcuch znaków z pamięci RAM mikrokontrolera oraz z pamięci zewnętrznej.

Parametry:
const char* A1 – wskaźnik na łańcuch znaków w pamięci RAM.
uint32_t A2 – Adres łańcucha znaków w pamięci zewnętrznej. Wartość 0xFFFFFFFF jest odpowiednikiem wskaźnika NULL.

Zwracana wartość:
-1 – Gdy łańcuch w RAM jest mniejszy (alfabetycznie) od łańcucha w pamięci zewnętrznej.
0 – Gdy oba łańcuchy są jednakowe.
1 – Gdy łańcuch znaków w pamięci zewnętrznej jest mniejszy (alfabetycznie) od łańcucha w pamięci RAM.


strcmpSS

int8_t CSIMM30::strcmp (uint32_t A1, uint32_t A2);

Opis:
Funkcja porównuje łańcuchy znaków zapisanych w pamięci zewnętrznej.

Parametry:
uint32_t A1 – Adres łańcucha znaków w pamięci zewnętrznej. Wartość 0xFFFFFFFF jest odpowiednikiem wskaźnika NULL.
uint32_t A2 – Adres łańcucha znaków w pamięci zewnętrznej. Wartość 0xFFFFFFFF jest odpowiednikiem wskaźnika NULL.

Zwracana wartość:
-1 – Gdy łańcuch z pod A1 jest mniejszy (alfabetycznie) od łańcucha z pod A2.
0 – Gdy oba łańcuchy są jednakowe.
1 – Gdy łańcuch z pod A2 jest mniejszy (alfabetycznie) od łańcucha z pod A1.


strLen

uint32_t CSIMM30::strLen (uint32_t Address);

Opis:
Funkcja zwraca długość łańcucha znaków zapisanego w pamięci zewnętrznej pod adresem wskazywanym przez Address.

Parametry:
uint32_t Address – Adres, pod którym znajduje się badany łańcuch znaków zakończony wartością 0. Wartość 0xFFFFFFFF odpowiada wartości NULL.

Zwracana wartość:
uint32_t – Długość łańcucha znaków w pamięci zewnętrznej.


memSet

void CSIMM30::memSet (uint32_t Address, uint8_t Value, uint32_t Count);

Opis:
Funkcja wypełnia obszar pamięci zewnętrznej podaną wartością.

Parametry:
uint32_t Address – Adres w pamięci zewnętrznej, od którego należy rozpocząć wypełnianie.
uint8_t Value – Wartość, jaką należy wypełnić pamięć.
uint32_t Count – Ilość bajtów do zapisania.

Zwracana wartość:
Nie dotyczy.

version

uin16_t CSIMM30::version();

Opis:
Funkcja zwraca numer wersji biblioteki.

Parametry:
Brak

Zwracana wartość:
Numer wersji biblioteki. W starszej połówce zwracany jest numer wersji, w młodszej numer podwersji.

Pliki do pobrania


Aplikacja demonstracyjna

Poniżej aplikacje demonstracyjne napisane dla ATMEGA32. Aplikacja po uruchomieniu powoduje detekcję pierwszego modułu. Jeśli moduł zostanie wykryty, następuje jego testowanie i wyświetlenie podsumowania, czy moduł jest sprawny.

Aplikacja demonstracyjna skonfigurowana jest do nasatępującego podłączenia:

A0 – A7 – PORTB
A8 – A11 – PORTD2 do PORTD5
D0 – D7 – PORTC
WR – PORTA0
CAS – PORTA1
RAS – PORTA2

Aplikacja wysyła komunikaty za pomocą interfejsu USART z prędkością 9600 bodów w konfiguracji 8 – bitów, brak parzystości, 1 bit stopu.



Komentarze

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *