#if 0 cd [file dirname [info script]] source makefile.tcl return #endif #include "uart.h" #include "ascii.h" Uart& Uart::sendString(const U8 *string) { U8 car; while((car=*string)) { sendChar(car); string++; } return *this; } Uart& Uart::sendString(const U8 *string,U32 len) { while(len) { sendChar(*string++); len--; } return *this; } void Uart::sendU32(U32 v,int size) { U8 buf[8]; U8 *pt=buf+size; int len; len=size; while(v && len--) { U8 c=v&0xf; c += c<10 ? '0':'a'-10; *--pt=c; v>>=4; } while(len--) *--pt='0'; sendChar('0'); sendChar('x'); len=size; pt=buf; while(len--) { sendChar(*pt++); } } #ifndef _bur #endif /* _bur */ void Uart::sendHex(U8 v) { U8 c; c=v>>4; c += c<10 ? '0':'a'-10; sendChar(c); c=v&0xf; c += c<10 ? '0':'a'-10; sendChar(c); } void Uart::sendPrintable(U8 v) { if(v<0x20 || v>=0x7f) v='.'; sendChar(v); } void Uart::sendInt(int v) { if(v==0) { sendChar('0'); return; } if(v<0) { sendChar('-'); v=-v; } U8 buf[10]; U8 *pt=buf; int len; len=0; while(v) { *pt='0'+ v%10; v/=10; pt++; len++; } while(len) { pt--; len--; sendChar(*pt); } } void Uart::dump(U8* buf,U32 len,U32 address,U32 increment) { const U32 lineLen=16; len+=(lineLen-1); len&=~(lineLen-1); increment=16/increment; while(len) { U32 dcnt; *this << address << ' '; dcnt=lineLen; while(dcnt--) { sendHex(*buf++); } buf-=lineLen; com1 << " "; dcnt=lineLen; while(dcnt--) { sendPrintable(*buf++); } *this << '\r' << '\n'; len-=lineLen; address+=increment; } } U32 Uart::yload(U8 *address) { volatile struct Trame { U8 asBuf[0]; U8 id; U8 state; U8 minusState; U8 checksumU; U8 checksumL; }trame; //U8 * const cmd=(U8*)0x200000; U8 cmd[1024]; /* cmd[sizeof(cmd)-1]='\0'; *this << "last command : " << (S8*)cmd << "\r\n"; */ U16 cnt; U32 timeout=0; U32 c; U32 dataLen; U8 *pt; U32 remain; U32 size=0; S8 *pb="ok"; while(1) { if(gotChar()) break; if((timeout&0x1fffff)==0) { sendChar('C'); } timeout++; } remain=sizeof(cmd); pt=cmd; while(1) { cnt=0; timeout=0; dataLen=0; while(1) { --timeout; if((timeout&0xfffff)==0) { pb="timeout"; break; } c=getChar(); if(c==~0U) continue; timeout=0; if(dataLen) { if(remain) { *pt++=c; remain--; } dataLen--; } else { trame.asBuf[cnt]=c; cnt++; if(cnt==1) { if(trame.id==Ascii::eot) break; } else if(cnt==3) { if(trame.id!=Ascii::soh && trame.id!=Ascii::stx) { pb="bad id"; break; } if((trame.state ^ trame.minusState) != 0xff) { pb="bad state"; break; } dataLen= (trame.id==Ascii::soh ? 128:1024); } else if(cnt==5) break; } } if(cnt==1 && trame.id==Ascii::eot) { sendChar(Ascii::ack); sendChar('C'); remain=sizeof(cmd); pt=cmd; } else if(cnt==5) { sendChar(Ascii::ack); if(trame.state==0) { sendChar('C'); if(cmd[0]==0x00) break; { U8 *p=cmd; cmd[sizeof(cmd)-1]='\0'; while((c=*p++)) ; size=0; while(1) { c=*p++; if(c=='\0') break; if(c==' ') break; size*=10; size+=c-'0'; } } pt=address; remain=size; } else { if(remain==0) { sendChar('C'); pt=cmd; remain=sizeof(cmd); } } } else { sendChar(Ascii::eot); *this << '\r' << '\n' << trame.id << ' ' << trame.state << ' ' << trame.minusState << ' ' << trame.checksumU << ' ' << trame.checksumL << ' ' << cnt << ' ' << dataLen << ' ' << remain << ' ' << pb << "\r\n"; break; } } /* while(getChar()!='z'); while(getChar()!='z'); while(getChar()!='z'); dump(cmd,sizeof(cmd),0,1); *this <<"\r\n"; *this << size <<"\r\n"; */ return size; } void Uart::init() { #if 1 bsr=0x03; ier=0x00; fcr=0x06; bsr=0xe0; excr1=0x00; bsr=0x03; mcr=0x00; bsr=0x83; lbgdl=12&0xff; lbgdh=12>>16; bsr=0x03; #endif #if 0 struct Init { U8 offset; U8 value; } __attribute__ ((packed)); const Init inits[]= { {((Uart*)0)->bsr.offset(),0x03}, {((Uart*)0)->ier.offset(),0x00}, {((Uart*)0)->fcr.offset(),0x06}, {((Uart*)0)->bsr.offset(),0xe0}, {((Uart*)0)->excr1.offset(),0x00}, {((Uart*)0)->bsr.offset(),0x03}, {((Uart*)0)->mcr.offset(),0x00}, {((Uart*)0)->bsr.offset(),0x83}, {((Uart*)0)->lbgdl.offset(),12&0xff}, {((Uart*)0)->lbgdh.offset(),12>>16}, {((Uart*)0)->bsr.offset(),0x03} }; for(register const Init*init=inits;;init++) { regs[init->offset]=init->value; } #endif }