I was reading up on the flash eeprom and best I can tell for the stm32f chips this is needed. micromouseusa.com/
Has Keil mdk5 not provided a simple function?
Difficult is a relative term. It sadly depends on experience. Flashing anything out side a tool will be difficult for us. In this case even more so because there are not specific chip examples.
SO, apparently that is the case. We specifically budgeted for eeprom. Somehow this was over looked. Now emulation is our only option. It is hard enough to write code with a eeporm viewer and eeprom read and write commands, no we really have work cut out.
So I see the only option is to dedicate a section of code for an eeprom effect. This will certainly work but I'm going to need a good write up to understand this. Processor stalls are fine, we only need to write a few bytes to tell the device how to operate. The plan is to send a USB control transfer to a report ID and tell the chip write bytes here. Then the device can read these values on boot up to know what to do. The problem will be the understanding; Where can I write safely, how can I write, how can I read. The max I would need is 16 bytes.
I would avoid the EEPROM Emulation completely if all you want to do is save a configuration structure.
Pick one (or two) of the early 16KB sectors (@ 0x08004000, 0x08008000 or 0x0800C000), and then journal the writing of your structure across this space, selecting the last one written, and writing the new/changed one beyond the current.
Reading, it's in the address space, so create a structure pointer to the base of the sector and index into them. Have the first word of your structure be a signature, ie not 0xFFFFFFFF and the last word a CRC or checksum to prove/confirm validity.
Simplified method,
typedef struct _CONFIG { uint32_t Signature; // 0x12345678 ? // .. other neat stuff uint32_t Checksum; } CONFIG; CONFIG *config = (CONFIG *)0x08004000; // Config FLASH Sector Base CONFIG curr; const CONFIG default = { 0 }; // Add int i; i = 0; while(config[i+1].Signature != 0xFFFFFFFF) // Index to last i++; if (config[i].Signature == 0xFFFFFFFF) // Empty case { puts("Config Empty, using defaults"); memcpy(&curr, &default, sizeof(CONFIG)); } else { // Check signature and checksum puts("Loading Config"); memcpy(&curr, &config[i], sizeof(CONFIG)); // .. } // ... // Writing next block if (config[i].Signature != 0xFFFFFFFF) // Advance to blank i++; curr.Signature = 0x12345678; // Checksum new configuration, then write to FLASH curr.Checksum = CRC32(0xFFFFFFFF, &curr, sizeof(CONFIG) - 4); FLASH_WriteBlock((uint32_t)&config[i], &curr, sizeof(CONFIG)); // Addr, Buffer, Size
That's not really "avoiding EEPROM emulation completely". That is, for all practical intents and purposes, EEPROM emulation (although a somewhat coarse one).
It does avoid pretending it is EEPROM and treats it like FLASH, so it does dispense with a rather thick abstraction from ST with an Adddress/Byte storage system that immediately reduces the available space by at least a quarter.
The problem with pretending is that you keep doing things which are inappropriate rather than change the paradigm to a more appropriate one. ie a FLASH within the MPU address space, vs a I2C EEPROM
Where is FLASH_writeBlock ?
I could not find an include to support this function. I tried a few other write methods.
1. Example from eeprom emulation reads but does not write. 2. STM32F2 Standard Peripheral bibliotheek same.
example
if(HAL_FLASH_Unlock()!=HAL_OK) //return ok. FLASH_PageErase(0x0800c000); FLASH->CR = 0;//known bug that apparent is not documented.
if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, 0x0800c000, 0x01010101) != HAL_OK) //error
HAL_FLASH_Lock();
I wrote the pseudo code off the top of my head in minutes.
FLASH_WriteBlock() is an abstraction for the code that manages the processor interaction with flash, figure it is a Flash aware memcpy()