cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H750VB SPI Slave MISO last bit returns low to early

TAlbr
Associate

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 

3 REPLIES 3

Do you use DMA to fill the SPI Tx? If you change the next byte's LSB to 1, will you still see the problem?

Can you please read out and post the SPI registers' content?

JW

TAlbr
Associate

No I don't use DMA to fill the output buffer.

I use

HAL_SPI_TransmitReceive_IT(&hspi2,(uint8_t *)aTxBuffer , (uint8_t *)aRxBuffer, BUFFERSIZE);

to fill the output register.

The master always clocks out two bytes at once. If the next LSB is 1 I still see the problem. (Screenshot attached)

When do you want me to read out the SPI registers' content? Init, when Interrupt ist called or after "HAL_SPI_TransmitReceive_IT"

Thank you very much

Regards,

Thomas

> [when output buffer is filled]

Can you please toggle a pin *before* and *after* calling HAL_SPI_TransmitReceive_IT() and add it to the LA?

> When do you want me to read out the SPI registers' content? Init, when Interrupt ist called or after "HAL_SPI_TransmitReceive_IT"

Any of these (say when interrupt is called), just tell us when whas it.

I just wanted to know how did you set up the SPI. I don't understand the Cube/HAL gibberish.

JW