cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 SPI vs STM32F4 spi

Evgeny Popov
Associate III

Im moving my project code from stmf407 to stm32h743 and i have stucked with spi. First of all stmh743 has many more registers and it also lack some of them like RXONLY register in CR1. What im trying to do its receive 19bytes from the master,the master is a complete device and i cant control it. The clock speed of the master is around 20nanoseconds. My previous project in stmf407 catching the data perfectly.

working STM32F407 spi code:

 

static void MX_SPI1_Init(void)
 {

SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_SLAVE;
hspi1.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
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.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(__FILE__, __LINE__);
  }
 }

static void ReadSpi(void)
    
{       
RxSPI1 = 0;
MX_SPI1_Init();
GPIOA->MODER = 0xAA809910;
SPI1->CR1 |= 0x40;  
RxCounter = 0;
    while(RxCounter <20){

 

    while (!(hspi1.Instance->SR  & SPI_FLAG_RXNE))

         ;
       
        RxSPI = hspi1.Instance->DR;
                
        
// now you have 8 SPI clock cycles to do something with the data
if (RxSPI != 0xFF )
{
    RxTable[RxCounter++] = RxSPI;  

}
}

      
return;
}

 

STM32H743 CODE:

 

static void ReadSpi(void)
    
{       
    

RxSPI1 = 0;
MX_SPI1_Init();
GPIOA->MODER = 0xAA809910;
SPI1->CR1 |= SPI_CFG2_SSM;
SPI1->CR1 |= SPI_CR1_SSI;
SPI1->CR1 |= SPI_CR1_SPE;
RxCounter = 0;
    while(RxCounter <20){

 

    while (!(hspi1.Instance->SR  & SPI_FLAG_RXP))

         ;

        RxSPI = hspi1.Instance->RXDR;
                
        
// now you have 8 SPI clock cycles to do something with the data
if (RxSPI != 0xFF )
{
    RxTable[RxCounter++] = RxSPI;  

}
}

     
return;
}


void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Supply configuration update enable
  */
  HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);

  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 1;
  RCC_OscInitStruct.PLL.PLLN = 24;
  RCC_OscInitStruct.PLL.PLLP = 2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  RCC_OscInitStruct.PLL.PLLR = 2;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
  RCC_OscInitStruct.PLL.PLLFRACN = 0;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                              |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV1;
  RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}
static void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_SLAVE;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
  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.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 0x0;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
  hspi1.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
  hspi1.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
  hspi1.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
  hspi1.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
  hspi1.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
  hspi1.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
  hspi1.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
  hspi1.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
  hspi1.Init.IOSwap = SPI_IO_SWAP_DISABLE;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
}

 

 What im catching:

Screenshot_2.png

 So i have a hard time to make spi of stm32h743 work as same as stm32f407's spi

line where we are waiting before catch the data in stm32f4 is  while (!(hspi1.Instance->SR & SPI_FLAG_RXNE))

and in stm32h743: while (!(hspi1.Instance->SR & SPI_FLAG_RXP)) the flag names are diffrent but i gues its ok. here is imahge of initialized registers of noth mcus in the debug mode.

STM32f407:

stm32f4 init.png

STM32H743:

after_init_STmh7.png

 as you can see stm32h7 has a lot if registers i didnt met before like FIFO and CSUPS etc... and lack of crucial registers as RXONLY.

f4 working fine, while h7 have around 4-6(rxcounter equls 4-6 and then it just hangs) interaction with:

    while(RxCounter <20){

 

    while (!(hspi1.Instance->SR  & SPI_FLAG_RXP))

         ;

        RxSPI = hspi1.Instance->RXDR;
                
        
// now you have 8 SPI clock cycles to do something with the data
if (RxSPI != 0xFF )
{
    RxTable[RxCounter++] = RxSPI;  

}
}

     
return;
}

I have tried a lot to make it work, seems like nothing working. I started to think that the problem with clock freq, can it be so?

here is clock configuration of STMH743:

h7 clock.png

here is clock configuration of STMf407:

stmf4 clock.png

 as you can see stmf4 has a higher clock, can it be the issue?

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions

so try H7 on higher core speed !

set divm1 to 8 and divn1 in PLL1 to...what you want, try 400 . -> 200Mhz core 

+ need to set RCC , see:

AScha3_0-1690444023924.png

 

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

10 REPLIES 10
RhSilicon
Lead

I have a project with F407 and I also thought about migrating to H743, but to solve USB Host issues. If you are using a baremetal code form, it may be interesting to generate the HAL code, and open the HAL functions to find out how registers are handled, most users will use HAL.

About the clock, where is the label "480 MHz Max" put the desired clock, try clicking on the "Resolve" button

STM32_Clock_Cfg.png

 

AScha.3
Chief III

you use a spi clock around 1 MHz - thats no problem with cpu clk.(i drive spi on H7 at 48M ! )

+

i used on F4 write to spi registers, to be fast.

on H7 i gave up on this, i didnt get it to work perfect. just using HAL calls, at 200MHz core speed its still faster than F4 with direct register access was. the spi on H7 is over complicated, in my opinion. use HAL and it works.

If you feel a post has answered your question, please click "Accept as Solution".

Thanks for yoir answe @AScha.3 i understand, but we cant see at what clock spi in f4 running, but it has 168Mhz compared to 96mhz of h7, so didnt it mean that spi clock of h7 lower aswell? Im afraid that slave spi not to fast to catch the master or maybe the problem isnt in clock at all, i really need help to solve this

 the whole spi code generated by cubemx, also my crystal on the board is 8mhz, so i cant choose higher.When i tried to configurated with 8mhz it seems like its almost impossilbe to make usb and spi higher that in the image. The funny thing is that on f4 i have 8mhz crystal as well and it somehow managed to run at 168mhz

so try H7 on higher core speed !

set divm1 to 8 and divn1 in PLL1 to...what you want, try 400 . -> 200Mhz core 

+ need to set RCC , see:

AScha3_0-1690444023924.png

 

If you feel a post has answered your question, please click "Accept as Solution".
TDK
Guru

> SPI1->CR1 |= SPI_CFG2_SSM;

What is this nonsense?

You need to do 8-bit reads in order to read one byte at a time. See how it's done in HAL and copy that.

*((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);

 

If you feel a post has answered your question, please click "Accept as Solution".

thank you for your response mate, and sorry for my delayed answer, I have configured d my clock with 400mhz:

new SPI.png

and trying to catch  data with HAL:

 for (int i=0; i<20; i++)
 {
	HAL_StatusTypeDef status = HAL_SPI_Receive(&hspi1, &RxTable[i], 1,HAL_MAX_DELAY);

 }

and it catches nothing. What can be else a problem?

sorry it was just stupid mistake with registers:

SPI1->CFG2 |= SPI_CFG2_SSM

I have tried the HAL code:

char RxTable[30];  
while(RxCounter <20){
    while (!(hspi1.Instance->SR  & SPI_FLAG_RXNE))

         ;
   RxTable[RxCounter++] = *((__IO uint8_t *)&hspi1.Instance->RXDR);
		

}

And it doesn't catch anything, what am i missing?

 

I don't know. What else did you change before (when it caught stuff) and now?

> h7 have around 4-6(rxcounter equls 4-6 and then it just hangs)

If you feel a post has answered your question, please click "Accept as Solution".