Yahoo Groups archive

Lpc2000

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

Message

Re: SPI, SSP on LPC2148 MCB2140 Keil Bug?

2005-09-01 by philips_apps

Hello Malcom,

Apart from the fact that the SSP supports several different serial 
interfaces compared to the SPI0 (SPI/SSI/Microwire vs SPI only), the 
key difference between the SSP and the SPI0 is the buffered 
transmission: there is a 8 frame deep FIFO for transmitting and a 8 
frame deep FIFO for receiving data. While sending data via SPI 
master configured SSP seems pretty similar to SPI0 master operation 
(simple write into the SSPDR), receiving data is a bit different.

Knowing that in any SPI mode for every single transmitted frame of 
data one frame of data is received, you expect that after 0x9F is 
sent, one byte is received. After sending 0x00, the second byte will 
be sitting in the SSP Rx FIFO (the one you seem to be interested in).

Having said this, you would have to perform one dummy read from the 
SSP Rx FIFO before you would actually access the desired data.

Also, keep in mind that with single stepping thru your code, you 
have unintentionally performed several reads from the SSP Rx FIFO. 
Additionally, you have not described the way you have declared 
your "input" variable: was it "unsigned char input;" or "volatile 
unsigned char input"? Declaring any variable that will be dealing 
with a LPC2000 register(s) as a "volatile" works well for us when 
testing hw/sw in Keil's uVision3 environment.

Recently we have tested LPC2148's SSP interface using a SPI Flash 
memory PMC25LV512. Here is the code for reading SPI memory's ID. 
This particular communication requires master to send a 
command "0xAB" followed by 3 dummy bytes. At the end, three dummy 
MOSI transmissions shift out Manufacturer and Device IDs. 

void main (void)  {
	volatile unsigned char RAM_data;	//temp variable
	volatile unsigned char flash_re[16];
	signed long int i;

//pin selection: P0.19(MOSI),P0.18(MISO),P0.17(SCK),P0.16(SSout)
	PINSEL1 = 0x000000A8;		
	IODIR0 = 0x00010000;		
	IOSET0 = 0x00010000;	//set SSout=1
//SSP initialization
	SSPCR0	= 0x01C7;	//8 bit SPI with CPHA=1,CPOL=1,SCR=1 
	SSPCR1	= 0x00;		//SSP master (off) in normal mode
	SSPCPSR	= 0x02;		//SPI clock
	SSPCR1	= 0x02;		//enable SSP master in normal mode
	RAM_data = SSPDR;	//read 8 bytes (clear SSP Rx FIFO)
	RAM_data = SSPDR;
	RAM_data = SSPDR;
	RAM_data = SSPDR;
	RAM_data = SSPDR;
	RAM_data = SSPDR;
	RAM_data = SSPDR;
	RAM_data = SSPDR;

	while(1){
//RDID command
	   IOCLR0 = 0x00010000;	//select SPI Flash
	   SSPDR = 0xAB;	//send command 0xAB...
	   SSPDR = 0x00;	//send dummy byte 1
	   SSPDR = 0x00;	//send dummy byte 2
	   SSPDR = 0x00;	//send dummy byte 3
	   SSPDR = 0x00;	//send dummy byte 4 (Rx man.id ID1)
  	   SSPDR = 0x00;	//send dummy byte 5 (Rx dev.id ID)
 	   SSPDR = 0x00;	//send dummy byte 6 (Rx man.id ID2)
  	   while((SSPSR & 0x10)==0x10);	//wait for the idle micro
		for (i=0;i<=6;i++) 	//read 7 bytes from FIFO
			flash_re[i]=SSPDR;
		IOSET0	= 0x00010000;	//deselect SPI Flash
	}
}

In this example flash_re[4]=0x9D, flash_re[5]=0x7B, and flash_re[6]
=0x7F, as it is specified in the memory's documentation.

Regards,

Philips Apps Team

--- In lpc2000@yahoogroups.com, "highgatematem28" <medwar19@h...> 
wrote:
> Hi All,
> 
> Has anyone set up the SPI or SSP on the LPC2148?
> 
> I cant get SPI0 to work at all, i.e. no SCK when I scope the dev 
board 
> (I have pull ups on SCK, MOSI0, MOI0 & SSEL0) and it is turned on 
in 
> the power reg.
> 
> void SPI_Init (void)
> {
> PINSEL0 = 0x00005500; // SPI Pins
> IODIR0 = 0x00000400; // Chipselect
> S0SPCCR = 0x000000FF; // bit timing
> S0SPCR = 0x000000A0; // Master, Ints enabled
> 
> VICVectCntl0 = 0x0000002A;
> VICVectAddr0 = (unsigned);
> VICIntEnable = 0x00000400;
> }
> 
> while(1)
> {
> SOSPDR = 0x5555;  // write continuously to stimulate SCK
> }
> 
> 
> So I thought I'll try the SSP instead.
> Set that up with, no interrupts: -
> 
> void SPI1_Init (void)
> {
> PINSEL1 = 0x000002A8; // SPI1 pins
> SSPCR0 = 0x00000007;
> SSPCR1 = 0x00000002;
> SSPCPSR = 0x00000002; // 30 MHz SCK
> SSPCPSR = 0x00007530;
> }
> 
> And the SPI1 SCK is there when I scope the hardware. Great!
> But no.... try reading data from the SPI and it's not there. So I 
> start single stepping and find the data only stays in the SSPDR 
reg 
> for one assembler instruction and is then lost (Keil Bug?).
> 
> My read command is 0x9F, which should return 0x20.
> 
> So my function is:
> 
> void read_Device_Type(void)
> {
> IOCLR0 = 0x00000400; // Pull Chip Sel low
> while (SSPSR & BSY); // wait for SPI Idle
> SSPDR = 0x009F; // Write command (1)
> while (!(SSPSR & TNF)); // Wait transmit
> SSPDR = 0x0000; // Dummy write (2)
> while (!(SSPSR & TNF)); // Wait transmit
> input = SSPDR; // Data from device (3)
> IOSET0 = 0x00000400; // Chip select high
> }
> 
> Now, looking at the memory location of SSPDR I find that after (1) 
> SSPDR = 0xFF, then after (2) SSPDR = 0x20 (what I expect) but when 
I 
> read SSPDR at (3) it returns 0x00.
> 
> If I replace (2) with (3) I return 0x00
> 
> 
> The disasembler reveals an STRH R1, [R0] instruction which shows 
the 
> correct return value but this is lost in the next LDR instruction.
> 
> Have scoped the data in and data out pins and I can see the 
correct 
> data on both.
> 
> Hope that gives you enough to understand, I spent all day on 
this....
> 
> Thanks,
> 
> Malcom

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.