OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [calmrisc16/] [ceb/] [current/] [support/] [calmbreaker.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
/*=============================================================================
2
//
3
//      calmbreaker.c
4
//
5
//      Host to CalmBreaker communication utility.
6
//
7
//=============================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under
14
// the terms of the GNU General Public License as published by the Free
15
// Software Foundation; either version 2 or (at your option) any later
16
// version.
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21
// for more details.
22
//
23
// You should have received a copy of the GNU General Public License
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
26
//
27
// As a special exception, if other files instantiate templates or use
28
// macros or inline functions from this file, or you compile this file
29
// and link it with other works to produce a work based on this file,
30
// this file does not by itself cause the resulting work to be covered by
31
// the GNU General Public License. However the source code for this file
32
// must still be made available in accordance with section (3) of the GNU
33
// General Public License v2.
34
//
35
// This exception does not invalidate any other reasons why a work based
36
// on this file might be covered by the GNU General Public License.
37
// -------------------------------------------
38
// ####ECOSGPLCOPYRIGHTEND####
39
//=============================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):    msalter
43
// Contributors: msalter
44
// Date:         2001-03-02
45
// Purpose:
46
// Description:  Host to CalmBreaker communication utility.
47
//
48
//####DESCRIPTIONEND####
49
//
50
//===========================================================================*/
51
 
52
#include <termios.h>
53
#include <fcntl.h>
54
#include <stdio.h>
55
 
56
int ser_fd;  // The com port
57
int is_risc16;
58
 
59
void
60
tty_setup(int fd)
61
{
62
    struct termios t;
63
 
64
    memset(&t, 0, sizeof(struct termios));
65
 
66
    t.c_oflag = 0;
67
    t.c_lflag = 0;
68
 
69
    t.c_cflag &= ~(CSIZE | PARENB);
70
    t.c_cflag |= CS8 | CREAD /*| CSTOPB*/;
71
    t.c_cflag |= CLOCAL;                   // ignore modem status lines
72
 
73
    t.c_iflag = IGNBRK | IGNPAR /* | ISTRIP */ ;
74
 
75
    t.c_lflag &= ~ICANON;                  // non-canonical mode
76
    t.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHOKE);
77
 
78
    t.c_cc[VMIN]  = 0;
79
    t.c_cc[VTIME] = 10;  // 1 second timeout
80
 
81
    t.c_cflag &= ~CRTSCTS;
82
 
83
    /* set speed */
84
    cfsetispeed(&t, B57600);
85
    cfsetospeed(&t, B57600);
86
 
87
    tcdrain(fd);
88
 
89
    if (tcsetattr(fd, TCSANOW, &t) < 0)
90
    {
91
        perror("tcssetattr");
92
        exit(1);
93
    }
94
}
95
 
96
static void
97
do_putc(unsigned char ch)
98
{
99
    // keep retrying until sent or an error is returned
100
    while (write(ser_fd, &ch, 1) == 0);
101
}
102
 
103
static int
104
do_getc(unsigned char *ucp)
105
{
106
    return read(ser_fd, ucp, 1);
107
}
108
 
109
static int
110
wait_for_ack(void)
111
{
112
    unsigned char ch;
113
    int i;
114
 
115
    // try for 5 seconds
116
    for (i = 0; i < 5; i++) {
117
        if (do_getc(&ch)) {
118
            if (ch == '+')
119
                return 1;
120
            printf("Bad ack [0x%x]\n", ch);
121
        }
122
    }
123
    printf("No ack\n");
124
    return 0;
125
}
126
 
127
// Add prefix and checksum to packet and send to MDS board.
128
void
129
send_packet_noack(unsigned char *pkt, int len)
130
{
131
    unsigned char cksum = 0;
132
 
133
    do_putc(':');
134
 
135
    while (len-- > 0) {
136
        cksum += *pkt;
137
        do_putc(*pkt++);
138
    }
139
 
140
    do_putc(0x100 - cksum);
141
}
142
 
143
// Add prefix and checksum to packet and send to MDS board.
144
void
145
send_packet(unsigned char *pkt, int len)
146
{
147
    send_packet_noack(pkt, len);
148
    wait_for_ack();
149
}
150
 
151
 
152
 
153
// Send a packet of code or data (max 0xff bytes)
154
int
155
send_data_packet(int is_data, unsigned addr, unsigned char *buf, int buflen)
156
{
157
    unsigned char uc, cksum = 0;
158
    int i;
159
 
160
    do_putc(':');
161
 
162
    // code or data?
163
    uc = is_data ? 0x52 : 0x51;
164
    cksum += uc;
165
    do_putc(uc);
166
 
167
    // code/data nwords?
168
    uc = buflen >> 1;
169
    cksum += uc;
170
    do_putc(uc);
171
 
172
    // code/data address
173
    uc = (unsigned char)(addr >> 24);
174
    cksum += uc;
175
    do_putc(uc);
176
    uc = (unsigned char)(addr >> 16);
177
    cksum += uc;
178
    do_putc(uc);
179
    uc = (unsigned char)(addr >> 8);
180
    cksum += uc;
181
    do_putc(uc);
182
    uc = (unsigned char)addr;
183
    cksum += uc;
184
    do_putc(uc);
185
 
186
    while (buflen-- > 0) {
187
        cksum += *buf;
188
        do_putc(*buf++);
189
    }
190
 
191
    do_putc(0x100 - cksum);
192
 
193
    return wait_for_ack();
194
}
195
 
196
 
197
void
198
send_command(unsigned char uc)
199
{
200
    send_packet(&uc, 1);
201
}
202
 
203
void
204
send_command_noack(unsigned char uc)
205
{
206
    send_packet_noack(&uc, 1);
207
}
208
 
209
// Simple single-byte commands
210
void target_reset(void) { send_command(0x20); }
211
void target_singlestep(void) { send_command(0x22); }
212
void target_singlecycle(void) { send_command(0x23); }
213
void target_stop(void) { send_command(0x24); }
214
void target_run(void) { send_command_noack(0x25); }
215
 
216
#define DOWNLOAD_CHUNK_SIZE 254
217
 
218
int
219
download_words(int is_data, unsigned addr, unsigned char *buf, int buflen)
220
{
221
    while (buflen >= DOWNLOAD_CHUNK_SIZE) {
222
        if (!send_data_packet(is_data, addr, buf, DOWNLOAD_CHUNK_SIZE)) {
223
            printf("Error downloading %d bytes of %s to 0x%x\n",
224
                   DOWNLOAD_CHUNK_SIZE, (is_data ? "data" : "code"), addr);
225
            return 0;
226
        }
227
        addr += DOWNLOAD_CHUNK_SIZE;
228
        buf += DOWNLOAD_CHUNK_SIZE;
229
        buflen -= DOWNLOAD_CHUNK_SIZE;
230
    }
231
    if (buflen && !send_data_packet(is_data, addr, buf, buflen)) {
232
        printf("Error downloading %d bytes of %s to 0x%x\n",
233
               buflen, (is_data ? "data" : "code"), addr);
234
        return 0;
235
    }
236
    return 1;
237
}
238
 
239
static inline int
240
gethexnibble(FILE *fp)
241
{
242
    int ch;
243
 
244
    ch = getc(fp);
245
    if (ch >= '0' && ch <= '9')
246
        return (ch - '0');
247
    if (ch >= 'a' && ch <= 'f')
248
        return (ch - 'a' + 10);
249
    if (ch >= 'A' && ch <= 'F')
250
        return (ch - 'A' + 10);
251
 
252
    if (ch == EOF)
253
        fprintf(stderr, "Unexpected EOF\n");
254
    else
255
        fprintf(stderr, "Bad hex char\n");
256
 
257
    return -1;
258
}
259
 
260
 
261
static inline int
262
gethexbyte(FILE *fp)
263
{
264
    int nib;
265
    unsigned char n;
266
 
267
    if ((nib = gethexnibble(fp)) < 0)
268
        return -1;
269
    n = nib << 4;
270
    if ((nib = gethexnibble(fp)) < 0)
271
        return -1;
272
    n |= nib;
273
    return n;
274
}
275
 
276
static inline int
277
chk_cksum(FILE *fp, unsigned int cksum)
278
{
279
    int n;
280
 
281
    if ((n = gethexbyte(fp)) < 0)
282
        return -1;
283
 
284
    cksum = ~cksum & 0xff;
285
 
286
    if (cksum != n) {
287
        fprintf(stderr, "Bad cksum[%02x]\n", cksum);
288
        return -1;
289
    }
290
    return 0;
291
}
292
 
293
int
294
load_srec(FILE *fp, int is_data)
295
{
296
    int count, dcount, data, n, addr_bytes = 0, is_term, is_comment;
297
    unsigned long address, cksum;
298
    unsigned char data_buf[256];
299
 
300
    is_comment = is_term = 0;
301
 
302
    do {
303
        if ((n = getc(fp)) == EOF)
304
            return 1;
305
    } while (n != 'S');
306
 
307
    switch (n = gethexnibble(fp)) {
308
      case 0:
309
      case 5:
310
        is_comment = 1;
311
        break;
312
 
313
      case 1:
314
      case 2:
315
      case 3:
316
        addr_bytes = n + 1;
317
        break;
318
 
319
      case 7:
320
      case 8:
321
      case 9:
322
        is_term = 1;
323
        addr_bytes = 11 - n;
324
        break;
325
 
326
      default:
327
        if (n < 0)
328
            return -1;
329
        fprintf(stderr, "Bad record type: %d\n", n);
330
        return -1;
331
    }
332
 
333
    if ((count = gethexbyte(fp)) < 0)
334
        return -1;
335
 
336
    cksum = count;
337
 
338
    --count; // don't count chksum
339
 
340
    if (is_comment) {
341
        while (count > 0) {
342
            if ((n = gethexbyte(fp)) < 0)
343
                return -1;
344
            cksum += n;
345
            --count;
346
        }
347
        if (chk_cksum(fp,cksum) < 0)
348
            return -1;
349
        return 0;
350
    }
351
 
352
    address = 0;
353
    while (count > 0 && addr_bytes) {
354
        if ((n = gethexbyte(fp)) < 0)
355
            return -1;
356
        cksum += n;
357
        address = (address << 8) | n;
358
        --addr_bytes;
359
        --count;
360
    }
361
 
362
    if (is_risc16 && (address & 0x400000))
363
        address &= 0x3fffff;
364
 
365
    if (is_term) {
366
        if (count || addr_bytes) {
367
            fprintf(stderr, "Malformed record cnt[%d] abytes[%d]\n",
368
                    count, addr_bytes);
369
            return -1;
370
        }
371
        if (chk_cksum(fp, cksum) == 0) {
372
            fprintf(stderr, "Setting start address: 0x%08x\n", address);
373
            return 1;
374
        }
375
        return -1;
376
    }
377
 
378
    for (dcount = 0; dcount < count; dcount++) {
379
        if ((data = gethexbyte(fp)) < 0)
380
            return -1;
381
        cksum += data;
382
        data_buf[dcount] = data;
383
    }
384
 
385
    if (chk_cksum(fp, cksum) < 0)
386
        return -1;
387
 
388
    if (dcount & 1)
389
        dcount++;
390
 
391
    if (!download_words(is_data, address, data_buf, dcount))
392
        return -1;
393
 
394
    return 0;
395
}
396
 
397
 
398
int
399
load_hex(FILE *fp, int is_data)
400
{
401
    int count, n, i;
402
    unsigned long address;
403
    unsigned char data_buf[256];
404
 
405
    do {
406
        if ((n = getc(fp)) == EOF)
407
            return 1;
408
    } while (n == '\r' || n == '\n');
409
 
410
    if (n == '#') {
411
        do {
412
            if ((n = getc(fp)) == EOF)
413
                return 1;
414
        } while (n != '\r' && n != '\n');
415
        return 0;
416
    }
417
 
418
    if (n != ':') {
419
        fprintf(stderr, "Unrecognized HEX line start.\n");
420
        return -1;
421
    }
422
 
423
    if ((count = gethexbyte(fp)) < 0)
424
        return -1;
425
 
426
    address = 0;
427
    for (i = 0; i < 4; i++) {
428
        if ((n = gethexbyte(fp)) < 0)
429
            return -1;
430
        address = (address << 8) | n;
431
    }
432
 
433
    // skip type byte
434
    if ((n = gethexbyte(fp)) < 0)
435
        return -1;
436
 
437
    for (i = 0; i < count; i++) {
438
        if ((n = gethexbyte(fp)) < 0)
439
            return -1;
440
        data_buf[i] = n;
441
    }
442
 
443
    // skip chksum byte
444
    if ((n = gethexbyte(fp)) < 0)
445
        return -1;
446
 
447
    if (count & 1)
448
        ++count;
449
 
450
    if (!download_words(is_data, address, data_buf, count))
451
        return -1;
452
 
453
    return 0;
454
}
455
 
456
 
457
int
458
main(int argc, char *argv[])
459
{
460
    int i;
461
    int do_download = 0, is_data, is_hex;
462
    int do_run = 0, do_reset = 0;
463
    char *filename = NULL;
464
    char *portname = "/dev/ttyS0";
465
    FILE *infile;
466
 
467
    if (argc == 1) {
468
        fprintf(stderr, "Usage: mds_talk [--run] [--reset] [--srec-code | --srec-date | --hex-code | --hex-data] [-f filename] [-p serial_dev]\n");
469
        exit(1);
470
    }
471
 
472
    is_risc16 = 0;
473
    for (i = 1; i < argc; i++) {
474
        if (!strcmp(argv[i], "--srec-code")) {
475
            do_download = 1;
476
            is_data = 0;
477
            is_hex = 0;
478
        } else if (!strcmp(argv[i], "--srec-data")) {
479
            do_download = 1;
480
            is_data = 1;
481
            is_hex = 0;
482
        } else if (!strcmp(argv[i], "--hex-code")) {
483
            do_download = 1;
484
            is_data = 0;
485
            is_hex = 1;
486
        } else if (!strcmp(argv[i], "--hex-data")) {
487
            do_download = 1;
488
            is_data = 1;
489
            is_hex = 1;
490
        } else if (!strcmp(argv[i], "--reset"))
491
            do_reset = 1;
492
        else if (!strcmp(argv[i], "--run"))
493
            do_run = 1;
494
        else if (!strcmp(argv[i], "-f")) {
495
            if (++i >= argc) {
496
                fprintf(stderr, "Missing filename\n");
497
                exit(1);
498
            }
499
            filename = argv[i];
500
        } else if (!strcmp(argv[i], "-p")) {
501
            if (++i >= argc) {
502
                fprintf(stderr, "Missing serial port name\n");
503
                exit(1);
504
            }
505
            portname = argv[i];
506
        } else if (!strcmp(argv[i], "--risc16")) {
507
            is_risc16 = 1;
508
        } else {
509
            fprintf(stderr, "Unknown argument \"%s\"\n", argv[i]);
510
            exit(1);
511
        }
512
    }
513
 
514
    if ((ser_fd = open(portname, O_RDWR | O_NOCTTY)) < 0) {
515
        fprintf(stderr, "Can't open port %s\n", portname);
516
        exit(1);
517
    }
518
    tty_setup(ser_fd);
519
 
520
    if (filename) {
521
        if ((infile = fopen(filename, "r")) == NULL) {
522
            fprintf(stderr, "Can't open file %s\n", filename);
523
            exit(1);
524
        }
525
    } else
526
        infile = stdin;
527
 
528
    if (do_reset)
529
        target_reset();
530
 
531
    if (do_download) {
532
        if (is_hex)
533
            while (!load_hex(infile, is_data)) ;
534
        else
535
            while (!load_srec(infile, is_data)) ;
536
    }
537
 
538
    if (do_run)
539
        target_run();
540
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.