2 ATMega Processors sharing a peripheral device (SPI ram)

Hi All.

Ive currently got a setup on my breadboard where i have 2 Atmega328 processors that are linked via serial. My current setup is:
Arduino A is connected to a ENCJ ethernet card. This downloads the data and stores each ~600 byte packet to an SPI ram chip i have wired in. It repeats until the download is complete (upto 32KB max) and then starts firing it over to the second arduino in 64byte packets over serial. Each packet is received on Arduino B, Saved to an SD card and then replies telling Arduino 1 to send the next 64 bytes across.
This configuration is working perfectly (altho it took me a bit to get working heh), but now im actually wanting to cut out the transfer over serial and give the 2nd arduino access to the SPI ram aswell, not because i want to rule out serial, but just for the flexibility the RAM offers me as i could quite feasibly partition the ram and utilise 24kb for ethernet buffers and 12kb for actual use on Arduino B that is going to be doing most of the leg work - and this part is just hurting my head!

I thought i could just use a few AND gate buffers either side of the SPI ram and wire the SCK,MOSI,MISO and CS wires through these to basically turn on and off which of the arduinos is talking/receiving to the RAM at any given time, and control this by sending just a single character over serial to say 'your turn' but its a no go. I think the reason for this is that the AND gate outputs are seemingly 'sinking' the current from the data signals, so rather than isolating which of the 2 sides is talking to the chip theyre just getting in the way and blocking all communication.
Hope this make sense? What would be the best way to get around this? stick a few resistors on the AND gate outputs to increase the output impedence? Diodes? Something else?

Thanks in advance for any help.

Cheers,
Carl.

I can't quite follow what you've done without a schematic, but maybe you should look at a MUX like the 74CBT3257, I've used these before to switch the SPI port on small AVRtiny chips for programming.

If you have a master CPU it can use one signal to both switch the MUX and signal the slave that it has access.


Rob

carlb007:
I thought i could just use a few AND gate buffers either side of the SPI ram and wire the SCK,MOSI,MISO and CS wires through these to basically turn on and off which of the arduinos is talking/receiving to the RAM at any given time, and control this by sending just a single character over serial to say 'your turn' but its a no go.

The AtMega328's support tri-state logic (high, low, float) and so you should be able to wire both AtMega's to a single RAM chip without additional hardware provided you carefully serialize access (one at time). SCK, MOSI and CS are outputs that all need to be switched between mode output and mode input (float) depending on which mcu has access to RAM. MISO is always input and so no issue. For CS, you should enable internal pull-up so that the RAM chip remains unselected when you switch control from one mcu to the other.

Thanks for reminding me of this interface style, I'd almost finished the design of a dual-processor board using I2C to talk between CPUs but have now changed it to use SPI RAM with some DIY dual-porting using the 74CBT3257.

The MUX does add another chip but it also means that there can never be hardware contention between the two CPU's SPI pins, worth it I think.


Rob

Graynomad:
The MUX does add another chip but it also means that there can never be hardware contention between the two CPU's SPI pins, worth it I think.

In my mind this just adds complexity and cost.

A good precaution is to always power the project from a decent lab supply during development and limit current to a safe level. In case of an accidental short (from incorrect wiring or software) this will trigger a brown out reset and tri-state outputs.

True it does increase the hardware complexity, but it also adds a fail safe option. With a MUX there is absolutely no way you can get bus contention, the same cannot be said for software no matter how much you test it.

I guess it depends on the intended market as to whether the hardware is worth it or go for the software option.


Rob

Hi,

Thanks for the replies. I think the tri-state thing might be where im falling down here. It seems like the and gate outputs are acting as a sink when not outputting a high rather than floating. Im using 74HCT08 chips at the moment as i need to level shift the voltage to 3v (ram and ethernet are both 3v and i want to keep both AVRs at 5v/16mhz). I was originally just using hex level shiftes to do this until i tried to share the ram.
Ill take a look at the MUX and see if i get anywhere - i dont even know what one is right now but im enjoying reading up on things and trying to learn as ive only been fiddling with this stuff for a few months now.
Failing that i may actually just add a secondary smaller ram chip on the other side of the setup...you can get a 8 byte ram chip for only 40p which might actually be a better, cheaper and less fiddly route than trying to just share the original chip in the first place...will see how it turns out!

Thanks all,
Carl.

You might have to add an extra wire-OR'd control line so that each processor can signal when it is accessing the other chip. (Or send the CS signals to another input on each processor so that it can know not to access the chip)

Here's what I just did for my board.

I have an ATMega1284 (5v) and an LPC1227 (3v3) sharing a 128kB SPI serial SRAM. The 5v side is the master and it has control over the MUX. Each chip's CS signal goes to the other and they will be used for handshaking.

It seems like the and gate outputs are acting as a sink when not outputting a high rather than floating.

Umm yes, an '08 has a push-pull output so if it's not sourcing current it's sinking current. AFAIK there are no chips that "float" for a low and drive for a high. The reverse is common though, look for "open-collector" or "open-drain" outputs. If you want to continue with this approach the 74xx09 might be better, that's an AND gate with open-drain output.

i may actually just add a secondary smaller ram chip on the other side of the setup

This is by far the easiest approach.

In my case the RAM has to be shared because that's how the CPUs communicate, but you can use serial. That said it will be MUCH more efficient to share the RAM because the data is only stored once, not stored and transferred and stored again.

The tri-state approach is simple and will work as well, it's just that there are no guarantees you will get the code right, even if you test it to kingdom come there will be a path you never thought of that will pop up one day :slight_smile: Also it doesn't help with the level conversion. Also if you need to store 32kB of data it won't work with the small AVRs we use on Arduinos.


Rob