Skip to main content
JPaz.1
Associate
March 25, 2021
Question

How to reset SPI using HAL functions using Nucleo - L073RZ

  • March 25, 2021
  • 12 replies
  • 6532 views

I am working on a SPI project (using DMA) as a slave and things seems to work fine but after an hour and maybe more in some cases I see one error and that locks the dma ....I can detect when that happens but I have problems to reset the SPI interface...I tried several things what were posted before like:

HAL_SPI_Abort_IT(&hspi3);

HAL_SPI_Abort(&hspi3);

HAL_SPI_AbortCpltCallback(&hspi3);

HAL_SPIEx_FlushRxFifo(&hspi3);

HAL_SPI_DeInit(&hspi3);

HAL_SPI_Init(&hspi3);

but it does not fix it ...I am using HAL functions ...in a post 2 years ago from from Gone Aug 06 he included the following:

  1. SPIP_SlaveConfigureSpi(pSPIP->hspi);
  2. SPIP_SlaveConfigureDma(pSPIP->hspi);

I do not think these are HAL functions I wonder if you anybody has the code for the functions mentioned above ?

I have been struggling with this for some time ......not sure if it is a noise issue (working with NUCLEO L073RZ ) I am using the highest priority for the SPi and also trying to add pull downs to clock and mosi to try to reduce noise but does not seem to help ....

Thanks for your help.

This topic has been closed for replies.

12 replies

Peter BENSCH
ST Technical Moderator
March 25, 2021

You are referring to the very bottom of this thread, but the two lines you mentioned just call the init functions for SPI2 and DMA (for some reason, pasting formatted blocks of code does not currently work):

 /*RCC->AHB1RSTR |= 1<<0; // DMA1

 NOPs(2);

 RCC->AHB1RSTR &= ~(1<<0);*/

 NOPs(2);

 RCC->APB1RSTR1 |= (1<<14);// SPI2

 NOPs(2);

 RCC->APB1RSTR1 &= ~(1<<14);

You will achieve exactly the same result using HAL functions defined in stm32l4xx_hal_rcc.h, but it would still have to be checked whether the NOPs are actually necessary.:

/*

 __HAL_RCC_DMA1_FORCE_RESET(); // see stm32l4xx_hal_rcc.h

 __NOP(); // cmsis_gcc.h

 __NOP();

 __HAL_RCC_DMA1_RELEASE_RESET(); // see stm32l4xx_hal_rcc.h

*/

 __NOP();

 __NOP();

 __HAL_RCC_SPI2_FORCE_RESET(); // see stm32l4xx_hal_rcc.h

 __NOP();

 __NOP();

 __HAL_RCC_SPI2_RELEASE_RESET(); // see stm32l4xx_hal_rcc.h

Regards

/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
JPaz.1
JPaz.1Author
Associate
March 25, 2021

Hi Peter,

Thanks for your replay ...I did find the dma1_force_reset in stm32l4xx_hal_rcc.h but did not find the SPI2_force_reset (?) .....I am new to STM32 anyways, using SPI2 using  (NUCLEO-L073RZ) and HAL functions I can transmit and receive correct most of the times ...STM processor is the slave and an Aardvark is the master (100Khz - 8 bits) not really creating too much traffic, sporadically mostly I leave the system idle for an hour and maybe more but suddenly i see an error and that is affecting the operation.

In the code I am using basic HAL stuff: (Besides the one SPI Have an ADC also using DMA ( running alone in a thread ) and a UART also TX/and RX using DMA (running also alone in a thread - there is very little traffic in UART almost null it is mostly in receive mode waiting for something that can appear every 20 min or so), I assigned the highest priority to the SPI interrupt. for SPI I have:

SPI_HandleTypeDef hspi2;

DMA_HandleTypeDef hdma_spi2_rx;

DMA_HandleTypeDef hdma_spi2_tx;

 MX_SPI2_Init();

void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi2)

{

complete_spi = 1;

}

And in the main program I have a switch to receive and transmit SPI values:

if(HAL_SPI_TransmitReceive_DMA(&hspi2, spi_data_tx, spi_data_rx, 1) != HAL_OK) {

complete_spi = 1;

}

Sometimes the DMA is locked and sometimes I got a wrong value I can detect the wrong value happens ...I wonder if there is some noise (?) I tried to add pull downs to SPI_SCLK, SPI_SS and SPI_MOSI it looks a bit better but the failure is very sporadic and it can happen anytime...problem is when the failure happens only thing I can do is reset the processor to start fresh again so I need to try to implement a mechanism to rest the SPI and continue.. i saw that previous post where some people recommended a method to rest SPI

  1. void SPIP_SlaveReStart(SPIP_t* pSPIP) {
  2. HAL_SPI_DeInit(pSPIP->hspi); // back to original state
  3. // first, we reset the cell (yes!)
  4. /*RCC->AHB1RSTR |= 1<<0; // DMA1
  5. NOPs(2);
  6. RCC->AHB1RSTR &= ~(1<<0);*/
  7. NOPs(2);
  8. RCC->APB1RSTR1 |= (1<<14);// SPI2
  9. NOPs(2);
  10. RCC->APB1RSTR1 &= ~(1<<14);
  11. SPIP_SlaveConfigureSpi(pSPIP->hspi);
  12. SPIP_SlaveConfigureDma(pSPIP->hspi);
  13. }

There are some portions commented out (?) not sure what is really needed to rest the SPI but I can do some experiments, I could not find the functions that were not commented out: HAL_RCC_SPI2_FORCE_RESET & HAL_RCC_SPI2_RELEASE_RESET in stm32l4xx_hal_rcc.h and also the last instructions SPIP_SlaveConfigureSpi() and SPIP_SlaveConfigureDma() are they HAL instructions or there are any HAL equivalents to them ? or there is a better way recommended by STM to rest a SPI peripheral and leave it to its initial state ? ..without affecting the rest of the system..

Thanks for your help, time and consideration,

Joe

Peter BENSCH
ST Technical Moderator
March 26, 2021

__HAL_RCC_SPI2_FORCE_RESET() and __HAL_RCC_SPI2_RELEASE_RESET() are defines.

You will find them in stm32l4xx_hal_rcc.h in either the firmware you may have downloaded to your repository (see e.g. STM32CubeIDE settings) or in the Github repository, currently at lines 2470 and 2568.

Regards

/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
JPaz.1
JPaz.1Author
Associate
March 29, 2021

when the spi fails how can I verify the status of the system like if there was a problem with interrupt or if an stack overflow or any other error in the processor happens ? ....are there some instructions to do so ....I can add those checks whenever i detect the spi error and determine if a system error happened too ...