[U-Boot] [PATCH 5/6] AVR32: Support for writing to internal flash on at32uc3

Gunnar Rangoy gunnar at rangoy.com
Thu Nov 13 16:25:11 CET 2008


This patch enables writing (the environment) to the internal flash in
the microcontroller.

Signed-off-by: Gunnar Rangoy <gunnar at rangoy.com>
Signed-off-by: Paul Driveklepp <pauldriveklepp at gmail.com>
Signed-off-by: Olav Morken <olavmrk at gmail.com>
---
 cpu/at32uc/flashc.c         |   69 +++++++++++++++++++++++++++++++++++++++++--
 cpu/at32uc/flashc.h         |   17 ++++++++++
 include/configs/atevk1100.h |    2 +-
 3 files changed, 84 insertions(+), 4 deletions(-)

diff --git a/cpu/at32uc/flashc.c b/cpu/at32uc/flashc.c
index f33a4bb..e626e1f 100644
--- a/cpu/at32uc/flashc.c
+++ b/cpu/at32uc/flashc.c
@@ -45,6 +45,7 @@ unsigned long flash_init(void)
 {
 	unsigned long fsz;
 	unsigned long size;
+	unsigned int i;
 
 	fsz = FLASHC_BFEXT(FSZ, flashc_readl(FSR));
 
@@ -55,6 +56,10 @@ unsigned long flash_init(void)
 	/* Currently, all interflash have pages which are 128 words. */
 	flash_info[0].sector_count = size / (128*4);
 
+	for(i=0; i<flash_info[0].sector_count; i++){
+		flash_info[0].start[i] = i*128*4 + CFG_FLASH_BASE;
+	}
+
 	return size;
 }
 
@@ -62,19 +67,77 @@ void flash_print_info(flash_info_t *info)
 {
 	printf("Flash: Vendor ID: 0x%02lx, Product ID: 0x%02lx\n",
 	       info->flash_id >> 16, info->flash_id & 0xffff);
-	printf("Size: %ld MB in %d sectors\n",
+	printf("Size: %ld kB in %d sectors\n",
 	       info->size >> 10, info->sector_count);
 }
 
+static void flash_wait_ready(void)
+{
+	while(! flashc_readl(FSR) & FLASHC_BIT(FRDY) );
+}
+
 int flash_erase(flash_info_t *info, int s_first, int s_last)
 {
-	/* TODO */
+	int page;
+
+	for(page=s_first;page<s_last; page++){
+		flash_wait_ready();
+		flashc_writel(
+			FCMD,FLASHC_BF(CMD, FLASHC_EP)
+			|FLASHC_BF(PAGEN, page)
+			|FLASHC_BF(KEY, 0xa5));
+	}
 	return ERR_OK;
 }
 
+static void write_flash_page(unsigned int pagen, const u32 *data)
+{
+	unsigned int i;
+	u32 *dst;
+
+	dst = (u32 *) CFG_FLASH_BASE;
+
+	/* clear page buffer */
+	flash_wait_ready();
+	flashc_writel(FCMD,
+		FLASHC_BF(CMD, FLASHC_CPB) |
+		FLASHC_BF(KEY, 0xa5));
+
+	/* fill page buffer*/
+	flash_wait_ready();
+	for(i=0; i<128; i++){
+		dst[i]=data[i];
+	}
+
+	/* issue write command */
+	flashc_writel(FCMD,
+		FLASHC_BF(CMD, FLASHC_WP)|
+		FLASHC_BF(PAGEN, pagen)|
+		FLASHC_BF(KEY, 0xa5));
+}
+
 int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong count)
 {
-	/* TODO */
+	unsigned int i;
+
+	if (addr % (4*128)) {
+		printf("flash: write_buff(): ERROR, addr(0x%08lx) not "
+			"on page boundary", addr);
+		return ERR_ALIGN;
+	}
+	if (count % (4*128)) {
+		printf("flash: write_buff(): ERROR, count(0x%lu) not "
+			"a multiple of pagesize", count);
+		return ERR_ALIGN;
+	}
+
+	for (i = 0; i < count; i += 128*4) {
+		unsigned int pagen;
+		pagen = (addr-CFG_FLASH_BASE+i) / (128*4);
+		write_flash_page(pagen, (u32*) (src+i));
+	}
+
+
 	return ERR_OK;
 }
 
diff --git a/cpu/at32uc/flashc.h b/cpu/at32uc/flashc.h
index 23618bc..3e97781 100644
--- a/cpu/at32uc/flashc.h
+++ b/cpu/at32uc/flashc.h
@@ -43,6 +43,23 @@
 #define FLASHC_LOCK_OFFSET			16
 #define FLASHC_LOCK_SIZE			16
 
+#define FLASHC_NOP 	0 /*No operation*/
+#define FLASHC_WP 	1 /*Write Page*/
+#define FLASHC_EP	2 /*Erase Page*/
+#define FLASHC_CPB 	3 /*Clear Page Buffer*/
+#define FLASHC_LP 	4 /*Lock region containing given Page*/
+#define FLASHC_UP 	5 /*Unlock region containing given Page*/
+#define FLASHC_EA 	6 /*Erase All*/
+#define FLASHC_WGPB	7 /*Write General-Purpose Fuse Bit*/
+#define FLASHC_EGPB 	8 /*Erase General-Purpose Fuse Bit*/
+#define FLASHC_SSB 	9 /*Set Security Bit*/
+#define FLASHC_PGPFB 	10 /*Program GP Fuse Byte*/
+#define FLASHC_EAGPF 	11 /*Erase All GPFuses*/
+#define FLASHC_QPR 	12 /*Quick Page Read*/
+#define FLASHC_WUP	13 /*Write User Page*/
+#define FLASHC_EUP	14 /*Erase User Page*/
+#define FLASHC_QPRUP 	15 /*Quick Page Read User Page*/
+
 
 /* Bit manipulation macros */
 #define FLASHC_BIT(name)					\
diff --git a/include/configs/atevk1100.h b/include/configs/atevk1100.h
index 166027a..776a3a1 100644
--- a/include/configs/atevk1100.h
+++ b/include/configs/atevk1100.h
@@ -160,7 +160,7 @@
 #define CFG_FLASH_BASE			0x80000000
 #define CFG_FLASH_SIZE			0x80000
 #define CFG_MAX_FLASH_BANKS		1
-#define CFG_MAX_FLASH_SECT		135
+#define CFG_MAX_FLASH_SECT		1024
 
 #define CFG_MONITOR_BASE		CFG_FLASH_BASE
 
-- 
1.5.6.3



More information about the U-Boot mailing list