Yahoo Groups archive

Lpc2000

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

Message

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:
>
> 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.