2012-03-29 01:09 PM
I am putting together a little self-programming bootloader. It looks to me like you program two bytes at a time, by putting the address in to the FLASH_AR and setting bit 0 in the FLASH_CR register. The manual doesn't seem to tell you where to put the bytes to be programmed. I suppose it could be bits 25-10 in the FLASH_OBR as that says Data1 and Data 0.
If that is the case is Byte 1 the byte to go in the address in FLASH_CR+1 and Byte 0 the byte to go in FLASH_CR? Thanks!2012-03-29 01:15 PM
They are written AT the address you want to program
*(vu16*)Address = *Data++; Address += 2; Where Address is 0x08001000, for example2012-03-29 01:42 PM
Thanks, Clive. I'm missing something though. How are you setting Address in this case? Just setting Address = 0x800100 type of thing?
I don't understand part of this line of C either! *(vu16*)Address What is vu16? Looks like you're casting Address to it, but then it looks like this is some kind of double pointer thing going on. What are the two asterisks doing here? I thought I was getting reasonably good at C, but obviously not. ;~) Do you not use registers such as FLASH_AR?2012-03-29 01:54 PM
In this case Address is a 32-bit unsigned value.
vu16 is a volatile unsigned short, it's defined in stm32f10x.h The casting converts the 32-bit number into a pointer to a 16-bit value, and the leading asterisk writes to that. ie WORD[0x08001000] = 0x1234 Reviewing the library source/*******************************************************************************
* Function Name : FLASH_ProgramHalfWord
* Description : Programs a half word at a specified address.
* Input : - Address: specifies the address to be programmed.
* - Data: specifies the data to be programmed.
* Output : None
* Return : FLASH Status: The returned value can be: FLASH_BUSY,
* FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or
* FLASH_TIMEOUT.
*******************************************************************************/
FLASH_Status FLASH_ProgramHalfWord(u32 Address, u16 Data)
{
FLASH_Status status = FLASH_COMPLETE;
/* Check the parameters */
assert_param(IS_FLASH_ADDRESS(Address));
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(ProgramTimeout);
if(status == FLASH_COMPLETE)
{
/* if the previous operation is completed, proceed to program the new data */
FLASH->CR |= CR_PG_Set;
*(vu16*)Address = Data;
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(ProgramTimeout);
if(status != FLASH_BUSY)
{
/* if the program operation is completed, disable the PG Bit */
FLASH->CR &= CR_PG_Reset;
}
}
/* Return the Program Status */
return status;
}
One optimization trick is that you don't need to toggle the PG bit for each half word.
I've never seen FLASH_AR used in writing to flash, only the page erase, but I can see how the documentation may lead you to believe otherwise.
2012-03-29 03:14 PM
OK, thanks again, Clive. That makes sense. I don't use any of those header files, I just use the Crossworks ones apart from when I'm using FreeRTOS, but then I don't have to get involved with the low level files then.
The manual says this: Bits 31:0 FAR: Flash Address Chooses the address to program when programming is selected, or a page to erase when Page Erase is selected Which is why I assumed it needed to be used! Thanks again, I think I should be able to do it now.2012-03-29 06:43 PM
Better to download the Firmware library and include the Flash related .c and .h files in your project. When stuck, refer to the FLash programming/IAP example