My attempt at 23K256 SRAM drivers. Includes 8-bit version.
Duane Degn
Posts: 10,588
I've been thinking about doing something like this for several years.
Every so often there is some discussion on this forum about using multiple memory chips in parallel.
When the CS came out I purchased some extra 23K256 SRAM chips. I figured I'd want to learn how to use the 23K256 chips that are on the C3 so I might as will have some extra for other Propeller projects.
I also wanted more memory to use with my machine vision project so I attempted an eight chip/bit SRAM driver.
I stacked the eight DIP chips on top of each other and soldered the common pins together. I soldered the serial in pins to a male header and connected each serial out pin to the male header through a 110 ohm resistor (for each of the eight chips). I also connected the Vdd, Vss, chip select and clock pins to the male header.
I soldered a 10 uF capacitor to the top of the stack.
Here's a picture.
Five of the chips have their serial out pins connected to their serial in with a resistor. The other three chips just have a wire connecting serial in and serial out. (I changed the resistors to wire on the three in to see is the resistors were causing a problem. They weren't.) It turned out to be important to change the data pins to inputs immediately after after giving a read command. Otherwise there was a conflict with the output from the Prop pin and the output from the SRAM.
After writing a one chip driver and testing it on all eight chips, I wrote the eight bit driver. These chips are the easiest SPI devices I've worked with. There aren't very many commands and there are just three modes to the chips. Both of my drivers only use the sequential mode.
Since there are eight chips in parallel each byte is written as one bit per chip. This means the SRAM memory address increments just once for every eight bytes written to, or read from, it.
I looked at the Spin 23K256 driver from the C3 downloads but I haven't looked at other 23K256 drivers.
Now that I've finished my drivers, I'll take a look at any others in the OBEX to see if mine are worth posting there.
Both the single chip and eight chip drivers share the serial in and serial out pins. The single chip driver will need some serious rewriting to use with the C3. If I can't find any fast C3 drivers for these chips, I'll probably modify my driver to work with the C3. I'd be surprised if someone hasn't already written a good (fast) driver for the C3's 23K256 chips.
These SRAM chips don't wear out like EEPROMs, right? I want to use these chips for a circular video capture buffer and the entire chip will be written to several times a second. This is the type of application SRAM is good for, right?
Here are the drivers. They both write a 1,024 block of data to the SRAM, read the data back, compare it with the original data and then write the same block to the next section of SRAM. The drivers continue to write the block of data until the entire SRAM has been tested. If there aren't any errors, the program asks to be turned off.
The 8-bit driver could be faster if the data pins were on Propeller pins 0 through 7. The shift instruction in both the read and write routines could be deleted. This would speed things up a lot since presently the Hub window is missed by one instruction.
Sometime I need to learn the tricks of using the counters for clock signals. I think a counter controlled clock would also speed up this driver.
As is, the 8-bit driver can read and write faster than 1 million bytes a second (@80MHz). The eight 32K chips grouped together makes for 256KBytes of memory.
PASM is awesome!
Duane
Single chip version:
Eight chip version:
Edit(3/11/15): I have deleted the archives SramSingleTest110528d - Archive [Date 2011.05.28 Time 11.26].zip
and SramByteTest110528a - Archive [Date 2011.05.28 Time 11.26].zip
I plan to upload this program or an improved version to my GitHub account.
If there isn't a replacement on GitHub send me a message and I'll make sure to upload the replacement code.
Every so often there is some discussion on this forum about using multiple memory chips in parallel.
When the CS came out I purchased some extra 23K256 SRAM chips. I figured I'd want to learn how to use the 23K256 chips that are on the C3 so I might as will have some extra for other Propeller projects.
I also wanted more memory to use with my machine vision project so I attempted an eight chip/bit SRAM driver.
I stacked the eight DIP chips on top of each other and soldered the common pins together. I soldered the serial in pins to a male header and connected each serial out pin to the male header through a 110 ohm resistor (for each of the eight chips). I also connected the Vdd, Vss, chip select and clock pins to the male header.
I soldered a 10 uF capacitor to the top of the stack.
Here's a picture.
Five of the chips have their serial out pins connected to their serial in with a resistor. The other three chips just have a wire connecting serial in and serial out. (I changed the resistors to wire on the three in to see is the resistors were causing a problem. They weren't.) It turned out to be important to change the data pins to inputs immediately after after giving a read command. Otherwise there was a conflict with the output from the Prop pin and the output from the SRAM.
After writing a one chip driver and testing it on all eight chips, I wrote the eight bit driver. These chips are the easiest SPI devices I've worked with. There aren't very many commands and there are just three modes to the chips. Both of my drivers only use the sequential mode.
Since there are eight chips in parallel each byte is written as one bit per chip. This means the SRAM memory address increments just once for every eight bytes written to, or read from, it.
I looked at the Spin 23K256 driver from the C3 downloads but I haven't looked at other 23K256 drivers.
Now that I've finished my drivers, I'll take a look at any others in the OBEX to see if mine are worth posting there.
Both the single chip and eight chip drivers share the serial in and serial out pins. The single chip driver will need some serious rewriting to use with the C3. If I can't find any fast C3 drivers for these chips, I'll probably modify my driver to work with the C3. I'd be surprised if someone hasn't already written a good (fast) driver for the C3's 23K256 chips.
These SRAM chips don't wear out like EEPROMs, right? I want to use these chips for a circular video capture buffer and the entire chip will be written to several times a second. This is the type of application SRAM is good for, right?
Here are the drivers. They both write a 1,024 block of data to the SRAM, read the data back, compare it with the original data and then write the same block to the next section of SRAM. The drivers continue to write the block of data until the entire SRAM has been tested. If there aren't any errors, the program asks to be turned off.
The 8-bit driver could be faster if the data pins were on Propeller pins 0 through 7. The shift instruction in both the read and write routines could be deleted. This would speed things up a lot since presently the Hub window is missed by one instruction.
Sometime I need to learn the tricks of using the counters for clock signals. I think a counter controlled clock would also speed up this driver.
As is, the 8-bit driver can read and write faster than 1 million bytes a second (@80MHz). The eight 32K chips grouped together makes for 256KBytes of memory.
PASM is awesome!
Duane
Single chip version:
Eight chip version:
Edit(3/11/15): I have deleted the archives SramSingleTest110528d - Archive [Date 2011.05.28 Time 11.26].zip
and SramByteTest110528a - Archive [Date 2011.05.28 Time 11.26].zip
I plan to upload this program or an improved version to my GitHub account.
If there isn't a replacement on GitHub send me a message and I'll make sure to upload the replacement code.
Comments
Yes, a counter controlled driver would speed it up, especially if it was on P0-P7 for the data lines. I made something similar (FlexMem) that takes four chips.
This will work well for your use of a circular capture buffer, because for that application always have to read/write 8 byte chunks is not an issue.
You don't have to worry, these SPI ram's don't wear out.
Bill
I just reread your FlexMem thread. You mentioned reading/writing a long at a time. I think I ought to consider adding read/write long methods to my driver. Since I can only address the SRAM in groups of eight bytes, I could treat these as two longs and probably gain some speed.
@Jazzed, Wow, our schematics are practically identical. (Not that there are very many options of wiring these chips.)
What value of resistors are you using? I think individual capacitors on each chip is a better alternative to my single capacitor. The stack of DIP chips didn't lend itself to individual capacitors. The chips seem to work fine sharing the one capacitor.
I hope you do try my code on your SpinSocket-SRAM boards. Hopefully my code will be useful to you (and others). I'm always glad when I hear others are using my code. I feel like the time I spent writing the code was even more productive.
BTW: The 23K256 chips cost $1.14 each (when buying 25 at once from Digi-Key). The stack of eight chips cost $9.12.
Duane
PS I just hit "Preview Post". The schematic in the code block doesn't look very good in the preview. Hopefully it will look better in the actual post.
You still need one more Cqpacitor 0.1uF=100nF
To have good decoupling
I'll probably be adding code to my current Flash JCACHE driver after I test with your code ... I left this option open because I knew I would eventually add to it. I read 32 to 256 bytes at a time with that for loading the data (and flushing with SRAM on such boards). To me it is a pretty big waste to spend so much time setting up the address just to get 1 byte or long. Don't get me wrong there is a time and place for everything of course, and if you're not using a cache, there is not much choice.
I finally found my PCBs and will go build boards now. I'll keep you up to date.
Due to the architecture of the chips, you have to use 8 bytes as the minimum packet read or written, so you might as well enjoy the speed!
I'm getting lots of output with incremental pattern pages.
At the end of each block I see "errorCount = 0"
Is there anything else I should be looking for that would indicate a problem?
Thanks.
@Sapieha, I wondered if I also needed a 0.1uF capacitor. I've learned here on the forum that small capacitors can respond faster to a voltage drop. I don't mind adding one 0.1uF capacitor. Do you think one will be enough for the intire stack? Or do I need one for each chip? I'm really hoping not to have to solder a capacitor to each chip.
@jazzed, Are the resistors to protect the SRAM or the Propeller? I think the "crow-barring" can be avoided if the Prop data pins are made inputs before the clock falls on the final bit of a command to the chips (my driver does not do this). This way the neither the Prop or the SRAM have output pins (at least acting in an output state) connected together. I'd need to modify my driver to treat the last bit of a command differently than the others.
I was having trouble with my driver when I has several instructions after the falling clock. I'd give the chips a read status command and the data returned by the SRAM was jibberish (I forgot to save an image from the logic analyzer). I had to make sure and set the Prop's data pins to inputs very quickly after the final bit of the read command.
@Bill, As I noted in the top post, three of the chips don't currently have resistors between the input and output pins on the SRAM. I haven't had trouble yet either. It does seem like a good idea to use resistors since unless you're really careful, both the SRAM and the Prop can have the data pins set as outputs. I would think something could be damaged if one side's output was high while the other's was low.
As I told jazzed, I think the safest way of sharing the input and output pins on the SRAM is to set the Props data pins as inputs before the SRAM starts to output. Since the SRAM reads on the rising clock and doesn't set its output pins until the falling clock, the Prop's pins could be set as inputs prior to the final falling clock edge of a read intruction to the SRAM.
I'm probably worrying about this too much. But as I said before, I've had trouble waiting too long in setting the Prop's data pins to inputs.
Why the heck is this stuff so fun?
Duane
The test program fills one buffer with incrementing numbers. This buffer is then used to fill sections of the SRAM. The program checks the read data against the original data used to fill the chip. If the data doesn't agree an error message is displayed and the errorCount variable is incremented.
It sounds like it's working fine. The other thing to check is to make sure the status bytes (bits turned to bytes since they are for eight chips) agrees with the configure bytes. I think they are supposed to be $00, $FF,
$00, $00, $00, $00, $00, $FF (sequential mode with hold turned off).
I'm glad you tried out the program.
Thanks,
Duane
I'll probably make a test package that is like my SDRAM test and post it back here.
My pins and the baud-rate will most likely be different, but you'll have more memory tests to try.
When two devices output different states to a single node (the same trace) a fight ensues.
During the fight, you will see a "middle state" at about 1.6V between transitions on an o-scope.
That's how you know something has to change. Heat is another indication of a problem.
Without the resistor one of the drivers will eventually blow up (can take a while).
The "middle state" was likely the jibberish data you were seeing before changing your code.
The resistor is there to protect the loser sort of like the EMT team in an ambulance.
Too much "coddling" (big resistor value) is not good since the node signal quality can be terrible.
It's kind of like someone expecting to fail which becomes a self-fulfilling prophecy.
That's the best generic explanation i can give. In electrical terms it's just ohms law and RC time.
As You have stacked them that close YES - as entire stack will produce same -TRANSIENTS pattern.
AS I said in other threads -- I will say one time more ----> That small capacitors are not to prevent Voltage drops -- Them are for SHORT transients on Top of Applied voltage to IC's. For Voltage drops are BULK capacitors in range on 10uF and more.
That is second function
In first place: Them are for prevent suppressing signal by SRAM's other pin as some of them have some settle time. And need be placed Propeller to SRAM's Input pin connected directly and SRAM's Output pin connected to Propeller by one resistor NOT to BIG -.- And as You write 120R are good enough NOT to give to much change time for that signal.
@Jazzed, It would be great if you made more memory tests. This kind of stuff is new to me. I remember now that your SDRAM (I have one of your boards) had walking ones and zeros.
I once tried making my own SDRAM driver. I soldered some wires to some old DIMM sticks I had. It didn't work. I don't know if the problem was hardware of software. One the hardware side, I had six inch wires going from the DIMM to the Propeller Proto board. One the software side, it was my second PASM program after flashing some LEDs. I'd say I'd set things up pretty well for failure. It was still fun. This was back when I was waiting for your SDRAM board to come out at Gadget Gangster.
@Sapeiha, Thank you for clarifying about transients. If I understand correctly transients are short burst of over voltage right? I just looked on Wikipedia and it appears the electronic pulses in circuits cause oscillations of both under and over voltages. I think I had just thought of these oscillation as under voltages. Thank you again.
Yes -You understand correct. - BUT still I will say it in other words.
You can See that burst as AC voltage on top of DC And as You know capacitor leads AC voltage and that give short for it.
Ah, yes, that does make more sense when you say that way. I do understand now. Thank you very much.
My RamPage modules are wired a very similar way with four chips each. Two of them can be combined for an 8 bit bus like you have here.
I'm also using 100 Ohm resistors in order to get the full 20 MHz operation...
I think you could do without any resistors, but I put them in there just to give a bit of protection in case something goes wrong...
This was my second project using stacked DIPs.
I saw Ben Heck use a stack of shift registers for one of his LED arrays. I wanted to try the stacked chip method myself. Here's the outcome.
I'm not sure why you bother with a custom circuit board for your PropRGB when a stack of DIPs and a rat's nest of wires gets the job done. I give you permission to market the idea.
Before starting my SRAM driver, I debated about modifying your Spin SQI driver to a PASM driver to use with you Flash Point modules. But after looking over the SQI data sheet I thought I'd try something simpler. I also wanted some memory that didn't wear out (to use as a video capture buffer). I think your RamPage has SRAM on it too. I'll have to take another look at those.
More fuel for the resistor debate.
Thanks for taking time to comment here. I value your opinion very much.
Duane
If people always use the provided driver unmodified (and that driver doesn't cause collisions), and the traces are very short, you would not need any resistors at all.
In longer traces/wires using a small series resistor is desirable because of inductive effects.
The only reason for a small series resistor in a properly functioning system is to prevent overshoot (or undershoot in the high to low transition). See http://en.wikipedia.org/wiki/Overshoot_(signal) Allowing such overshoot to go unchecked when it exceeds about 0.7V beyond power and ground can reduce the life of the signal's target device input. It can also cause minimal excess power dissipation and EMI problems.
You will have to change these lines in spisram_cache_ssr.spin to your pin numbers:
SCSPIN = 25 ' SpinSocket-SRAM module
SCLKPIN = 24 ' SpinSocket-SRAM module
You will probably have to change SpinSocketSramTest.spin _xinfreq to your frequency.
The package must be built with BSTC or BST with non-parallax extensions (haven't tried homespun).
I use this run.bat file as: run.bat SpinSocketSramTest.spin com6
bstc -d %2 -p0 -Ograux -L c:\bstc\spin %1
Detailed memory tests should be designed with the architecture in mind, but I've found the types of tests included in the package to be very good at detecting faults in different types of RAM.
The spisram_cache_ssr.spin file also includes the SpinSocket-Flash cache driver and programming code. You probably won't have to worry about it for a while.
http://www.ipsilog.com/content/index.php?id=17&no_cache=1&tx_ttnews[tt_news]=8&tx_ttnews[backPid]=3
My memory test was just to make sure the Propeller was communicating with the SRAM. I can see the need to make sure all the bits of memory are working correctly.
The driver I wrote pushed my knowledge of PASM to its current limits. I was very pleased that it actually worked.
Have you described how to use your cache driver? I'm not asking you to explain it here. I remember seeing something about a cache in your SDRAM thread. I'm not sure how one uses a cache. I kind of thought with the Propeller one had to manage all the memory stuff directly.
I see in the driver you just posted you read the JEDEC ID of the chips. Do 23K256 chips have JEDEC IDs? I don't remember seeing anything about them in the data sheet. I was amazed at how simple the 23K256 data sheet was.
I once wrote an all Spin driver for some Winbond memory chips (I think I've told you this). I remember it had a JEDEC ID and that one could use the ID to determine the memory's size at runtime. Mike Green's driver uses the JEDEC information in his driver. I was too new to the Propeller (and microcontrollers in general) to understand how to use Mike's driver.
The SRAM looks like it uses 1.8V. Would you need level shifters to use it?
Indeed. I'm very pleased it worked too. It helped me get moving on my SRAM project which was just collecting dust, so I really appreciate that.
Spin programs can use cache driver's simple read/write pub methods. I've not described it in detail except for comments in the code for methods like PUB writeLong(madr,val) for example. If you need more detail than that I would be happy to provide it.
Nick made a really nice video on using SDRAM with SPIN. See it here: http://vimeo.com/19761389
Languages like ZOG, Catalina, and David Betz's XBASIC use cache for running programs from C3 and other devices. SDRAM works with ZOG. ZOG and Catalina will both support SpinSocket-Flash and SRAM soon.
XBASIC supports SpinSocket-Flash (and soon SRAM) with a cache. XBASIC can run with only HUB memory too.
The propeller does handle all memory access (cache uses a COG). It's just that a cache is faster in most cases where synchronous clock block transfers are available. Boards without clock block transfer memories would still benefit from a cache, but would not load/store data as quickly.
This is a new feature and my boards have Flash. I've not tested the driver with a non-flash board yet. If this is causing trouble please forgive me.
Typically that will be a minimum voltage specification. The maximum voltage will most likely be over 3.3V and an interface would not need special shifters.
1. 1.5V to 1.8V: IP12A512C-T
2. 2.7V to 3.6V: IP12B512C-T
It has double density than 23K256.
Use 160 pasm instruction to read 160 words into a cog ram in full speed - 8 microseconds, using 320 longs of cog space (170 longs left for rest of code)
Then we have 24 microseconds to display this. Seems to need three cogs. Two for display lines (even and odd) and third as a graphic driver. It may have 24 microseconds to write to ram between reads and it can also write to buffer when vblank
This is another one mad idea by beginner I don't know if it can be done. 18 pins needed for sram, 8 for vga output=26, still 6 pins left (for communication with second propeller?)
And if graphic driver cog can use 2 of these pins to set vsync and hsync signals, we can have 256 colors.
Something like this would be great. I'm afraid it's beyond my present programming abilities.
One of my "mad ideas" was to use SRAM with some sort of camera for machine vision experiments. I even added an 8-bit bus to my Parallax Laser Rangefinder in hopes of capturing a high resolution image from it.
Since making the initial stack of 23K256 chips show at the beginning or this thread, I've made several others.
Three of the boards are stackable. The stackable boards are in two pieces so the pins can all be in a line or side by side as shown. You can see the 4x4 right angle header that lets the two halves share chip select, clock, Vdd and Vss with the other half board.
It turned out these boards were very sensitive to power fluctuations. With one of the boards, when all eight chips' data pins would try to go high all at the same time (by outputing $FF), the chips would reset and and I'd get errors after the attempted $FF read. A couple of extra caps solved the problem (each board already had several bypass caps).
I tried to make the boards so they would fit next to each other, so I think they could be used in a 16-bit bus configuration.
The data pins come out the bottom of the boards. CS, CLK, Vdd and Vss connections are made with the right angle four position female header. Obviously none of the SRAM were completely hooked up in the above photos.
My plan was to use them with Jazzed's TetraProp boards to distribute the task of analyzing any captured image. The above pictures show two TetraProp boards under SRAM boards.
The C3 uses a counter to trigger the various SPI devices' select lines. I've wondered about using this type of system to select from multiple stacks of SRAM.
This project is currently on a back burner (low priority).
I think your idea to use all but a few pins of a Prop for graphics purposes is fine. I don't mind using a second Prop as a graphics slave. I have several projects where a second Prop controls a resource intense graphics display while another Prop takes care of the other tasks.
One such project displays data in my (chemistry) lab on a 19" 1600x1200 VGA monitor. The driver for the monitor (found in the Propeller Tool library, written by Chip Gracey) uses six cogs. This has made a huge difference in my lab by keeping a long list of the data collected available for easy review.
My other graphic slave projects involve LCD touchscreens I've purchased from Rayman. I have one of his 3.5" screens (driven by his PTP) and several of his 4.3" screens. I believe these touchscreens are driven in a similar fashion as VGA. I know Rayman has used external RAM with his video drivers, but I haven't spent much time figuring out how they work (not that I'd know how they worked if I had spent a lot of time trying to figure it out).
I thought about something like this: set a counter to clock a stack of 23k256, then execute 160 instruction like this:
320 longs wasted, but now you have one line of display data in cog.
And in this model it seems that one propeller will use 3 cogs for vga, one for communicating with second propeller, and one to execute main LMM program. One cog still free. Second chip can do sound, keyboard and mouse services and other i/o
Cheapest is SPI_SRAM, currently comes to 32KB (Microchip. OnSemi) or 64KB (IPSiLog)
Speeds are moderate at 20MHz
FLASH now comes in QuadSPI, and also DDR clocked from Spansion & Macronix - a LOT of storage 64MB+, for moderate cost
and still in 8 pin packages.
These parts have much higher output bit rates, as they are wider, and can output data every 10ns with a 50MHz DDR clock
Then there are non volatile SPI options
( not so cheap, but available and an option for development, and they are faster which may matter )
Cypress NVSRAM - SPI to 40MHz 8KB/ 32KB/128KB at 40MHz
Everspin MRAM, 32KB / 128KB / 512KB (4MBit) 40MHz - all now at Digikey. (Everspin claim unlimited read/writes ? )
and FRAM from Ramtron and Fujitsu, but lower MHz and finite cycles.
Propeller #1:
1 cog main LMM/XMM machine
1 cog cache driver
3 cogs video driver
1 cog communication with second propeller
2 cogs still free...
Propeller #2
- audio out
- audio/analog joystick in
- keyboard
- mouse
- MIDI
- RS232 to PC
- eeprom
- SD card
Boot first Propeller #2, then boot Propeller #1 from it