Skip to main content
Visitor II
November 25, 2025
Question

STM32C092 (NUCLEO-C092RC Board) Flash example not working

  • November 25, 2025
  • 1 reply
  • 297 views

Dear all

I have a complex Flash problem. But even with NUCLEO-C092RC Board and the provided FLASH_EraseProgram example I have Flash erase and/or program problems.

I adapted the original provided ST code a litte to get more information of the problem with the on board LED's.

This is the code I changed: (all the rest is 100% original code)

Problem description (with Keil uVision):

/**
 * @brief The application entry point.
 * @retval int
 */
int main(void)
{

 /* USER CODE BEGIN 1 */
 /* STM32C0xx HAL library initialization:
 - Configure the Flash prefetch
 - Systick timer is configured by default as source of time base, but user 
 can eventually implement his proper time base source (a general purpose 
 timer for example or other time source), keeping in mind that Time base 
 duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and 
 handled in milliseconds basis.
 - Low Level Initialization
 */

 /* USER CODE END 1 */

 /* MCU Configuration--------------------------------------------------------*/

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();

 /* USER CODE BEGIN Init */
 /* Configure the system clock to 48 MHz */
 /* USER CODE END Init */

 /* Configure the system clock */
 SystemClock_Config();

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */
 /* USER CODE BEGIN 2 */
 /* Initialize LED1 and LED2 */
 BSP_LED_Init(LED1);
 BSP_LED_Init(LED2);
#if !defined (GENERATOR_STM32WL3XX)
 /* Unlock the Flash to enable the flash control register access *************/
 HAL_FLASH_Unlock();
#endif /* ! GENERATOR_STM32WL3XX */

 /* Clear OPTVERR bit set on virgin samples */
 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);

 /* Erase the user Flash area
 (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/

 /* Get the 1st page to erase */
 FirstPage = GetPage(FLASH_USER_START_ADDR);

 /* Get the number of pages to erase from 1st page */
 NbOfPages = GetPage(FLASH_USER_END_ADDR) - FirstPage + 1;

 /* Fill EraseInit structure*/
 EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
 EraseInitStruct.Page = FirstPage;
 EraseInitStruct.NbPages = NbOfPages;

 /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
 you have to make sure that these data are rewritten before they are accessed during code
 execution. If this cannot be done safely, it is recommended to flush the caches by setting the
 DCRST and ICRST bits in the FLASH_CR register. */
 if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
 {
 /*
 Error occurred while page erase.
 User can add here some code to deal with this error.
 PageError will contain the faulty page and then to know the code error on this page,
 user can call function 'HAL_FLASH_GetError()'
 */
 /* Infinite loop */
 while (1)
 {
 BSP_LED_On(LED1);
 HAL_Delay(200);
 BSP_LED_Off(LED1);
 HAL_Delay(200); 
// Error_Handler();
 }
 }

 /* Program the user Flash area word by word
 (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/

 Address = FLASH_USER_START_ADDR;

 while (Address < FLASH_USER_END_ADDR)
 {
 if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, DATA_64) == HAL_OK)
 {
 Address = Address + 8; /* increment to next double word*/
 }
 else
 {
 /* Error occurred while writing data in Flash memory.
 User can add here some code to deal with this error */
 while (1)
 {
 BSP_LED_On(LED1);
 HAL_Delay(100);
 BSP_LED_Off(LED1);
 HAL_Delay(900); 
 
 // Error_Handler();
 }
 }
 }
#if !defined (GENERATOR_STM32WL3XX)
 /* Lock the Flash to disable the flash control register access (recommended
 to protect the FLASH memory against possible unwanted operation) *********/
 HAL_FLASH_Lock();
#endif /* ! GENERATOR_STM32WL3XX */

 /* Check if the programmed data is OK
 MemoryProgramStatus = 0: data programmed correctly
 MemoryProgramStatus != 0: number of words not programmed correctly ******/
 Address = FLASH_USER_START_ADDR;
 MemoryProgramStatus = 0x0;

 while (Address < FLASH_USER_END_ADDR)
 {
 data32 = *(__IO uint32_t *)Address;

 if (data32 != DATA_32)
 {
 MemoryProgramStatus++;
 }
 Address = Address + 4;
 }
 
 BSP_LED_Off(LED1);
 BSP_LED_Off(LED2);
 /*Check if there is an issue to program data*/
 if(MemoryProgramStatus != 0)
 {
 /* Turn on LED2 when there are errors detected after data programming */
 BSP_LED_On(LED2);
 }
 else
 {
 /* No error detected. Switch on LED1 */
 BSP_LED_On(LED1);
 }

 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */

 }
 /* USER CODE END 3 */
}
  • same problem happen also with original code from ST example, but the LED's are not showing what happen in SW.
  • Problem is not happen without Emulator (LED1 constant ON at the end)
  • Emulator variant: I set a break point to HAL_FLASH_Lock(); (This is important to do!!!) Let run the code. LED 1 is all 0.2s ON and OFF. --> erase routine failed. If now I reset the emulator, and restart the program system is working. If once the program has worked also the next time program will work. 
    To go back in in error state disconnect emulator reconnect and set break point on the same position.
    If I have no breakpoint set, it is random, sometimes is working, but not always.

Find attached the full project compiled with Keil.

Hope anybody can see same effect. Thank you for any ideas for solving the problems.

By the way I have more or less similar problem with STM32G0B1 CPU.

Franz

 

    This topic has been closed for replies.

    1 reply

    Technical Moderator
    November 25, 2025

    Hello @franz2 

    The example FLASH_EraseProgram work correctly on my side.

     

    franz2Author
    Visitor II
    November 25, 2025

    Have you set the break point on line HAL_FLASH_Lock(); ?

    Technical Moderator
    November 25, 2025

    Hello @franz2 

    Thank you for bringing this issue to our attention.

    I reported this internally.

    Internal ticket number: 222522 (This is an internal tracking number and is not accessible or usable by customers).