18 #define verbose(level, ...) \
19 do { if (tohit_verbosity >= (level)) { printf("tohit: " __VA_ARGS__); } } while (0)
21 //#define WITHOUT_CFSETSPEED
23 #ifdef WITHOUT_CFSETSPEED
26 struct rs232_speed_struct
32 static const struct rs232_speed_struct rs232_speeds[] =
108 /* Set both the input and output baud rates stored in *TERMIOS_P to SPEED. */
110 rs232_cfsetspeed (struct termios *termios_p, speed_t speed)
114 for (cnt = 0; cnt < sizeof (rs232_speeds) / sizeof (rs232_speeds[0]); ++cnt)
115 if (speed == rs232_speeds[cnt].internal)
117 cfsetispeed (termios_p, speed);
118 cfsetospeed (termios_p, speed);
121 else if (speed == rs232_speeds[cnt].value)
123 cfsetispeed (termios_p, rs232_speeds[cnt].internal);
124 cfsetospeed (termios_p, rs232_speeds[cnt].internal);
127 /*__set_errno (EINVAL);*/
132 #endif /* WITHOUT_CFSETSPEED */
134 /* Set right mode and speed for RS232 interface */
135 /* baud can be either speed in character per second or special Bxxxx constant */
136 int rs232_setmode(int fd, int baud, int mode, int flowc)
140 /* Flush input and output queues. */
141 if (tcflush(fd, TCIOFLUSH) != 0) {
142 fprintf(stderr,"Error in tcflush\n");
146 /* Fetch the current terminal parameters. */
147 if (tcgetattr(fd, &ts) != 0) {
148 fprintf(stderr,"Error in tcgetattr\n");
152 /* Sets hardware control flags: */
154 /* Enable receiver */
155 /* Ignore CD (local connection) */
156 ts.c_cflag = CS8 | CREAD | CLOCAL;
158 /* Use RTS/CTS flow control */
159 ts.c_cflag |= CRTSCTS; /* CCTS_OFLOW | CRTS_IFLOW */
162 ts.c_oflag = NL0 | CR0 | TAB0 | BS0 | VT0 | FF0;
165 /* set right ispeed and ospeed */
166 #ifdef WITHOUT_CFSETSPEED
167 if(rs232_cfsetspeed(&ts,baud)<0){
168 fprintf(stderr,"Error in rs232_cfsetspeed\n");
171 #else /* WITHOUT_CFSETSPEED */
172 if(cfsetspeed(&ts,baud)<0){
173 fprintf(stderr,"Error in cfsetspeed\n");
176 #endif /* WITHOUT_CFSETSPEED */
178 ts.c_cc[VINTR] = '\0';
179 ts.c_cc[VQUIT] = '\0';
180 ts.c_cc[VERASE] = '\0';
181 ts.c_cc[VKILL] = '\0';
182 ts.c_cc[VEOF] = '\0';
183 ts.c_cc[VTIME] = '\0';
185 ts.c_cc[VSWTC] = '\0';
186 ts.c_cc[VSTART] = '\0';
187 ts.c_cc[VSTOP] = '\0';
188 ts.c_cc[VSUSP] = '\0';
189 ts.c_cc[VEOL] = '\0';
190 ts.c_cc[VREPRINT] = '\0';
191 ts.c_cc[VDISCARD] = '\0';
192 ts.c_cc[VWERASE] = '\0';
193 ts.c_cc[VLNEXT] = '\0';
194 ts.c_cc[VEOL2] = '\0';
196 /* Sets the new terminal parameters. */
197 if (tcsetattr(fd, TCSANOW, &ts) != 0) {
198 fprintf(stderr,"Error in tcsetattr\n");
205 int rs232_sendch(int fd,unsigned char c)
207 verbose(3, " > sending 0x%02X\n", c);
208 if(write(fd, &c, 1) != 1){
209 fprintf(stderr,"Error in rs232_sendch\n");
216 int rs232_recch(int fd)
220 /* const char *message; */
223 recieved=read(fd, &c, 1);
225 }while(trycount-- && (recieved==-1) && ((errno==EINTR)||(errno==EAGAIN)));
228 fprintf(stderr,"Timeout in rs232_recch\n");
232 fprintf(stderr,"Error in rs232_recch errno = %d\n", errno);
233 perror("rs232_recch");
234 printf("Read 0x%02X a recieved:%d \n",c,recieved);
238 verbose(3, " < read 0x%02X \n",c);
243 int rs232_test(int fd,int time)
249 if(time<tohit_waitrep)
255 x=select(fd + 1, &rfds, NULL, NULL, &tv);
257 printf("rs232_test %d ",x);
262 void tohit_sendi(int fd,long a, int bytes)
265 rs232_sendch(fd,(a>>(8*bytes)) & 0xFF);
269 long tohit_reci(int fd, int bytes)
274 rs232_test(fd,500000);
282 int tohit_sendichk(int fd,long a, int bytes)
284 tohit_sendi(fd,a,bytes);
285 rs232_test(fd,500000);
286 if(tohit_reci(fd,bytes)!=a)
291 /* Synchronize with target */
292 int tohit_synchronize(int fd)
296 verbose(1, "Synchronizing with target\n");
302 if(rs232_test(fd,500000)>0){
313 printf("Error timeout\n");
317 /* Run 55=>AA synchronization */
321 rs232_sendch(fd,0x55);
322 rs232_test(fd,500000);
328 printf("Error in AA reply\n");
334 const char *cmd_name[] = {
335 [1+TOHIT_WRITEBB] = "WRITEBB",
336 [1+TOHIT_WRITE] = "WRITE",
337 [1+TOHIT_WRITEFL] = "WRITEFL",
338 [1+TOHIT_READ] = "READ",
339 [1+TOHIT_ERASEBL] = "ERASEBL",
340 [1+TOHIT_ERASEREG] = "ERASEREG",
341 [1+TOHIT_GOTO] = "GOTO",
342 [1+TOHIT_RESET] = "RESET"
345 const char *boot_err[] = {
346 [EBOOT_PROG_FAILURE] = "Flash programming failure (damaged flash?)",
347 [EBOOT_EXT_FLASH_VERIFY] = "External flash verify failed",
348 [EBOOT_FLASH_VERIFY] = "Flash verify failed",
349 [EBOOT_ROW_NOT_ERASED] = "Flash row was not erased",
350 [EBOOT_NO_FWE] = "Flash write not enabled (FWE pin)",
351 [EBOOT_ROW_BEGIN] = "Programming starts in the middle of a row",
352 [EBOOT_BLOCKADDR] = "Wrong flash block start/end address",
353 [EBOOT_BLNUM_HIGH] = "Flash block number to high",
354 [EBOOT_BLNUM_LOW] = "Flash block number to low (negative)",
355 [EBOOT_FLASH_ERROR] = "Flash error indicated",
356 [EBOOT_ERASE_FAILURE] = "Flash erase failure"
359 #define ARR_SIZE(x) (sizeof(x)/sizeof(x[0]))
362 int tohit_open4cmd(char *sdev, int baud, int cmd)
367 /* Open RS232 device */
368 if ((fd = open(sdev, O_RDWR | O_NONBLOCK)) == -1) {
369 printf("Error openning %s\n",sdev);
373 /* Set RS232 device mode and speed */
374 if(rs232_setmode(fd,baud,0,0)<0){
375 printf("Error in rs232_setmode\n");
379 /* Synchronize with target */
380 if(tohit_synchronize(fd)<0){
381 printf("Error in tohit_synchronize\n");
387 verbose(1, "Sending command 0x%02X (%s)\n", cmd, cmd_name[1+cmd]);
388 c=cmd | ((cmd ^ 7) << 3);
390 rs232_test(fd,500000);
391 if ((c | 0x80)!=rs232_recch(fd)) {
392 printf("Error in cmd reply\n");
399 int tohit_cmdrepchk(int fd)
402 verbose(2, "Waiting for end reply\n");
403 rs232_test(fd,3000000);
406 printf("Error no end reply\n");
409 if (res!=0xAA && res!=0x5a) {
410 int err = (int)(signed char)res;
411 printf("Error in end reply - received 0x%02X == %d (%s)\n",
413 (err < 0 && -err < ARR_SIZE(boot_err)) ? boot_err[-err] : NULL);
421 char *tohit_sdev="/dev/ttyS1";
425 int tohit_goto(unsigned long adr)
428 if((fd=tohit_open4cmd(tohit_sdev, tohit_baud, TOHIT_GOTO))<0)
430 printf("Error in tohit_open4cmd\n");
435 verbose(2, "Sending go address 0x%08lx\n", adr);
436 if (tohit_sendichk(fd,adr,4)<0) {
437 printf("Error in goto adr send and reply\n");
446 void print_flash_error(int err)
448 printf("Flash error: %s\n",
449 (err >= 0 && err < ARR_SIZE(boot_err)) ? boot_err[err] : "unknown error");
452 int tohit_writemem(int cmd, const unsigned char *buf,
453 unsigned long adr, unsigned long size, int blockmode)
460 unsigned char rbuf[128];
462 if((blockmode==1)||(blockmode>128)) blockmode=128;
464 if((fd=tohit_open4cmd(tohit_sdev, tohit_baud, cmd))<0)
466 printf("Error in tohit_open4cmd\n");
470 if(cmd==TOHIT_WRITEBB){
471 verbose(2, "Sending size 0x%04lx\n", size);
472 if (tohit_sendichk(fd,size,2)<0) {
473 printf("Error in start adr send and reply\n");
478 verbose(2, "Sending address 0x%08lx\n", adr);
479 if (tohit_sendichk(fd,adr,4)<0) {
480 printf("Error in start adr send and reply\n");
484 verbose(2, "Sending size 0x%08lx\n", size);
485 if (tohit_sendichk(fd,size,4)<0) {
486 printf("Error in size send and reply\n");
493 printf("Data send\n");
496 verbose(2, "Writing in single byte mode\n");
498 rs232_sendch(fd,buf[i]);
499 rs232_test(fd,500000);
502 if (i % FLASH_ROW == FLASH_ROW-1) {
503 print_flash_error(rbuf[i]);
505 printf("Error in data reply (expected 0x%02x, received 0x%02x)\n", buf[i], c);
518 }else{ /*TOHIT_WRITEFL*/
520 verbose(2, "Writing in block mode (block size=%d)\n", blockmode);
521 count=blockmode-(adr&(blockmode-1));
523 if(count>(size-i)) count=size-i;
525 verbose(3, " writing %d bytes\n",count);
529 k=write(fd, buf+i+j, count-j);
531 if((k<=0)||(j>count)){
533 printf("Error in blk write (%d,%d)\n",j,k);
539 verbose(3, " reading %d bytes\n",count);
542 if ((i+j) % FLASH_ROW == FLASH_ROW - 1) {
543 verbose(3, " waiting for flashing a row\n");
544 rs232_test(fd,2/*sec*/*1000000);
546 rs232_test(fd,500000);
548 k=read(fd, rbuf+j, count-j);
553 printf("Error in blk write - no reply (%d,%d)\n",j,k);
558 if (tohit_verbosity < 3) {
562 for(j=0;j<count;j++){
563 if (rbuf[j]!=buf[i+j]) {
564 if (i+j % FLASH_ROW == FLASH_ROW-1) {
565 print_flash_error(rbuf[j]);
567 printf("Error in data reply at position %d\n", j);
570 for (k=j; k < count && k < j+8; k++)
571 printf(" 0x%02x", rbuf[j+k]);
572 printf("\nReceived:");
573 for (k=j; k < count && k < j+8; k++)
574 printf(" 0x%02x", buf[i+j+k]);
587 if(tohit_cmdrepchk(fd)<0){
588 printf("Error no end reply\n");
596 int tohit_readmem(int cmd, unsigned char *buf,
597 unsigned long adr, unsigned long size, int blockmode)
603 if((fd=tohit_open4cmd(tohit_sdev, tohit_baud, cmd))<0)
605 printf("Error in tohit_open4cmd\n");
609 verbose(2, "Sending address 0x%08lx\n", adr);
610 if (tohit_sendichk(fd,adr,4)<0) {
611 printf("Error in start adr send and reply\n");
615 verbose(2, "Sending size 0x%08lx\n", size);
616 if (tohit_sendichk(fd,size,4)<0) {
617 printf("Error in size send and reply\n");
622 /* Read memory by single byte */
624 rs232_test(fd,500000);
625 if((c=rs232_recch(fd))<0){
626 printf("Error in receive char\n");
642 if(tohit_cmdrepchk(fd)<0){
643 printf("Error no end reply\n");
648 /* Read memory by blocks */
650 if(size-i>blockmode) c=blockmode;
653 while(rs232_sendch(fd,0)<0);
655 rs232_test(fd,500000);
656 ret=read(fd,buf+i+k,c-k);
658 printf("Error in block receive\n");
668 if(rs232_recch(fd)!=0xff){
669 printf("Error no end reply\n");
678 int tohit_blockerase(int block)
682 if((fd=tohit_open4cmd(tohit_sdev, tohit_baud, TOHIT_ERASEBL))<0)
684 printf("Error in tohit_open4cmd\n");
689 verbose(2, "Sending block number: %d\n", block);
690 rs232_sendch(fd,block);
691 rs232_test(fd,2000000);
692 rs232_test(fd,2000000);
694 if(tohit_cmdrepchk(fd)<0){
695 printf("Error no end reply\n");
703 int tohit_regerase(unsigned long adr, unsigned long size)
707 if((fd=tohit_open4cmd(tohit_sdev, tohit_baud, TOHIT_ERASEREG))<0)
709 printf("Error in tohit_open4cmd\n");
713 verbose(2, "Sending start address 0x%08lx\n", adr);
714 if (tohit_sendichk(fd,adr,4)<0) {
715 printf("Error in start adr send and reply\n");
719 verbose(2, "Sending size 0x%08lx\n", size);
720 if (tohit_sendichk(fd,size,4)<0) {
721 printf("Error in size send and reply\n");
728 if(tohit_cmdrepchk(fd)<0){
729 printf("Error no end reply\n");
737 int tohit_reset(void)
740 if((fd=tohit_open4cmd(tohit_sdev, tohit_baud, TOHIT_RESET))<0)
742 printf("Error in tohit_open4cmd\n");
750 int tohit_break(void)
756 /* Open RS232 device */
757 if ((fd = open(tohit_sdev, O_RDWR | O_NONBLOCK)) == -1) {
758 printf("Error openning %s\n",tohit_sdev);
762 if(rs232_setmode(fd,tohit_baud/2,0,0)<0)
768 verbose(1, "Sending break chars \n");