2024-02-14 04:20 AM
Using the STM32H747I-DISCO, I am having problems getting SPI working at all.
I am using SPI5, to allow connecting an X-NUCLEO-NFC08A1 directly via the Arduino headers.
I do not see any data on the SCK line and HAL_SPI_Transmit() always fails.
Looking in stm32h7xx_hal_spi.c, I see that SPI_FLAG_EOT is never detected and so HAL_SPI_Transmit() times out with HAL_SPI_ERROR_FLAG set.
Is there a working sample showing SPI configuration and use on the STM32H747?
Can anyone suggest what I'm doing wrong?
Thanks.
Pin/port definitions:
#define SPIx SPI5
#define SPIx_IRQn SPI5_IRQn
#define SPIx_SCK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOK_CLK_ENABLE()
#define SPIx_MISO_GPIO_CLK_ENABLE() __HAL_RCC_GPIOJ_CLK_ENABLE()
#define SPIx_MOSI_GPIO_CLK_ENABLE() __HAL_RCC_GPIOJ_CLK_ENABLE()
#define SPIx_CLK_ENABLE() __HAL_RCC_SPI5_CLK_ENABLE()
#define SPIx_SCK_PIN 0
#define SPIx_SCK_GPIO_PORT GPIOK
#define SPIx_SCK_AF GPIO_AF5_SPI5
#define SPIx_MISO_PIN 10
#define SPIx_MISO_GPIO_PORT GPIOJ
#define SPIx_MISO_AF GPIO_AF5_SPI5
#define SPIx_MOSI_PIN 11
#define SPIx_MOSI_GPIO_PORT GPIOJ
#define SPIx_MOSI_AF GPIO_AF5_SPI5
#define SPIx_FORCE_RESET() __HAL_RCC_SPI5_FORCE_RESET()
#define SPIx_RELEASE_RESET() __HAL_RCC_SPI5_RELEASE_RESET()
Hardware setup:
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) {
GPIO_InitTypeDef GPIO_InitStruct;
if (hspi->Instance == SPIx) {
SPIx_SCK_GPIO_CLK_ENABLE();
SPIx_MISO_GPIO_CLK_ENABLE();
SPIx_MOSI_GPIO_CLK_ENABLE();
SPIx_CLK_ENABLE();
/* SPI SCK GPIO pin configuration */
GPIO_InitStruct.Pin = SPIx_SCK_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = SPIx_SCK_AF;
HAL_GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStruct);
/* SPI MISO GPIO pin configuration */
GPIO_InitStruct.Pin = SPIx_MISO_PIN;
GPIO_InitStruct.Alternate = SPIx_MISO_AF;
HAL_GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStruct);
/* SPI MOSI GPIO pin configuration */
GPIO_InitStruct.Pin = SPIx_MOSI_PIN;
GPIO_InitStruct.Alternate = SPIx_MOSI_AF;
HAL_GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStruct);
}
}
SPI initialisation:
hspi5.Instance = SPIx;
hspi5.Init.Mode = SPI_MODE_MASTER;
hspi5.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
hspi5.Init.Direction = SPI_DIRECTION_2LINES;
hspi5.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi5.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi5.Init.DataSize = SPI_DATASIZE_8BIT;
hspi5.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi5.Init.TIMode = SPI_TIMODE_DISABLE;
hspi5.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi5.Init.CRCPolynomial = 7;
hspi5.Init.CRCLength = SPI_CRC_LENGTH_8BIT;
hspi5.Init.NSS = SPI_NSS_SOFT;
hspi5.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
hspi5.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE; /* Recommended setting to avoid glitches */
if(HAL_SPI_Init(&hspi5) != HAL_OK) {
Error_Handler();
}
Solved! Go to Solution.
2024-02-14 08:58 AM
Solved:
#define SPIx_SCK_PIN 0
Should be
#define SPIx_SCK_PIN GPIO_PIN_0
etc.
2024-02-14 06:36 AM - edited 2024-02-14 06:37 AM
To establish that you're checking the right pins, I'd recommend initializing those pins as GPIO output and toggling them to verify they show up on the scope.
I'd also recommend downloading the schematic for the board to ensure those pins are free to use on the board and don't require solder bridges to be changed. This information is usually also in the user manual.
Here is an example that uses HAL_SPI_Transmit:
> HAL_SPI_Transmit() always fails
If it returns something other than HAL_OK, it suggests to have a code bug. There don't appear to be any issues in the code you presented, but there's a lot more relevant code, for example the code where you actually call HAL_SPI_Transmit.
2024-02-14 07:04 AM - edited 2024-02-14 07:21 AM
@TDK I believe these are the correct pins, image from user manual included below.
My simple test of transmitting looks like this:
while(1) {
uint32_t tx[1024] = {0};
printf("SPI tx ret=%d\r\n", HAL_SPI_Transmit(&hspi5, (uint8_t *)tx, 1024*sizeof(uint32_t), 2000));
HAL_Delay(1000);
}
The return value from HAL_SPI_Transmit is 1 (error) and HAL_SPI_GetError(&hspi5) return 0x20 (HAL_SPI_ERROR_FLAG). This occurs due to timeout waiting on EOT.
Can you suggest what to check next to help debug this?
As far as I can see, my code is the same as the polling SPI example you posted - though some changes have been necessary for the STM32H747I-DISCO. Is there a working sample for this board?
2024-02-14 08:58 AM
Solved:
#define SPIx_SCK_PIN 0
Should be
#define SPIx_SCK_PIN GPIO_PIN_0
etc.