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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [io/] [serial/] [current/] [tests/] [ser_test_protocol.inl] - Blame information for rev 786

Details | Compare with Previous | View Log

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