I have an EPROM Emulation project that uses a 45ns NVSRAM module which is being used by another host computer for it's operating program. I am handling the NVSRAM contents via the Teensy 3.5.
I have 7 PI5A100WEX SPDT analog switches, rated at ~7ns switching period - NVSRAM is on the COMmon terminals. Two of these handle the 8 data bits, 4 are used for the 15 address pins, and the last one handles CE, OE, and WE.
On my scope I've been able to refine the coding/timing to get a single byte write to the NVSRAM within a 45ns window. This is the fastest I can get it to run before there isn't enough time for the address/data pins to settle and enough time for the WE to go low for full byte programming.
The host processor is an HD6303YCP 8-bit microcontroller running at 3MHZ.
In the scope screen shot you can see each of the clock signals. The top is the 6303 clock, the second is the CE line (from the 6303 to the NVSRAM), the third is the write pulse from the T3.5 and the 4th is the signal that throws the analog switches.
The 6303 controls the NVSRAM output by using the CE line (OE cycles with the system clock - this is read-only for the 6303). The 6303 is accessing the NVSRAM when this line is pulled low.
There is about 340ns of time (between the green cursors, second row) where the 6303 isn't accessing the NVSRAM. This is on the lower end of typical - this ranges up to around 500ns but inconsistent.
The idea here is to use an interrupt to wait until the CE line goes high and then be able to sneak in a read or write in that time when the 6303 isn't accessing the NVSRAM.
I came across another page here showing how one guy was able to get the interrupts on this board down into the 132ns range.
https://forum.pjrc.com/threads/45413-ISR-latency-Teensy-3-1-and-3-6
But the code there is unintelligible for myself at a *rookie* level here and everything else I have been finding refers to the attachinterrupt function which is HORRIFICALLY slow and pinging in at around 550ns latency. Obviously this T3.5 can do MUCH better than that and I am going to need that capability to finish this project. 130ns interrupt latency + 45ns for the write/read cycle and I'm still under 200ns which in no case have I ever seen this 6303 access the NVSRAM between cycles any faster than about 300ns. Ironically, the read/write is so short that the 6303 doesn't fault but occasionally it drops communication through its SCI port during a read/write sequence. Fortunately there is no bus contention because of the switches but the 6303 does "hiccup" if you strip it's access to the NVSRAM in the middle of a read, LOL..
I have attached the source here: It is a very simple program that mostly does nothing other than just sit there so this ONE interrupt will be the only one I'll need to use. Address/Data read/write requests are handled through the USB/serial port via a serial.available code block in the loop().
Thank you so much in advance for your time and assistance with this!! This is the last step in completing this project and I'm very excited to put this to full use!
I have 7 PI5A100WEX SPDT analog switches, rated at ~7ns switching period - NVSRAM is on the COMmon terminals. Two of these handle the 8 data bits, 4 are used for the 15 address pins, and the last one handles CE, OE, and WE.
On my scope I've been able to refine the coding/timing to get a single byte write to the NVSRAM within a 45ns window. This is the fastest I can get it to run before there isn't enough time for the address/data pins to settle and enough time for the WE to go low for full byte programming.
The host processor is an HD6303YCP 8-bit microcontroller running at 3MHZ.
In the scope screen shot you can see each of the clock signals. The top is the 6303 clock, the second is the CE line (from the 6303 to the NVSRAM), the third is the write pulse from the T3.5 and the 4th is the signal that throws the analog switches.
The 6303 controls the NVSRAM output by using the CE line (OE cycles with the system clock - this is read-only for the 6303). The 6303 is accessing the NVSRAM when this line is pulled low.
There is about 340ns of time (between the green cursors, second row) where the 6303 isn't accessing the NVSRAM. This is on the lower end of typical - this ranges up to around 500ns but inconsistent.
The idea here is to use an interrupt to wait until the CE line goes high and then be able to sneak in a read or write in that time when the 6303 isn't accessing the NVSRAM.
I came across another page here showing how one guy was able to get the interrupts on this board down into the 132ns range.
https://forum.pjrc.com/threads/45413-ISR-latency-Teensy-3-1-and-3-6
But the code there is unintelligible for myself at a *rookie* level here and everything else I have been finding refers to the attachinterrupt function which is HORRIFICALLY slow and pinging in at around 550ns latency. Obviously this T3.5 can do MUCH better than that and I am going to need that capability to finish this project. 130ns interrupt latency + 45ns for the write/read cycle and I'm still under 200ns which in no case have I ever seen this 6303 access the NVSRAM between cycles any faster than about 300ns. Ironically, the read/write is so short that the 6303 doesn't fault but occasionally it drops communication through its SCI port during a read/write sequence. Fortunately there is no bus contention because of the switches but the 6303 does "hiccup" if you strip it's access to the NVSRAM in the middle of a read, LOL..
I have attached the source here: It is a very simple program that mostly does nothing other than just sit there so this ONE interrupt will be the only one I'll need to use. Address/Data read/write requests are handled through the USB/serial port via a serial.available code block in the loop().
Thank you so much in advance for your time and assistance with this!! This is the last step in completing this project and I'm very excited to put this to full use!
Code:
#define Data0 2
#define Data7 9
#define ADR0 31
#define ADR7 38
#define ADR8 14
#define ADR14 20
#define OE 22
#define CS 21
#define WRITE_EN 23
#define SWITCH 10
unsigned int integerValue=0;
char incomingByte;
int progaddress = 0;
void setAddress(int address) {
uint8_t xlow = address & 0xff;
uint8_t xhigh = (address >>8);
for (int pin = ADR0; pin <= ADR7; pin += 1) { //sets output pins with data bits
digitalWriteFast(pin, xlow & 1);
xlow = xlow >> 1;
}
for (int pin = ADR8; pin <= ADR14; pin += 1) { //sets output pins with data bits
digitalWriteFast(pin, xhigh & 1);
xhigh = xhigh >> 1;
}
}
byte readEPROM(int address) {
for (int pin = Data0; pin <= Data7; pin += 1) { //set ardino data pins to read
pinMode(pin, INPUT);
}
setAddress(address); // call to sub to set the address bits
byte data = 0;
digitalWriteFast(SWITCH, HIGH);
digitalWriteFast(CS, LOW); //Turns the SRAM ON
digitalWriteFast(OE, LOW); // SRAM OE ON
for (int pin = Data7; pin >= Data0; pin -= 1) { // reads data on SRAM outputs into Arduino
data = (data << 1) + digitalReadFast(pin);
}
digitalWriteFast(OE, HIGH); //disables SRAM data outputs
digitalWriteFast(CS, HIGH); //Turns off the SRAM
digitalWriteFast(SWITCH, LOW);
return data;
}
void writeEPROM(int address, byte data) {
digitalWrite(CS, LOW); //Turns SRAM ON
digitalWrite(OE, HIGH); //Output Enable OFF
setAddress(address);
for (int pin = Data0; pin <= Data7; pin += 1) { //sets data pins on arduino to OUTPUT mode
pinMode(pin, OUTPUT);
}
for (int pin = Data0; pin <= Data7; pin += 1) { //sets output pins with data bits
digitalWrite(pin, data & 1);
data = data >> 1;
}
digitalWriteFast(SWITCH, HIGH);
digitalWriteFast(WRITE_EN, LOW); //pulls the SRAM W line low for a moment to program the data
digitalWriteFast(WRITE_EN, LOW); //pulls the SRAM W line low for a moment to program the data
digitalWriteFast(WRITE_EN, LOW); //pulls the SRAM W line low for a moment to program the data
digitalWriteFast(WRITE_EN, HIGH);
digitalWriteFast(SWITCH, LOW);
digitalWriteFast(CS, HIGH);
for (int pin = Data0; pin <= Data7; pin += 1) { //sets data pins on arduino to INPUT mode
pinMode(pin, INPUT);
}
}
void setup() {
Serial.begin(9600);
pinMode(CS, OUTPUT);
digitalWrite(CS, HIGH);
pinMode(OE, OUTPUT);
digitalWrite(OE, HIGH); //SRAM output enable pin. HIGH = disabled
pinMode(WRITE_EN, OUTPUT);
digitalWrite(WRITE_EN, HIGH); // SRAM WRITE PIN
pinMode(SWITCH, OUTPUT);
digitalWrite(SWITCH, LOW);
for (int pin = Data0; pin <= Data7; pin += 1) { //set ardino data pins to read
pinMode(pin, INPUT);
}
for (int pin = ADR0; pin <= ADR7; pin += 1) { //sets address pins on arduino to OUTPUT mode
pinMode(pin, OUTPUT);
}
for (int pin = ADR8; pin <= ADR14; pin += 1) { //sets address pins on arduino to OUTPUT mode
pinMode(pin, OUTPUT);
}
}
void loop() {
Last edited: