summaryrefslogtreecommitdiff
path: root/firmware/src/dfu/flash.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/src/dfu/flash.c')
-rw-r--r--firmware/src/dfu/flash.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/firmware/src/dfu/flash.c b/firmware/src/dfu/flash.c
index 1a40627..4d0c9d9 100644
--- a/firmware/src/dfu/flash.c
+++ b/firmware/src/dfu/flash.c
@@ -2,22 +2,23 @@
#include <lib_AT91SAM7.h>
#include <AT91SAM7.h>
#include <dfu/dbgu.h>
+#include <board.h>
-#define EFCS_CMD_WRITE_PAGE 0x01
-#define EFCS_CMD_SET_LOCK_BIT 0x02
-#define EFCS_CMD_WRITE_PAGE_LOCK 0x03
-#define EFCS_CMD_CLEAR_LOCK 0x04
-#define EFCS_CMD_ERASE_ALL 0x08
-#define EFCS_CMD_SET_NVM_BIT 0x0b
-#define EFCS_CMD_CLEAR_NVM_BIT 0x0d
-#define EFCS_CMD_SET_SECURITY_BIT 0x0f
+#define EFCS_CMD_WRITE_PAGE 0x1
+#define EFCS_CMD_SET_LOCK_BIT 0x2
+#define EFCS_CMD_WRITE_PAGE_LOCK 0x3
+#define EFCS_CMD_CLEAR_LOCK 0x4
+#define EFCS_CMD_ERASE_ALL 0x8
+#define EFCS_CMD_SET_NVM_BIT 0xb
+#define EFCS_CMD_CLEAR_NVM_BIT 0xd
+#define EFCS_CMD_SET_SECURITY_BIT 0xf
static u_int16_t page_from_ramaddr(const void *addr)
{
u_int32_t ramaddr = (u_int32_t) addr;
ramaddr -= (u_int32_t) AT91C_IFLASH;
- return (ramaddr >> AT91C_IFLASH_PAGE_SHIFT);
+ return ((ramaddr >> AT91C_IFLASH_PAGE_SHIFT));
}
#define PAGES_PER_LOCKREGION (AT91C_IFLASH_LOCK_REGION_SIZE>>AT91C_IFLASH_PAGE_SHIFT)
#define IS_FIRST_PAGE_OF_LOCKREGION(x) ((x % PAGES_PER_LOCKREGION) == 0)
@@ -32,13 +33,15 @@ static int is_page_locked(u_int16_t page)
static void unlock_page(u_int16_t page)
{
+ page &= 0x3ff;
AT91F_MC_EFC_PerformCmd(AT91C_BASE_MC, AT91C_MC_FCMD_UNLOCK |
- AT91C_MC_CORRECT_KEY | page);
+ AT91C_MC_CORRECT_KEY | (page << 8));
}
void flash_page(u_int8_t *addr)
{
- u_int16_t page = page_from_ramaddr(addr);
+ u_int16_t page = page_from_ramaddr(addr) & 0x3ff;
+ u_int32_t fsr = AT91F_MC_EFC_GetStatus(AT91C_BASE_MC);
DEBUGP("flash_page(0x%x=%u) ", addr, page);
if (is_page_locked(page)) {
@@ -46,9 +49,23 @@ void flash_page(u_int8_t *addr)
unlock_page(page);
}
+ if (!(fsr & AT91C_MC_FRDY)) {
+ DEBUGP("NOT_FLASHING ");
+ return;
+ }
+
DEBUGP("performing start_prog ");
+#if 1
AT91F_MC_EFC_PerformCmd(AT91C_BASE_MC, AT91C_MC_FCMD_START_PROG |
- AT91C_MC_CORRECT_KEY | page);
+ AT91C_MC_CORRECT_KEY | (page << 8));
+#endif
}
+void flash_init(void)
+{
+ unsigned int fmcn = AT91F_MC_EFC_ComputeFMCN(MCK);
+ AT91F_MC_EFC_CfgModeReg(AT91C_BASE_MC, fmcn << 16 | AT91C_MC_FWS_3FWS |
+ AT91C_MC_FRDY | AT91C_MC_LOCKE |
+ AT91C_MC_PROGE);
+}
personal git repositories of Harald Welte. Your mileage may vary