Skip to main content
YShe.1
Associate II
March 18, 2023
Solved

Writing to internal flash STM32L422KBT6

  • March 18, 2023
  • 1 reply
  • 2185 views

Hi I hove something trobels with writing data after erease. I have only option bank and page erease and nothing other. I doing a bank1 erease and after this tryuing to write something whith is complitly not writing to memeory. Only on another compilation if memory is eresed I have data writen. How to clean and then write data? Im writing a uint16_t like a doble word, also I have only duble word. This making me cry, plese help just make a data rewrite, like it should be. I not wish have additional function for erease. Many thanks.

#define FLASH_START_ADDRESS 0x08010000
 
// Function to erase the flash memory
void erase_flash()
{
 // Unlock the flash memory for writing
 HAL_FLASH_Unlock();
 
 // Initialize the erase configuration structure
 FLASH_EraseInitTypeDef erase_init;
 erase_init.TypeErase = FLASH_TYPEERASE_MASSERASE; // Mass erase the flash memory
 erase_init.Banks = FLASH_BANK_1; // Select the bank of the flash memory to erase
 
 // Perform the erase operation and store any errors
 uint32_t flash_error;
 HAL_FLASHEx_Erase(&erase_init, &flash_error);
 
 // Lock the flash memory after erasing is complete
 HAL_FLASH_Lock();
}
 
// Function to write data to the flash memory
void write_flash(uint16_t *data, uint32_t size)
{
 // Unlock the flash memory for writing
 HAL_FLASH_Unlock();
 
 // Iterate over the array of data and write each element to the flash memory
 uint32_t i, flash_error;
 for (i = 0; i < size; i++)
 {
 // Convert the 16-bit data to a 64-bit value and write it to the flash memory
 uint64_t value = *(data + i);
 flash_error = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, FLASH_START_ADDRESS + i * 8, value);
 
 // Handle any errors that occur during the write operation
 if (flash_error != HAL_OK)
 {
 // Insert code to handle the error here
 }
 }
 
 // Lock the flash memory after writing is complete
 HAL_FLASH_Lock();
}

This topic has been closed for replies.
Best answer by Tesla DeLorean

Try, put what you want in a structure, pass in casted base address of structure, and size in bytes

/**
 * @brief Gets the page of a given address
 * @param Addr: Address of the FLASH Memory
 * @retval The page of a given address
 */
static uint32_t GetPage(uint32_t Addr) // Single Bank Device
{
 return((Addr - FLASH_BASE) / FLASH_PAGE_SIZE);
}
 
// Function to write data to the flash memory
// BYTE pointer, Size in BYTES, put what you want in a STRUCTURE
 
void write_flash(uint8_t *data, uint32_t size)
{
 FLASH_EraseInitTypeDef EraseInitStruct = {0};
 uint32_t addr = FLASH_START_ADDRESS; // 64-bit aligned 
 uint64_t value;
 uint32_t PageError;
 
 size = (size + 7) & ~7; // Round to 64-bit words
 
 // Unlock the flash memory for writing
 HAL_FLASH_Unlock();
 
 /* Clear OPTVERR bit set on virgin samples */
 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
 
 /* Fill EraseInit structure, spanning size of write operation */
 EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
 EraseInitStruct.Banks = FLASH_BANK_1;
 EraseInitStruct.Page = GetPage(addr); // Starting Page
 EraseInitStruct.NbPages = GetPage(addr + size) - EraseInitStruct.Page + 1; // Page Count, at least 1 
 
 if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
 {
 // Insert code to handle the error here
 
 HAL_FLASH_Lock();
 return;
 }
	
 size /= sizeof(uint64_t); // Byte count to 64-bit word count
 
 // Iterate over the array of data and write each element to the flash memory
 while(size--)
 {
 memcpy(&value, data, sizeof(uint64_t)); // alignment safe copy of byte array into 64-bit value
 
 if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addr, value) != HAL_OK)
 {
 // Insert code to handle the error here
 
 HAL_FLASH_Lock();
 return;
 }
 
 
 addr += sizeof(uint64_t); // Advance address
 data += sizeof(uint64_t); // Advance byte buffer
 }
 
 // Lock the flash memory after writing is complete
 HAL_FLASH_Lock();
}

1 reply

Tesla DeLorean
Tesla DeLoreanBest answer
Guru
March 18, 2023

Try, put what you want in a structure, pass in casted base address of structure, and size in bytes

/**
 * @brief Gets the page of a given address
 * @param Addr: Address of the FLASH Memory
 * @retval The page of a given address
 */
static uint32_t GetPage(uint32_t Addr) // Single Bank Device
{
 return((Addr - FLASH_BASE) / FLASH_PAGE_SIZE);
}
 
// Function to write data to the flash memory
// BYTE pointer, Size in BYTES, put what you want in a STRUCTURE
 
void write_flash(uint8_t *data, uint32_t size)
{
 FLASH_EraseInitTypeDef EraseInitStruct = {0};
 uint32_t addr = FLASH_START_ADDRESS; // 64-bit aligned 
 uint64_t value;
 uint32_t PageError;
 
 size = (size + 7) & ~7; // Round to 64-bit words
 
 // Unlock the flash memory for writing
 HAL_FLASH_Unlock();
 
 /* Clear OPTVERR bit set on virgin samples */
 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
 
 /* Fill EraseInit structure, spanning size of write operation */
 EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
 EraseInitStruct.Banks = FLASH_BANK_1;
 EraseInitStruct.Page = GetPage(addr); // Starting Page
 EraseInitStruct.NbPages = GetPage(addr + size) - EraseInitStruct.Page + 1; // Page Count, at least 1 
 
 if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
 {
 // Insert code to handle the error here
 
 HAL_FLASH_Lock();
 return;
 }
	
 size /= sizeof(uint64_t); // Byte count to 64-bit word count
 
 // Iterate over the array of data and write each element to the flash memory
 while(size--)
 {
 memcpy(&value, data, sizeof(uint64_t)); // alignment safe copy of byte array into 64-bit value
 
 if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addr, value) != HAL_OK)
 {
 // Insert code to handle the error here
 
 HAL_FLASH_Lock();
 return;
 }
 
 
 addr += sizeof(uint64_t); // Advance address
 data += sizeof(uint64_t); // Advance byte buffer
 }
 
 // Lock the flash memory after writing is complete
 HAL_FLASH_Lock();
}

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..