Flash 접근 함수들을 복원한다. STM32F1 레퍼런스 매뉴얼 보면서.


flash.h

#ifndef FLASH_H
#define FLASH_H

#include "stm32f1xx.h"

#define FLASH_KEY1      0x45670123
#define FLASH_KEY2      0xCDEF89AB

#define BUFFER_ADDR     0x08004000
#define APP_ADDR        0x08042800

void Flash_Unlock(void);
void Flash_Lock(void);
void Flash_ErasePage(uint32_t addr);
void Flash_WriteHalfWord(uint32_t addr, uint16_t data);
void Flash_WritePage(uint32_t page, uint8_t *data);

#endif

Flash_Unlock / Lock

void Flash_Unlock(void) {
    if (FLASH->CR & FLASH_CR_LOCK) {
        FLASH->KEYR = FLASH_KEY1;
        FLASH->KEYR = FLASH_KEY2;
    }
}

void Flash_Lock(void) {
    FLASH->CR |= FLASH_CR_LOCK;
}

키 순서 중요하다. 틀리면 락 안 풀림.


Flash_ErasePage

void Flash_ErasePage(uint32_t addr) {
    // BSY 대기
    while (FLASH->SR & FLASH_SR_BSY);
    
    // 페이지 삭제 설정
    FLASH->CR |= FLASH_CR_PER;
    FLASH->AR = addr;
    FLASH->CR |= FLASH_CR_STRT;
    
    // 완료 대기
    while (FLASH->SR & FLASH_SR_BSY);
    
    // PER 클리어
    FLASH->CR &= ~FLASH_CR_PER;
}

Flash_WriteHalfWord

void Flash_WriteHalfWord(uint32_t addr, uint16_t data) {
    while (FLASH->SR & FLASH_SR_BSY);
    
    FLASH->CR |= FLASH_CR_PG;
    
    *(volatile uint16_t *)addr = data;
    
    while (FLASH->SR & FLASH_SR_BSY);
    
    FLASH->CR &= ~FLASH_CR_PG;
}

16비트 단위로만 쓸 수 있다.


Flash_WritePage

void Flash_WritePage(uint32_t page, uint8_t *data) {
    uint32_t addr = BUFFER_ADDR + page * 2048;
    
    Flash_Unlock();
    Flash_ErasePage(addr);
    
    for (int i = 0; i < 2048; i += 2) {
        uint16_t halfword = data[i] | (data[i + 1] << 8);
        Flash_WriteHalfWord(addr + i, halfword);
    }
    
    Flash_Lock();
}

에러 체크 추가

원본엔 없었지만 안전하게:

uint8_t Flash_ErasePage_Safe(uint32_t addr) {
    Flash_ErasePage(addr);
    
    // EOP 체크
    if (FLASH->SR & FLASH_SR_EOP) {
        FLASH->SR = FLASH_SR_EOP;  // 클리어
        return 0;  // 성공
    }
    
    return 1;  // 실패
}

다음 글에서 빌드하고 원본이랑 비교.

#30 - 빌드 및 비교