Yahoo Groups archive

Lpc2000

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

Thread

SPI, SSP on LPC2148 MCB2140 Keil Bug?

SPI, SSP on LPC2148 MCB2140 Keil Bug?

2005-09-01 by highgatematem28

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

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....
Show quoted textHide quoted text
> 
> Thanks,
> 
> Malcom

Re: SPI, SSP on LPC2148 MCB2140 Keil Bug?

2005-11-02 by Problem Solver

Dear Philips Apps Team:
I want to know if it is required to attach a 7-bit crcs and 1 bit stop
bit to the command you sent to detect the card (RDID command)?


--- In lpc2000@yahoogroups.com, "philips_apps" <philips_apps@y...> wrote:
Show quoted textHide quoted text
>
> 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
>

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.