Page 1 of 1

DRAMARDUINO - Dram tester with Arduino

Posted: Sat Oct 15, 2016 2:30 pm
by iss
Hi all!

Below you can see all details of my 2-hours 2-dollar project 'DramArduino'.
It's simple and very handy DRAM chip tester. It works with 4164 and 41256 IC's.
Testing is not too fast but acceptable - 4 different passes are performed in about 80 seconds total.
Results are 100% reliable only if the test FAILS - you can throw away the chip without fear.
If the test passes, this doesn't certainly mean that it will work in Oric, because as you know Oric's are very 'sensitive' to DRAM.
Actually this was my goal exactly - to sort out the working chips from about 200 before I'm get bored :).

Working with the tool is easy: place the chip in the ZIF socket, press small reset button, wait until GREEN LED blinks,
if it remains permanently on - chip is OK, if the chip is bad - RED LED lights.
If USB is connected, status is reported in your serial console. This helped me to detect some 'lazy' chips - they failed in
different, on every next test, growing addresses but when they become 'hot' test passes always.
IIRC such fail to boot Oric was reported somewhere in this forum...

Attached are 'schematic', source code and pictures - do with them what you want :).
dramarduino.png
da.jpg
EDIT 2020-10-29: Sketch fixed!
dramarduino.ino.2020-10-29.zip
(1.4 KiB) Downloaded 2145 times

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Wed Jan 16, 2019 1:36 am
by Voyageur
Hi Iss,
Thank you for sharing the DramTester.
I've made one and it works !
I just controlled some 4164 and it is a good and not so long test :)
If you agree, I will show this Arduino shield on flag_fr CEO forum.
Have a good day !

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Wed Jan 16, 2019 8:35 am
by iss
Hello, Voyageur!
I'm very glad that you liked this little tool and I'll be really happy if you share it on CEO forum.

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Sun Mar 10, 2019 7:08 pm
by witchy
Hi Iss,

This was timed beautifully, for an upcoming 'Japanese Computing' exhibition at the Centre For Computing History in Cambridge I was testing my Sanyo MBC555 and the CGA card in there has 8x41256 chips on board. I built the tester on a breadboard and it works perfectly, thanks! Unfortunately it passed all 8 so the fault I have is elsewhere on the board.
dramArduino.jpg

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Mon Oct 05, 2020 9:38 am
by john
Resurrecting a old thread here but looks like there is a critical bug in this code which causes only memory location 0x0000 to be tested.

Code: Select all

void setBus(unsigned int a) {
  int i;
  for (i = 0; i < BUS_SIZE; i++) {
    digitalWrite(a_bus[i], a % 1);
    a /= 2;
  }
}
a%1 will always result in 0 so no matter what value a is, 0 will always be written to the address lines.

Code should be changed to:

Code: Select all

digitalWrite(a_bus[i], a % 2);

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Wed Oct 07, 2020 8:36 am
by HigashiJun
Interesting...

I will give it a try on my DRAMARDUINO.

Thanks.

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Wed Oct 07, 2020 10:01 am
by iss
Wow, nice catch. Interesting is that in my local file it's:

Code: Select all

digitalWrite(a_bus[i], a & 1);
Maybe I've uploaded something preliminary...
First post is now updated with the correct sketch!

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Thu Oct 29, 2020 5:42 pm
by thekorex
Hello everyone, yesterday I got a pack of KM4164B-15 ICs and quickly built a big mess of wires on a breadboard to test them using DramArduino which I want to thank @iss for creating and sharing.

After testing a few of the ICs I noticed the sketch still contains two more occurrences of the problematic % 1 in both fill(int v) and fillx(int v) functions.

I think this will cause fill(int v) to simply test the RAM with zeros, regardeless of the value of v and fillx(int v) to always generate the sequence "0 1 0 1..." and never the opposite one "1 0 1 0..."

Code: Select all

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();
}
I replaced each function's second line containing

Code: Select all

  v %= 1;
with

Code: Select all

  v &= 1;
to get the lower bit of v and I believe it solves the problem.

Anyway, thank you again for sharing this nice project.

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Thu Oct 29, 2020 7:37 pm
by iss
thekorex wrote: Thu Oct 29, 2020 5:42 pm ...
Thank you for reporting @thekorex!

First post is updated again with the correct sketch!

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Thu Dec 10, 2020 4:52 pm
by shift838
iss wrote: Thu Oct 29, 2020 7:37 pm
thekorex wrote: Thu Oct 29, 2020 5:42 pm ...
Thank you for reporting @thekorex!

First post is updated again with the correct sketch!
I was looking for exactly one of these and found the schematics and sketch here. It works great, but I would like to be able to interface a button to execute the DRAM test, which I have done in the below code. But I want it to stop when it fails, I then want to be able to change the DRAM and hit the button again to start a new test. Currently with the 'While (1);' statement it will put the unit in the endless loop where you have to RESET the arduino to start a new test. I don't want to have to restart the arduino.

I have tried to remove the While statement and put in a 'return;' but that generates just a constant loop of FAILED being printed via the serial monitor and I have to reset the Arduino to stop it.

Looks like this in the serial monitor:

Code: Select all

DRAM TESTER Selected: 256K x 1 
Pass #1...
 FAILED $1
 FAILED $3
 FAILED $5
 FAILED $7
 FAILED $9
 FAILED $B
 FAILED $D
 FAILED $F
 FAILED $11
 FAILED $13
 FAILED $15
 FAILED $17
 FAILED $19
the code is below. any help would be greatly appreciated.

Code: Select all


#include <Bounce2.h>
#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

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 13;     // the number of the pushbutton pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 205;    // the debounce time; increase if the output flickers

/* ================================================================== */
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;
  for (i = 0; i < BUS_SIZE; i++) {
    digitalWrite(a_bus[i], a & 1);
    a /= 2;
  }
}

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);
  return;
}

void ok(void)
{
  digitalWrite(R_LED, HIGH);
  digitalWrite(G_LED, LOW);
  interrupts();
  Serial.println(" PASSED!");
  Serial.flush();
  //while(1);
  return;
}

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;
  
// initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
  Serial.begin(115200);
  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);

if (digitalRead(M_TYPE)) {
    /* jumper not set - 41256 */
    bus_size = BUS_SIZE;
    Serial.print("Selected: 256K x 1 ");
  } else {
    /* jumper set - 4164 */
    bus_size = BUS_SIZE - 1;
    Serial.print("Selected: 64K x 1 ");
  }
  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() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  
  if ( (millis() - lastDebounceTime) > debounceDelay) {
      if (buttonState == LOW) {
        Serial.println("");
        interrupts(); Serial.println("Pass #1..."); Serial.flush(); noInterrupts(); fillx(0);
        interrupts(); Serial.println("Pass #2..."); Serial.flush(); noInterrupts(); fillx(1);
        interrupts(); Serial.println("Pass #3..."); Serial.flush(); noInterrupts(); fill(0);
        interrupts(); Serial.println("Pass #4..."); Serial.flush(); noInterrupts(); fill(1);
        ok();
        
        lastDebounceTime = millis(); //set the current time
      }
      else if (buttonState == HIGH) {
        lastDebounceTime = millis(); //set the current time
      }//close if/else
  
    }//close if(time buffer)
}//close void loop


Re: DRAMARDUINO - Dram tester with Arduino

Posted: Mon Feb 08, 2021 4:32 pm
by TA2KQ
Hello all,
Came across this forum and topic while searching for an easy solution with Arduino to test DRAM's. Seemed like what I need, so I built it. It's working and it can identify bad chips that I have. I am relatively new to Arduino and by no means a programmer, I could only make heads and tails of 60% of the code so far, I need to learn bit banging and the operators related to get it all, I know. But still something seems strange to me, if anyone can explain why, I will be grateful. There is a pin to select 4164 and 41256 chips that changes the bus size variable accordingly, so far so good, but if I put a 4164 and test it as 41256, it still passes OK, and strangely it also takes as long as a real 41256. Shouldn't it sort of "hit a wall" and return an error when the address incrementing loop goes over XA7 and come to a non-existent XA8 bit?
This may be a very stupid question but please bear with me and explain as plainly as possible why this happens?
Thanks!

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Mon Feb 08, 2021 4:49 pm
by mikeb
TA2KQ wrote: Mon Feb 08, 2021 4:32 pm if I put a 4164 and test it as 41256, it still passes OK, and strangely it also takes as long as a real 41256. Shouldn't it sort of "hit a wall" and return an error when the address incrementing loop goes over XA7 and come to a non-existent XA8 bit?
Hello!

I suspect what you're doing is testing the 4164 completely, four times.

The extra XA8 bit has nowhere to go when testing a 4164, so each row and column address would effectively ignore the upper bit, meaning the count would loop from 65535 back to 0 -- ignoring the upper bit of a binary count doubles the possible addresses.

Because the 8 bit addresses are being used for rows, then columns, you end up with a double count, twice -- i.e. four times.

A similiar thing happens if you read a 2764 EPROM as a 27128 (you end up with two identical sets of data, end to end, not: expected valid data followed by tumbleweeds!)

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Mon Feb 08, 2021 8:21 pm
by iss
Indeed! @mikeb's answer explains very good what happens. Here are 4164 and 41256:
4164-41256.png
As you can see in 4164 pin-1 is NC (Not Connected) internally, so for 4164 it really doesn't matter what logic level you put on it -
the test is repeated 4 times. Additionally from the 'schematics' you can see that the jumper doesn't have any 'electrical' meaning and is used only to 'tell' the software that it has to include the address line A8 in the testing cycle too and so testing time is 4 times longer (per every test). Of course it's possible also autodetection :).

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Tue Feb 09, 2021 5:19 pm
by mikeb
... further thought!

In an actual Oric, the memory test relies on this "missing address line" situation to distinguish between a 4164 (64k/48k Oric) and a 4116 (16k Oric) bank

With the quarter size DRAM chip (16K), now there is nowhere for A7 to go. So whether the row/col address bit 7 is high or low, you get the SAME location in memory based on bits 0..6

The RAM test writes to one location (#4500), reads back from a different one (#0500), and if it works, concludes it's only a 16K Oric (because the memory map wraps around 4 times from #0000-#3FFF, #4000-#7FFF, #8000-#BFFF, and #C000-#FFFF).
iss wrote: Mon Feb 08, 2021 8:21 pm Of course it's possible also autodetection :).
Possible, but caution applies -- if you "auto detect and test" a working 41256 with pin 1 snapped off, won't you get told it's a "working 4164"? :)

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Thu Feb 11, 2021 11:28 am
by TA2KQ
mikeb wrote: Mon Feb 08, 2021 4:49 pm
TA2KQ wrote: Mon Feb 08, 2021 4:32 pm if I put a 4164 and test it as 41256, it still passes OK, and strangely it also takes as long as a real 41256. Shouldn't it sort of "hit a wall" and return an error when the address incrementing loop goes over XA7 and come to a non-existent XA8 bit?
I suspect what you're doing is testing the 4164 completely, four times.
Yes, I figured that out after I posted the question, but it is good to have a confirmation. :-) Thank you for taking the time!

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Thu Feb 11, 2021 11:35 am
by TA2KQ
While we are at it, another question:

I have a set of TI 6154 chips I bought from China, they are not fakes, but they are used (pulled from old boards)
These chips all test fine with this tester, but they cause intermittent errors when I use them in the computer.
Someone said they may be somewhat "tired" chips, and the conditions of this tester are more forgiving than the conditions of the computer, especially in the speed they are read / written, or refreshed.
This sounds quite logical to me. What are your thoughts, and what can be done to make this code more challenging to identify this kind of faults?

Thanks to all!
Bora

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Thu Feb 11, 2021 3:16 pm
by Dbug
I wonder if it's possible to emulate what memtest+ does, like trying to access the ram in one direction, the other direction, randomly, testing with different patterns, etc... to detect edge cases like ram that "mostly work" but fails now and then.

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Thu Feb 11, 2021 4:51 pm
by mikeb
TA2KQ wrote: Thu Feb 11, 2021 11:35 am I have a set of TI 6154 chips I bought from China
Skipping past the obvious objections regarding fakes, and relabelled chips, what is the FULL numbering from the top of the chip? Often, the part number is immediately followed by a speed indication, and there are plenty of 4164-like chips that are too slow for Oric (which accesses the DRAM three times in every 1 microsecond cycle) that work just fine in other 1MHz computers (accessed once per cycle).

E.g. TI6154-1 TI6154-15 ... -2 ? -3? would indicate 100ns, 150ns, 200ns, 300ns access times. 100/150ns should be fine. Any slower is not going to work reliably (or at all).

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Thu Feb 11, 2021 6:36 pm
by iss
I second @mikeb: what's the full name of the chips? A readable picture will be best :). I can't find any info about such thing like TI 6154... else about the "tired" chips - this sounds like "conspiracy" :).
Dbug wrote: Thu Feb 11, 2021 3:16 pm I wonder if it's possible to emulate what memtest+ does, like trying to access the ram in one direction, the other direction, randomly, testing with different patterns, etc... to detect edge cases like ram that "mostly work" but fails now and then.
The tester makes 4 loops with different data. As I said I found some lazy chips which starts to pass the test after some time for heating.

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Thu Feb 11, 2021 9:24 pm
by TA2KQ
They are TMS4164-20NL, date code AP8432
They seem to be genuine, rubbing with IPA and acetone did not reveal anything. They are obviously second hand with solder marks on their pins small scratches here and there. Oh, and I confess, I bought them for a Sinclair Spectrum and testing them on it. 😊

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Fri Feb 12, 2021 5:33 pm
by mikeb
TA2KQ wrote: Thu Feb 11, 2021 9:24 pm They are TMS4164-20NL, date code AP8432
They seem to be genuine, rubbing with IPA and acetone did not reveal anything. They are obviously second hand with solder marks on their pins small scratches here and there. Oh, and I confess, I bought them for a Sinclair Spectrum and testing them on it. 😊
Ah, well, those are on the slow side (200ns) and so may be unreliable. They can't guarantee to get the data out in time for access by the CPU and ULA (twice) in each 1MHz clock cycle. So while they may work "mostly", you will have screen glitches from the ULA getting bad data, and more importantly, all sorts of unreliability with data being read from memory, which will put all sorts of interesting bugs into working code :(

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Fri Feb 12, 2021 6:53 pm
by Dbug
mikeb wrote: Fri Feb 12, 2021 5:33 pm
TA2KQ wrote: Thu Feb 11, 2021 9:24 pm They are TMS4164-20NL, date code AP8432
Ah, well, those are on the slow side (200ns) and so may be unreliable. They can't guarantee to get the data out in time for access by the CPU and ULA (twice) in each 1MHz clock cycle. So while they may work "mostly", you will have screen glitches from the ULA getting bad data, and more importantly, all sorts of unreliability with data being read from memory, which will put all sorts of interesting bugs into working code :(
Naive question: If you have slow ram chips, and you use them only from $0000 to $B4000 and from $C000 to $FFFF, where only the 6502 is actually doing active reads, using fast chips for the area frequently accessed by the ULA, would that work?

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Fri Feb 12, 2021 11:53 pm
by kenneth
The RAM chip is used in a "slice" of all the memory, and not in an area of ​​the memory, we cannot have different speeds. :wink:

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Sat Feb 13, 2021 5:48 pm
by mikeb
Dbug wrote: Fri Feb 12, 2021 6:53 pm If you have slow ram chips, and you use them only from $0000 to $B4000 and from $C000 to $FFFF, where only the 6502 is actually doing active reads, using fast chips for the area frequently accessed by the ULA, would that work?
Good thought!

As Kenneth said -- and definitely not under current hardware. Although each chip is a 1 bit x 64k slice up the whole memory map, and so the speed affects every address, the address being accessed bounces about during the 1MHZ cycle. e.g. Processor: 0x500, ULA: 0xBB80 ULA: 0xB500 ... (slow, quick, quick).

You could (for some crazy reason) split DRAM up into slow and fast banks, but you'd have to do that electrically between the ULA and the DRAM, identify what addresses are being accessed, and direct the requests to the fast bank (for all screen memory) and slow bank (for everything else).

It would be a lot of work for a "look what *I* did!" project, and you'd still need enough FAST (normal!) DRAM (16K at least) to feed the ULA, as well as 64K of slow DRAM so I don't think it's a good project to attempt :)

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Tue Feb 16, 2021 9:53 am
by TA2KQ
mikeb wrote: Fri Feb 12, 2021 5:33 pm
TA2KQ wrote: Thu Feb 11, 2021 9:24 pm They are TMS4164-20NL, date code AP8432
They seem to be genuine, rubbing with IPA and acetone did not reveal anything. They are obviously second hand with solder marks on their pins small scratches here and there. Oh, and I confess, I bought them for a Sinclair Spectrum and testing them on it. 😊
Ah, well, those are on the slow side (200ns) and so may be unreliable. They can't guarantee to get the data out in time for access by the CPU and ULA (twice) in each 1MHz clock cycle. So while they may work "mostly", you will have screen glitches from the ULA getting bad data, and more importantly, all sorts of unreliability with data being read from memory, which will put all sorts of interesting bugs into working code :(
Interesting... My knowledge of digital electronics is at novice level at best, so bare with me, but doesn't 200ns translate into 5Mhz? The CPU clock in a ZX Spectrum is 3.5MHz. I also didn't know that in a ZX Spectrum the CPU and the ULA access the RAM twice in one clock cycle, how does that work? I thought the ULA actually "stopped" the CPU when it needs to access the RAM, and that RAM is the "lower" 16K where the screen image is kept. I know that the CPU clock is generated inside the ULA and fed to the CPU via a transistor which is controlled by the ULA to stop the CPU whenever it needs to do something sneaky with the data bus, so in theory, there shouldn't be 2 reads/writes in 1 clock cycle. Also these chips that causing problems are used in the "upper" 32K range of the RAM, I really don't know whether the ULA ever needs to access there. I'll do some research on whether it is possible to use 200ns DRAM chips in a ZX Spectrum upper RAM which may cast some light on the subject. I am hoping that this problem I am having will inspire the coders in making this DRAM test code better and more aggressive so that it can catch not only absolutely defective chips but these kind of intermittent problems too. Cheers, and stay safe!

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Tue Feb 16, 2021 4:55 pm
by mikeb
TA2KQ wrote: Tue Feb 16, 2021 9:53 am Interesting... My knowledge of digital electronics is at novice level at best, so bare with me, but doesn't 200ns translate into 5Mhz?
200ns would be 5MHz if it was a simple period to frequency conversion. 200ns is how long it takes from presenting a row-column address pair and saying "READ!" to valid data being available. So, factor in some time for "setting up row address", DRAM takes it, "Setting up column address", DRAM takes THAT, wait 200ns, grab valid data ... in practice you can't pull one byte out of DRAM every 200ns. That applies to Oric/Spectrum/any use of DRAM.

No idea about the exact mechanics of the Spectrum's ULA/Graphics, anything I wrote was about the specifics of Oric which is *not* entirely "textbook normal" on its timings. This manifests itself in Oric being a "1MHz machine" that requires a 2MHz 6502A part -- because the actual clock ACTIVE time for the 6502 is 33% of the clock cycle (333ns, too short for a 1MHZ part which needs 450-500ns needed!).

So the 6502 has to be over and done QUICKLY to get out of the way for the ULA to double-dip into memory to produce the picture. On an Oric, there's not much latitude to use slower than 150ns DRAM, or to use a 6502/1MHz as a replacement processor. It just won't work.

A Spectrum memory map is clearly different to Oric, so any comments on that aspect were again based on Oric's map.

It sounds like the Spectrum approach was that the ULA forces the CPU to stop to make space for access to DRAM, which is one (simpler) way of dealing with, I suppose it makes exact timing of software slightly more interesting. Oric doesn't need to do this, both the CPU and ULA have equal opportunity to access memory (CPU on 33% high part of cycle, ULA twice on 66% low part).

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Mon Feb 28, 2022 5:21 pm
by mmu_man
It seems Jan Beta had a try at building it, he even mentions the forum:


Re: DRAMARDUINO - Dram tester with Arduino

Posted: Mon Feb 28, 2022 9:27 pm
by iss
mmu_man wrote: Mon Feb 28, 2022 5:21 pm It seems Jan Beta had a try at building it, he even mentions the forum:
Indeed! And #DRAMARDUINO is on the Hacakday. :)

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Thu Mar 10, 2022 3:50 pm
by franks3dshop
Hi all, I just added my 2 cents to this project here is the modified version with these modifications:

- I have added a ratio to slowdown the blinking (BLINK_RATIO) so not too get epilepsy from the thing!
- Added more feedback on the serial port about the test in progress and at what address the error first occurs.

I wish to also add a 0.9" OLED screen to better follow the process like some version on Ebay

I used this board with a Arduino Nano (can also use a Arduino Uno) :
https://www.pcbway.com/project/sharepro ... _Nano.html



Frank
Franks3dShop-assembled.jpg
dramduino.ino.2021.11.09.zip
(17.28 KiB) Downloaded 153 times

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Fri Mar 11, 2022 2:41 am
by franks3dshop
Did a test today and it works! It will work with a 16x2 LCD module with a PCF8574 module.
IMG_2923.JPG
IMG_2924.JPG
Made a small video:
https://youtu.be/0HXAVb3HuZQ

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Tue Oct 25, 2022 4:31 pm
by Stan
Hi,
I've purchased a vintage DRAM tester from eBay recently, and while I was waiting, I decided to buy an Arduino and try making some basic tester.
Here is how I came across this forum thread.
I had some free time, made some 'google research', and made some software updates over the iss's ino code that I would like to share with you.
Major updates:
- fillx() accepts custom 8-bit test patterns
- first fills the entire DRAM with the test pattern, then reads back and verifies (readx() func) in a second pass
- stops after MAX_ERRORS count of errors, not after first error
- added Auto-find 4164/41256. The jumper is no longer required, but if closed, will force a 4164 test. This is not the best auto-find solution though, as it writes/reads only one bit.
- readAddress and writeAddress routines rewritten for direct port manipulation - significant speed increase

Other updates that I have on my mind would require hardware changes (such as 4116 12V -5V DRAM support)

It was real fun to see how the Arduino tester catches single-bit errors while the 50-euro ebay tester didn't:
Screenshot bad ram.png

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Tue Oct 25, 2022 9:15 pm
by iss
@Stan: Cool! I like the pattern test, 64/256 detection and MAX_ERRORS improvements.
Not sure about new 'blink' mode (IMO the speed-up comes mainly because no in-test blinking).
I'll test asap and make the changes 'official' :wink:

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Wed Oct 26, 2022 8:30 am
by Stan
I also do not like the blinking :D I'm leaving it you or anybody who has something in mind about it.

>>>(IMO the speed-up comes mainly because no in-test blinking).
Not only. Looks like every arduino's digitalWrite(); digitalRead(); does a bunch of operations that can last several microseconds and we have a lot of them for every DRAM read or write.
https://roboticsbackend.com/arduino-fast-digitalwrite/

Whereas a direct read from a port even needs a delay because DRAM is not so fast:

/* column */
setBus(c);
PORTB &= ~(1 << PORTB_CAS);

/* bit read value */
__asm__("nop\n\t"); //62.5ns
__asm__("nop\n\t"); //62.5ns
__asm__("nop\n\t"); //62.5ns
__asm__("nop\n\t"); //62.5ns
ret = PINB & (1 << PINB_DO);

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Wed Oct 26, 2022 2:24 pm
by iss
Stan wrote: Wed Oct 26, 2022 8:30 am... arduino's digitalWrite(); digitalRead();
Yes, this is well known and direct port I/O is the way, which I made already in assembler... :wink:

Re: DRAMARDUINO - Dram tester with Arduino

Posted: Fri Oct 28, 2022 1:11 pm
by Stan
Good. Just saying that skipping the LED blinks is not the real reason for the speed up.