From: hackbard <hackbard@staubsauger.localdomain>
Date: Sat, 8 Sep 2007 20:15:31 +0000 (+0200)
Subject: added low level flash support
X-Git-Url: https://hackdaworld.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5da509dc909c60d63c5fba98e7ced43040eb6827;p=my-code%2Farm.git

added low level flash support
---

diff --git a/betty/Makefile b/betty/Makefile
index f740401..3883fce 100644
--- a/betty/Makefile
+++ b/betty/Makefile
@@ -19,7 +19,7 @@ HOST_TARGET = lpcload fwdump
 CROSS_TARGET = fwbc.hex fwflash.hex betty.hex
 
 # betty deps
-BETTY_DEPS = system.o uart.o buttons.o spi.o display.o
+BETTY_DEPS = system.o uart.o buttons.o spi.o display.o flash.o
 
 # all projects
 all: $(HOST_TARGET) $(CROSS_TARGET)
@@ -41,7 +41,7 @@ arm: arm_clean $(CROSS_TARGET)
 
 # betty is special ;)
 betty.elf: betty.o startup.o $(BETTY_DEPS)
-	#$(CROSS_LD) $(CROSS_ROM_LDFLAGS) startup.o -o $@ $<
+	#$(CROSS_LD) $(CROSS_ROM_LDFLAGS) startup.o $(BETTY_DEPS) -o $@ $<
 	$(CROSS_LD) $(CROSS_RAM_LDFLAGS) startup.o $(BETTY_DEPS) -o $@ $<
 
 # .hex out of .elf
diff --git a/betty/betty.c b/betty/betty.c
index 31bc5a2..45e6ae7 100644
--- a/betty/betty.c
+++ b/betty/betty.c
@@ -20,8 +20,9 @@
 
 int main() {
 
-	char buf[]="betty - live from flash at 0x80000000! ;)\r\n";
+	char announce[]="betty - live from flash at 0x80000000! ;)\r\n";
 	t_button button;
+	u32 addr;
 
 	/* system init */
 	pll_init();
@@ -36,21 +37,37 @@ int main() {
 	button_init(&button);
 	button_set_retries(&button,100);
 
+	/* flash init */
+	flash_init();
+
 	/*
 	 * start it ...
 	 */
 
+	/* pause - seems to not work if running from flash! (?) */
 	pause(0xffffff);
+
+	/* announce */
+	uart0_send_string(announce);
+
+	/* toggle backlight */
 	bl_toggle();
 
+	//addr=0x82000000;
+	flash_sector_erase(BANK2,0);
+	addr=FLASH_BANK2;
+
 	while(1) {
 		pause(0x0fffff);
 
 		/* button test! */
 		if(button_get_event(&button)) {
-			uart0_send_string(buf);
-			if(button.key[0]==BUTTON_POWER)
+			uart0_send_string(announce);
+			if(button.key[0]==BUTTON_POWER) {
 				bl_toggle();
+				flash_write_buf(addr,(u16 *)announce,42);
+				addr+=64;
+			}
 		}
 	}
 
diff --git a/betty/betty.h b/betty/betty.h
index 41b3687..33e64d5 100644
--- a/betty/betty.h
+++ b/betty/betty.h
@@ -24,31 +24,12 @@
 #include "buttons.h"
 #include "spi.h"
 #include "display.h"
+#include "flash.h"
 
 /*
  * defines
  */
 
-/* bank 0/2 and boootloader addr/size */
-#define BANK0			0x80000000
-#define BANK1			0x81000000
-#define BANK2			0x82000000
-#define BANK_SIZE		0x00100000
-#define BOOTLOADER		0x7fffe000
-#define BL_SIZE			0x00002000
-
-/* flash cmd addresses - flash[0-18] <--> arm[1-19]*/
-#define B0F555	(*((volatile unsigned short *)(BANK0|0xaaa)))	// 0x555
-#define B0F2AA	(*((volatile unsigned short *)(BANK0|0x554)))	// 0x2aa
-#define B0F	(*((volatile unsigned short *)(BANK0)))
-#define B2F555	(*((volatile unsigned short *)(BANK2|0xaaa)))	// 0x555
-#define B2F2AA	(*((volatile unsigned short *)(BANK2|0x554)))	// 0x2aa
-#define B2F	(*((volatile unsigned short *)(BANK2)))
-
-/* lcd command and data addresses */
-#define LCD_CMD		(*((volatile unsigned char *)(BANK1)))
-#define LCD_DATA	(*((volatile unsigned char *)(BANK1+1)))
-
  /*
   * function prototypes
   */
diff --git a/betty/buttons.c b/betty/buttons.c
index 9eb99b5..21efe01 100644
--- a/betty/buttons.c
+++ b/betty/buttons.c
@@ -26,10 +26,10 @@ void button_init(t_button *button) {
 	PINSEL0&=~((1<<27)|(1<<26));	// p0.13
 
 	// ctrl databus for p2.18 - p2.24
-	PINSEL2&=(PINSEL2&(~((1<<5)|(1<<4))))|(1<<4);
+	PINSEL2=(PINSEL2&P2MASK&~((1<<5)|(1<<4)))|(1<<4);
 
 	// ctrl addr bus for p3.20, p3.21
-	PINSEL2=(PINSEL2&(~((1<<27)|(1<<26)|(1<<25))))|(1<<27)|(1<<26);
+	PINSEL2=(PINSEL2&P2MASK&~((1<<27)|(1<<26)|(1<<25)))|(1<<27)|(1<<26);
 
 	// input
 	IODIR0&=~((1<<30)|(1<<28)|(1<<27)|(1<<22)|(1<<13));
diff --git a/betty/display.c b/betty/display.c
index a5db338..07fb923 100644
--- a/betty/display.c
+++ b/betty/display.c
@@ -11,6 +11,11 @@
  * functions
  */
 
+void display_init(void) {
+
+	BCFG1=0x00000c42;
+}
+
 void bl_init(void) {
 
 	PINSEL0&=~(1<<9|(1<<8));
diff --git a/betty/flash.c b/betty/flash.c
new file mode 100644
index 0000000..8d9c02a
--- /dev/null
+++ b/betty/flash.c
@@ -0,0 +1,230 @@
+/*
+ * flash.c - low level flash handling
+ *
+ * author: hackbard@hackdaworld.org
+ *
+ */
+
+#include "flash.h"
+
+/*
+ * sector addresses
+ */
+static unsigned long sector_address[19]={
+	0x00000,0x02000,0x03000,0x04000,0x08000,
+	0x10000,0x18000,
+	0x20000,0x28000,
+	0x30000,0x38000,
+	0x40000,0x48000,
+	0x50000,0x58000,
+	0x60000,0x68000,
+	0x70000,0x78000
+};
+
+/*
+ * functions
+ */
+
+void flash_init(void) {
+
+	/*
+	 * idle clocks between rad & write: 0+1
+	 * length of read access: 1+3
+	 * bls lines high during write access
+	 * length of write access: 0+1
+	 * no write protect, no burst-rom
+	 * 16 bit data width
+	 */
+
+	BCFG0=0x10000420;	// flash 1
+	BCFG2=0x10000420;	// flash 2
+
+	/*
+	 * p3.27: write enable
+	 * p3.25: chip select 2
+	 * p2.15 - p2.8: data bus
+	 * a[1:15] -> address lines
+	 */
+
+	PINSEL2=(PINSEL2&P2MASK)|(1<<8);
+	PINSEL2=(PINSEL2&P2MASK&~((1<<15)|(1<<14)))|(1<<14);
+	PINSEL2=(PINSEL2&P2MASK&~((1<<5)|(1<<4)))|(1<<4);
+	PINSEL2=(PINSEL2&P2MASK)|(1<<24);
+	PINSEL2=(PINSEL2&P2MASK&~((1<<27)|(1<<26)|(1<<25)))|(1<<27)|(1<<26);
+}
+
+void flash_reset(u8 bank) {
+
+	if((bank!='0')&(bank!='2'))
+		return;
+
+	if(bank=='0')
+		FLASH_B0F=0xf0;
+	else
+		FLASH_B2F=0xf0;
+}
+
+void flash_sector_erase(u8 bank,u8 sector) {
+
+	u32 a18_12;
+
+	if(sector>18)
+		return;
+	a18_12=sector_address[sector]<<1;
+
+	switch(bank) {
+		case '0':
+			FLASH_B0F555=0xaa;
+			FLASH_B0F2AA=0x55;
+			FLASH_B0F555=0x80;
+			FLASH_B0F555=0xaa;
+			FLASH_B0F2AA=0x55;
+			*((volatile u16 *)(FLASH_BANK0|a18_12))=0x30;
+			break;
+		case '2': 
+			FLASH_B2F555=0xaa;
+			FLASH_B2F2AA=0x55;
+			FLASH_B2F555=0x80;
+			FLASH_B2F555=0xaa;
+			FLASH_B2F2AA=0x55;
+			*((volatile u16 *)(FLASH_BANK2|a18_12))=0x30;
+			break;
+		default:
+			return;
+	}
+
+	return;
+}
+
+void flash_chip_erase(u8 bank) {
+
+	u8 status;
+
+	if((bank!='0')&(bank!='2'))
+		return;
+
+	if(bank=='0') {
+		FLASH_B0F555=0xaa;
+		FLASH_B0F2AA=0x55;
+		FLASH_B0F555=0x80;
+		FLASH_B0F555=0xaa;
+		FLASH_B0F2AA=0x55;
+		FLASH_B0F555=0x10;
+	}
+	else {
+		FLASH_B2F555=0xaa;
+		FLASH_B2F2AA=0x55;
+		FLASH_B2F555=0x80;
+		FLASH_B2F555=0xaa;
+		FLASH_B2F2AA=0x55;
+		FLASH_B2F555=0x10;
+	}
+
+	while(1) {
+		if(bank=='0')
+			status=FLASH_B0F;
+		else
+			status=FLASH_B2F;
+		if(status&0x80)
+			break;
+	}
+}
+
+void flash_unlock_bypass(u8 bank) {
+
+	if((bank!='0')&(bank!='2'))
+		return;
+
+	if(bank=='0') {
+		FLASH_B0F555=0xaa;
+		FLASH_B0F2AA=0x55;
+		FLASH_B0F555=0x20;
+	}
+	else {
+		FLASH_B2F555=0xaa;
+		FLASH_B2F2AA=0x55;
+		FLASH_B2F555=0x20;
+	}
+}
+
+void flash_unlock_bypass_reset(u8 bank) {
+
+	if((bank!='0')&(bank!='2'))
+		return;
+
+	if(bank=='0') {
+		FLASH_B0F=0x90;
+		FLASH_B0F=0x00;
+	}
+	else {
+		FLASH_B2F=0x90;
+		FLASH_B2F=0x00;
+	}
+}
+
+int flash_write_word(u32 addr,u16 data) {
+
+	u16 check;
+
+	if(data==0xffff)
+		return 0;
+
+	*((unsigned volatile short *)addr)=0xa0;
+	*((unsigned volatile short *)addr)=data;
+	while(1) {
+		check=*((unsigned short *)addr);
+		if((data&0x80)==(check&0x80))
+			break;
+	}
+	if(data!=check)
+		return -1;
+
+	return 0;
+}
+
+#define flash_read_word(addr,data) *(data)=*((unsigned volatile short *)(addr))
+
+int flash_write_buf(u32 addr,u16 *buf,int len) {
+
+	int cnt,ret;
+	u8 bank;
+
+	/* len must be a multiple of 2 */
+	if(len&0x1)
+		return -1;
+
+	/* decide the bank */
+	if(addr<0x82000000)
+		bank='0';
+	else
+		bank='2';
+
+	/* unlock */
+	flash_unlock_bypass(bank);
+
+	/* write the data */
+	ret=0;
+	for(cnt=0;cnt<len/2;cnt++) {
+		if(flash_write_word(addr,*(buf+cnt))==0)
+			ret+=2;
+		addr+=2;
+	}
+
+	/* relock */
+	flash_unlock_bypass_reset(bank);
+
+	return ret;
+}
+
+void flash_read_buf(u32 addr,u16 *buf,int len) {
+
+	int cnt;
+
+	/* len must be a multiple of 2 */
+	if(len&0x1)
+		return;
+
+	for(cnt=0;cnt<len/2;cnt++)
+		flash_read_word(addr,buf+cnt);
+}
+
diff --git a/betty/flash.h b/betty/flash.h
new file mode 100644
index 0000000..8683b93
--- /dev/null
+++ b/betty/flash.h
@@ -0,0 +1,46 @@
+/*
+ * flash.h - header file for the low level flash handling
+ *
+ * author: hackbard@hackdaworld.org
+ *
+ */
+
+#ifndef FLASH_H
+#define FLASH_H
+
+#include "lpc2xxx.h"
+#include "types.h"
+
+/*
+ * defines
+ */
+
+#define BANK0				'0'
+#define BANK2				'2'
+#define FLASH_BANK0			0x80000000
+#define FLASH_BANK2			0x82000000
+#define FLASH_SIZE			0x00100000
+
+/* cmd addresses (shifted to left!) */
+#define FLASH_B0F555	(*((volatile unsigned short *)(FLASH_BANK0|0xaaa)))
+#define FLASH_B0F2AA	(*((volatile unsigned short *)(FLASH_BANK0|0x554)))
+#define FLASH_B0F	(*((volatile unsigned short *)(FLASH_BANK0)))
+#define FLASH_B2F555	(*((volatile unsigned short *)(FLASH_BANK2|0xaaa)))
+#define FLASH_B2F2AA	(*((volatile unsigned short *)(FLASH_BANK2|0x554)))
+#define FLASH_B2F	(*((volatile unsigned short *)(FLASH_BANK2)))
+
+/*
+ * function prototypes
+ */
+
+void flash_init(void);
+void flash_reset(u8 bank);
+void flash_sector_erase(u8 flash,u8 sector);
+void flash_chip_erase(u8 bank);
+void flash_unlock_bypass(u8 bank);
+void flash_unlock_bypass_reset(u8 bank);
+int flash_write_word(u32 addr,u16 data);
+int flash_write_buf(u32 addr,u16 *buf,int len);
+void flash_read_buf(u32 addr,u16 *buf,int len);
+
+#endif
diff --git a/betty/lpc2xxx.h b/betty/lpc2xxx.h
index 4dd46ad..cd71ee3 100644
--- a/betty/lpc2xxx.h
+++ b/betty/lpc2xxx.h
@@ -62,6 +62,7 @@
 #define PINSEL0        (*((volatile unsigned long *) 0xE002C000))
 #define PINSEL1        (*((volatile unsigned long *) 0xE002C004))
 #define PINSEL2        (*((volatile unsigned long *) 0xE002C014))
+#define P2MASK         0x0FF3E9FC
 
 /* General Purpose Input/Output (GPIO) */
 #define IOPIN          (*((volatile unsigned long *) 0xE0028000))
diff --git a/betty/system.c b/betty/system.c
index 4876802..d6aec13 100644
--- a/betty/system.c
+++ b/betty/system.c
@@ -31,9 +31,10 @@ void pll_init(void) {
 		continue;
 }
 
-void pause(int cnt) {
+void pause(u32 cnt) {
 
 	while(cnt--)
+		//continue;
 		asm volatile ("nop");
 }
 
diff --git a/betty/system.h b/betty/system.h
index 37dcaa9..e837f01 100644
--- a/betty/system.h
+++ b/betty/system.h
@@ -14,6 +14,6 @@
 /* function prototypes */
 void mmap_init(u8 memtype);
 void pll_init(void);
-void pause(int cnt);
+void pause(u32 cnt);
 
 #endif
diff --git a/betty/types.h b/betty/types.h
new file mode 100644
index 0000000..e3a3091
--- /dev/null
+++ b/betty/types.h
@@ -0,0 +1,16 @@
+/*
+ * type.h - type definitions
+ *
+ * author: hackbard@hackdaworld.org
+ *
+ */
+
+#ifndef TYPE_H
+#define TYPE_H
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+
+#endif
+