added low level flash support
authorhackbard <hackbard@staubsauger.localdomain>
Sat, 8 Sep 2007 20:15:31 +0000 (22:15 +0200)
committerhackbard <hackbard@staubsauger.localdomain>
Sat, 8 Sep 2007 20:15:31 +0000 (22:15 +0200)
betty/Makefile
betty/betty.c
betty/betty.h
betty/buttons.c
betty/display.c
betty/flash.c [new file with mode: 0644]
betty/flash.h [new file with mode: 0644]
betty/lpc2xxx.h
betty/system.c
betty/system.h
betty/types.h [new file with mode: 0644]

index f740401..3883fce 100644 (file)
@@ -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
index 31bc5a2..45e6ae7 100644 (file)
@@ -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;
+                       }
                }
        }
 
index 41b3687..33e64d5 100644 (file)
 #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
   */
index 9eb99b5..21efe01 100644 (file)
@@ -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));
index a5db338..07fb923 100644 (file)
  * 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 (file)
index 0000000..8d9c02a
--- /dev/null
@@ -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 (file)
index 0000000..8683b93
--- /dev/null
@@ -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
index 4dd46ad..cd71ee3 100644 (file)
@@ -62,6 +62,7 @@
 #define PINSEL0        (*((volatile unsigned long *) 0xE002C000))\r
 #define PINSEL1        (*((volatile unsigned long *) 0xE002C004))\r
 #define PINSEL2        (*((volatile unsigned long *) 0xE002C014))\r
+#define P2MASK         0x0FF3E9FC\r
 \r
 /* General Purpose Input/Output (GPIO) */\r
 #define IOPIN          (*((volatile unsigned long *) 0xE0028000))\r
index 4876802..d6aec13 100644 (file)
@@ -31,9 +31,10 @@ void pll_init(void) {
                continue;
 }
 
-void pause(int cnt) {
+void pause(u32 cnt) {
 
        while(cnt--)
+               //continue;
                asm volatile ("nop");
 }
 
index 37dcaa9..e837f01 100644 (file)
@@ -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 (file)
index 0000000..e3a3091
--- /dev/null
@@ -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
+