Initial commit
[kk_librfid.git] / firmware / src / os / .svn / text-base / flash.c.svn-base
blobc729ff8b44f301cd1b2e8ad677a301b4467e4413
1 #include <sys/types.h>
2 #include <lib_AT91SAM7.h>
3 #include <AT91SAM7.h>
4 #include <dfu/dbgu.h>
5 #include <board.h>
7 #define EFCS_CMD_WRITE_PAGE             0x1
8 #define EFCS_CMD_SET_LOCK_BIT           0x2
9 #define EFCS_CMD_WRITE_PAGE_LOCK        0x3
10 #define EFCS_CMD_CLEAR_LOCK             0x4
11 #define EFCS_CMD_ERASE_ALL              0x8
12 #define EFCS_CMD_SET_NVM_BIT            0xb
13 #define EFCS_CMD_CLEAR_NVM_BIT          0xd
14 #define EFCS_CMD_SET_SECURITY_BIT       0xf
16 static u_int16_t page_from_ramaddr(const void *addr)
18         u_int32_t ramaddr = (u_int32_t) addr;
19         ramaddr -= (u_int32_t) AT91C_IFLASH;
20         return ((ramaddr >> AT91C_IFLASH_PAGE_SHIFT));
22 #define PAGES_PER_LOCKREGION    (AT91C_IFLASH_LOCK_REGION_SIZE>>AT91C_IFLASH_PAGE_SHIFT)
23 #define IS_FIRST_PAGE_OF_LOCKREGION(x)  ((x % PAGES_PER_LOCKREGION) == 0)
24 #define LOCKREGION_FROM_PAGE(x) (x / PAGES_PER_LOCKREGION)
26 static int is_page_locked(u_int16_t page)
28         u_int16_t lockregion = LOCKREGION_FROM_PAGE(page);
30         return (AT91C_BASE_MC->MC_FSR & (lockregion << 16));
33 static void unlock_page(u_int16_t page)
35         page &= 0x3ff;
36         AT91F_MC_EFC_PerformCmd(AT91C_BASE_MC, AT91C_MC_FCMD_UNLOCK |
37                                 AT91C_MC_CORRECT_KEY | (page << 8));
40 void flash_page(u_int8_t *addr)
42         u_int16_t page = page_from_ramaddr(addr) & 0x3ff;
43         u_int32_t fsr = AT91F_MC_EFC_GetStatus(AT91C_BASE_MC);
44         DEBUGP("flash_page(0x%x=%u) ", addr, page);
46         if (is_page_locked(page)) {
47                 DEBUGP("unlocking ");
48                 unlock_page(page);
49         }
51         if (!(fsr & AT91C_MC_FRDY)) {
52                 DEBUGP("NOT_FLASHING ");                
53                 return;
54         }
56         DEBUGP("performing start_prog ");
58         AT91F_MC_EFC_PerformCmd(AT91C_BASE_MC, AT91C_MC_FCMD_START_PROG |
59                                 AT91C_MC_CORRECT_KEY | (page << 8));
62 void flash_init(void)
64         unsigned int fmcn = AT91F_MC_EFC_ComputeFMCN(MCK);
66         AT91F_MC_EFC_CfgModeReg(AT91C_BASE_MC, (fmcn&0xff) << 16 | 
67                                 AT91C_MC_FWS_3FWS);