Come posso testare le DRAM ?
Capita di doversi cimentare nel riparare un vecchio computer o console che utilizza queste tipologie di RAM e fortunatamente ci sono dei modi che ci aiutano a trovare il banco (o più) difettoso.
Ma perché le DRAM? Queste RAM dinamiche (da cui il nome) a differenza di quelle statiche hanno necessità di rinfrescare i loro dati memorizzati riscrivendoli spesso ogni tot millisecondi. I dati su queste RAM vengono memorizzati e mantenuti da una carica di un condensatore presente sulla cella di memoria, ma questo condensatore anche se non mantiene la carica per molto tempo e se il dato viene letto la carica si esaurisce molto più rapidamente, quindi i dati devono essere riscritti sia se si legge (solo la riga letta) che periodicamente (tutti i dati presenti).
Sono state scelte queste RAM per un semplice motivo, il costo!, infatti rispetto alle SRAM questo modello richiede molti meno transistor nella costruzione quindi si possono avere RAM con molta più capacità al costo di una SRAM 4 volte più piccola.
Beh, ora vediamo come risolvere i problemi di queste memorie, spesso a causa del deterioramento dei condensatori non mantengono più i dati scritti e un metodo per trovare la RAM guasta può essere quello di posizionarne un’altra sopra di essa (metodo Piggyback), in questo modo i dati verranno scritti e memorizzati sulle due ram e se un dato va perso sulla ram difettosa, sarà recuperato da quella buona.
Attenzione che non è un sistema infallibile, infatti se la RAM ha dei pin in corto, quella messa sopra non riuscirà a passare nessun dato sulla linea in corto, inoltre se ci sono più banchi difettosi il computer potrebbe non partire (se non ha un sistema per controllare la RAM all’avvio) e non saprete quale altra è rovinata.
Questo metodo invece richiede di costruirsi un piccolo tester basato su Arduino, lo schema si trova in rete ed è molto semplice, il funzionamento non fa altro che scrivere e leggere diverse volte per verificare che i dati siano effettivamente corretti.
Potete trovare le informazioni e lo schema a questo link: https://forum.defence-force.org/viewtopic.php?t=1699
Visto che lo schema è disegnato a mano, ve ne metto uno rifatto seguendo l’originale (by ISS):
Tester per 4164
#include <SoftwareSerial.h>
#define DI 15 // PC1
#define DO 8 // PB0
#define CAS 9 // PB1
#define RAS 17 // PC3
#define WE 16 // PC2
#define XA0 18 // PC4
#define XA1 2 // PD2
#define XA2 19 // PC5
#define XA3 6 // PD6
#define XA4 5 // PD5
#define XA5 4 // PD4
#define XA6 7 // PD7
#define XA7 3 // PD3
#define XA8 14 // PC0
#define M_TYPE 10 // PB2
#define R_LED 11 // PB3
#define G_LED 12 // PB4
#define RXD 0 // PD0
#define TXD 1 // PD1
#define BUS_SIZE 9 // impostare a 7 se utilizzato per 4116
volatile int bus_size;
//SoftwareSerial USB(RXD, TXD);
const unsigned int a_bus[BUS_SIZE] = {
XA0, XA1, XA2, XA3, XA4, XA5, XA6, XA7, XA8
};
void setBus(unsigned int a) {
int i;
//funzione corretta
for (i = 0; i < bus_size; i++) {
if (bitRead(a, i)==1) {
digitalWrite(a_bus[i], HIGH);
} else {
digitalWrite(a_bus[i], LOW);
}
}
}
void writeAddress(unsigned int r, unsigned int c, int v) {
/* row */
setBus(r);
digitalWrite(RAS, LOW);
/* rw */
digitalWrite(WE, LOW);
/* val */
digitalWrite(DI, (v & 1)? HIGH : LOW);
/* col */
setBus(c);
digitalWrite(CAS, LOW);
digitalWrite(WE, HIGH);
digitalWrite(CAS, HIGH);
digitalWrite(RAS, HIGH);
}
int readAddress(unsigned int r, unsigned int c) {
int ret = 0;
/* row */
setBus(r);
digitalWrite(RAS, LOW);
/* col */
setBus(c);
digitalWrite(CAS, LOW);
/* get current value */
ret = digitalRead(DO);
digitalWrite(CAS, HIGH);
digitalWrite(RAS, HIGH);
return ret;
}
void error(int r, int c)
{
unsigned long a = ((unsigned long)c << bus_size) + r;
digitalWrite(R_LED, LOW);
digitalWrite(G_LED, HIGH);
interrupts();
Serial.print(” FAILED $”);
Serial.println(a, HEX);
Serial.flush();
while (1)
;
}
void ok(void)
{
digitalWrite(R_LED, HIGH);
digitalWrite(G_LED, LOW);
interrupts();
Serial.println(” OK!”);
Serial.flush();
while (1)
;
}
void blink(void)
{
digitalWrite(G_LED, LOW);
digitalWrite(R_LED, LOW);
delay(1000);
digitalWrite(R_LED, HIGH);
digitalWrite(G_LED, HIGH);
}
void green(int v) {
digitalWrite(G_LED, v);
}
void fill(int v) {
int r, c, g = 0;
v %= 1;
for (c = 0; c < (1<<bus_size); c++) {
green(g? HIGH : LOW);
for (r = 0; r < (1<<bus_size); r++) {
writeAddress(r, c, v);
if (v != readAddress(r, c))
error(r, c);
}
g ^= 1;
}
blink();
}
void fillx(int v) {
int r, c, g = 0;
v %= 1;
for (c = 0; c < (1<<bus_size); c++) {
green(g? HIGH : LOW);
for (r = 0; r < (1<<bus_size); r++) {
writeAddress(r, c, v);
if (v != readAddress(r, c))
error(r, c);
v ^= 1;
}
g ^= 1;
}
blink();
}
void setup() {
int i;
Serial.begin(9600);
while (!Serial)
; /* wait */
Serial.println();
Serial.print(“DRAM TESTER “);
for (i = 0; i < BUS_SIZE; i++)
pinMode(a_bus[i], OUTPUT);
pinMode(CAS, OUTPUT);
pinMode(RAS, OUTPUT);
pinMode(WE, OUTPUT);
pinMode(DI, OUTPUT);
pinMode(R_LED, OUTPUT);
pinMode(G_LED, OUTPUT);
pinMode(M_TYPE, INPUT);
pinMode(DO, INPUT);
digitalWrite(WE, HIGH);
digitalWrite(RAS, HIGH);
digitalWrite(CAS, HIGH);
digitalWrite(R_LED, HIGH);
digitalWrite(G_LED, HIGH);
// se si usa la memoria 4146 non inserire questo ciclo if (digitalRead)… else ..
if (digitalRead(M_TYPE)) {
/* jumper not set – 41256 */
bus_size = BUS_SIZE;
Serial.print(“256Kx1 “);
} else {
/* jumper set – 4164 */
bus_size = BUS_SIZE – 1;
Serial.print(“64Kx1 “);
}
Serial.flush();
digitalWrite(R_LED, LOW);
digitalWrite(G_LED, LOW);
noInterrupts();
for (i = 0; i < (1 << BUS_SIZE); i++) {
digitalWrite(RAS, LOW);
digitalWrite(RAS, HIGH);
}
digitalWrite(R_LED, HIGH);
digitalWrite(G_LED, HIGH);
}
void loop() {
interrupts(); Serial.print(“.”); Serial.flush(); noInterrupts(); fillx(0);
interrupts(); Serial.print(“.”); Serial.flush(); noInterrupts(); fillx(1);
interrupts(); Serial.print(“.”); Serial.flush(); noInterrupts(); fill(0);
interrupts(); Serial.print(“.”); Serial.flush(); noInterrupts(); fill(1);
ok();
}
Realizzate questo circuito, programmate Arduino scaricando il file .ino oppure incollando il codice sorgente su di un progetto vuoto dell’ide di Arduino e programmatelo. Con Arduino connesso ad un pc potete vedere tramite il monitor seriale lo stato del test, oppure visibile tramite i led.
Funzionamento
1. Selezionate il tipo di RAM (4164 – 41256) tramite il jumper, se inserito si testano le 4164, se lasciato aperto si testano le 41256.
2. Inserite la RAM da testare facendo attenzione al corretto orientamento (una inversione di polarità vi brucerà il banco di RAM).
3. Alimentate Arduino che comincerà subito il test, attendete poco più di un minuto e se tutto ok si accenderà il led verde, in caso contrario il rosso.
Un altro esempio di DRAM tester (4164) V1
Questa è una realizzazione di un tester simile a quello descritto sopra.
E’ la prima versione che ho realizato e legge solo le 4164-256.
Il funzionamento è leggermente diverso e funziona con un display e due pulsanti, uno per scegliere il tipo di RAM da testare e uno per iniziare il test.
I vari test effettuati sono visibili nel display come il risultato finale.
In questo caso l’alimentazione della memoria viene gestita da Arduino che provvederà ad alimentare la RAM appena si inizia il test e la interromperà quando finito. Una piccola sicurezza per evitare di bruciare la RAM se viene posizionata al contrario.
Ora tocca a voi inventare un vostro tester personale o più semplicemente usare quello descritto.
IL CODICE PRECEDENTE NON VA BENE PER QUESTO TESTER.
Ed ora ecco il nuovo tester adatto anche per le 4116 V2
Ed Infine la versione 4
Questo utilizza l’alimentazione di Arduino e la eleva a 12V con il booster, pin più crea la -5V con il 7660.
Lo switch è stato sostituito con un jumper per evitare di spostarlo accidentalmente e bruciare la ram, per il resto è simile alla versione 3.
Anche questo PCB non è compatibile con il sorgente originale.
Se vuoi costruitlo visita la mia pagina github
Beta testing versione 4.2
non finisce qui, in test la versione software per testare anche le ram 4532 (parte alta o bassa), con finale animato! 🙂
Questa versione esegue 5 test:
1 scrittua-lettura bit 0-1
2 scrittura-lettura tutti 1
3 solo scrittura tutti 1
4 solo lettura attesi tutti 1 (verifica che i dati vengano mantenuti)
5 scrittura-lettura tutti 0