Memory Experiments

 

https://github.com/merlinmarrs/Video-Memory

This project started with an ambitious board combining ADC, DAC and SRAM. 

 

There were too many issues so I broke the board down into two parts: a memory board and a ADC/DAC board. This allowed me to isolate things and proceed in a step by step way.

I discovered that the memory needed a WR signal inbetween clock address refreshing, and for the second board that my op amp choice was inappropriate and needed to work around it (by using the DAC only as an R2R ladder and skipping the op-amp for the ADC input). 

 

During assembly I found that several 0 ohm jumpers were causing shorts. I also tore out the 8 pin header but applying too much force accidentally. Otherwise the switch system was very effective to test my understanding of the memory chip operation. It can essentially record a series of button manipulations for about 1.5 minutes.  

Here is my first successful “recording” of a sine wave through the ADC and into SRAM and play back from SRAM through the DAC :

BOARD ERRATA:

-need last bit of address counter (cuts memory in half !)

-more jumpers should be broken out for testing (like alternative op amp for input, clk for various chips, etc.)

-leds burn out when activated and output plugged into 5V at the same time…

-GND and 5V switched on the two boards 🙁

-Wrong op amp spec’d. The ADC1175 suggests the LMH6702MF and a choke between power supplies. 

-caps on all ICs

-the LEDs I set up on the microchip are plugged into ADC…

-Add enable header on microchip board

-power LED on the ADC board

-add a MSB and LSB next to LEDs on memory board **

I calculated how much I could store in the 4K of the SRAM I am currently using, and it would be a single line of a 600×800 screen at 40Mhz pixel frequency…

So what can I do with this ? I could record 4,000 pixels of a static image (i.e. lower the resolution of the image to 100×400 for instance) and then play it back. This would require me to control the sampling of the ADC with the CLK pin of the ADC1175 for every X pixels, somehow synchronized with the VGA in signal (use timing signals of an incoming VGA signal set), or to generate a custom VGA output signal with different timing using the VGAX library. 

Some important references : 

nootropicdesign.com/video-experimenter/build

gieskes.nl/visual-equipment/?file=gvs1

I am looking into what I could draw on screen with only 4K memory at a 20MHz clock.

EEPROM and SD cards are also interesting before reaching the holy grail of magnetic recording media of course…

I have the AT28C256F-15TU EEPROM chip which has 256K x 8 bits (enough to at least store an entire 600×800 static screen) and the ADV7125STZ50 8 bit triple HS video DAC. 

https://www.mouser.fr/datasheet/2/268/doc0006-1108095.pdf

https://www.mouser.fr/datasheet/2/609/ADV7125-1503638.pdf

I’d like to have a standalone arduino VGAX based board (https://github.com/smaffer/vgax) which can output 120×60 pixels and reads from internal SRAM and can record and playback. With 256K I could record a static image on screen at a higher resolution or a low resolution short video.

I have already made an SD card image saving board: 

Just realized what I’m trying to do is called a frame grabber and it’s a massive PCB :

https://en.wikipedia.org/wiki/Frame_grabber#:~:text=A%20frame%20grabber%20is%20an,or%20a%20digital%20video%20stream.&text=Historically%2C%20frame%20grabber%20expansion%20cards,to%20interface%20cameras%20to%20PCs.

 

*********************************************************************************

I have designed a similar memory board but using a 256K EEPROM chip in place of the  SRAM and with VGA connectors to begin testing images. (There do appear to be larger SRAMs, going up to 16MB. There are obviously large flash memories in SD format going into the GBs which may also be interesting to play with).

-Added out VGA to work with VGAX library (not sure if need a second microchip to handle just the memory stuff?)

-Added a 16MHz resonator

-With two 8 bit counters to have the full 13 bits to control this time.

-EEPROM will keep a recording after power down.

-can control buffers with microchip

Just learned that EEPROM is probably the slowest…

Just a thought but I could save control signals for the 0c74 instead of saving actual pixel information…

*************

First test (WORKING):

int switchState = 0;

pinMode(6, OUTPUT); // CLK LED (*)
pinMode(7, OUTPUT); // CLK

pinMode(10, OUTPUT); // WR/RD SIGNAL TO SRAM
pinMode(A3, INPUT); // WR/RD SWITCH (WR HIGH, READ LOW)

pinMode(8, OUTPUT); // WR LED
}

// the loop function runs over and over again forever
void loop() {

switchState = digitalRead(A3);

// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (switchState == LOW) {
// WR selected on switch so turn WR LED on and send a LOW to SRAM

digitalWrite(8, HIGH);
//
digitalWrite(10, HIGH);
digitalWrite(6, HIGH); // 
digitalWrite(7, HIGH); // 
delay(10);
digitalWrite(10, LOW);
digitalWrite(6, HIGH); // 
digitalWrite(7, HIGH); // 
delay(10); // 
digitalWrite(10, LOW);
digitalWrite(6, LOW); 
digitalWrite(7, LOW); 
delay(10); // 
digitalWrite(10, HIGH);
digitalWrite(6, LOW); // 
digitalWrite(7, LOW); // 
delay(10); // 

}
else {
// READ selected on switch so turn WR LED OFF on and send a HIGH to SRAM
digitalWrite(10, HIGH); // STAYS HIGH THE WHOLE TIME
digitalWrite(8, LOW);
//
digitalWrite(6, HIGH); // 
digitalWrite(7, HIGH); //
delay(20); // 
digitalWrite(6, LOW); // 
digitalWrite(7, LOW); // 
delay(20); //

}

}

This is what it produces:

Second test (WORKING): 

int switchState = 0;

// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin 13 as an output.
pinMode(6, OUTPUT); // CLK LED (*)
pinMode(7, OUTPUT); // CLK

pinMode(10, OUTPUT); // WR/RD SIGNAL TO SRAM
pinMode(A3, INPUT); // WR/RD SWITCH (WR HIGH, READ LOW)

pinMode(8, OUTPUT); // WR LED
}

// the loop function runs over and over again forever
void loop() {

switchState = digitalRead(A3);

// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (switchState == LOW) {
// WR selected on switch so turn WR LED on and send a LOW to SRAM

digitalWrite(8, HIGH);
//
digitalWrite(10, HIGH);
digitalWrite(6, HIGH); // turn the LED on (HIGH is the voltage level)
digitalWrite(7, HIGH); // turn the LED on (HIGH is the voltage level)
delayMicroseconds(1);
digitalWrite(10, LOW);
digitalWrite(6, HIGH); // turn the LED on (HIGH is the voltage level)
digitalWrite(7, HIGH); // turn the LED on (HIGH is the voltage level)
delayMicroseconds(1); // wait for a second
digitalWrite(10, LOW);
digitalWrite(6, LOW); // turn the LED on (HIGH is the voltage level)
digitalWrite(7, LOW); // turn the LED on (HIGH is the voltage level)
delayMicroseconds(1); // wait for a second
digitalWrite(10, HIGH);
digitalWrite(6, LOW); // turn the LED on (HIGH is the voltage level)
digitalWrite(7, LOW); // turn the LED on (HIGH is the voltage level)
delayMicroseconds(1); // wait for a second
// wait for a second
}
else {
// READ selected on switch so turn WR LED OFF on and send a HIGH to SRAM
digitalWrite(10, HIGH); // STAYS HIGH THE WHOLE TIME
digitalWrite(8, LOW);
//
digitalWrite(6, HIGH); // turn the LED on (HIGH is the voltage level)
digitalWrite(7, HIGH); // turn the LED on (HIGH is the voltage level)
delayMicroseconds(1); // wait for a second
digitalWrite(6, LOW); // turn the LED on (HIGH is the voltage level)
digitalWrite(7, LOW); // turn the LED on (HIGH is the voltage level)
delayMicroseconds(1); // wait for a second

}

}

And here are some shots of what three different speeds (10ms, 10microseconds, 1 microseconds) as delay in the Arduino code :

 

***********************************************************************

Third test (NOT WORKING):

I recorded a sine wave at 100KHz (with WR activated on the microchip board) with the ADC being clocked at 10KHz. I made sure I had the ADC selected with the right buffers and then sent this 8 bit sequence to the memory where I recorded it with a new Arduino code:

void setup()
{
DDRD = B11111111; // set PORTD (digital 7~0) to outputs
DDRB = B11111111; // set PORTB (digital 7~0) to outputs
}

void loop()
{
if((PINC & 0b00001000)==0)
{
PORTD = B11111111; // set PORTD pins (digital 7~0) high
PORTB = B00000000; // set PORTD pins (digital 7~0) low
PORTD = B00000000; // set PORTD pins (digital 7~0) low
PORTB = B11111111; // set PORTD pins (digital 7~0) high

}
else
{
PORTB = B00000100; // WR PULLED HIGH SO TURNED OFF
PORTD = B11111111; // set PORTD pins (digital 7~0) high
PORTD = B00000000; // set PORTD pins (digital 7~0) low
}
}

/*
CLOCK:
_____ _____
| ` | | |
___| |___| |____

WR:
_________ ____________
` | |
|___|

*/

I then switched to the DAC with the buffers and switched into READ mode on the microchip board.  Now the 8 bit sequence was being translated back into a sine wave. I took this sine wave and amplified it with an audio amp and sent it to the three color channels combined with an arduino running the VGAX pattern code without the colors plugged in and only H and V SYNC.

I got this on the screen :

Here is the tentacular and unoptimized setup :

To make this actually easy to use, I need to:

-have the microchip control the buffers and the ADC clocking based on the switch state.

-have the memory and adc on a single board.

-have a VGAX out setup integrated into the memory board.

-have an op amp on the ADC board to amplify the output signal !!

-have a dial change the speed of the playback / sampling of recording.

*******************************************

I added an external crystal and set the AVR dude Fuses to : Ext. Crystal Osc.8.0 – ___MHz 16K CK/14 CK + 65 ms. 

I added F_CPU 16000000UL ABOVE the #include. 

Forgot that if you don’t add 0b before a binary number nothing happens with the pins !

Here is the code that still isn’t working :

/*
* eeprom board v.2.c
*
* Created: 06/02/2022 09:19:50
* Author : Jonah
*/

#include <avr/io.h>

int main(void)
{

DDRC = 0b00000000; // PC3 is the switch for WR (0) or RD(1)

DDRD = 0b11111111; //PD5 is CLK and PD4 is !OE

DDRB = 0b11111111; //PB0 is the LED and PB2 is !WE

while (1)
{

/*
BYTE WRITE: A low pulse on the WE or CE input with CE or WE low (respectively) and OE high initiates a write
cycle. The address is latched on the falling edge of CE or WE, whichever occurs last. The data is latched by the first
rising edge of CE or WE. Once a byte write is started, it will automatically time itself to completion. Once a
programming operation is initiated and for the duration of tWC, a read operation will effectively be a polling operation.
*/

if((PINC & 0b00001000)==0) // WRITE MODE: (CE -> TIED LO); !WE -> TOGGLE ; !OE -> HI ; CLK -> TOGGLE
{
PORTD = 0b00010000; // !OE -> HI ; CLK -> LO
PORTB = 0b00000000; // !WE -> LO
PORTB = 0b00000001; // !WE -> LO (to make the pulse width at least 100ns)
PORTB = 0b00000101; // !WE -> HI
PORTD = 0b00110000; // !OE -> HI ; CLK -> HI (next address must come a max of 50 ns following !WE going HI?)

}

/*
READ: The AT28C256 is accessed like a Static RAM. When CE and OE are low and WE is high, the data stored at
the memory location determined by the address pins is asserted on the outputs.
The outputs are put in the highimpedance state when either CE or OE is high. This dual-line control offers designers flexibility in preventing bus
contention in their system.

*/

else // READ MODE : (CE -> TIED LO); !WE -> HI ; !OE -> (TOGGLE ? OR JUST LO?) ; CLK -> TOGGLE
{
PORTB = 0b00000101; // !WE -> HI
PORTD = 0b00100000; // !OE -> LO ; CLK -> HI
PORTD = 0b00000000; // !OE -> LO ; CLK -> LO
}
}
}

**********************************************************************************

One question I have is: does the EEPROM require OE to go on and off when reading unlike the SRAM I worked with in the previous board ?

Another question is, how long does the EEPROM need to write a byte ? It talks about “access times of 150ns”…?

Is it OK I have CE tied low the whole time ?

As a next step I will try doing all of this but very slowly to see if that works. 

*EDIT : tried slowing everything down and I’m still not able to load anything into the memory :(. I just get 5V and little pops of ground after writing ground into every cell of the memory. This is after changing !OE toggle and always ON also. 

I did get the VGAX code running though so at least that works. 

ERRATA:

-the labeling of WR and RD are confusing, when the switch is to the RD side it is in WR mode etc. 

-the VGA parts are COMPLETELY wrong. 

-I need to order 16MHz of this format (I took one from a dead Arduino board). 

-the text is too small and came off during cleaning.

 

TROUBLESHOOTING AT28C256 EEPROM:

-Need to wait a second before doing and writing or reading,

-Need to either wait the maximum time for the EEPROM to write (Write Cycle Time Max AT28C256 = 10ms) or poll 1/0 7 to wait until it matches what you sent it before starting another write cycle.

-The device may be locked (even though the devices should ship unlocked) :(. The unlock sequence is :

LOAD DATA AA
TO
ADDRESS 5555

LOAD DATA 55
TO
ADDRESS 2AAA

LOAD DATA 80
TO
ADDRESS 5555

LOAD DATA AA
TO
ADDRESS 5555

 

LOAD DATA 55
TO
ADDRESS 2AAA

LOAD DATA 20
TO
ADDRESS 5555

LOAD DATA XX
TO
ANY ADDRESS(4)

LOAD LAST BYTE
TO
LAST ADDRESS

 

************************

Here are some thoughts I have on the SRAM device :

Do I want addressed to loop or not ? (Add inverter if want to loop)

  >> Make it optional with a jumper, this expands the possibilities of experimenting.

Max sample rate I can get from SRAM ? 
>>Looks to be around 20MHz if the read time is 50ns ?
What happens if I slow a recorded signal down with a knob, what visual effects produced ?
>> I need a bunch of recorded stuff and a super fast clock or else I just output bands everyonce and a while.
Bigger SRAM same brand? need more counters?

  >> Check out this super fast 1Mx8bit SRAM

61-64WV10248EDBLL-276598.pdf (mouser.fr)

Two memories ? Feedback from one memory possible ?
Jumpers to either have vgax doing syncs or input vga.
Record at slow speed play back at high speed ? Keeps theme of time and computation…
How have vgax send clock and wr signal for memory circuit while doing vgax timing ? Or have separate clocks (high speed resonator) and sync somehow ? ( Or generate my own sync sign also in logic ?)
How actually use and function with two vgas ?
It would be cool to be able to record an image, or parts of a series of images, on an input vga signal and then play them back at different speeds and doubled with the original. This seems really challenging to do accurately but could be cool to stretch an image or sample every line from an animation.

Also would be cool to be able to output blocky animations based on memory. Could vgax output memory values? Then could compose.

Could the vgax do a kind of low fi screen capture ? This is a ripoff of gieske though…
Could this thing be a composition machine, where you slowly switch 8 pin dip switches and take a “photo” of each finished byte ? Then play back at higher speeds?
I started this board wanting to learn about memory. What have I learned ? Could have button to reset address counters, knob for clock speed, but what other Params?
Could take memory and output it as pattern by vgax ?
Do all first with Arduino analog read  ?? Why is this better than Arduino ? What advantage, what has it allowed me to learn ? Faster ? Physicalized memory space ?
**********
Retried this code modified slightly from this tutorial : https://scanlines.xyz/t/tutorials-for-generating-video-sync-signals-with-arduino/104

#define LINE_CYCLES 508
#define HSYNC_CYLCLES 60
#define VSYNC_LINES 2
#define FRAME_LINES 525
#define PIXEL_FREQ 1

volatile int linecount;

void setup(){
pinMode(7, OUTPUT); // VSync
pinMode(9, OUTPUT); // HSync
pinMode(6, OUTPUT); // Pixel frequency

//inverted fast pwm mode on timer 1
TCCR1A = _BV(COM1A1) | _BV(COM1A0) | _BV(WGM11);
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10);

ICR1 = LINE_CYCLES; // Overflow at Cycles per line
OCR1A = HSYNC_CYLCLES; // Compare high after HSync cycles

//timer 0 in CTC mode
TCCR0A = _BV(COM0A0) | _BV(WGM01) ; // Toggle pin on each cycle, no CPU clock prescaling/
TCCR0B = _BV(CS00); // no clock prescaling
OCR0A = PIXEL_FREQ; // go super fast

TIMSK1 = _BV(TOIE1); // Enable timer overflow interrupt
}

ISR(TIMER1_OVF_vect)
{

if (linecount == 0) PORTD = PORTD ^ 0x80; //Toggle the most significant bit of port D.;
else if (linecount == 2) PORTD = PORTD ^ 0x80; //Toggle the most significant bit of port D.;
else if (linecount == 3) PORTD = PORTD ^ 0x80; //Toggle the most significant bit of port D.;
else if (linecount == FRAME_LINES) linecount = 0;
linecount++;
}

void loop(){}

*******************

Works well. Also tried generating my own V and H sync with logic and a 4040 counter from this tutorial : https://hackaday.io/project/9782-nes-zapper-video-synth-theremin/log/32271-vga-sync-generation

It didn’t work for me. The reset of the 4040 didn’t want to be connected to anything but GND, otherwise the whole thing was inoperational. 

I also messed around again with floppy disk writing. I got the floppy disk motor turning, plugged the index into step, activated the drive select, and connected direction to either 5V or GND. I soldered a connector for the 5 wires froming from the recording magnets. I tried blasting them with a sine wave added to a 10KHz square wave but saw no sign of the signals when playing back the floppy. 

I have a new plan: Triple SRAM device for copying and pasting a loop of very blocky “video” :

 

*****************************************************************************************

Here’s what I learned :

version 1 :

I need to make a smd breakout board for chips or order DIP versions so that I can do tests first. This would save a lot of time designing and redesigning boards. The idea for a minimal integrated board was good though. Break more pins out.

version 2 :

BOARD A : I need to make a more stable way to solder pin headers to the card so they don’t rip off easily. I should use buffers to protect the LEDs. There are also way too many jumpers between the the counter and SRAM. 

BOARD B : The op amps don’t work. The DAC doesn’t work as I wired it. I forgot to connect the CLK of the DAC.  

It’s a mess to connect the two boards, make the right connections. The two boards need to be integrated. 

version 3 :

The EEPROM doesn’t work, is it locked ? I also used the wrong VGA pins. 

version 4 :

It’s a beautiful board but the DAC was VERY challenging to solder by hand. I think the level of complexity and ambition of the board was a little bit too high for this production method. I think I should head back to a board that is easy to assemble, easy to test and understand. 

version 5: 

The idea : using buffers I can have LEDs display what is in the memory while also outputing analog output. There are fewer jumpers than in earlier versions. I am planning to use the inverter to control the SRAM WR which appears to be possible based on the datasheet. Simplified DAC with R2 ladder, I can control A12 with a switch and have an A11 LED now. I got rid of the VGA functionality – this makes things simpler. I chose switches over shunts to make connections.

I want to make 3 of these boards, ABC, so that they can each record in two 4K memories, and then do cool logic transformations and save the results too. Connecting the ADC to the SRAM inputs requires 8 jumpers, and I’ve done away with 8 pin dip switches. To manually set data you connect the jumpers to the spare + and – headers. 

I would like the decisions to be guided by how I could practically use this device to “record” 8 bits of data / an analog signal for a given period of time (based on the clock speed) and then play it back (while modifying the clock speed manually, and overwriting portions of the memory, possibly from another pair of memory boards) to display on a screen (with another board handling the VGA signals and optionally sharing its clock with this board to keep things in sync). I want to move to something that produces output ASAP, and away from endlessly redesigning these boards looking for something perfect. (If this works I want to make 3, then a specialized VGA board too).

I’ve added reverse polarity protection, a STEP button, which is hardware debounced, to manually advance one address at a time. I kept the op-amp modular so that it could be used to amplify analog in or out. I switched out the edge accessible thumb pots for normal pots, so this thing is no longer really stackable.

Not sure exactly how they stack (but many things accessible on the edges) though and not sure if I should have a battery included or not so that it remembers what it recorded…

Version 5 UPDATE :

Thoughts on possible  version 6 additions :

Backup battery to record option ?

8pin dip switch with header somewhere on board?
Question I have to resolve with current version :
What can I record (in analog and in digital) and for how long ?
What does it look like on the screen with and without a generated pixel clock to do the sync?
Going at pixel frequency speed I can draw different repeating textures on the screen when I record very slowly and then speed it up :

Patterns are repeating, it’s like a texture. Sending a non-repeating signal, like the arbitrary function signal which leaves a non-repeating pattern on screen, seems like a cool thing to try. Another option is to have a single block of memory but to jump around in how you address it somehow ?
How fast and how slow can it go ?
With a 10K resistor and a 0.1uF for the CD4046 I have a max sampling speed of 1Khz that is barely enough to represent a 100 Hz sine wave.
Apparently this max is called the Nyquist frequency :

Nyquist Frequency=Fmax = SampleRate/2

The SRAM module IS61C64AL can run up to 20MHz according to the datasheet (https://www.issi.com/WW/pdf/61C64AL.pdf)

When I feed it the 3MHz pixel frequency from the modified VGAX it can record a 1.5MHz sine wave and play it back ! The problem when it is going slow is that it just outputs bands every now and then. It could act as a memory of a control signals which would change parameters in a circuit which generates more interesting output. (It could even control an analog computer like this https://the-analog-thing.org/ ).
The other option would be to have a super fast clock that is connected to the V and H sync, one that I can divide and use to control recording of a large SRAM memory.
Would second mem board be cool ?
Not unless I get a bigger SRAM I think and daisy chain a series of 8 bit counters :
https://www.mouser.fr/datasheet/2/198/62-65WV10248EALL-BLL-462620.pdf
VERSION 5 UPDATE :

Here are the issues :
-I added a reset for the counters to go back to address 0. It takes a while to kick in though – I think because it resets the counter but not the 8 bit storage register ?
-I added an LED to show when ADD21 is activated.
-the 74F541 does not like 5V. I replaced it with an 74HCT254 and pulled the DIR pin HIGH.
-the ADC1175 operates at 4.5-5.5V ! (I will test it’s max speed – supposedly 20MHz by powering it with 5V)
-One pin connection missing on 8 pin dip switch
-The phase shifter sucks and the amp doesn’t currently work.
-CS should be held down and not toggled with WE.
-RCO for cascading counters was not working at higher frequencies – I switched to sending the last Qout of each counter to the CLK in. 
-I don’t have a way of taking 5V analog signals and stepping them down to 3.3V.
-The memory should default to floating (instead of ground?) so that I can re-record over previous stuff. (Currently when I re-record, if a pin is not set it defaults to being black and just erasing everything).
-need a 3.3V to 5V booster if you want to interface with another 5V memory. It would be nice to have an in-line 8 plug so I don’t need to plug in each wire one by one…
-I can’t currently take VGA in at 400×800 from a computer (amplified) and saved it into the memory (it’s pixel clock is at 40MHz, I set the function generator to 4MHz). But I can record an image imperfectly from the VGAX color out at around 1.3038210 MHz.
-I need to amplify at the input and the output (and ideally be able to offset them both and up and down – especially to hit the middly of the CMOS threshold between low and hi if I want to record in image in b&w with a single bit). The next version of the board would have two amps.
-When I play back a recording, each time the memory restarts at zero, the frame of the video moves. (To solve this I need the freq divider, AND chip and inverter).
-Pin 11 of the ADC should be connected to 3.3V while pin 13 should be connected to 5V.
Possible improvements:
-a 5V power in with 3.3V LDO so I can power things with both ?
-if I want to upload something to memory, and then change to outputing, I have to disconnect all the wires that were connected to it previously. I should have a 74HCT254 Bus transciever that can change directions to disconnect a set of 8 wires from the memory. ALTERNATE OPTION : Just keep everything plugged in and turn off ADC?
-Maybe an LED that tells me I’m recording (easy not to notice that it’s not in recording mode and then connect it to outputs that are pulling it up and down). 
-Would be cool to be able to select which chunk of memory I’m replaying over with two knobs that control the start point and end point. (This could be two comparators connected to two pots ?)
Developements:
I can load values into the memory from Arduino’s PRGMEM like so:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/* TO LOAD DATA INTO THE MEMORY */

#include <avr/pgmspace.h>

byte myByte;

#define IMG_PIRATE_BWIDTH 30
#define IMG_PIRATE_HEIGHT 60
//data size=900 bytes
const byte img_pirate_data[IMG_PIRATE_HEIGHT*IMG_PIRATE_BWIDTH] PROGMEM={
0, 7,255,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 63,252, 6, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 0, 0, 0, 0, 0,
2,255,112, 96,129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15,222, 2, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
255,240, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
252, 65,144, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0,
248, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,144, 0, 0, 0, 0, 0, 0,
65,132, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0,
0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
36,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0,
65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0,
8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0,
16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 0, 0, 0, 0, 0, 0, 0, 0,
32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,130,168,160, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,138, 42, 32, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34,136, 32,130, 0, 0, 32, 0, 0, 0, 1, 69, 64, 80, 0, 20, 5, 4, 0,
32, 0, 0, 0, 0, 0, 0, 8,170,160, 0, 0,170,170, 40, 42,170,136, 0, 0, 0, 0, 64, 17, 4, 68, 64, 16, 68, 0,
0, 0, 0, 0, 0, 0, 0,162, 10, 2,170,170,170,170,168, 32, 0, 34, 0, 0, 0, 0, 65, 65, 4, 16, 84, 16, 68, 0,
64, 0, 0, 0, 0, 0, 10,130,171,239,255,238,170,170,160,162,170,162, 0, 0, 0, 0, 68, 1, 4, 16, 65, 16, 64, 0,
36, 0, 0, 0, 0, 0, 8, 42,187,250,170,170,187,238,250, 0, 0, 34, 0, 0, 0, 0, 69, 80, 80, 68, 20, 5, 4, 0,
0, 0, 0, 0, 0, 0, 34,170,255,234,170,170,171,187,178, 60, 0,170,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
152, 0, 0, 0, 0, 0, 0,171,254,170, 0, 2,186,255,248, 61, 3, 2, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1,196, 0, 0, 0, 0, 10,187,254,168,112, 4,171,191,248, 54, 0, 40,136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 8,198, 96, 0, 0, 42,191,250,163,240, 14,174,255,254,136,170,138, 34,128, 1,128, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,139,191,250,168, 53, 26,171,255,252,138, 34,186,162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 42,251,250,170,170,170,174,191,254, 34,187,174,232,128, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 2,170,174,255,186,170,170,187,255,255, 34,234,251,170,128, 0,128, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 0, 0,138,187,187,171,170,238,187,191,255,138,175,255,238, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 10,239,255,186,186,170,238,239,255,224,235,255,250, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 46,175,255,255,238,186,190,255,255,248,171,255,250,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,170,191,255,255,250,171,187,239,255,254, 42,255,238, 32, 0,144, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 42,238,255,255,251,170,174,187,255,254,174,190,234,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1,128, 0, 0,174,187,255,255,254,235,171,255,255,254, 10,171,170,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 32, 0, 0, 0,138,174,255,255,255,186,163,255,255,255,162,186,186,128, 0, 4, 36, 0, 0, 0, 0, 0, 0, 0,
0, 4, 0, 0, 0, 0, 43,187,239,255,254,170,234,170,174,234, 34, 42,168, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 10,174,186,255,251,171,168,128, 10,128, 2, 34,226, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0,
0, 0, 64, 0, 0, 0, 2,171,239,187,254,234,170, 40, 0, 0, 0, 40, 32, 0, 0, 2,170,168, 0, 0, 0, 0, 0, 0,
0, 0, 40, 0, 8, 0, 0, 42,190,239,190,186,128, 0, 0, 0, 0, 0,160, 0, 0, 64,170,170,160, 0, 0, 0, 0, 0,
0, 2,160, 0, 60, 0, 0, 42,171,190,250,168, 0, 0, 10,170,168, 0, 0, 0, 0,128, 16, 10,168, 0, 0, 0, 0, 0,
0, 42,128, 2,240, 0, 0,130,234,186,170,160, 0,170,170,170,174,128, 0, 0, 0, 6, 0,170,170,128, 0, 0, 0, 0,
0,170,128, 47, 0, 0, 0, 10, 42,170,170,128, 42,170,175,255,250, 32, 0, 0, 1, 0, 42,170,170,168, 0, 0, 0, 0,
10,170, 64, 40, 48, 0, 0, 0, 40,162,170, 0,171,255,255,255,234,136, 0, 0, 2, 0, 2,170,170,170, 0, 0, 0, 0,
170,170, 0,160,176, 0, 0, 0, 0,130,168, 2,191,186,175,250,170, 32, 0, 0, 1, 56, 0,170,170,170, 0, 0, 0, 0,
170,170,130,130, 64, 0, 0, 0, 2, 8,168, 10,239,255,234,170,170,136, 0, 0, 16, 60,128,170,170,170, 0, 0, 0, 0,
170,170,128,138, 0, 60, 0, 0, 0, 8, 32, 2,255,255,255,234,186,128, 0, 0, 0, 7,232, 42,170,170,128, 0, 0, 0,
170,170,160,168, 0,252, 0, 0, 0, 0, 0, 10,175,255,255,251,170,128, 0, 0, 0, 0, 26, 42,170,170,128, 0, 0, 0,
170,170,168, 8, 0,240, 32, 0, 0, 0, 0, 8,190,187,235,238,168, 32, 0, 0, 0, 0, 4,170,170,170,160, 0, 0, 0,
170,170,160,170, 0,240,192, 0, 0, 0, 0, 0,170,254,238,170,186, 0, 0, 0, 0, 0, 72, 42,170,170,168, 0, 0, 0,
170,168, 0,170,128, 2, 64, 0, 0, 0, 0, 0, 2,171,170, 58,160, 0, 0, 0, 0, 0, 2, 10,170,170,170,128, 0, 0,
170,170, 42,170,168, 3, 0, 0, 0, 0, 0, 0, 2, 10, 42, 8, 0, 0, 0, 0, 0, 0, 1, 42,170,170,170,168,128, 0,
170,170,170,170,169, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 18, 42,170,170,170,170,168, 0,
170,170,170,170,168, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54,128, 0, 42,170,170,170,170,170, 0,
170,170,170,168, 36, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,188, 96, 15,170,170,170,170,170,170, 0,
170,170,170,170, 0,130, 14, 96, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 95, 0, 63,234,170,170,170,170,170,128,
170,170,170,170,170,170,143,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0,249,240, 63,234,170,170,170,170,170,128,
170,170,170,170,170,170,144, 63,240, 0, 0, 0, 0, 65, 0, 0, 0, 15,192, 0, 63,144, 63,170,170,170,170,170,170,160,
170,170,170,170,170,170,175,239,240, 0, 1, 0, 0, 2, 24, 0, 0, 15,252, 0, 7,228, 15,218,170,170,170,170,170,168,
170,170,170,170,170,170,168,255,240, 48, 64, 0, 13,129, 1, 0, 0, 3,255, 0, 0,114, 15,250,170,170,170,170,170,170,
170,170,170,170,170,170,170, 62,192,188, 0, 0, 63,126,192, 36, 0, 2,127,208, 0,185,191,250,170,170,170,170,170,170,
};

void setup() {

Serial.begin(9600);

pinMode(7, OUTPUT); // I/O 8
pinMode(6, OUTPUT);
pinMode(5, OUTPUT);
pinMode(4, OUTPUT);
pinMode(3, OUTPUT);
pinMode(2, OUTPUT);
pinMode(1, OUTPUT);
pinMode(0, OUTPUT); // I/O 0

pinMode(8, OUTPUT); // CLK

for (byte k = 0; k < 200; k++) {
myByte = pgm_read_byte_near(img_pirate_data + k);
Serial.print(myByte);
digitalWrite(8, LOW); //CLK LOW
delay(1);
PORTD = myByte;
digitalWrite(8, HIGH); //CLK HIGH
delay(1);
}
for (byte k = 0; k < 200; k++) {
myByte = pgm_read_byte_near(img_pirate_data + 200+ k);
Serial.print(myByte);
digitalWrite(8, LOW); //CLK LOW
delay(1);
PORTD = myByte;
digitalWrite(8, HIGH); //CLK HIGH
delay(1);
}
for (byte k = 0; k < 200; k++) {
myByte = pgm_read_byte_near(img_pirate_data + 200+ k);
Serial.print(myByte);
digitalWrite(8, LOW); //CLK LOW
delay(1);
PORTD = myByte;
digitalWrite(8, HIGH); //CLK HIGH
delay(1);
}
for (byte k = 0; k < 200; k++) {
myByte = pgm_read_byte_near(img_pirate_data + 200+ k);
Serial.print(myByte);
digitalWrite(8, LOW); //CLK LOW
delay(1);
PORTD = myByte;
digitalWrite(8, HIGH); //CLK HIGH
delay(1);
}

Serial.print(“FINISHED”);
}

void loop() {

}

 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

I have a different Arduino to trigger the memory on each pixel and generate the sync signals :
/* TO TRIGGER MEMORY CLOCK EACH PIXEL AND GEN VGA SYNCS */

#define LINE_CYCLES 508
#define HSYNC_CYLCLES 60
#define VSYNC_LINES 2
#define FRAME_LINES 525
#define PIXEL_FREQ 1

volatile int linecount;

void setup(){
pinMode(7, OUTPUT); // VSync
pinMode(9, OUTPUT); // HSync
pinMode(6, OUTPUT); // Pixel frequency

//inverted fast pwm mode on timer 1
TCCR1A = _BV(COM1A1) | _BV(COM1A0) | _BV(WGM11);
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10);

ICR1 = LINE_CYCLES; // Overflow at Cycles per line
OCR1A = HSYNC_CYLCLES; // Compare high after HSync cycles

//timer 0 in CTC mode
TCCR0A = _BV(COM0A0) | _BV(WGM01) ; // Toggle pin on each cycle, no CPU clock prescaling/
TCCR0B = _BV(CS00); // no clock prescaling
OCR0A=PIXEL_FREQ;

TIMSK1 = _BV(TOIE1); // Enable timer overflow interrupt
}

ISR(TIMER1_OVF_vect)
{

if (linecount == 0) PORTD = PORTD ^ 0x80; //Toggle the most significant bit of port D.;
else if (linecount == 2) PORTD = PORTD ^ 0x80; //Toggle the most significant bit of port D.;
else if (linecount == 3) PORTD = PORTD ^ 0x80; //Toggle the most significant bit of port D.;
else if (linecount == FRAME_LINES) linecount = 0;
linecount++;
}

void loop(){

}

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
UPDATE:
I finally have a screen I can use to subtract the memory contents with :

#include <VGAX.h>

VGAX vga;

void setup()
{
vga.begin();
vga.clear(11);
}
void loop(){for (int y=0; y!=VGAX_HEIGHT; y++) {
for (int x=0; x!=VGAX_BWIDTH; x++) {
vga.putpixel(x, y, 3);
}}}

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

I now can use this with an AND chip and my own function gen frequency and output from the SRAM !

And here are some of the images I’m getting (using an AND also for the clock coming from the signal gen) :

And here I am trying to record VGA…
…from VGAX (120×60):

 

…and from a computer VGA at 800×600 passing along the sync signals:

Here was what was onscreen :

Test card - Wikipedia

I can reproduce this reliably with :
-op amp taking memory and amplifying it
-a pixel clock at 1.007MHz (pixel clock for 640×480 of 25.175 MHz divided by 25)
But it kinda turns on and off and also jumps around on the screen for some reason.
I also found out I could use the vertical sync along with a counter (taking as input a 4MHz fucntion generated square wave) and a bunch of AND gates to essentially only record only every X frame and store it in memory. This meant I can save way more frames. Getting the right spacing for the frames will be key to be able to store a short video. 
UPDATE 1:
I can now save a short video : 695.45 kHz (This is the slowest I can go and still almost see an image) on the function gen AND’ed with the top 4 frequency divisions of the vertical sync. This makes for a burst of image recording every X number of frames.  I then amplify the output to make it visible on screen (and speed the clock up to 695.48 kHz). One problem is that it looks like everything is in fast forward and it’s barely possible to interpret the images. The other issue is once the video starts again from memory its frame moves with regards to the screen. 
UPDATE 2:
If the reset is connected to the inverse of the freq subdivision of the vertical sync signal AND’ed with the address 20, it will play the image in a loop and always place it in the same part of the screen ! 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TESTING MAX ADC SPEED:
I’m not sure what to make of this as the signal was super noisy but, I can “follow” a sine that is at 50Hz sampling it at 5MHz fine. I’m not sure what conclusions to draw from this…

VGA controller board :

-Attiny(?) 
-several clock speeds to chose from
-knob to select diff screen resolutions
-PLL to sync to input VGA? Use an XOR to see delay with signal and then get closer to it ?
-easy setup to pass input VGA syncs to an output VGA
-filters to knock out certain frequencies to tune into what I want. 

 

ANALOG BOARD:

Based on the Analog Thing functionality (summing, multiplying, comparing, integrating, differentiating, etc.) along with counters to divide the screen by powers of two !

 

UPDATE:

Working now on a next version of the 16MB board. The idea is to fix the issues in the 16MB board, add more functionality, and also to move towards a finished board that is more plug-and-play with regards to recording VGA signals and less of a prepared instrument for testing. It’s a test to see if I could make something that behaves like a product.

One question is if it requires an analog function generator or not, and to what degree the machine is mono-functional or not. (Though I think if it could record video reliably and display to a screen that would already be not bad.)

Fixes :

  • A21 LED added
  • Top and bottom bias of ADC now controllable with pots
  • op amps on input and output both with variable gain and bias
  • fixed 5V and 3.3V power (ADC and op amps need 5V) with onboard LDO.
  • got rid of phase shifter and 8 pin dip switch
  • CS no longer tied to WR on SRAM.
  • various enables broken out so they can be turned on an off with external control 64KBSRAM
  • counters daisy chained with last address going to clock input of the following counter (no longer using RCO)
  • Replaced 74*541 with 74*245 (so it would have big footprint to let wires pass under but work with 3.3V)
  •  Added VGA in and out connectors and made pass thru mode for input.
  • Added f divider, AND, and NOT gates.

This board should allow me to test the idea of having a control board chroreograph a sequence of memory operations, and allow me to begin testing the analog board with a stable (not breadborded) video recorder.