SRAM Controller

ylp88

Senior Member
I have got around to setting up a breadboard with a 32K x 8 SRAM chip (W24257).

Of the 13 address lines, I have interfaced 8 of them (thus I can only use 256 bytes of the 32K) and tied the others low. 6 of the IO pins are connected to PORTB of a 16F628 while the remaining 2 are connected to PORTA. /WE and /OE are also connected to PORTA while /CS is grounded via a resistor.

I have managed to get a program on the PIC which receives a serial byte from a PC which specifies a SRAM address. The PIC then shifts this address though the shift-register onto the address pins. Anotehr byte is then sent from the PC which is a data byte and this is placed on the data lines. The program then configures the control lines and then attempts to read the data back from the SRAM chip and serially transmit the data back to the PC.

No luck, however...

Through debugging, I have determined that address data is correctly received by the PIC and correctly placed on the address lines by the shift-register.

My question comes about how to configure the control lines to write to the SRAM, and then later, how to configure them to get the data back out.

After shfting out the address, my current program configures the lines as follows:
1) Set /OE high
2) Set /WE low
3) Place data onto IO lines
4) Set /WE high
5) Set /OE low

This is based on my interpretation of &quot;Write Cycle 1&quot; (refer pg. 7), as described in the Winbond datasheet for the device: <A href='http://www.datasheetcatalog.com/datasheets_pdf/W/2/4/2/W24257A-12.shtml' Target=_Blank>External Web Link</a>.

The read part of the program is as such:
1) Set /WE high
2) Set /OE low
3) Read data from IO lines
4) Set /OE high
5) Set /WE low

This is based on my interpretation of &quot;Read Cycle 3&quot; (refer pg. 6), again, as described in the Winbond datasheet for the device. Have added the /WE controls, though as logic would have my set them accordingly, anyhow. Albeit it is not in the timing diagram, it is mentioned in the datasheet's &quot;Truth Table&quot; (refer pg. 2).

The data comes back to my PC corrupt, however. Examination of the binary equivalent of the ASCII characters that are returned show no common errors.

I suspect a few things. Most suspect is my interpretation of the timing diagrams for the read/write cycles. Am I controlling these lines correctly? In the right order? Of the right levels? I can only assume that at 4MHz, each instruction takes 100ns - much longer than any time parameter of the device, although have allowed for some idle cycles just in case.

the second suspect is that the chip is faulty but I will try and get a replacement tomorrow (or ASAP). None the less, I do not suspect this nearly as much as the way I am controlling my control lines.

Any help is appreciated...

If needed, I can also post the program but I have decided not to unless it is requested becuase it may cause more confusion, especially due to its long size. It is <i>quite </i> well documented (in my opinion), however, so feel free to ask for it.

<b><i>ylp88 </b> </i>
 

hippy

Technical Support
Staff member
<i>After shfting out the address, my current program configures the lines as follows:

1) Set /OE high
2) Set /WE low
3) Place data onto IO lines
4) Set /WE high
5) Set /OE low </i>

That looks okay to me, the chip latches the data as /WE goes high. The /OE then going low should then put the SRAM data on the bus so you can verify the write. Don't forget to make the PICAXE data bus an input between steps 4 and 5.

<i>The read part of the program is as such:
1) Set /WE high
2) Set /OE low
3) Read data from IO lines
4) Set /OE high
5) Set /WE low </i>

The last step 5 is probably causing some problems as it writes to the device.

In summary ...

Keep /CS, /OE and /WE high at most times, and keep the bus as an input.

To read -

1) Set address
2) Make bus input
3) Set /WE high
4) Set /CS low
5) set /OE low
6) Read bus
7) Set /OE high
8) Set /CS high

To write -

1) Set Address
2) Set /WE high
3) Set /OE high
4) Set /CS high
5) Make bus an output
6) Put data on bus
7) Set /CS low
8) Set /WR low
9) Set /WR high
10) Set /CS high
11) Make bus input

Some steps may be skipped because the lines will normally be high and /CS can be kept low.

Edited by - hippy on 18/04/2006 22:07:00
 

hippy

Technical Support
Staff member
I will be interested in knowing how you get on. I've spent the last two days making a PICmicro 16F88 generate PAL composite video, which it is doing remarkably well using the internal oscillator at 8MHz, but the problem is not enough processing time to do a character bit map lookup between text lines and a lack of SFR (RAM) to store pixel bitmaps, which limits the display size to 3 lines of 8 chars. using the same bit map per line, I've managed to squeeze 7 lines of 10 chars out of it ( 8 lines works but the display looked a bit cramped ), and at 16MHz it should be able to deliver even more.

Image : http://homepage.ntlworld.com/the.happy.hippy/picaxe/pal.jpg (31KB)

My plan now is to store the bit map in external SRAM, built-up when new data arrives by serial ( the display blanks on updates like the ZX80 did ! ) and then just churn through the bit map data ...<code><pre><font size=2 face='Courier'>.-----------------------------------------------------.
| .-----------------------------------------------. |
| | .--------. | |
| | .-----&gt;| INC |------------------. | |
| | | .--&gt;| CLR |---------------. | | |
| | | | `--------' | | | |
| | | | .--------. .-----^--^-----. | |
| | | | | B7 |---===---| D7 A0-10 | | |
| | | | | B6 |---===---| D6 | | |
| | | `---| A5 B5 |---===---| D5 /OE |&lt;--' |
| | `------| A4 B4 |---===---| D4 | |
| `---------| A3 B3 |---===---| D3 /WR |&lt;-----'
`------------| A2 B2 |---===---| D2 |
RX &gt;--------&gt;| A1 B1 |---===---| D1 |
.---| A0 B0 |---. -| D0 |
| `--------' | `--------------'
| 16F88 |
| `---===---.---&gt; Composite Video
`--------------------===---' </font></pre></code> Thanks for mentioning SRAM and PICAXE's which got me motivated on this project in the first place.
 

ylp88

Senior Member
I've tried a few times to get the SRAM working but to minimal success.

I have attempted to simplify the program down to some simpler routines - write 4 known bytes to the SRAM in known consecutive locations (&quot;B&quot; into 0x02, ... , &quot;E&quot; into 0x05). Then the program attempts to read the data back and transmits its results to the PC.

Mixed results but not very good. The shift register appears to be working and the relavant data and control lines set (according to your timing/order suggestions). Results include, in order, an &quot;a&quot; (it is actually a superscript &quot;a&quot; with a line under it), another (funny, as previous) &quot;a&quot;, and then two euro symbols. Unfortunately, the euro is not valid in my program nor is it legal tender in Australia!

I am starting to suspect my SRAM chips which have probably not been kept in an ideal environment. I will attempt to get a few new SRAM chips so that I can see if it makes a difference but with less than half a week until Uni break it over and with lots of work to do, I won't get too much time - although I will endeavour to find time.

Let me know if you have success with your attempts to access the SRAM as I would be delighted to hear of your progress.

Good luck.

<b><i>ylp88 </b> </i>

PS. Your TV/PAL display looks great! A bit out of my league, though, me thinks...
 

hippy

Technical Support
Staff member
<i>Your TV/PAL display looks great! A bit out of my league, though, me thinks... </i>

Just basic bit-banging really. The hard part is finding the timing needed ( I'm still not quite there, even video chip manufacturers say their devices put out different signals ) and making it so. Mind you, I've always enjoyed optimising at the sub-microsecond level ! There's some wobble on the lines, but not suprising with an on-chip osc and 1cm ~= 1uS on a full-size TV. Suffice to say I know a lot more about PAL/NTSC than I ever did - There was me thinking V-Sync was just a pulse ;-)

The Propeller Chip seems to do video this way, using high-speed shift registers.

Not sure when I'll get a chance to implement a full SRAM solution but I'll wire a PICAXE to SRAM on a bread board and see what I can achieve anyway. I'll get back.
 

ylp88

Senior Member
haha... You shouldn't have mentioned the wobble. I just figured it may have been a shaky camera in hand or just one of those screen refresh jitters.

I did get one kit several years ago which had black and white ping pong on a TV screen. VERY primative but it was able to draw sharp edges using a 10MHz crystal. That is, 10MHz to process video data, create an AI (you can play against 4 different difficulty levels) and basic &quot;beeps&quot; when you hit the &quot;ball&quot;.

EDIT: I also though I might ask - is it necessary to control the &quot;latch&quot; pin on the shift register? You havn't done so on your ASCII schematic above but I was following a Silicon Chip schmatic with a 74HC595 and it does...

<b><i>ylp88 </b> </i>

Edited by - ylp88 on 20/04/2006 02:22:41
 

hippy

Technical Support
Staff member
I'd forgotten you'd moved to shift registers ( a single binary counter suits me as it will be serial access always ).

Yes, you will need to control the latch (STcp). It looks rising edge activated so cannot be hard-wired to act as a pass through on the datasheet I skimmed. You also need '595 /OE wired low.

Might be worth trying it tied low incase it does do pass through, and tying SHcp to STcp may work as well, auto-latching after every shift.

If not, you could link '595 CP with SRAM /OE to save an extra I/O line. Although /OE low will bring data out of the chip which may change as the new address is latched in but you won't care because you won't be reading the data bus then. When /OE goes back high the address is latched, SRAM tri-states again.

When you do a proper read and bring /OE low you'll get the data back as expected and the latched address should stay as it was, even when /OE goes back high as you won't have shifted the register being latched.

The alternative is to use a shift register like the '164 which doesn't have latches.

Edited by - hippy on 20/04/2006 03:05:51
 

ylp88

Senior Member
Okay, now I'm getting very confused!

<code><pre><font size=2 face='Courier'> MOVLW 0x00
MOVWF b0
BTFSC PORTB, 0 ; Check if PORTB&lt;0&gt; is high
BSF b0, 0 ; If so, update b0
BTFSC PORTA, 7 ; Check if PORTA&lt;7&gt; is high
BSF b0, 1 ; If so, update b0
BTFSC PORTA, 6 ; Check if PORTA&lt;6&gt; is high
BSF b0, 2 ; If so, update b0
BTFSC PORTB, 3 ; Check if PORTB&lt;3&gt; is high
BSF b0, 3 ; If so, update b0
BTFSC PORTB, 4 ; Check if PORTB&lt;4&gt; is high
BSF b0, 4 ; If so, update b0
BTFSC PORTB, 5 ; Check if PORTB&lt;5&gt; is high
BSF b0, 5 ; If so, update b0
BTFSC PORTB, 6 ; Check if PORTB&lt;6&gt; is high
BSF b0, 6 ; If so, update b0
BTFSC PORTB, 7 ; Check if PORTB&lt;7&gt; is high
BSF b0, 7 ; If so, update b0

MOVFW b0 ; Move the final result into W </font></pre></code>

The data that is retunred to me seem to only be correct for the bits I read from PORTA. However, ALL the data read from PORTB is read as being low.

I have programmed PORTB to be inputs (except the serial RX pin):
<code><pre><font size=2 face='Courier'> MOVLW b'11000000'
MOVWF TRISA ; Set PORTA as outputs, except RA6 and RA7

MOVLW b'11111011' ; Set PORTB as inputs, except RB2 (TX)
MOVWF TRISB </font></pre></code>

I am wondering whether the &quot;three state outputs&quot; of the SRAM chip are having an effect here. Three state refers to high, low and high-Z, right? Maybe the problem? Maybe not?

Any other thoughts?

Ithe interface between the PORTA pins and the SRAM IOs and the PORTB pins and the SRAM IOs are the same - straight connection? Should they have pull-down resistors or be connected via resistors? Seems odd that PORTA does not seem to have this problem, though. I've tried lokking at the 16F628 datasheet for the IO block diagram but that just confuses me...

Any ideas?

<b><i>ylp88 </b> </i>

Edited by - ylp88 on 20/04/2006 06:02:18
 

ylp88

Senior Member
I've also noticed that there is no command:

MOVFW

ie. Move register to W.

Does one exist. I have used it and it seems to compile and work correctly. It seems a bit odd having MOVWF but not having MOVFW. I've seen some examples on websites using it so I decided to use it. Alternative: MOVF F,W ???

<b><i>ylp88 </b> </i>
 

hippy

Technical Support
Staff member
Can't see any reason why the code shouldn't work for reading. Not pulling both /CS and /OE low while reading will leave the SRAM tri-stated and all bets are off for what is read. When both are low though the SRAM should actively drive the lines into PORTA/B and thus they should be readable.

Take a step back and check that the reading code does work when you remove the SRAM and pull the inputs +V/0V via an R.

Check that RP0/RP1 bits are set right so you are accessing the PORTA/PORTB and when setting TRISA/TRISB.

The real problem with this type of issue is that both reading and writing have to work before you see a satisfactory result, and it's difficult to tell if one or both aren't working.

As to &quot;MOVFW sfr&quot; I believe it's an opcode which the assembler accepts for orthoganality and translates into &quot;MOVF sfr,W&quot; ( or whatever it should be ).
 

hippy

Technical Support
Staff member
I've had some luck with a simple 18X and SRAM test circuit ...<code><pre><font size=2 face='Courier'>; .--------------------.
; | .--------. 10K | .----------.
; `--&gt;| I0 O7 |--===--^--&gt;| D0 Dx |- N/C
; | O6 |----------&gt;| /WR |
; | O5 |----------&gt;| /OE /CS |---.
; | O4 |----------&gt;| A4 | |
; | O3 |----------&gt;| A3 | |
; | O2 |----------&gt;| A2 A11 |---{
; | O1 |----------&gt;| A1 : | |
; | O0 |----------&gt;| A0 A5 |---{
; `--------' `----------' _|_ 0V </font></pre></code> <code><pre><font size=2 face='Courier'> SYMBOL A0 = pin0
SYMBOL A1 = pin1
SYMBOL A2 = pin2
SYMBOL A3 = 3
SYMBOL A4 = 4
SYMBOL OE = 5
SYMBOL WR = 6
SYMBOL DO = pin7 </font></pre></code> <code><pre><font size=2 face='Courier'> SYMBOL DI = pin0 </font></pre></code> <code><pre><font size=2 face='Courier'>PowerOnReset: </font></pre></code> <code><pre><font size=2 face='Courier'> pins = %01100000 ' DO=0 /OE=1 /WR=1 A4..A0=0 </font></pre></code> <code><pre><font size=2 face='Courier'> b0 = 0 ' Adr
b1 = $AA ' Val
GOSUB WriteB1ToAddressInB0 </font></pre></code> <code><pre><font size=2 face='Courier'> b0 = 0 ' Adr
GOSUB ReadAddressInB0ToB1 </font></pre></code> <code><pre><font size=2 face='Courier'> END </font></pre></code> <code><pre><font size=2 face='Courier'>WriteB1ToAddressInB0: </font></pre></code> <code><pre><font size=2 face='Courier'> pins = b0 * 8 &amp; %00011000 | %01100000 ' /OE=1 /WR=1 A4=? A3=? A2..A0=0
FOR b0 = 0 TO 7
A0 = bit0
A1 = bit1
A2 = bit2
DO = bit8 ' Lsb of b1
LOW WR
HIGH WR
b1 = b1/2
NEXT
RETURN </font></pre></code> <code><pre><font size=2 face='Courier'>ReadAddressInB0ToB1: </font></pre></code> <code><pre><font size=2 face='Courier'> pins = b0 * 8 &amp; %00011000 | %01100000 ' /OE=1 /WR=1 A4=? A3=? A2..A0=0
FOR b0 = 0 TO 7
A0 = bit0
A1 = bit1
A2 = bit2
LOW OE
b1 = b1/2
bit15 = DI
HIGH OE
NEXT
RETURN </font></pre></code> That's a 64Kx8 wired as a 32Bx1, software configured as 4Bx8 ! The SRAM was normal PC 15nS cache, Made by ISIS, 5V.

Two things I learnt -

1) Don't connect the /WR output from 18X to 0V. No damage done, the PICmicro is robust.

2) Don't get /WR and /OE crossed over.

Edited by - hippy on 21/04/2006 00:06:07
 

hippy

Technical Support
Staff member
FYI, /WE and /OE can both be controlled okay when pulled-up to +V ( I used 1K8 ) and the signal from the controller is through a diode pointing towards the controller.

With all the SRAM I have, projects to use that with traditional microprocessors look simple. SRAM only, with PICAXE/PICmicro bootloader. Tri-state the processor, boot-load the code, let processor out of reset, bingo !

One trick for using multiple SRAM's easily - Bend the /CS pins out, solder all SRAM as a tower with every pin connected, then run flying leads to the individual /CS pins. A sod if any chip fails, but that's a risk one has to accept.

Once again, thanks for the inspiration generated by your posting.
 

jodicalhon

New Member
ylp88 and hippy,

This is a very informative and enjoyable thread. I've learnt heaps that I should be able to make good use of in a project I have on a backburner. (One of many....)

Thanks for the inspiration, the ideas, and the concrete information!
 

ylp88

Senior Member
I'm still trying to get mine working! Just when I think I've found the problem or I see a pattern, something else occurs not to my expectation.

When I get time, I will remove the serial interface and use PORTB to control the data bus and use PORTA to set the control lines.

When I get time....

I'll keep you posted with any developments.

<b><i>ylp88 </b> </i>
 
Top