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 #define PIC_ADR(_ptr,_var) \
62 "1:\tmov.l @sp+,%0\n" \
63 "\tadd.l %1-1b,%0\n" \
64 : "=r" (_ptr) : "i" (&(_var)) : "cc" \
68 static const unsigned long
69 flash_blocks[] TO_TEXT =
70 {0x00000,0x01000,0x02000,0x03000,0x04000,0x05000,0x06000,0x07000,
71 0x08000,0x10000,0x20000,0x30000,0x40000,0};
74 flash_block_count TO_TEXT =
75 sizeof(flash_blocks)/sizeof(unsigned long)-2;
78 volatile void FlWait(long n)
88 volatile void FlWait(long n);
93 #if (CPU_SYS_HZ>16000000)
109 int FlAdr2Blk(unsigned long adr)
112 unsigned long *blocks;
113 PIC_ADR(blocks,flash_blocks[0]);
115 if(adr<blocks[0]) return -1;
117 if(adr<blocks[bl+1]) return bl;
123 /* Check if block number is blank */
127 unsigned long *blocks;
128 PIC_ADR(blocks,flash_blocks[0]);
130 if(bl>=flash_block_count) return -2;
133 /* No software control over Flash/External select */
134 /* *BCRL=(*BCRL & (EAE ^ 0x0ff)); */
136 p=(__u16*)blocks[bl];
137 pe=(__u16*)blocks[bl+1];
141 if (*p!=0xffff) return -1;
147 /* Erase block number */
151 if(bl>=flash_block_count) return -EBOOT_BLNUM_HIGH;
152 if(bl<0) return -EBOOT_BLNUM_LOW;
154 if(FlTest(bl)==0) return 0;
156 if((*FLM_FLMCR1 & FLMCR1_FWEm)==0) return -EBOOT_NO_FWE;
158 *FLM_FLMCR1=FLMCR1_SWE1m;
165 *FLM_EBR2=(1 << (bl-8));
169 if(*FLM_FLMCR2 & FLMCR2_FLERm) goto fls_error;
171 *FLM_FLMCR1|=FLMCR1_ESU1m;
173 *FLM_FLMCR1|=FLMCR1_E1m;
174 FlWait(5000); /*z=max10000*/
175 *FLM_FLMCR1&=~FLMCR1_E1m;
176 FlWait(10); /*alpha*/
177 *FLM_FLMCR2&=~FLMCR1_ESU1m;
178 FlWait(10); /*betha*/
180 if(*FLM_FLMCR2 & FLMCR2_FLERm) goto fls_error;
181 *FLM_FLMCR1|=FLMCR1_EV1m;
184 *FLM_FLMCR1&=FLMCR1_SWE1m; /*clear EV1*/
189 *FLM_FLMCR1&=FLMCR1_SWE1m; /*clear EV1*/
194 return -EBOOT_ERASE_FAILURE;
198 return -EBOOT_FLASH_ERROR;
201 void FlProgPulse(int time_zx)
204 *FLM_FLMCR1|=FLMCR1_PSU1m;
206 *FLM_FLMCR1|=FLMCR1_P1m;
207 FlWait(time_zx); /*z0,z1 or z2*/
208 *FLM_FLMCR1&=~FLMCR1_P1m;
210 *FLM_FLMCR1&=FLMCR1_SWE1m; /*clear PSU1*/
215 /* Program data to address */
216 int FlProgRow(__u8 *adr, __u8 *data)
218 __u8 prog_data[FLASH_ROW];
224 if((unsigned long)adr & (FLASH_ROW-1)) return -EBOOT_ROW_BEGIN;
225 if((*FLM_FLMCR1 & FLMCR1_FWEm)==0 ) return -EBOOT_NO_FWE;
226 #ifdef WITH_EXTERNAL_FLASH
227 if(((__u32)adr>=EXTERNAL_FLASH_START)&&
228 ((__u32)adr<=EXTERNAL_FLASH_END)){
229 return ExtFlProgRow(adr,data);
231 #endif /*WITH_EXTERNAL_FLASH*/
234 for(i=FLASH_ROW;i--;x++){
235 if(*x!=0xff) return -EBOOT_ROW_NOT_ERASED;
238 for(i=0;i<FLASH_ROW;i++,x++) prog_data[i]=*x;
240 *FLM_FLMCR1=FLMCR1_SWE1m;
244 while(n<100){ /*N1+N2<1000*/
249 for(i=0;i<FLASH_ROW;i++,x++) *x=prog_data[i];
251 FlProgPulse(n>6?150:25); /*z0<30 or z2<200 if n>N1*/
253 /* Program-Verify Mode */
254 *FLM_FLMCR1|=FLMCR1_PV1m;
258 for(i=0;i<FLASH_ROW;i+=2,x+=2){
260 FlWait(2); /*epsilon*/
261 *(__u16*)(prog_data+i)=*(__u16*)x;
263 *FLM_FLMCR1&=FLMCR1_SWE1m; /*clear PV1*/
267 for(i=0;i<FLASH_ROW;i++,x++){
270 if((~c&d)&0xff) goto fls_error;
272 m=1; /* Reprogram needed */
273 /* DEB_BLOG(0xEE000000+(long)x); */
274 /* DEB_BLOG(0xEF000000+(__u16)(c<<8)+(__u8)d); */
280 FlProgPulse(7); /*z1<10*/
283 for(i=0;i<FLASH_ROW;i++){
286 if(c!=d) m=1; /* Reprogram needed */
287 if((~c&d)&0xff) goto fls_error;
294 DEB_BLOG(0xED000000+n);
300 return -EBOOT_PROG_FAILURE;
304 return -EBOOT_FLASH_VERIFY;
307 int FlPrepBlk(unsigned long badr, unsigned long len)
311 blend=FlAdr2Blk(badr+len-1);
312 if((bl<0)||(blend<0)) return -EBOOT_BLOCKADDR;
313 for(;bl<=blend;bl++){
316 if(res<0) return res;
324 #define RS232_TDR SCI_TDR4
325 #define RS232_RDR SCI_RDR4
326 #define RS232_SMR SCI_SMR4
327 #define RS232_SCMR SCI_SCMR4
328 #define RS232_SCR SCI_SCR4
329 #define RS232_SSR SCI_SSR4
330 #define RS232_BRR SCI_BRR4
331 #define RS232_RXD_PIN ((*DIO_PORT3)&(1<<6))
334 #define RS232_TDR SCI_TDR2
335 #define RS232_RDR SCI_RDR2
336 #define RS232_SMR SCI_SMR2
337 #define RS232_SCMR SCI_SCMR2
338 #define RS232_SCR SCI_SCR2
339 #define RS232_SSR SCI_SSR2
340 #define RS232_BRR SCI_BRR2
341 #define RS232_RXD_PIN ((*DIO_PORTA)&(1<<2))
344 #define RS232_TDR SCI_TDR1
345 #define RS232_RDR SCI_RDR1
346 #define RS232_SMR SCI_SMR1
347 #define RS232_SCMR SCI_SCMR1
348 #define RS232_SCR SCI_SCR1
349 #define RS232_SSR SCI_SSR1
350 #define RS232_BRR SCI_BRR1
351 #define RS232_RXD_PIN ((*DIO_PORT3)&(1<<4))
354 #define RS232_BAUD_RAW 0xff00
356 int SCIInit(unsigned baud)
361 /*disable SCI interrupts and Rx/Tx machine*/
365 if((baud&RS232_BAUD_RAW)!=RS232_BAUD_RAW){
366 divisor=div_us_ulus((CPU_SYS_HZ/16+baud/2),baud);
368 if(++cks>=4) return -1;
371 divisor=(divisor+1)>>1;
375 *RS232_BRR=divisor-1;
377 *RS232_SMR=(SMR_CKSxm&cks);
380 *RS232_SCR=SCR_TEm|SCR_REm;
384 volatile int SCISend(unsigned char c)
386 unsigned int i=50000;
387 while((*RS232_SSR & SSR_TDREm)==0 && i>0) i--;
390 *RS232_SSR=~SSR_TDREm&0xff;
394 volatile int SCIReceive(unsigned char *c,unsigned int time)
398 while(!((ssr=*RS232_SSR) & SSR_RDRFm) && ((time--)>0))
399 if(ssr&(SSR_ORERm|SSR_FERm)) break;
400 if (time==0) return -1;
403 while(!((ssr=*RS232_SSR) & SSR_RDRFm))
404 if(ssr&(SSR_ORERm|SSR_FERm)) break;
407 *RS232_SSR=~(SSR_RDRFm|SSR_MPBTm);
408 if(ssr & (SSR_ORERm|SSR_FERm)){
409 *RS232_SSR=~(SSR_ORERm|SSR_FERm|SSR_MPBTm);
415 unsigned long GetAdr()
420 a=((unsigned long)c << 24);
422 a=a | (((unsigned long)c << 16) & 0xff0000);
424 a=a | (((unsigned long)c << 8) & 0xff00);
426 a=a | ((unsigned long)c & 0xff);
427 SCISend((a >> 24) & 0xFF);
428 SCISend((a >> 16) & 0xFF);
429 SCISend((a >> 8) & 0xFF);
434 int SCIAutoBaud(void)
439 /* Disable power-on reset of WDT owerflow */
440 *WDT_WRSTCSRw=(0x5a00 | 1*WRSTCSR_RSTEm | 0*WRSTCSR_RSTSm);
441 /* Select watchdog function and input clocks */
442 *WDT_WTCSR0w=(0xa500 | 1*WTCSR0_WTITm |(1 & WTCSR0_CKSxm));
443 *WDT_WTCSR0w=(0xa500 | 1*WTCSR0_WTITm | 1*WTCSR0_TMEm | (1 & WTCSR0_CKSxm));
445 while(!RS232_RXD_PIN) *WDT_WTCNT0w=(0x5a00);
446 while(RS232_RXD_PIN) *WDT_WTCNT0w=(0x5a00);
452 *WDT_WTCNT0w=(0x5a00);
461 /* Disable watchdog */
462 *WDT_WTCSR0w=(0xa500);
464 SCIInit(((t*2+7)/9)|RS232_BAUD_RAW);
469 #ifdef WITH_EXTERNAL_FLASH
471 #define EXTFL_addr_mask 0x0ffffl
472 #define EXTFL_reg1_addr (0x555*2l)
473 #define EXTFL_reg2_addr (0x2aa*2l)
474 #define EXTFL_sec_size 0x10000
475 #define EXTFL_width8 0
476 #define EXTFL_cmd_unlock1 0xaaaa /* reg1 */
477 #define EXTFL_cmd_unlock2 0x5555 /* reg2 */
478 #define EXTFL_cmd_rdid 0x9090 /* reg1 */
479 #define EXTFL_cmd_prog 0xa0a0 /* reg1 */
480 #define EXTFL_cmd_erase 0x8080 /* reg1 */
481 #define EXTFL_cmd_reset 0xf0f0 /* any */
482 #define EXTFL_erase_all 0x1010 /* reg1 */
483 #define EXTFL_erase_sec 0x3030 /* sector */
484 #define EXTFL_fault_bit 0x2020
485 #define EXTFL_manid 1
486 #define EXTFL_devid 0x2258
488 #define FLASH_WR16(addr,val) (*(volatile __u16*)(addr)=(val))
489 #define FLASH_RD16(addr) (*(volatile __u16*)(addr))
491 /* Program data to address */
492 int ExtFlProgRow(__u8 *addr, __u8 *data)
498 __u32 a=(__u32)addr&~EXTFL_addr_mask;
500 val=*((__u16*)data)++;
501 /* security sequence */
502 FLASH_WR16(a+EXTFL_reg1_addr,EXTFL_cmd_unlock1);
504 FLASH_WR16(a+EXTFL_reg2_addr,EXTFL_cmd_unlock2);
506 /* program command */
507 FLASH_WR16(a+EXTFL_reg1_addr,EXTFL_cmd_prog);
509 FLASH_WR16(addr,val);
511 /* wait for result */
512 old=FLASH_RD16(addr);
514 while((new=FLASH_RD16(addr))!=old){
516 if((old&EXTFL_fault_bit)&&(new&EXTFL_fault_bit)){
517 if((FLASH_RD16(addr))!=new) ret=-2;
523 FLASH_WR16(a,EXTFL_cmd_reset);
525 if(FLASH_RD16(addr)!=val) return -EBOOT_EXT_FLASH_VERIFY;
531 int ExtFlErase(__u8 *addr)
535 __u32 a=(__u32)addr&~EXTFL_addr_mask;
536 /* security sequence */
537 FLASH_WR16(a+EXTFL_reg1_addr,EXTFL_cmd_unlock1);
539 FLASH_WR16(a+EXTFL_reg2_addr,EXTFL_cmd_unlock2);
542 FLASH_WR16(a+EXTFL_reg1_addr,EXTFL_cmd_erase);
544 /* security sequence */
545 FLASH_WR16(a+EXTFL_reg1_addr,EXTFL_cmd_unlock1);
547 FLASH_WR16(a+EXTFL_reg2_addr,EXTFL_cmd_unlock2);
549 /* select erase range */
551 FLASH_WR16(a+EXTFL_reg1_addr,EXTFL_erase_all);
553 old=FLASH_RD16(addr);
555 while((new=FLASH_RD16(addr))!=old){
557 if((old&EXTFL_fault_bit)&&(new&EXTFL_fault_bit)){
558 if((FLASH_RD16(addr))!=new) ret=-2;
564 FLASH_WR16(a,EXTFL_cmd_reset);
566 if(FLASH_RD16(addr)!=0xffff) ret--;
570 #endif /*WITH_EXTERNAL_FLASH*/
572 void Call(unsigned long adr)
574 __asm__ /*__volatile__*/(
581 void ProgMode(unsigned baud)
596 if(baud) SCIInit(baud);
598 if(!baud) SCIAutoBaud();
606 DEB_WR_HEX(cmd,2); /*!!!*/
607 if((cmd & 7) == (((cmd >> 3) & 7) ^ 7)){
610 if((cmd<=2)||(cmd==4)){
611 /* memory download/upload/erase region */
615 /* memory download */
618 DEB_WR_HEX(badr,8); /*!!!*/
619 DEB_WR_HEX(len,8); /*!!!*/
620 adr=(unsigned char *)badr;
622 if(SCIReceive(&c,0)<0){
633 /* flash programming */
634 /* check and erase range */
635 /*if(FlPrepBlk(badr,len)<0) e=0xfc;*/
636 i=badr-(badr & 0xffffffe0);
642 adr=(unsigned char *)(badr & ~(FLASH_ROW-1));
643 j=(unsigned char *)badr-adr;
646 if(SCIReceive(&c,0)<0){
653 DEB_WR_HEX((long)adr,6); /*!!!*/
654 if((ret=FlProgRow(adr,buf))!=0) {
659 DEB_BLOG(0xEA000000|(__u32)adr|((__u8)j&0x7f));
660 DEB_WR_HEX(j,2); /*!!!*/
666 if(j/*&&!(e&0x80)*/){
667 while(j<FLASH_ROW) buf[j++]=0xff;
668 if((ret=FlProgRow(adr,buf))!=0) e=-ret;
672 /* check and erase region */
673 e=FlPrepBlk(badr,len);
680 DEB_WR_HEX(badr,8); /*!!!*/
681 DEB_WR_HEX(len,8); /*!!!*/
682 adr=(unsigned char *)badr;
686 if(SCIReceive(&c,0)<0){
699 if (c<flash_block_count){
700 if(FlErase(c)==0) SCISend(0x5A);
702 #ifdef WITH_EXTERNAL_FLASH
704 if(ExtFlErase((__u8*)EXTERNAL_FLASH_START)==0)
705 SCISend(0x5A); else SCISend(0xFF);
706 #endif /*WITH_EXTERNAL_FLASH*/
711 DEB_WR_HEX(badr,8); /*!!!*/