Friday, September 9, 2016

HAL_FLASHEx_DATAEEPROM_Program() bug

HAL_FLASHEx_DATAEEPROM_Program() bug

The Bug


I've been using HAL drivers to program an STM32L151CB chip.  While trying to use the HAL_FLASHEx_DATAEEPROM_Program() function in the STM HAL library, I discovered that when I wrote a data byte, and then a "0" into the next byte, that my data was lost.  I wrote a sample program, source below, which demonstrated the problem.

The Fix


It turns out that I was using the STM32L1xx_HAL_Driver V1.1.2 that came packaged with the STM32CubeMX 1.4 code.  After determining that this was a bug in the HAL driver, I thought to check, and there was a newer STM32CubeMX 1.6 release, which included STM32L1xx_HAL_Driver V1.2.0.  The new code worked beautifully.   I did find a mention of a fix in the release notes for driver version 1.1.3, but it was quite vague:


  • FLASH:
    • Correct issue preventing Cat.1 devices to write data in EEPROM.


Sample code



void
DemoFlashBug(void)
{

 HAL_StatusTypeDef status;
 uint32_t Byte0Addr,Byte1Addr;

 HAL_FLASHEx_DATAEEPROM_Unlock();  //Unprotect the EEPROM to allow writing

 Byte0Addr = 0x08080000;
 Byte1Addr = 0x08080001;

 // Print values before we do anything
 trace_puts("Prior to updates");
 trace_printf("Byte0 is: %d\n", *(uint8_t *) Byte0Addr);
 trace_printf("Byte1 is: %d\n", *(uint8_t *) Byte1Addr);

 // Set the first byte to 99
 status = HAL_FLASHEx_DATAEEPROM_Program(TYPEPROGRAMDATA_BYTE, Byte0Addr, (uint32_t) 99);
 if (status != HAL_OK) {
  Error_Handler();
 }
 // Print values after setting byte 0
 trace_puts("\nByte 0 should be set to 99");
 trace_printf("Byte0 is: %d\n", *(uint8_t *) Byte0Addr);
 trace_printf("Byte1 is: %d\n", *(uint8_t *) Byte1Addr);

 status = HAL_FLASHEx_DATAEEPROM_Program(TYPEPROGRAMDATA_BYTE, Byte1Addr, (uint32_t) 0);
 if (status != HAL_OK) {
  Error_Handler();
 }
 // Print values after setting byte 1
 trace_puts("\nByte 1 set to 0");
 trace_printf("Byte0 is: %d\n",  *(uint8_t *) Byte0Addr);
 trace_printf("Byte1 is: %d\n", *(uint8_t *) Byte1Addr);

 if ( *(uint8_t *) Byte0Addr != 99) {
  trace_puts("WTF?!?\n");
 } else {
  trace_puts("OK, it worked!\n");
 }
 HAL_FLASHEx_DATAEEPROM_Lock();  //Unprotect the EEPROM to allow writing

}

Moral of the story

Grab the latest HAL drivers.

No comments:

Post a Comment