#include #include #include #include #include #include #include #include "tty.h" static const uint8_t magic[] = {0x2D, 0xC0, 0x3B, 0x5F, 0xEA, 0xE3, 0x1A, 0x3A, 0x83, 0x11, 0x6A, 0x33, 0x98, 0x46, 0x1C, 0x47}; #define ACK 0x05 #define NACK 0x0A #define BLK_SIZE 256 void usage(char *p) { fprintf(stderr, "Usage: %s \n", p); exit(1); } uint32_t crc32x(unsigned char *buf, size_t len, uint32_t crc) { int i; crc = ~crc; while (len--) { crc ^= *buf++; for (i=0; i<8; i++) { uint32_t t = ~((crc & 1) - 1); crc = (crc >> 1) ^ (0xEDB88320 & t); } } return ~crc; } void set_buffer(uint32_t addr, uint8_t *buf) { uint32_t crc32; buf[0] = addr >> 24; buf[1] = addr >> 16; buf[2] = addr >> 8; buf[3] = addr; crc32 = crc32x(buf, BLK_SIZE + sizeof(uint32_t), 0xffffffff); buf[BLK_SIZE + 4] = crc32 >> 24; buf[BLK_SIZE + 5] = crc32 >> 16; buf[BLK_SIZE + 6] = crc32 >> 8; buf[BLK_SIZE + 7] = crc32; } static void _write(int fd, const uint8_t *buf, size_t size) { int rv = 0; do { rv += write(fd, buf + rv, size - rv); } while (rv != size); } int main(int argc, char *argv[]) { int tty_fd, fw_fd; uint8_t buf[BLK_SIZE + 2 * sizeof(uint32_t)]; uint32_t addr; int rv; if (argc != 3) { usage(argv[0]); } tty_fd = tty_open(argv[1]); if (tty_fd < 0) { fprintf(stderr, "TTY OPEN ERROR %i: %s\n", errno, strerror(errno)); return 1; } fw_fd = open(argv[2], O_RDONLY); if (fw_fd < 0) { fprintf(stderr, "FW OPEN ERROR %i: %s\n", errno, strerror(errno)); return 1; } while ((rv = read(tty_fd, buf, sizeof(buf)))); _write(tty_fd, magic, sizeof(magic)); *buf = NACK; read(tty_fd, buf, 1); if (*buf != ACK) { fprintf(stderr, "CONNECT ERROR: %x\n", *buf); return 1; } printf("CONNECTED\n"); addr = 0; memset(buf, 0xff, sizeof(buf)); do { rv = read(fw_fd, buf + sizeof(uint32_t), BLK_SIZE); if (rv < 0) { fprintf(stderr, "FW READ ERROR %i: %s\n", errno, strerror(errno)); return 1; } if (rv == 0) { addr = -1; } set_buffer(addr, buf); do { _write(tty_fd, buf, sizeof(buf)); *buf = NACK; read(tty_fd, buf, 1); if (*buf == NACK) { fprintf(stderr, "NACK...\n"); } } while (*buf != ACK); addr += BLK_SIZE; memset(buf, 0xff, sizeof(buf)); } while (rv); close(tty_fd); close(fw_fd); return 0; }