• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

修訂4bf9efba35113d91b56fb25ce16d6dd829b9195d (tree)
時間2011-04-27 01:08:59
作者Yoshinori Sato <ysato@user...>
CommiterYoshinori Sato

Log Message

RX with USB support.

Change Summary

差異

--- a/Makefile
+++ b/Makefile
@@ -1,17 +1,21 @@
11 CC = gcc
22 CFLAGS = -Wall -O2 -g
3-OBJS = main.o comm.o
3+OBJS = main.o comm.o serial.o usb.o
44 TARGET= h8flash
55
66 all: h8flash
77
8-$(TARGET): main.o comm.o
9- $(CC) -o $(TARGET) $(OBJS)
8+$(TARGET): $(OBJS)
9+ $(CC) -o $(TARGET) $(OBJS) -lusb
1010
1111 main.o: main.c h8flash.h
1212
1313 comm.o: comm.c h8flash.h
1414
15+serial.o: serial.c h8flash.h
16+
17+usb.o: usb.c
18+
1519 .phony: clean
1620
1721 clean:
--- a/comm.c
+++ b/comm.c
@@ -16,82 +16,59 @@
1616 #include <termios.h>
1717 #include <fcntl.h>
1818 #include <stdlib.h>
19+#include <errno.h>
1920 #include "h8flash.h"
2021
2122 #define TRY1COUNT 60
2223 #define BAUD_ADJUST_LEN 30
2324
24-#define ACK 0x06
25-
26-#define QUERY_DEVICE 0x20
27-#define QUERY_DEVICE_RES 0x30
28-#define QUERY_CLOCKMODE 0x21
29-#define QUERY_CLOCKMODE_RES 0x31
30-#define QUERY_MULTIRATE 0x22
31-#define QUERY_MULTIRATE_RES 0x32
32-#define QUERY_FREQ 0x23
33-#define QUERY_FREQ_RES 0x33
34-#define QUERY_BOOT_AREA 0x24
35-#define QUERY_BOOT_AREA_RES 0x34
36-#define QUERY_USER_AREA 0x25
37-#define QUERY_USER_AREA_RES 0x35
38-#define QUERY_WRITESIZE 0x27
39-#define QUERY_WRITESIZE_RES 0x37
40-
41-#define SELECT_DEVICE 0x10
42-#define SET_CLOCKMODE 0x11
43-
44-#define SET_BITRATE 0x3f
45-
46-#define WRITEMODE 0x40
47-#define WRITE_USERBOOT 0x42
48-#define WRITE_USER 0x43
49-#define BLANKCHECK_USERBOOT 0x4c
50-#define BLANKCHECK_USER 0x4d
51-#define WRITE128 0x50
52-
5325 /* NAK answer list */
5426 const unsigned char naktable[] = {0x80, 0x90, 0x91, 0xbf, 0xc0, 0xc2, 0xc3, 0xc8,
5527 0xcc, 0xcd, 0xd0, 0xd2, 0xd8};
5628
57-/* send multibyte command */
58-static void send(int ser_fd, char *data, int len)
29+/* big endian to cpu endian convert 32bit */
30+static __inline__ int getlong(unsigned char *p)
5931 {
60- unsigned char sum;
61- write(ser_fd, data, len);
62- for(sum = 0; len > 0; len--, data++)
63- sum += *data;
64- sum = 0x100 - sum;
65- write(ser_fd, &sum, 1);
32+ return (*p << 24) | (*(p+1) << 16) | (*(p+2) << 8) | *(p+3);
33+}
34+
35+/* big endian to cpu endian convert 16bit */
36+static __inline__ short getword(unsigned char *p)
37+{
38+ return (*p << 8) | *(p+1);
6639 }
6740
68-/* receive 1byte */
69-static int receive_byte(int ser_fd, char *data)
41+/* cpu endian to big endian 32bit */
42+static __inline__ void setlong(unsigned char *buf, unsigned long val)
7043 {
71- int r;
72- struct timeval tv;
73- fd_set fdset;
74-
75- *data = 0;
76- tv.tv_sec = 60;
77- tv.tv_usec = 0;
78- FD_ZERO(&fdset);
79- FD_SET(ser_fd, &fdset);
80- r = select(ser_fd + 1, &fdset, NULL, NULL, &tv);
81- if (r == -1)
82- return -1;
83- return read(ser_fd, data, 1);
44+ *(buf + 0) = (val >> 24) & 0xff;
45+ *(buf + 1) = (val >> 16) & 0xff;
46+ *(buf + 2) = (val >> 8) & 0xff;
47+ *(buf + 3) = (val ) & 0xff;
48+}
49+
50+/* send multibyte command */
51+static void send(struct port_t *p, unsigned char *data, int len)
52+{
53+ unsigned char sum;
54+ p->send_data(data, len);
55+ if (len > 1) {
56+ for(sum = 0; len > 0; len--, data++)
57+ sum += *data;
58+ sum = 0x100 - sum;
59+ p->send_data(&sum, 1);
60+ }
8461 }
8562
8663 /* receive answer */
87-static int receive(int ser_fd, char *data)
64+static int receive(struct port_t *p, unsigned char *data)
8865 {
8966 int len;
9067 unsigned char *rxptr;
9168 unsigned char sum;
9269
9370 rxptr = data;
94- if (receive_byte(ser_fd, rxptr) != 1)
71+ if (p->receive_byte(rxptr) != 1)
9572 return -1;
9673 rxptr++;
9774 /* ACK */
@@ -100,19 +77,19 @@ static int receive(int ser_fd, char *data)
10077 }
10178 /* NAK */
10279 if (memchr(naktable, *data, sizeof(naktable))) {
103- if (receive_byte(ser_fd, rxptr) != 1)
80+ if (p->receive_byte(rxptr) != 1)
10481 return -1;
10582 else
10683 return 2;
10784 }
10885
10986 /* multibyte response */
110- if (receive_byte(ser_fd, rxptr) != 1)
87+ if (p->receive_byte(rxptr) != 1)
11188 return -1;
11289 rxptr++;
11390 len = *(data + 1) + 1;
11491 for(; len > 0; len--) {
115- if (receive_byte(ser_fd, rxptr) != 1)
92+ if (p->receive_byte(rxptr) != 1)
11693 return -1;
11794 rxptr++;
11895 }
@@ -129,124 +106,8 @@ static int receive(int ser_fd, char *data)
129106 return *(data + 1);
130107 }
131108
132-/* big endian to cpu endian convert 32bit */
133-static __inline__ int getlong(unsigned char *p)
134-{
135- return (*p << 24) | (*(p+1) << 16) | (*(p+2) << 8) | *(p+3);
136-}
137-
138-/* big endian to cpu endian convert 16bit */
139-static __inline__ short getword(unsigned char *p)
140-{
141- return (*p << 8) | *(p+1);
142-}
143-
144-/* cpu endian to big endian 32bit */
145-static __inline__ void setlong(unsigned char *buf, unsigned long val)
146-{
147- *(buf + 0) = (val >> 24) & 0xff;
148- *(buf + 1) = (val >> 16) & 0xff;
149- *(buf + 2) = (val >> 8) & 0xff;
150- *(buf + 3) = (val ) & 0xff;
151-}
152-
153-/* set host bitrate */
154-static int setbaud(int ser_fd, int bitrate)
155-{
156- int b;
157- struct termios serattr;
158-
159- b = 0;
160- switch (bitrate) {
161- case 96: b = B9600; break;
162- case 192: b = B19200; break;
163- case 384: b = B38400; break;
164- case 576: b = B57600; break;
165- case 1152: b = B115200; break;
166- }
167- if (b == 0)
168- return 0;
169-
170- tcgetattr(ser_fd, &serattr);
171- cfsetospeed(&serattr, b);
172- cfsetispeed(&serattr, b);
173- tcsetattr(ser_fd, TCSANOW, &serattr);
174- return 1;
175-}
176-
177-/* host serial open */
178-int open_serial(const char *ser_port)
179-{
180- int ser_fd;
181- struct termios serattr;
182-
183- ser_fd = open(ser_port, O_RDWR);
184- if (ser_fd == -1) {
185- perror("PROGNAME: ");
186- return -1;
187- }
188-
189- tcgetattr(ser_fd, &serattr);
190- serattr.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON | IXOFF);
191- serattr.c_oflag &= ~OPOST;
192- serattr.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
193- serattr.c_cflag &= ~(CSIZE | PARENB);
194- serattr.c_cflag |= CS8 | CLOCAL;
195- serattr.c_cc[VMIN] = 1;
196- serattr.c_cc[VTIME] = 0;
197- cfsetospeed(&serattr, B9600);
198- cfsetispeed(&serattr, B9600);
199- tcsetattr(ser_fd, TCSANOW, &serattr);
200-
201- return ser_fd;
202-}
203-
204-/* connection target CPU */
205-int connect_target(int ser_fd)
206-{
207- int try1;
208- int r;
209- struct timeval tv;
210- fd_set fdset;
211- unsigned char buf[BAUD_ADJUST_LEN];
212-
213- /* wait connection establish */
214- for(try1 = 0; try1 < TRY1COUNT; try1++) {
215- memset(buf, 0x00, BAUD_ADJUST_LEN);
216- /* send dummy data */
217- write(ser_fd, buf, BAUD_ADJUST_LEN);
218- tv.tv_sec = 1;
219- tv.tv_usec = 0;
220- FD_ZERO(&fdset);
221- FD_SET(ser_fd, &fdset);
222- /* wait reply */
223- r = select(ser_fd + 1, &fdset, NULL, NULL, &tv);
224- if (r == -1)
225- return 0;
226- if ((r > 0) && (read(ser_fd, buf, 1) == 1) && buf[0] == 0)
227- goto connect;
228- if (try1 == 0) {
229- printf("now connection");
230- fflush(stdout);
231- } else {
232- putchar('.');
233- fflush(stdout);
234- }
235- }
236- putchar('\n');
237- return 0;
238- connect:
239- /* connect done */
240- buf[0] = 0x55;
241- write(ser_fd, buf, 1);
242- if ((receive_byte(ser_fd, buf) == 1) && (buf[0] == 0xe6))
243- return 1; /* ok */
244- else
245- return 0; /* ng */
246-}
247-
248109 /* get target device list */
249-struct devicelist_t *get_devicelist(int ser_fd)
110+struct devicelist_t *get_devicelist(struct port_t *port)
250111 {
251112 unsigned char rxbuf[255+3];
252113 unsigned char *devp;
@@ -254,14 +115,14 @@ struct devicelist_t *get_devicelist(int ser_fd)
254115 int devno;
255116
256117 rxbuf[0] = QUERY_DEVICE;
257- write(ser_fd, rxbuf, 1);
258- if (receive(ser_fd, rxbuf) == -1)
118+ send(port, rxbuf, 1);
119+ if (receive(port, rxbuf) == -1)
259120 return NULL;
260121 if (rxbuf[0] != QUERY_DEVICE_RES)
261122 return NULL;
262123
263124 devno = rxbuf[2];
264- devlist = (struct devicelist_t *)malloc(sizeof(struct devicelist_t) +
125+ devlist = (struct devicelist_t *)malloc(sizeof(struct devicelist_t) +
265126 sizeof(struct devinfo_t) * devno);
266127 if (devlist == NULL)
267128 return NULL;
@@ -272,26 +133,25 @@ struct devicelist_t *get_devicelist(int ser_fd)
272133 memcpy(devlist->devs[devno].code, devp + 1, 4);
273134 memcpy(devlist->devs[devno].name, devp + 5, *devp-4);
274135 devlist->devs[devno].name[*devp - 4] = 0;
275- devp += 1 + 4 + *devp;
136+ devp += *devp;
276137 }
277138 return devlist;
278139 }
279140
280141 /* set target device ID */
281-int select_device(int ser_fd, const char *code)
142+int select_device(struct port_t *port, const char *code)
282143 {
283- char buf[6] = {SELECT_DEVICE, 0x04, 0x00, 0x00, 0x00, 0x00};
144+ unsigned char buf[6] = {SELECT_DEVICE, 0x04, 0x00, 0x00, 0x00, 0x00};
284145
285146 memcpy(&buf[2], code, 4);
286- send(ser_fd, buf, sizeof(buf));
287- if (receive(ser_fd, buf) != 1)
147+ send(port, buf, sizeof(buf));
148+ if (receive(port, buf) != 1)
288149 return 0;
289- else
290- return 1;
150+ return 1;
291151 }
292152
293153 /* get target clock mode */
294-struct clockmode_t *get_clockmode(int ser_fd)
154+struct clockmode_t *get_clockmode(struct port_t *port)
295155 {
296156 unsigned char rxbuf[255+3];
297157 unsigned char *clkmdp;
@@ -299,13 +159,17 @@ struct clockmode_t *get_clockmode(int ser_fd)
299159 int numclock;
300160
301161 rxbuf[0] = QUERY_CLOCKMODE;
302- write(ser_fd, rxbuf, 1);
303- if (receive(ser_fd, rxbuf) == -1)
162+ send(port, rxbuf, 1);
163+ if (receive(port, rxbuf) == -1)
304164 return NULL;
305165 if (rxbuf[0] != QUERY_CLOCKMODE_RES)
306166 return NULL;
307167
308168 numclock = rxbuf[2];
169+ if (numclock == 0) {
170+ numclock = 1;
171+ rxbuf[3] = 0;
172+ }
309173 clocks = (struct clockmode_t *)malloc(sizeof(struct clockmode_t) +
310174 sizeof(int) * numclock);
311175 if (clocks == NULL)
@@ -319,64 +183,66 @@ struct clockmode_t *get_clockmode(int ser_fd)
319183 }
320184
321185 /* set target clock mode */
322-int set_clockmode(int ser_fd, int mode)
186+int set_clockmode(struct port_t *port, int mode)
323187 {
324- char buf[3] = {SET_CLOCKMODE, 0x01, 0x00};
188+ unsigned char buf[3] = {SET_CLOCKMODE, 0x01, 0x00};
325189
326190 buf[2] = mode;
327- send(ser_fd, buf, sizeof(buf));
328- if (receive(ser_fd, buf) != 1)
191+ send(port, buf, sizeof(buf));
192+ if (receive(port, buf) != 1)
329193 return 0;
330194 else
331195 return 1;
332196 }
333197
334198 /* get target multiplier/divider rate */
335-struct multilist_t *get_multirate(int ser_fd)
199+struct multilist_t *get_multirate(struct port_t *port)
336200 {
337201 unsigned char rxbuf[255+3];
338202 unsigned char *mulp;
339203 struct multilist_t *multilist;
204+ struct multirate_t *rate;
340205 int nummulti;
341206 int numrate;
342207 int listsize;
343- signed char rate;
344208
345209 rxbuf[0] = QUERY_MULTIRATE;
346- write(ser_fd, rxbuf, 1);
347- if (receive(ser_fd, rxbuf) == -1)
210+ send(port, rxbuf, 1);
211+ if (receive(port, rxbuf) == -1)
348212 return NULL;
349213 if (rxbuf[0] != QUERY_MULTIRATE_RES)
350214 return NULL;
351215
352216 /* calc multilist size */
353217 nummulti = rxbuf[2];
354- listsize = sizeof(struct multilist_t);
218+ listsize = sizeof(struct multilist_t) + sizeof(struct multirate_t *) * nummulti;
355219 mulp = &rxbuf[3];
356- for (; nummulti > 0; nummulti--) {
357- listsize += sizeof(struct multirate_t) + sizeof(int) * (*mulp);
358- mulp += *mulp + 1;
220+ for(; nummulti > 0; nummulti--) {
221+ listsize += sizeof(struct multirate_t) + sizeof(int) * *mulp;
222+ mulp += *mulp;
359223 }
360-
361224 multilist = (struct multilist_t *)malloc(listsize);
362225 if (multilist == NULL)
363226 return NULL;
364227
365- /* setup multilist */
228+ /* setup list */
366229 multilist->nummulti = rxbuf[2];
230+ rate = (struct multirate_t *)&multilist->muls[multilist->nummulti];
367231 mulp = &rxbuf[3];
368232 for (nummulti = 0; nummulti < multilist->nummulti; nummulti++) {
369- multilist->muls[nummulti].numrate = *mulp++;
370- for (numrate = 0; numrate < multilist->muls[nummulti].numrate; numrate++) {
371- rate = *mulp++;
372- multilist->muls[nummulti].rate[numrate] = rate;
233+ multilist->muls[nummulti] = rate;
234+ rate->numrate = *mulp++;
235+ for (numrate = 0; numrate < rate->numrate; numrate++) {
236+ rate->rate[numrate] = *mulp++;
373237 }
374- }
238+ rate = (struct multirate_t *)&rate->rate[numrate];
239+ }
240+
375241 return multilist;
376242 }
377243
378244 /* get target operation frequency list */
379-struct freqlist_t *get_freqlist(int ser_fd)
245+struct freqlist_t *get_freqlist(struct port_t *port)
380246 {
381247 unsigned char rxbuf[255+3];
382248 unsigned char *freqp;
@@ -384,8 +250,8 @@ struct freqlist_t *get_freqlist(int ser_fd)
384250 int numfreq;
385251
386252 rxbuf[0] = QUERY_FREQ;
387- write(ser_fd, rxbuf, 1);
388- if (receive(ser_fd, rxbuf) == -1)
253+ send(port, rxbuf, 1);
254+ if (receive(port, rxbuf) == -1)
389255 return NULL;
390256 if (rxbuf[0] != QUERY_FREQ_RES)
391257 return NULL;
@@ -407,7 +273,7 @@ struct freqlist_t *get_freqlist(int ser_fd)
407273 }
408274
409275 /* get target rom mapping */
410-struct arealist_t *get_arealist(enum mat_t mat, int ser_fd)
276+struct arealist_t *get_arealist(struct port_t *port, enum mat_t mat)
411277 {
412278 char ans;
413279 unsigned char rxbuf[255+3];
@@ -427,8 +293,8 @@ struct arealist_t *get_arealist(enum mat_t mat, int ser_fd)
427293 default:
428294 return NULL;
429295 }
430- write(ser_fd, rxbuf, 1);
431- if (receive(ser_fd, rxbuf) == -1)
296+ send(port, rxbuf, 1);
297+ if (receive(port, rxbuf) == -1)
432298 return NULL;
433299 if (rxbuf[0] != ans)
434300 return NULL;
@@ -450,26 +316,50 @@ struct arealist_t *get_arealist(enum mat_t mat, int ser_fd)
450316 }
451317
452318 /* get write page size */
453-int get_writesize(int ser_fd)
319+int get_writesize(struct port_t *port)
454320 {
455321 unsigned char rxbuf[5];
322+ unsigned short size;
456323
457324 rxbuf[0] = QUERY_WRITESIZE;
458- write(ser_fd, rxbuf, 1);
459- if (receive(ser_fd, rxbuf) == -1)
325+ send(port, rxbuf, 1);
326+ if (receive(port, rxbuf) == -1)
460327 return -1;
461328 if (rxbuf[0] != QUERY_WRITESIZE_RES)
462329 return -1;
463330
464331 if (rxbuf[1] != 2)
465332 return -1;
466- return rxbuf[2] << 8 | rxbuf[3];
333+ size = rxbuf[2] << 8 | rxbuf[3];
334+ return size;
335+}
336+
337+/* bitrate candidate list */
338+static const int rate_list[]={1152,576,384,192,96};
339+
340+/* bitrate error margine (%) */
341+#define ERR_MARGIN 4
342+
343+/* select communication bitrate */
344+static int adjust_bitrate(int p_freq)
345+{
346+ int brr;
347+ int errorrate;
348+ int rate_no;
349+
350+ for (rate_no = 0; rate_no < sizeof(rate_list) / sizeof(int); rate_no++) {
351+ brr = (p_freq * 100) / (32 * rate_list[rate_no]);
352+ errorrate = abs((p_freq * 10000) / ((brr + 1) * rate_list[rate_no] * 32) - 100);
353+ if (errorrate <= ERR_MARGIN)
354+ return rate_list[rate_no];
355+ }
356+ return 0;
467357 }
468358
469359 /* set target bitrate */
470-int set_bitrate(int ser_fd, int bitrate, int freq, int coremul, int peripheralmul)
360+static int set_bitrate(struct port_t *p, int bitrate, int freq, int coremul, int peripheralmul)
471361 {
472- char buf[9] = {SET_BITRATE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
362+ unsigned char buf[9] = {SET_BITRATE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
473363
474364 buf[2] = (bitrate >> 8) & 0xff;
475365 buf[3] = bitrate & 0xff;
@@ -482,37 +372,114 @@ int set_bitrate(int ser_fd, int bitrate, int freq, int coremul, int peripheralmu
482372 buf[7] = coremul;
483373 buf[8] = peripheralmul;
484374
485- send(ser_fd, buf, sizeof(buf));
486- if (receive(ser_fd, buf) != 1)
375+ send(p, buf, sizeof(buf));
376+ if (receive(p, buf) != 1)
487377 return 0;
488378
489- if (!setbaud(ser_fd, bitrate))
490- return 0;
379+ if (p->setbaud) {
380+ if (!p->setbaud(bitrate))
381+ return 0;
491382
383+ }
492384 usleep(10000);
493385 buf[0] = ACK;
494- write(ser_fd, buf, 1);
495- if (receive(ser_fd, buf) != 1)
386+ send(p, buf, 1);
387+ if (receive(p, buf) != 1)
496388 return 0;
497389 else
498390 return 1;
499391 }
500392
393+#define C_MULNO 0
394+#define P_MULNO 1
395+#define C_FREQNO 0
396+#define P_FREQNO 1
397+
398+/* change communicate bitrate */
399+static int change_bitrate(struct port_t *p, int in_freq,
400+ struct multilist_t *multi, struct freqlist_t *freq)
401+{
402+ int rateno;
403+ int core_mul, peripheral_mul;
404+ int core_freq, peripheral_freq;
405+ int clock;
406+ int rate;
407+
408+ core_mul = 0;
409+ peripheral_mul = 0;
410+ /* select cpu core clock frequency */
411+ for (rateno = 0, core_freq = -1; rateno < multi->muls[C_MULNO]->numrate; rateno++) {
412+ if (multi->muls[C_MULNO]->rate[rateno] > 0)
413+ clock = in_freq * multi->muls[C_MULNO]->rate[rateno];
414+ else
415+ clock = in_freq / -multi->muls[C_MULNO]->rate[rateno];
416+ if (!(clock >= freq->freq[C_FREQNO].min && clock <= freq->freq[C_FREQNO].max))
417+ continue;
418+ if (core_freq < clock) {
419+ core_mul = multi->muls[C_MULNO]->rate[rateno];
420+ core_freq = clock;
421+ }
422+ }
423+
424+ /* select peripheral clock freqency */
425+ if (multi->nummulti > P_MULNO) {
426+ for (rateno = 0, peripheral_freq = -1;
427+ rateno < multi->muls[P_MULNO]->numrate; rateno++) {
428+ if (multi->muls[P_MULNO]->rate[rateno] > 0)
429+ clock = in_freq * multi->muls[P_MULNO]->rate[rateno];
430+ else
431+ clock = in_freq / -multi->muls[P_MULNO]->rate[rateno];
432+ if (clock < freq->freq[P_FREQNO].min ||
433+ clock > freq->freq[P_FREQNO].max)
434+ continue;
435+ if (peripheral_freq < clock) {
436+ peripheral_mul = multi->muls[P_MULNO]->rate[rateno];
437+ peripheral_freq = clock;
438+ }
439+ }
440+ } else {
441+ peripheral_mul = 0;
442+ peripheral_freq = core_freq;
443+ }
444+
445+ /* select clock check */
446+ if (core_freq == -1 || peripheral_freq == -1) {
447+ fprintf(stderr,"input frequency (%d.%d MHz) is out of range\n",
448+ in_freq / 100, in_freq % 100);
449+ return 0;
450+ }
451+
452+ VERBOSE_PRINT("core multiple rate=%d, freq=%d.%d MHz\n",
453+ core_mul, core_freq / 100, core_freq % 100);
454+ VERBOSE_PRINT("peripheral multiple rate=%d, freq=%d.%d MHz\n",
455+ peripheral_mul, peripheral_freq / 100, peripheral_freq % 100);
456+
457+ /* select bitrate from peripheral cock*/
458+ rate = adjust_bitrate(peripheral_freq);
459+ if (rate == 0)
460+ return 0;
461+
462+ VERBOSE_PRINT("bitrate %d bps\n",rate * 100);
463+
464+ /* setup host/target bitrate */
465+ return set_bitrate(p, rate, in_freq, core_mul, peripheral_mul);
466+}
467+
501468 /* check blank page */
502-static int skipcheck(unsigned char *data)
469+static int skipcheck(unsigned char *data, unsigned short size)
503470 {
504471 unsigned char r = 0xff;
505472 int c;
506- for (c = 0; c < 128; c++)
473+ for (c = 0; c < size; c++)
507474 r &= *data++;
508475 return (r == 0xff);
509476 }
510477
511478 /* write rom image */
512-int write_rom(int ser_fd, const unsigned char *romimage, struct writeinfo_t *writeinfo)
479+int write_rom(struct port_t *port, const unsigned char *romimage, struct writeinfo_t *writeinfo)
513480 {
514481 unsigned char *buf = NULL;
515- unsigned long romaddr;
482+ unsigned int romaddr;
516483
517484 buf = (unsigned char *)malloc(5 + writeinfo->size);
518485 if (buf == NULL) {
@@ -522,25 +489,27 @@ int write_rom(int ser_fd, const unsigned char *romimage, struct writeinfo_t *wri
522489
523490 puts("erase flash...");
524491 /* enter writemode */
525- *(buf + 0) = WRITEMODE;
526- write(ser_fd, buf, 1);
527- if (receive(ser_fd, buf) != 1) {
528- fputs(PROGNAME ": writemode start failed", stderr);
492+ buf[0] = WRITEMODE;
493+ send(port, buf, 1);
494+ if (receive(port, buf) != 1) {
495+ printf("%02x ", buf[0]);
496+ fputs(PROGNAME ": writemode start failed\n", stderr);
529497 goto error;
530498 }
531499
532500 /* mat select */
533501 switch (writeinfo->mat) {
534502 case user:
535- *(buf + 0) = WRITE_USER;
503+ buf[0] = WRITE_USER;
536504 break;
537505 case userboot:
538- *(buf + 0) = WRITE_USERBOOT;
506+ buf[0] = WRITE_USERBOOT;
539507 break;
540508 }
541- write(ser_fd, buf, 1);
542- if (receive(ser_fd, buf) != 1) {
543- fputs(PROGNAME ": writemode start failed", stderr);
509+ send(port, buf, 1);
510+ if (receive(port, buf) != 1) {
511+ printf("%02x ", buf[0]);
512+ fputs(PROGNAME ": writemode start failed\n", stderr);
544513 goto error;
545514 }
546515
@@ -548,44 +517,44 @@ int write_rom(int ser_fd, const unsigned char *romimage, struct writeinfo_t *wri
548517 for (romaddr = writeinfo->area.start;
549518 romaddr < writeinfo->area.end;
550519 romaddr += writeinfo->size) {
551- if (skipcheck((unsigned char *)(romimage + romaddr)))
520+ if (skipcheck((unsigned char *)(romimage + romaddr - writeinfo->area.start), writeinfo->size))
552521 continue;
553522 /* set write data */
554- *(buf + 0) = WRITE128;
523+ *(buf + 0) = WRITE;
555524 setlong(buf + 1, romaddr);
556525 if ((romaddr + writeinfo->size) < writeinfo->area.end) {
557- memcpy(buf + 5, romimage + romaddr, writeinfo->size);
526+ memcpy(buf + 5, romimage + romaddr - writeinfo->area.start, writeinfo->size);
558527 } else {
559- /* lastpage < 128byte*/
560- memcpy(buf + 5, romimage + romaddr,
528+ /* lastpage < writesize */
529+ memcpy(buf + 5, romimage + romaddr - writeinfo->area.start,
561530 (writeinfo->area.end - romaddr));
562531 memset(buf + 5 + writeinfo->area.end - romaddr, 0xff,
563532 writeinfo->size - (writeinfo->area.end - romaddr));
564533 }
565534 /* write */
566- send(ser_fd, buf, 5 + writeinfo->size);
567- if (receive(ser_fd, buf) != 1) {
568- fprintf(stderr, PROGNAME ": write data %08lx failed.", romaddr);
535+ send(port, buf, 5 + writeinfo->size);
536+ if (receive(port, buf) != 1) {
537+ fprintf(stderr, PROGNAME ": write data %08x failed.", romaddr);
569538 goto error;
570539 }
571540 if (verbose)
572- printf("write - %08lx\n",romaddr);
541+ printf("write - %08x\n",romaddr);
573542 else {
574- printf("writing %ld/%ld byte\r", romaddr, writeinfo->area.end);
543+ printf("writing %d/%d byte\r", romaddr, writeinfo->area.end);
575544 fflush(stdout);
576545 }
577546 }
578547 /* write finish */
579- *(buf + 0) = WRITE128;
548+ *(buf + 0) = WRITE;
580549 memset(buf + 1, 0xff, 4);
581- send(ser_fd, buf, 5);
582- if (receive(ser_fd, buf) != 1) {
550+ send(port, buf, 5);
551+ if (receive(port, buf) != 1) {
583552 fputs(PROGNAME ": writemode exit failed", stderr);
584553 goto error;
585554 }
586555 free(buf);
587556 if (!verbose)
588- printf("writing %ld/%ld byte\n", writeinfo->area.end, writeinfo->area.end);
557+ printf("writing %d/%d byte\n", writeinfo->area.end, writeinfo->area.end);
589558
590559
591560 return 1;
@@ -593,3 +562,235 @@ int write_rom(int ser_fd, const unsigned char *romimage, struct writeinfo_t *wri
593562 free(buf);
594563 return 0;
595564 }
565+
566+/* connect to target chip */
567+int setup_connection(struct port_t *p, int input_freq)
568+{
569+ int c;
570+ int r = -1;
571+ struct devicelist_t *devicelist = NULL;
572+ struct clockmode_t *clockmode = NULL;
573+ struct multilist_t *multilist = NULL;
574+ struct freqlist_t *freqlist = NULL;
575+
576+ /* connect target */
577+ if (!p->connect_target()) {
578+ if (errno != 0)
579+ perror(PROGNAME);
580+ else
581+ fputs("target no response\n", stderr);
582+ goto error;
583+ }
584+
585+ /* query target infomation */
586+ devicelist = get_devicelist(p);
587+ if (devicelist == NULL) {
588+ if (errno != 0)
589+ perror(PROGNAME);
590+ else
591+ fputs("devicelist error\n", stderr);
592+ goto error;
593+ }
594+ if (verbose) {
595+ char codes[5];
596+ printf("Support devices: %d\n", devicelist->numdevs);
597+ for (c = 0; c < devicelist->numdevs; c++) {
598+ memcpy(codes, devicelist->devs[c].code, 4);
599+ codes[4] = '\0';
600+ printf("%d: %s - %s\n", c+1, codes, devicelist->devs[c].name);
601+ }
602+ }
603+
604+ /* query target clockmode */
605+ clockmode = get_clockmode(p);
606+ if (clockmode == NULL) {
607+ if (errno != 0)
608+ perror(PROGNAME);
609+ else
610+ fputs("clockmode error\n",stderr);
611+ goto error;
612+ }
613+ if (verbose) {
614+ if (clockmode->nummode > 0) {
615+ printf("Support clock modes %d:", clockmode->nummode);
616+ for (c = 0; c < clockmode->nummode; c++) {
617+ printf(" %02x", clockmode->mode[c]);
618+ }
619+ printf("\n");
620+ } else
621+ printf("no clockmode support\n");
622+ }
623+
624+ /* SELDEV devicetype select */
625+ if (devicelist->numdevs < SELDEV) {
626+ fprintf(stderr, "Select Device (%d) not supported.\n", SELDEV);
627+ goto error;
628+ }
629+ if (!select_device(p, devicelist->devs[SELDEV].code)) {
630+ fputs("device select error", stderr);
631+ goto error;
632+ }
633+
634+ /* SELCLK clockmode select */
635+ if (clockmode->nummode > 0) {
636+ if (clockmode->nummode < SELCLK) {
637+ fprintf(stderr, "Select clock (%d) not supported.\n", SELCLK);
638+ goto error;
639+ }
640+ if (!set_clockmode(p, clockmode->mode[SELCLK])) {
641+ fputs("clock select error", stderr);
642+ goto error;
643+ }
644+ } else {
645+ if (!set_clockmode(p, 0)) {
646+ fputs("clock select error", stderr);
647+ goto error;
648+ }
649+ }
650+
651+ /* query multiplier/devider rate */
652+ multilist = get_multirate(p);
653+ if (multilist == NULL) {
654+ if (errno != 0)
655+ perror(PROGNAME);
656+ else
657+ fputs("multilist error\n",stderr);
658+ goto error;
659+ }
660+ if (verbose) {
661+ int c1,c2;
662+ printf("Support multiple rate: %d\n", multilist->nummulti);
663+ for (c1 = 0; c1 < multilist->nummulti; c1++) {
664+ printf("%d:", c1 + 1);
665+ for (c2 = 0; c2 < multilist->muls[c1]->numrate; c2++)
666+ printf(" %d", multilist->muls[c1]->rate[c2]);
667+ printf("\n");
668+ }
669+ }
670+
671+ /* query operation frequency range */
672+ freqlist = get_freqlist(p);
673+ if (freqlist == NULL) {
674+ if (errno != 0)
675+ perror(PROGNAME);
676+ else
677+ fputs("freqlist error\n",stderr);
678+ goto error;
679+ }
680+ if (verbose) {
681+ printf("operation frequencies: %d\n", freqlist->numfreq);
682+ for (c = 0; c < freqlist->numfreq; c++) {
683+ printf("%d: %d.%d - %d.%d\n", c + 1,
684+ freqlist->freq[c].min / 100,freqlist->freq[c].min % 100,
685+ freqlist->freq[c].max / 100,freqlist->freq[c].max % 100);
686+ }
687+ }
688+
689+ /* set writeing bitrate */
690+ if (!change_bitrate(p, input_freq, multilist, freqlist)) {
691+ fputs("set bitrate failed\n",stderr);
692+ goto error;
693+ }
694+
695+ r = 0;
696+ error:
697+ free(devicelist);
698+ free(clockmode);
699+ free(multilist);
700+ free(freqlist);
701+ return r;
702+}
703+
704+/* connect to target chip */
705+void dump_configs(struct port_t *p)
706+{
707+ struct devicelist_t *devicelist = NULL;
708+ struct clockmode_t *clockmode = NULL;
709+ struct multilist_t *multilist = NULL;
710+ struct freqlist_t *freqlist = NULL;
711+ int dev;
712+ int clk;
713+ int c1,c2;
714+
715+ /* connect target */
716+ if (!p->connect_target()) {
717+ if (errno != 0)
718+ perror(PROGNAME);
719+ else
720+ fputs("target no response\n", stderr);
721+ goto error;
722+ }
723+
724+ /* query target infomation */
725+ devicelist = get_devicelist(p);
726+ if (devicelist == NULL) {
727+ if (errno != 0)
728+ perror(PROGNAME);
729+ else
730+ fputs("devicelist error\n", stderr);
731+ goto error;
732+ }
733+ /* query target clockmode */
734+ clockmode = get_clockmode(p);
735+ if (clockmode == NULL) {
736+ if (errno != 0)
737+ perror(PROGNAME);
738+ else
739+ fputs("clockmode error\n",stderr);
740+ goto error;
741+ }
742+ for(dev = 0; dev < devicelist->numdevs; dev++) {
743+ if (!select_device(p, devicelist->devs[dev].code)) {
744+ fputs("device select error", stderr);
745+ goto error;
746+ }
747+ for (clk = 0; clk < clockmode->nummode; clk++) {
748+ if (!set_clockmode(p, clockmode->mode[clk])) {
749+ fputs("clock select error", stderr);
750+ goto error;
751+ }
752+
753+ printf("dev: %s - clock: %d\n", devicelist->devs[dev].name, clk);
754+ multilist = get_multirate(p);
755+ if (multilist == NULL) {
756+ if (errno != 0)
757+ perror(PROGNAME);
758+ else
759+ fputs("multilist error\n",stderr);
760+ goto error;
761+ }
762+ printf("multiple / divide rate\n");
763+ for (c1 = 0; c1 < multilist->nummulti; c1++) {
764+ for (c2 = 0; c2 < multilist->muls[c1]->numrate; c2++)
765+ printf(" %d", (int)multilist->muls[c1]->rate[c2]);
766+ printf("\n");
767+ }
768+
769+ /* query operation frequency range */
770+ freqlist = get_freqlist(p);
771+ if (freqlist == NULL) {
772+ if (errno != 0)
773+ perror(PROGNAME);
774+ else
775+ fputs("freqlist error\n",stderr);
776+ goto error;
777+ }
778+ printf("operation frequency (MHz)\n");
779+ for (c1 = 0; c1 < freqlist->numfreq; c1++) {
780+ printf("%d.%d - %d.%d\n",
781+ freqlist->freq[c1].min / 100,freqlist->freq[c1].min % 100,
782+ freqlist->freq[c1].max / 100,freqlist->freq[c1].max % 100);
783+ }
784+ free(multilist);
785+ free(freqlist);
786+ multilist = NULL;
787+ freqlist = NULL;
788+ }
789+ }
790+error:
791+ free(multilist);
792+ free(freqlist);
793+ free(devicelist);
794+ free(clockmode);
795+}
796+
--- a/h8flash.h
+++ b/h8flash.h
@@ -13,6 +13,9 @@
1313 /* default using serialport */
1414 #define DEFAULT_SERIAL "/dev/ttyS0"
1515
16+#define DEFAULT_VID 0x045b
17+#define DEFAULT_PID 0x0025
18+
1619 /* use devicetype */
1720 #define SELDEV 0
1821 /* use clockmode */
@@ -26,6 +29,36 @@
2629
2730
2831 #define PROGNAME "h8flash"
32+#define VERBOSE_PRINT(...) do { if (verbose) printf(__VA_ARGS__); } while(0)
33+
34+#define ACK 0x06
35+
36+#define QUERY_DEVICE 0x20
37+#define QUERY_DEVICE_RES 0x30
38+#define QUERY_CLOCKMODE 0x21
39+#define QUERY_CLOCKMODE_RES 0x31
40+#define QUERY_MULTIRATE 0x22
41+#define QUERY_MULTIRATE_RES 0x32
42+#define QUERY_FREQ 0x23
43+#define QUERY_FREQ_RES 0x33
44+#define QUERY_BOOT_AREA 0x24
45+#define QUERY_BOOT_AREA_RES 0x34
46+#define QUERY_USER_AREA 0x25
47+#define QUERY_USER_AREA_RES 0x35
48+#define QUERY_WRITESIZE 0x27
49+#define QUERY_WRITESIZE_RES 0x37
50+
51+#define SELECT_DEVICE 0x10
52+#define SET_CLOCKMODE 0x11
53+
54+#define SET_BITRATE 0x3f
55+
56+#define WRITEMODE 0x40
57+#define WRITE_USERBOOT 0x42
58+#define WRITE_USER 0x43
59+#define BLANKCHECK_USERBOOT 0x4c
60+#define BLANKCHECK_USER 0x4d
61+#define WRITE 0x50
2962
3063 enum mat_t {user, userboot};
3164
@@ -36,7 +69,7 @@ struct devinfo_t {
3669
3770 struct devicelist_t {
3871 int numdevs;
39- struct devinfo_t devs[1];
72+ struct devinfo_t devs[0];
4073 };
4174
4275 struct clockmode_t {
@@ -51,7 +84,7 @@ struct multirate_t {
5184
5285 struct multilist_t {
5386 int nummulti;
54- struct multirate_t muls[0];
87+ struct multirate_t *muls[0];
5588 };
5689
5790 struct freq_t {
@@ -65,8 +98,8 @@ struct freqlist_t {
6598 };
6699
67100 struct area_t {
68- unsigned long start;
69- unsigned long end;
101+ unsigned int start;
102+ unsigned int end;
70103 };
71104
72105 struct arealist_t {
@@ -80,17 +113,30 @@ struct writeinfo_t {
80113 int size;
81114 };
82115
83-int open_serial(const char *port);
84-int connect_target(int ser_fd);
85-struct devicelist_t *get_devicelist(int ser_fd);
86-struct clockmode_t *get_clockmode(int ser_fd);
87-struct multilist_t *get_multirate(int ser_fd);
88-struct freqlist_t *get_freqlist(int ser_fd);
89-struct arealist_t *get_arealist(enum mat_t mat, int ser_fd);
90-int get_writesize(int ser_fd);
91-int select_device(int ser_fd, const char *code);
92-int set_clockmode(int ser_fd, int mode);
93-int set_bitrate(int ser_fd, int bitrate, int freq, int coremul, int peripheralmul);
94-int write_rom(int ser_fd, const unsigned char *romimage, struct writeinfo_t *writeinfo);
116+enum port_type {serial, usb};
117+
118+struct port_t {
119+ enum port_type type;
120+ int (*connect_target)(void);
121+ int (*send_data)(const unsigned char *data, int len);
122+ int (*receive_byte)(unsigned char *data);
123+ int (*setbaud)(int bitrate);
124+ void (*close)(void);
125+};
126+
127+struct port_t *open_serial(char *portname);
128+struct port_t *open_usb(unsigned short vid, unsigned short pid);
129+struct devicelist_t *get_devicelist(struct port_t *port);
130+struct clockmode_t *get_clockmode(struct port_t *port);
131+struct multilist_t *get_multirate(struct port_t *port);
132+struct freqlist_t *get_freqlist(struct port_t *port);
133+struct arealist_t *get_arealist(struct port_t *port, enum mat_t mat);
134+int get_writesize(struct port_t *port);
135+int select_device(struct port_t *port, const char *code);
136+int set_clockmode(struct port_t *port, int mode);
137+int write_rom(struct port_t *port, const unsigned char *romimage,
138+ struct writeinfo_t *writeinfo);
139+int setup_connection(struct port_t *port, int input_freq);
140+void dump_configs(struct port_t *p);
95141
96142 extern int verbose;
--- a/main.c
+++ b/main.c
@@ -11,23 +11,16 @@
1111 #include <stdio.h>
1212 #include <getopt.h>
1313 #include <stddef.h>
14-#include <sys/stat.h>
15-#include <sys/types.h>
16-#include <sys/mman.h>
17-#include <unistd.h>
18-#include <fcntl.h>
19-#include <errno.h>
2014 #include <stdlib.h>
2115 #include <ctype.h>
2216 #include <string.h>
23-#include <signal.h>
24-#include <libgen.h>
17+#include <errno.h>
18+#include <sys/mman.h>
19+#include <sys/stat.h>
2520 #include "h8flash.h"
2621
2722 #define SREC_MAXLEN (256*2 + 4 + 1)
2823
29-#define VERBOSE_PRINT(...) do { if (verbose) printf(__VA_ARGS__); } while(0)
30-
3124 int verbose = 0;
3225
3326 const static struct option long_options[] = {
@@ -36,16 +29,17 @@ const static struct option long_options[] = {
3629 {"freq", required_argument, NULL, 'f'},
3730 {"binary", no_argument, NULL, 'b'},
3831 {"verbose", no_argument, NULL, 'V'},
32+ {"list", no_argument, NULL, 'l'},
3933 {0, 0, 0, 0}
4034 };
4135
4236 static void usage(void)
4337 {
44- puts(PROGNAME " [-p serial port][-f input clock frequency][-b][--userboot] filename");
38+ puts(PROGNAME " [-p serial port][-f input clock frequency][-b][--userboot][-l] filename");
4539 }
4640
4741 /* read raw binary */
48-static int write_binary(FILE *fp, struct writeinfo_t *writeinfo, int ser_fd)
42+static int write_binary(FILE *fp, struct writeinfo_t *writeinfo, struct port_t *p)
4943 {
5044 int fno;
5145 struct stat bin_st;
@@ -57,10 +51,10 @@ static int write_binary(FILE *fp, struct writeinfo_t *writeinfo, int ser_fd)
5751 fstat(fno, &bin_st);
5852 bin_len = bin_st.st_size;
5953
60- if ((bin_buf = (char *)mmap(NULL, bin_len, PROT_READ, MAP_SHARED, fno, 0)) == MAP_FAILED)
54+ if ((bin_buf = (unsigned char *)mmap(NULL, bin_len, PROT_READ, MAP_SHARED, fno, 0)) == MAP_FAILED)
6155 goto error_perror;
6256 writeinfo->area.end = bin_len - 1;
63- if (!write_rom(ser_fd, bin_buf, writeinfo))
57+ if (!write_rom(p, bin_buf, writeinfo))
6458 goto error;
6559 munmap(bin_buf, bin_len);
6660 fclose(fp);
@@ -75,11 +69,11 @@ static int write_binary(FILE *fp, struct writeinfo_t *writeinfo, int ser_fd)
7569 }
7670
7771 /* read srec binary */
78-static int write_srec(FILE *fp, struct writeinfo_t *writeinfo, int ser_fd)
72+static int write_srec(FILE *fp, struct writeinfo_t *writeinfo, struct port_t *p)
7973 {
8074 unsigned char *romimage = NULL;
8175 unsigned char *bufp;
82- unsigned long last_addr = 0;
76+ unsigned int last_addr = 0;
8377 int buff_size;
8478 static char linebuf[SREC_MAXLEN + 1];
8579 char *lp;
@@ -91,7 +85,7 @@ static int write_srec(FILE *fp, struct writeinfo_t *writeinfo, int ser_fd)
9185 int r = 0;
9286 int l;
9387
94- romimage = (char *)malloc(writeinfo->area.end - writeinfo->area.start + 1);
88+ romimage = (unsigned char *)malloc(writeinfo->area.end - writeinfo->area.start + 1);
9589 if (!romimage) {
9690 perror(PROGNAME);
9791 goto error;
@@ -131,7 +125,7 @@ static int write_srec(FILE *fp, struct writeinfo_t *writeinfo, int ser_fd)
131125 fprintf(stderr, "srec address %08x is out of romarea\n", addr);
132126 goto error;
133127 }
134- bufp = romimage + addr;
128+ bufp = romimage + addr - writeinfo->area.start;
135129 if (last_addr < (addr + len - 1))
136130 last_addr = (addr + len - 1);
137131
@@ -156,7 +150,7 @@ static int write_srec(FILE *fp, struct writeinfo_t *writeinfo, int ser_fd)
156150 }
157151 }
158152 writeinfo->area.end = last_addr;
159- r = write_rom(ser_fd, romimage, writeinfo);
153+ r = write_rom(p, romimage, writeinfo);
160154 error:
161155 free(romimage);
162156 fclose(fp);
@@ -164,7 +158,8 @@ static int write_srec(FILE *fp, struct writeinfo_t *writeinfo, int ser_fd)
164158 }
165159
166160 /* read rom writing data */
167-static int writefile_to_rom(char *fn, int force_binary, struct writeinfo_t *writeinfo, int ser_fd)
161+static int writefile_to_rom(char *fn, int force_binary, struct writeinfo_t *writeinfo,
162+ struct port_t *port)
168163 {
169164 FILE *fp = NULL;
170165 static char linebuf[SREC_MAXLEN + 1];
@@ -192,7 +187,7 @@ static int writefile_to_rom(char *fn, int force_binary, struct writeinfo_t *writ
192187 if (force_binary ||
193188 linebuf[0] != 'S' ||
194189 isdigit(linebuf[1]) == 0)
195- return write_binary(fp, writeinfo, ser_fd);
190+ return write_binary(fp, writeinfo, port);
196191
197192 /* check body (calcurate checksum) */
198193 memcpy(hexbuf, &linebuf[2], 2);
@@ -203,262 +198,19 @@ static int writefile_to_rom(char *fn, int force_binary, struct writeinfo_t *writ
203198 }
204199 if ((sum & 0xff) == 0xff)
205200 /* checksum ok is Srecord format */
206- return write_srec(fp, writeinfo, ser_fd);
201+ return write_srec(fp, writeinfo, port);
207202 else
208- return write_binary(fp, writeinfo, ser_fd);
209-}
210-
211-/* bitrate candidate list */
212-static const int rate_list[]={1152,576,384,192,96};
213-
214-/* bitrate error margine (%) */
215-#define ERR_MARGIN 4
216-
217-/* select communication bitrate */
218-static int adjust_bitrate(int p_freq)
219-{
220- int brr;
221- int errorrate;
222- int rate_no;
223-
224- for (rate_no = 0; rate_no < sizeof(rate_list) / sizeof(int); rate_no++) {
225- brr = (p_freq * 100) / (32 * rate_list[rate_no]);
226- errorrate = abs((p_freq * 10000) / ((brr + 1) * rate_list[rate_no] * 32) - 100);
227- if (errorrate <= ERR_MARGIN)
228- return rate_list[rate_no];
229- }
230- return 0;
231-}
232-
233-#define C_MULNO 0
234-#define P_MULNO 1
235-#define C_FREQNO 0
236-#define P_FREQNO 1
237-
238-/* change communicate bitrate */
239-static int change_bitrate(int ser_fd, int in_freq,
240- struct multilist_t *multi, struct freqlist_t *freq)
241-{
242- int rateno;
243- int core_mul, peripheral_mul;
244- int core_freq, peripheral_freq;
245- int clock;
246- int rate;
247-
248- core_mul = 0;
249- peripheral_mul = 0;
250- /* select cpu core clock frequency */
251- for (rateno = 0, core_freq = -1; rateno < multi->muls[C_MULNO].numrate; rateno++) {
252- if (multi->muls[C_MULNO].rate[rateno] > 0)
253- clock = in_freq * multi->muls[C_MULNO].rate[rateno];
254- else
255- clock = in_freq / -multi->muls[C_MULNO].rate[rateno];
256- if (!(clock >= freq->freq[C_FREQNO].min && clock <= freq->freq[C_FREQNO].max))
257- continue;
258- if (core_freq < clock) {
259- core_mul = multi->muls[C_MULNO].rate[rateno];
260- core_freq = clock;
261- }
262- }
263-
264- /* select peripheral clock freqency */
265- if (multi->nummulti > P_MULNO) {
266- for (rateno = 0, peripheral_freq = -1;
267- rateno < multi->muls[P_MULNO].numrate; rateno++) {
268- if (multi->muls[P_MULNO].rate[rateno] > 0)
269- clock = in_freq * multi->muls[P_MULNO].rate[rateno];
270- else
271- clock = in_freq / -multi->muls[P_MULNO].rate[rateno];
272- if (clock < freq->freq[P_FREQNO].min ||
273- clock > freq->freq[P_FREQNO].max)
274- continue;
275- if (peripheral_freq < clock) {
276- peripheral_mul = multi->muls[P_MULNO].rate[rateno];
277- peripheral_freq = clock;
278- }
279- }
280- } else {
281- peripheral_mul = 0;
282- peripheral_freq = core_freq;
283- }
284-
285- /* select clock check */
286- if (core_freq == -1 || peripheral_freq == -1) {
287- fprintf(stderr,"input frequency (%d.%d MHz) is out of range\n",
288- in_freq / 100, in_freq % 100);
289- return 0;
290- }
291-
292- VERBOSE_PRINT("core multiple rate=%d, freq=%d.%d MHz\n",
293- core_mul, core_freq / 100, core_freq % 100);
294- VERBOSE_PRINT("peripheral multiple rate=%d, freq=%d.%d MHz\n",
295- peripheral_mul, peripheral_freq / 100, peripheral_freq % 100);
296-
297- /* select bitrate from peripheral cock*/
298- rate = adjust_bitrate(peripheral_freq);
299- if (rate == 0)
300- return 0;
301-
302- VERBOSE_PRINT("bitrate %d bps\n",rate * 100);
303-
304- /* setup host/target bitrate */
305- return set_bitrate(ser_fd, rate, in_freq, core_mul, peripheral_mul);
306-}
307-
308-/* connect to target chip */
309-static int setup_connection(const char *ser_port, int input_freq)
310-{
311- int ser_fd;
312- int c;
313- int r = -1;
314- struct devicelist_t *devicelist = NULL;
315- struct clockmode_t *clockmode = NULL;
316- struct multilist_t *multilist = NULL;
317- struct freqlist_t *freqlist = NULL;
318-
319- /* serial port open */
320- ser_fd = open_serial(ser_port);
321- if (ser_fd == -1)
322- return -1;
323-
324- /* connect target */
325- if (!connect_target(ser_fd)) {
326- if (errno != 0)
327- perror(PROGNAME);
328- else
329- fputs("target no response\n", stderr);
330- goto error;
331- }
332-
333- /* query target infomation */
334- devicelist = get_devicelist(ser_fd);
335- if (devicelist == NULL) {
336- if (errno != 0)
337- perror(PROGNAME);
338- else
339- fputs("devicelist error\n", stderr);
340- goto error;
341- }
342- if (verbose) {
343- char codes[5];
344- printf("supports devices: %d\n", devicelist->numdevs);
345- for (c = 0; c < devicelist->numdevs; c++) {
346- memcpy(codes, devicelist->devs[c].code, 4);
347- codes[4] = '\0';
348- printf("%d: %s - %s\n", c+1, codes, devicelist->devs[c].name);
349- }
350- }
351-
352- /* query target clockmode */
353- clockmode = get_clockmode(ser_fd);
354- if (clockmode == NULL) {
355- if (errno != 0)
356- perror(PROGNAME);
357- else
358- fputs("clockmode error\n",stderr);
359- goto error;
360- }
361- if (verbose) {
362- if (clockmode->nummode > 0) {
363- printf("supports clockmode %d:", clockmode->nummode);
364- for (c = 0; c < clockmode->nummode; c++) {
365- printf(" %02x", clockmode->mode[c]);
366- }
367- printf("\n");
368- } else
369- printf("no clockmode support\n");
370- }
371-
372- /* SELDEV devicetype select */
373- if (devicelist->numdevs < SELDEV) {
374- fprintf(stderr, "Select Device (%d) not supported.\n", SELDEV);
375- goto error;
376- }
377- if (!select_device(ser_fd, devicelist->devs[SELDEV].code)) {
378- fputs("device select error", stderr);
379- goto error;
380- }
381-
382- /* SELCLK clockmode select */
383- if (clockmode->nummode > 0) {
384- if (clockmode->nummode < SELCLK) {
385- fprintf(stderr, "Select clock (%d) not supported.\n", SELCLK);
386- goto error;
387- }
388- if (!set_clockmode(ser_fd, clockmode->mode[SELCLK])) {
389- fputs("clock select error", stderr);
390- goto error;
391- }
392- } else {
393- if (!set_clockmode(ser_fd, 0)) {
394- fputs("clock select error", stderr);
395- goto error;
396- }
397- }
398-
399- /* query multiplier/devider rate */
400- multilist = get_multirate(ser_fd);
401- if (multilist == NULL) {
402- if (errno != 0)
403- perror(PROGNAME);
404- else
405- fputs("multilist error\n",stderr);
406- goto error;
407- }
408- if (verbose) {
409- int c1,c2;
410- printf("supports multirate: %d\n", multilist->nummulti);
411- for (c1 = 0; c1 < multilist->nummulti; c1++) {
412- printf("%d:", c1 + 1);
413- for (c2 = 0; c2 < multilist->muls[c1].numrate; c2++)
414- printf(" %d", multilist->muls[c1].rate[c2]);
415- }
416- printf("\n");
417- }
418-
419- /* query operation frequency range */
420- freqlist = get_freqlist(ser_fd);
421- if (freqlist == NULL) {
422- if (errno != 0)
423- perror(PROGNAME);
424- else
425- fputs("freqlist error\n",stderr);
426- goto error;
427- }
428- if (verbose) {
429- printf("operation frequencies: %d\n", freqlist->numfreq);
430- for (c = 0; c < freqlist->numfreq; c++) {
431- printf("%d: %d.%d - %d.%d\n", c + 1,
432- freqlist->freq[c].min / 100,freqlist->freq[c].min % 100,
433- freqlist->freq[c].max / 100,freqlist->freq[c].max % 100);
434- }
435- }
436-
437- /* set writeing bitrate */
438- if (!change_bitrate(ser_fd, input_freq, multilist, freqlist)) {
439- fputs("set bitrate failed\n",stderr);
440- goto error;
441- }
442-
443- r =ser_fd;
444- error:
445- free(devicelist);
446- free(clockmode);
447- free(multilist);
448- free(freqlist);
449- if (r == -1 && ser_fd >= 0)
450- close(ser_fd);
451- return r;
203+ return write_binary(fp, writeinfo, port);
452204 }
453205
454206 /* get target rommap */
455-static int get_rominfo(int ser_fd, struct writeinfo_t *writeinfo)
207+static int get_rominfo(struct port_t *port, struct writeinfo_t *writeinfo)
456208 {
457209 struct arealist_t *arealist = NULL;
458210 int c;
459211
460212 /* get target rommap list */
461- arealist = get_arealist(writeinfo->mat, ser_fd);
213+ arealist = get_arealist(port, writeinfo->mat);
462214 if (arealist == NULL) {
463215 if (errno != 0)
464216 perror(PROGNAME);
@@ -469,7 +221,7 @@ static int get_rominfo(int ser_fd, struct writeinfo_t *writeinfo)
469221 if (verbose) {
470222 printf("area map\n");
471223 for (c = 0; c < arealist->areas; c++)
472- printf("%08lx - %08lx\n", arealist->area[c].start,
224+ printf("%08x - %08x\n", arealist->area[c].start,
473225 arealist->area[c].end);
474226 }
475227
@@ -483,51 +235,18 @@ static int get_rominfo(int ser_fd, struct writeinfo_t *writeinfo)
483235 free(arealist);
484236
485237 /* get writeing size */
486- writeinfo->size = get_writesize(ser_fd);
238+ writeinfo->size = get_writesize(port);
487239 if (writeinfo->size < 0) {
488240 if (errno != 0)
489241 perror(PROGNAME);
490242 else
491- fputs("writesize error\n",stderr);
243+ fputs("writesize error\n", stderr);
492244 return 0;
493245 }
494246 VERBOSE_PRINT("writesize %d byte\n", writeinfo->size);
495247 return 1;
496248 }
497249
498-static int serial_lock(const char *lock)
499-{
500- struct stat s;
501- int fd;
502- pid_t pid;
503- char buf[128];
504-
505- if (stat(lock, &s) == 0) {
506- fd = open(lock, O_RDWR);
507- if (fd == -1)
508- return -1;
509- read(fd, buf, sizeof(buf));
510- pid = atoi(buf);
511- if (pid > 0) {
512- if (kill(pid, 0) != -1 || errno != ESRCH)
513- return -1;
514- else {
515- lseek(fd, 0, SEEK_SET);
516- ftruncate(fd, 0);
517- }
518- }
519- } else {
520- fd = creat(lock, 0666);
521- if (fd == -1)
522- return -1;
523- }
524- pid = getpid();
525- sprintf(buf,"%8d",pid);
526- if (write(fd, buf, 8) != 8)
527- return -1;
528- return fd;
529-}
530-
531250 static int get_freq_num(const char *arg)
532251 {
533252 int scale = 100;
@@ -555,30 +274,31 @@ static int get_freq_num(const char *arg)
555274
556275 int main(int argc, char *argv[])
557276 {
558- char ser_port[FILENAME_MAX] = DEFAULT_SERIAL;
559- char lockname[FILENAME_MAX];
277+ char port[FILENAME_MAX] = DEFAULT_SERIAL;
560278 int c;
561279 int long_index;
562280 int input_freq;
563281 int force_binary;
564- int ser_fd;
565- int lock_fd;
282+ int config_list;
566283 int r;
567284 struct writeinfo_t writeinfo;
285+ struct port_t *p = NULL;
568286
569287 writeinfo.mat = user;
570288 force_binary = 0;
571289 input_freq = 0;
290+ config_list = 0;
291+
572292 /* parse argment */
573- while ((c = getopt_long(argc, argv, "p:f:bV",
293+ while ((c = getopt_long(argc, argv, "p:f:bVl",
574294 long_options, &long_index)) >= 0) {
575295 switch (c) {
576296 case 'u':
577297 writeinfo.mat = userboot;
578298 break ;
579299 case 'p':
580- strncpy(ser_port, optarg, sizeof(ser_port));
581- ser_port[sizeof(ser_port) - 1] = '\0';
300+ strncpy(port, optarg, sizeof(port));
301+ port[sizeof(port) - 1] = '\0';
582302 break ;
583303 case 'f':
584304 input_freq = get_freq_num(optarg);
@@ -589,44 +309,58 @@ int main(int argc, char *argv[])
589309 case 'V':
590310 verbose = 1;
591311 break ;
312+ case 'l':
313+ config_list = 1;
314+ break;
592315 case '?':
593316 usage();
594317 return 1;
595318 }
596319 }
597320
598- if (optind >= argc) {
321+ if (optind >= argc && !config_list) {
599322 usage();
600323 return 1;
601324 }
602325
603- snprintf(lockname, sizeof(lockname), LOCKDIR "/LCK..%s", basename(ser_port));
604- lock_fd = serial_lock(lockname);
605- if (lock_fd == -1) {
606- fputs(PROGNAME ": Serial port lock failed.\n",stderr);
607- return 1;
326+ r = 1;
327+ if (strncasecmp(port, "usb", 3) == 0) {
328+ unsigned short vid = DEFAULT_VID;
329+ unsigned short pid = DEFAULT_PID;
330+ if (strlen(port) > 3) {
331+ if (sscanf("%04x:%04x", port + 3, &vid, &pid) != 2) {
332+ fputs("Unkonwn USB device id", stderr);
333+ goto error;
334+ }
335+ }
336+ p = open_usb(vid, pid);
337+ } else
338+ p = open_serial(port);
339+ if (p == NULL)
340+ goto error;
341+
342+ if (config_list) {
343+ dump_configs(p);
344+ p->close();
345+ return 0;
608346 }
609347
610- r = 1;
611- ser_fd = setup_connection(ser_port, input_freq);
612- if(ser_fd < 0)
348+ if (setup_connection(p, input_freq) < 0)
613349 goto error;
614350 puts("connect target");
615351
616- if(!get_rominfo(ser_fd, &writeinfo))
352+ if(!get_rominfo(p, &writeinfo))
617353 goto error;
618-
619- if(writefile_to_rom(argv[optind], force_binary, &writeinfo, ser_fd)) {
620- VERBOSE_PRINT("write %08lx - %08lx ", writeinfo.area.start, writeinfo.area.end);
354+
355+ if(writefile_to_rom(argv[optind], force_binary,
356+ &writeinfo, p)) {
357+ VERBOSE_PRINT("write %08x - %08x ", writeinfo.area.start,
358+ writeinfo.area.end);
621359 r = 0;
622360 }
623361 error:
624362 puts((r==0)?"done":"write failed");
625- if (ser_fd >= 0)
626- close(ser_fd);
627-
628- close(lock_fd);
629- unlink(lockname);
630-
363+ if (p)
364+ p->close();
631365 return r;
632366 }
--- /dev/null
+++ b/serial.c
@@ -0,0 +1,206 @@
1+/*
2+ * Renesas CPU On-chip Flash memory writer
3+ * serial I/O
4+ *
5+ * Yoshinori Sato <ysato@users.sourceforge.jp>
6+ *
7+ * This file is subject to the terms and conditions of the GNU Lesser
8+ * General Public License version 2.1 (or later).
9+ */
10+
11+#include <stdio.h>
12+#include <sys/time.h>
13+#include <sys/types.h>
14+#include <unistd.h>
15+#include <string.h>
16+#include <termios.h>
17+#include <fcntl.h>
18+#include <stdlib.h>
19+#include <libgen.h>
20+#include <errno.h>
21+#include <sys/stat.h>
22+#include <sys/types.h>
23+#include <signal.h>
24+#include "h8flash.h"
25+
26+#define TRY1COUNT 60
27+#define BAUD_ADJUST_LEN 30
28+
29+static int ser_fd;
30+static int lock_fd;
31+static char lockname[FILENAME_MAX];
32+
33+/* send byte stream */
34+static int send_data(const unsigned char *buf, int len)
35+{
36+ return write(ser_fd, buf, len);
37+}
38+
39+/* receive 1byte */
40+static int receive_byte(unsigned char *data)
41+{
42+ int r;
43+ struct timeval tv;
44+ fd_set fdset;
45+
46+ *data = 0;
47+ tv.tv_sec = 60;
48+ tv.tv_usec = 0;
49+ FD_ZERO(&fdset);
50+ FD_SET(ser_fd, &fdset);
51+ r = select(ser_fd + 1, &fdset, NULL, NULL, &tv);
52+ if (r == -1)
53+ return -1;
54+ return read(ser_fd, data, 1);
55+}
56+
57+/* set host bitrate */
58+static int setbaud(int bitrate)
59+{
60+ int b;
61+ struct termios serattr;
62+
63+ b = 0;
64+ switch (bitrate) {
65+ case 96: b = B9600; break;
66+ case 192: b = B19200; break;
67+ case 384: b = B38400; break;
68+ case 576: b = B57600; break;
69+ case 1152: b = B115200; break;
70+ }
71+ if (b == 0)
72+ return 0;
73+
74+ tcgetattr(ser_fd, &serattr);
75+ cfsetospeed(&serattr, b);
76+ cfsetispeed(&serattr, b);
77+ tcsetattr(ser_fd, TCSANOW, &serattr);
78+ return 1;
79+}
80+
81+/* connection target CPU */
82+static int connect_target(void)
83+{
84+ int try1;
85+ int r;
86+ struct timeval tv;
87+ fd_set fdset;
88+ unsigned char buf[BAUD_ADJUST_LEN];
89+
90+ /* wait connection establish */
91+ for(try1 = 0; try1 < TRY1COUNT; try1++) {
92+ memset(buf, 0x00, BAUD_ADJUST_LEN);
93+ /* send dummy data */
94+ write(ser_fd, buf, BAUD_ADJUST_LEN);
95+ tv.tv_sec = 1;
96+ tv.tv_usec = 0;
97+ FD_ZERO(&fdset);
98+ FD_SET(ser_fd, &fdset);
99+ /* wait reply */
100+ r = select(ser_fd + 1, &fdset, NULL, NULL, &tv);
101+ if (r == -1)
102+ return 0;
103+ if ((r > 0) && (read(ser_fd, buf, 1) == 1) && buf[0] == 0)
104+ goto connect;
105+ if (try1 == 0) {
106+ printf("now connection");
107+ fflush(stdout);
108+ } else {
109+ putchar('.');
110+ fflush(stdout);
111+ }
112+ }
113+ putchar('\n');
114+ return 0;
115+ connect:
116+ /* connect done */
117+ buf[0] = 0x55;
118+ write(ser_fd, buf, 1);
119+ if ((receive_byte(buf) == 1) && (buf[0] == 0xe6))
120+ return 1; /* ok */
121+ else
122+ return 0; /* ng */
123+}
124+
125+void port_close(void)
126+{
127+ close(ser_fd);
128+ close(lock_fd);
129+ unlink(lockname);
130+}
131+
132+static struct port_t serial_port = {
133+ .type = serial,
134+ .send_data = send_data,
135+ .receive_byte = receive_byte,
136+ .connect_target = connect_target,
137+ .setbaud = setbaud,
138+ .close = port_close,
139+};
140+
141+static int serial_lock(const char *lock)
142+{
143+ struct stat s;
144+ int fd;
145+ pid_t pid;
146+ char buf[128];
147+
148+ if (stat(lock, &s) == 0) {
149+ fd = open(lock, O_RDWR);
150+ if (fd == -1)
151+ return -1;
152+ read(fd, buf, sizeof(buf));
153+ pid = atoi(buf);
154+ if (pid > 0) {
155+ if (kill(pid, 0) != -1 || errno != ESRCH)
156+ return -1;
157+ else {
158+ lseek(fd, 0, SEEK_SET);
159+ ftruncate(fd, 0);
160+ }
161+ }
162+ } else {
163+ fd = creat(lock, 0666);
164+ if (fd == -1)
165+ return -1;
166+ }
167+ pid = getpid();
168+ sprintf(buf,"%8d",pid);
169+ if (write(fd, buf, 8) != 8)
170+ return -1;
171+ return fd;
172+}
173+
174+/* host serial open */
175+struct port_t *open_serial(char *ser_port)
176+{
177+ struct termios serattr;
178+
179+ snprintf(lockname, sizeof(lockname), LOCKDIR "/LCK..%s", basename(ser_port));
180+ lock_fd = serial_lock(lockname);
181+ if (lock_fd == -1) {
182+ fputs(PROGNAME ": Serial port lock failed.\n",stderr);
183+ return NULL;
184+ }
185+
186+ ser_fd = open(ser_port, O_RDWR);
187+ if (ser_fd == -1) {
188+ perror("PROGNAME: ");
189+ return NULL;
190+ }
191+
192+ tcgetattr(ser_fd, &serattr);
193+ serattr.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON | IXOFF);
194+ serattr.c_oflag &= ~OPOST;
195+ serattr.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
196+ serattr.c_cflag &= ~(CSIZE | PARENB);
197+ serattr.c_cflag |= CS8 | CLOCAL;
198+ serattr.c_cc[VMIN] = 1;
199+ serattr.c_cc[VTIME] = 0;
200+ cfsetospeed(&serattr, B9600);
201+ cfsetispeed(&serattr, B9600);
202+ tcsetattr(ser_fd, TCSANOW, &serattr);
203+
204+ return &serial_port;
205+}
206+
--- /dev/null
+++ b/usb.c
@@ -0,0 +1,89 @@
1+#include <usb.h>
2+#include <stdio.h>
3+#include "h8flash.h"
4+
5+#define USB_TIMEOUT 100000
6+
7+static struct usb_dev_handle *handle;
8+
9+static int usb_send_data(const unsigned char *buf, int len)
10+{
11+ return usb_bulk_write(handle, 0x01, (const char *)buf, len, USB_TIMEOUT);
12+}
13+
14+int usb_read_byte(unsigned char *data)
15+{
16+ static unsigned char buf[64];
17+ static unsigned char *rp;
18+ static int count = 0;
19+
20+ if (count == 0) {
21+ int r = usb_bulk_read(handle, 0x82, (char *)buf, 64, USB_TIMEOUT);
22+ if (r < 0)
23+ return r;
24+ count = r;
25+ rp = buf;
26+ }
27+ count--;
28+ *data = *rp++;
29+ return 1;
30+}
31+
32+/* connection target CPU */
33+static int connect_target(void)
34+{
35+ unsigned char req = 0x55;
36+ int r;
37+ usb_bulk_write(handle, 0x01, (const char *)&req, 1, USB_TIMEOUT);
38+ while ((r = usb_bulk_read(handle, 0x82, (char *)&req, 1, USB_TIMEOUT)) == 0)
39+ usleep(100000);
40+ if (r < 0 || req != 0xe6)
41+ return 0;
42+ else
43+ return 1;
44+}
45+
46+static void port_close(void)
47+{
48+ usb_close(handle);
49+}
50+
51+static struct port_t usb_port = {
52+ .type = usb,
53+ .send_data = usb_send_data,
54+ .receive_byte = usb_read_byte,
55+ .connect_target = connect_target,
56+ .setbaud = NULL,
57+ .close = port_close,
58+};
59+
60+struct port_t *open_usb(unsigned short vid, unsigned short pid)
61+{
62+ struct usb_bus *busses;
63+ struct usb_bus *bus;
64+ struct usb_device *dev = NULL;
65+ usb_init();
66+ usb_get_busses();
67+ usb_find_busses();
68+ usb_find_devices();
69+
70+ busses = usb_get_busses();
71+
72+ for (bus = busses; bus; bus = bus->next) {
73+ for (dev = bus->devices; dev; dev = dev->next) {
74+ if ((dev->descriptor.idVendor == vid) &&
75+ (dev->descriptor.idProduct == pid))
76+ goto found;
77+ }
78+ }
79+found:
80+ if (dev == NULL)
81+ return NULL;
82+ handle = usb_open(dev);
83+ if (handle == NULL) {
84+ puts(usb_strerror());
85+ return NULL;
86+ }
87+ usb_claim_interface(handle, dev->config->interface->altsetting->bInterfaceNumber);
88+ return &usb_port;
89+}