2014-03-31 03:37 PM
2014-03-31 03:48 PM
/**
* @brief Write a byte on the SD.
* @param Data: byte to send.
* @retval None
*/
uint8_t SD_WriteByte(uint8_t Data)
{
/*!< Wait until the transmit buffer is empty */
while(SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_TXE) == RESET)
{
}
/*!< Send the byte */
SPI_SendData8(SD_SPI, Data);
/*!< Wait to receive a byte*/
while(SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_RXNE) == RESET)
{
}
/*!< Return the byte read from the SPI bus */
return SPI_ReceiveData8(SD_SPI);
}
2014-03-31 04:11 PM
Clive,
Thanks for the post but I want to use the RXFIFO so I can just read the 3 bytes out without having to poll for each byte. -Henk2014-03-31 04:30 PM
Are you using the TX FIFO, and are you SURE that has evacuated completely across the wire before trying to read things that might have come back at you? Can you check that the RX FIFO has any content before trying to read back values? Have you confirmed you can talk to your device successfully using more conventional sequencing of the SPI bus?
/* Waiting until TX FIFO is empty */
while (SPI_GetTransmissionFIFOStatus(SPIx) != SPI_TransmissionFIFOStatus_Empty)
{}
/* Wait busy flag */
while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_BSY) == SET)
{}
2014-03-31 05:19 PM
I see my command 0x9F being sent out on the oscilloscope, but the code hangs at the last line waiting for a received byte.
SPI_Cmd(SPI1, ENABLE); // Wait until transmit buffer is empty while( !(SPI1->SR & 0x02) ); // Send the first byte SPI_SendData8(SPI1, 0x9F); // Wait to receive the first byte back. - hangs here. while( !(SPI1->SR & 0x01) );2014-03-31 07:04 PM
Below are the SPI1 register settings:
Here if I see 8 clock edges, and the data being sent out I should be seeing something received. Even if the data is all zero or FF's I shouldn't get stuck in this loop.2014-03-31 08:24 PM
More debugging:
If I keep the following line below uncommented after my dummy write the code hangs'' while( !(SPI1->SR & 0x01) ); '' If I comment that code out and if I do several reads back to back I see the correct data on the 5th read of the data register. There has to be a better way! received[0] = SPI1->DR; received[1] = SPI1->DR; received[2] = SPI1->DR; received[3] = SPI1->DR; SPI_Cmd(SPI1, ENABLE); SPI_SendData8(SPI1, 0x05); // Here is where I need to check to be sure that the read-> is empty. received[0] = SPI1->DR; // Reading back 0x00 but 0xFF on the scope. received[1] = SPI1->DR; // Reading back 0x00 but 0xFF on the scope. received[2] = SPI1->DR; // Reading back 0xFF but 0xFF on the scope. received[3] = SPI1->DR; // Reading back 0xFF but 0xFF on the scope. // Dummy data to read status register out SPI_SendData8(SPI1, 0xAA); // Wait until there is data in the receiver buffer and continue. while( !(SPI1->SR & 0x01) ); // hangs here if uncommented! received[4] = SPI1->DR; // Reading back 0xFF but 0x02 on the scope. received[5] = SPI1->DR; // Reading back 0xFF but 0x02 on the scope. received[6] = SPI1->DR; // Reading back 0x02 but 0x02 on the scope. received[7] = SPI1->DR; // Reading back 0x02 but 0x02 on the scope. received[8] = SPI1->DR; // I see the correct data here.2014-03-31 08:43 PM
There has to be a better way!
Presumably by qualifying that the FIFO has content? The FIFO provides some level of elastisity, in that you can blow all the way through the code before anything actually happens on the bus. I'm not using F0 parts.while(SPI_GetReceptionFIFOStatus(SPI1) != SPI_ReceptionFIFOStatus_Empty) // Flush
received[0] = SPI1->DR;
// ...
while(SPI_GetTransmissionFIFOStatus(SPI1) != SPI_TransmissionFIFOStatus_Empty); // Spin for outbound completion
// ...
while(SPI_GetReceptionFIFOStatus(SPI1) == SPI_ReceptionFIFOStatus_Empty); // Spin if Nothing There
received[i++] = SPI1->DR;
while(SPI_GetReceptionFIFOStatus(SPI1) == SPI_ReceptionFIFOStatus_Empty); // Spin if Nothing There
received[i++] = SPI1->DR;
2014-04-01 01:26 AM
Mike,
I'am sorry for only making assumptions here, I hope it will help anyway. There are two things you may consider: 1) accessing SPI1->DR to copy into a byte array is a bad idea because, DR is 16-bit wide while byte is ... 8-bit wide. Normally it does not hurt, but on STM32F0 (clive1 suggested you are using such a device) there is a packing data engine: reading 16-bit from DR, is (more or less) equivalent to two 8-bit reads. If the RXFIFO contains more than one byte, you loose the MSB ... this might explain the 'scrambling' of data you observed. 2) SPI->SR bit RXNE may not be set for a single byte reception. This is because of the RXFIFO that can be coupled with DMA. See the definition of the bit FRXTH or CR2 register. It must be set if you want RXNE to be set as soon as a single byte is received.2014-04-01 10:21 AM
and
the threshold (defined by FRXTH bit) is reached. -Mike