AnsweredAssumed Answered

STM32F103C8: Master full-duplex SPI problem

Question asked by antuna.juan on Aug 22, 2013
Latest reply on Aug 22, 2013 by John F.
Hi all,

I am using a STM32F103C8 as a master in a SPI communication to an external ADS.

My project has other interrupt sources, so I am not using additional interrupts for this SPI communication.The communication does both tx and rx, and for that I have followed the protocol specified in the MCU datasheet. 

The problem is that the program often gets stuck in the last part of the communication, when the last two data bytes have to be received. When the RXNE flag should be set for second time (because the last data should be entering the serial register), it is not set so the program keeps waiting for it.

At first I thought it could be possible that if an interupt arrives in the middle of the receiving of the last two data bytes the communication might be disrupted, so I framed the last two waits for RXNE between __disable_irq() and __enable_irq(), but that did not solve the problem. For now I will implement it with software timeouts and retries, but it is a workaround, I would like to know the real cause.

Can anyone point out some ideas?? Below you can find the code snippet for the communication.


Kind regards,
Juan Antuna


    //First select the slave
    GPIOB->BRR = 0x00001000;
    //Wait until the SPI bus is free
    while(((SPI2->SR & SPI_I2S_FLAG_TXE) == (u16)RESET));
    //Write the first command
    SPI2->DR = RDATA_COMMAND;
    //Wait until the SPI bus is free
    while(((SPI2->SR & SPI_I2S_FLAG_TXE) == (u16)RESET));
    //Write the second command: 
    SPI2->DR = NOP_COMMAND;
    //Wait until RXNE is set (data received)
    while(((SPI2->SR & SPI_I2S_FLAG_RXNE) == (u16)RESET));
    //Read the first response
    temp = SPI2->DR;
    //Wait until the SPI bus is free
    while(((SPI2->SR & SPI_I2S_FLAG_TXE) == (u16)RESET));
    //Write the third command:
    SPI2->DR = NOP_COMMAND;
    //Wait until RXNE is set (data received)
    while(((SPI2->SR & SPI_I2S_FLAG_RXNE) == (u16)RESET));
    //Read the second response
    data1 = (u8)(SPI2->DR);
    //Wait until the SPI bus is free
    while(((SPI2->SR & SPI_I2S_FLAG_TXE) == (u16)RESET));
    //Write the third command:    
    SPI2->DR = NOP_COMMAND;
    //Wait until RXNE is set (data received)
    while(((SPI2->SR & SPI_I2S_FLAG_RXNE) == (u16)RESET));
    //Read the third response
    data2 = (u8)(SPI2->DR);
    //Wait until RXNE is set (last data received)
    while(((SPI2->SR & SPI_I2S_FLAG_RXNE) == (u16)RESET));
    //Read the last response
    data3 = (u8)(SPI2->DR);
    //Wait until the SPI bus is free
    while(((SPI2->SR & SPI_I2S_FLAG_TXE) == (u16)RESET));
    //Wait until BSY flag is 0
    while(((SPI1->SR & SPI_I2S_FLAG_BSY) != (u16)RESET));
    //Deselect the slave
    GPIOB->BSRR = 0x00001000;


Outcomes