Reply by Robert Adsett March 10, 20062006-03-10
At 08:16 AM 3/10/2006 +0000, Danish Ali wrote:
>That's a very useful page. (I can't vouch
for the chinese-like
>text at the bottom) but I still say it should be an _official_
>Philips document, so those who start with (say) an lpc2148 and
>then say "I need more pins" can move to an lpc2294 knowing the
>areas which require attention even if they only know documents
>from Philips.
	It might be nice but the wiki is capable of responding far faster than 
Philips bureaucracy.

Mutter, spammers.  Spam removed from various pages now.  BTW community help 
in keeping the pages up to date and clean of spam is appreciated (even if 
I'm not the owner of the site I feel confident in that statement)

Robert

" 'Freedom' has no meaning of itself.  There are always
restrictions,   be 
they legal, genetic, or physical.  If you don't believe me, try to chew a 
radio signal. "  -- Kelvin Throop, III
http://www.aeolusdevelopment.com/
	

An Engineer's Guide to the LPC2100 Series

Reply by brendanmurphy37 March 10, 20062006-03-10
--- In lpc2000@lpc2..., Tom Walsh <tom@...> wrote:

> Thank you, I am aware of that document.  It
doesn't pertain to the 
> problem we are seeing.  The problem we are seeing is that at random 
> intervals the SPIF flag does not get set.  For myself, I have an ISR 
> which is triggered by the SPINT request, at the top of the ISR I loop 
> looking for the SPIF flag to be set.  Randomly, this flag fails to be 
> asserted by the hardware.  This causes my ISR to deadlock.
> 

I'd guessed you'd seen it OK, but just in case you weren't aware
of 
it....

The behaviour you describe certainly seems odd, and like you say, 
though the work-around works, I'd be a bit worried too that it could 
fail (on the basis that it's to get around unexplained rather than well 
understood behaviour).

I'd be inclined to reduce the software as much as possible to try and 
isolate the behaviour. This will either identify the source of the 
problem, or if not, should give something small and manageable that 
Philips could take a look at.

Let us know the outcome if you go down this route.

Brendan
	
Reply by Tom Walsh March 10, 20062006-03-10
brendanmurphy37 wrote:

>--- In lpc2000@lpc2..., Tom Walsh <tom@...>
wrote:
>  
>
>>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:
>>    
>>
>
>Tom,
>
>I presume you've seen and taken account of the LPC2106 erratum, 
>specifically the item "unintentional clearing of SPI interrupt
flag" in 
>your investigations?
>
>  
>
Thank you, I am aware of that document.  It doesn't pertain to the 
problem we are seeing.  The problem we are seeing is that at random 
intervals the SPIF flag does not get set.  For myself, I have an ISR 
which is triggered by the SPINT request, at the top of the ISR I loop 
looking for the SPIF flag to be set.  Randomly, this flag fails to be 
asserted by the hardware.  This causes my ISR to deadlock.

I had found that even if you got an SPINT which brough you into the ISR, 
you cannot write into the SPDR until SPIF is set.  Otherwise a WCOL 
would be raised.  So, you have to wait in the ISR until SPIF is raised, 
usually this takes 10..20 interations of a simple for() loop polling the 
SPIF bit.  However, randomly the SPIF bit is never raised, thus leaving 
you deadlocked awaiting that bit.

My, rather inelegant, solution was to put a max interation count to the 
loop and record the max value of the loop when it found a valid SPIF 
bit.  Then I took that value and increased it to what I felt was a 
"worst case" loop value.

So far this has worked, the SPI has run for many hours servicing the 
UARTs under moderate load without a lockup or noticable data loss.  I am 
concerned that although this does work (the max count) it may be that 
later, when the product is released, that data loss may show up!

The SPI of the LPC2106 seems to be rather fragile...

Regards,

TomW
	>I'm not saying this is the cause of the behaviour you're seeing,
but if 
>you haven't looked into this, it might be
worth doing so.
>
>Brendan
>
>
>
>
>
>
>
>
> 
>Yahoo! Groups Links
>
>
>
> 
>
>
>
>
>
>  
>
	-- 
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------
	
Reply by brendanmurphy37 March 10, 20062006-03-10
--- In lpc2000@lpc2..., Tom Walsh <tom@...> wrote:
> 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:

Tom,

I presume you've seen and taken account of the LPC2106 erratum, 
specifically the item "unintentional clearing of SPI interrupt flag"
in 
your investigations?

I'm not saying this is the cause of the behaviour you're seeing, but
if 
you haven't looked into this, it might be worth doing so.

Brendan
	
Reply by brightside_design March 10, 20062006-03-10
--- 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
	
Reply by Robert Adsett March 9, 20062006-03-09
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
	
Reply by Danish Ali March 9, 20062006-03-09
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
>
	
Reply by Tom Walsh March 9, 20062006-03-09
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..."
----------------
	
Reply by c.barbaro March 9, 20062006-03-09
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..."
> ----------------
>
	
Reply by Tom Walsh March 9, 20062006-03-09
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..."
----------------