SPI problem

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SPI problem

636 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rahulvasist on Fri Aug 12 01:15:08 MST 2011
Hi,
I'm a newbie to ARM controllers. I've been trying to interface a FRAM( fm25cl64).
I'm trying to write some data to the memory and read back the same data. But so far I'm not receiving any data. The data buffer always shows 0xff after the read operation.
. Pls help



int main(void) {
    unsigned int data[]={2,0,0,100};
    unsigned int dataread[11],readcmd[10]={5,0,0};
    unsigned int dummy,i,stat;
    LPC_PINCON->PINSEL0=(3<<30);

    LPC_PINCON->PINSEL1=60;
    LPC_PINCON->PINMODE0=(1<<31);
    LPC_PINCON->PINMODE1=42;

    LPC_SPI->SPCR=0x820;
    LPC_SPI->SPCCR=88;
    LPC_GPIO0->FIODIR= (1<<16);
    LPC_GPIO0->FIOSET = (1<<16);
    for(i=0;i<100;i++);


    LPC_GPIO0->FIOCLR= (1<<16);
    LPC_SPI->SPDR=6; //to send write enable
    LPC_GPIO0->FIOSET = (1<<16);
    for(i=0;i<100;i++);

    LPC_GPIO0->FIOCLR= (1<<16);
    for(i=0;i<100;i++);
    {
        LPC_SPI->SPDR=data;
        stat=LPC_SPI->SPSR ;
        dummy= stat & 128;            //writing data to the memory. 2 is the write to memory command
                                      //followed by 2-byte address
        while((dummy )!= 128)
        {
            stat=LPC_SPI->SPSR ;
            dummy= stat & 128;

        }
        dummy=LPC_SPI->SPDR;

    }
    LPC_GPIO0->FIOSET = (1<<16);
    for(i=0;i<100;i++);
    LPC_GPIO0->FIOCLR= (1<<16);

    for(i=0;i<5;i++)
        {
        LPC_SPI->SPDR=readcmd;
        stat=LPC_SPI->SPSR ;
        while((stat & 128 )!= 128)       //read from memory
            stat=LPC_SPI->SPSR ;         //5 is the read from memory followed by 2-byte address
        dataread=LPC_SPI->SPDR;

        }
    LPC_GPIO0->FIOSET = (1<<16);

    return 0 ;
}
0 Kudos
5 Replies

530 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rahulvasist on Sat Aug 20 05:03:45 MST 2011
Hi,
   I wrote a different code and used a different memory(this time I used FM25V10). But even now I´ve the same problem. Every time I read(both the memory and the status register) I only receive 0xff. I connected MOSI to MISO(of the micro controller), then it shows the correct data. I´ve attached the code.
0 Kudos

530 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rahulvasist on Sun Aug 14 05:31:43 MST 2011
ok. I'l do the things u've suggested and get back to you.

About the write enable op-code, I'm sending that op-code before the write command. It is in the beginning of the code itself.
0 Kudos

530 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Sat Aug 13 23:49:55 MST 2011
Check your signals with a logic analyzer.

Also check the data sheet.

I quote from the data sheet:

Quote:
WREN - Set Write Enable Latch
The FM25CL64 will [B][COLOR=Red]power up with writes disabled[/COLOR][/B].
The WREN command must be issued prior to any
write operation. Sending the WREN op-code will
allow the user to issue subsequent op-codes for write
operations. [B][COLOR=Red]These include writing[/COLOR][/B] the Status Register
(WRSR) and writing [B][COLOR=Red]the memory[/COLOR][/B] (WRITE).

And the read command is 3 not 5 (5 is read status register).

I also suggest to make your code more readable.
As an example I take a few lines in the beginning of your code:
LPC_PINCON->PINSEL1=60;
LPC_PINCON->PINMODE0=(1<<31);
LPC_PINCON->PINMODE1=42;
I prefer:
LPC_PINCON->PINSEL1  = 0b111100; // P0.18 = MOSI, P0.17 = MISO, P0.16 = GPIO
LPC_PINCON->PINMODE0 = 2<<30;    // P0.15 has neither pull-up nor pull-down
LPC_PINCON->PINMODE1 = 0b101010; // P0.18..16 have neither pull-up nor pull-down
This makes your code much more readable and using binary or hex values instead of decimal removes one possible cause of errors and makes your code easier to review.
Using 2<<30 instead of 1<<31 makes more sense (to me) when setting a group of 2 bits to 2 - especially when the user manual states that writing 2 to bits 31..30 has a certain meaning.
Although this all does not change a thing in the executable code, it makes it more readable and less sensitive to typing/review errors.

But definitely check your signals with a logic analyzer - there is some problem with your SPI that I am missing right now. The read status register should never return 0xff.

Regards,[INDENT]Rob
[/INDENT]
0 Kudos

530 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rahulvasist on Fri Aug 12 07:04:47 MST 2011
thanks for replying
1. I'm using lpc1769
2. For the chip select i've used port 0 pin 16. I use it as a normal GPIO pin to do the chip select function.
3. About the for loop, I was just trying different things and I guess I've posted the wrong code
4. As the pins are being driven by the memory on one side and the microcontroller on the other, I thought it would be best to have no pull-ups.
5. Write protect is left floating. It says in the datasheet of the FRAM that this can be done.
0 Kudos

530 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Fri Aug 12 03:12:19 MST 2011
A few things.

You do not tell us which chip you are using? I'm guessing it is an lpc17xx.
Also your code is a bit unreadable, next time please wrap your code with the [ CODE ] tags to keep the formatting.

You specify all SPI pins as having no pull up or pull down, are you sure you want this? Do you have external pull ups on the pins?

Are you sure the signals towards the FRAM are good?
You should measure with a scope to see if the signals are OK and if the timing is correct.

In your code there is a for() loop that runs all the way up to 100 but the data[] array does not contain this many items.

What are your connections? Chip Select, Write Protect ?
Did I miss the chip select handling in your code?

All questions ...

Regards,

Rob
0 Kudos