2 * flash.c - low level flash handling
4 * author: hackbard@hackdaworld.org
14 unsigned long sector_address[20]={
15 0x00000,0x02000,0x03000,0x04000,0x08000,
23 0x80000 // not a sector, end of flash!
30 void flash_init(void) {
33 * idle clocks between rad & write: 0+1
34 * length of read access: 1+3
35 * bls lines high during write access
36 * length of write access: 0+1
37 * no write protect, no burst-rom
41 BCFG0=0x10000420; // flash 1
42 BCFG2=0x10000420; // flash 2
46 * p3.25: chip select 2
47 * p2.15 - p2.8: data bus
48 * a[1:15] -> address lines
51 PINSEL2=(PINSEL2&P2MASK)|(1<<8);
52 PINSEL2=(PINSEL2&P2MASK&~((1<<15)|(1<<14)))|(1<<14);
53 PINSEL2=(PINSEL2&P2MASK&~((1<<5)|(1<<4)))|(1<<4);
54 PINSEL2=(PINSEL2&P2MASK)|(1<<24);
55 PINSEL2=(PINSEL2&P2MASK&~((1<<27)|(1<<26)|(1<<25)))|(1<<27)|(1<<26);
58 void flash_reset(u8 bank) {
60 if((bank!='0')&(bank!='2'))
69 void flash_sector_erase(u8 bank,u8 sector) {
75 a18_12=sector_address[sector]<<1;
84 *((volatile u16 *)(FLASH_BANK0|a18_12))=0x30;
92 *((volatile u16 *)(FLASH_BANK2|a18_12))=0x30;
101 int flash_sec_erase(u32 addr) {
106 a18_12=addr&0x00000fffff;
107 base=addr&0xff000000;
109 *((volatile u16 *)(base|(0x555<<1)))=0xaa;
110 *((volatile u16 *)(base|(0x2aa<<1)))=0x55;
111 *((volatile u16 *)(base|(0x555<<1)))=0x80;
112 *((volatile u16 *)(base|(0x555<<1)))=0xaa;
113 *((volatile u16 *)(base|(0x2aa<<1)))=0x55;
114 *((volatile u16 *)(base|(a18_12<<1)))=0x30;
119 void flash_chip_erase(u8 bank) {
123 if((bank!='0')&(bank!='2'))
153 void flash_unlock_bypass(u8 bank) {
155 if((bank!='0')&(bank!='2'))
170 void flash_unlock_bypass_reset(u8 bank) {
172 if((bank!='0')&(bank!='2'))
185 int flash_write_word(u32 addr,u16 data) {
192 *((unsigned volatile short *)addr)=0xa0;
193 *((unsigned volatile short *)addr)=data;
195 check=*((unsigned short *)addr);
196 if((data&0x80)==(check&0x80))
205 #define flash_read_word(addr,data) *(data)=*((unsigned volatile short *)(addr))
207 int flash_write_buf(u32 addr,u16 *buf,int len) {
212 /* len must be a multiple of 2 */
216 /* decide the bank */
223 flash_unlock_bypass(bank);
227 for(cnt=0;cnt<len/2;cnt++) {
228 if(flash_write_word(addr,*(buf+cnt))==0)
234 flash_unlock_bypass_reset(bank);
239 void flash_read_buf(u32 addr,u16 *buf,int len) {
243 /* len must be a multiple of 2 */
247 for(cnt=0;cnt<len/2;cnt++)
248 flash_read_word(addr,buf+cnt);