cancel
Showing results for 
Search instead for 
Did you mean: 

SPI read problem

Posted on July 28, 2015 at 13:20

Hi everybody,

I'm trying to develop a function to read all the content of my E2PROM, I can read one value without a problem but at the second read, I'm blocked at the waiting of the flag RXNE, I don't understand.. Can you help me? Thank you

void spi2_conf()
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
/* Enable SPI clock, SPI1 */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
/* SPI SCK, MOSI, MISO pin configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15 | GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_1; // 10 MHz
GPIO_Init(GPIOB, &GPIO_InitStructure);
// Configure CS pin as output floating
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_0); // SPI1 SCK
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_0); // SPI1 MOSI
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_0); // SPI1 MISO
/* SPI configuration -------------------------------------------------------*/
SPI_I2S_DeInit(SPI2);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Hard; //modif test
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_RxFIFOThresholdConfig(SPI2,SPI_RxFIFOThreshold_HF);
SPI_Init(SPI2, &SPI_InitStructure);
SPI_SSOutputCmd(SPI2, ENABLE);
SPI_Cmd(SPI2, ENABLE);
}
uint8_t SPI2_SendByte(uint x)
{
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); // TX Empty (Front Test)
SPI_SendData8(SPI2, x);
SPI_I2S_ClearFlag(SPI2, SPI_I2S_FLAG_RXNE);
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET); // Wait for data to shift out
return(SPI_ReceiveData8(SPI2)); // Read to clear RXNE
}
uint8_t spi2_read(uint8_t adress)
{
uint8_t spi_rd_data_local=66;
set_CS2(0);
SPI2_SendByte(0b00000011); //code read
SPI2_SendByte(0b00000000);
SPI2_SendByte(adress);
// Send Dummy Byte for Clocks
spi_rd_data_local=SPI2_SendByte(0xFF);
spi_rd_data_local=SPI_ReceiveData8(SPI2);
//resultat lisible
//pour mettre fin a lecture, remettre CS à 1
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
set_CS2(1);
return (spi_rd_data_local);
}
void spi2_enable_write(void)
{
set_CS2(1);
set_CS2(0);
SPI2_SendByte(0b00000110); //code wren
set_CS2(1);
}
void spi2_power_on(void)
{
set_CS2(1);
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); // TX Empty (Front Test)
SPI_SendData8(SPI2, 0b00000100);// code reset write latch
set_CS2(0);
set_CS2(1);
}
main:
spi2_conf();
spi2_power_on();
spi2_enable_write();
while(1)
{
spi2_write(1,0xFF);
delay_ms(10);
spi2_write(2,0xFF);
delay_ms(10);
spi2_write(3,0xFF);
delay_ms(10);
testspi1=spi2_read(1);
delay_ms(10);
testspi2=spi2_read(2);
delay_ms(10);
testspi3=spi2_read(3);

5 REPLIES 5
Posted on July 28, 2015 at 15:27

I forgot de mention that I work on stm32f051r8

Posted on July 28, 2015 at 15:53

Just reading the SPI data register does *nothing*

You have to send the dummy byte to generate the clocks, the bus is symmetrical, as data clocks out, returned data is clocked in.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on July 28, 2015 at 16:03

I am sending the dumy byte!

Look:

// Send Dummy Byte for Clocks
spi_rd_data_local=SPI2_SendByte(0xFF);
spi_rd_data_local=SPI_ReceiveData8(SPI2);

or you are talking of another part of my code? >Thanks a lot
Posted on July 28, 2015 at 17:37

No you're not!

You're SPI2_SendByte() is already reading the returned data, so either use that data it returned, of if you want TWO bytes use it twice. So either

spi_rd_data_local=SPI2_SendByte(0xFF);

or

spi_rd_data_local=SPI2_SendByte(0xFF); // First byte coming back



 
spi_rd_data_local=SPI2_SendByte(0xFF); // Second byte coming back

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on July 29, 2015 at 11:43

Thank you clive for your perfect help as always!

but now I have another problem for the write function, just the first one works.. Can you save me another time?

uint8_t spi2_write(uint8_t addr, uint8_t value)
{
uint8_t valuer;
set_CS2(0);
SPI2_SendByte(0b00000010);// code write
SPI2_SendByte(0b00000000);
SPI2_SendByte(addr);
valuer=SPI2_SendByte(value);// on peut mettre plus qu'une seule valeur
set_CS2(1);
return valuer;
//protection des données apres ecriture envisageables
}