EmbeddedRelated.com
Forums

SPI Mode Fault

Started by rawjoeshaw February 9, 2007
I keep seeing Mode Faults when I do SPI writes on my LPC2106. Here is
my write function:

void SPI_Write(unsigned char *buffer,unsigned int bytecount)
{
unsigned int j;
unsigned int i = 0;
while (bytecount--) {
S0SPDR_bit.DATA = *buffer++;
while (!(j=(S0SPSR&0xF8))) ;
i |= j;
//if (i != 0x80) break;
}
}

At the end of the write function, i will be 0xD0, which indicates
SPIF, WCOL, and MODF. If I only compare S0SPSR to 0x80, it usually
works fine. Uncommenting the last line, the function causes the
function to exit randomly after writing the first byte, with i = 0x10
(Mode Fault). So I'm guessing the mode fault triggers me to write
another byte, which results in the Write Collision.

So why the random mode fault? the LPC isn't really talking to
anything, data is just going to my logic analyzer, so nothing else
should be contending as master. Also, SSEL is pulled high, so there
shouldn't be anything messing with SSEL to even cause a mode fault.

Any help is appreciated. -Joe

An Engineer's Guide to the LPC2100 Series

--- In l..., "rawjoeshaw" wrote:
>
> I keep seeing Mode Faults when I do SPI writes on my LPC2106. Here is
> my write function:
>
> void SPI_Write(unsigned char *buffer,unsigned int bytecount)
> {
> unsigned int j;
> unsigned int i = 0;
> while (bytecount--) {
> S0SPDR_bit.DATA = *buffer++;
> while (!(j=(S0SPSR&0xF8))) ;
> i |= j;
> //if (i != 0x80) break;
> }
> }
>
> At the end of the write function, i will be 0xD0, which indicates
> SPIF, WCOL, and MODF. If I only compare S0SPSR to 0x80, it usually
> works fine. Uncommenting the last line, the function causes the
> function to exit randomly after writing the first byte, with i = 0x10
> (Mode Fault). So I'm guessing the mode fault triggers me to write
> another byte, which results in the Write Collision.
>
> So why the random mode fault? the LPC isn't really talking to
> anything, data is just going to my logic analyzer, so nothing else
> should be contending as master. Also, SSEL is pulled high, so there
> shouldn't be anything messing with SSEL to even cause a mode fault.
>
> Any help is appreciated. -Joe
>

Sounds similar to the problem I just had. I had SS configured as GPIO
which I assumed would cause the SS to rest in an inactive state (as it
does on other micros). Apparently not, even when only using master you
**must** configure the SS pin as an SS pin **and** pull it up.
--- In l..., "nonuckingfumber" wrote:
>
> --- In l..., "rawjoeshaw" wrote:
> >
> > I keep seeing Mode Faults when I do SPI writes on my LPC2106. Here is
> > my write function:
> >
> > void SPI_Write(unsigned char *buffer,unsigned int bytecount)
> > {
> > unsigned int j;
> > unsigned int i = 0;
> > while (bytecount--) {
> > S0SPDR_bit.DATA = *buffer++;
> > while (!(j=(S0SPSR&0xF8))) ;
> > i |= j;
> > //if (i != 0x80) break;
> > }
> > }
> >
> > At the end of the write function, i will be 0xD0, which indicates
> > SPIF, WCOL, and MODF. If I only compare S0SPSR to 0x80, it usually
> > works fine. Uncommenting the last line, the function causes the
> > function to exit randomly after writing the first byte, with i = 0x10
> > (Mode Fault). So I'm guessing the mode fault triggers me to write
> > another byte, which results in the Write Collision.
> >
> > So why the random mode fault? the LPC isn't really talking to
> > anything, data is just going to my logic analyzer, so nothing else
> > should be contending as master. Also, SSEL is pulled high, so there
> > shouldn't be anything messing with SSEL to even cause a mode fault.
> >
> > Any help is appreciated. -Joe
> > Sounds similar to the problem I just had. I had SS configured as GPIO
> which I assumed would cause the SS to rest in an inactive state (as it
> does on other micros). Apparently not, even when only using master you
> **must** configure the SS pin as an SS pin **and** pull it up.
>

Wish that was the case, but I do configure SSEL as SPI (not GPIO) and
I do pull it high.
Have you pulled SSEL high with an external resistor? If it floats,
there is a possibility that the SPI gadget changes to slave mode at
random.

I don't think you can use SSEL as GPIO.

This issue has been discussed dozens of times on this forum. Maybe
you can find the right answer by searching the archives.

Richard
I pull it high via a resistor and I configure SSEL as an SPI pin (not GPIO). I've seen all the posts on this topic. None seem to apply. No one has really posted anything about a Mode Fault in SPI.

>>> On 2007-02-09 at 13:04, r...@pacbell.net wrote:

Have you pulled SSEL high with an external resistor? If it floats,
there is a possibility that the SPI gadget changes to slave mode at
random.

I don't think you can use SSEL as GPIO.

This issue has been discussed dozens of times on this forum. Maybe
you can find the right answer by searching the archives.

Richard
Pull up SSEL and use another pin to CS.

Regards
Krzysztof

--- In l..., "rawjoeshaw" wrote:
>
> I keep seeing Mode Faults when I do SPI writes on my LPC2106. Here is
> my write function:
>
> void SPI_Write(unsigned char *buffer,unsigned int bytecount)
> {
> unsigned int j;
> unsigned int i = 0;
> while (bytecount--) {
> S0SPDR_bit.DATA = *buffer++;
> while (!(j=(S0SPSR&0xF8))) ;
> i |= j;
> //if (i != 0x80) break;
> }
> }
>
> At the end of the write function, i will be 0xD0, which indicates
> SPIF, WCOL, and MODF. If I only compare S0SPSR to 0x80, it usually
> works fine. Uncommenting the last line, the function causes the
> function to exit randomly after writing the first byte, with i = 0x10
> (Mode Fault). So I'm guessing the mode fault triggers me to write
> another byte, which results in the Write Collision.
>
> So why the random mode fault? the LPC isn't really talking to
> anything, data is just going to my logic analyzer, so nothing else
> should be contending as master. Also, SSEL is pulled high, so there
> shouldn't be anything messing with SSEL to even cause a mode fault.
>
> Any help is appreciated. -Joe
>
I do pull SSEL high and use another pin for CS.
I appreciate the help from everyone on this list, I really do. And I do
not in any way want to disrespect the graciousness of the contributors
to this list. But this is the third "Pull SSEL high" response I've
received (despite me saying at the bottom of the email that I pull SSEL
high). I've done my research, I've looked at all the SPI posts on this
list, none apply. I would like to know if anyone has anything else to
offer as a possible solution.

Kindest regards. -Joe

>>> k...@yahoo.com >>>
Pull up SSEL and use another pin to CS.

Regards
Krzysztof

--- In l..., "rawjoeshaw" wrote:
>
> I keep seeing Mode Faults when I do SPI writes on my LPC2106. Here is
> my write function:
>
> void SPI_Write(unsigned char *buffer,unsigned int bytecount)
> {
> unsigned int j;
> unsigned int i = 0;
> while (bytecount--) {
> S0SPDR_bit.DATA = *buffer++;
> while (!(j=(S0SPSR&0xF8))) ;
> i |= j;
> //if (i != 0x80) break;
> }
> }
>
> At the end of the write function, i will be 0xD0, which indicates
> SPIF, WCOL, and MODF. If I only compare S0SPSR to 0x80, it usually
> works fine. Uncommenting the last line, the function causes the
> function to exit randomly after writing the first byte, with i = 0x10
> (Mode Fault). So I'm guessing the mode fault triggers me to write
> another byte, which results in the Write Collision.
>
> So why the random mode fault? the LPC isn't really talking to
> anything, data is just going to my logic analyzer, so nothing else
> should be contending as master. Also, SSEL is pulled high, so there
> shouldn't be anything messing with SSEL to even cause a mode fault.
>
> Any help is appreciated. -Joe
>
--- In l..., "rawjoeshaw" wrote:
>
> I keep seeing Mode Faults when I do SPI writes on my LPC2106. Here
is
> my write function:
>
> void SPI_Write(unsigned char *buffer,unsigned int bytecount)
> {
> unsigned int j;
> unsigned int i = 0;
> while (bytecount--) {
> S0SPDR_bit.DATA = *buffer++;
> while (!(j=(S0SPSR&0xF8))) ;
> i |= j;
> //if (i != 0x80) break;
> }
> }
>
> At the end of the write function, i will be 0xD0, which indicates
> SPIF, WCOL, and MODF. If I only compare S0SPSR to 0x80, it usually
> works fine. Uncommenting the last line, the function causes the
> function to exit randomly after writing the first byte, with i 0x10
> (Mode Fault). So I'm guessing the mode fault triggers me to write
> another byte, which results in the Write Collision.
>
> So why the random mode fault? the LPC isn't really talking to
> anything, data is just going to my logic analyzer, so nothing else
> should be contending as master. Also, SSEL is pulled high, so there
> shouldn't be anything messing with SSEL to even cause a mode fault.
>
> Any help is appreciated. -Joe

Hey Joe. I'm just reading about this now and haven't actually tried
it yet. But from the LPC214x User Manual, here's the recommended
sequence of events for Master operation:

1. Set the SPI clock counter register to the desired clock rate.
2. Set the SPI control register to the desired settings.
3. Write the data to transmitted to the SPI data register. This write
starts the SPI data
transfer.
4. Wait for the SPIF bit in the SPI status register to be set to 1.
The SPIF bit will be set
after the last cycle of the SPI data transfer.
5. Read the SPI status register.
6. Read the received data from the SPI data register (optional).
7. Go to step 3 if more data is required to transmit.

Reading that literally, you're supposed to wait for SPIF bit to go to
1 (step #4) *before* attempting to read any other status bits (step
#5). And you said, "If I only compare S0SPSR to 0x80, it usually
works fine." So perhaps the other status bits aren't accurate up to
that point, and one of them is erroneously going high, triggering
exit from the while loop before the correct time?

This might do the trick:

while (!((i=S0SPSR)&0x80));
if (i != 0x80) break;