STM32H750VB SPI Slave MISO last bit returns low to early
- May 8, 2020
- 3 replies
- 1232 views
Hi there,
I am using the STM32H750VB as an SPI Slave in Interrupt mode and it is working but I am not happy with what I see with my analyzer.
SPI is working with Idle-Clock Low and aquiring data at leading edge. LSB first.
That's all how it should be but when you take a closer look at the last bit you see, that MISO is returning to zero just after the rising edge. In my opinion this should happen when the last clock is completed, e.g. falling edge of the clock.
Is there any way to delay this, as my SPI Master decodes the last byte sometimes as 123(0x7B) instead of 251(0xFB) as it reads the level of the MISO "too late".
The spi is working with a clock frequency of 50khz.
Thanks
Best regards,
Thomas
Below my init:
void MX_SPI2_Init(void)
{
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_SLAVE;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_HARD_INPUT;
hspi2.Init.FirstBit = SPI_FIRSTBIT_LSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 0x0;
hspi2.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
hspi2.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
hspi2.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
hspi2.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
hspi2.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
hspi2.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
hspi2.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
hspi2.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
hspi2.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
hspi2.Init.IOSwap = SPI_IO_SWAP_DISABLE;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
Error_Handler();
}
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{
GPIO_TypeDef * pAkt_GPIO;
// Port-Pins konfigurieren
pAkt_GPIO = GPIOB;
if(spiHandle->Instance==SPI2)
{
/* USER CODE BEGIN SPI2_MspInit 0 */
/* USER CODE END SPI2_MspInit 0 */
/* SPI2 clock enable */
__HAL_RCC_SPI2_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**SPI2 GPIO Configuration
PC1 ------> SPI2_MOSI
PC2_C ------> SPI2_MISO
PB12 ------> SPI2_NSS
PB13 ------> SPI2_SCK
*/
// Chipselect auf PB12
pAkt_GPIO->MODER &= ~GPIO_MODER_MODE12;
pAkt_GPIO->MODER |= GPIO_MODER_MODE12_1; // Alternate function for SPI Chip-Select
pAkt_GPIO->OSPEEDR |= GPIO_OSPEEDR_OSPEED12; // High Speed on
pAkt_GPIO->AFR[1] |= (uint32_t)GPIO_AF5_SPI2 << 16; // AFRH ==> AF5
// Clock auf PB13
pAkt_GPIO->MODER &= ~GPIO_MODER_MODE13;
pAkt_GPIO->MODER |= GPIO_MODER_MODE13_1; // Alternate function for SPI SCK
pAkt_GPIO->OSPEEDR |= GPIO_OSPEEDR_OSPEED13; // High Speed on
pAkt_GPIO->AFR[1] |= (uint32_t)GPIO_AF5_SPI2 << 20; // AFRH ==> AF5
pAkt_GPIO = GPIOC;
// MOSI auf PC1
pAkt_GPIO->MODER &= ~GPIO_MODER_MODE1;
pAkt_GPIO->MODER |= GPIO_MODER_MODE1_1; // Alternate function for SPI MOSI
pAkt_GPIO->OSPEEDR |= GPIO_OSPEEDR_OSPEED1; // High Speed on
pAkt_GPIO->AFR[0] |= (uint32_t)GPIO_AF5_SPI2 << 4; // AFRL ==> AF5
// MISO auf PC2
pAkt_GPIO->MODER &= ~GPIO_MODER_MODE2;
pAkt_GPIO->MODER |= GPIO_MODER_MODE2_1; // Alternate function for SPI MISO
pAkt_GPIO->OSPEEDR |= GPIO_OSPEEDR_OSPEED2; // High Speed on
pAkt_GPIO->AFR[0] |= (uint32_t)GPIO_AF5_SPI2 << 8; // AFRL ==> AF5