SPI for the 1000th time... :-(

Started by "d.holzwarth" October 24, 2007
hello everyone

I was reading through most of the SPI related topics but its still
very confusing to me... :-/

I have two LPC2368/78 with one being the SPI master and one being the
SPI slave.

the SPI slave LPC always gets a "slave abort" AND a "read overrun". I
guess its related to the SSEL discussion and I really don't know what
to do with that pin...

if I select the SSEL function in the PINSEL0 then the SSEL pin is
always "1" (= which is inactive for my settings: CPHA = 0, CPOL = 1).
I also tried to set SSEL as GPIO output and toggle it manually: set
it to low (tive) when the master starts writing and set it back to
high (=inactive) when the master stops writing.

as I said I dont have a bus system, only 1 master and 1 slave so I
dont need any chip selects or so (at least not the way they are
intended). but as I said I dunno what to do with SSEL signal to make
a simple master <--> slave transmission work...

I would be very pleased if someone could help me!

thx D. Holzwarth

An Engineer's Guide to the LPC2100 Series

--- In l..., "Michael Anton" wrote:
>
> > -----Original Message-----
> > From: l...
> > [mailto:l...]On Behalf
> > Of d.holzwarth
> > Sent: Wednesday, October 24, 2007 12:02 AM
> > To: l...
> > Subject: [lpc2000] Re: SPI for the 1000th time... :-(
> >
> >
> > well, what's confusing me is the statement on page 373 of the
> > usermanual:
> >
> > "If the Px.y/SSEL/... pin is assigned the SSEL function in
> > Pin Function
> > Select Register 0, the SSEL signal must always be inactive
> > when the SPI
> > controller is a master."
> >
> > however, on page 371 there's written:
> >
> > "When a device is set up to be a slave, its I/Os are
> > only active when it is selected by the SSEL signal being active."
> >
> > the way I understand those 2 statements, they exclude each
> > other... :-/
> >
> > my guess would be that the first one means "if a master is idle,
the
> > SSEL signal must be inactive" - but there's that "always" which
is
> > kinda confusing...
> > As I understand this from past discussions, the SSEL is not used
> when in master mode, but must be tied to an inactive state for
> the SPI to work at all. In some older variants of the LPC series,
> the SSEL can not be used as GPIO, and it must be tied to the
> inactive state, and another GPIO pin used as the CS output.
>
> Probably the SSEL in master mode could be used in a multi-master
> system to detect collisions, or to at least avoid any contention
> if another device tried to use the bus (but I don't have anything
> to back this up, it is just a hunch).
>
> Good luck,
>
> Mike
>

OK, I've never used the LPC micros, but this strikes me as inactive
meaning the pin is not an output, ie an input on the slave.

As another poster has mentioned, the SSEL line as I understand
should frame the start/end of a word transmission.

Another possibility is the SSEL on the slave could be held low, and
you rely on the 8 clock bits (I'm assuming 8 bit transfers) setting
the new word rx'd flag/interrupt etc. But that depends on the
processor's behaviour.

Put it this way, for a slave to be enabled, its select line needs to
be active, and this usually means an active low signal into the
select pin.

The master should be capable of generating a suitable select signal
to do this, and you'd connect this directly to the slave.

Ray
my SSEL pin is active low and I set it to 0 before the transmission of
1 byte and set it back to high after that transmission is finished (its
configured as a GIPO output because if I choose the SSEL function it
remains always high...).

I somehow managed to "kill" my ISR tho... its no more firing at
all... :-/ the reason is that the SPIF bit of the SPI status register
never has a 1. but I dont know whats the reason for that... (as I
understand it after the last clock the SPIF in the slave should be 1)
Doesn't your SSEL pin have to be low for the entire command sequence
and not for each byte? The SSEL is the framing for the entire command
sequence (falling edge or rising edge).

"I set it to 0 before the transmission of 1 byte and set it back to
high after that transmission is finished"

--- In l..., "d.holzwarth" wrote:
>
> my SSEL pin is active low and I set it to 0 before the transmission of
> 1 byte and set it back to high after that transmission is finished (its
> configured as a GIPO output because if I choose the SSEL function it
> remains always high...).
>
> I somehow managed to "kill" my ISR tho... its no more firing at
> all... :-/ the reason is that the SPIF bit of the SPI status register
> never has a 1. but I dont know whats the reason for that... (as I
> understand it after the last clock the SPIF in the slave should be 1)
>
d.holzwarth Wrote
>my SSEL pin is active low and I set it to 0 before the transmission of
>1 byte and set it back to high after that transmission is finished (its

Um, SSEL is input not an output. The master should have it always pulled
high externally. On the slave the master should pull it low before the
transmission starts. The slave will then let the slave program know it has
been selected and the slave program will be responsible for emptying the
receive and filling the transmit as fast as the master clocks the data.
Neither micro should ever set their own SSEL directly.

>configured as a GIPO output because if I choose the SSEL function it
> remains always high...).

That seems entirely reasonable, although I'd put a pullup on it as security
myself.

Robert
--------------------------------
mail2web LIVE Free email based on Microsoft Exchange technology -
http://link.mail2web.com/LIVE



--- In l..., "Sutton Mehaffey" wrote:
>
> Doesn't your SSEL pin have to be low for the entire command sequence
> and not for each byte? The SSEL is the framing for the entire command
> sequence (falling edge or rising edge).

I think that depends entirely on the slave device and its' protocol.
There are gadgets that accept a write command and address as a single
transaction. They then send/receive data sequentially from/to that
address and onward as bytes/words for each subsequent transfer. The
data transfer can be as small as one byte (bracketed by SSEL) or an
entire sector (or larger, I presume) bracketed by another SSEL. In
I2C, the master NAKs the last received byte but there is no such
facility in SPI. So, to tell the slave it is finally finished, the
master raises SSEL.

Given a choice between I2C and SPI, I go for SPI every time. It is a
lot easier to get working and triggering a logic analyzer on SSEL is a
lot easier than decoding the I2C start condition.
Both are fairly easy to get working. I have 3 I2C and 3 SPI
peripherals on our new products. The Beagle analyzer has been a great
tool for analyzing SPI and I2C bus traffic and getting the code
working. And, it's only about $200.

However, my SD card (SPI) is giving me some trouble since each
different card I use gives different CSD values that don't correspond
with valid values in the SD manual.

Sutton

--- In l..., "rtstofer" wrote:
>
> --- In l..., "Sutton Mehaffey" wrote:
> >
> > Doesn't your SSEL pin have to be low for the entire command sequence
> > and not for each byte? The SSEL is the framing for the entire command
> > sequence (falling edge or rising edge).
>
> I think that depends entirely on the slave device and its' protocol.
> There are gadgets that accept a write command and address as a single
> transaction. They then send/receive data sequentially from/to that
> address and onward as bytes/words for each subsequent transfer. The
> data transfer can be as small as one byte (bracketed by SSEL) or an
> entire sector (or larger, I presume) bracketed by another SSEL. In
> I2C, the master NAKs the last received byte but there is no such
> facility in SPI. So, to tell the slave it is finally finished, the
> master raises SSEL.
>
> Given a choice between I2C and SPI, I go for SPI every time. It is a
> lot easier to get working and triggering a logic analyzer on SSEL is a
> lot easier than decoding the I2C start condition.
>
dont forget that I have a master AND a slave ;-)

so my master sets the SSEL (zero before the transmission of 1 byte, one
when the SPIF is set indicating the transmission is over). the slave
obviously doesnt touch the SSEL (the slave LPC has got that specific
pin configured as SSEL function. only the master has it configured as
GPIO output).

I've done some more testing now and my slave ISR is still behaving odd
(ie. the breakpoint doesn't stop) but when I do enter the ISR I still
get a "slave abort" and/or "read overrun" ... :-/
d.holzwarth Wrote
>dont forget that I have a master AND a slave ;-)

I haven't

>
>so my master sets the SSEL (zero before the transmission of 1 byte, one

The master should never set its SSEL (not ever), it should be pulled up
externally.

>when the SPIF is set indicating the transmission is over). the slave
>obviously doesnt touch the SSEL (the slave LPC has got that specific
>pin configured as SSEL function. only the master has it configured as
>GPIO output).

I don't know if that works on any LPC's, I know it doesn't on many. For
SPI, SSEL must be set as SSEL and it must be pulled high on the master.

>I've done some more testing now and my slave ISR is still behaving odd
>(ie. the breakpoint doesn't stop) but when I do enter the ISR I still
>get a "slave abort" and/or "read overrun" ... :-/

I do believe slave abort is telling you SSEL has been selected (Or maybe
deselected?). You don't switch to slave mode so much as the peripheral
tells you that you have been switched to slave mode. read overrun sounds
more that you are not reading/writing the data quickly enough.

Robert

--------------------------------
mail2web.com - Microsoft Exchange solutions from a leading provider -
http://link.mail2web.com/Business/Exchange



Let's just sum it up:

On the master - set the SSEL pin for SSEL function and pull it up with
an external resistor. On SOME LPCs this isn't necessary but, just in
case, do it anyway.

On the master - pick a GPIO pin to connect to the slave device SSEL.
Control it by setting it low before a transaction and setting it high
after.

On the slave - set the SSEL pin for SSEL function and connect it to
whatever GPIO pin the master is using to select the slave. It would
be a good idea to put a pull-up resistor on this signal.

Some datasheets will tell you to put a pull-down resistor on SCK to
prevent it from floating high during reset when signals are
tri-stated. See page 10 here:
http://www.st.com/stonline/books/pdf/docs/10027.pdf

Richard