| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- #include "board.h"
- #define FLASH_BYPASS do{M0P_FLASH->BYPASS = 0x5A5A;\
- M0P_FLASH->BYPASS = 0xA5A5; }while(0)
- // HC32L196
- // page Size:512bytes
- // total size:256Kbyes(512page)
- // space :0x08000000 ~ 0x0803FFFF
- void McuFlash_init(void)
- {
- rt_base_t level;
- level = rt_hw_interrupt_disable();
-
- #if defined(SYSCLK_4M_MODE)
- FLASH_BYPASS;
- M0P_FLASH->TNVS = 0x020u;
- FLASH_BYPASS;
- M0P_FLASH->TPGS = 0x017u;
- FLASH_BYPASS;
- M0P_FLASH->TPROG = 0x01Bu;
- FLASH_BYPASS;
- M0P_FLASH->TSERASE = 0x04650u;
- FLASH_BYPASS;
- M0P_FLASH->TMERASE = 0x0222E0u;
- FLASH_BYPASS;
- M0P_FLASH->TPRCV = 0x018u;
- FLASH_BYPASS;
- M0P_FLASH->TSRCV = 0x0F0u;
- FLASH_BYPASS;
- M0P_FLASH->TMRCV = 0x03E8u;
- #elif defined(SYSCLK_8M_MODE)
- FLASH_BYPASS;
- M0P_FLASH->TNVS = 0x040u;
- FLASH_BYPASS;
- M0P_FLASH->TPGS = 0x02Eu;
- FLASH_BYPASS;
- M0P_FLASH->TPROG = 0x036u;
- FLASH_BYPASS;
- M0P_FLASH->TSERASE = 0x08CA0u;
- FLASH_BYPASS;
- M0P_FLASH->TMERASE = 0x0445C0u;
- FLASH_BYPASS;
- M0P_FLASH->TPRCV = 0x030u;
- FLASH_BYPASS;
- M0P_FLASH->TSRCV = 0x1E0u;
- FLASH_BYPASS;
- M0P_FLASH->TMRCV = 0x07D0u;
- #elif defined(SYSCLK_16M_MODE)
- FLASH_BYPASS;
- M0P_FLASH->TNVS = 0x080u;
- FLASH_BYPASS;
- M0P_FLASH->TPGS = 0x05Cu;
- FLASH_BYPASS;
- M0P_FLASH->TPROG = 0x06Cu;
- FLASH_BYPASS;
- M0P_FLASH->TSERASE = 0x11940u;
- FLASH_BYPASS;
- M0P_FLASH->TMERASE = 0x088B80u;
- FLASH_BYPASS;
- M0P_FLASH->TPRCV = 0x060u;
- FLASH_BYPASS;
- M0P_FLASH->TSRCV = 0x3C0u;
- FLASH_BYPASS;
- M0P_FLASH->TMRCV = 0x0FA0u;
- #endif
- rt_hw_interrupt_enable(level);
- }
- void McuFlash_WaitBusy(void)
- {
- while(M0P_FLASH->CR_f.BUSY){
- // wait until not busy
- }
- }
- void McuFlash_Unlock(void)
- {
- rt_base_t level;
- level = rt_hw_interrupt_disable();
-
- FLASH_BYPASS;
- M0P_FLASH->SLOCK0 = 0xFFFFFFFF; // 0:forbid PE; 1:allow PE;
- FLASH_BYPASS;
- M0P_FLASH->SLOCK1 = 0xFFFFFFFF;
- FLASH_BYPASS;
- M0P_FLASH->SLOCK2 = 0xFFFFFFFF;
- FLASH_BYPASS;
- M0P_FLASH->SLOCK3 = 0xFFFFFFFF;
- rt_hw_interrupt_enable(level);
- }
- void McuFlash_Lock(void)
- {
- rt_base_t level;
- McuFlash_WaitBusy();
- level = rt_hw_interrupt_disable();
- FLASH_BYPASS;
- M0P_FLASH->SLOCK0 = 0x00000000; // 0:forbid PE; 1:allow PE;
- FLASH_BYPASS;
- M0P_FLASH->SLOCK1 = 0x00000000;
- FLASH_BYPASS;
- M0P_FLASH->SLOCK2 = 0x00000000;
- FLASH_BYPASS;
- M0P_FLASH->SLOCK3 = 0x00000000;
- rt_hw_interrupt_enable(level);
- }
- #ifndef BOOTLOADER_ENABLE
- void McuFlash_ErasePage(uint32_t addr)
- {
- rt_base_t level;
- McuFlash_WaitBusy();
- level = rt_hw_interrupt_disable();
- FLASH_BYPASS;
- M0P_FLASH->CR_f.OP = 0x2u; // 0:read; 1:probram; 2:sector rease; 3:chip erase
- *((volatile uint8_t *)addr) = 0xFFu; // start erase page
- rt_hw_interrupt_enable(level);
- }
- void McuFlash_WordPP(uint32_t addr, uint32_t data)
- {
- rt_base_t level;
- McuFlash_WaitBusy();
- level = rt_hw_interrupt_disable();
- FLASH_BYPASS;
- M0P_FLASH->CR_f.OP = 0x1u; // 0:read; 1:probram; 2:sector rease; 3:chip erase
- *((volatile uint32_t *)addr) = data; // start program
- rt_hw_interrupt_enable(level);
- }
- #endif
- void McuFlash_EraseSegment(uint32_t start, uint32_t len)
- {
- uint32_t end;
- // Page size = 512byts
- // total 512xPages
- end = start+len-1; // be sure start + len < 0xFFFFFFFFu - 0xFFu
- while(start<=end){
- McuFlash_ErasePage(start);
- start += 512;
- }
- }
- // prepare for word programming
- void McuFlash_OpenWP(uint32_t addr, McuFlash_WP_t *p)
- {
- p->addr = addr & ~0x3u; // must 4 bytes aligned
- p->idx = 0;
- }
- // program words from buffer
- void McuFlash_Buf2WP(uint8_t *buf, uint32_t len, McuFlash_WP_t *p)
- {
- while(len--){ // program size is 4 byte
- p->u.byte[p->idx] = *buf++;
- if (p->idx==3){
- p->idx = 0;
- McuFlash_WordPP(p->addr, p->u.word);
- p->addr += 4;
- } else {
- p->idx++;
- }
- }
- }
- // program last not enough gathered word if exists
- void McuFlash_CloseWP(McuFlash_WP_t *p)
- {
- if (p->idx!=0){
- while(p->idx<4){
- p->u.byte[p->idx] = 0xFFu;
- p->idx++;
- }
- p->idx = 0;
- McuFlash_WordPP(p->addr, p->u.word);
- p->addr += 4;
- }
- }
|