3 #include <system_def.h>
4 //#include <h8s2633h.h>
8 #undef WITH_EXTERNAL_FLASH
11 #define DEB_WR_HEX(...)
13 #define DEB_WR_HEX(_hex,_digs) deb_wr_hex(_hex,_digs);
14 void deb_wr_hex(long hex, short digs);
21 #define DEB_BLOG_INIT do{ *(long*)0x280000=0x280000+4; } while(0)
22 #define DEB_BLOG(_val) do{ *((*(long**)0x280000)++)=_val; } while(0)
25 #ifdef WITH_EXTERNAL_FLASH
26 #define EXTERNAL_FLASH_START 0x40000
27 #define EXTERNAL_FLASH_END (0x40000+0xfffff)
28 int ExtFlProgRow(__u8 *addr, __u8 *data);
29 int ExtFlErase(__u8 *addr);
30 #endif /*WITH_EXTERNAL_FLASH*/
33 /* Enable watchdog with selected system clock prescaller */
34 /* 2, 64, 128, 512, 2048, 8192, 32768, 131072 */
35 void wdg_enable(int psel)
37 /* Enable power-on reset of WDT owerflow */
38 *WDT_WRSTCSRw=(0x5a00 | 1*WRSTCSR_RSTEm | 0*WRSTCSR_RSTSm);
39 /* Select watchdog function and input clocks */
40 *WDT_WTCSR0w=(0xa500 | 1*WTCSR0_WTITm |(psel & WTCSR0_CKSxm));
41 *WDT_WTCSR0w=(0xa500 | 1*WTCSR0_WTITm | 1*WTCSR0_TMEm | (psel & WTCSR0_CKSxm));
44 /* Disable watchdog */
47 *WDT_WTCSR0w=(0xa500);
53 *WDT_WTCNT0w=(0x5a00);
56 #define TO_TEXT __attribute__ ((section (".text")))
58 static const unsigned long
59 flash_blocks[] TO_TEXT =
60 {0x00000,0x01000,0x02000,0x03000,0x04000,0x05000,0x06000,0x07000,
61 0x08000,0x10000,0x20000,0x30000,0x40000,0};
64 flash_block_count TO_TEXT =
65 sizeof(flash_blocks)/sizeof(unsigned long)-2;
68 volatile void FlWait(long n)
78 volatile void FlWait(long n);
83 #if (CPU_SYS_HZ>16000000)
99 int FlAdr2Blk(unsigned long adr)
102 unsigned long *blocks;
103 blocks = &flash_blocks[0];
105 if(adr<blocks[0]) return -1;
107 if(adr<blocks[bl+1]) return bl;
113 /* Check if block number is blank */
117 unsigned long *blocks;
118 blocks = &flash_blocks[0];
120 if(bl>=flash_block_count) return -2;
123 /* No software control over Flash/External select */
124 /* *BCRL=(*BCRL & (EAE ^ 0x0ff)); */
126 p=(__u16*)blocks[bl];
127 pe=(__u16*)blocks[bl+1];
131 if (*p!=0xffff) return -1;
137 /* Erase block number */
141 if(bl>=flash_block_count) return -EBOOT_BLNUM_HIGH;
142 if(bl<0) return -EBOOT_BLNUM_LOW;
144 if(FlTest(bl)==0) return 0;
146 if((*FLM_FLMCR1 & FLMCR1_FWEm)==0) return -EBOOT_NO_FWE;
148 *FLM_FLMCR1=FLMCR1_SWE1m;
155 *FLM_EBR2=(1 << (bl-8));
159 if(*FLM_FLMCR2 & FLMCR2_FLERm) goto fls_error;
161 *FLM_FLMCR1|=FLMCR1_ESU1m;
163 *FLM_FLMCR1|=FLMCR1_E1m;
164 FlWait(5000); /*z=max10000*/
165 *FLM_FLMCR1&=~FLMCR1_E1m;
166 FlWait(10); /*alpha*/
167 *FLM_FLMCR2&=~FLMCR1_ESU1m;
168 FlWait(10); /*betha*/
170 if(*FLM_FLMCR2 & FLMCR2_FLERm) goto fls_error;
171 *FLM_FLMCR1|=FLMCR1_EV1m;
174 *FLM_FLMCR1&=FLMCR1_SWE1m; /*clear EV1*/
179 *FLM_FLMCR1&=FLMCR1_SWE1m; /*clear EV1*/
184 return -EBOOT_ERASE_FAILURE;
188 return -EBOOT_FLASH_ERROR;
191 void FlProgPulse(int time_zx)
194 *FLM_FLMCR1|=FLMCR1_PSU1m;
196 *FLM_FLMCR1|=FLMCR1_P1m;
197 FlWait(time_zx); /*z0,z1 or z2*/
198 *FLM_FLMCR1&=~FLMCR1_P1m;
200 *FLM_FLMCR1&=FLMCR1_SWE1m; /*clear PSU1*/
205 /* Program data to address */
206 int FlProgRow(__u8 *adr, __u8 *data)
208 __u8 prog_data[FLASH_ROW];
214 if((unsigned long)adr & (FLASH_ROW-1)) return -EBOOT_ROW_BEGIN;
215 if((*FLM_FLMCR1 & FLMCR1_FWEm)==0 ) return -EBOOT_NO_FWE;
216 #ifdef WITH_EXTERNAL_FLASH
217 if(((__u32)adr>=EXTERNAL_FLASH_START)&&
218 ((__u32)adr<=EXTERNAL_FLASH_END)){
219 return ExtFlProgRow(adr,data);
221 #endif /*WITH_EXTERNAL_FLASH*/
224 for(i=FLASH_ROW;i--;x++){
225 if(*x!=0xff) return -EBOOT_ROW_NOT_ERASED;
228 for(i=0;i<FLASH_ROW;i++,x++) prog_data[i]=*x;
230 *FLM_FLMCR1=FLMCR1_SWE1m;
234 while(n<100){ /*N1+N2<1000*/
239 for(i=0;i<FLASH_ROW;i++,x++) *x=prog_data[i];
241 FlProgPulse(n>6?150:25); /*z0<30 or z2<200 if n>N1*/
243 /* Program-Verify Mode */
244 *FLM_FLMCR1|=FLMCR1_PV1m;
248 for(i=0;i<FLASH_ROW;i+=2,x+=2){
250 FlWait(2); /*epsilon*/
251 *(__u16*)(prog_data+i)=*(__u16*)x;
253 *FLM_FLMCR1&=FLMCR1_SWE1m; /*clear PV1*/
257 for(i=0;i<FLASH_ROW;i++,x++){
260 if((~c&d)&0xff) goto fls_error;
262 m=1; /* Reprogram needed */
263 /* DEB_BLOG(0xEE000000+(long)x); */
264 /* DEB_BLOG(0xEF000000+(__u16)(c<<8)+(__u8)d); */
270 FlProgPulse(7); /*z1<10*/
273 for(i=0;i<FLASH_ROW;i++){
276 if(c!=d) m=1; /* Reprogram needed */
277 if((~c&d)&0xff) goto fls_error;
284 DEB_BLOG(0xED000000+n);
290 return -EBOOT_PROG_FAILURE;
294 return -EBOOT_FLASH_VERIFY;
297 int FlPrepBlk(unsigned long badr, unsigned long len)
301 blend=FlAdr2Blk(badr+len-1);
302 if((bl<0)||(blend<0)) return -EBOOT_BLOCKADDR;
303 for(;bl<=blend;bl++){
306 if(res<0) return res;
314 #define RS232_TDR SCI_TDR4
315 #define RS232_RDR SCI_RDR4
316 #define RS232_SMR SCI_SMR4
317 #define RS232_SCMR SCI_SCMR4
318 #define RS232_SCR SCI_SCR4
319 #define RS232_SSR SCI_SSR4
320 #define RS232_BRR SCI_BRR4
321 #define RS232_RXD_PIN ((*DIO_PORT3)&(1<<6))
324 #define RS232_TDR SCI_TDR2
325 #define RS232_RDR SCI_RDR2
326 #define RS232_SMR SCI_SMR2
327 #define RS232_SCMR SCI_SCMR2
328 #define RS232_SCR SCI_SCR2
329 #define RS232_SSR SCI_SSR2
330 #define RS232_BRR SCI_BRR2
331 #define RS232_RXD_PIN ((*DIO_PORTA)&(1<<2))
334 #define RS232_TDR SCI_TDR1
335 #define RS232_RDR SCI_RDR1
336 #define RS232_SMR SCI_SMR1
337 #define RS232_SCMR SCI_SCMR1
338 #define RS232_SCR SCI_SCR1
339 #define RS232_SSR SCI_SSR1
340 #define RS232_BRR SCI_BRR1
341 #define RS232_RXD_PIN ((*DIO_PORT3)&(1<<4))
344 #define RS232_BAUD_RAW 0xff00
346 int SCIInit(unsigned baud)
351 /*disable SCI interrupts and Rx/Tx machine*/
355 if((baud&RS232_BAUD_RAW)!=RS232_BAUD_RAW){
356 divisor=div_us_ulus((CPU_SYS_HZ/16+baud/2),baud);
358 if(++cks>=4) return -1;
361 divisor=(divisor+1)>>1;
365 *RS232_BRR=divisor-1;
367 *RS232_SMR=(SMR_CKSxm&cks);
370 *RS232_SCR=SCR_TEm|SCR_REm;
374 volatile int SCISend(unsigned char c)
376 unsigned int i=50000;
377 while((*RS232_SSR & SSR_TDREm)==0 && i>0) i--;
380 *RS232_SSR=~SSR_TDREm&0xff;
384 volatile int SCIReceive(unsigned char *c,unsigned int time)
388 while(!((ssr=*RS232_SSR) & SSR_RDRFm) && ((time--)>0))
389 if(ssr&(SSR_ORERm|SSR_FERm)) break;
390 if (time==0) return -1;
393 while(!((ssr=*RS232_SSR) & SSR_RDRFm))
394 if(ssr&(SSR_ORERm|SSR_FERm)) break;
397 *RS232_SSR=~(SSR_RDRFm|SSR_MPBTm);
398 if(ssr & (SSR_ORERm|SSR_FERm)){
399 *RS232_SSR=~(SSR_ORERm|SSR_FERm|SSR_MPBTm);
405 unsigned long GetAdr()
410 a=((unsigned long)c << 24);
412 a=a | (((unsigned long)c << 16) & 0xff0000);
414 a=a | (((unsigned long)c << 8) & 0xff00);
416 a=a | ((unsigned long)c & 0xff);
417 SCISend((a >> 24) & 0xFF);
418 SCISend((a >> 16) & 0xFF);
419 SCISend((a >> 8) & 0xFF);
424 int SCIAutoBaud(void)
429 /* Disable power-on reset of WDT owerflow */
430 *WDT_WRSTCSRw=(0x5a00 | 1*WRSTCSR_RSTEm | 0*WRSTCSR_RSTSm);
431 /* Select watchdog function and input clocks */
432 *WDT_WTCSR0w=(0xa500 | 1*WTCSR0_WTITm |(1 & WTCSR0_CKSxm));
433 *WDT_WTCSR0w=(0xa500 | 1*WTCSR0_WTITm | 1*WTCSR0_TMEm | (1 & WTCSR0_CKSxm));
435 while(!RS232_RXD_PIN) *WDT_WTCNT0w=(0x5a00);
436 while(RS232_RXD_PIN) *WDT_WTCNT0w=(0x5a00);
442 *WDT_WTCNT0w=(0x5a00);
451 /* Disable watchdog */
452 *WDT_WTCSR0w=(0xa500);
454 SCIInit(((t*2+7)/9)|RS232_BAUD_RAW);
459 #ifdef WITH_EXTERNAL_FLASH
461 #define EXTFL_addr_mask 0x0ffffl
462 #define EXTFL_reg1_addr (0x555*2l)
463 #define EXTFL_reg2_addr (0x2aa*2l)
464 #define EXTFL_sec_size 0x10000
465 #define EXTFL_width8 0
466 #define EXTFL_cmd_unlock1 0xaaaa /* reg1 */
467 #define EXTFL_cmd_unlock2 0x5555 /* reg2 */
468 #define EXTFL_cmd_rdid 0x9090 /* reg1 */
469 #define EXTFL_cmd_prog 0xa0a0 /* reg1 */
470 #define EXTFL_cmd_erase 0x8080 /* reg1 */
471 #define EXTFL_cmd_reset 0xf0f0 /* any */
472 #define EXTFL_erase_all 0x1010 /* reg1 */
473 #define EXTFL_erase_sec 0x3030 /* sector */
474 #define EXTFL_fault_bit 0x2020
475 #define EXTFL_manid 1
476 #define EXTFL_devid 0x2258
478 #define FLASH_WR16(addr,val) (*(volatile __u16*)(addr)=(val))
479 #define FLASH_RD16(addr) (*(volatile __u16*)(addr))
481 /* Program data to address */
482 int ExtFlProgRow(__u8 *addr, __u8 *data)
488 __u32 a=(__u32)addr&~EXTFL_addr_mask;
490 val=*((__u16*)data)++;
491 /* security sequence */
492 FLASH_WR16(a+EXTFL_reg1_addr,EXTFL_cmd_unlock1);
494 FLASH_WR16(a+EXTFL_reg2_addr,EXTFL_cmd_unlock2);
496 /* program command */
497 FLASH_WR16(a+EXTFL_reg1_addr,EXTFL_cmd_prog);
499 FLASH_WR16(addr,val);
501 /* wait for result */
502 old=FLASH_RD16(addr);
504 while((new=FLASH_RD16(addr))!=old){
506 if((old&EXTFL_fault_bit)&&(new&EXTFL_fault_bit)){
507 if((FLASH_RD16(addr))!=new) ret=-2;
513 FLASH_WR16(a,EXTFL_cmd_reset);
515 if(FLASH_RD16(addr)!=val) return -EBOOT_EXT_FLASH_VERIFY;
521 int ExtFlErase(__u8 *addr)
525 __u32 a=(__u32)addr&~EXTFL_addr_mask;
526 /* security sequence */
527 FLASH_WR16(a+EXTFL_reg1_addr,EXTFL_cmd_unlock1);
529 FLASH_WR16(a+EXTFL_reg2_addr,EXTFL_cmd_unlock2);
532 FLASH_WR16(a+EXTFL_reg1_addr,EXTFL_cmd_erase);
534 /* security sequence */
535 FLASH_WR16(a+EXTFL_reg1_addr,EXTFL_cmd_unlock1);
537 FLASH_WR16(a+EXTFL_reg2_addr,EXTFL_cmd_unlock2);
539 /* select erase range */
541 FLASH_WR16(a+EXTFL_reg1_addr,EXTFL_erase_all);
543 old=FLASH_RD16(addr);
545 while((new=FLASH_RD16(addr))!=old){
547 if((old&EXTFL_fault_bit)&&(new&EXTFL_fault_bit)){
548 if((FLASH_RD16(addr))!=new) ret=-2;
554 FLASH_WR16(a,EXTFL_cmd_reset);
556 if(FLASH_RD16(addr)!=0xffff) ret--;
560 #endif /*WITH_EXTERNAL_FLASH*/
562 void Call(unsigned long adr)
564 __asm__ /*__volatile__*/(
571 void ProgMode(unsigned baud)
586 if(baud) SCIInit(baud);
588 if(!baud) SCIAutoBaud();
596 DEB_WR_HEX(cmd,2); /*!!!*/
597 if((cmd & 7) == (((cmd >> 3) & 7) ^ 7)){
600 if((cmd<=2)||(cmd==4)){
601 /* memory download/upload/erase region */
605 /* memory download */
608 DEB_WR_HEX(badr,8); /*!!!*/
609 DEB_WR_HEX(len,8); /*!!!*/
610 adr=(unsigned char *)badr;
612 if(SCIReceive(&c,0)<0){
623 /* flash programming */
624 /* check and erase range */
625 /*if(FlPrepBlk(badr,len)<0) e=0xfc;*/
626 i=badr-(badr & 0xffffffe0);
632 adr=(unsigned char *)(badr & ~(FLASH_ROW-1));
633 j=(unsigned char *)badr-adr;
636 if(SCIReceive(&c,0)<0){
643 DEB_WR_HEX((long)adr,6); /*!!!*/
644 if((ret=FlProgRow(adr,buf))!=0) {
649 DEB_BLOG(0xEA000000|(__u32)adr|((__u8)j&0x7f));
650 DEB_WR_HEX(j,2); /*!!!*/
656 if(j/*&&!(e&0x80)*/){
657 while(j<FLASH_ROW) buf[j++]=0xff;
658 if((ret=FlProgRow(adr,buf))!=0) e=-ret;
662 /* check and erase region */
663 e=FlPrepBlk(badr,len);
670 DEB_WR_HEX(badr,8); /*!!!*/
671 DEB_WR_HEX(len,8); /*!!!*/
672 adr=(unsigned char *)badr;
676 if(SCIReceive(&c,0)<0){
689 if (c<flash_block_count){
690 if(FlErase(c)==0) SCISend(0x5A);
692 #ifdef WITH_EXTERNAL_FLASH
694 if(ExtFlErase((__u8*)EXTERNAL_FLASH_START)==0)
695 SCISend(0x5A); else SCISend(0xFF);
696 #endif /*WITH_EXTERNAL_FLASH*/
701 DEB_WR_HEX(badr,8); /*!!!*/