EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

SPI Code hangs

Started by brightside_design March 8, 2006
I have a problem with a simple SPI example program.
Part: LPC2129
PCK: 14.7 MHz
Mode: Master, CPOL=0, CPHA=0, LSIF=0.

I initialise the SPI like this:-
void SPI_Init(void)
   {
	S0SPCCR = 0x26;	// Divides PCK to give about 400kHz
	S0SPCR = 0x20;	// Select Master mode
   }

And then use the SPI like this:-
void SPI_Transfer( char *buf, int count)
{
	int r = 0, i = 0;

	for( ; i < count; i++ )
	{
		S0SPDR = buf[i];	// Write data
		do{ r = S0SPSR; }while(!(r & 0x80));// Wait for SPIF
		// Read status - to be done
		buf[i] = S0SPDR;	// Read data
	}
}

Sometimes I power up the device and this function runs correctly 
with problem whatsoever. Other times the function just hangs. If I 
attach a JTAG debugger (Keil ULINK) I find that the function is 
hanging at the line "do{ r = S0SPSR; }while(!(r & 0x80));" on the 
first itteration.

There is no hardware attached to the SPI port. I figured that the 
device should put data out onto an unconnected pin without any 
problem and that I should be able to get the software working before 
thinking about ading hardware.

Has anyone got any ideas what might be going wrong?

Thanks,

Paul
	

An Engineer's Guide to the LPC2100 Series

brightside_design wrote:

>I have a problem with a simple SPI example program.
>Part: LPC2129
>PCK: 14.7 MHz
>Mode: Master, CPOL=0, CPHA=0, LSIF=0.
>
>I initialise the SPI like this:-
>void SPI_Init(void)
>   {
>	S0SPCCR = 0x26;	// Divides PCK to give about 400kHz
>	S0SPCR = 0x20;	// Select Master mode
>   }
>
>And then use the SPI like this:-
>void SPI_Transfer( char *buf, int count)
>{
>	int r = 0, i = 0;
>
>	for( ; i < count; i++ )
>	{
>		S0SPDR = buf[i];	// Write data
>		do{ r = S0SPSR; }while(!(r & 0x80));// Wait for SPIF
>		// Read status - to be done
>		buf[i] = S0SPDR;	// Read data
>	}
>}
>
>  
>

Try writing it this way:

void SPI_Transfer( char *buf, int count)
{
volatile int r = 0;
volatile int i = 0;
	for( ; i < count; i++ )
	{
		S0SPDR = buf[i];	// Write data
		do{ r = S0SPSR; }while(!(r & 0x80));// Wait for SPIF
		// Read status - to be done
		buf[i] = S0SPDR;	// Read data
	}
}
	If you look deeper at the underlying assembly language via the JTAG, I'm 
fairly confident you will find that it reads "r" once, then loops on
the 
resultant value.  Essentially, the volatile keyword tells the compiler 
to assume nothing about the variables' value it holds, to actually check 
it rather than to optimize the reference.

YMMV, but your function would probably work if you turned off all 
optimizations (-O0).

TomW
	>Sometimes I power up the device and this function runs correctly 
>with problem whatsoever. Other times the function
just hangs. If I 
>attach a JTAG debugger (Keil ULINK) I find that the function is 
>hanging at the line "do{ r = S0SPSR; }while(!(r & 0x80));" on
the 
>first itteration.
>
>There is no hardware attached to the SPI port. I figured that the 
>device should put data out onto an unconnected pin without any 
>problem and that I should be able to get the software working before 
>thinking about ading hardware.
>
>Has anyone got any ideas what might be going wrong?
>
>Thanks,
>
>Paul
>
>
>
>
>
> 
>Yahoo! Groups Links
>
>
>
> 
>
>
>
>  
>
	-- 
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------
	
--- In lpc2000@lpc2..., Tom Walsh <tom@...> wrote:
>
> brightside_design wrote:
> 
> >I have a problem with a simple SPI example program.
> >Part: LPC2129
> >PCK: 14.7 MHz
> >Mode: Master, CPOL=0, CPHA=0, LSIF=0.
> >
> >I initialise the SPI like this:-
> >void SPI_Init(void)
> >   {
> >	S0SPCCR = 0x26;	// Divides PCK to give about 400kHz
> >	S0SPCR = 0x20;	// Select Master mode
> >   }
> >
> >And then use the SPI like this:-
> >void SPI_Transfer( char *buf, int count)
> >{
> >	int r = 0, i = 0;
> >
> >	for( ; i < count; i++ )
> >	{
> >		S0SPDR = buf[i];	// Write data
> >		do{ r = S0SPSR; }while(!(r & 0x80));// Wait for SPIF
> >		// Read status - to be done
> >		buf[i] = S0SPDR;	// Read data
> >	}
> >}
> >
> >  
> >
> 
> Try writing it this way:
> 
> void SPI_Transfer( char *buf, int count)
> {
> volatile int r = 0;
> volatile int i = 0;
> 	for( ; i < count; i++ )
> 	{
> 		S0SPDR = buf[i];	// Write data
> 		do{ r = S0SPSR; }while(!(r & 0x80));// Wait for SPIF
> 		// Read status - to be done
> 		buf[i] = S0SPDR;	// Read data
> 	}
> }
> 
> 
> If you look deeper at the underlying assembly language via the 
JTAG, I'm 
> fairly confident you will find that it reads
"r" once, then loops 
on the 
> resultant value.  Essentially, the volatile
keyword tells the 
compiler 
> to assume nothing about the variables' value
it holds, to actually 
check 
> it rather than to optimize the reference.
> 
> YMMV, but your function would probably work if you turned off all 
> optimizations (-O0).
> 
> TomW
> 
> 
> >Sometimes I power up the device and this function runs correctly 
> >with problem whatsoever. Other times the function just hangs. If 
I 
> >attach a JTAG debugger (Keil ULINK) I find
that the function is 
> >hanging at the line "do{ r = S0SPSR; }while(!(r &
0x80));" on the 
> >first itteration.
> >
> >There is no hardware attached to the SPI port. I figured that the 
> >device should put data out onto an unconnected pin without any 
> >problem and that I should be able to get the software working 
before 
> >thinking about ading hardware.
> >
> >Has anyone got any ideas what might be going wrong?
> >
> >Thanks,
> >
> >Paul
> 
> 
> -- 
> Tom Walsh - WN3L - Embedded Systems Consultant
> http://openhardware.net, http://cyberiansoftware.com
> "Windows? No thanks, I have work to do..."
> ----------------
>

Thanks Tom, I will try that when I have a moment but I don't think 
thats the answer. I've just read through the disassemby for that 
function and it is reading the register each time through. Also the 
problem is intermittant, sometimes it works fine, other times it 
hangs.

Paul
	
brightside_design wrote:

>--- In lpc2000@lpc2..., Tom Walsh <tom@...>
wrote:
>  
>
>>brightside_design wrote:
>>
>>    
>>
>>>I have a problem with a simple SPI example program.
>>>Part: LPC2129
>>>PCK: 14.7 MHz
>>>Mode: Master, CPOL=0, CPHA=0, LSIF=0.
>>>
>>>I initialise the SPI like this:-
>>>void SPI_Init(void)
>>>  {
>>>	S0SPCCR = 0x26;	// Divides PCK to give about 400kHz
>>>	S0SPCR = 0x20;	// Select Master mode
>>>  }
>>>
>>>And then use the SPI like this:-
>>>void SPI_Transfer( char *buf, int count)
>>>{
>>>	int r = 0, i = 0;
>>>
>>>	for( ; i < count; i++ )
>>>	{
>>>		S0SPDR = buf[i];	// Write data
>>>		do{ r = S0SPSR; }while(!(r & 0x80));// Wait for SPIF
>>>		// Read status - to be done
>>>		buf[i] = S0SPDR;	// Read data
>>>	}
>>>}
>>>
>>> 
>>>
>>>      
>>>
>>Try writing it this way:
>>
>>void SPI_Transfer( char *buf, int count)
>>{
>>volatile int r = 0;
>>volatile int i = 0;
>>	for( ; i < count; i++ )
>>	{
>>		S0SPDR = buf[i];	// Write data
>>		do{ r = S0SPSR; }while(!(r & 0x80));// Wait for SPIF
>>		// Read status - to be done
>>		buf[i] = S0SPDR;	// Read data
>>	}
>>}
>>
>>
>>If you look deeper at the underlying assembly language via the 
>>    
>>
>JTAG, I'm 
>  
>
>>fairly confident you will find that it reads "r" once, then
loops 
>>    
>>
>on the 
>  
>
>>resultant value.  Essentially, the volatile keyword tells the 
>>    
>>
>compiler 
>  
>
>>to assume nothing about the variables' value it holds, to actually 
>>    
>>
>check 
>  
>
>>it rather than to optimize the reference.
>>
>>YMMV, but your function would probably work if you turned off all 
>>optimizations (-O0).
>>
>>TomW
>>
>>
>>    
>>
>>>Sometimes I power up the device and this function runs correctly 
>>>with problem whatsoever. Other times the function just hangs. If 
>>>      
>>>
>I 
>  
>
>>>attach a JTAG debugger (Keil ULINK) I find that the function is 
>>>hanging at the line "do{ r = S0SPSR; }while(!(r &
0x80));" on the 
>>>first itteration.
>>>
>>>There is no hardware attached to the SPI port. I figured that the 
>>>device should put data out onto an unconnected pin without any 
>>>problem and that I should be able to get the software working 
>>>      
>>>
>before 
>  
>
>>>thinking about ading hardware.
>>>
>>>Has anyone got any ideas what might be going wrong?
>>>
>>>Thanks,
>>>
>>>Paul
>>>      
>>>
>>-- 
>>Tom Walsh - WN3L - Embedded Systems Consultant
>>http://openhardware.net, http://cyberiansoftware.com
>>"Windows? No thanks, I have work to do..."
>>----------------
>>
>>    
>>
>
>Thanks Tom, I will try that when I have a moment but I don't think 
>thats the answer. I've just read through the disassemby for that 
>function and it is reading the register each time through. Also the 
>problem is intermittant, sometimes it works fine, other times it 
>hangs.
>
>  
>
I have a state machine which is servicing three MAX3100 UARTS on the SPI 
circuit.  The state machine steps are governed by the SPI interrupt.  
Each time an SPI interrupt fires, the state machine advances one step.  
  The machine runs until all UARTS are "quiet", meaning nothing to 
transmit and nothing in the recievers.  Then the machine shuts down.

The state machine is driven by the SPI interrupt, however, the initial 
"kick-off" of putting the machine into motion is handled by two
external 
conditions:

1) EXTINT0 is triggered by a wired-OR of the IRQ output of the MAX3100's 
(interrupt asserted only on RX data available).

2) Data has been entered into one of the transmit queues.  In which 
case, the EXTINT0 ISR is soft triggered via  VICSoftInt bit.

That is the structure of my ISR and it's relation to the other software 
in the system.  What I'd found was that this state machine / VICSoftInt 
mechanism would run fine for a while, then randomly the SPI ISR would 
deadlock looking for the SPI completion bit.  The only way I've found 
out of that deadlock was to put a timeout in the code which looks at the 
completion bit:

================= begin spiISR() =============void spi0ISR (void)
{// state machine to service the uarts.
volatile ushort byt;
   for (byt=0x80; byt; byt--) if (SPSR & 0x80) break;
   switch (spiState) {
         /////////////////////////////////////////
         // handler for serial2
         /////////////////////////////////////////
      case Srx2step0:   // begin the walk down all three uarts.
            // assume shutdown in final state...
            // but any activty will force a new cycle to run.
         AllIsQuietOnSpi = True;
         dataWord = getS2DataTosend();
            // send first byte on its way.
         IOCLR = SEL2_BIT;
         spiState = Srx2step1;
         SPDR = (dataWord >> 8);
         break;
...
================== snip ===============
This works for me.  I don't like it, but it works.  I'd spent several 
days trying to work out why the SPI would deadlock and could not find 
any explanation.  What I did find out is that the SPI interrupt would 
fire well before the SPIF completion bit was set!!!

This was proven by examining the value of the "byt" variable in my
above 
routine.  It always showed that a significant number of loops occurred 
before the SPIF bit was seen.  There were random intervals in which the 
for() loop would expire to full count (zero).  After some testing, I 
arrived at the value of 0x80 as the loop value which was twice the worst 
case delay count awaiting the SPIF bit (when it did not goto zero).

So, I would arrive at the spiISR service and have to wait for the 
completion bit.  Sometimes there would be an interrupt, but never a 
completion bit.  I also found that I had to wait until that bit appeared 
otherwise if I assumed that because I was in the ISR due to a completed 
cycle and simply load the next byte into the SPI data register, the SPI 
would sometimes die with a WCOL write collision!

According to the docs, there is absolutely no information nor timing 
diagrams detailing the relationship of: the SPIF bit, shift clock, and 
interrupts.  Again, the Philips docs are sadly lacking in detail on 
critical issues (see discussion in this group messages regarding the ADC 
leakage).

This is with the LPC2106 processor.  Interestingly, the SSI of the 
LPC2138 does not suffer from this problem...  So, there appears to be an 
as yet documented failure / weakness in the LCP2106 SPI controller.

Given that I was three months into this new board, had my first 
prototype and was commited to using the Philips part, I had to "deal 
with it".  Not like I've been here before.  :-/

The random deadlock is explained as a race condition between when the 
interrupt fired and when I actually reloaded the SPI TX register.  Most 
times I would be outside of the time between the SPI interrupt and SPIF 
flagging, but sometimes I would hit it and lockup the SPI controller.

I cannot explain why the SPIF bit is missed however. That appears to be 
a race condition in the silicon where a co-incidence of reading from the 
SPI status register vs. the AHB writing into the status register... ???
	Regards,

TomW
	-- 
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------
	
brightside_design wrote:

>--- In lpc2000@lpc2..., Tom Walsh <tom@...>
wrote:
>  
>
>>brightside_design wrote:
>>
>>    
>>
>>>I have a problem with a simple SPI example program.
>>>Part: LPC2129
>>>PCK: 14.7 MHz
>>>Mode: Master, CPOL=0, CPHA=0, LSIF=0.
>>>
>>>I initialise the SPI like this:-
>>>void SPI_Init(void)
>>>  {
>>>	S0SPCCR = 0x26;	// Divides PCK to give about 400kHz
>>>	S0SPCR = 0x20;	// Select Master mode
>>>  }
>>>
>>>And then use the SPI like this:-
>>>void SPI_Transfer( char *buf, int count)
>>>{
>>>	int r = 0, i = 0;
>>>
>>>	for( ; i < count; i++ )
>>>	{
>>>		S0SPDR = buf[i];	// Write data
>>>		do{ r = S0SPSR; }while(!(r & 0x80));// Wait for SPIF
>>>		// Read status - to be done
>>>		buf[i] = S0SPDR;	// Read data
>>>	}
>>>}
>>>
>>> 
>>>
>>>      
>>>
>>Try writing it this way:
>>
>>void SPI_Transfer( char *buf, int count)
>>{
>>volatile int r = 0;
>>volatile int i = 0;
>>	for( ; i < count; i++ )
>>	{
>>		S0SPDR = buf[i];	// Write data
>>		do{ r = S0SPSR; }while(!(r & 0x80));// Wait for SPIF
>>		// Read status - to be done
>>		buf[i] = S0SPDR;	// Read data
>>	}
>>}
>>
>>
>>If you look deeper at the underlying assembly language via the 
>>    
>>
>JTAG, I'm 
>  
>
>>fairly confident you will find that it reads "r" once, then
loops 
>>    
>>
>on the 
>  
>
>>resultant value.  Essentially, the volatile keyword tells the 
>>    
>>
>compiler 
>  
>
>>to assume nothing about the variables' value it holds, to actually 
>>    
>>
>check 
>  
>
>>it rather than to optimize the reference.
>>
>>YMMV, but your function would probably work if you turned off all 
>>optimizations (-O0).
>>
>>TomW
>>
>>
>>    
>>
>>>Sometimes I power up the device and this function runs correctly 
>>>with problem whatsoever. Other times the function just hangs. If 
>>>      
>>>
>I 
>  
>
>>>attach a JTAG debugger (Keil ULINK) I find that the function is 
>>>hanging at the line "do{ r = S0SPSR; }while(!(r &
0x80));" on the 
>>>first itteration.
>>>
>>>There is no hardware attached to the SPI port. I figured that the 
>>>device should put data out onto an unconnected pin without any 
>>>problem and that I should be able to get the software working 
>>>      
>>>
>before 
>  
>
>>>thinking about ading hardware.
>>>
>>>Has anyone got any ideas what might be going wrong?
>>>
>>>Thanks,
>>>
>>>Paul
>>>      
>>>
>>-- 
>>Tom Walsh - WN3L - Embedded Systems Consultant
>>http://openhardware.net, http://cyberiansoftware.com
>>"Windows? No thanks, I have work to do..."
>>----------------
>>
>>    
>>
>
>Thanks Tom, I will try that when I have a moment but I don't think 
>thats the answer. I've just read through the disassemby for that 
>function and it is reading the register each time through. Also the 
>problem is intermittant, sometimes it works fine, other times it 
>hangs.
>
>  
>
Oh, just some further information.  The LPC2106 is running  the SPI 
under interrupts while the LCP2138 is not.  Here is a sample of the SSI 
bit polling on the LPC2138:

========== begin spiPutByte() ===========
static void spiPutByte(uchar inBuf)
{// spit a byte of data at the MMC.
   SSPDR = (REG16) inBuf; while (SSPSR & SSP_BSY);
      // dummy read clears SPI BSY flag on LPC2xxx processors.
   dummyReader = (uchar) SSPDR;
}

=============== snip ==============
I am not yet using the SPI on the LPC2138, so that doesn't prove 
anything other than the SSI is more durable?

TomW
	-- 
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------
	
Hi.

I had no time to enter in depth regarding your problem but when
I read your phrase: 
"I cannot explain why the SPIF bit is missed however. That appears to
be a race condition in the silicon where a co-incidence of reading
from the SPI status register vs. the AHB writing into the status
register... ???"

I remembered the errata document for the LPC2138 processor where
similar problems are documented for both the timer and the uart.
If you write a register via software at the same time that hardware
want to write the same register, the hardware write is not performed.
For timer this occurs when you are clearing a timer match interrupt
(ex. interrupt on match0) and another match occurs at the same time
(ex. match1): the match interrupt is never generated.
For uart this occurs if you read the IIR register, clearing the THRE
bit and at the same time the transmitter register become empty so that
hardware want to set the THRE bit: the bit is never set, the interrupt
is never generated.

The consequence is: if timers and uarts have these problems, why not
the SPI?
Have you checked the ERRATA for the LPC2106?

Anyway, I agree that "there is absolutely no information nor timing
diagrams detailing the relationship of: the SPIF bit, shift clock, and
interrupts.  Again, the Philips docs are sadly lacking in detail on
critical issues (see discussion in this group messages regarding the
ADC leakage)."

I know of my colleague working with SPI on LPC2138 and finding a lot
of problems.
I think that Philips failed create a microcontroller with "robust"
peripherals to be used in industrial environment.
Unfortunately (or fortunately??) it is very cheap, and this attract
the marketing peoples (the programmers will patch the code in one mode
or another...)

Good luck,
Carlo

--- In lpc2000@lpc2..., Tom Walsh <tom@...> wrote:
>

> Oh, just some further information.  The LPC2106 is
running  the SPI 
> under interrupts while the LCP2138 is not.  Here is a sample of the SSI 
> bit polling on the LPC2138:
> 
> ========== begin spiPutByte() ===========> 
> static void spiPutByte(uchar inBuf)
> {// spit a byte of data at the MMC.
>    SSPDR = (REG16) inBuf; while (SSPSR & SSP_BSY);
>       // dummy read clears SPI BSY flag on LPC2xxx processors.
>    dummyReader = (uchar) SSPDR;
> }
> 
> =============== snip ==============> 
> I am not yet using the SPI on the LPC2138, so that doesn't prove 
> anything other than the SSI is more durable?
> 
> TomW
> 
> 
> -- 
> Tom Walsh - WN3L - Embedded Systems Consultant
> http://openhardware.net, http://cyberiansoftware.com
> "Windows? No thanks, I have work to do..."
> ----------------
>
	
c.barbaro wrote:

>Hi.
>
>I had no time to enter in depth regarding your problem but when
>I read your phrase: 
>"I cannot explain why the SPIF bit is missed however. That appears to
>be a race condition in the silicon where a co-incidence of reading
>from the SPI status register vs. the AHB writing into the status
>register... ???"
>
>I remembered the errata document for the LPC2138 processor where
>similar problems are documented for both the timer and the uart.
>If you write a register via software at the same time that hardware
>want to write the same register, the hardware write is not performed.
>For timer this occurs when you are clearing a timer match interrupt
>(ex. interrupt on match0) and another match occurs at the same time
>(ex. match1): the match interrupt is never generated.
>For uart this occurs if you read the IIR register, clearing the THRE
>bit and at the same time the transmitter register become empty so that
>hardware want to set the THRE bit: the bit is never set, the interrupt
>is never generated.
>
>The consequence is: if timers and uarts have these problems, why not
>the SPI?
>Have you checked the ERRATA for the LPC2106?
>
>  
>
Yes, and I do think that you are correct.   It may be an inherent design 
failure of the AHB.  The discussion in apnote AN10414 strongly suggests 
to me that there are such flaws in the hardware mechanisms between the 
ARM core and the peripheral bus.

>Anyway, I agree that "there is absolutely no
information nor timing
>diagrams detailing the relationship of: the SPIF bit, shift clock, and
>interrupts.  Again, the Philips docs are sadly lacking in detail on
>critical issues (see discussion in this group messages regarding the
>ADC leakage)."
>
>I know of my colleague working with SPI on LPC2138 and finding a lot
>of problems.
>I think that Philips failed create a microcontroller with "robust"
>peripherals to be used in industrial environment.
>Unfortunately (or fortunately??) it is very cheap, and this attract
>the marketing peoples (the programmers will patch the code in one mode
>or another...)
>
>  
>
Well, I don't think that we can really fault Philips for some of
this.  
IMO, ARM Inc. itself shares some of this blame.  I see that ARM Inc. is 
the one pushing / offering the AHB peripheral bus.  I suspect that 
Philips collected the LPC2000 series together, Ala Carte, from a menu of 
IP available from ARM.  So, design flaws in the AHB are being 
promulgated into customers' silicon.

The documentation issue is a real black-eye though.  I've been designing 
systems for a long time now and the documentation for the LPC2000 series 
is atrocious!  The documentation is okay for writing software, but the 
hardware documentation is simply terrible!

For example: refer to Philips document UM10120 "LPC213x User Manual". 

Look at Section 12.4.5 "SPI Interrupt register (S0SPINT - 
0xE002 001C)".  The only mention of the relationship of the SPI data 
register shifting to an empty state and the occurance of the interrupt is:

"SPI interrupt flag. Set by the SPI interface to generate an interrupt. 
Cleared by writing a 1 to this bit.
Note: this bit will be set once when SPIE = 1 and at least one of SPIF 
and WCOL bits is 1. However, only when the SPI Interrupt bit is set and 
SPI0 Interrupt is enabled in the VIC, SPI based interrupt can be 
processed by interrupt handling software."

That is it!  No timing diagram or flow chart to explain the process.  
Just a vague statement that the interrupt bit is used to set an 
interrupt condition.  This is a childish explanation, thoroughly lacking 
in any detail.  Any embedded engineer knows what an interrupt does, we 
need to know WHEN you set the interrupt, what is the relationship of the 
SPIF + SPINT?

1) Which comes first, the SPIF or SPINT?

2) At what clock & edge does the SPIF become asserted?

3) At what clock & edge does SPINT get asserted?

Those are questions that hardware + software engineers need to have 
answered.   Not some silly pablum about what an interrupt is.  The 
documentation is okay as far as identifying where the registers are and 
what bits are used for...  The documentation is littered with these 
omissions.

Another example, what is the characteristic input capacitance of the 
clock circuits?  I have an 18pf crystal, how many picofarads will the 
processor pins represent when calculating the additional load 
capacitance for proper crystal operation?  If the range is, say, from 
3pf..13pf then document that so that we are aware that the loading 
capacitance may have to be altered in production due to silicon 
fabrication differences.

Another example, what is the characteristic input resistance of the ADC 
circuit?  Is that resistance a fixed value or does it change 
significantly during conversion (conversion loading)?

Now, my question is, if this is not the definitive document we should be 
looking at for this information: WHERE IS THE "REAL" DOCUMENTATION???

I just get very annoyed at having to spend days trying to 'get it
right' 
due to the lack of adequate documentation.  I am not a hobbyist, I do 
this for a living.
	TomW

-- 
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------
	
A quick sanity check:
You say you have no hardware attached.
You know you need a pull-up resistor on the SSEL pin,
which MUST be routed to the SPI block in PINSEL0.

The user manual tells you that you can't use the SSEL pin for GPIO
on devices earlier than the 2148 - even if you only ever use SSP as a master!
Without this, if the pin (or when wired as GPIO, the internal floating net)
goes low, the SPI will automatically be a slave.

imho this should be in an official "gotcha" document even if it is not
an errata item.

Hope this helps,
Danish
--- In lpc2000@lpc2..., "brightside_design"
<brightside_design@...> wrote:
>
> I have a problem with a simple SPI example program.
> Part: LPC2129
> PCK: 14.7 MHz
> Mode: Master, CPOL=0, CPHA=0, LSIF=0.
> 
> ...
> Sometimes I power up the device and this function runs correctly 
> with problem whatsoever. Other times the function just hangs. If I 
> attach a JTAG debugger (Keil ULINK) I find that the function is 
> hanging at the line "do{ r = S0SPSR; }while(!(r & 0x80));" on
the 
> first itteration.
> 
> There is no hardware attached to the SPI port. I figured that the 
> device should put data out onto an unconnected pin without any 
> problem and that I should be able to get the software working before 
> thinking about ading hardware.
> 
> Has anyone got any ideas what might be going wrong?
> 
> Thanks,
> 
> Paul
>
	
Quoting Danish Ali <danish@dani...>:

> A quick sanity check:
> You say you have no hardware attached.
> You know you need a pull-up resistor on the SSEL pin,
> which MUST be routed to the SPI block in PINSEL0.
>
> The user manual tells you that you can't use the SSEL pin for GPIO
> on devices earlier than the 2148 - even if you only ever use SSP as a
master!
> Without this, if the pin (or when wired as GPIO, the internal floating net)
> goes low, the SPI will automatically be a slave.
>
> imho this should be in an official "gotcha" document even if it
is 
> not an errata item.

See http://www.open-research.org.uk/ARMuC/LPC2100Tips.html

Robert
	
--- In lpc2000@lpc2..., Robert Adsett <subscriptions@...> 
wrote:
>
> Quoting Danish Ali <danish@...>:
> 
> > A quick sanity check:
> > You say you have no hardware attached.
> > You know you need a pull-up resistor on the SSEL pin,
> > which MUST be routed to the SPI block in PINSEL0.
> >
> > The user manual tells you that you can't use the SSEL pin for
GPIO
> > on devices earlier than the 2148 - even if you only ever use SSP 
as a master!
> > Without this, if the pin (or when wired as
GPIO, the internal 
floating net)
> > goes low, the SPI will automatically be a
slave.
> >
> > imho this should be in an official "gotcha" document even if
it 
is 
> > not an errata item.
> 
> See http://www.open-research.org.uk/ARMuC/LPC2100Tips.html
> 
> Robert
>

I just added a pull-up to SSEL and it appears to be working! Thanks 
for the help Danish and thank you Robert for the link; I'm sure I 
would have been falling into one of the other "gotchas" in the next 
few days!

Paul
	

The 2024 Embedded Online Conference