2020-05-26 07:05 PM
Hello everyone!
I am trying to write to flash without using built-in HAL functions. Initially, I want "Hello World!". The Flash is only aligned double word writable as shown in the reference manual (RM0394) standard Programming technique Section 3.3.7.
Link to reference manual:
https://www.st.com/en/microcontrollers-microprocessors/stm32l412kb.html#
Before you go through the code, I also think there's no need to erase the flash since it's FFFF.. all the way so I am assuming, I don't need to clean it at least right now. I have also tried altering the Start_Address to go to different pages but, I haven't had any luck yet. The reason to choose page 48 is because I will need 32 Kb. I am considering 32Kb starting from the top. This is just an assumption.
My code:
uint64_t* Start_Address = (uint64_t*)(0x08018000); /* Page 48 address */
volatile uint32_t* pClkCtrlreg = (uint32_t*)(0x40021048); /* RCC_AHB1ENR Clock Enable Register */
volatile uint32_t* pFlashKeyReg = (uint32_t*)(0x40022008); /* FLASH_KEYR Register */
volatile uint32_t* pFlashStatusReg = (uint32_t*)(0x40022010); /* FLASH_SR Status Register enable */
volatile uint32_t* pFlashCtrlReg = (uint32_t*)(0x40022014); /* FLASH_CR Control Register enable */
uint64_t TEST = 2434; /* Just an example*/
*pClkCtrlreg |= (1<<8); /* Flash Clock enabled*/
if(!((*pFlashStatusReg) & (1<<16))){ /* Unlocking the Flash */
*pFlashKeyReg = 0x45670123; /* Entering Key 1*/
*pFlashKeyReg = 0xCDEF89AB; /* Entering Key 2*/
}
/* Page Erase (Page 48 only) */
if(!((*pFlashStatusReg) & (1<<16))){ /* BSY Flag Status check */
if(((*pFlashStatusReg) & (1<<7))) /* Check if PGSERR is set*/
{
*pFlashStatusReg &= 0x11113C05; /* Clearing previous programming errors while PGSERR is set */
}
else
{
*pFlashStatusReg &= 0xFFFF3FED; /* Clearing previous programming errors while PGSERR is not set */
}
*pFlashCtrlReg |= (1<<1); /* Set the PER Bit */
*pFlashCtrlReg |= (3<<7); /* Page 48: Set Bits 7th and 8th */
*pFlashCtrlReg &= (~(1<<3)); /* Page 48: Clear Bit 3 */
*pFlashCtrlReg &= (~(1<<4)); /* Page 48: Clear Bit 4 */
*pFlashCtrlReg &= (~(1<<5)); /* Page 48: Clear Bit 5 */
*pFlashCtrlReg &= (~(1<<6)); /* Page 48: Clear Bit 6 */
*pFlashStatusReg |= (1<<16); /* Set STRT Bit */
while((*pFlashStatusReg) & (1<<16)); /* Wait until BSY Flag is cleared*/
}
/* Standard Programming Technique */
if(!((*pFlashStatusReg) & (1<<16))){ /* BSY Flag Status check */
if(((*pFlashStatusReg) & (1<<7))) /* Check if PGSERR is set*/
{
*pFlashStatusReg &= 0x11113C05; /* Clearing previous programming errors while PGSERR is set */
}
else
{
*pFlashStatusReg &= 0xFFFF3FED; /* Clearing previous programming errors while PGSERR is not set */
}
*pFlashCtrlReg |= (1<<0); /* Set the PG Bit */
// Flash is unlocked and ready to be written at this stage. How should I write to flash now? I have tried memset/memcpy. Can y'all suggest what to do next?
2020-05-26 08:18 PM
No need to reinvent the wheel. Use the CMSIS headers so yourself and others can read your code.
Here's what HAL does. Easy enough to read the functions and lift the relevant code.
/**
* @brief Program a double word (64-bit) at a specified address.
* @note This function must be used when the device voltage range is from
* 2.7V to 3.6V and Vpp in the range 7V to 9V.
*
* @note If an erase and a program operations are requested simultaneously,
* the erase operation is performed before the program one.
*
* @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_ADDRESS(Address));
/* If the previous operation is completed, proceed to program the new data */
CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
FLASH->CR |= FLASH_PSIZE_DOUBLE_WORD;
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+4) = (uint32_t)(Data >> 32);
}
2020-05-26 08:50 PM
I agree with this but, my manager doesn't want me to use this library for the allotted task
2020-05-26 08:53 PM
I agree with this but, my manager doesn't want me to use this library for the allotted task
2020-05-26 09:05 PM
So I was able to write to Flash using this but, how do I clear it?