2013-04-09 06:59 AM
Hello everyone...
I have a question: I'm programming a application with a lcd-touch and i want to be ableto store a few integers to a area that keeps it's data during power off.Where do i begin, because i just have no idea....I understand that i should use flash memory, but how?I am using a stm32f4Discovery boardThanks #flash-eeprom2013-04-09 08:01 AM
Well it gets a little complicated on the F4 because the smaller (16K), more practical flash blocks, are at the front of the memory. This means you either need to break the code into a boot loader and application, or carve a hole out in the memory map.
You can only write to flash cells which are erased, erasure is a relatively long process. For the 128K blocks this can be a few seconds, and will stall execution if the processor tries to run from flash. If you write requirements are small, it can often make sense to journal the writes across a block, ie add the new setting/value to the tail end of what's already written, and then scan through the values when you want to read the last, most current, value. And erase the block only if you consume all the available space. This will help reduce the wear on the cells, and minimize the limited erase cycles. It often make sense to write configuration/calibration data using a structure, and that has integrity checking. ie so you can confirm the data was completely written, and valid.2013-04-09 09:21 AM
Okay i see,
This gives me something to google, I will look in to this and try to make sense off it all....I guess there is no easy way for this than.Just for my vision now, could i take a 128kb sector and erase a small part of it?I have a dozen values or so that i wan't to write so if i make like an array and updateit partially would that be possible?And for the overall usage in my program, is there some info on storing a integer to flash?thanks2013-04-09 11:30 AM
128KB is the smallest erasable unit for a 128KB page.
Recommend you look at the examples in the firmware library, and read the programming manual (PM0081 ?) for the part. Once unlocked writing a 32-bit word goes like this. FLASHStatus = FLASH_ProgramWord(FlashAddr, FlashWord);2013-04-09 12:30 PM
Thanks Clive that helped me on my way!
I guess I can work with the delay by adding aplease wait while data is stored screen...I'm glad that it is starting to make some sense now.2013-04-10 03:10 AM
I have managed to write one parameter, but if i wan't to write more i get problems with
different retrieved values..[code]uint32_t FLASHStatus;void ProgramToFlash(){ SettingsArray[0] = SuctionSetpoint; SettingsArray[1] = DischargeSetpoint; SettingsArray[2] = FreezingSetpoint; SettingsArray[3] = CoolingSetpoint; SettingsArray[4] = FanLowSetpoint; SettingsArray[5] = FanHighSetpoint; SettingsArray[6] = DefrostFanSetpoint; SettingsArray[7] = CompressorOnDelay; SettingsArray[8] = CondensorOnDelay; SettingsArray[9] = LiquidOnDelay; /* Unlock the Flash to enable the flash control register access *************/ FLASH_Unlock(); /* Clear pending flags (if any) */ FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR); FLASH_EraseSector(FLASH_Sector_11, VoltageRange_3); int i; for(i=0;i<10;i++) { FLASHStatus = FLASH_ProgramWord(ADDR_FLASH_SECTOR_11 + (i*4), SettingsArray[i]); if (FLASHStatus != FLASH_COMPLETE)while(1); } /* Lock the Flash to disable the flash control register access (recommended to protect the FLASH memory against possible unwanted operation) *********/ FLASH_Lock(); }[/code][code]returned1 = (*(__IO uint32_t*) ADDR_FLASH_SECTOR_11);returned2 = (*(__IO uint32_t*) ADDR_FLASH_SECTOR_11 + 4);[/code]2013-04-10 03:26 AM
i get problems with different retrieved values..
Which are?2013-04-10 03:39 AM
I get the first value right that's 8
but if i try the second value i get 12 and i put 10 there
the third is 10 when it should be -3002013-04-10 03:43 AM
2013-04-10 04:13 AM
Ok, so you're reading the same value and adding different values to it, perhaps?
Try returned1 = *(__IO uint32_t*)(ADDR_FLASH_SECTOR_11); returned2 = *(__IO uint32_t*)( ADDR_FLASH_SECTOR_11 + 4); returned3 = *(__IO uint32_t*)( ADDR_FLASH_SECTOR_11 + 8); Better yet, dump out the content of your array, and the flash where they've been written, and let's inspect that.