Electronics > Microcontrollers
STM32... How can SPI cause a reset? Serious bug here.
VK3DRB:
Hi.
I have a bug which is driving me nuts.
I am using an STM32L151RBT6A, programmed in C using STM32cubeIDE rev. 1.15.1.
The SPI drives two radios: CC1120 (FSK) and SX1276 (LoRa).
Wiring is correct as per the datasheets and separate chip selects are used for the SPI.
The STM32 resests (reset glitch form 3.0V to 0V) whenever I do an SPI operation, even if I have both radio chips in reset, or one in reset or none in reset.
I cannot see how this can occur. Power supplies are clean, no radios operating (no RF).
I rerouted the nSS pin to PB0 (cut track and wire-add wire) to separate the chip select to try to find out what is causing the reset.
I am under immense pressure to fix this bug within the next two days. If anyone spots anything here, please let me know. It will be much appreciated.
Code is here:
u8 data=0;
uint8_t receivedData = 0;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_Delay(500);
HAL_GPIO_WritePin(nCS_SX1276,SET_PIN_HIGH);
HAL_GPIO_WritePin(nCS_CC1120,SET_PIN_LOW);
//HAL_GPIO_WritePin(nRESET_SX1276,SET_PIN_LOW);
//HAL_GPIO_WritePin(nRESET_CC1120,SET_PIN_LOW);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // Set CS low on PB0, the rewired CS for the CC1120
data = 0x30; // Reset command for CC1120
if (HAL_SPI_TransmitReceive(&hspi1, &data, &receivedData, 1, HAL_MAX_DELAY) != HAL_OK) // THIS COMMAND CAUSES THE RESET OF THE STM32!!!
{
Error_Handler();
}
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); // Set CS high
}
/* USER CODE END 3 */
static void MX_SPI1_Init(void)
{
/* USER CODE BEGIN SPI1_Init 0 */
/* USER CODE END SPI1_Init 0 */
/* USER CODE BEGIN SPI1_Init 1 */
/* USER CODE END SPI1_Init 1 */
/* SPI1 parameter configuration*/
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();
}
/* USER CODE BEGIN SPI1_Init 2 */
/* USER CODE END SPI1_Init 2 */
}
ataradov:
Does it also happen when you single step through the code? If so, can you narrow down the place?
If you can't reproduce it with single stepping, define another GPIO and toggle it at different places along the code path inside the HAL_SPI_TransmitReceive().
thm_w:
Can you be more specific, you are saying nReset (pin 7 of the MCU) is going from 3V to 0V without outside intervention? That doesn't really make sense.
Does 3V-MCU change at all when that happens?
Does it happen with the debugger disconnected? (maybe its wired incorrectly)
VDDA should not be tied to Vdd with a 10k resistor. Change that to 0R.
ataradov:
--- Quote from: thm_w on May 30, 2024, 12:54:50 am ---That doesn't really make sense.
--- End quote ---
Reset pin is open drain (with internal pull-up) and MCU itself can drive it low on a number of internal reset sources.
One of those sources is WDT. So, if WDT is enabled, I would check the WDT timeout and the duration of a blocking loop in SPI.
And of course, check the reset reason. It will tell you exactly why reset has happened.
VK3DRB:
--- Quote from: ataradov on May 30, 2024, 12:45:02 am ---Does it also happen when you single step through the code? If so, can you narrow down the place?
If you can't reproduce it with single stepping, define another GPIO and toggle it at different places along the code path inside the HAL_SPI_TransmitReceive().
--- End quote ---
I found the line of code in stm32I1xx_hal_spi.c that crashed using debug, if that is any help...
/* Transmit and Receive data in 8 Bit mode */
else
{
if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U))
{
*((__IO uint8_t *)&hspi->Instance->DR) = (*hspi->pTxBuffPtr); // STEPPING OVER THIS LINE OF CODE CAUSES THE RESET!
hspi->pTxBuffPtr += sizeof(uint8_t);
hspi->TxXferCount--;
}
Navigation
[0] Message Index
[#] Next page
Go to full version