Skip to main content
oeliks
Associate III
July 30, 2021
Solved

Write Double without HAL

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.

This topic has been closed for replies.
Tesla DeLorean
Tesla DeLoreanBest answer
Guru
July 30, 2021

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 (See Profile) Up vote any posts that you find helpful, it shows what's working..

5 replies

Tesla DeLorean
Tesla DeLoreanBest answer
Guru
July 30, 2021

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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
Piranha
Principal III
August 8, 2021

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.

oeliks
oeliksAuthor
Associate III
August 15, 2021

Doesnt RM mention about flushing pipeline in flash section?​

oeliks
oeliksAuthor
Associate III
July 30, 2021

Thank You, now I start to understand it.​