Forums

Philips SPI1 confusion

Started by gen_4p July 28, 2006
Hello,
I am working on some SPI routines on SSP port (lpc2148) and need some
sanity check.
Approach for sending data is quite standard and straightforward -
- check if transmit FIFO is not full
- write a byte to data register
- wait for the end of transmittion (busy flag cleared)

Nevertheless that is what I see in Philips provided code.

1. From ../files/LPC214x_LPC213x Sample Code for Keil.zip
or ../files/LPC214x_LPC213x Sample Code for ARM-RVDK.zip

#define SSPSR_BSY 1 << 4

while ( !(SSPSR & SSPSR_TNF) );
SSPDR = data;
/* Wait until the Busy bit is cleared */
while ( !(SSPSR & SSPSR_BSY) );

>From my point of view the last line is waiting not for clearing of
a BUSY flag, but for setting it. Am I wrong ?

2. Even more - from Philips app note for accessing mmc:

while ( !(SSPSR & 0x02) );
SSPDR = data; // writing to fifo
/* Wait until the Busy bit is cleared */
while ( !(SSPSR & 0x04) );

Here, in my opinion, the last line is waiting for the setting of the
RNE bit in SSPSR, what is "Receive FIFO is not empty".
I can see a point here, since BUSY flag is cleared when ALL bytes are
sent from FIFO, and RNE flag is set when just one byte is sent (on
condition that receive FIFO was flashed before sending). But then the
comment (/* Wait until the Busy bit is cleared */) doesn't hold the
truth.

Will highly appreciate any comments on this issue.

Gennady

An Engineer's Guide to the LPC2100 Series

--- In l..., "gen_4p" wrote:
>
> Hello,
> I am working on some SPI routines on SSP port (lpc2148) and need
some
> sanity check.
> Approach for sending data is quite standard and straightforward -
> - check if transmit FIFO is not full
> - write a byte to data register
> - wait for the end of transmittion (busy flag cleared)
>
> Nevertheless that is what I see in Philips provided code.
>
> 1. From ../files/LPC214x_LPC213x Sample Code for Keil.zip
> or ../files/LPC214x_LPC213x Sample Code for ARM-RVDK.zip
>
> #define SSPSR_BSY 1 << 4
>
> while ( !(SSPSR & SSPSR_TNF) );
> SSPDR = data;
> /* Wait until the Busy bit is cleared */
> while ( !(SSPSR & SSPSR_BSY) );
>
> From my point of view the last line is waiting not for clearing of
> a BUSY flag, but for setting it. Am I wrong ?
>

The short answer is "yes, you are wrong". Easy to miss, but the "!"
negates the expression inside the brackets. One way of reading it
would be "WHILE NOT (SSPSR AND BUSY) DO NOTHING".

By the way, that trailing semi-colon is a bad idea: I'd tend to use
something like the following to make it clear what's going on:

while (!(SSPSR & SSPSR_BSY))
{
;
}

> 2. Even more - from Philips app note for accessing mmc:
>
> while ( !(SSPSR & 0x02) );
> SSPDR = data; // writing to fifo
> /* Wait until the Busy bit is cleared */
> while ( !(SSPSR & 0x04) );
>
> Here, in my opinion, the last line is waiting for the setting of
the
> RNE bit in SSPSR, what is "Receive FIFO is not empty".
> I can see a point here, since BUSY flag is cleared when ALL bytes
are
> sent from FIFO, and RNE flag is set when just one byte is sent (on
> condition that receive FIFO was flashed before sending). But then
the
> comment (/* Wait until the Busy bit is cleared */) doesn't hold
the
> truth.
>

Same comment.

> Will highly appreciate any comments on this issue.
>
> Gennady
>
--- In l..., "brendanmurphy37"
wrote:
>
> --- In l..., "gen_4p" wrote:
> >
> > Hello,
> > I am working on some SPI routines on SSP port (lpc2148) and need
> some
> > sanity check.
> > Approach for sending data is quite standard and straightforward -
> > - check if transmit FIFO is not full
> > - write a byte to data register
> > - wait for the end of transmittion (busy flag cleared)
> >
> > Nevertheless that is what I see in Philips provided code.
> >
> > 1. From ../files/LPC214x_LPC213x Sample Code for Keil.zip
> > or ../files/LPC214x_LPC213x Sample Code for ARM-RVDK.zip
> >
> > #define SSPSR_BSY 1 << 4
> >
> > while ( !(SSPSR & SSPSR_TNF) );
> > SSPDR = data;
> > /* Wait until the Busy bit is cleared */
> > while ( !(SSPSR & SSPSR_BSY) );
> >
> > From my point of view the last line is waiting not for clearing
of
> > a BUSY flag, but for setting it. Am I wrong ?
> > The short answer is "yes, you are wrong". Easy to miss, but
the "!"
> negates the expression inside the brackets. One way of reading it
> would be "WHILE NOT (SSPSR AND BUSY) DO NOTHING".
>
> By the way, that trailing semi-colon is a bad idea: I'd tend to
use
> something like the following to make it clear what's going on:
>
> while (!(SSPSR & SSPSR_BSY))
> {
> ;
> }
>
> > 2. Even more - from Philips app note for accessing mmc:
> >
> > while ( !(SSPSR & 0x02) );
> > SSPDR = data; // writing to fifo
> > /* Wait until the Busy bit is cleared */
> > while ( !(SSPSR & 0x04) );
> >
> > Here, in my opinion, the last line is waiting for the setting of
> the
> > RNE bit in SSPSR, what is "Receive FIFO is not empty".
> > I can see a point here, since BUSY flag is cleared when ALL
bytes
> are
> > sent from FIFO, and RNE flag is set when just one byte is sent
(on
> > condition that receive FIFO was flashed before sending). But
then
> the
> > comment (/* Wait until the Busy bit is cleared */) doesn't hold
> the
> > truth.
> > Same comment.
>
> > Will highly appreciate any comments on this issue.
> >
> > Gennady
>
Before anyone points it out, please ignore my last post above - it's
complete nonsense - I misread the polarity of the busy flag sense.

Apologies!

Brendan
--- In l..., "brendanmurphy37"
wrote:
>
> --- In l..., "brendanmurphy37"
> wrote:
> >
> > --- In l..., "gen_4p" wrote:
> > >
> > > Hello,
> > > I am working on some SPI routines on SSP port (lpc2148) and
need
> > some
> > > sanity check.
> > > Approach for sending data is quite standard and
straightforward -
> > > - check if transmit FIFO is not full
> > > - write a byte to data register
> > > - wait for the end of transmittion (busy flag cleared)
> > >
> > > Nevertheless that is what I see in Philips provided code.
> > >
> > > 1. From ../files/LPC214x_LPC213x Sample Code for Keil.zip
> > > or ../files/LPC214x_LPC213x Sample Code for ARM-RVDK.zip
> > >
> > > #define SSPSR_BSY 1 << 4
> > >
> > > while ( !(SSPSR & SSPSR_TNF) );
> > > SSPDR = data;
> > > /* Wait until the Busy bit is cleared */
> > > while ( !(SSPSR & SSPSR_BSY) );
> > >
> > > From my point of view the last line is waiting not for clearing
> of
> > > a BUSY flag, but for setting it. Am I wrong ?
> > >
> >
> > The short answer is "yes, you are wrong". Easy to miss, but
> the "!"
> > negates the expression inside the brackets. One way of reading it
> > would be "WHILE NOT (SSPSR AND BUSY) DO NOTHING".
> >
> > By the way, that trailing semi-colon is a bad idea: I'd tend to
> use
> > something like the following to make it clear what's going on:
> >
> > while (!(SSPSR & SSPSR_BSY))
> > {
> > ;
> > }
> >
> > > 2. Even more - from Philips app note for accessing mmc:
> > >
> > > while ( !(SSPSR & 0x02) );
> > > SSPDR = data; // writing to fifo
> > > /* Wait until the Busy bit is cleared */
> > > while ( !(SSPSR & 0x04) );
> > >
> > > Here, in my opinion, the last line is waiting for the setting
of
> > the
> > > RNE bit in SSPSR, what is "Receive FIFO is not empty".
> > > I can see a point here, since BUSY flag is cleared when ALL
> bytes
> > are
> > > sent from FIFO, and RNE flag is set when just one byte is sent
> (on
> > > condition that receive FIFO was flashed before sending). But
> then
> > the
> > > comment (/* Wait until the Busy bit is cleared */) doesn't hold
> > the
> > > truth.
> > >
> >
> > Same comment.
> >
> > > Will highly appreciate any comments on this issue.
> > >
> > > Gennady
> > >
> > Before anyone points it out, please ignore my last post above -
it's
> complete nonsense - I misread the polarity of the busy flag sense.
>
> Apologies!
>
> Brendan
>

Thanks Brendan,
so the verdict is... ?

I can see where does confusion come from -
SPI0 is using the COMPLETE flag (for end - check if SET),
SPI1 is using the BUSY flag (for end - check if CLEARED).

I just see this repeated over and over in a lot of examples (and
since SSP is the same for all LPCs, it applies for the full line).
Just wonder if anybody could make SPI1 work based on this app notes ?

Gennady
--- In l..., "gen_4p" wrote:
> Thanks Brendan,
> so the verdict is... ?
>

Er, I'm not sure!

The code certainly looks wrong, in that it doesn't match the
(seemingly more acurate) comments.

> I can see where does confusion come from -
> SPI0 is using the COMPLETE flag (for end - check if SET),
> SPI1 is using the BUSY flag (for end - check if CLEARED).
>
> I just see this repeated over and over in a lot of examples (and
> since SSP is the same for all LPCs, it applies for the full line).
> Just wonder if anybody could make SPI1 work based on this app notes ?
>

One thought: there's a chance the code actually works (in certain
cases), even though the code might well be stricly speaking incorrect.

As a general point: the quality of Philips app notes varies somewhat
alarmingly. Some of it is understandable in that to demonstrate a
point, or to keep them brief, a lot of stuff is left out. Other
examples are just plain questionable.

As you say, it would be interesting if anyone has got this code to
work.

Brendan.