Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Message

Re: [lpc2000] Re: SPI Code hangs

2006-03-09 by Tom Walsh

brightside_design wrote:

>--- In lpc2000@yahoogroups.com, 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..."
----------------------------------------------------

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.