Question
STM32F103C8: Master full-duplex SPI problem
Posted on August 22, 2013 at 09:54
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; #stm32 #stm32 #stm32 #spi