2 * flash.c - low level flash handling
4 * author: hackbard@hackdaworld.org
14 unsigned long sector_address[19]={
15 0x00000,0x02000,0x03000,0x04000,0x08000,
29 void flash_init(void) {
32 * idle clocks between rad & write: 0+1
33 * length of read access: 1+3
34 * bls lines high during write access
35 * length of write access: 0+1
36 * no write protect, no burst-rom
40 BCFG0=0x10000420; // flash 1
41 BCFG2=0x10000420; // flash 2
45 * p3.25: chip select 2
46 * p2.15 - p2.8: data bus
47 * a[1:15] -> address lines
50 PINSEL2=(PINSEL2&P2MASK)|(1<<8);
51 PINSEL2=(PINSEL2&P2MASK&~((1<<15)|(1<<14)))|(1<<14);
52 PINSEL2=(PINSEL2&P2MASK&~((1<<5)|(1<<4)))|(1<<4);
53 PINSEL2=(PINSEL2&P2MASK)|(1<<24);
54 PINSEL2=(PINSEL2&P2MASK&~((1<<27)|(1<<26)|(1<<25)))|(1<<27)|(1<<26);
57 void flash_reset(u8 bank) {
59 if((bank!='0')&(bank!='2'))
68 void flash_sector_erase(u8 bank,u8 sector) {
74 a18_12=sector_address[sector]<<1;
83 *((volatile u16 *)(FLASH_BANK0|a18_12))=0x30;
91 *((volatile u16 *)(FLASH_BANK2|a18_12))=0x30;
100 int flash_sec_erase(u32 addr) {
105 a18_12=addr&0x00000fffff;
106 base=addr&0xff000000;
108 *((volatile u16 *)(base|(0x555<<1)))=0xaa;
109 *((volatile u16 *)(base|(0x2aa<<1)))=0x55;
110 *((volatile u16 *)(base|(0x555<<1)))=0x80;
111 *((volatile u16 *)(base|(0x555<<1)))=0xaa;
112 *((volatile u16 *)(base|(0x2aa<<1)))=0x55;
113 *((volatile u16 *)(base|(a18_12<<1)))=0x30;
118 void flash_chip_erase(u8 bank) {
122 if((bank!='0')&(bank!='2'))
152 void flash_unlock_bypass(u8 bank) {
154 if((bank!='0')&(bank!='2'))
169 void flash_unlock_bypass_reset(u8 bank) {
171 if((bank!='0')&(bank!='2'))
184 int flash_write_word(u32 addr,u16 data) {
191 *((unsigned volatile short *)addr)=0xa0;
192 *((unsigned volatile short *)addr)=data;
194 check=*((unsigned short *)addr);
195 if((data&0x80)==(check&0x80))
204 #define flash_read_word(addr,data) *(data)=*((unsigned volatile short *)(addr))
206 int flash_write_buf(u32 addr,u16 *buf,int len) {
211 /* len must be a multiple of 2 */
215 /* decide the bank */
222 flash_unlock_bypass(bank);
226 for(cnt=0;cnt<len/2;cnt++) {
227 if(flash_write_word(addr,*(buf+cnt))==0)
233 flash_unlock_bypass_reset(bank);
238 void flash_read_buf(u32 addr,u16 *buf,int len) {
242 /* len must be a multiple of 2 */
246 for(cnt=0;cnt<len/2;cnt++)
247 flash_read_word(addr,buf+cnt);