EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

SPI slave comms on ATtiny26

Started by Lewin A.R.W. Edwards February 11, 2004
What sensible methods do people use to implement SPI slave comms on
AVR micros? I'm specifically working with the ATtiny26L right now.

I'm currently using a software approach, with the select line
connected to an int-on-change pin. When that int comes in, I read the
state of the pin and if it's high, I turn off the USI UART and set
MISO to input mode so it doesn't interfere with other devices on the
bus. This has a speed downside, and more importantly fearsome things
happen to the bus if the micro is crashed. (Of course my code is
pefrect and error-reef, but I have to allow for the presence of bad
fairies ;). Upside is that it's trivial to detect end-of-transaction
and clear out any garbage data that may have accumulated.

Second method I considered was using an LS244 to buffer the
MISO/MOSI/SCK lines and tristate it with the select signal. Downside
to this is increased BOM.

Third method I considered was for all devices to regard themselves as
continuously selected, but only listen/respond to certain commands
(and keep their mittens off the MISO line until it's their turn to
talk). This seems to be horrendously fragile though, for all kinds of
reasons.

Is there some seriously silly error I've made, or are these my only
options?

"Lewin A.R.W. Edwards" <larwe@larwe.com> skrev i meddelandet
news:608b6569.0402111439.27d28942@posting.google.com...
> What sensible methods do people use to implement SPI slave comms on > AVR micros? I'm specifically working with the ATtiny26L right now. > > I'm currently using a software approach, with the select line > connected to an int-on-change pin. When that int comes in, I read the > state of the pin and if it's high, I turn off the USI UART and set > MISO to input mode so it doesn't interfere with other devices on the > bus. This has a speed downside, and more importantly fearsome things > happen to the bus if the micro is crashed. (Of course my code is > pefrect and error-reef, but I have to allow for the presence of bad > fairies ;). Upside is that it's trivial to detect end-of-transaction > and clear out any garbage data that may have accumulated. > > Second method I considered was using an LS244 to buffer the > MISO/MOSI/SCK lines and tristate it with the select signal. Downside > to this is increased BOM. > > Third method I considered was for all devices to regard themselves as > continuously selected, but only listen/respond to certain commands > (and keep their mittens off the MISO line until it's their turn to > talk). This seems to be horrendously fragile though, for all kinds of > reasons. > > Is there some seriously silly error I've made, or are these my only > options?
Lewin, The ATmega48, sampling now, is just a little bit more expensive with a H/W SPI. It also have the debugwire OCD interface. -- Best Regards, Ulf Samuelsson ulf@a-t-m-e-l.com This is a personal view which may or may not be share by my Employer Atmel Nordic AB

Lewin A.R.W. Edwards wrote:
> What sensible methods do people use to implement SPI slave comms on > AVR micros? I'm specifically working with the ATtiny26L right now. > > I'm currently using a software approach, with the select line > connected to an int-on-change pin. When that int comes in, I read the > state of the pin and if it's high, I turn off the USI UART and set > MISO to input mode so it doesn't interfere with other devices on the > bus.
Without a /SS pin, you will have to watch for hand-over contention. Resistors in the MISO lines would probably do, so any make before break is tolerated. > This has a speed downside, and more importantly fearsome things
> happen to the bus if the micro is crashed. (Of course my code is > pefrect and error-reef, but I have to allow for the presence of bad > fairies ;).
;)
> Upside is that it's trivial to detect end-of-transaction > and clear out any garbage data that may have accumulated. > > Second method I considered was using an LS244 to buffer the > MISO/MOSI/SCK lines and tristate it with the select signal. Downside > to this is increased BOM.
and it does not solve all the time-domain problems, only the hand-over contention ones.
> > Third method I considered was for all devices to regard themselves as > continuously selected, but only listen/respond to certain commands > (and keep their mittens off the MISO line until it's their turn to > talk). This seems to be horrendously fragile though, for all kinds of > reasons.
Why is this more fragile than the first method ?. I can see it has a higher average software load, but has some benefits of being able to BUS WDOG and BUS quality check via checksums etc.
> > Is there some seriously silly error I've made, or are these my only > options?
You can also run SPI devices in a serial daisy-chain. Then the physical location determines who gets what info, and you have no handover as such. Data speeds can be higher, and ALL nodes are event locked, which can also be good. Of course, the wiring is different.. :) -jg
Hi Ulf,

> Lewin, The ATmega48, sampling now, is just a little bit more expensive > with a H/W SPI. It also have the debugwire OCD interface.
Sorry, I'm committed to the tiny26L :) This is for my book... I don't have time to revise around a new microcontroller. See the response I'm about to write to Jim in this same thread...
Hi Jim,

Let me preface this with a bunch of details I probably ought to have 
given in the original posting: I'm adapting my submarine circuitry to 
the somewhat cut-down approach I take in my book. (Anyone who happens to 
be reading, and is on my "to review the manuscript list" - It seems 
likely that all the drafts are going out with the schematics only, no 
sourcecode or commentary in that chapter, until I know just WTF I'm doing!).

The sub uses an ATmega128 as the "main controller", connected to the 
"untrusted" Linux SBC via RS232. Each mechnical controller module has 
its own MISO line. All modules share a single SCK and MOSI.

The ATmega128 supplies more or less continuous clock and gets a constant 
stream of data from all [8] connected modules; some of the information 
is redundant. For instance, the motor controller transmits a constant, 
repeating stream of packets that indicate the current direction flag 
(FWD/REV), last measured tach interval, current PWM duty cycle, thermal 
flag state, and a few other flags that indicate whether a stall has been 
detected, etc.

At any moment, up to eight commands may be in the process of being 
serialized out the individual MISO lines from the mega128. Comprehensive 
"black box" packets summarizing all the incoming datastreams go out the 
serial line to the PC at approximately 0.5Hz.

However - For various reasons, mostly related to the skills I'm trying 
to demonstrate in the text, the circuits in the book are bit-banged 
directly from the PC's parallel port. I have designed a very simple 
generic 8-way interface (see <http://www.larwe.com/parallel.gif> - note 
the URL mentioned in the image isn't live yet) for this purpose.

For the purpose of this discussion, I can _guarantee_ that only one 
select line will ever be asserted, and that any desired recovery time 
can be allowed between deasserting one device and asserting another. 
Data rates are very low.

>> Third method I considered was for all devices to regard themselves as >> continuously selected, but only listen/respond to certain commands > > Why is this more fragile than the first method ?.
Well, if I'm using the select line, I can use it as a simple failsafe against partial transactions. I can simply clear everything out and go into sleep mode (or concentrate on background tasks) when select is deasserted. Once select is asserted, I can perk the micro up to watch the USI. If I am just listening to bits coming randomly down the wire, I have to establish a more complicated protocol to know when transactions begin or end.
> You can also run SPI devices in a serial daisy-chain. Then the physical
I'd have to bit-bang the downstream port on the micro, though. Not keen on that idea :)
Lewin A.R.W. Edwards wrote:
> Hi Jim,
<snip>
>>> Third method I considered was for all devices to regard themselves as >>> continuously selected, but only listen/respond to certain commands >> >> >> Why is this more fragile than the first method ?. > > > Well, if I'm using the select line, I can use it as a simple failsafe > against partial transactions. I can simply clear everything out and go > into sleep mode (or concentrate on background tasks) when select is > deasserted. Once select is asserted, I can perk the micro up to watch > the USI. If I am just listening to bits coming randomly down the wire, I > have to establish a more complicated protocol to know when transactions > begin or end.
I had assumed you would still Select/INT, for frame info, but that instead of the Select lines doing the channel tags, the message content does ( like LIN BUS ), trades HW wiring, for a SW scheme.
> >> You can also run SPI devices in a serial daisy-chain. Then the physical > > > I'd have to bit-bang the downstream port on the micro, though. Not keen > on that idea :)
No need to do that, just do this ---|MOSI MISO|--->--|MOSI MISO|--->--|MOSI MISO|--->--- and parallel the clocks, & frame/INT. Each device looks like an 8 bit shift register, and takes 8 clocks so 8 slaves will have a complete frame ready after 64 clocks. Then assert the common frame/INT line, and they all get/put their respective bytes. The host can work out how many are in the chain by counting clocks. [Which node is where is a tad harder....] Advantage of this ring bus, is the PC interface is constant, and the number of nodes can be added to, keeping PC and BOX connectors fixed. -jg

The 2024 Embedded Online Conference