📄 flash.c
字号:
#include "flash.h"
#include "AT91RM9200.h"
typedef volatile unsigned short * PReg;
// SMC register definition
#define FLASH_SMC_NWS (0x8 << 0)
#define FLASH_SMC_WSEN (0x1 << 7)
#define FLASH_SMC_TDF (0x4 << 8)
#define FLASH_SMC_BAT (0x1 << 12)
#define FLASH_SMC_DBW (0x1 << 13)
#define FLASH_SMC_DRP (0x0 << 15)
#define FLASH_SMC_ACCS (0x0 << 16)
#define FLASH_SMC_RWSETUP (0x0 << 24)
#define FLASH_SMC_RWHOLD (0x0 << 28)
// Status register bit definition
#define FLASH_WSM_READY_BIT (0x1 << 7)
#define FLASH_ERASE_SUSPEND_BIT (0x1 << 6)
#define FLASH_ERASE_CLRLOCK_BIT (0x1 << 5)
#define FLASH_PROG_SETLOCK_BIT (0x1 << 4)
#define FLASH_PROG_VOLTAGE_BIT (0x1 << 3)
#define FLASH_PROG_SUSPEND_BIT (0x1 << 2)
#define FLASH_DEV_PROTECT_BIT (0x1 << 1)
// Extended status register bit definition
#define FLASH_BUFFER_AVAILBLE_BIT (0x1 << 7)
// Constant definition
#define FLASH_BASE_ADD (0x10000000)
#define FLASH_BLK_ADD_MASK (0xFFFF0000)
// Commands Definition
#define FLASH_READ_ARRAY(); *((PReg)FLASH_BASE_ADD) = 0xFF;
#define FLASH_READ_ID(ID); *((PReg)FLASH_BASE_ADD) = 0x90; (ID) = *((PReg)0x0000001A);
#define FLASH_READ_STATUS(STATE); *((PReg)FLASH_BASE_ADD) = 0x70; while(!(*((PReg)FLASH_BASE_ADD) & FLASH_WSM_READY_BIT)); (STATE) = *((PReg)FLASH_BASE_ADD);
#define FLASH_CLR_STATUS(); *((PReg)FLASH_BASE_ADD) = 0x50;
#define FLASH_SET_LOCK_BIT(ADD); *((PReg)((ADD) & FLASH_BLK_ADD_MASK)) = 0x60; *((PReg)((ADD) & FLASH_BLK_ADD_MASK)) = 0x01;
#define FLASH_CLR_LOCK_BIT(ADD); *((PReg)((ADD) & FLASH_BLK_ADD_MASK)) = 0x60; *((PReg)((ADD) & FLASH_BLK_ADD_MASK)) = 0xD0;
#define FLASH_BLK_ERASE(ADD); *((PReg)((ADD) & FLASH_BLK_ADD_MASK)) = 0x20; *((PReg)((ADD) & FLASH_BLK_ADD_MASK)) = 0xD0;
#define FLASH_SETUP_BUFFER(ADD); *((PReg)(ADD)) = 0xE8;
#define FLASH_SETUP_WRITE(ADD, NUM); *((PReg)(ADD)) = (NUM);
#define FLASH_WRITE_CONFIRM(ADD); *((PReg)(ADD)) = 0xD0);
#define FLASH_PROG_WORD(ADD, WORD) *((PReg)(ADD)) = 0x10); *((PReg)(ADD)) = WORD);
uint8 FlashOpen(void) {
AT91C_BASE_EBI->EBI_CSA &= (~AT91C_EBI_CS0A_BFC);
AT91C_BASE_EBI->EBI_CFGR = AT91C_EBI_DBPUC;
AT91C_BASE_SMC->SMC_CSR[0] = (FLASH_SMC_NWS | FLASH_SMC_WSEN | FLASH_SMC_TDF | FLASH_SMC_BAT | FLASH_SMC_DBW | FLASH_SMC_DRP | FLASH_SMC_ACCS | FLASH_SMC_RWSETUP | FLASH_SMC_RWHOLD);
}
uint8 FlashClose(void) {
AT91C_BASE_SMC->SMC_CSR[0] = 0x00;
}
uint8 FlashGetID(void) {
uint8 id;
FLASH_READ_ID(id);
return (id);
}
uint8 FlashErase(uint32 add) {
CpuSr sr;
uint16 state;
SpinLock(sr);
FLASH_BLK_ERASE(add);
FLASH_READ_STATUS(state);
FLASH_CLR_STATUS();
FLASH_READ_ARRAY();
SpinUnLock(sr);
}
uint8 FlashLock(uint32 add) {
CpuSr sr;
uint16 state;
SpinLock(sr);
FLASH_SET_LOCK_BIT(add);
FLASH_READ_STATUS(state);
FLASH_CLR_STATUS();
FLASH_READ_ARRAY();
SpinUnLock(sr);
}
uint8 FlashUnLock(uint32 add) {
CpuSr sr;
uint16 state;
SpinLock(sr);
FLASH_CLR_LOCK_BIT(add);
FLASH_READ_STATUS(state);
FLASH_CLR_STATUS();
FLASH_READ_ARRAY();
SpinUnLock(sr);
}
uint8 FlashWriteBuffer(uint32 add, int32 num, char * data) {
CpuSr sr;
uint16 idx, state, cnt;
while(num > 0) {
SpinLock(sr);
FLASH_SETUP_BUFFER(add);
if((*(PReg)(add & FLASH_BLK_ADD_MASK) & FLASH_BUFFER_AVAILBLE_BIT) == 0) {
FLASH_READ_ARRAY();
SpinUnLock(sr);
return FLASH_BUSY;
}
idx = (num >= 16 ? 16 : ((num & 1) + (num >> 1)));
FLASH_SETUP_WRITE(add, idx);
do {
idx -= 1;
*(PReg)(add) = *(PReg)data;
add += 2;
data += 2;
} while(idx > 0);
FLASH_WRITE_CONFIRM(add);
FLASH_READ_STATUS(state);
FLASH_CLR_STATUS();
FLASH_READ_ARRAY();
SpinUnLock(sr);
if(state & FLASH_DEV_PROTECT_BIT) {
return FLASH_LOCKED;
}
num -= 16;
}
return FLASH_NO_ERR;
}
uint8 FlashProgram(uint32 add, uint16 word) {
CpuSr sr;
uint16 state;
SpinLock(sr);
FLASH_PROG_WORD(add, word);
FLASH_READ_STATUS(state);
FLASH_CLR_STATUS();
FLASH_READ_ARRAY();
SpinUnLock(sr);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -