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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [calmrisc16/] [ceb/] [v2_0/] [support/] [calmbreaker.c] - Blame information for rev 27

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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