cancel
Showing results for 
Search instead for 
Did you mean: 

Write Double without HAL

oeliks
Senior

Hi! Jest a curiosity topic.

Currently Im writing a double word to flash with HAL_FLASH_Program function.

RM notes that You should write a word32 and than to the same adress another word32.

How can You write a 2x_word_32 or 1x_doubleword_64 without HAL funciin or making struct etc.

?

​Chip Im using is stm32L432KC, that has a page flash aligment and You can write only double word to it at once.

Thanks !​

Writing to desired location like to FLASH->KEYR​ or with +0x04UL distancing with another word fails with data aligment error flag.

1 ACCEPTED SOLUTION

Accepted Solutions

They don't write the data to the same address

/**
  * @brief  Program double-word (64-bit) at a specified address.
  * @param  Address: specifies the address to be programmed.
  * @param  Data: specifies the data to be programmed.
  * @retval None
  */
static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
{
  /* Check the parameters */
  assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
 
  /* Set PG bit */
  SET_BIT(FLASH->CR, FLASH_CR_PG);
 
  /* Program first word */
  *(__IO uint32_t*)Address = (uint32_t)Data;
 
  /* Barrier to ensure programming is performed in 2 steps, in right order
    (independently of compiler optimization behavior) */
  __ISB();
 
  /* Program second word */
  *(__IO uint32_t*)(Address+4U) = (uint32_t)(Data >> 32);
}

If I were using assembler I'd probably use the STRD in this context. It does expect 32-bit (4-byte) alignment of the address. The flash array expects a 64-bit (8-byte) alignment of the address.

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

View solution in original post

5 REPLIES 5

They don't write the data to the same address

/**
  * @brief  Program double-word (64-bit) at a specified address.
  * @param  Address: specifies the address to be programmed.
  * @param  Data: specifies the data to be programmed.
  * @retval None
  */
static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
{
  /* Check the parameters */
  assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
 
  /* Set PG bit */
  SET_BIT(FLASH->CR, FLASH_CR_PG);
 
  /* Program first word */
  *(__IO uint32_t*)Address = (uint32_t)Data;
 
  /* Barrier to ensure programming is performed in 2 steps, in right order
    (independently of compiler optimization behavior) */
  __ISB();
 
  /* Program second word */
  *(__IO uint32_t*)(Address+4U) = (uint32_t)(Data >> 32);
}

If I were using assembler I'd probably use the STRD in this context. It does expect 32-bit (4-byte) alignment of the address. The flash array expects a 64-bit (8-byte) alignment of the address.

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

Thank You, now I start to understand it.​

Typical for ST's code. The comments show how actually incompetent the developers are. First, they talk about avoiding an instruction reorder by compiler optimization... for volatile types, which are not reordered anyway! Second, if the types where not volatile, a compiler barrier would be enough, not a pipeline flush instruction (ISB). Third, ISB doesn't even guarantee the order of memory accesses - for that there is DMB. Forth, only Cortex-M7 can reorder the memory accesses, therefore none of those instructions are actually required for Cortex-M4 in L4 series.

Doesnt RM mention about flushing pipeline in flash section?​

No, it talks about flushing caches, which is a different issue and is not addressed at driver level. User code must flush caches if an executable code memory is modified.