2022-07-06 12:33 PM
I'm using a "blue pill" breakout board and developing with STM32CubeIDE and HAL libraries.
When I HAL_SPI_Transmit to SPI1, I get a signal on the MOSI line (PB5), but the corresponding clock signal on SCL (PB3) is a constant 0V. If I run the same code, targetting SPI2, it works fine.
When I try this using the STM32 "Arduino" library, which uses the LL functions not HAL, it works fine on SPI1.
This smells like an AFIO mapping issue, but I can't find the issue.
I am able to reproduce the problem by creating a fresh project, assigning PB3-PB5 to SPI and writing to the port. This results in a signal on my scope for MOSI but not SCL.
static void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
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.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
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();
}
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI1_Init();
while (1)
{
uint8_t chr = 0x55;
HAL_SPI_Transmit(&hspi1, &chr, 1, 1);
}
}
2022-07-06 01:07 PM
It's a remapped usage, so AFIO involved for sure.
Also part of the JTAG/SWD pins, so going to need some attention there too.
Quick grep of related details
STM32Cube_FW_F1_V1.8.4\Projects\STM32F103RB-Nucleo\Examples_LL\SPI\SPI_OneBoard_HalfDuplex_DMA\Src\main.c
/* Remap SPI1 pins and disable JTAG */
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_AFIO);
LL_GPIO_AF_Remap_SWJ_NOJTAG();
while((AFIO->MAPR & AFIO_MAPR_SWJ_CFG_JTAGDISABLE) != AFIO_MAPR_SWJ_CFG_JTAGDISABLE);
LL_GPIO_AF_EnableRemap_SPI1();
/* Configure SCK Pin connected to pin 31 of CN10 connector */
LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_3, LL_GPIO_MODE_ALTERNATE);
LL_GPIO_SetPinSpeed(GPIOB, LL_GPIO_PIN_3, LL_GPIO_SPEED_FREQ_LOW);
LL_GPIO_SetPinPull(GPIOB, LL_GPIO_PIN_3, LL_GPIO_PULL_DOWN);
/* Configure MOSI Pin connected to pin 29 of CN10 connector */
LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_5, LL_GPIO_MODE_ALTERNATE);
LL_GPIO_SetPinSpeed(GPIOB, LL_GPIO_PIN_5, LL_GPIO_SPEED_FREQ_LOW);
LL_GPIO_SetPinPull(GPIOB, LL_GPIO_PIN_5, LL_GPIO_PULL_DOWN);
...
2022-07-06 01:28 PM
Thanks for pointing me in the right direction. I added the header
#include "stm32f1xx_ll_gpio.h"
and updated my init function above to
static void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
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.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
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();
}
LL_GPIO_AF_Remap_SWJ_NOJTAG();
while((AFIO->MAPR & AFIO_MAPR_SWJ_CFG_JTAGDISABLE) != AFIO_MAPR_SWJ_CFG_JTAGDISABLE);
}
and it works! And SWD debugging still works too.
This seems like a bug in the HAL library, but it has been around long enough that I can't be the first to discover it.
2022-07-07 06:48 AM
I created ticket 00160627 to track this bug.