2015-02-23 03:25 AM
I am making a stand-alone SWD programmer for STM32F1 and L1 families, based on STM32F103. For that I have used AN0062 ''
Programming Internal Flash
Over the Serial Wire Debug
Interface
'' by Silicon Labs. Everything works fine and the final touch I need to implement is the ability to re-program read-protected targets. However, the procedure to lower the Read Protection (RDP) from Level 1 to Level 0, described in the Reference Manual for STM32F1/L1 requires to read and write into Flash controller registers inside the target, that is prohibited by the Read Protection itself. Does anybody knows a correct way to set the RDP to Level0 by means of an external custom SWD programmer? Thanks! #rdp #swd2015-02-23 04:12 AM
Unlock RDP:
1. unlock flash 2. unlock option bytes 3. erase option bytes 4. write new read out protection value 5. reset (or for some systems: relaunch option bytes (with implicit reset)) 6. program flash [FLASH, RCC, PWR, ... are readable and writeable. With RDP, too]2015-02-23 09:16 PM
Thanks for response, damh!
I just have tried it, with no success. As soon I start to unlock the Flash, i.e. read the FLASH->PECR register: flash_PECR = readMem(FLASH_PECR_ADDR); where uint32_t readMem(uint32_t addr) { uint32_t ret; writeAP(AP_TAR, addr); readAP(AP_DRW, &ret); readDP(DP_RDBUFF, &ret); return ret; } and #define FLASH_PECR_ADDR 0x40023C04 i get the FAULT ack by SWD at the first writeAP(AP_TAR, addr); inside readMem(). Also, I have tried to write to the FLASH_PEKEYR_ADDR immediately without reading anything from the Flash controller inside the target. Also without success - the first use of writeAP(AP_TAR, addr); causes the SWD's FAULT ack. Some other things I did unsuccessfully try too: . read (or write) OB_RDP_ADDR . read FLASH_OBR_ADDR . read RAM (0x20000000) At the same time, the ST-LINK Utility removes the RDP on my target without a hitch. Am I doing something wrong? Thanks in advance!2015-02-23 09:53 PM
hmm :\
you can try to write a small program to run from RAM. Can you read/write the RAM?2015-02-24 03:04 AM
Sorry for misinformation.
It was my error. I forgot to clear SWD's error sticky bit after getting the first FAULT ack from a read-protected target. After clearing the sticky bit I got the access to the Flash controller registers on the target. (BTW, the target is STM32F107/) However, now I can't remove the Read Protection. Writing the RDP_Key (0x00A5) goes without errors, but after target's power-reseting the RDP is still enabled. The code is: FLASH_Status flashEraseAllOptionBytes(void) { FLASH_Status status = FLASH_COMPLETE; status = flashWaitForLastOperation(EraseTimeout); if(status == FLASH_COMPLETE) { // Authorize the small information block programming // FLASH->OPTKEYR = FLASH_KEY1; // FLASH->OPTKEYR = FLASH_KEY2; writeMem((uint32_t)&(FLASH->OPTKEYR), FLASH_KEY1); writeMem((uint32_t)&(FLASH->OPTKEYR), FLASH_KEY2); uint32_t flash_CR; // if the previous operation is completed, proceed to erase the option bytes // FLASH->CR |= CR_OPTER_Set; // FLASH->CR |= CR_STRT_Set; flash_CR = readMem((uint32_t)&(FLASH->CR)); flash_CR |= CR_OPTER_Set; writeMem((uint32_t)&(FLASH->CR), flash_CR); flash_CR |= CR_STRT_Set; writeMem((uint32_t)&(FLASH->CR), flash_CR); status = flashWaitForLastOperation(EraseTimeout); // Disable the OPTER Bit // FLASH->CR &= CR_OPTER_Reset; flash_CR = readMem((uint32_t)&(FLASH->CR)); flash_CR &= CR_OPTER_Reset; writeMem((uint32_t)&(FLASH->CR), flash_CR); // Enable the Option Bytes Programming operation // FLASH->CR |= CR_OPTPG_Set; flash_CR = readMem((uint32_t)&(FLASH->CR)); flash_CR |= CR_OPTPG_Set; writeMem((uint32_t)&(FLASH->CR), flash_CR); // Disable Read Protection // OB->RDP = 0x00; writeAP(AP_CSW, AP_CSW_DEFAULT_16); // as STM32F1's FPEC works in 16-bit mode, switch to AHB-AP size to 16-bit // writeMem((uint32_t)&(OB->RDP), RDP_Key); writeMem(0x1FFFF800, 0x00A5); writeAP(AP_CSW, AP_CSW_DEFAULT); // switch to AHB-AP size back to 32-bit status = flashWaitForLastOperation(EraseTimeout); flash_CR = readMem((uint32_t)&(FLASH->CR)); flash_CR &= CR_OPTPG_Reset; writeMem((uint32_t)&(FLASH->CR), flash_CR); } return status; } Just in case, I also tried writing RDP_key = 0x5AA5, without success. Will try to remove RDP on an STM32L1 in meanwhile... Thanks for your time!2015-02-24 04:03 AM
You miss Step#1
2015-02-24 04:09 AM
Sorry again for posting too fast without checking manuals. :)
All I had to do was to unlock the FPEC itself before starting to work with the Option Byte Register. static void flashUnlock(void) { writeMem((uint32_t)&(FLASH->KEYR), FLASH_KEY1); writeMem((uint32_t)&(FLASH->KEYR), FLASH_KEY2); } Thanks again for your support!2018-07-14 07:59 PM
Hi。From the <PM0075 Programming manual> , P15,Mass Erase as below code is successful 。Now,I want to Main Flash memory programming , but I don't how to do it . Help me.....
Thanks!
FLASH_Status flashEraseAllOptionBytes_STM32(void)
{ FLASH_Status status = FLASH_COMPLETE; uint32_t flash_CR,flash_SR; flash_CR = readMem((uint32_t)&(FLASH->CR)); flash_CR |= CR_MER_Set; writeMem((uint32_t)&(FLASH->CR), flash_CR);flash_CR |= CR_STRT_Set;
writeMem((uint32_t)&(FLASH->CR), flash_CR);status = FLASH_WaitForLastOperation(((uint32_t)0x000B0000));
return 0x09;
}