2023-10-22 02:23 PM - edited 2023-10-22 02:34 PM
int main()
{
uint8_t Read_Out_X_Y_Z_REG_Address=0xA8;
uint8_t Out_X_Y_Z_Data_Separate[6]={0};
int16_t Out_X_Y_Z_Data_RESULT[3]={0};
SPI1->CR1 |= SPI_CR1_SPE;
uint8_t address=0x8F; //Register address+read
uint8_t result;
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET); //Chip Select
while(!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = address;
while(!(SPI1->SR & SPI_SR_TXE));
while((SPI1->SR & SPI_SR_BSY) != RESET);
while((SPI1->SR & SPI_SR_RXNE));
result=SPI1->DR; //STARTING HERE I COMMENT THE CODE FOR THE EXPERIMENT.
while((SPI1->SR & SPI_SR_RXNE));
while((SPI1->SR & SPI_SR_BSY) != RESET);
while(!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = 0;
while(!(SPI1->SR & SPI_SR_TXE));
while((SPI1->SR & SPI_SR_BSY) != RESET);
while((SPI1->SR & SPI_SR_RXNE));
result=SPI1->DR;
while((SPI1->SR & SPI_SR_RXNE));
while((SPI1->SR & SPI_SR_BSY) != RESET);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET); //Chip Select
}
uint8_t result;
result=SPI1->DR;
result=SPI1->DR;
SPI1->CR1 |= SPI_CR1_SPE;
uint8_t address=0x8F; //Register address+read
uint8_t result;
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET); //Chip Select
while(!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = address;
while(!(SPI1->SR & SPI_SR_TXE));
while((SPI1->SR & SPI_SR_BSY) != RESET);
while((SPI1->SR & SPI_SR_RXNE));
//result=SPI1->DR; //DEACTIVATED
while((SPI1->SR & SPI_SR_RXNE));
result=SPI1->DR;
while((SPI1->SR & SPI_SR_BSY) != RESET);
Solved! Go to Solution.
2023-10-22 06:54 PM - edited 2023-10-22 06:56 PM
> But the RX buffer and SPI1->DR are not the same thing.
Maybe at some technical standpoint they are not the same since SPI->DR is a hardware interface, but for the purposes of reading data, they are effectively the same.
When RXNE is asserted, there is data in the RX buffer. The RX buffer is read by reading SPI->DR, which clears RXNE. There is no intermediate step or race condition here.
Not seeing any contradictions in the RM.
In the last figure, at the green arrow, RXNE transitions from 1 to 0 when the 0xA1 value is read from SPI->DR. RXNE goes back to 1 when the next data (0xA2) is available to be read.
2023-10-22 04:52 PM - edited 2023-10-22 04:54 PM
Reading SPI->DR does in fact clear RXNE just as the RM says. Note that reading it from your debugger still counts as reading it, which is likely why you saw it was cleared despite not reading it in code.
The RM has explicit step by step instructions for operation SPI in register mode. I'd recommend following those.
Note that you can queue 2 bytes to be sent before the first byte is received.
> It's hard for me to imagine that the SPI_DR register keeps track of when SPI_DR will be read.
You should think of SPI->DR as a hardware interface, not just a register in memory. The SPI peripheral has an internal state machine that respond to reads and writes to this interface appropriately. That's why reads always show incoming data and writes always send data out.
2023-10-22 05:21 PM - edited 2023-10-22 05:25 PM
While the RX buffer is full, the SPI_SR_RXNE bit is 1.
The instruction in the image above suggests reading data from the SPI1->DR register while the RX buffer is full.
But the RX buffer and SPI1->DR are not the same thing.
Let's say a situation occurs when the RX buffer is full, I read the SPI1->DR data, but the data from the RX buffer has not yet reached the SPI1->DR register.
It seems strange to me that there is no indicator indicating that data has reached the SPI1->DR register from the RX buffer.
2023-10-22 05:45 PM - edited 2023-10-22 06:23 PM
With the TX buffer everything happens logically.
I need to wait until the TX buffer is empty and after that I need to fill the SPI_DR register.
Therefore the description is suitable: write SPI_DR.
But with the RX buffer, I don’t see the logic, as I described above.
The RX buffer is full, but for some reason it is necessary to read SPI_DR, although the data is not in the SPI_DR register, but in the RX buffer.
2023-10-22 06:47 PM - edited 2023-10-22 06:50 PM
---
2023-10-22 06:54 PM - edited 2023-10-22 06:56 PM
> But the RX buffer and SPI1->DR are not the same thing.
Maybe at some technical standpoint they are not the same since SPI->DR is a hardware interface, but for the purposes of reading data, they are effectively the same.
When RXNE is asserted, there is data in the RX buffer. The RX buffer is read by reading SPI->DR, which clears RXNE. There is no intermediate step or race condition here.
Not seeing any contradictions in the RM.
In the last figure, at the green arrow, RXNE transitions from 1 to 0 when the 0xA1 value is read from SPI->DR. RXNE goes back to 1 when the next data (0xA2) is available to be read.
2023-10-22 07:09 PM - edited 2023-10-22 07:29 PM
My last drawing was wrong, I deleted it)
>but for the purposes of reading data, they are effectively the same.
Ok, are SPI_DR and RX buffer the same thing if the purpose is reading?
Maybe you know where I can read this from official sources?
I can’t understand why SPI_DR and RX buffer are the same thing if they are physically located in different parts of the microcontroller.
The image shows that RX buffer and RX Data are different parts of the Microcontroller even for reading.
Transferring data from different parts of the Microcontroller takes a certain time.
The RX buffer is full, but we are reading RX Data Register, I don’t understand.
2023-10-22 09:02 PM
Again, think of SPI->DR as an interface, not a memory location. It's not a memory location. Nothing is stored there. When the CPU gets a write to SPI->DR instruction, it puts that data into the TX buffer. When it gets a read instruction, it gets data from the RX buffer.