2025-01-28 07:43 PM
I have a read-only SPI master. Here’s the code:
SpiHandle.Init.Mode = SPI_MODE_MASTER;
SpiHandle.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
SpiHandle.Init.DataSize = SPI_DATASIZE_16BIT;
SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;
SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE;
SpiHandle.Init.NSS = SPI_NSS_HARD_OUTPUT;
SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
SpiHandle.Init.TIMode = SPI_TIMODE_DISABLE;
SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
SpiHandle.Init.CRCPolynomial = 7;
SpiHandle.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
SpiHandle.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
SpiHandle.Init.Mode = SPI_MODE_MASTER;
/**SPI1 GPIO Configuration
PA1 ------> SPI1_SCK
PA4 ------> SPI1_NSS
PA6 ------> SPI1_MISO
*/
GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
while (1) {
HAL_SPI_Receive(&SpiHandle, (uint8_t *)&angle, 1, 100);
}
Here’s the clock and (a very noisy) NSS:
Why are there two 16-bit words per transaction? Does a HAL_SPI_Receive send a word and then receive a word?
2025-01-28 09:21 PM
The receive-only master SPI sends clocks continuously until the peripheral is turned off. Code takes some time between getting the 1 byte you requested and turning off the peripheral.
So it reads the first word which it returns, but then continues to receive another word which is ignored.
For this reason, receive-only master should generally be avoided. Using it in full duplex mode and leaving the MOSI pin uninitialized will provide the same functionality.