cancel
Showing results for 
Search instead for 
Did you mean: 

FLASHEx_Erase returns HAL_ERROR only when TIM16 is activated in CubeMX.

TDudl.1
Associate II

Hello,

I asked this question once, but I feel that I explained the problem inadequately.

I am attempting to write to internal flash memory and am following the (UNLOCK, ERASE, WRITE, LOCK) approach. Everything writes fine in the simple code I have written until I introduce TIM16.

void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN 5 */
 
  static FLASH_EraseInitTypeDef EraseInitStruct;
  uint32_t PAGEError;
  int programIterator;
  HAL_StatusTypeDef statusErase;
  HAL_StatusTypeDef statusProgram;
  uint64_t bufferToWrite[64];
  
  //HAL_TIM_PWM_Start(&htim16, TIM_CHANNEL_1);
  
  /* Enable the flash control register access */
   HAL_FLASH_Unlock();
 
   /* Erase the user Flash area*/
   uint32_t addressToWrite = (0X08080000);
 
   /* Fill EraseInit structure*/
   EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
   EraseInitStruct.Page = 128;
   EraseInitStruct.NbPages = 1;
   PAGEError = 0;
 
   statusErase = HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError);
   if (statusErase != HAL_OK)
   {
 
   }// end if
 
   for(int i = 0; i < sizeof(bufferToWrite) / 8 ; i++ )
   {
     bufferToWrite[i] = i;
   } // end for
   
   /* Program the user Flash area word by word <-- using DOUBLEWORD*/
   for (programIterator = 0; programIterator < sizeof(bufferToWrite)/8 ; programIterator++ )
   {
     statusProgram = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addressToWrite, bufferToWrite[programIterator]);
     if (statusProgram == HAL_OK)
     {
     }
     else
     {
     } // end if
     addressToWrite += 8;
   } // end for
 
   /* Disable the flash control register access */
   HAL_FLASH_Lock();
   
   /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END 5 */
}

This snippet of code will write to flash with:

  • TIM17 - PWM CH1 at 1MHz
  • No PWM timers

and only fails to erase when TIM16 is activated. (Even if the channel is left disabled)

I have dug all over trying to find this issue and cannot seem to pinpoint it.

I have stripped the project down to just the starter project with TIM16 turned on and FreeRTOS Cmsis v2.

Specifically, the Erase fails in FLASHEx_Erase(). Even more specifically, it gets a HAL_ERROR in FLASH_WaitForLastOperation() called by FLASHEx_Erase().

The error code given is error 160, but I can't seem to track down what that means.

Any help or a direction to debug would be helpful!

Remember, this code runs and writes with PWM timers, and without... It specifially fails when TIM16 is activated.

EDIT: This is how far it makes it in FLASH_WaitForLastOperation()

HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
{
  uint32_t error;
  uint32_t tickstart = HAL_GetTick();
 
  /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
     Even if the FLASH operation fails, the BUSY flag will be reset and an error
     flag will be set */
  while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
  {
    if ((HAL_GetTick() - tickstart) >= Timeout)
    {
      return HAL_TIMEOUT;
    }
  }
 
  /* Check FLASH operation error flags */
  error = FLASH->SR;
 
  /* Check FLASH End of Operation flag */
  if ((error & FLASH_FLAG_EOP) != 0U)
  {
    /* Clear FLASH End of Operation pending bit */
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
  }
 
  /* Workaround for BZ 70309 :
     - OPTVERR is always set at power-up due to failure of engi bytes checking
     - FLASH_WaitForLastOperation() is called at the beginning of erase or program
       operations, so the bit will be clear when performing first operation */
  if ((error & FLASH_FLAG_OPTVERR) != 0U)
  {
    /* Clear FLASH OPTVERR bit */
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
 
    /* Clear OPTVERR bit in "error" variable to not treat it as error */
    error &= ~FLASH_FLAG_OPTVERR;
  }
 
  /* Now update error variable to only error value */
  error &= FLASH_FLAG_SR_ERRORS;
 
  /* clear error flags */
  __HAL_FLASH_CLEAR_FLAG(error);
 
  if (error != 0U)
  {
    /*Save the error code*/
    pFlash.ErrorCode = error;
 
    return HAL_ERROR;
  }

3 REPLIES 3
TDK
Guru

Previous thread:

https://community.st.com/s/question/0D53W00001Pw0nbSAB/halflashexerase-returns-halerror-only-when-tim16-is-activated-in-cubemx-tim16-is-set-up-for-1mhz-pwm-ch1-i-am-attempting-to-write-to-internal-flash-and-have-no-issues-until-tim16-is-activated

Would be nice to include your chip number. Guessing G4 something but would prefer not to have to guess.

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

Ahh yes, It’s a stm32Wb55RG.

Remy ISSALYS
ST Employee

Hello,

In your project did you use TIM1 or not ? Can you check TL_RefTable when you use TIM16, to see if CPU2 is in hardfault ? Your issue seems to be similar to this post:

STM32WB Application recieves hardfault keyword after TL_Enable() is called

Best Regards