cancel
Showing results for 
Search instead for 
Did you mean: 

Communicating with an EEPROM over SPI

dave4
Associate II
Posted on January 15, 2010 at 09:02

Communicating with an EEPROM over SPI

12 REPLIES 12
dave4
Associate II
Posted on May 17, 2011 at 13:37

Hello,

I am trying to communicate with an ST M95160 EEPROM device using an STM32F101R8T6, and while I can send instructions and data to the device, I cannot get the EEPROM to reply to my commands

Here is my configuration for the SPI peripheral

Code:

void SPI_Configuration(void)

{

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // Configure as Full Duplex

SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // Configure as SPI Master

SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // Use 8bit data frames

SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;

SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;

SPI_InitStructure.SPI_NSS = SPI_NSS_Hard; // Use hardware slave select control

SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; // Set data rate APB/2 = (8MHz/2 = 4MHz)

SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // Send / receive data MSB first

SPI_InitStructure.SPI_CRCPolynomial = 7;

SPI_Init(SPI1, &SPI_InitStructure); // Configure SPI1

SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE); // Enable Rx not empty interrupt

SPI_SSOutputCmd(SPI1, ENABLE); // Enable slave select output

SPI_Cmd(SPI1, ENABLE); // Enable SPI1

}

and this is what I am sending (the commands are mapped with some #defines)

Code:

GPIO_ResetBits(GPIOA, GPIO_Pin_4);

SPI_I2S_SendData(SPI1, EEPROM_WRITE_EN);

SPI_I2S_SendData(SPI1, EEPROM_WRITE);

SPI_I2S_SendData(SPI1, 0xFF);

SPI_I2S_SendData(SPI1, 0xCC);

SPI_I2S_SendData(SPI1, EEPROM_WRITE_DIS);

SPI_I2S_SendData(SPI1, EEPROM_WRITE_EN);

SPI_I2S_SendData(SPI1, EEPROM_WRITE);

SPI_I2S_SendData(SPI1, EEPROM_READ);

SPI_I2S_SendData(SPI1, 0xFF);

SPI_I2S_SendData(SPI1, EEPROM_WRITE_DIS);

GPIO_SetBits(GPIOA, GPIO_Pin_4);

I have noticed that the RXNE interrupt fires during the sendData commands, where I have a routine to fill a buffer with what is received

I have attached a scope trace showing what I am seeing (green = NSS, purple = SCK, blue = MOSI pin, yellow = MISO pin)

I think that I should be seeing data coming back on the MISO line, why would that not be the case?

Regards

Dave

chikos33
Associate II
Posted on May 17, 2011 at 13:37

Hi Dave,

It semms strange to me: why do you set NSS output function if you are handling the NSS by software? (GPIO_ResetBits(GPIOA, GPIO_Pin_4);) I suggest you either remove the NSS SPI_SSOutputCmd or the GPIO management (It would be safer to start with NSS managed by software).

Are you sure you configured correctly the SPI MISO pin PA6 (Alternate function Push Pull or Input floating)?

This EEPROM supports (CPOL = 0, CPHA = 0) and (CPOL = 1, CPHA = 1) so may be you can try the second configuartion.

Note: RxNE interrupt will be generated in all cases (even when no data are received on the MISO line) because it is only relative to the clock signal.

Now, as I've seen in the EEPROM datasheet, that the read sequence seems a little different from yours, they state:

// Enable Chip select

SPI_I2S_SendData(SPI1, EEPROM_READ); // send data read instruction

SPI_I2S_SendData(SPI1, EEPROM_Address1); // send the MSB of the address

SPI_I2S_SendData(SPI1, EEPROM_Address2); // send the LSB of the address

SPI_I2S_SendData(SPI1, 0xff); // send dummy data

while (!SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE)); // Wait for data to be received

buffer[n] = SPI_I2S_ReceiveData(SPI1); // Or you can do it through interrupt of course.

SPI_I2S_SendData(SPI1, 0xff); // Send dummy data

while (!SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE)); // Wait for data to be received

buffer[n + 1] = SPI_I2S_ReceiveData(SPI1); // ....

......

And you continue sending dummy data and receiving data from EEPROM till the end of buffer

That's what I understood from the datasheet, please tell me if I'm wrong?

Thanks and Good luck!

jj
Associate II
Posted on May 17, 2011 at 13:37

There is a similar ''failed MISO'' post just a few posts down. Indeed the SPI-NSS signal is most always ''prime suspect.''

My past recommendation (which worked) was to temporarily ''break'' the connection between STM's NSS and CS of eeprom. Again temporarily tie the CS of eeprom to ground - see if then MISO behaves per expectation...

dave4
Associate II
Posted on May 17, 2011 at 13:37

Hi,

>why do you set NSS output function if you are handling the NSS by >software?

I tried using the software configuration, but found that the line is not reset to 1 after the command block, even though I send

SPI_NSSInternalSoftwareConfig(SPI1, SPI_NSSInternalSoft_Set);

to reset it (or I am using this command incorrectly)

>This EEPROM supports (CPOL = 0, CPHA = 0) and (CPOL = 1, CPHA = 1) so may >be you can try the second configuartion.

Is CPOL=0,CPHA=0 the equivalent of SPI_CPOL_Low and SPI_CPHA_2Edge ?

What is the purpose of sending dummy data at every stage of reading the memory ? Is this just for testing, or will I have to do this in my final application ?

Also, you say that I can do the receiving through an interrupt, how would I stop it going to the interrupt routine on every clock cycle and just when I want to receive data which is actually in the buffer ?

--dave

chikos33
Associate II
Posted on May 17, 2011 at 13:37

Hi dave,

- In this case, remove the SPI_SSOutputCmd and NSS hardware management feature and use only the GPIO set/reset to have a clean code.

- CPOL=0,CPHA=0 is the equivalent of SPI_CPOL_Low and SPI_CPHA_1Edge

CPOL=1,CPHA=1 is the equivalent of SPI_CPOL_High and SPI_CPHA_2Edge

- As jj.sprague said, it is often a NSS issue, so check you are setting the levels at the right time (I think NSS should rise again just after the write command is finished ? ....).

- You have to send dummy data for each read operation because the SPI clock is generated only when data are sent through MOSI (I'm talking about 2linesFullDuplex mode only here). So after sending the address (on two bytes) you have to keep sending dummy data in order to generate clock and allow slave to send you data back on MISO line.

- At first time, try to use only polling mode to verify that EEPROM is ''alive'' and responds correctly to your commands.

Then, if you want to use RxNE interrupt, you will need for exampel to enable/disable the interrupt each time. You also can use a token (a global variable taking either 0 or 1 value to indicate if the data received on MISO is valid data or dummy) ... anyway, it should be managed by software.

I hope it helps a little 🙂

Regards.

dave4
Associate II
Posted on May 17, 2011 at 13:37

Hi,

Thanks for the information, I can now poll the EEPROM with read_status and get sensible responses back.

However, when I moved on to reading some real data using the following code

Code:

GPIO_SetBits(GPIOA, GPIO_Pin_4);

GPIO_ResetBits(GPIOA, GPIO_Pin_4);

SPI_I2S_SendData(SPI1, EEPROM_WRITE_EN);

SPI_I2S_SendData(SPI1, EEPROM_WRITE);

SPI_I2S_SendData(SPI1, 0x00);

SPI_I2S_SendData(SPI1, 0xFE);

SPI_I2S_SendData(SPI1, 0xCC);

SPI_I2S_SendData(SPI1, EEPROM_WRITE_DIS);

GPIO_SetBits(GPIOA, GPIO_Pin_4);

GPIO_ResetBits(GPIOA, GPIO_Pin_4);

//SPI_I2S_SendData(SPI1, EEPROM_WRITE_EN);

//SPI_I2S_SendData(SPI1, EEPROM_WRITE);

SPI_I2S_SendData(SPI1, EEPROM_READ);

SPI_I2S_SendData(SPI1, 0x00);

SPI_I2S_SendData(SPI1, 0xFE);

SPI_I2S_SendData(SPI1, 0xFF);

while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != SET);

EEPROM_buffer[EE_idx] = SPI_I2S_ReceiveData(SPI1);

SPI_I2S_SendData(SPI1, 0xFF);

EE_idx++;

while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != SET);

EEPROM_buffer[EE_idx] = SPI_I2S_ReceiveData(SPI1);

SPI_I2S_SendData(SPI1, 0xFF);

EE_idx++;

GPIO_SetBits(GPIOA, GPIO_Pin_4);

I get the clocks generated, but the receive line is a constant high, and the value 0xFF is written into my buffer instead of 0xCC which I was expecting. This is shown in the attached scope trace (yellow = MISO).

Thanks

Dave

dave4
Associate II
Posted on May 17, 2011 at 13:37

Update - FIXED

Thanks to chikos33 for all your help, I appreciate it.

Regards

Dave 🙂

dave4
Associate II
Posted on May 17, 2011 at 13:37

Update - FIXED

Thanks to chikos33 for all your help, I appreciate it.

Regards

Dave 🙂

chikos33
Associate II
Posted on May 17, 2011 at 13:37

All the pleasure is for me, Dave :p

I wish you even better luck for the remaining application parts.