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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [io/] [serial/] [v2_0/] [tests/] [ser_test_protocol.inl] - Blame information for rev 307

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

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//        ser_test_protocol.c
4
//
5
//        Serial device driver testing protocol
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):     jskov
44
// Contributors:  jskov, gthomas
45
// Date:          1999-03-17
46
// Description:   Protocol implementation used to test eCos serial devices.
47
//                Relies on ser_filter to be present on the host side to
48
//                respond to test requests.
49
//
50
// To Do:
51
//  o Clean up.
52
//  o Clean up config change magic.
53
//  o Figure out how to handle kernel dependency
54
//    : without kernel, no timeout. Without timeout, no filter auto detection.
55
//
56
//####DESCRIPTIONEND####
57
 
58
#include 
59
#include 
60
#include 
61
 
62
#include 
63
#include 
64
#include 
65
#include 
66
#include 
67
 
68
#include            // for reclaiming interrupt vector
69
 
70
//----------------------------------------------------------------------------
71
// Definition of which device to run tests on on various platforms.
72
 
73
#define NA_MSG "No test device specified"
74
 
75
// Cleaned up drivers will export the testing parameters via CDL.
76
// When all drivers are changed, replace the TEST_ macros throughout
77
// with the CYGPRI_ equivalents.
78
#ifdef CYGPRI_SER_TEST_CRASH_ID
79
# define TEST_CRASH_ID CYGPRI_SER_TEST_CRASH_ID
80
# define TEST_SER_DEV  CYGPRI_SER_TEST_SER_DEV
81
# define TEST_TTY_DEV  CYGPRI_SER_TEST_TTY_DEV
82
#endif
83
 
84
// Note that CYGPRI_SER_TEST_OVERRIDE_INT_1 and CYGPRI_SER_TEST_OVERRIDE_INT_2
85
// may also be exported. These identify interrupts that should be reclaimed
86
// from the ROM monitor before the test is started.
87
 
88
#if defined(CYGPKG_HAL_POWERPC_MBX)                          \
89
    && defined(CYGPKG_HAL_QUICC)                 \
90
    && defined(CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC)                 \
91
    && defined(CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC1)
92
# define TEST_CRASH_ID "ppcmbx"
93
# define TEST_SER_DEV CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_NAME
94
# if defined(CYGPKG_IO_SERIAL_TTY_TTY1)
95
#  define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY1_DEV
96
# endif
97
#endif
98
#if defined(CYGPKG_HAL_MN10300_AM31_STDEVAL1)           \
99
    && defined(CYGPKG_IO_SERIAL_MN10300)                \
100
    && defined(CYGPKG_IO_SERIAL_MN10300_SERIAL2)
101
# define TEST_CRASH_ID "am31st"
102
# define TEST_SER_DEV CYGDAT_IO_SERIAL_MN10300_SERIAL2_NAME
103
# if defined(CYGPKG_IO_SERIAL_TTY_TTY2)
104
#  define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY1_DEV
105
# endif
106
#endif
107
#if defined(CYGPKG_HAL_MN10300_AM33_STB)                \
108
    && defined(CYGPKG_IO_SERIAL_MN10300)                \
109
    && defined(CYGPKG_IO_SERIAL_MN10300_SERIAL0)
110
# define TEST_CRASH_ID "am33st"
111
# define TEST_SER_DEV CYGDAT_IO_SERIAL_MN10300_SERIAL0_NAME
112
# if defined(CYGPKG_IO_SERIAL_TTY_TTY0)
113
#  define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY0_DEV
114
# endif
115
#endif
116
 
117
// We can't rely on haldiag for ser_filter detection - it may not define
118
// a working character reading function.
119
#ifndef   TEST_SER_DEV
120
# define  SER_NOP_TEST
121
# define  TTY_NOP_TEST
122
# define  TEST_SER_DEV "/dev/null"
123
# define  TEST_TTY_DEV "/dev/null"
124
#else
125
# ifndef  TEST_TTY_DEV
126
#  define TTY_NOP_TEST
127
# define  TEST_TTY_DEV "/dev/null"
128
# endif
129
#endif
130
 
131
#ifndef TEST_CRASH_ID
132
#define TEST_CRASH_ID "......"
133
#endif
134
 
135
//----------------------------------------------------------------------------
136
// Crash types
137
// Eventually this will be moved into a separate header file so a script
138
// can read the definitions and use the output formats/codes to analyze
139
// test results. For now we just keep it here...
140
 
141
// FAILCODE:
142
//  tttttt: 6 letter target code
143
//  cccc:   crash code (16bit hex value)
144
 
145
#define TEST_CRASH(__h, __code, __msg, args...)                         \
146
    CYG_MACRO_START                                                     \
147
    int __len = 1;                                                      \
148
    /* Try to flush remaining input */                                  \
149
    cyg_thread_delay(50);                                               \
150
    cyg_io_get_config(__h, CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH,        \
151
                      0, &__len);                                       \
152
    diag_printf("FAILCODE:<" TEST_CRASH_ID ":%04x:" __code, ## args);    \
153
    diag_printf("!>\n");                                                \
154
    CYG_FAIL(__msg);                                                    \
155
    hang();                                                             \
156
    CYG_MACRO_END
157
 
158
// Target IO
159
#define TEST_CRASH_IO                     0x0000
160
#define TEST_CRASH_IO_READ                "%d",            0x0001
161
#define TEST_CRASH_IO_WRITE               "%d",            0x0002
162
#define TEST_CRASH_IO_DRAIN               "%d",            0x0003
163
#define TEST_CRASH_IO_GET_CFG             "%d",            0x0004
164
#define TEST_CRASH_IO_SET_CFG             "%d",            0x0005
165
 
166
// Target
167
#define TEST_CRASH_CRC                    0x0010
168
#define TEST_CRASH_CRC_CHAR               "%02x",          0x0011
169
#define TEST_CRASH_CRC_BAD                "%08x:%08x",     0x0012
170
#define TEST_CRASH_CRC_HOST               "",              0x0013
171
 
172
// Protocol errors
173
#define TEST_CRASH_PROT                   0x1000
174
#define TEST_CRASH_PROT_BIN_MODE          "%d",            0x1080
175
#define TEST_CRASH_PROT_TEXT              "%d",            0x1100
176
 
177
#define TEST_CRASH_HOST_xx                0xf000
178
#define TEST_CRASH_HOST_TIMEOUT           "%d:%d:%d:%d",      0xf000
179
        // command#, read invocation#, expected, actual
180
#define TEST_CRASH_HOST_CRC_BAD           "%d:%08x:%08x:%d:%02x:%02x", 0xf010
181
        // command#, expected CRC, actual, index, expected char, actual
182
#define TEST_CRASH_HOST_DUPLEX_BAD        "%d:%d:%02x:%02x",     0xf020
183
        // command#, index, expected char, actual
184
 
185
//----------------------------------------------------------------------------
186
// The data in buffer and the cmd buffer
187
#ifndef IN_BUFFER_SIZE
188
# define IN_BUFFER_SIZE 1024
189
#endif
190
cyg_uint8 in_buffer[IN_BUFFER_SIZE];
191
 
192
cyg_int8 cmd_buffer[128];
193
 
194
//----------------------------------------------------------------------------
195
// Some types specific to the testing protocol.
196
typedef enum {
197
    MODE_NO_ECHO = 0,
198
    MODE_EOP_ECHO,
199
    MODE_DUPLEX_ECHO
200
} cyg_mode_t;
201
 
202
typedef enum {
203
    TEST_RETURN_OK = ENOERR,
204
    TEST_RETURN_NA
205
} cyg_test_return_t;
206
 
207
typedef struct ser_cfg {
208
    cyg_serial_baud_rate_t    baud_rate;
209
    cyg_serial_word_length_t  data_bits;
210
    cyg_serial_stop_bits_t    stop_bits;
211
    cyg_serial_parity_t       parity;
212
    cyg_uint32                flags;
213
    // etc...
214
} cyg_ser_cfg_t;
215
 
216
typedef enum {
217
    OPT_SERIAL_DEBUG = 0,
218
    OPT_VERBOSE_LEVEL
219
} cyg_option_t;
220
 
221
typedef enum {
222
    _NONE = 0,
223
    PROTOCOL_PROGRESS,
224
    PROTOCOL_DATA,
225
} cyg_verbosity_level_t;
226
 
227
 
228
// A few predifined option macros. Use after test_ping().
229
#define TEST_OPTIONS(__handle, __array) \
230
  test_options(__handle, sizeof(__array)/8, __array)
231
 
232
#define TEST_HOST_DEBUG(__handle)                               \
233
    CYG_MACRO_START                                             \
234
    cyg_uint32 __options[] = {OPT_SERIAL_DEBUG, 1};             \
235
    test_options((__handle), sizeof(__options)/8,               \
236
                 __options);                                    \
237
    CYG_MACRO_END
238
 
239
#define TEST_HOST_PROGRESS(__handle)                            \
240
    CYG_MACRO_START                                             \
241
    cyg_uint32 __options[] =                                    \
242
        {OPT_SERIAL_DEBUG, 1,                                   \
243
         OPT_VERBOSE_LEVEL, PROTOCOL_PROGRESS};                 \
244
    test_options((__handle), sizeof(__options)/8,               \
245
                 __options);                                    \
246
    CYG_MACRO_END
247
 
248
#define TEST_HOST_DATA(__handle)                                \
249
    CYG_MACRO_START                                             \
250
    cyg_uint32 __options[] =                                    \
251
        {OPT_SERIAL_DEBUG, 1,                                   \
252
         OPT_VERBOSE_LEVEL, PROTOCOL_DATA};                     \
253
    test_options((__handle), sizeof(__options)/8,               \
254
                 __options);                                    \
255
    CYG_MACRO_END
256
 
257
//----------------------------------------------------------------------------
258
// A few predefined configurations. These must all be valid for any
259
// given target until change_config is behaving correctly.
260
cyg_ser_cfg_t test_configs[] = {
261
#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_9600)
262
    { CYGNUM_SERIAL_BAUD_9600, CYGNUM_SERIAL_WORD_LENGTH_8,
263
      CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
264
      CYGNUM_SERIAL_FLOW_NONE },
265
#endif
266
 
267
#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_14400)
268
#if !defined(CYGPKG_HAL_MN10300_AM31) &&    \
269
    !defined(CYGPKG_HAL_MN10300_AM33)
270
    { CYGNUM_SERIAL_BAUD_14400, CYGNUM_SERIAL_WORD_LENGTH_8,
271
      CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
272
      CYGNUM_SERIAL_FLOW_NONE },
273
#endif
274
#endif
275
 
276
    { CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8,
277
      CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
278
      CYGNUM_SERIAL_FLOW_NONE },
279
 
280
#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_38400)
281
    { CYGNUM_SERIAL_BAUD_38400, CYGNUM_SERIAL_WORD_LENGTH_8,
282
      CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
283
      CYGNUM_SERIAL_FLOW_NONE },
284
#endif
285
 
286
#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_57600)
287
#if !defined(CYGPKG_HAL_MN10300_AM33)
288
    { CYGNUM_SERIAL_BAUD_57600, CYGNUM_SERIAL_WORD_LENGTH_8,
289
      CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
290
      CYGNUM_SERIAL_FLOW_NONE },
291
#endif
292
#endif
293
 
294
#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_115200)
295
#if !defined(CYGPKG_HAL_MN10300_STDEVAL1)
296
    { CYGNUM_SERIAL_BAUD_115200, CYGNUM_SERIAL_WORD_LENGTH_8,
297
      CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
298
      CYGNUM_SERIAL_FLOW_NONE },
299
#endif
300
#endif
301
 
302
#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_PARITY_EVEN)
303
    // One stop bit, even parity
304
    { CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8,
305
      CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_EVEN,
306
      CYGNUM_SERIAL_FLOW_NONE },
307
#endif
308
 
309
#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_PARITY_EVEN)
310
#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_STOP_2)
311
    // Two stop bits, even parity
312
    { CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8,
313
      CYGNUM_SERIAL_STOP_2, CYGNUM_SERIAL_PARITY_EVEN,
314
      CYGNUM_SERIAL_FLOW_NONE },
315
#endif
316
#endif
317
 
318
#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_STOP_2)
319
    // Two stop bits, no parity
320
    { CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8,
321
      CYGNUM_SERIAL_STOP_2, CYGNUM_SERIAL_PARITY_NONE,
322
      CYGNUM_SERIAL_FLOW_NONE },
323
#endif
324
};
325
 
326
//----------------------------------------------------------------------------
327
// Macros to help extract values from the argument string.
328
// Note: This is probably not an ideal solution, but it was easy to make :)
329
 
330
#define INIT_VALUE(__args)                      \
331
    unsigned int v;                             \
332
    char *__ptr1, *__ptr2 = (__args)
333
 
334
#define SET_VALUE(__slot)                       \
335
do {                                            \
336
    __ptr1 = index(__ptr2, (int) ':');          \
337
    if (__ptr1)                                 \
338
        *__ptr1 = 0;                            \
339
    v = atoi(__ptr2);                           \
340
    __ptr2 = __ptr1+1;                          \
341
    (__slot) = v;                               \
342
} while (0)
343
 
344
 
345
//----------------------------------------------------------------------------
346
// CRC magic - it's a bit of a hack for now.
347
// FIXME: standard definition?
348
#define ADD_CRC_BYTE(__crc, __c)                \
349
    CYG_MACRO_START                             \
350
    (__crc) = ((__crc) << 1) ^ (__c);           \
351
    CYG_MACRO_END
352
 
353
// FIXME: Hack to allow easy ASCII transfer.
354
#define FIX_CRC(__crc, __icrc)                  \
355
    CYG_MACRO_START                             \
356
    __icrc = (int) (__crc);                     \
357
    if (__icrc < 0)                             \
358
        __icrc = -__icrc;                       \
359
    CYG_MACRO_END
360
 
361
//----------------------------------------------------------------------------
362
// Macros for read/write to serial with error cheking.
363
static volatile cyg_uint32 r_stamp;
364
static volatile int aborted;
365
 
366
// This routine will be called if the read "times out"
367
static void
368
do_abort(void *handle)
369
{
370
    cyg_io_handle_t io_handle = (cyg_io_handle_t)handle;
371
    cyg_int32 len = 1;  // Need something here
372
    cyg_io_get_config(io_handle, CYG_IO_GET_CONFIG_SERIAL_ABORT, 0, &len);
373
    aborted = 1;
374
}
375
#include "timeout.inl"
376
 
377
// Read with timeout (__t = timeout in ticks, int* __r = result)
378
#define Tcyg_io_read_timeout(__h, __d, __l, __t, __r)           \
379
    CYG_MACRO_START                                             \
380
    int __res;                                                  \
381
    r_stamp = timeout((__t), do_abort, (__h));                  \
382
    __res = cyg_io_read((__h), (__d), (__l));                   \
383
    if (ENOERR != __res && -EINTR != __res) {                   \
384
        TEST_CRASH(__h, TEST_CRASH_IO_READ,                     \
385
                   "cyg_io_read/timeout failed", __res);        \
386
    }                                                           \
387
    *(__r) = __res;                                             \
388
    untimeout(r_stamp);                                         \
389
    CYG_MACRO_END
390
 
391
#define Tcyg_io_read(__h, __d, __l)                     \
392
    CYG_MACRO_START                                     \
393
    int __res = cyg_io_read((__h), (__d), (__l));       \
394
    if (ENOERR != __res) {                              \
395
        TEST_CRASH(__h, TEST_CRASH_IO_READ,             \
396
                   "cyg_io_read failed", __res);        \
397
    }                                                   \
398
    CYG_MACRO_END
399
 
400
#define Tcyg_io_write(__h, __d, __l)                                    \
401
    CYG_MACRO_START                                                     \
402
    int __res;                                                          \
403
    cyg_uint32 __len = 1;                                               \
404
    __res = cyg_io_write((__h), (__d), (__l));                          \
405
    if (ENOERR != __res) {                                              \
406
        TEST_CRASH(__h, TEST_CRASH_IO_WRITE,                            \
407
                   "cyg_io_write failed", __res);                       \
408
    }                                                                   \
409
    __res = cyg_io_get_config((__h),                                    \
410
                              CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN,    \
411
                              0, &__len);                               \
412
    if (ENOERR != __res) {                                              \
413
        TEST_CRASH(__h, TEST_CRASH_IO_DRAIN,                            \
414
                   "DRAIN failed", __res);                              \
415
    }                                                                   \
416
    CYG_MACRO_END
417
 
418
 
419
//----------------------------------------------------------------------------
420
// Some libc like functions that are handy to have around.
421
static int
422
strlen(const char *c)
423
{
424
    int l = 0;
425
    while (*c++) l++;
426
    return l;
427
}
428
 
429
static char*
430
strcpy(char* dest, const char* src)
431
{
432
    char c;
433
    while ((c = *src++)) {
434
        *dest++ = c;
435
    }
436
    *dest = c;
437
 
438
    return dest;
439
}
440
 
441
static char*
442
itoa(char* dest, int v)
443
{
444
    char b[16];
445
    char* p = &b[16];
446
 
447
    *--p = 0;
448
    if (v) {
449
        while (v){
450
            *--p = (v % 10) + '0';
451
            v = v / 10;
452
        }
453
    } else
454
        *--p = '0';
455
 
456
    return strcpy(dest, p);
457
}
458
 
459
#define min(_a, _b) ((_a) < (_b)) ? (_a) : (_b)
460
 
461
void
462
hang(void)
463
{
464
    while (1);
465
}
466
 
467
//-----------------------------------------------------------------------------
468
// Configuration changing function.
469
//
470
// First change to the new config and back again to determine if the driver
471
// can handle the config.
472
// If not, return error.
473
//
474
// Then query the host for its capability to use the config:
475
// Format out:
476
//  "@CONFIG::<#data bits>:<#stop bits>::!"
477
// Format in:
478
//  OK/ER
479
//
480
// On ER, return error.
481
//
482
// On OK, change to the new configuration. Resynchronize with the host:
483
//  Target waits for host to send S(ync)
484
//     [host will delay at least .1 secs after changing baud rate so the
485
//      line has time to settle.]
486
//
487
//  When receiving S(ync), target replies OK to the host which then
488
//  acknowledges with D(one).
489
//
490
//  Host can also send R(esync) which means it didn't receieve the OK. If
491
//  so the target resends its S(ync) message.
492
//
493
// If the synchronization has not succeeded within 1 second
494
// (configurable in the protocol), both host and target will revert to
495
// the previous configuration and attempt to synchronize again. If
496
// this fails, this call will hang and the host will consider the test
497
// a failure.
498
//
499
// To Do:
500
//  Host&protocol currently only supports:
501
//   - no/even parity
502
int
503
change_config(cyg_io_handle_t handle, cyg_ser_cfg_t* cfg)
504
{
505
    cyg_serial_info_t old_cfg, new_cfg;
506
    const char cmd[] = "@CONFIG:";
507
    char reply[2];
508
    int msglen;
509
    int res, len;
510
    cyg_uint8 *p1;
511
 
512
    // Prepare the command.
513
    p1 = &cmd_buffer[0];
514
    p1 = strcpy(p1, &cmd[0]);
515
    p1 = itoa(p1, cfg->baud_rate);
516
    *p1++ = ':';
517
    p1 = itoa(p1, cfg->data_bits);
518
    *p1++ = ':';
519
    p1 = itoa(p1, cfg->stop_bits);
520
    *p1++ = ':';
521
    p1 = itoa(p1, cfg->parity);
522
    *p1++ = ':';
523
    p1 = itoa(p1, cfg->flags);
524
    *p1++ = '!';
525
    *p1 = 0;                            // note: we may append to this later
526
 
527
    // Tell user what we're up to.
528
    CYG_TEST_INFO(&cmd_buffer[1]);
529
 
530
    // Change to new config and then back to determine if the driver likes it.
531
    len = sizeof(old_cfg);
532
    res = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_SERIAL_INFO,
533
                            &old_cfg, &len);
534
    res = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_SERIAL_INFO,
535
                            &new_cfg, &len);
536
 
537
    if (res != ENOERR) {
538
        TEST_CRASH(handle, TEST_CRASH_IO_GET_CFG,
539
                   "Can't get serial config", res);
540
    }
541
 
542
    new_cfg.baud = cfg->baud_rate;
543
    new_cfg.word_length = cfg->data_bits;
544
    new_cfg.stop = cfg->stop_bits;
545
    new_cfg.parity = cfg->parity;
546
    new_cfg.flags = cfg->flags;
547
 
548
    res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO,
549
                            &new_cfg, &len);
550
    cyg_thread_delay(10);  // Some chips don't like changes to happen to fast...
551
 
552
    // Driver didn't like it. It will not have changed anything, so it's
553
    // safe to return now.
554
    if (ENOERR != res) {
555
        // Let user know that the config was skipped due to the target.
556
        const char txt_tskipped[] = "- skipped by target!";
557
        p1 = strcpy(p1, txt_tskipped);
558
        *p1 = 0;
559
        CYG_TEST_INFO(&cmd_buffer[1]);
560
        return res;
561
    }
562
 
563
    // Succeeded. Change back to the original config so we can communicate
564
    // with the host.
565
    res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO,
566
                            &old_cfg, &len);
567
    cyg_thread_delay(10); // Some chips don't like changes to happen to fast...
568
 
569
    if (res != ENOERR) {
570
        TEST_CRASH(handle, TEST_CRASH_IO_SET_CFG,
571
                   "Can't set serial config", res);
572
    }
573
 
574
    // Send command to host and read host's reply.
575
    msglen = strlen(&cmd_buffer[0]);
576
    Tcyg_io_write(handle, &cmd_buffer[0], &msglen);
577
    msglen = 2;
578
    Tcyg_io_read(handle, &reply[0], &msglen);
579
 
580
    // Did host accept configuration?
581
    if ('O' != reply[0] || 'K' != reply[1]) {
582
        // Let user know that the config was skipped due to the host.
583
        const char txt_hskipped[] = "- skipped by host!";
584
        p1 = strcpy(p1, txt_hskipped);
585
        *p1 = 0;
586
        CYG_TEST_INFO(&cmd_buffer[1]);
587
        diag_printf("Host didn't accept config (%02x, %02x).\n",
588
                    reply[0], reply[1]);
589
 
590
        res = ENOSUPP;
591
        return res;
592
    }
593
 
594
    // Now change config and wait for host to send us a S(ync)
595
    // character.
596
    // Loop until protocol exchange completed. This may hang (as seen
597
    // from the host), but only when we get totally lost, in which
598
    // case there's not much else to do really. In this case the host
599
    // will consider the test a FAIL.
600
    len = sizeof(new_cfg);
601
    res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO,
602
                            &new_cfg, &len);
603
    cyg_thread_delay(10);  // Some chips don't like changes to happen to fast...
604
    if (res != ENOERR) {
605
        TEST_CRASH(handle, TEST_CRASH_IO_SET_CFG,
606
                   "Can't set serial config/2", res);
607
    }
608
 
609
    {
610
        int change_succeeded = 0;
611
        int using_old_config = 0;
612
        char in_buf[1];
613
        int len;
614
        int saw_host_sync;
615
 
616
        for (;;) {
617
            aborted = 0;                    // global abort flag
618
 
619
            // FIXME: Timeout time needs to be configurable, and needs to
620
            // be sent to the host before getting here. That would allow
621
            // changing the timeout by just rebuilding the test - without
622
            // changing the host software.
623
            saw_host_sync = 0;
624
            r_stamp = timeout(100, do_abort, handle);
625
            while(!aborted) {
626
                len = 1;
627
                in_buf[0] = 0;
628
                res = cyg_io_read(handle, in_buf, &len);
629
                if (ENOERR != res && -EINTR != res) {
630
                    // We may have to reset the driver here if the fail
631
                    // was due to a framing or parity error.
632
                    break;
633
                }
634
                if ('R' == in_buf[0]) {
635
                    // Resync - host didn't see our message. Try again.
636
                    saw_host_sync = 0;
637
                } else if ('S' == in_buf[0] && !saw_host_sync) {
638
                    // In sync - reply to host if we haven't already
639
                    char ok_msg[2] = "OK";
640
                    int ok_len = 2;
641
                    Tcyg_io_write(handle, ok_msg, &ok_len);
642
                    saw_host_sync = 1;
643
                } else if ('D' == in_buf[0] && saw_host_sync) {
644
                    // Done - exchange completed.
645
                    change_succeeded = 1;
646
                    break;
647
                }
648
            }
649
            untimeout(r_stamp);
650
 
651
            if (change_succeeded) {
652
                // If we had to revert to the old configuration, return error.
653
                if (using_old_config)
654
                    return -EIO;
655
                else
656
                    return ENOERR;
657
            }
658
 
659
            // We didn't synchronize with the host. Due to an IO error?
660
            if (ENOERR != res && -EINTR != res) {
661
                // We may have to reset the driver if the fail was due to
662
                // a framing or parity error.
663
            }
664
 
665
            // Revert to the old configuration and try again.
666
            len = sizeof(old_cfg);
667
            res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO,
668
                                    &old_cfg, &len);
669
            cyg_thread_delay(10);  // Some chips don't like changes to happen to fast...
670
            if (res != ENOERR) {
671
                TEST_CRASH(handle, TEST_CRASH_IO_SET_CFG,
672
                           "Can't set serial config/3", res);
673
            }
674
            using_old_config = 1;
675
        }
676
 
677
    }
678
}
679
 
680
 
681
//-----------------------------------------------------------------------------
682
// Host sends CRC in decimal ASCII, terminated with !
683
int
684
read_host_crc(cyg_io_handle_t handle)
685
{
686
    int crc, len;
687
    cyg_uint8 ch;
688
 
689
    crc = 0;
690
    while (1) {
691
        len = 1;
692
        Tcyg_io_read(handle, &ch, &len);
693
        if ('!' == ch)
694
            break;
695
 
696
        if (!((ch >= '0' && ch <= '9'))){
697
            TEST_CRASH(handle, TEST_CRASH_CRC_CHAR,
698
                       "Illegal CRC format from host", ch);
699
        }
700
 
701
        crc = crc*10 + (ch - '0');
702
    }
703
 
704
    return crc;
705
}
706
 
707
//---------------------------------------------------------------------------
708
// Test binary data transmission.
709
// Format out:
710
//  "@BINARY::!"
711
// Format in:
712
//  !<#size bytes data>
713
// For echo modes, also:
714
//     Format out:
715
//      <#size bytes data>
716
//     Format in:
717
//      OK/ER
718
// Format out:
719
//  DONE
720
//
721
//  The last DONE allows the host to eat bytes if target is sending too many.
722
//
723
// Mode:
724
//   MODE_NO_ECHO:
725
//       Just receive data and verify CRC.
726
//   MODE_EOP_ECHO:
727
//       Receive data, verify CRC, resend data.
728
//       Expect OK/ER reply from host when done.
729
//   MODE_DUPLEX_ECHO:
730
//       Receive data, echo data, verify CRC.
731
//       Expect OK/ER reply from host when done.
732
//
733
// Note:
734
//   Using diag_printf while talking with the host may cause some funky
735
//   errors (bytes from the host side being lost!?!?)
736
//
737
// To Do:
738
//   MODE_DUPLEX_ECHO:
739
//     The current implementation is simple and may not stress the
740
//     driver enough. Also, it's command packet format doesn't match
741
//     that of the other modes.
742
 
743
cyg_test_return_t
744
test_binary(cyg_io_handle_t handle, int size, cyg_mode_t mode)
745
{
746
    const char cmd[] = "@BINARY:";
747
    int msglen;
748
    cyg_uint32 xcrc;
749
    int icrc, host_crc;
750
    cyg_uint8 *p1;
751
    cyg_int8 host_status = 'O';         // host is happy by default
752
 
753
    // Verify that the test can be run with available ressources.
754
    if (MODE_EOP_ECHO == mode && size > IN_BUFFER_SIZE)
755
        return TEST_RETURN_NA;
756
 
757
    // Prepare and send the command.
758
    p1 = &cmd_buffer[0];
759
    p1 = strcpy(p1, &cmd[0]);
760
    p1 = itoa(p1, size);
761
    *p1++ = ':';
762
    p1 = itoa(p1, mode);
763
    *p1++ = '!';
764
    *p1++ = 0;
765
 
766
    CYG_TEST_INFO(&cmd_buffer[1]);
767
 
768
    msglen = strlen(&cmd_buffer[0]);
769
    Tcyg_io_write(handle, &cmd_buffer[0], &msglen);
770
 
771
    // Get CRC back.
772
    host_crc = read_host_crc(handle);
773
 
774
    // Depending on mode, start reading data.
775
    xcrc = 0;
776
    switch (mode) {
777
    case MODE_NO_ECHO:
778
    {
779
        // Break transfers into chunks no larger than the buffer size.
780
        int tx_len, chunk_len, i;
781
        while (size > 0) {
782
            chunk_len = min(IN_BUFFER_SIZE, size);
783
            tx_len = chunk_len;
784
            size -= chunk_len;
785
 
786
            Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
787
 
788
            for (i = 0; i < tx_len; i++) {
789
                ADD_CRC_BYTE(xcrc, in_buffer[i]);
790
            }
791
        }
792
 
793
        // Reply that we have completed the test.
794
        {
795
            const char msg_done[] = "DONE";
796
 
797
            chunk_len = strlen(&msg_done[0]);
798
            Tcyg_io_write(handle, &msg_done[0], &chunk_len);
799
        }
800
 
801
    }
802
    break;
803
    case MODE_EOP_ECHO:
804
    {
805
        // We have already checked that the in buffer is large enough.
806
        int i, tx_len, chunk_len;
807
        chunk_len = tx_len = size;
808
        Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
809
 
810
        for (i = 0; i < tx_len; i++) {
811
            ADD_CRC_BYTE(xcrc, in_buffer[i]);
812
        }
813
 
814
        // Echo data back.
815
        chunk_len = size;
816
        Tcyg_io_write(handle, &in_buffer[0], &chunk_len);
817
 
818
        // Now read host side's status
819
        chunk_len = 2;
820
        Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
821
        host_status = in_buffer[0];
822
 
823
        // Reply that we have completed the test.
824
        {
825
            const char msg_done[] = "DONE";
826
 
827
            chunk_len = strlen(&msg_done[0]);
828
            Tcyg_io_write(handle, &msg_done[0], &chunk_len);
829
        }
830
    }
831
    break;
832
    case MODE_DUPLEX_ECHO:
833
    {
834
        int chunk_len;
835
        int block_size = 64;
836
 
837
        // This is a simple implementation (maybe too simple).
838
        // Host sends 4 packets with the same size (64 bytes atm).
839
        // Target echoes in this way:
840
        //  packet1 -> packet1
841
        //  packet2 -> packet2, packet2
842
        //  packet3 -> packet3
843
        //  packet4 -> /dev/null
844
        //
845
        // The reads/writes are interleaved in a way that should ensure
846
        // the target out buffer to be full before the target starts to read
847
        // packet3. That is, the target should be both receiving (packet3)
848
        // and sending (packet2) at the same time.
849
 
850
        while (size--) {
851
            // block_size -> block_size
852
            chunk_len = block_size;
853
            Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
854
            chunk_len = block_size;
855
            Tcyg_io_write(handle, &in_buffer[0], &chunk_len);
856
 
857
            // block_size -> 2 x block_size
858
            chunk_len = block_size;
859
            Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
860
            chunk_len = block_size;
861
            Tcyg_io_write(handle, &in_buffer[0], &chunk_len);
862
            chunk_len = block_size;
863
            Tcyg_io_write(handle, &in_buffer[0], &chunk_len);
864
 
865
            // block_size -> block_size
866
            chunk_len = block_size;
867
            Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
868
            chunk_len = block_size;
869
            Tcyg_io_write(handle, &in_buffer[0], &chunk_len);
870
 
871
            // block_size -> 0
872
            chunk_len = block_size;
873
            Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
874
        }
875
 
876
        // Kill the CRC. Leave packet verification to the host for now.
877
        xcrc = host_crc = 0;
878
 
879
        // Now read host side's status
880
        chunk_len = 2;
881
        Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
882
        host_status = in_buffer[0];
883
 
884
        // Reply that we have completed the test.
885
        {
886
            const char msg_done[] = "DONE";
887
 
888
            chunk_len = strlen(&msg_done[0]);
889
            Tcyg_io_write(handle, &msg_done[0], &chunk_len);
890
        }
891
    }
892
    break;
893
    default:
894
        TEST_CRASH(handle, TEST_CRASH_PROT_BIN_MODE,
895
                   "Unknown mode", mode);
896
        break;
897
    }
898
 
899
 
900
    // Verify that the CRC matches the one from the host.
901
    FIX_CRC(xcrc, icrc);
902
    if (host_crc != icrc) {
903
        TEST_CRASH(handle, TEST_CRASH_CRC_BAD,
904
                   "Input CRC failed", icrc, host_crc);
905
    }
906
 
907
    // Verify that the host is happy with the data we echoed.
908
    if ('O' != host_status) {
909
        TEST_CRASH(handle, TEST_CRASH_CRC_HOST,
910
                   "Output CRC failed");
911
    }
912
 
913
    CYG_TEST_PASS("Binary test completed");
914
    return TEST_RETURN_OK;
915
}
916
 
917
//---------------------------------------------------------------------------
918
// Test transformations on text transmissions
919
// Format out:
920
//  "@TEXT:!<4 bytes binary checksum>"
921
// Format in:
922
//  ""
923
//  OK/ER
924
//
925
// Mode:
926
//   MODE_EOP_ECHO:
927
//       Receive data, verify CRC, resend data.
928
//       Expect OK/ER reply from host when done.
929
//   MODE_DUPLEX_ECHO:
930
//       Receive data, echo data, verify CRC.
931
//       Expect OK/ER reply from host when done.
932
//
933
cyg_test_return_t
934
test_text(cyg_io_handle_t handle, cyg_mode_t mode, const char* s_base,
935
           const char* s_out, const char* s_in)
936
{
937
    return TEST_RETURN_NA;
938
}
939
 
940
//---------------------------------------------------------------------------
941
// Send PING to host, verifying the filter's presence.
942
// Format out:
943
//  "@PING:!"
944
// Format in:
945
//  "OK"
946
// or
947
//  No response if directly connected to GDB.
948
//
949
// This call only returns if the ser_filter is listening. Otherwise it
950
// sends N/A and hangs.
951
void
952
test_ping(cyg_io_handle_t handle)
953
{
954
    char msg[] = "@PING:" TEST_CRASH_ID "!";
955
    char msg2[] = "\n";
956
    int msglen = strlen(msg);
957
    int res;
958
 
959
    msglen = strlen(msg);
960
    Tcyg_io_write(handle, msg, &msglen);
961
 
962
    // Now read host side's status
963
    msglen = 2;
964
    Tcyg_io_read_timeout(handle, &in_buffer[0], &msglen, 100, &res);
965
    if (ENOERR == res && 'O' == in_buffer[0] && 'K' == in_buffer[1])
966
        return;
967
 
968
    msglen = strlen(msg2);
969
    Tcyg_io_write(handle, msg2, &msglen);
970
 
971
    CYG_TEST_NA("No host side testing harness detected.");
972
}
973
 
974
 
975
//---------------------------------------------------------------------------
976
// Send OPT to host, setting options in the filter.
977
// Format out:
978
//  "@OPT:option1,value1:...:optionN,valueN!"
979
// Format in:
980
//  "OK"
981
//
982
// Only integer values can be used. Any option not recognized by the
983
// filter will be silently ignored.
984
void
985
test_options(cyg_io_handle_t handle, int count, cyg_uint32* options)
986
{
987
    const char cmd[] = "@OPT:";
988
    int msglen;
989
    cyg_uint8 *p1;
990
 
991
    // Prepare and send the command.
992
    p1 = &cmd_buffer[0];
993
    p1 = strcpy(p1, &cmd[0]);
994
    while(count--) {
995
        p1 = itoa(p1, *options++);      // option
996
        *p1++ = ':';
997
        p1 = itoa(p1, *options++);      // value
998
        *p1++ = ':';
999
    }
1000
    *(p1-1) = '!';
1001
    *p1++ = 0;
1002
 
1003
    CYG_TEST_INFO(&cmd_buffer[1]);
1004
 
1005
    msglen = strlen(&cmd_buffer[0]);
1006
    Tcyg_io_write(handle, &cmd_buffer[0], &msglen);
1007
 
1008
    // Now read host side's status
1009
    msglen = 2;
1010
    Tcyg_io_read(handle, &in_buffer[0], &msglen);
1011
}
1012
 
1013
 
1014
//---------------------------------------------------------------------------
1015
// Some helper functions to get a test started.
1016
void
1017
test_open_ser( cyg_io_handle_t* handle )
1018
{
1019
#if defined(CYGPKG_IO_SERIAL_DEVICES) && !defined(SER_NOP_TEST)
1020
    Cyg_ErrNo res;
1021
 
1022
    if (cyg_test_is_simulator)
1023
        CYG_TEST_NA("Cannot run from simulator");
1024
 
1025
#if defined(HAL_VSR_SET_TO_ECOS_HANDLER)
1026
# if defined(CYGPRI_SER_TEST_OVERRIDE_INT_1)
1027
    HAL_VSR_SET_TO_ECOS_HANDLER(CYGPRI_SER_TEST_OVERRIDE_INT_1, NULL);
1028
# endif
1029
# if defined(CYGPRI_SER_TEST_OVERRIDE_INT_2)
1030
    HAL_VSR_SET_TO_ECOS_HANDLER(CYGPRI_SER_TEST_OVERRIDE_INT_2, NULL);
1031
# endif
1032
#endif
1033
 
1034
    res = cyg_io_lookup(TEST_SER_DEV, handle);
1035
    if (res != ENOERR) {
1036
        CYG_TEST_FAIL_FINISH("Can't lookup " TEST_SER_DEV);
1037
    }
1038
#else
1039
    CYG_TEST_NA(NA_MSG);
1040
#endif
1041
}
1042
 
1043
void
1044
test_open_tty( cyg_io_handle_t* handle )
1045
{
1046
#if defined(CYGPKG_IO_SERIAL_TTY) && !defined(TTY_NOP_TEST)
1047
    Cyg_ErrNo res;
1048
 
1049
    if (cyg_test_is_simulator)
1050
        CYG_TEST_NA("Cannot run from simulator");
1051
 
1052
#if defined(HAL_VSR_SET_TO_ECOS_HANDLER)
1053
# if defined(CYGPRI_SER_TEST_OVERRIDE_INT_1)
1054
    HAL_VSR_SET_TO_ECOS_HANDLER(CYGPRI_SER_TEST_OVERRIDE_INT_1, NULL);
1055
# endif
1056
# if defined(CYGPRI_SER_TEST_OVERRIDE_INT_2)
1057
    HAL_VSR_SET_TO_ECOS_HANDLER(CYGPRI_SER_TEST_OVERRIDE_INT_2, NULL);
1058
# endif
1059
#endif
1060
 
1061
    res = cyg_io_lookup(TEST_TTY_DEV, handle);
1062
    if (res != ENOERR) {
1063
        CYG_TEST_FAIL_FINISH("Can't lookup " TEST_TTY_DEV);
1064
    }
1065
#else
1066
    CYG_TEST_NA(NA_MSG);
1067
#endif
1068
}
1069
 
1070
//---------------------------------------------------------------------------
1071
// end of ser_test_protocol.inl

powered by: WebSVN 2.1.0

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