2020-11-15 01:13 AM
I encountered this problem when I attempted to send a one byte command using HAL_SPI_Transmit(..), and then trying to read 2 byte response from Miso, using HAL_SPI_Receive(..)
My test code is plain as follows, no intterupts, nothing connected to SPI port.
/* USER CODE BEGIN 2 */
uint8_t data = 0xd0;
uint8_t received[16];
HAL_GPIO_WritePin(TP_CS_GPIO_Port, TP_CS_Pin, GPIO_PIN_SET); // unselect slave
HAL_Delay(10);
while (1) {
HAL_GPIO_WritePin(TP_CS_GPIO_Port, TP_CS_Pin, GPIO_PIN_RESET); // select slave
while (HAL_SPI_Transmit(&hspi1, &data, 1, 100) != HAL_OK); // Transmit 1 byte command
while (HAL_SPI_Receive(&hspi1, received, 16, 100) != HAL_OK); // Receive 16 bytes
HAL_GPIO_WritePin(TP_CS_GPIO_Port, TP_CS_Pin, GPIO_PIN_SET); // unselect slave
__NOP();
}
/* USER CODE END 2 */
Trace on logic analyser is as seen on attached image, only the first byte 0xd0 on MOSI is transmitted by my code, following bytes are parasitics :
SPI configuration is as follows :
static void MX_SPI1_Init(void)
{
/* USER CODE BEGIN SPI1_Init 0 */
/* USER CODE END SPI1_Init 0 */
/* USER CODE BEGIN SPI1_Init 1 */
/* USER CODE END SPI1_Init 1 */
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
My computer is Mac Pro Catalina, I am using STM32 cubeIDE 1.4.2
Any comments ?
Edit : A further diagnosis has shown that, these parasitic transmission of bytes happen in the first 12 read cycles (1 byte each) after reset. Then on subsequent transmit/receive sequences, no more byte transmissions happen, only first one that I transmitted is emitted on MOSI. If there is residual data on Tx Buffer, does that cause this? If so, how to flush tx Buffer?
BR
Best regards
2020-11-15 07:38 AM
MOSI has to have a signal on it, that's how SPI works. If you care about what that signal is, for instance if you want it to be all 0x00 bytes, you can do HAL_SPI_TransmitReceive instead of just HAL_SPI_Receive. In the current implementation, in two line master mode, HAL_SPI_Receive will transmit the current content of your receive buffer. Zeroing your receive buffer will have it transmit zeroes.
2020-11-15 11:01 AM
Thanks a lot TDK. That means I have to study SPI Protocol once more. I have been using it to drive my TFT displays and SD cards without hitting this issue since years. I want to learn how I could survive so far. :grinning_face:
2020-11-15 01:08 PM
Typically in an SPI transaction, there are parts where MOSI is ignored and other parts where MISO is ignored. That is probably the case here, so it doesn't matter that the buffer isn't zeroed. That information would be in the datasheet of whatever device you're interfacing with.