12 static int setup(int fd)
14 speed_t ispeed, ospeed;
18 memset(&tty, 0, sizeof(tty));
20 ret = tcgetattr(fd, &tty);
27 tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
28 | INLCR | IGNCR | ICRNL | IXON);
29 tty.c_oflag &= ~OPOST;
30 tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
31 tty.c_cflag &= ~(CSIZE | PARENB);
35 //tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
37 ret = tcsetattr(fd, TCSANOW, &tty);
46 static int write_to_cart(int fd, const void *data, size_t size)
50 ret = write(fd, data, size);
60 static int read_from_cart(int fd, void *data, size_t size)
64 ret = read(fd, data, size);
65 if (ret != (int)size) {
74 #define send_cmd(fd, cmd) \
75 write_to_cart(fd, cmd, sizeof(cmd) - 1)
77 static int read_check_byte(int fd, char expect)
82 ret = read_from_cart(fd, &r, 1);
84 fprintf(stderr, "missing response, need '%c'\n", expect);
89 fprintf(stderr, "unexpected response: '%c', need '%c'\n",
97 static int write_with_check(int fd, const void *data, size_t size, char chk)
101 ret = write_to_cart(fd, data, size);
105 ret = read_check_byte(fd, chk);
108 fprintf(stderr, "data sent: '%16s'\n",
117 #define send_cmd_check_k(fd, cmd) \
118 write_with_check(fd, cmd, sizeof(cmd) - 1, 'k')
120 int main(int argc, char *argv[])
122 const char *portname = "/dev/ttyUSB0";
131 fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
139 send_cmd_check_k(fd, " *T");
143 f = fopen(argv[1], "rb");
149 fseek(f, 0, SEEK_END);
151 fseek(f, 0, SEEK_SET);
152 if (size > 0xf00000) {
153 fprintf(stderr, "size too large: %zd\n", size);
157 blocks = (size + 0xffff) >> 16;
159 write_with_check(fd, &blocks, 1, 'k');
161 // at this point, 'd' will arrive even if we don't
162 // write any more data, what's the point of that?
164 for (i = 0; i < blocks; i++) {
165 ret = fread(buf, 1, sizeof(buf), f);
166 if (i != blocks - 1 && ret != sizeof(buf)) {
167 fprintf(stderr, "failed to read block %d/%d\n",
170 if (ret < sizeof(buf))
171 memset(buf + ret, 0, sizeof(buf) - ret);
173 write_to_cart(fd, buf, sizeof(buf));
176 ret = read_check_byte(fd, 'd');
180 send_cmd_check_k(fd, "*rm");