diff options
Diffstat (limited to 'src/serial.c')
-rw-r--r-- | src/serial.c | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/src/serial.c b/src/serial.c new file mode 100644 index 0000000..53a90a6 --- /dev/null +++ b/src/serial.c @@ -0,0 +1,153 @@ + +/* -------------------------------------------------------------------- + Copyright (C) 2004 Dominic Radermacher <dominic.radermacher@gmail.com> + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + -------------------------------------------------------------------- */ + +#include <stdio.h> +#include <unistd.h> /* tcgetattr, read(), write() */ +#include <termios.h> /* tcgetattr, tcflush() */ +#include <fcntl.h> /* open */ +#include <sys/types.h> /* open */ +#include <sys/stat.h> /* open */ + +#include "hc11tools.h" +#include "serial.h" + +#define SERBUFSIZE 16 + +/* -------------------------------------------------------------------- + Function: serial_open + Revision: 20040801 (use this version !) + -------------------------------------------------------------------- */ + +int serial_open(char *device, int speed, int c_flags) +{ + int fd; + struct termios term; + + if((fd = open(device, O_RDWR)) < 0) { + return -1; + } + if(tcgetattr(fd, &term) < 0) { /* Get current characteristics */ + return -1; + } + cfsetispeed(&term, speed); + cfsetospeed(&term, speed); + cfmakeraw(&term); /* makeraw sets default CS8 */ + term.c_cflag |= c_flags; /* apply c_flags */ + if(tcsetattr(fd, TCSANOW, &term) < 0) { /* Now set everything */ + return -1; + } + return fd; +} + +int serial_setspeed(int fd, int speed) +{ + struct termios term; + + if(tcgetattr(fd, &term) < 0) { + perror("tcgetattr"); + return -1; + } + if(cfsetispeed(&term, speed) < 0) { + perror("cfsetispeed"); + return -1; + } + if(cfsetospeed(&term, speed) < 0) { + perror("cfsetospeed"); + return -1; + } + if(tcsetattr(fd, TCSANOW, &term) < 0) { + perror("tcsetattr"); + return -1; + } + return 0; +} + +int serial_waitrxdata(int fd) +{ + fd_set fds; + struct timeval tv; + + FD_ZERO(&fds); + FD_SET(fd, &fds); + tv.tv_sec = 2; + tv.tv_usec = 0; + return select(fd+1, &fds, NULL, NULL, &tv); +} + +int serial_rx_empty(int fd) +{ + fd_set fds; + struct timeval tv; + + FD_ZERO(&fds); + FD_SET(fd, &fds); + tv.tv_sec = 0; + tv.tv_usec = 10; + return select(fd+1, &fds, NULL, NULL, &tv); +} + +int upload_firmware(int fd, struct obj *bo) +{ + int i, size, len, trig; + uint8_t buf[1]; + + trig=SERBUFSIZE/2; + + tcflush(fd, TCIOFLUSH); + printf("Press reset on the HC11 board ... "); + fflush(stdout); + while(serial_waitrxdata(fd) == 0); + printf("ok, got BRK\n"); + if(read(fd, buf, 1) != 1) { + return -1; + } + sleep(1); + printf("Sending upload request code (0xff)\n"); + buf[0]=0xff; + if(write(fd, buf, 1) != 1) { /* send upload code */ + return -1; + } + size=bo->end_addr-bo->start_addr; + printf("Uploading firmware (%i bytes) ... ", size); + fflush(stdout); + tcflush(fd, TCIOFLUSH); + write(fd, &bo->code[0], SERBUFSIZE); + for(i=0; i<size; i++) { + if((i > 0) && ((i+trig)%trig == 0)) { + len=size-(i+trig); + if(len > trig) { + len=trig; + } + write(fd, &bo->code[i+trig], len); + } + if(serial_waitrxdata(fd) == 0) { + fprintf(stderr, "serial.c:138: reply timeout - board not ready ?\n"); + return -1; + } + if(read(fd, buf, 1) != 1) { + fprintf(stderr, "serial.c:142: read error\n"); + return -1; + } + if(buf[0] != bo->code[i]) { + fprintf(stderr, "serial.c:146: byte #%i: %02x != %02x\n", i, buf[0], bo->code[i]); + return -1; + } + fflush(stdout); + } + printf("ok\n"); + return 0; +} |