return rx;
}
+void flash_reset(u8 bank) {
+
+ if((bank!='0')&(bank!='2'))
+ return;
+
+ if(bank=='0')
+ B0F=0xf0;
+ else
+ B2F=0xf0;
+}
+
void flash_sector_erase(u8 flash,u8 sector) {
u32 a18_12;
void flash_chip_erase(u8 bank) {
+ u8 status;
+
if((bank!='0')&(bank!='2'))
return;
B2F2AA=0x55;
B2F555=0x10;
}
+
+ while(1) {
+ if(bank=='0')
+ status=B0F;
+ else
+ status=B2F;
+
+ if(status&0x80)
+ break;
+ }
}
void unlock_bypass(u8 bank) {
}
}
-void flash_write(u32 addr,u16 data) {
+int flash_write(u32 addr,u16 data) {
+
+ u16 check;
+
+ *((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;
- *((volatile unsigned short *)addr)=0xa0;
- *((volatile unsigned short *)addr)=data;
+ return 0;
}
-void receive_data_and_write_to_flash(u32 addr,u32 datalen) {
+int receive_data_and_write_to_flash(u32 addr,u32 datalen) {
u8 bank;
- u32 i;
+ u32 i,ret;
u16 data;
- u8 byte;
u8 cksm;
+ u8 byte;
/* which bank to program */
if(addr<0x82000000)
/* receive and write data */
cksm=0;
+ ret=0;
for(i=0;i<datalen/2;i++) {
byte=uart0_get_byte();
+ uart0_send_byte(byte);
data=byte;
cksm+=byte;
byte=uart0_get_byte();
+ uart0_send_byte(byte);
cksm+=byte;
data|=byte<<8;
- *((unsigned volatile short *)addr)=0xa0;
- *((unsigned volatile short *)addr)=data;
+ if(flash_write(addr,data)<0)
+ ret=-1;
addr+=2;
}
/* relock bypass */
unlock_bypass_reset(bank);
- /* send an ack */
+ /* modify cksm on purpose, so the user knows ... */
+ cksm+=1;
+
+ /* send the cksm */
uart0_send_byte(cksm);
+
+ return ret;
}
/*
cfsetispeed(&term,B115200);
cfsetospeed(&term,B115200);
+ // timeouts
+
+ term.c_cc[VMIN]=0;
+ term.c_cc[VTIME]=100; // 10 seconds timeout
+
ret=tcsetattr(lpc->sfd,TCSANOW,&term);
return ret;
int write_to_flash(t_lpc *lpc,u8 *buf,u32 addr,int len) {
- int cnt,size,ret;
- u8 cksm;
+ int cnt,ret;
+ u8 cksml,cksmr;
+ u8 check;
+ int i;
/* send cmd */
send_cmd(lpc->sfd,addr+lpc->roff,len,CMD_WRITE);
/* transfer data */
cnt=0;
- cksm=0;
+ cksml=0;
while(len) {
- size=2;
- while(size) {
- ret=write(lpc->sfd,buf+cnt,2);
- if(ret<0) {
- perror("transmit flash content");
- return ret;
+ for(i=0;i<2;i++) {
+ while(1) {
+ ret=write(lpc->sfd,buf+cnt+i,1);
+ if(ret<0) {
+ perror("transmit flash content (w)");
+ return ret;
+ }
+ if(ret==1)
+ break;
}
- size-=ret;
+ while(1) {
+ ret=read(lpc->sfd,&check,1);
+ if(ret<0) {
+ perror("transmit flash content (r)");
+ return ret;
+ }
+ if(ret==1)
+ break;
+ }
+ if(buf[cnt+i]!=check)
+ printf("FATAL: write to flash: wrong transfer\n");
}
- cksm+=buf[cnt];
- cksm+=buf[cnt+1];
+ cksml+=buf[cnt];
+ cksml+=buf[cnt+1];
cnt+=2;
len-=2;
}
/* check ack */
- ret=read(lpc->sfd,buf,1);
- if(ret<0) {
- perror("write to flash: ack rx");
- return ret;
+ while(1) {
+ ret=read(lpc->sfd,&cksmr,1);
+ if(ret<0) {
+ perror("write to flash: read cksm");
+ return ret;
+ }
+ if(ret==1) break;
}
- if(buf[0]!=cksm) {
- printf("FATAL: write to ram: wrong checksum!\n");
- return -1;
+ if(cksml!=cksmr) {
+ printf("FATAL: wrong checksum or failure in flash write!\n");
+ if(cksml+1==cksmr)
+ printf(" -> most probably due to flash write!");
+ else
+ printf(" -> most probably due to failure in transfer!");
}
return 0;