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 -4;
154 if(FlTest(bl)==0) return 0;
156 if((*FLM_FLMCR1 & FLMCR1_FWEm)==0) return -1;
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*/
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 -6;
225 if((*FLM_FLMCR1 & FLMCR1_FWEm)==0 ) return -5;
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 -4;
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 *FLM_FLMCR1|=FLMCR1_PV1m;
257 for(i=0;i<FLASH_ROW;i+=2,x+=2){
259 FlWait(2); /*epsilon*/
260 *(__u16*)(prog_data+i)=*(__u16*)x;
262 *FLM_FLMCR1&=FLMCR1_SWE1m; /*clear PV1*/
266 for(i=0;i<FLASH_ROW;i++,x++){
269 if((~c&d)&0xff) goto fls_error;
272 /* DEB_BLOG(0xEE000000+(long)x); */
273 /* DEB_BLOG(0xEF000000+(__u16)(c<<8)+(__u8)d); */
279 FlProgPulse(7); /*z1<10*/
282 for(i=0;i<FLASH_ROW;i++){
286 if((~c&d)&0xff) goto fls_error;
293 DEB_BLOG(0xED000000+n);
306 int FlPrepBlk(unsigned long badr, unsigned long len)
310 blend=FlAdr2Blk(badr+len-1);
311 if((bl<0)||(blend<0)) return -8;
312 for(;bl<=blend;bl++){
315 if(res<0) return res;
323 #define RS232_TDR SCI_TDR4
324 #define RS232_RDR SCI_RDR4
325 #define RS232_SMR SCI_SMR4
326 #define RS232_SCMR SCI_SCMR4
327 #define RS232_SCR SCI_SCR4
328 #define RS232_SSR SCI_SSR4
329 #define RS232_BRR SCI_BRR4
330 #define RS232_RXD_PIN ((*DIO_PORT3)&(1<<6))
333 #define RS232_TDR SCI_TDR2
334 #define RS232_RDR SCI_RDR2
335 #define RS232_SMR SCI_SMR2
336 #define RS232_SCMR SCI_SCMR2
337 #define RS232_SCR SCI_SCR2
338 #define RS232_SSR SCI_SSR2
339 #define RS232_BRR SCI_BRR2
340 #define RS232_RXD_PIN ((*DIO_PORTA)&(1<<2))
343 #define RS232_TDR SCI_TDR1
344 #define RS232_RDR SCI_RDR1
345 #define RS232_SMR SCI_SMR1
346 #define RS232_SCMR SCI_SCMR1
347 #define RS232_SCR SCI_SCR1
348 #define RS232_SSR SCI_SSR1
349 #define RS232_BRR SCI_BRR1
350 #define RS232_RXD_PIN ((*DIO_PORT3)&(1<<4))
353 #define RS232_BAUD_RAW 0xff00
355 int SCIInit(unsigned baud)
360 /*disable SCI interrupts and Rx/Tx machine*/
364 if((baud&RS232_BAUD_RAW)!=RS232_BAUD_RAW){
365 divisor=div_us_ulus((CPU_SYS_HZ/16),baud);
367 if(++cks>=4) return -1;
370 divisor=(divisor+1)>>1;
374 *RS232_BRR=divisor-1;
376 *RS232_SMR=(SMR_CKSxm&cks);
379 *RS232_SCR=SCR_TEm|SCR_REm;
383 volatile int SCISend(unsigned char c)
385 unsigned int i=50000;
386 while((*RS232_SSR & SSR_TDREm)==0 && i>0) i--;
389 *RS232_SSR=~SSR_TDREm&0xff;
393 volatile int SCIReceive(unsigned char *c,unsigned int time)
397 while(!((ssr=*RS232_SSR) & SSR_RDRFm) && ((time--)>0))
398 if(ssr&(SSR_ORERm|SSR_FERm)) break;
399 if (time==0) return -1;
402 while(!((ssr=*RS232_SSR) & SSR_RDRFm))
403 if(ssr&(SSR_ORERm|SSR_FERm)) break;
406 *RS232_SSR=~(SSR_RDRFm|SSR_MPBTm);
407 if(ssr & (SSR_ORERm|SSR_FERm)){
408 *RS232_SSR=~(SSR_ORERm|SSR_FERm|SSR_MPBTm);
414 unsigned long GetAdr()
419 a=((unsigned long)c << 24);
421 a=a | (((unsigned long)c << 16) & 0xff0000);
423 a=a | (((unsigned long)c << 8) & 0xff00);
425 a=a | ((unsigned long)c & 0xff);
426 SCISend((a >> 24) & 0xFF);
427 SCISend((a >> 16) & 0xFF);
428 SCISend((a >> 8) & 0xFF);
433 int SCIAutoBaud(void)
438 /* Disable power-on reset of WDT owerflow */
439 *WDT_WRSTCSRw=(0x5a00 | 1*WRSTCSR_RSTEm | 0*WRSTCSR_RSTSm);
440 /* Select watchdog function and input clocks */
441 *WDT_WTCSR0w=(0xa500 | 1*WTCSR0_WTITm |(1 & WTCSR0_CKSxm));
442 *WDT_WTCSR0w=(0xa500 | 1*WTCSR0_WTITm | 1*WTCSR0_TMEm | (1 & WTCSR0_CKSxm));
444 while(!RS232_RXD_PIN) *WDT_WTCNT0w=(0x5a00);
445 while(RS232_RXD_PIN) *WDT_WTCNT0w=(0x5a00);
451 *WDT_WTCNT0w=(0x5a00);
460 /* Disable watchdog */
461 *WDT_WTCSR0w=(0xa500);
463 SCIInit(((t*2+7)/9)|RS232_BAUD_RAW);
468 #ifdef WITH_EXTERNAL_FLASH
470 #define EXTFL_addr_mask 0x0ffffl
471 #define EXTFL_reg1_addr (0x555*2l)
472 #define EXTFL_reg2_addr (0x2aa*2l)
473 #define EXTFL_sec_size 0x10000
474 #define EXTFL_width8 0
475 #define EXTFL_cmd_unlock1 0xaaaa /* reg1 */
476 #define EXTFL_cmd_unlock2 0x5555 /* reg2 */
477 #define EXTFL_cmd_rdid 0x9090 /* reg1 */
478 #define EXTFL_cmd_prog 0xa0a0 /* reg1 */
479 #define EXTFL_cmd_erase 0x8080 /* reg1 */
480 #define EXTFL_cmd_reset 0xf0f0 /* any */
481 #define EXTFL_erase_all 0x1010 /* reg1 */
482 #define EXTFL_erase_sec 0x3030 /* sector */
483 #define EXTFL_fault_bit 0x2020
484 #define EXTFL_manid 1
485 #define EXTFL_devid 0x2258
487 #define FLASH_WR16(addr,val) (*(volatile __u16*)(addr)=(val))
488 #define FLASH_RD16(addr) (*(volatile __u16*)(addr))
490 /* Program data to address */
491 int ExtFlProgRow(__u8 *addr, __u8 *data)
497 __u32 a=(__u32)addr&~EXTFL_addr_mask;
499 val=*((__u16*)data)++;
500 /* security sequence */
501 FLASH_WR16(a+EXTFL_reg1_addr,EXTFL_cmd_unlock1);
503 FLASH_WR16(a+EXTFL_reg2_addr,EXTFL_cmd_unlock2);
505 /* program command */
506 FLASH_WR16(a+EXTFL_reg1_addr,EXTFL_cmd_prog);
508 FLASH_WR16(addr,val);
510 /* wait for result */
511 old=FLASH_RD16(addr);
513 while((new=FLASH_RD16(addr))!=old){
515 if((old&EXTFL_fault_bit)&&(new&EXTFL_fault_bit)){
516 if((FLASH_RD16(addr))!=new) ret=-2;
522 FLASH_WR16(a,EXTFL_cmd_reset);
524 if(FLASH_RD16(addr)!=val) return -3;
530 int ExtFlErase(__u8 *addr)
534 __u32 a=(__u32)addr&~EXTFL_addr_mask;
535 /* security sequence */
536 FLASH_WR16(a+EXTFL_reg1_addr,EXTFL_cmd_unlock1);
538 FLASH_WR16(a+EXTFL_reg2_addr,EXTFL_cmd_unlock2);
541 FLASH_WR16(a+EXTFL_reg1_addr,EXTFL_cmd_erase);
543 /* security sequence */
544 FLASH_WR16(a+EXTFL_reg1_addr,EXTFL_cmd_unlock1);
546 FLASH_WR16(a+EXTFL_reg2_addr,EXTFL_cmd_unlock2);
548 /* select erase range */
550 FLASH_WR16(a+EXTFL_reg1_addr,EXTFL_erase_all);
552 old=FLASH_RD16(addr);
554 while((new=FLASH_RD16(addr))!=old){
556 if((old&EXTFL_fault_bit)&&(new&EXTFL_fault_bit)){
557 if((FLASH_RD16(addr))!=new) ret=-2;
563 FLASH_WR16(a,EXTFL_cmd_reset);
565 if(FLASH_RD16(addr)!=0xffff) ret--;
569 #endif /*WITH_EXTERNAL_FLASH*/
571 void Call(unsigned long adr)
573 __asm__ /*__volatile__*/(
580 void ProgMode(unsigned baud)
594 if(baud) SCIInit(baud);
596 if(!baud) SCIAutoBaud();
604 DEB_WR_HEX(cmd,2); /*!!!*/
605 if((cmd & 7) == (((cmd >> 3) & 7) ^ 7)){
608 if((cmd<=2)||(cmd==4)){
609 /* memory download/upload/erase region */
613 /* memory download */
616 DEB_WR_HEX(badr,8); /*!!!*/
617 DEB_WR_HEX(len,8); /*!!!*/
618 adr=(unsigned char *)badr;
620 if(SCIReceive(&c,0)<0){
631 /* flash programming */
632 /* check and erase range */
633 /*if(FlPrepBlk(badr,len)<0) e=0xfc;*/
634 i=badr-(badr & 0xffffffe0);
640 adr=(unsigned char *)(badr & ~(FLASH_ROW-1));
641 j=(unsigned char *)badr-adr;
644 if(SCIReceive(&c,0)<0){
650 DEB_WR_HEX((long)adr,6); /*!!!*/
651 if((j=FlProgRow(adr,buf))!=0) e=0xff;
652 DEB_BLOG(0xEA000000|(__u32)adr|((__u8)j&0x7f));
653 DEB_WR_HEX(j,2); /*!!!*/
659 if(j/*&&!(e&0x80)*/){
660 while(j<FLASH_ROW) buf[j++]=0xff;
661 if(FlProgRow(adr,buf)!=0) e=0xff;
665 /* check and erase region */
666 e=FlPrepBlk(badr,len);
673 DEB_WR_HEX(badr,8); /*!!!*/
674 DEB_WR_HEX(len,8); /*!!!*/
675 adr=(unsigned char *)badr;
679 if(SCIReceive(&c,0)<0){
692 if (c<flash_block_count){
693 if(FlErase(c)==0) SCISend(0x5A);
695 #ifdef WITH_EXTERNAL_FLASH
697 if(ExtFlErase((__u8*)EXTERNAL_FLASH_START)==0)
698 SCISend(0x5A); else SCISend(0xFF);
699 #endif /*WITH_EXTERNAL_FLASH*/
704 DEB_WR_HEX(badr,8); /*!!!*/