1 //==========================================================================
5 // Serial device driver testing protocol
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.
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.
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
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.
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.
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.
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####
44 // Contributors: jskov, gthomas
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.
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.
56 //####DESCRIPTIONEND####
58 #include <pkgconf/system.h>
59 #include <pkgconf/io.h>
60 #include <pkgconf/io_serial.h>
62 #include <cyg/io/io.h>
63 #include <cyg/io/devtab.h>
64 #include <cyg/io/ttyio.h>
65 #include <cyg/infra/diag.h>
66 #include <cyg/infra/cyg_ass.h>
68 #include <cyg/hal/hal_intr.h> // for reclaiming interrupt vector
70 //----------------------------------------------------------------------------
71 // Definition of which device to run tests on on various platforms.
73 #define NA_MSG "No test device specified"
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
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.
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
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
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
117 // We can't rely on haldiag for ser_filter detection - it may not define
118 // a working character reading function.
120 # define SER_NOP_TEST
121 # define TTY_NOP_TEST
122 # define TEST_SER_DEV "/dev/null"
123 # define TEST_TTY_DEV "/dev/null"
125 # ifndef TEST_TTY_DEV
126 # define TTY_NOP_TEST
127 # define TEST_TTY_DEV "/dev/null"
131 #ifndef TEST_CRASH_ID
132 #define TEST_CRASH_ID "......"
135 //----------------------------------------------------------------------------
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...
141 // FAILCODE:<tttttt:cccc:[optional data, separated by :]!>
142 // tttttt: 6 letter target code
143 // cccc: crash code (16bit hex value)
145 #define TEST_CRASH(__h, __code, __msg, args...) \
147 cyg_uint32 __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, \
152 diag_printf("FAILCODE:<" TEST_CRASH_ID ":%04x:" __code, ## args); \
153 diag_printf("!>\n"); \
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
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
173 #define TEST_CRASH_PROT 0x1000
174 #define TEST_CRASH_PROT_BIN_MODE "%d", 0x1080
175 #define TEST_CRASH_PROT_TEXT "%d", 0x1100
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
185 //----------------------------------------------------------------------------
186 // The data in buffer and the cmd buffer
187 #ifndef IN_BUFFER_SIZE
188 # define IN_BUFFER_SIZE 1024
190 cyg_uint8 in_buffer[IN_BUFFER_SIZE];
192 char cmd_buffer[128];
194 //----------------------------------------------------------------------------
195 // Some types specific to the testing protocol.
203 TEST_RETURN_OK = ENOERR,
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;
217 OPT_SERIAL_DEBUG = 0,
225 } cyg_verbosity_level_t;
228 // A few predifined option macros. Use after test_ping().
229 #define TEST_OPTIONS(__handle, __array) \
230 test_options(__handle, sizeof(__array)/8, __array)
232 #define TEST_HOST_DEBUG(__handle) \
234 cyg_uint32 __options[] = {OPT_SERIAL_DEBUG, 1}; \
235 test_options((__handle), sizeof(__options)/8, \
239 #define TEST_HOST_PROGRESS(__handle) \
241 cyg_uint32 __options[] = \
242 {OPT_SERIAL_DEBUG, 1, \
243 OPT_VERBOSE_LEVEL, PROTOCOL_PROGRESS}; \
244 test_options((__handle), sizeof(__options)/8, \
248 #define TEST_HOST_DATA(__handle) \
250 cyg_uint32 __options[] = \
251 {OPT_SERIAL_DEBUG, 1, \
252 OPT_VERBOSE_LEVEL, PROTOCOL_DATA}; \
253 test_options((__handle), sizeof(__options)/8, \
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 },
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 },
276 { CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8,
277 CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
278 CYGNUM_SERIAL_FLOW_NONE },
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 },
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 },
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 },
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 },
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 },
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 },
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 :)
330 #define INIT_VALUE(__args) \
332 char *__ptr1, *__ptr2 = (__args)
334 #define SET_VALUE(__slot) \
336 __ptr1 = index(__ptr2, (int) ':'); \
345 //----------------------------------------------------------------------------
346 // CRC magic - it's a bit of a hack for now.
347 // FIXME: standard definition?
348 #define ADD_CRC_BYTE(__crc, __c) \
350 (__crc) = ((__crc) << 1) ^ (__c); \
353 // FIXME: Hack to allow easy ASCII transfer.
354 #define FIX_CRC(__crc, __icrc) \
356 __icrc = (int) (__crc); \
361 //----------------------------------------------------------------------------
362 // Macros for read/write to serial with error cheking.
363 static volatile cyg_uint32 r_stamp;
364 static volatile int aborted;
366 // This routine will be called if the read "times out"
368 do_abort(void *handle)
370 cyg_io_handle_t io_handle = (cyg_io_handle_t)handle;
371 cyg_uint32 len = 1; // Need something here
372 cyg_io_get_config(io_handle, CYG_IO_GET_CONFIG_SERIAL_ABORT, 0, &len);
375 #include "timeout.inl"
377 // Read with timeout (__t = timeout in ticks, int* __r = result)
378 #define Tcyg_io_read_timeout(__h, __d, __l, __t, __r) \
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); \
388 untimeout(r_stamp); \
391 #define Tcyg_io_read(__h, __d, __l) \
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); \
400 #define Tcyg_io_write(__h, __d, __l) \
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); \
409 __res = cyg_io_get_config((__h), \
410 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN, \
412 if (ENOERR != __res) { \
413 TEST_CRASH(__h, TEST_CRASH_IO_DRAIN, \
414 "DRAIN failed", __res); \
419 //----------------------------------------------------------------------------
420 // Some libc like functions that are handy to have around.
422 strlen(const char *c)
430 strcpy(char* dest, const char* src)
433 while ((c = *src++)) {
442 itoa(char* dest, int v)
450 *--p = (v % 10) + '0';
456 return strcpy(dest, p);
459 #define min(_a, _b) ((_a) < (_b)) ? (_a) : (_b)
467 //-----------------------------------------------------------------------------
468 // Configuration changing function.
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.
474 // Then query the host for its capability to use the config:
476 // "@CONFIG:<baud rate code>:<#data bits>:<#stop bits>:<parity on/off>:<flow control code>!"
480 // On ER, return error.
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.]
487 // When receiving S(ync), target replies OK to the host which then
488 // acknowledges with D(one).
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.
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
500 // Host&protocol currently only supports:
503 change_config(cyg_io_handle_t handle, cyg_ser_cfg_t* cfg)
505 cyg_serial_info_t old_cfg, new_cfg;
506 const char cmd[] = "@CONFIG:";
513 // Prepare the command.
515 p1 = strcpy(p1, &cmd[0]);
516 p1 = itoa(p1, cfg->baud_rate);
518 p1 = itoa(p1, cfg->data_bits);
520 p1 = itoa(p1, cfg->stop_bits);
522 p1 = itoa(p1, cfg->parity);
524 p1 = itoa(p1, cfg->flags);
526 *p1 = 0; // note: we may append to this later
528 // Tell user what we're up to.
529 CYG_TEST_INFO((char *)&cmd_buffer[1]);
531 // Change to new config and then back to determine if the driver likes it.
532 len = sizeof(old_cfg);
533 res = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_SERIAL_INFO,
535 res = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_SERIAL_INFO,
539 TEST_CRASH(handle, TEST_CRASH_IO_GET_CFG,
540 "Can't get serial config", res);
543 new_cfg.baud = cfg->baud_rate;
544 new_cfg.word_length = cfg->data_bits;
545 new_cfg.stop = cfg->stop_bits;
546 new_cfg.parity = cfg->parity;
547 new_cfg.flags = cfg->flags;
549 res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO,
551 cyg_thread_delay(10); // Some chips don't like changes to happen to fast...
553 // Driver didn't like it. It will not have changed anything, so it's
554 // safe to return now.
556 // Let user know that the config was skipped due to the target.
557 const char txt_tskipped[] = "- skipped by target!";
558 p1 = strcpy(p1, txt_tskipped);
560 CYG_TEST_INFO(&cmd_buffer[1]);
564 // Succeeded. Change back to the original config so we can communicate
566 res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO,
568 cyg_thread_delay(10); // Some chips don't like changes to happen to fast...
571 TEST_CRASH(handle, TEST_CRASH_IO_SET_CFG,
572 "Can't set serial config", res);
575 // Send command to host and read host's reply.
576 msglen = strlen(&cmd_buffer[0]);
577 Tcyg_io_write(handle, &cmd_buffer[0], &msglen);
579 Tcyg_io_read(handle, &reply[0], &msglen);
581 // Did host accept configuration?
582 if ('O' != reply[0] || 'K' != reply[1]) {
583 // Let user know that the config was skipped due to the host.
584 const char txt_hskipped[] = "- skipped by host!";
585 p1 = strcpy(p1, txt_hskipped);
587 CYG_TEST_INFO(&cmd_buffer[1]);
588 diag_printf("Host didn't accept config (%02x, %02x).\n",
595 // Now change config and wait for host to send us a S(ync)
597 // Loop until protocol exchange completed. This may hang (as seen
598 // from the host), but only when we get totally lost, in which
599 // case there's not much else to do really. In this case the host
600 // will consider the test a FAIL.
601 len = sizeof(new_cfg);
602 res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO,
604 cyg_thread_delay(10); // Some chips don't like changes to happen to fast...
606 TEST_CRASH(handle, TEST_CRASH_IO_SET_CFG,
607 "Can't set serial config/2", res);
611 int change_succeeded = 0;
612 int using_old_config = 0;
618 aborted = 0; // global abort flag
620 // FIXME: Timeout time needs to be configurable, and needs to
621 // be sent to the host before getting here. That would allow
622 // changing the timeout by just rebuilding the test - without
623 // changing the host software.
625 r_stamp = timeout(100, do_abort, handle);
629 res = cyg_io_read(handle, in_buf, &len);
630 if (ENOERR != res && -EINTR != res) {
631 // We may have to reset the driver here if the fail
632 // was due to a framing or parity error.
635 if ('R' == in_buf[0]) {
636 // Resync - host didn't see our message. Try again.
638 } else if ('S' == in_buf[0] && !saw_host_sync) {
639 // In sync - reply to host if we haven't already
640 char ok_msg[2] = "OK";
641 cyg_uint32 ok_len = 2;
642 Tcyg_io_write(handle, ok_msg, &ok_len);
644 } else if ('D' == in_buf[0] && saw_host_sync) {
645 // Done - exchange completed.
646 change_succeeded = 1;
652 if (change_succeeded) {
653 // If we had to revert to the old configuration, return error.
654 if (using_old_config)
660 // We didn't synchronize with the host. Due to an IO error?
661 if (ENOERR != res && -EINTR != res) {
662 // We may have to reset the driver if the fail was due to
663 // a framing or parity error.
666 // Revert to the old configuration and try again.
667 len = sizeof(old_cfg);
668 res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO,
670 cyg_thread_delay(10); // Some chips don't like changes to happen to fast...
672 TEST_CRASH(handle, TEST_CRASH_IO_SET_CFG,
673 "Can't set serial config/3", res);
675 using_old_config = 1;
682 //-----------------------------------------------------------------------------
683 // Host sends CRC in decimal ASCII, terminated with !
685 read_host_crc(cyg_io_handle_t handle)
694 Tcyg_io_read(handle, &ch, &len);
698 if (!((ch >= '0' && ch <= '9'))){
699 TEST_CRASH(handle, TEST_CRASH_CRC_CHAR,
700 "Illegal CRC format from host", ch);
703 crc = crc*10 + (ch - '0');
709 //---------------------------------------------------------------------------
710 // Test binary data transmission.
712 // "@BINARY:<byte size>:<mode>!"
714 // <checksum>!<#size bytes data>
715 // For echo modes, also:
717 // <#size bytes data>
723 // The last DONE allows the host to eat bytes if target is sending too many.
727 // Just receive data and verify CRC.
729 // Receive data, verify CRC, resend data.
730 // Expect OK/ER reply from host when done.
732 // Receive data, echo data, verify CRC.
733 // Expect OK/ER reply from host when done.
736 // Using diag_printf while talking with the host may cause some funky
737 // errors (bytes from the host side being lost!?!?)
741 // The current implementation is simple and may not stress the
742 // driver enough. Also, it's command packet format doesn't match
743 // that of the other modes.
746 test_binary(cyg_io_handle_t handle, int size, cyg_mode_t mode)
748 const char cmd[] = "@BINARY:";
753 cyg_int8 host_status = 'O'; // host is happy by default
755 // Verify that the test can be run with available ressources.
756 if (MODE_EOP_ECHO == mode && size > IN_BUFFER_SIZE)
757 return TEST_RETURN_NA;
759 // Prepare and send the command.
761 p1 = strcpy(p1, &cmd[0]);
768 CYG_TEST_INFO(&cmd_buffer[1]);
770 msglen = strlen(&cmd_buffer[0]);
771 Tcyg_io_write(handle, &cmd_buffer[0], &msglen);
774 host_crc = read_host_crc(handle);
776 // Depending on mode, start reading data.
781 // Break transfers into chunks no larger than the buffer size.
783 cyg_uint32 chunk_len;
785 chunk_len = min(IN_BUFFER_SIZE, size);
789 Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
791 for (i = 0; i < tx_len; i++) {
792 ADD_CRC_BYTE(xcrc, in_buffer[i]);
796 // Reply that we have completed the test.
798 const char msg_done[] = "DONE";
800 chunk_len = strlen(&msg_done[0]);
801 Tcyg_io_write(handle, &msg_done[0], &chunk_len);
808 // We have already checked that the in buffer is large enough.
810 cyg_uint32 chunk_len;
811 chunk_len = tx_len = size;
812 Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
814 for (i = 0; i < tx_len; i++) {
815 ADD_CRC_BYTE(xcrc, in_buffer[i]);
820 Tcyg_io_write(handle, &in_buffer[0], &chunk_len);
822 // Now read host side's status
824 Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
825 host_status = in_buffer[0];
827 // Reply that we have completed the test.
829 const char msg_done[] = "DONE";
831 chunk_len = strlen(&msg_done[0]);
832 Tcyg_io_write(handle, &msg_done[0], &chunk_len);
836 case MODE_DUPLEX_ECHO:
838 cyg_uint32 chunk_len;
841 // This is a simple implementation (maybe too simple).
842 // Host sends 4 packets with the same size (64 bytes atm).
843 // Target echoes in this way:
844 // packet1 -> packet1
845 // packet2 -> packet2, packet2
846 // packet3 -> packet3
847 // packet4 -> /dev/null
849 // The reads/writes are interleaved in a way that should ensure
850 // the target out buffer to be full before the target starts to read
851 // packet3. That is, the target should be both receiving (packet3)
852 // and sending (packet2) at the same time.
855 // block_size -> block_size
856 chunk_len = block_size;
857 Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
858 chunk_len = block_size;
859 Tcyg_io_write(handle, &in_buffer[0], &chunk_len);
861 // block_size -> 2 x block_size
862 chunk_len = block_size;
863 Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
864 chunk_len = block_size;
865 Tcyg_io_write(handle, &in_buffer[0], &chunk_len);
866 chunk_len = block_size;
867 Tcyg_io_write(handle, &in_buffer[0], &chunk_len);
869 // block_size -> 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);
876 chunk_len = block_size;
877 Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
880 // Kill the CRC. Leave packet verification to the host for now.
883 // Now read host side's status
885 Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
886 host_status = in_buffer[0];
888 // Reply that we have completed the test.
890 const char msg_done[] = "DONE";
892 chunk_len = strlen(&msg_done[0]);
893 Tcyg_io_write(handle, &msg_done[0], &chunk_len);
898 TEST_CRASH(handle, TEST_CRASH_PROT_BIN_MODE,
899 "Unknown mode", mode);
904 // Verify that the CRC matches the one from the host.
906 if (host_crc != icrc) {
907 TEST_CRASH(handle, TEST_CRASH_CRC_BAD,
908 "Input CRC failed", icrc, host_crc);
911 // Verify that the host is happy with the data we echoed.
912 if ('O' != host_status) {
913 TEST_CRASH(handle, TEST_CRASH_CRC_HOST,
914 "Output CRC failed");
917 CYG_TEST_PASS("Binary test completed");
918 return TEST_RETURN_OK;
921 //---------------------------------------------------------------------------
922 // Test transformations on text transmissions
924 // "@TEXT:<mode>!<4 bytes binary checksum><C string>"
931 // Receive data, verify CRC, resend data.
932 // Expect OK/ER reply from host when done.
934 // Receive data, echo data, verify CRC.
935 // Expect OK/ER reply from host when done.
938 test_text(cyg_io_handle_t handle, cyg_mode_t mode, const char* s_base,
939 const char* s_out, const char* s_in)
941 return TEST_RETURN_NA;
944 //---------------------------------------------------------------------------
945 // Send PING to host, verifying the filter's presence.
947 // "@PING:<crash id>!"
951 // No response if directly connected to GDB.
953 // This call only returns if the ser_filter is listening. Otherwise it
954 // sends N/A and hangs.
956 test_ping(cyg_io_handle_t handle)
958 char msg[] = "@PING:" TEST_CRASH_ID "!";
960 cyg_uint32 msglen = strlen(msg);
963 msglen = strlen(msg);
964 Tcyg_io_write(handle, msg, &msglen);
966 // Now read host side's status
968 Tcyg_io_read_timeout(handle, &in_buffer[0], &msglen, 100, &res);
969 if (ENOERR == res && 'O' == in_buffer[0] && 'K' == in_buffer[1])
972 msglen = strlen(msg2);
973 Tcyg_io_write(handle, msg2, &msglen);
975 CYG_TEST_NA("No host side testing harness detected.");
979 //---------------------------------------------------------------------------
980 // Send OPT to host, setting options in the filter.
982 // "@OPT:option1,value1:...:optionN,valueN!"
986 // Only integer values can be used. Any option not recognized by the
987 // filter will be silently ignored.
989 test_options(cyg_io_handle_t handle, int count, cyg_uint32* options)
991 const char cmd[] = "@OPT:";
995 // Prepare and send the command.
997 p1 = strcpy(p1, &cmd[0]);
999 p1 = itoa(p1, *options++); // option
1001 p1 = itoa(p1, *options++); // value
1007 CYG_TEST_INFO(&cmd_buffer[1]);
1009 msglen = strlen(&cmd_buffer[0]);
1010 Tcyg_io_write(handle, &cmd_buffer[0], &msglen);
1012 // Now read host side's status
1014 Tcyg_io_read(handle, &in_buffer[0], &msglen);
1018 //---------------------------------------------------------------------------
1019 // Some helper functions to get a test started.
1021 test_open_ser( cyg_io_handle_t* handle )
1023 #if defined(CYGPKG_IO_SERIAL_DEVICES) && !defined(SER_NOP_TEST)
1026 if (cyg_test_is_simulator)
1027 CYG_TEST_NA("Cannot run from simulator");
1029 #if defined(HAL_VSR_SET_TO_ECOS_HANDLER)
1030 # if defined(CYGPRI_SER_TEST_OVERRIDE_INT_1)
1031 HAL_VSR_SET_TO_ECOS_HANDLER(CYGPRI_SER_TEST_OVERRIDE_INT_1, NULL);
1033 # if defined(CYGPRI_SER_TEST_OVERRIDE_INT_2)
1034 HAL_VSR_SET_TO_ECOS_HANDLER(CYGPRI_SER_TEST_OVERRIDE_INT_2, NULL);
1038 res = cyg_io_lookup(TEST_SER_DEV, handle);
1039 if (res != ENOERR) {
1040 CYG_TEST_FAIL_FINISH("Can't lookup " TEST_SER_DEV);
1043 CYG_TEST_NA(NA_MSG);
1048 test_open_tty( cyg_io_handle_t* handle )
1050 #if defined(CYGPKG_IO_SERIAL_TTY) && !defined(TTY_NOP_TEST)
1053 if (cyg_test_is_simulator)
1054 CYG_TEST_NA("Cannot run from simulator");
1056 #if defined(HAL_VSR_SET_TO_ECOS_HANDLER)
1057 # if defined(CYGPRI_SER_TEST_OVERRIDE_INT_1)
1058 HAL_VSR_SET_TO_ECOS_HANDLER(CYGPRI_SER_TEST_OVERRIDE_INT_1, NULL);
1060 # if defined(CYGPRI_SER_TEST_OVERRIDE_INT_2)
1061 HAL_VSR_SET_TO_ECOS_HANDLER(CYGPRI_SER_TEST_OVERRIDE_INT_2, NULL);
1065 res = cyg_io_lookup(TEST_TTY_DEV, handle);
1066 if (res != ENOERR) {
1067 CYG_TEST_FAIL_FINISH("Can't lookup " TEST_TTY_DEV);
1070 CYG_TEST_NA(NA_MSG);
1074 //---------------------------------------------------------------------------
1075 // end of ser_test_protocol.inl