*This content has been reposted with the approval of the original author.
Preface
I Recently got a piece of APM32F103VC MINI development board and found that it has a very rich peripheral resources, the main frequency can reach 96Mhz after a period of study. Recently, the IAP (In Application Programming) function has been used in the project, so we evaluate the IAP implementation of APM32F103.
In-Application Programming (IAP) is a programming mode applied to Flash program memory. It can read/write to another program Flash space by calling a specific IAP program under the normal operation of the application, and can even control the read/write operation of a segment, a page or even a byte, which brings greater flexibility to the field upgrade of data storage and firmware.
Then, we mentioned that the program jump run is to modify the PC pointer to our APP program, and then modify our interrupt vector register so that our APP program can correctly interrupt.
In this chapter, we will review the basics of Flash programming in the third part of IAP implementation.
1 Why program Flash?
As we all know, the Flash of MCU saves our program. In general, we program the Flash of MCU through our recorder or simulator when we produce or debug. In this process, we do not need to pay attention to the programming process of Flash, and only need to complete the programming operation of Flash through tools.
Why do IAP need to care about Flash programming? Because a key factor of IAP is able to program the content of our APP area through BootLoader.
Namely, we need to implement Flash MCU programming operations.
2 Flash programming process
In the manual of APM32F103, we can see that Flash programming is divided into four steps: unlocking, erasing, programming and locking. Next we take a step by step look at what we need to do.
2.1 Flash Unlock and Lock
Flash is the place where our program is stored, and the need to program FLash must be “certain”, not “temporary”. So it involves more cumbersome “unlock” steps in case our important program content is changed.
The standard library functions for APM32F1 are as follows:
/*!
- @brief Unlocks the FMC Program Erase Controller
*
*
*/
void FMC_Unlock(void)
{
FMC->KEY = 0×45670123;
FMC->KEY = 0xCDEF89AB;
}
/*!
- @brief Locks the FMC Program Erase Controller.
*
*
*/
void FMC_Lock(void)
{
FMC-
}
2.2 Flash erasure
Due to the Flash features of APM32F1, address content written by Flash data must be 0xFFFF. For example, we want to draw a wonderful picture on a piece of paper, then our paper must be blank, so as not to be affected by paper stains on us.
That for APM32F1 Flash, 0xFFFF is “blank”, this state we can enjoy “writing”.
The Flash erase operation is to turn Flash back to “blank”.
Erase is divided into “total erase” and “page erase”. If we use the “total erase”, our BootLoader program will also be erased because our BootLoader is also stored in Flash, making the MCU “blank”. Therefore, we will use “page erase” to complete the erase operation of the APP storage area.
The standard library functions for APM32F1 are as follows:
/*!
- @brief Erases a specified FMC page.
*
- @param pageAddr: The page address to be erased.
*
*/
FMC_STATUS_T FMC_ErasePage(uint32_t pageAddr)
{
FMC_STATUS_T status = FMC_STATUS_COMPLETE;
status = FMC_WaitForLastOperation(0×000B0000);
if(status == FMC_STATUS_COMPLETE)
{
FMC->CTRL2_B.PAGEERA = BIT_SET;
FMC->ADDR = pageAddr;
FMC->CTRL2_B.STA = BIT_SET;
status = FMC_WaitForLastOperation(0×000B0000);
FMC->CTRL2_B.PAGEERA = BIT_RESET;
}
return status;
}
/*!
- @brief Erases all FMC pages.
*
*
*/
FMC_STATUS_T FMC_EraseAllPage(void)
{
FMC_STATUS_T status = FMC_STATUS_COMPLETE;
status = FMC_WaitForLastOperation(0×000B0000);
if(status == FMC_STATUS_COMPLETE)
{
FMC->CTRL2_B.MASSERA = BIT_SET;
FMC->CTRL2_B.STA = BIT_SET;
status = FMC_WaitForLastOperation(0×000B0000);
FMC->CTRL2_B.MASSERA = BIT_RESET;
}
return status;
}
2.3 Flash programming
Once we have erased the target area above, we are ready to program Flash.
The standard library functions of APM32F1 provide us with word programming and half word programming operations.
/*!
- @brief Programs a word at a specified address.
*
- @param address:the address to be programmed.
*
- @param data: the data to be programmed.
*
*/
FMC_STATUS_T FMC_ProgramWord(uint32_t address, uint32_t data)
{
FMC_STATUS_T status = FMC_STATUS_COMPLETE;
__IOM uint32_t temp = 0;
#ifdef APM32F10X_HD
__set_PRIMASK(1);
#endif
status = FMC_WaitForLastOperation(0×000B0000);
if(status == FMC_STATUS_COMPLETE)
{
FMC->CTRL2_B.PG = BIT_SET;
*(__IOM uint16_t *)address = data;
status = FMC_WaitForLastOperation(0×000B0000);
if(status == FMC_STATUS_COMPLETE)
{
temp = address + 2;
(__IOM uint16_t) temp = data >> 16;
status = FMC_WaitForLastOperation(0×000B0000);
FMC->CTRL2_B.PG = BIT_RESET;
}
else
{
FMC->CTRL2_B.PG = BIT_RESET;
}
}
#ifdef APM32F10X_HD
__set_PRIMASK(0);
#endif
return status;
}
/*!
- @brief Programs a half word at a specified address.
*
- @param address:the address to be programmed.
*
- @param data: the data to be programmed.
*
*/
FMC_STATUS_T FMC_ProgramHalfWord(uint32_t address, uint16_t data)
{
FMC_STATUS_T status = FMC_STATUS_COMPLETE;
#ifdef APM32F10X_HD
__set_PRIMASK(1);
#endif
status = FMC_WaitForLastOperation(0×000B0000);
if(status == FMC_STATUS_COMPLETE)
{
FMC->CTRL2_B.PG = BIT_SET;
*(__IOM uint16_t *)address = data;
status = FMC_WaitForLastOperation(0×000B0000);
FMC->CTRL2_B.PG = BIT_RESET;
}
#ifdef APM32F10X_HD
__set_PRIMASK(0);
#endif
return status;
}
3 Flash read
After completing the Flash programming of the target area, we generally need to check whether the actual content we write to Flash is consistent with our expected content.
We can check through direct reading and comparsion or CRC check. There are various methods of verification, but they are inseparable from Flash reading. Flash APM32F1 read is relatively simple, which you can directly use the address pointer to read the contents of the corresponding address directly.
data = *(__IOM uint16_t *)address;
data = *(__IOM uint32_t *)address;