From: hackbard Date: Sat, 28 Jul 2007 16:05:21 +0000 (+0200) Subject: cleaned lpcload (only init working by now) + added Makefile X-Git-Url: https://hackdaworld.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=06e719791011a2c8eb472943492b7b0b6d445c6f;p=my-code%2Farm.git cleaned lpcload (only init working by now) + added Makefile --- diff --git a/betty/Makefile b/betty/Makefile new file mode 100644 index 0000000..3bff9d0 --- /dev/null +++ b/betty/Makefile @@ -0,0 +1,5 @@ +CC = gcc +CFLAGS = -Wall + +all: lpcload + diff --git a/betty/lpcload.c b/betty/lpcload.c index bdb3948..ff78d96 100644 --- a/betty/lpcload.c +++ b/betty/lpcload.c @@ -14,12 +14,46 @@ #include #include -#define VERBOSE (1<<0) -#define FIRMWARE (1<<1) - -#define CRYSTFREQ "10000" - -#define BUFSIZE 64 +#define VERBOSE (1<<0) +#define FIRMWARE (1<<1) + +#define TXRX_TYPE_BAUD 0x01 +#define TXRX_TYPE_SYNC 0x02 +#define TXRX_TYPE_DATA 0x03 + +#define CMD_SUCCESS "0\r\n" +#define INVALID_COMMAND "1\r\n" +#define SRC_ADDR_ERROR "2\r\n" +#define DST_ADDR_ERROR "3\r\n" +#define SRC_ADDR_NOT_MAPPED "4\r\n" +#define DST_ADDR_NOT_MAPPED "5\r\n" +#define COUNT_ERROR "6\r\n" +#define COMPARE_ERROR "10\r\n" +#define BUSY "11\r\n" +#define PARAM_ERROR "12\r\n" +#define ADDR_ERROR "13\r\n" +#define ADDR_NOT_MAPPED "14\r\n" +#define CMD_LOCKED "15\r\n" +#define INVALID_CODE "16\r\n" +#define INVALID_BAUD_RATE "17\r\n" +#define INVALID_STOP_BIT "18\r\n" + +#define CRYSTFREQ "10000" + +#define BUFSIZE 64 + +typedef unsigned char u8; + +typedef struct s_lpc { + int sfd; /* serial fd */ + char sdev[128]; /* seriel device */ + int fwfd; /* fimrware fd */ + char fwfile[128]; /* firmware file */ + u8 info; /* info/mode */ + char freq[8]; /* frequency */ + int partid; /* part id */ + u8 bcv[2]; /* boot code version */ +} t_lpc; void usage(void) { @@ -31,46 +65,114 @@ void usage(void) { } -int txrx(int fd,char *buf,int *len,unsigned char v) { +int open_serial_device(t_lpc *lpc) { + + struct termios term; + + //memset(&term,0,sizeof(struct termios)); + + /* open serial device */ + + lpc->sfd=open(lpc->sdev,O_RDWR); + if(lpc->sfd<0) { + perror("tts open"); + return lpc->sfd; + } + + /* configure the serial device */ + + tcgetattr(lpc->sfd,&term); + + // input/output baudrate + + cfsetispeed(&term,B9600); + cfsetospeed(&term,B9600); + + // control options -> 8n1 + + term.c_cflag&=~PARENB; // no parity + term.c_cflag&=~CSTOPB; // only 1 stop bit + term.c_cflag&=~CSIZE; // no bit mask for data bits + term.c_cflag|=CS8; // 8 data bits + + // line options -> raw input + + term.c_lflag&=~(ICANON|ECHO|ECHOE|ISIG); + + // input options -> disable flow control + + term.c_iflag&=~(IXON|IXOFF|IXANY); + + // more control options -> timeout + + term.c_cc[VMIN]=0; + term.c_cc[VTIME]=10; // 1 second timeout + + tcsetattr(lpc->sfd,TCSANOW,&term); + + return lpc->sfd; +} + +int open_firmware(t_lpc *lpc) { + + /* open firmware file */ + + lpc->fwfd=open(lpc->fwfile,O_RDONLY); + + if(lpc->fwfd<0) + perror("fw open"); + + return lpc->fwfd; +} + +int txrx(t_lpc *lpc,char *buf,int len,u8 type) { int ret,cnt; int i; /* write */ - if(v&VERBOSE) + if(lpc->info&VERBOSE) printf(" >> "); cnt=0; - while(*len) { - ret=write(fd,buf+cnt,*len); + while(len) { + ret=write(lpc->sfd,buf+cnt,len); if(ret<0) { perror("txrx write"); return ret; } - if(v&VERBOSE) + if(lpc->info&VERBOSE) for(i=0;i0x19)&(buf[cnt+i]<0x7f))? buf[cnt+i]:'.'); - *len-=ret; + len-=ret; cnt+=ret; } - if(v&VERBOSE) + if(lpc->info&VERBOSE) printf(" (%d)\n",cnt); - /* cut the echo */ - // add more checking here! - while(cnt) - cnt-=read(fd,buf,cnt); + /* cut the echo if not of type auto baud */ + + if(type!=TXRX_TYPE_BAUD) { + while(cnt) { + ret=read(lpc->sfd,buf,cnt); + if(ret<0) { + perror("txrx echo cut"); + return ret; + } + cnt-=ret; + } + } /* read */ - if(v&VERBOSE) + if(lpc->info&VERBOSE) printf(" << "); ret=1; cnt=0; while(ret>0) { - ret=read(fd,buf+cnt,BUFSIZE-cnt); + ret=read(lpc->sfd,buf+cnt,BUFSIZE-cnt); if(ret<0) { perror("txrx read"); return ret; @@ -79,40 +181,107 @@ int txrx(int fd,char *buf,int *len,unsigned char v) { printf("txrx read: too small buf size (%d)!\n",BUFSIZE); return -1; } - if(v&VERBOSE) + if(lpc->info&VERBOSE) for(i=0;i0x19)&(buf[cnt+i]<0x7f))? buf[cnt+i]:'.'); cnt+=ret; } - if(v&VERBOSE) + if(lpc->info&VERBOSE) printf(" (%d)\n",cnt); - *len=cnt; + len=cnt; + buf[cnt]='\0'; + + /* check/strip return code if type is data */ + + if(type==TXRX_TYPE_DATA) { + ret=strlen(CMD_SUCCESS); + if(!strncmp(buf,CMD_SUCCESS,ret)) { + for(i=ret;ifreq)+2; + strncpy(buf,lpc->freq,BUFSIZE); + buf[len-2]='\r'; + buf[len-1]='\n'; + txrx(lpc,buf,len,TXRX_TYPE_SYNC); + if(strncmp(buf,"OK\r\n",4)) { + printf("freq set failed\n"); + return -1; + } + + return 0; +} + +int read_part_id(t_lpc *lpc) { + char buf[BUFSIZE]; + memcpy(buf,"J\r\n",3); + txrx(lpc,buf,3,TXRX_TYPE_DATA); + lpc->partid=atoi(buf); + + return lpc->partid; +} + +int read_bcv(t_lpc *lpc) { + + char buf[BUFSIZE]; + char *ptr; + + memcpy(buf,"K\r\n",3); + txrx(lpc,buf,3,TXRX_TYPE_DATA); + ptr=strtok(buf,"\r\n"); + lpc->bcv[0]=strtol(ptr,NULL,16); + ptr=strtok(NULL,"\r\n"); + lpc->bcv[1]=strtol(ptr,NULL,16); + + return 0; +} + +int main(int argc,char **argv) { + + t_lpc lpc; + int i; + /* * initial ... */ - info=0; - memset(&term,0,sizeof(struct termios)); - strncpy(cfreq,CRYSTFREQ,7); + memset(&lpc,0,sizeof(t_lpc)); + strncpy(lpc.freq,CRYSTFREQ,7); /* parse argv */ @@ -125,17 +294,17 @@ int main(int argc,char **argv) { switch(argv[i][1]) { case 'd': - strncpy(tts,argv[++i],127); + strncpy(lpc.sdev,argv[++i],127); break; case 'f': - strncpy(fw,argv[++i],127); - info|=FIRMWARE; + strncpy(lpc.fwfile,argv[++i],127); + lpc.info|=FIRMWARE; break; case 'v': - info|=VERBOSE; + lpc.info|=VERBOSE; break; case 'c': - strncpy(cfreq,argv[++i],7); + strncpy(lpc.freq,argv[++i],7); break; default: usage(); @@ -144,106 +313,25 @@ int main(int argc,char **argv) { } - /* - * open serial device - */ + /* open serial port */ + open_serial_device(&lpc); - tts_fd=open(tts,O_RDWR); - if(tts_fd<0) { - perror("tts open"); - return tts_fd; - } - - /* - * configure serial device - */ - - tcgetattr(tts_fd,&term); - - // input/output baudrate - - cfsetispeed(&term,B9600); - cfsetospeed(&term,B9600); - - // control options -> 8n1 - - term.c_cflag&=~PARENB; // no parity - term.c_cflag&=~CSTOPB; // only 1 stop bit - term.c_cflag&=~CSIZE; // no bit mask for data bits - term.c_cflag|=CS8; // 8 data bits - - // line options -> raw input - - term.c_lflag&=~(ICANON|ECHO|ECHOE|ISIG); - - // input options -> disable flow control - - term.c_iflag&=~(IXON|IXOFF|IXANY); - - // more control options -> timeout - - term.c_cc[VMIN]=0; - term.c_cc[VTIME]=10; // 1 second timeout - - tcsetattr(tts_fd,TCSANOW,&term); - - /* auto baud sequence */ - - printf("auto baud sequence ...\n"); - write(tts_fd,"?",1); - len=0; - txrx(tts_fd,buf,&len,info); - if(strncmp(buf,"Synchronized\r\n",14)) { - printf("auto baud detection failed\n"); - return -1; - } - - /* tell bl that we are synchronized (it's allready in buf) */ - - printf("sync sequence ...\n"); - len=14; - txrx(tts_fd,buf,&len,info); - if(strncmp(buf,"OK\r\n",4)) { - printf("sync failed\n"); - return -1; - } - - /* tell bl the crystal frequency */ - - printf("frequency setting sequence ...\n"); - len=strlen(cfreq)+2; - strncpy(buf,cfreq,BUFSIZE); - buf[len-2]='\r'; - buf[len-1]='\n'; - txrx(tts_fd,buf,&len,info); - if(strncmp(buf,"OK\r\n",4)) { - printf("freq set failed\n"); - return -1; - } + /* boot loader init */ + printf("boot loader init ...\n"); + bl_init(&lpc); /* read part id */ - printf("read part id ...\n"); - len=3; - memcpy(buf,"J\r\n",3); - txrx(tts_fd,buf,&len,info); - buf[len]='\0'; - printf("part id: %d (0x%x)\n",atoi(buf),atoi(buf+3)); + read_part_id(&lpc); + printf("part id: %d\n",lpc.partid); /* read boot code version */ - printf("read boot code version ...\n"); - len=3; - memcpy(buf,"K\r\n",3); - txrx(tts_fd,buf,&len,info); - buf[len]='\0'; - printf("boot code version: %c %c\n",(buf),atoi(buf)); - - - + read_bcv(&lpc); + printf("boot code version: %02x %02x\n",lpc.bcv[0],lpc.bcv[1]); // to be continued ... (parsing fw file and poking it to ram) -end: - close(tts_fd); +//end: + close(lpc.sfd); return 0; }