1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#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 <tty> <firmware>\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;
}
|