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

Subversion Repositories openrisc_me

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/trunk/rtos/ecos-2.0/packages/io/serial/v2_0
    from Rev 27 to Rev 174
    Reverse comparison

Rev 27 → Rev 174

/cdl/tty.cdl
0,0 → 1,130
# ====================================================================
#
# tty.cdl
#
# eCos serial TTY configuration data
#
# ====================================================================
#####ECOSGPLCOPYRIGHTBEGIN####
## -------------------------------------------
## This file is part of eCos, the Embedded Configurable Operating System.
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
##
## eCos is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free
## Software Foundation; either version 2 or (at your option) any later version.
##
## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
## WARRANTY; without even the implied warranty of MERCHANTABILITY or
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
## for more details.
##
## You should have received a copy of the GNU General Public License along
## with eCos; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
##
## As a special exception, if other files instantiate templates or use macros
## or inline functions from this file, or you compile this file and link it
## with other works to produce a work based on this file, this file does not
## by itself cause the resulting work to be covered by the GNU General Public
## License. However the source code for this file must still be made available
## in accordance with section (3) of the GNU General Public License.
##
## This exception does not invalidate any other reasons why a work based on
## this file might be covered by the GNU General Public License.
##
## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
## at http://sources.redhat.com/ecos/ecos-license/
## -------------------------------------------
#####ECOSGPLCOPYRIGHTEND####
# ====================================================================
######DESCRIPTIONBEGIN####
#
# Author(s): jskov
# Original data: gthomas
# Contributors:
# Date: 1999-07-07
#
#####DESCRIPTIONEND####
#
# ====================================================================
 
cdl_component CYGPKG_IO_SERIAL_HALDIAG {
display "HAL/diag serial device driver"
flavor bool
default_value 1
description "
This option enables the use of the HAL diagnostic channel
via the standard I/O drivers."
compile -library=libextras.a common/haldiag.c
}
 
cdl_option CYGDAT_IO_SERIAL_TTY_CONSOLE {
display "Console device name"
flavor data
default_value {"\"/dev/ttydiag\""}
description "
This option selects the TTY device to use for the console."
}
 
cdl_component CYGPKG_IO_SERIAL_TTY_TTYDIAG {
display "TTY mode HAL/diag channel"
flavor bool
default_value 1
description "
This option causes '/dev/ttydiag' to be included in the standard
drivers."
}
 
cdl_component CYGPKG_IO_SERIAL_TTY_TTY0 {
display "TTY mode channel #0"
flavor bool
default_value 0
description "
This option causes '/dev/tty0' to be included in the standard
drivers."
 
cdl_option CYGDAT_IO_SERIAL_TTY_TTY0_DEV {
display "TTY mode channel #0 device"
flavor data
default_value { "\"/dev/ser0\"" }
description "
This option selects the physical device to use for
'/dev/tty0'."
}
}
cdl_component CYGPKG_IO_SERIAL_TTY_TTY1 {
display "TTY mode channel #1"
flavor bool
default_value 0
description "
This option causes '/dev/tty1' to be included in the standard
drivers."
 
cdl_option CYGDAT_IO_SERIAL_TTY_TTY1_DEV {
display "TTY mode channel #1 device"
flavor data
default_value {"\"/dev/ser1\""}
description "
This option selects the physical device to use for
'/dev/tty1'."
}
}
 
cdl_component CYGPKG_IO_SERIAL_TTY_TTY2 {
display "TTY mode channel #2"
flavor bool
default_value 0
description "
This option causes '/dev/tty2' to be included in the standard
drivers."
 
cdl_option CYGDAT_IO_SERIAL_TTY_TTY2_DEV {
display "TTY mode channel #2 device"
flavor data
default_value {"\"/dev/ser2\""}
description "
This option selects the physical device to use for
'/dev/tty2'."
}
}
/cdl/termios.cdl
0,0 → 1,132
# ====================================================================
#
# termios.cdl
#
# eCos POSIX termios compatible terminal configuration data
#
# ====================================================================
#####ECOSGPLCOPYRIGHTBEGIN####
## -------------------------------------------
## This file is part of eCos, the Embedded Configurable Operating System.
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
##
## eCos is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free
## Software Foundation; either version 2 or (at your option) any later version.
##
## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
## WARRANTY; without even the implied warranty of MERCHANTABILITY or
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
## for more details.
##
## You should have received a copy of the GNU General Public License along
## with eCos; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
##
## As a special exception, if other files instantiate templates or use macros
## or inline functions from this file, or you compile this file and link it
## with other works to produce a work based on this file, this file does not
## by itself cause the resulting work to be covered by the GNU General Public
## License. However the source code for this file must still be made available
## in accordance with section (3) of the GNU General Public License.
##
## This exception does not invalidate any other reasons why a work based on
## this file might be covered by the GNU General Public License.
##
## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
## at http://sources.redhat.com/ecos/ecos-license/
## -------------------------------------------
#####ECOSGPLCOPYRIGHTEND####
# ====================================================================
######DESCRIPTIONBEGIN####
#
# Author(s): jlarmour, gthomas
# Contributors:
# Date: 2000-07-22
#
#####DESCRIPTIONEND####
#
# ====================================================================
 
cdl_interface CYGINT_IO_SERIAL_TERMIOS_TERMIOS_TTY {
display "Interface for termios tty driver file enabling"
}
 
cdl_option CYGBLD_IO_SERIAL_TERMIOS_TERMIOS_TTY {
display "Build termios tty driver file"
calculated 1
active_if { CYGINT_IO_SERIAL_TERMIOS_TERMIOS_TTY > 0 }
compile -library=libextras.a common/termiostty.c
}
 
 
cdl_component CYGPKG_IO_SERIAL_TERMIOS_TERMIOS0 {
display "Termios TTY channel #0"
flavor bool
default_value 0
implements CYGINT_IO_SERIAL_TERMIOS_TERMIOS_TTY
description "
This option causes '/dev/termios0' to be included in the standard
drivers."
 
cdl_option CYGDAT_IO_SERIAL_TERMIOS_TERMIOS0_DEV {
display "Termios TTY channel #0 device"
flavor data
default_value { "\"/dev/ser0\"" }
description "
This option selects the physical device to use for
'/dev/termios0'."
}
}
cdl_component CYGPKG_IO_SERIAL_TERMIOS_TERMIOS1 {
display "Termios TTY channel #1"
flavor bool
default_value 0
implements CYGINT_IO_SERIAL_TERMIOS_TERMIOS_TTY
description "
This option causes '/dev/termios1' to be included in the standard
drivers."
 
cdl_option CYGDAT_IO_SERIAL_TERMIOS_TERMIOS1_DEV {
display "Termios TTY channel #1 device"
flavor data
default_value {"\"/dev/ser1\""}
description "
This option selects the physical device to use for
'/dev/termios1'."
}
}
 
cdl_component CYGPKG_IO_SERIAL_TERMIOS_TERMIOS2 {
display "Termios TTY channel #2"
flavor bool
default_value 0
implements CYGINT_IO_SERIAL_TERMIOS_TERMIOS_TTY
description "
This option causes '/dev/termios2' to be included in the standard
drivers."
 
cdl_option CYGDAT_IO_SERIAL_TERMIOS_TERMIOS2_DEV {
display "Termios TTY channel #2 device"
flavor data
default_value {"\"/dev/ser2\""}
description "
This option selects the physical device to use for
'/dev/termios2'."
}
}
 
cdl_option CYGSEM_IO_SERIAL_TERMIOS_USE_SIGNALS {
display "Support signals"
flavor bool
requires CYGINT_ISO_SIGNAL_NUMBERS
requires CYGINT_ISO_SIGNAL_IMPL
default_value { CYGINT_ISO_SIGNAL_NUMBERS != 0 && \
CYGINT_ISO_SIGNAL_IMPL != 0 }
description "This option selects whether those parts of the termios
interface involving signals is supported. This includes
BRKINT mode, the INTR and QUIT characters, and whether
SIGHUP is sent on terminal close."
}
 
# EOF termios.cdl
/cdl/io_serial.cdl
0,0 → 1,362
# ====================================================================
#
# io_serial.cdl
#
# eCos IO configuration data
#
# ====================================================================
#####ECOSGPLCOPYRIGHTBEGIN####
## -------------------------------------------
## This file is part of eCos, the Embedded Configurable Operating System.
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
##
## eCos is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free
## Software Foundation; either version 2 or (at your option) any later version.
##
## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
## WARRANTY; without even the implied warranty of MERCHANTABILITY or
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
## for more details.
##
## You should have received a copy of the GNU General Public License along
## with eCos; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
##
## As a special exception, if other files instantiate templates or use macros
## or inline functions from this file, or you compile this file and link it
## with other works to produce a work based on this file, this file does not
## by itself cause the resulting work to be covered by the GNU General Public
## License. However the source code for this file must still be made available
## in accordance with section (3) of the GNU General Public License.
##
## This exception does not invalidate any other reasons why a work based on
## this file might be covered by the GNU General Public License.
##
## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
## at http://sources.redhat.com/ecos/ecos-license/
## -------------------------------------------
#####ECOSGPLCOPYRIGHTEND####
# ====================================================================
######DESCRIPTIONBEGIN####
#
# Author(s): jskov
# Original data: gthomas
# Contributors:
# Date: 1999-07-07
#
#####DESCRIPTIONEND####
#
# ====================================================================
 
cdl_package CYGPKG_IO_SERIAL {
display "Serial device drivers"
active_if CYGPKG_IO
requires CYGPKG_ERROR
include_dir cyg/io
description "
This option enables drivers for basic I/O services on
serial devices."
doc ref/io.html
 
compile -library=libextras.a common/serial.c
define_proc {
puts $::cdl_header "/***** proc output start *****/"
puts $::cdl_header "#include <pkgconf/system.h>"
puts $::cdl_header "#ifdef CYGDAT_IO_SERIAL_DEVICE_HEADER"
puts $::cdl_header "# include CYGDAT_IO_SERIAL_DEVICE_HEADER"
puts $::cdl_header "#endif "
puts $::cdl_header "/****** proc output end ******/"
}
 
cdl_option CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING {
display "Support non-blocking read and write calls"
default_value 0
description "
This option enables extra code in the generic serial driver
which allows clients to switch read() and write() call
semantics from blocking to non-blocking."
}
 
cdl_interface CYGINT_IO_SERIAL_BLOCK_TRANSFER {
display "Driver requires block transfer callback functions"
description "
Some low-level drivers can be optimized to transfer blocks
of data instead of a single character at a time. These usually
rely on a hardware FIFO of some sort."
}
 
cdl_interface CYGINT_IO_SERIAL_LINE_STATUS_HW {
display "Serial driver supports line status"
}
 
cdl_option CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS {
display "Support line status callbacks"
requires { CYGINT_IO_SERIAL_LINE_STATUS_HW > 0 }
default_value { 0 != CYGINT_IO_SERIAL_LINE_STATUS_HW }
description "
This option indicates that if the serial driver supports it,
serial line status and modem status information should be
propagated to higher layers via callbacks."
}
 
cdl_component CYGPKG_IO_SERIAL_FLOW_CONTROL {
display "Flow control"
description "
This component contains options related to flow control."
flavor bool
requires (CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE || \
CYGOPT_IO_SERIAL_FLOW_CONTROL_HW)
default_value 0
 
cdl_component CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE {
display "Software flow control"
default_value 1
description "
This component enables support of software flow control."
 
cdl_option CYGDAT_IO_SERIAL_FLOW_CONTROL_XON_CHAR {
display "Start character"
flavor data
default_value 17
legal_values 0 to 255
description "
This option specifies the ascii character used to
indicate that transmission should start."
}
 
cdl_option CYGDAT_IO_SERIAL_FLOW_CONTROL_XOFF_CHAR {
display "Stop character"
flavor data
default_value 19
legal_values 0 to 255
description "
This option specifies the ascii character used to
indicate that transmission should stop."
}
}
 
cdl_option CYGOPT_IO_SERIAL_FLOW_CONTROL_HW {
display "Hardware flow control"
active_if { CYGINT_IO_SERIAL_FLOW_CONTROL_HW > 0 }
requires { CYGINT_IO_SERIAL_FLOW_CONTROL_HW > 0 }
requires CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
default_value { CYGINT_IO_SERIAL_FLOW_CONTROL_HW > 0 ? \
CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS : 0 }
description "
If the hardware supports it, this option allows hardware
flow control to be enabled. This may be in the form of
either or both of RTS/CTS, or DSR/DTR flow control."
}
 
cdl_interface CYGINT_IO_SERIAL_FLOW_CONTROL_HW {
display "Serial h/w supports hardware flow control"
}
 
cdl_option CYGDAT_IO_SERIAL_FLOW_CONTROL_DEFAULT {
display "Default flow control method"
flavor data
legal_values { "NONE" "XONXOFF" "RTSCTS" "DSRDTR" }
default_value { "NONE" }
description "This option allows a default flow control method
to be defined. Combinations of flow control methods
may also be set, but this is only possible by
using the cyg_io_set_config() API in source code."
}
 
cdl_option CYGNUM_IO_SERIAL_FLOW_CONTROL_LOW_WATER_PERCENT {
display "Rx flow control low water mark"
flavor data
legal_values 1 to 100
default_value 33
description "This sets the water mark used for determining
when to disable flow control, expressed
as a percentage of the buffer size. When the
receive buffer size is lower than this percentage,
if the transmitter had previously been throttled, it
will now be informed it can restart."
}
 
cdl_option CYGNUM_IO_SERIAL_FLOW_CONTROL_HIGH_WATER_PERCENT {
display "Rx flow control high water mark"
flavor data
legal_values 1 to 100
default_value 66
requires { CYGNUM_IO_SERIAL_FLOW_CONTROL_HIGH_WATER_PERCENT >= \
CYGNUM_IO_SERIAL_FLOW_CONTROL_LOW_WATER_PERCENT }
description "This sets the water mark used for determining
when to enable flow control, expressed
as a percentage of the buffer size. When the
receive buffer size exceeds this percentage,
signals are sent to the transmitter to tell it
to throttle tranmission."
}
 
}
 
cdl_component CYGPKG_IO_SERIAL_TTY {
display "TTY-mode serial device drivers"
flavor bool
default_value 1
description "
This option enables a simple terminal-like device driver
that can be used for serial devices that interact with humans,
such as a system console."
script tty.cdl
compile -library=libextras.a common/tty.c
}
 
cdl_component CYGPKG_IO_SERIAL_TERMIOS {
display "Termios compatible TTY drivers"
flavor bool
requires CYGPKG_ISOINFRA
requires CYGPKG_IO_FILEIO
requires CYGINT_ISO_ERRNO_CODES
requires CYGINT_ISO_ERRNO
requires CYGINT_ISO_MALLOC
default_value { 0 != CYGPKG_ISOINFRA && 0 != CYGPKG_IO_FILEIO && \
0 != CYGINT_ISO_ERRNO_CODES && \
0 != CYGINT_ISO_ERRNO }
implements CYGINT_ISO_TERMIOS
description "
This option enables terminal drivers compatible with
POSIX termios."
script termios.cdl
compile common/termios.c
}
 
cdl_component CYGPKG_IO_SERIAL_DEVICES {
display "Hardware serial device drivers"
flavor bool
default_value 0
description "
This option enables the hardware device drivers
for the current platform."
}
 
cdl_option CYGBLD_IO_SERIAL_EXTRA_TESTS {
display "Build extra serial tests"
default_value 0
no_define
description "
This option enables the building of some extra tests which
can be used when testing / debugging serial drivers. These
are not built by default since they do not use the dedicated
testing infrastructure."
 
make -priority 320 {
<PREFIX>/bin/serial_echo : <PACKAGE>/tests/serial_echo.c
@sh -c "mkdir -p tests $(dir $@)"
$(CC) -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o tests/serial_echo.o $<
@echo $@ ": \\" > $(notdir $@).deps
@echo $(wildcard $(PREFIX)/lib/*) " \\" >> $(notdir $@).deps
@tail +2 deps.tmp >> $(notdir $@).deps
@echo >> $(notdir $@).deps
@rm deps.tmp
$(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ tests/serial_echo.o
}
}
 
cdl_component CYGPKG_IO_SERIAL_OPTIONS {
display "Serial device driver build options"
flavor none
description "
Package specific build options including control over
compiler flags used only in building this package,
and details of which tests are built."
 
 
cdl_option CYGPKG_IO_SERIAL_CFLAGS_ADD {
display "Additional compiler flags"
flavor data
no_define
default_value { "" }
description "
This option modifies the set of compiler flags for
building the serial device drivers. These flags are used in addition
to the set of global flags."
}
 
cdl_option CYGPKG_IO_SERIAL_CFLAGS_REMOVE {
display "Suppressed compiler flags"
flavor data
no_define
default_value { "" }
description "
This option modifies the set of compiler flags for
building the serial device drivers. These flags are removed from
the set of global flags if present."
}
 
cdl_option CYGPKG_IO_SERIAL_TESTS {
display "Serial device driver tests"
flavor data
no_define
calculated { CYGPKG_IO_SERIAL_DEVICES ? "tests/serial1 tests/serial2 tests/serial3 tests/serial4 tests/serial5 tests/tty1 tests/tty2 tests/flow1 tests/flow2" : "" }
description "
This option specifies the set of tests for the serial device drivers."
}
}
 
cdl_option CYGPKG_IO_SERIAL_SELECT_SUPPORT {
display "Enable serial device select support"
flavor bool
active_if CYGPKG_IO_FILEIO
requires CYGPKG_IO_FILEIO
default_value 1
description "
This option enables support for the select() API function on all
serial devices."
}
 
# These could be regular define_proc outputs, but keeping them as
# CDL interfaces allow us to possibly skip building/running some
# tests.
cdl_component CYGPKG_IO_SERIAL_TEST_SPECS {
display "Serial testing specification"
flavor bool
calculated 1
no_define
cdl_interface CYGINT_IO_SERIAL_TEST_SKIP_9600 {
display "Skip 9600 baud testing"
}
 
cdl_interface CYGINT_IO_SERIAL_TEST_SKIP_14400 {
display "Skip 14400 baud testing"
}
 
cdl_interface CYGINT_IO_SERIAL_TEST_SKIP_19200 {
display "Skip 19200 baud testing"
}
 
cdl_interface CYGINT_IO_SERIAL_TEST_SKIP_38400 {
display "Skip 38400 baud testing"
}
 
cdl_interface CYGINT_IO_SERIAL_TEST_SKIP_57600 {
display "Skip 57600 baud testing"
}
 
cdl_interface CYGINT_IO_SERIAL_TEST_SKIP_115200 {
display "Skip 115200 baud testing"
}
 
cdl_interface CYGINT_IO_SERIAL_TEST_SKIP_PARITY_EVEN {
display "Skip even-parity testing"
}
 
cdl_interface CYGINT_IO_SERIAL_TEST_SKIP_PARITY_ODD {
display "Skip odd-parity testing"
}
 
cdl_interface CYGINT_IO_SERIAL_TEST_SKIP_STOP_2 {
display "Skip 2-stop bit testing"
}
}
}
 
# EOF io_serial.cdl
/tests/serial1.c
0,0 → 1,154
//==========================================================================
//
// serial1.c
//
// Test serial driver API
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): jskov
// Contributors: jskov
// Date: 1999-03-17
// Description: Test the serial driver API.
//
//####DESCRIPTIONEND####
 
#include <pkgconf/system.h>
 
#include <cyg/infra/testcase.h> // test macros
#include <cyg/infra/cyg_ass.h> // assertion macros
 
// Package requirements
#if defined(CYGPKG_IO_SERIAL) && defined(CYGPKG_KERNEL)
 
#include <pkgconf/kernel.h>
 
// Package option requirements
#if defined(CYGFUN_KERNEL_API_C)
 
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
#include <cyg/kernel/kapi.h>
unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
cyg_thread thread_data;
cyg_handle_t thread_handle;
 
#include "ser_test_protocol.inl"
 
//---------------------------------------------------------------------------
// Serial test main function.
 
 
void
serial_api_test(int dummy)
{
cyg_io_handle_t handle;
int res, len;
unsigned char buffer[16];
 
// Always return...
if (dummy)
return;
 
CYG_TEST_FAIL_FINISH("Not reached");
 
test_open_ser(&handle);
 
// read & write
res = cyg_io_read(handle, &buffer[0], &len);
res = cyg_io_write(handle, &buffer[0], &len);
 
// cyg_io_get_config
cyg_io_get_config(handle,
CYG_IO_GET_CONFIG_SERIAL_INFO, &buffer[0], &len);
cyg_io_get_config(handle,
CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN, &buffer[0], &len);
cyg_io_get_config(handle,
CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH, &buffer[0], &len);
cyg_io_get_config(handle,
CYG_IO_GET_CONFIG_SERIAL_ABORT, &buffer[0], &len);
cyg_io_get_config(handle,
CYG_IO_GET_CONFIG_SERIAL_OUTPUT_FLUSH, &buffer[0], &len);
 
// cyg_io_set_config
cyg_io_set_config(handle,
CYG_IO_SET_CONFIG_SERIAL_INFO, &buffer[0], &len);
}
 
 
void
serial_test( void )
{
serial_api_test(1);
 
CYG_TEST_PASS_FINISH("serial1 test OK");
}
 
void
cyg_start(void)
{
CYG_TEST_INIT();
cyg_thread_create(10, // Priority - just a number
(cyg_thread_entry_t*)serial_test, // entry
0, //
"serial_thread", // Name
&stack[0], // Stack
CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size
&thread_handle, // Handle
&thread_data // Thread data structure
);
cyg_thread_resume(thread_handle);
cyg_scheduler_start();
}
 
#else // CYGFUN_KERNEL_API_C
#define N_A_MSG "Needs kernel C API"
#endif
 
#else // CYGPKG_IO_SERIAL && CYGPKG_KERNEL
#define N_A_MSG "Needs IO/serial and Kernel"
#endif
 
#ifdef N_A_MSG
void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG);
}
#endif // N_A_MSG
 
// EOF serial1.c
/tests/serial2.c
0,0 → 1,127
//==========================================================================
//
// serial2.c
//
// Test simple string output.
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): jskov
// Contributors: jskov
// Date: 1999-03-17
// Description: Test simple string output.
//
//####DESCRIPTIONEND####
 
#include <pkgconf/system.h>
 
#include <cyg/infra/testcase.h> // test macros
#include <cyg/infra/cyg_ass.h> // assertion macros
 
#if defined(CYGPKG_IO_SERIAL) && defined(CYGPKG_KERNEL)
 
#include <pkgconf/kernel.h>
 
// Package option requirements
#if defined(CYGFUN_KERNEL_API_C)
 
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
#include <cyg/kernel/kapi.h>
unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
cyg_thread thread_data;
cyg_handle_t thread_handle;
 
#include "ser_test_protocol.inl"
 
//---------------------------------------------------------------------------
// Serial test main function.
void
serial_test( void )
{
char test_msg1[]="This is a test message!\n";
char test_msg2[]="$O5468697320697320612074657374206d657373616765210d0a#12";
int msglen;
cyg_io_handle_t ser_handle;
 
test_open_ser(&ser_handle);
 
CYG_TEST_INFO("Writing a raw string to the serial device...");
msglen = strlen(&test_msg1[0]);
Tcyg_io_write(ser_handle, &test_msg1[0], &msglen);
 
CYG_TEST_INFO("Writing a GDB encoded string to the serial device...");
msglen = strlen(&test_msg2[0]);
Tcyg_io_write(ser_handle, &test_msg2[0], &msglen);
 
CYG_TEST_PASS_FINISH("serial2 test OK");
}
 
void
cyg_start(void)
{
CYG_TEST_INIT();
cyg_thread_create(10, // Priority - just a number
(cyg_thread_entry_t*)serial_test, // entry
0, //
"serial_thread", // Name
&stack[0], // Stack
CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size
&thread_handle, // Handle
&thread_data // Thread data structure
);
cyg_thread_resume(thread_handle);
cyg_scheduler_start();
}
 
#else // CYGFUN_KERNEL_API_C
#define N_A_MSG "Needs kernel C API"
#endif
 
#else // CYGPKG_IO_SERIAL && CYGPKG_KERNEL
#define N_A_MSG "Needs IO/serial and Kernel"
#endif
 
#ifdef N_A_MSG
void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG);
}
#endif // N_A_MSG
 
// EOF serial2.c
/tests/tty1.c
0,0 → 1,162
//==========================================================================
//
// tty.c
//
// Test TTY driver API
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): jskov
// Contributors: jskov
// Date: 1999-04-08
// Description: Test the TTY driver API.
//
//####DESCRIPTIONEND####
 
#include <pkgconf/system.h>
 
#include <cyg/infra/testcase.h> // test macros
#include <cyg/infra/cyg_ass.h> // assertion macros
 
// Package requirements
#if defined(CYGPKG_IO_SERIAL) && defined(CYGPKG_KERNEL)
 
#include <pkgconf/kernel.h>
 
// Package option requirements
#if defined(CYGFUN_KERNEL_API_C)
 
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
#include <cyg/kernel/kapi.h>
unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
cyg_thread thread_data;
cyg_handle_t thread_handle;
 
#include "ser_test_protocol.inl"
 
//---------------------------------------------------------------------------
// TTY test main function.
 
 
void
tty_api_test(cyg_io_handle_t* handle)
{
int res, len;
unsigned char buffer[16];
 
// Always return...
if (handle)
return;
 
CYG_TEST_FAIL_FINISH("Not reached");
 
// read & write
res = cyg_io_read(handle, &buffer[0], &len);
res = cyg_io_write(handle, &buffer[0], &len);
 
// cyg_io_get_config
// TTY layer
cyg_io_get_config(handle,
CYG_IO_GET_CONFIG_TTY_INFO, &buffer[0], &len);
// Call-throughs to serial layer.
cyg_io_get_config(handle,
CYG_IO_GET_CONFIG_SERIAL_INFO, &buffer[0], &len);
cyg_io_get_config(handle,
CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN, &buffer[0], &len);
cyg_io_get_config(handle,
CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH, &buffer[0], &len);
cyg_io_get_config(handle,
CYG_IO_GET_CONFIG_SERIAL_ABORT, &buffer[0], &len);
cyg_io_get_config(handle,
CYG_IO_GET_CONFIG_SERIAL_OUTPUT_FLUSH, &buffer[0], &len);
 
// cyg_io_set_config
// TTY layer.
cyg_io_set_config(handle,
CYG_IO_SET_CONFIG_TTY_INFO, &buffer[0], &len);
// Call-throughs to serial layer.
cyg_io_set_config(handle,
CYG_IO_SET_CONFIG_SERIAL_INFO, &buffer[0], &len);
}
 
 
void
tty_test( void )
{
cyg_io_handle_t tty_handle;
 
test_open_tty(&tty_handle);
 
tty_api_test(&tty_handle);
 
CYG_TEST_PASS_FINISH("tty1 test OK");
}
 
void
cyg_start(void)
{
CYG_TEST_INIT();
cyg_thread_create(10, // Priority - just a number
(cyg_thread_entry_t*)tty_test, // entry
0, //
"tty_thread", // Name
&stack[0], // Stack
CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size
&thread_handle, // Handle
&thread_data // Thread data structure
);
cyg_thread_resume(thread_handle);
cyg_scheduler_start();
}
 
#else // CYGFUN_KERNEL_API_C
#define N_A_MSG "Needs kernel C API"
#endif
 
#else // CYGPKG_IO_SERIAL && CYGPKG_KERNEL
#define N_A_MSG "Needs IO/serial and Kernel"
#endif
 
#ifdef N_A_MSG
void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG);
}
#endif // N_A_MSG
// EOF tty1.c
/tests/serial3.c
0,0 → 1,166
//==========================================================================
//
// serial3.c
//
// Test data half-duplex receive and send.
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): jskov
// Contributors: jskov
// Date: 1999-03-17
// Description: Test the half-duplex receive and send capabilities of
// the serial driver.
// Requirements: This test requires the ser_filter on the host side.
//
//####DESCRIPTIONEND####
 
#include <pkgconf/system.h>
 
#include <cyg/infra/testcase.h> // test macros
#include <cyg/infra/cyg_ass.h> // assertion macros
 
// Package requirements
#if defined(CYGPKG_IO_SERIAL) && defined(CYGPKG_KERNEL)
 
#include <pkgconf/kernel.h>
 
// Package option requirements
#if defined(CYGFUN_KERNEL_API_C)
 
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
#include <cyg/kernel/kapi.h>
unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
cyg_thread thread_data;
cyg_handle_t thread_handle;
 
#include "ser_test_protocol.inl"
 
//---------------------------------------------------------------------------
// Serial test main function.
void
serial_test( void )
{
cyg_io_handle_t ser_handle;
 
test_open_ser(&ser_handle);
 
// We need the filter for this test.
test_ping(ser_handle);
 
#if (CYGINT_IO_SERIAL_TEST_SKIP_38400 > 0)
{
// The board is too slow to run the driver in interrupt mode
// at the default 38400 baud when doing this test, so run it
// at a slower rate.
cyg_ser_cfg_t slow_cfg = {
CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8,
CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
CYGNUM_SERIAL_FLOW_NONE };
 
CYG_TEST_INFO("Reducing baud rate to 19200");
change_config(ser_handle, &slow_cfg);
}
#endif
 
// Start slowly, then go for max size.
{
test_binary(ser_handle, 16, MODE_EOP_ECHO);
test_binary(ser_handle, 128, MODE_EOP_ECHO);
test_binary(ser_handle, 256, MODE_EOP_ECHO);
test_binary(ser_handle, IN_BUFFER_SIZE, MODE_EOP_ECHO);
}
 
// Write some varying length packets.
{
int i;
for(i = 0; i < 8; i++) {
// No echo.
test_binary(ser_handle, 256 + 42*i, MODE_NO_ECHO);
test_binary(ser_handle, 64 + 7*i, MODE_NO_ECHO);
// Echo.
test_binary(ser_handle, 256 + 42*i, MODE_EOP_ECHO);
test_binary(ser_handle, 64 + 7*i, MODE_EOP_ECHO);
}
}
 
#if 0 // Disable this for now.
// End with some long packets.
{
test_binary(ser_handle, 2048, MODE_NO_ECHO);
test_binary(ser_handle, 16384, MODE_NO_ECHO);
test_binary(ser_handle, 65536, MODE_NO_ECHO);
}
#endif
 
CYG_TEST_PASS_FINISH("serial3 test OK");
}
 
void
cyg_start(void)
{
CYG_TEST_INIT();
cyg_thread_create(10, // Priority - just a number
(cyg_thread_entry_t*)serial_test, // entry
0, //
"serial_thread", // Name
&stack[0], // Stack
CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size
&thread_handle, // Handle
&thread_data // Thread data structure
);
cyg_thread_resume(thread_handle);
cyg_scheduler_start();
}
 
#else // CYGFUN_KERNEL_API_C
#define N_A_MSG "Needs kernel C API"
#endif
 
#else // CYGPKG_IO_SERIAL && CYGPKG_KERNEL
#define N_A_MSG "Needs IO/serial and Kernel"
#endif
 
#ifdef N_A_MSG
void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG);
}
#endif // N_A_MSG
// EOF serial3.c
/tests/tty2.c
0,0 → 1,128
//==========================================================================
//
// tty2.c
//
// Test simple string output.
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): jskov
// Contributors: jskov
// Date: 1999-03-17
// Description: Test simple string output.
//
//####DESCRIPTIONEND####
 
#include <pkgconf/system.h>
 
#include <cyg/infra/testcase.h> // test macros
#include <cyg/infra/cyg_ass.h> // assertion macros
 
// Package requirements
#if defined(CYGPKG_IO_SERIAL) && defined(CYGPKG_KERNEL)
 
#include <pkgconf/kernel.h>
 
// Package option requirements
#if defined(CYGFUN_KERNEL_API_C)
 
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
#include <cyg/kernel/kapi.h>
unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
cyg_thread thread_data;
cyg_handle_t thread_handle;
 
#include "ser_test_protocol.inl"
 
//---------------------------------------------------------------------------
// TTY test main function.
void
tty_test( void )
{
char test_msg1[]="This is a test message!\n";
char test_msg2[]="$O5468697320697320612074657374206d657373616765210d0a#12";
int msglen;
cyg_io_handle_t tty_handle;
 
test_open_tty(&tty_handle);
 
CYG_TEST_INFO("Writing a raw string to the TTY device...");
msglen = strlen(&test_msg1[0]);
Tcyg_io_write(tty_handle, &test_msg1[0], &msglen);
 
CYG_TEST_INFO("Writing a GDB encoded string to the TTY device...");
msglen = strlen(&test_msg2[0]);
Tcyg_io_write(tty_handle, &test_msg2[0], &msglen);
 
CYG_TEST_PASS_FINISH("tty2 test OK");
}
 
void
cyg_start(void)
{
CYG_TEST_INIT();
cyg_thread_create(10, // Priority - just a number
(cyg_thread_entry_t*)tty_test, // entry
0, //
"tty_thread", // Name
&stack[0], // Stack
CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size
&thread_handle, // Handle
&thread_data // Thread data structure
);
cyg_thread_resume(thread_handle);
cyg_scheduler_start();
}
 
 
#else // CYGFUN_KERNEL_API_C
#define N_A_MSG "Needs kernel C API"
#endif
 
#else // CYGPKG_IO_SERIAL && CYGPKG_KERNEL
#define N_A_MSG "Needs IO/serial and Kernel"
#endif
 
#ifdef N_A_MSG
void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG);
}
#endif // N_A_MSG
// EOF tty2.c
/tests/serial4.c
0,0 → 1,143
//==========================================================================
//
// serial4.c
//
// Test serial configuration changing
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): jskov
// Contributors: jskov
// Date: 1999-03-17
// Description: Test the configuration capabilities of the serial driver.
// Requirements: This test requires the ser_filter on the host side.
//
// To Do:
// This test should do a full test of the configuration combinations.
// This will get possible with proper test_change_config protocol
// implementation.
//####DESCRIPTIONEND####
 
#include <pkgconf/system.h>
 
#include <cyg/infra/testcase.h> // test macros
#include <cyg/infra/cyg_ass.h> // assertion macros
 
// Package requirements
#if defined(CYGPKG_IO_SERIAL) && defined(CYGPKG_KERNEL)
 
#include <pkgconf/kernel.h>
 
// Package option requirements
#if defined(CYGFUN_KERNEL_API_C)
 
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
#include <cyg/kernel/kapi.h>
unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
cyg_thread thread_data;
cyg_handle_t thread_handle;
 
#include "ser_test_protocol.inl"
 
//---------------------------------------------------------------------------
// Serial test main function.
void
serial_test( void )
{
cyg_io_handle_t ser_handle;
 
test_open_ser(&ser_handle);
 
// We need the filter for this test.
test_ping(ser_handle);
 
// Test multiple configurations (defined in the protocol file).
// FIXME: This will get replaced with a test over the full configuration
// permutation space.
{
int i;
int count = sizeof(test_configs) / sizeof(cyg_ser_cfg_t);
char msg[] = "This is a test\n";
int msglen = strlen(msg);
 
for (i = 0; i < count; i++){
if (ENOERR == change_config(ser_handle, &test_configs[i])) {
test_binary(ser_handle, 128, MODE_EOP_ECHO);
test_binary(ser_handle, 256, MODE_NO_ECHO);
Tcyg_io_write(ser_handle, msg, &msglen);
}
}
}
 
CYG_TEST_PASS_FINISH("serial4 test OK");
}
 
void
cyg_start(void)
{
CYG_TEST_INIT();
cyg_thread_create(10, // Priority - just a number
(cyg_thread_entry_t*)serial_test, // entry
0, //
"serial_thread", // Name
&stack[0], // Stack
CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size
&thread_handle, // Handle
&thread_data // Thread data structure
);
cyg_thread_resume(thread_handle);
cyg_scheduler_start();
}
 
#else // CYGFUN_KERNEL_API_C
#define N_A_MSG "Needs kernel C API"
#endif
 
#else // CYGPKG_IO_SERIAL && CYGPKG_KERNEL
#define N_A_MSG "Needs IO/serial and Kernel"
#endif
 
#ifdef N_A_MSG
void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG);
}
#endif // N_A_MSG
 
// EOF serial4.c
/tests/serial5.c
0,0 → 1,148
//==========================================================================
//
// serial5.c
//
// Test data duplex receive and send.
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): jskov
// Contributors: jskov
// Date: 1999-03-19
// Description: Test the duplex receive and send capabilities of
// the serial driver.
// Requirements: This test requires the ser_filter on the host side.
//####DESCRIPTIONEND####
 
#include <pkgconf/system.h>
 
#include <cyg/infra/testcase.h> // test macros
#include <cyg/infra/cyg_ass.h> // assertion macros
 
// Package requirements
#if defined(CYGPKG_IO_SERIAL) && defined(CYGPKG_KERNEL)
 
#include <pkgconf/kernel.h>
 
// Package option requirements
#if defined(CYGFUN_KERNEL_API_C)
 
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
#include <cyg/kernel/kapi.h>
unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
cyg_thread thread_data;
cyg_handle_t thread_handle;
 
#include "ser_test_protocol.inl"
 
//---------------------------------------------------------------------------
// Serial test main function.
void
serial_test( void )
{
cyg_io_handle_t ser_handle;
 
test_open_ser(&ser_handle);
 
// We need the filter for this test.
test_ping(ser_handle);
 
 
#if (CYGINT_IO_SERIAL_TEST_SKIP_38400 > 0)
{
// The board is too slow to run the driver in interrupt mode
// at the default 38400 baud when doing this test, so run it
// at a slower rate.
cyg_ser_cfg_t slow_cfg = {
CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8,
CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
CYGNUM_SERIAL_FLOW_NONE };
 
CYG_TEST_INFO("Reducing baud rate to 19200");
change_config(ser_handle, &slow_cfg);
}
#endif
 
// Start out slow, then go for many tests. Each cycle causes
// 512 bytes to be sent over the wire.
test_binary(ser_handle, 1, MODE_DUPLEX_ECHO);
test_binary(ser_handle, 2, MODE_DUPLEX_ECHO);
test_binary(ser_handle, 5, MODE_DUPLEX_ECHO);
 
#if 0 // Disable these until the ser_filter produces status output.
test_binary(ser_handle, 128, MODE_DUPLEX_ECHO);
test_binary(ser_handle, 512, MODE_DUPLEX_ECHO);
test_binary(ser_handle, 1024, MODE_DUPLEX_ECHO);
#endif
 
CYG_TEST_PASS_FINISH("serial5 test OK");
}
 
void
cyg_start(void)
{
CYG_TEST_INIT();
cyg_thread_create(10, // Priority - just a number
(cyg_thread_entry_t*)serial_test, // entry
0, //
"serial_thread", // Name
&stack[0], // Stack
CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size
&thread_handle, // Handle
&thread_data // Thread data structure
);
cyg_thread_resume(thread_handle);
cyg_scheduler_start();
}
 
#else // CYGFUN_KERNEL_API_C
#define N_A_MSG "Needs kernel C API"
#endif
 
#else // CYGPKG_IO_SERIAL && CYGPKG_KERNEL
#define N_A_MSG "Needs IO/serial and Kernel"
#endif
 
#ifdef N_A_MSG
void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG);
}
#endif // N_A_MSG
// EOF serial5.c
/tests/timeout.inl
0,0 → 1,143
#ifndef CYGONCE_IO_SERIAL_MISC_TIMEOUT_INL
#define CYGONCE_IO_SERIAL_MISC_TIMEOUT_INL
//==========================================================================
//
// timeout.inl
//
// Simple timeout support for serial I/O testing.
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): gthomas
// Contributors: gthomas
// Date: 1999-02-05
// Description: Simple timeout functions
//####DESCRIPTIONEND####
 
// Timeout support
 
typedef void (timeout_fun)(void *);
#ifndef NTIMEOUTS
#define NTIMEOUTS 8
#endif
typedef struct {
cyg_int32 delta; // Number of "ticks" in the future for this timeout
timeout_fun *fun; // Function to execute when it expires
void *arg; // Argument to pass when it does
} timeout_entry;
static timeout_entry timeouts[NTIMEOUTS];
static cyg_handle_t timeout_alarm_handle;
static cyg_alarm timeout_alarm;
static cyg_int32 last_delta;
 
static void
do_timeout(cyg_handle_t alarm, cyg_addrword_t data)
{
int i;
cyg_int32 min_delta;
timeout_entry *e = timeouts;
min_delta = 0x7FFFFFFF; // Maxint
for (i = 0; i < NTIMEOUTS; i++, e++) {
if (e->delta) {
e->delta -= last_delta;
if (e->delta == 0) {
// Time for this item to 'fire'
(e->fun)(e->arg);
} else {
if (e->delta < min_delta) min_delta = e->delta;
}
}
}
if (min_delta != 0x7FFFFFFF) {
// Still something to do, schedule it
cyg_alarm_initialize(timeout_alarm_handle, cyg_current_time()+min_delta, 0);
last_delta = min_delta;
}
}
 
static cyg_uint32
timeout(cyg_int32 delta, timeout_fun *fun, void *arg)
{
int i;
cyg_int32 min_delta;
static bool init = false;
timeout_entry *e = timeouts;
cyg_uint32 stamp;
if (!init) {
cyg_handle_t h;
cyg_clock_to_counter(cyg_real_time_clock(), &h);
cyg_alarm_create(h, do_timeout, 0, &timeout_alarm_handle, &timeout_alarm);
init = true;
}
stamp = 0; // Assume no slots available
for (i = 0; i < NTIMEOUTS; i++, e++) {
if ((e->delta == 0) && (e->fun == 0)) {
// Free entry
e->delta = delta;
e->fun = fun;
e->arg = arg;
stamp = (cyg_uint32)e;
break;
}
}
e = timeouts;
min_delta = 0x7FFFFFFF;
for (i = 0; i < NTIMEOUTS; i++, e++) {
if (e->delta && (e->delta < min_delta)) min_delta = e->delta;
}
if (min_delta != 0x7FFFFFFF) {
// Still something to do, schedule it
cyg_alarm_initialize(timeout_alarm_handle, cyg_current_time()+min_delta, 0);
last_delta = min_delta;
}
return stamp;
}
 
static void
untimeout(cyg_uint32 stamp)
{
if (stamp != 0) {
timeout_entry *e = (timeout_entry *)stamp;
if (e->fun != 0) {
e->delta = 0;
e->fun = 0;
e->arg = 0;
}
}
}
 
#endif // CYGONCE_IO_SERIAL_MISC_TIMEOUT_INL
/tests/flow1.c
0,0 → 1,209
//==========================================================================
//
// flow1.c
//
// Test data half-duplex receive and send with flow control.
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): jskov,jlarmour
// Contributors:
// Date: 2000-07-27
// Description: Test the half-duplex receive and send capabilities of
// the serial driver with flow control.
// Requirements: This test requires the ser_filter on the host side.
//
//####DESCRIPTIONEND####
 
#include <pkgconf/system.h>
 
#include <cyg/infra/testcase.h> // test macros
#include <cyg/infra/cyg_ass.h> // assertion macros
 
#ifdef CYGPKG_KERNEL
# include <pkgconf/kernel.h>
#endif
#ifdef CYGPKG_IO_SERIAL
# include <pkgconf/io_serial.h>
#endif
 
// Package requirements
#ifndef CYGPKG_IO_SERIAL
# define NA_MSG "Requires I/O serial package"
#elif !defined(CYGFUN_KERNEL_API_C)
# define NA_MSG "Requires kernel C API"
#elif !defined(CYGPKG_IO_SERIAL_FLOW_CONTROL)
# define NA_MSG "Requires serial flow control"
#endif
 
#ifdef NA_MSG
void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( NA_MSG);
}
#else
 
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
#include <cyg/kernel/kapi.h>
unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
cyg_thread thread_data;
cyg_handle_t thread_handle;
 
// redefine buffer size for large transfer tests
#ifndef CYGPKG_HAL_ARM_AEB
# define IN_BUFFER_SIZE 65536
#endif
 
#include "ser_test_protocol.inl"
 
 
//---------------------------------------------------------------------------
// run the tests
 
static void
run_tests( cyg_io_handle_t ser_handle )
{
 
// Start slowly, then go for max size.
{
test_binary(ser_handle, 16, MODE_EOP_ECHO);
test_binary(ser_handle, 128, MODE_EOP_ECHO);
test_binary(ser_handle, 256, MODE_EOP_ECHO);
test_binary(ser_handle, IN_BUFFER_SIZE, MODE_EOP_ECHO);
}
 
// Write some varying length packets.
{
int i;
for(i = 0; i < 8; i++) {
// No echo.
test_binary(ser_handle, 256 + 42*i, MODE_NO_ECHO);
test_binary(ser_handle, 64 + 7*i, MODE_NO_ECHO);
// Echo.
test_binary(ser_handle, 256 + 42*i, MODE_EOP_ECHO);
test_binary(ser_handle, 64 + 7*i, MODE_EOP_ECHO);
}
}
 
// End with some long packets.
{
test_binary(ser_handle, 2048, MODE_NO_ECHO);
test_binary(ser_handle, 16384, MODE_NO_ECHO);
test_binary(ser_handle, 65536, MODE_NO_ECHO);
}
}
 
//---------------------------------------------------------------------------
// Serial test main function.
 
void
serial_test( void )
{
cyg_io_handle_t ser_handle;
cyg_ser_cfg_t *cfg=&test_configs[0];
cyg_ser_cfg_t new_cfg;
int count = sizeof(test_configs) / sizeof(cyg_ser_cfg_t);
int i;
 
test_open_ser(&ser_handle);
 
// We need the filter for this test.
test_ping(ser_handle);
 
// Choose the configuration with the fastest baud rate, to be most
// provocative. Start at 1 coz cfg already points at 0
for (i=1; i<count; i++) {
if (cfg->baud_rate < test_configs[i].baud_rate)
cfg=&test_configs[i];
}
 
// Set flow control from configuration
// Choose software first
 
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE
CYG_TEST_INFO("Setting software flow control");
 
new_cfg = *cfg;
new_cfg.flags |= CYGNUM_SERIAL_FLOW_XONXOFF_RX |
CYGNUM_SERIAL_FLOW_XONXOFF_TX;
if (ENOERR == change_config(ser_handle, &new_cfg))
run_tests( ser_handle );
#endif
 
// hardware flow control
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW
CYG_TEST_INFO("Setting hardware flow control");
 
new_cfg = *cfg;
new_cfg.flags |= CYGNUM_SERIAL_FLOW_RTSCTS_RX|CYGNUM_SERIAL_FLOW_RTSCTS_TX;
if (ENOERR == change_config(ser_handle, &new_cfg))
run_tests( ser_handle );
 
CYG_TEST_INFO("Setting DSR/DTR hardware flow control");
 
new_cfg = *cfg;
new_cfg.flags |= CYGNUM_SERIAL_FLOW_DSRDTR_RX|CYGNUM_SERIAL_FLOW_DSRDTR_TX;
if (ENOERR == change_config(ser_handle, &new_cfg))
run_tests( ser_handle );
#endif
CYG_TEST_PASS_FINISH("flow1 test OK");
}
 
void
cyg_start(void)
{
CYG_TEST_INIT();
cyg_thread_create(10, // Priority - just a number
(cyg_thread_entry_t*)serial_test, // entry
0, //
"serial_thread", // Name
&stack[0], // Stack
CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size
&thread_handle, // Handle
&thread_data // Thread data structure
);
cyg_thread_resume(thread_handle);
cyg_scheduler_start();
}
 
#endif // ifndef NA_MSG
 
// EOF flow1.c
/tests/flow2.c
0,0 → 1,182
//==========================================================================
//
// flow2.c
//
// Test duplex receive and send with flow control.
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): jskov,jlarmour
// Contributors:
// Date: 2000-07-27
// Description: Test the duplex receive and send capabilities of
// the serial driver with flow control.
// Requirements: This test requires the ser_filter on the host side.
//
//####DESCRIPTIONEND####
 
#include <pkgconf/system.h>
 
#include <cyg/infra/testcase.h> // test macros
#include <cyg/infra/cyg_ass.h> // assertion macros
 
#ifdef CYGPKG_KERNEL
# include <pkgconf/kernel.h>
#endif
#ifdef CYGPKG_IO_SERIAL
# include <pkgconf/io_serial.h>
#endif
 
// Package requirements
#ifndef CYGPKG_IO_SERIAL
# define NA_MSG "Requires I/O serial package"
#elif !defined(CYGFUN_KERNEL_API_C)
# define NA_MSG "Requires kernel C API"
#elif !defined(CYGPKG_IO_SERIAL_FLOW_CONTROL)
# define NA_MSG "Requires serial flow control"
#endif
 
#ifdef NA_MSG
void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( NA_MSG);
}
#else
 
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
#include <cyg/kernel/kapi.h>
unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
cyg_thread thread_data;
cyg_handle_t thread_handle;
 
#include "ser_test_protocol.inl"
 
 
//---------------------------------------------------------------------------
// run the tests
 
static void
run_tests( cyg_io_handle_t ser_handle )
{
// Start slowly, then go for max size.
{
test_binary(ser_handle, 16, MODE_DUPLEX_ECHO);
test_binary(ser_handle, 128, MODE_DUPLEX_ECHO);
test_binary(ser_handle, 256, MODE_DUPLEX_ECHO);
test_binary(ser_handle, 1024, MODE_DUPLEX_ECHO);
}
}
 
//---------------------------------------------------------------------------
// Serial test main function.
 
void
serial_test( void )
{
cyg_io_handle_t ser_handle;
cyg_ser_cfg_t *cfg=&test_configs[0];
cyg_ser_cfg_t new_cfg;
int count = sizeof(test_configs) / sizeof(cyg_ser_cfg_t);
int i;
 
test_open_ser(&ser_handle);
 
// We need the filter for this test.
test_ping(ser_handle);
 
// Choose the configuration with the fastest baud rate, to be most
// provocative. Start at 1 coz cfg already points at 0
for (i=1; i<count; i++) {
if (cfg->baud_rate < test_configs[i].baud_rate)
cfg=&test_configs[i];
}
 
// Set flow control from configuration
// Choose software first
 
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE
CYG_TEST_INFO("Setting software flow control");
 
new_cfg = *cfg;
new_cfg.flags |= CYGNUM_SERIAL_FLOW_XONXOFF_RX |
CYGNUM_SERIAL_FLOW_XONXOFF_TX;
if (ENOERR == change_config(ser_handle, &new_cfg))
run_tests( ser_handle );
#endif
 
// hardware flow control
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW
CYG_TEST_INFO("Setting RTS/CTS hardware flow control");
 
new_cfg = *cfg;
new_cfg.flags |= CYGNUM_SERIAL_FLOW_RTSCTS_RX|CYGNUM_SERIAL_FLOW_RTSCTS_TX;
if (ENOERR == change_config(ser_handle, &new_cfg))
run_tests( ser_handle );
 
CYG_TEST_INFO("Setting DSR/DTR hardware flow control");
 
new_cfg = *cfg;
new_cfg.flags |= CYGNUM_SERIAL_FLOW_DSRDTR_RX|CYGNUM_SERIAL_FLOW_DSRDTR_TX;
if (ENOERR == change_config(ser_handle, &new_cfg))
run_tests( ser_handle );
#endif
CYG_TEST_PASS_FINISH("flow2 test OK");
}
 
void
cyg_start(void)
{
CYG_TEST_INIT();
cyg_thread_create(10, // Priority - just a number
(cyg_thread_entry_t*)serial_test, // entry
0, //
"serial_thread", // Name
&stack[0], // Stack
CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size
&thread_handle, // Handle
&thread_data // Thread data structure
);
cyg_thread_resume(thread_handle);
cyg_scheduler_start();
}
 
#endif // ifndef NA_MSG
 
// EOF flow2.c
/tests/ser_test_protocol.inl
0,0 → 1,1071
//==========================================================================
//
// ser_test_protocol.c
//
// Serial device driver testing protocol
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): jskov
// Contributors: jskov, gthomas
// Date: 1999-03-17
// Description: Protocol implementation used to test eCos serial devices.
// Relies on ser_filter to be present on the host side to
// respond to test requests.
//
// To Do:
// o Clean up.
// o Clean up config change magic.
// o Figure out how to handle kernel dependency
// : without kernel, no timeout. Without timeout, no filter auto detection.
//
//####DESCRIPTIONEND####
 
#include <pkgconf/system.h>
#include <pkgconf/io.h>
#include <pkgconf/io_serial.h>
 
#include <cyg/io/io.h>
#include <cyg/io/devtab.h>
#include <cyg/io/ttyio.h>
#include <cyg/infra/diag.h>
#include <cyg/infra/cyg_ass.h>
 
#include <cyg/hal/hal_intr.h> // for reclaiming interrupt vector
 
//----------------------------------------------------------------------------
// Definition of which device to run tests on on various platforms.
 
#define NA_MSG "No test device specified"
 
// Cleaned up drivers will export the testing parameters via CDL.
// When all drivers are changed, replace the TEST_ macros throughout
// with the CYGPRI_ equivalents.
#ifdef CYGPRI_SER_TEST_CRASH_ID
# define TEST_CRASH_ID CYGPRI_SER_TEST_CRASH_ID
# define TEST_SER_DEV CYGPRI_SER_TEST_SER_DEV
# define TEST_TTY_DEV CYGPRI_SER_TEST_TTY_DEV
#endif
 
// Note that CYGPRI_SER_TEST_OVERRIDE_INT_1 and CYGPRI_SER_TEST_OVERRIDE_INT_2
// may also be exported. These identify interrupts that should be reclaimed
// from the ROM monitor before the test is started.
 
#if defined(CYGPKG_HAL_POWERPC_MBX) \
&& defined(CYGPKG_HAL_QUICC) \
&& defined(CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC) \
&& defined(CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC1)
# define TEST_CRASH_ID "ppcmbx"
# define TEST_SER_DEV CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_NAME
# if defined(CYGPKG_IO_SERIAL_TTY_TTY1)
# define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY1_DEV
# endif
#endif
#if defined(CYGPKG_HAL_MN10300_AM31_STDEVAL1) \
&& defined(CYGPKG_IO_SERIAL_MN10300) \
&& defined(CYGPKG_IO_SERIAL_MN10300_SERIAL2)
# define TEST_CRASH_ID "am31st"
# define TEST_SER_DEV CYGDAT_IO_SERIAL_MN10300_SERIAL2_NAME
# if defined(CYGPKG_IO_SERIAL_TTY_TTY2)
# define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY1_DEV
# endif
#endif
#if defined(CYGPKG_HAL_MN10300_AM33_STB) \
&& defined(CYGPKG_IO_SERIAL_MN10300) \
&& defined(CYGPKG_IO_SERIAL_MN10300_SERIAL0)
# define TEST_CRASH_ID "am33st"
# define TEST_SER_DEV CYGDAT_IO_SERIAL_MN10300_SERIAL0_NAME
# if defined(CYGPKG_IO_SERIAL_TTY_TTY0)
# define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY0_DEV
# endif
#endif
 
// We can't rely on haldiag for ser_filter detection - it may not define
// a working character reading function.
#ifndef TEST_SER_DEV
# define SER_NOP_TEST
# define TTY_NOP_TEST
# define TEST_SER_DEV "/dev/null"
# define TEST_TTY_DEV "/dev/null"
#else
# ifndef TEST_TTY_DEV
# define TTY_NOP_TEST
# define TEST_TTY_DEV "/dev/null"
# endif
#endif
 
#ifndef TEST_CRASH_ID
#define TEST_CRASH_ID "......"
#endif
 
//----------------------------------------------------------------------------
// Crash types
// Eventually this will be moved into a separate header file so a script
// can read the definitions and use the output formats/codes to analyze
// test results. For now we just keep it here...
 
// FAILCODE:<tttttt:cccc:[optional data, separated by :]!>
// tttttt: 6 letter target code
// cccc: crash code (16bit hex value)
 
#define TEST_CRASH(__h, __code, __msg, args...) \
CYG_MACRO_START \
int __len = 1; \
/* Try to flush remaining input */ \
cyg_thread_delay(50); \
cyg_io_get_config(__h, CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH, \
0, &__len); \
diag_printf("FAILCODE:<" TEST_CRASH_ID ":%04x:" __code, ## args); \
diag_printf("!>\n"); \
CYG_FAIL(__msg); \
hang(); \
CYG_MACRO_END
 
// Target IO
#define TEST_CRASH_IO 0x0000
#define TEST_CRASH_IO_READ "%d", 0x0001
#define TEST_CRASH_IO_WRITE "%d", 0x0002
#define TEST_CRASH_IO_DRAIN "%d", 0x0003
#define TEST_CRASH_IO_GET_CFG "%d", 0x0004
#define TEST_CRASH_IO_SET_CFG "%d", 0x0005
 
// Target
#define TEST_CRASH_CRC 0x0010
#define TEST_CRASH_CRC_CHAR "%02x", 0x0011
#define TEST_CRASH_CRC_BAD "%08x:%08x", 0x0012
#define TEST_CRASH_CRC_HOST "", 0x0013
 
// Protocol errors
#define TEST_CRASH_PROT 0x1000
#define TEST_CRASH_PROT_BIN_MODE "%d", 0x1080
#define TEST_CRASH_PROT_TEXT "%d", 0x1100
 
#define TEST_CRASH_HOST_xx 0xf000
#define TEST_CRASH_HOST_TIMEOUT "%d:%d:%d:%d", 0xf000
// command#, read invocation#, expected, actual
#define TEST_CRASH_HOST_CRC_BAD "%d:%08x:%08x:%d:%02x:%02x", 0xf010
// command#, expected CRC, actual, index, expected char, actual
#define TEST_CRASH_HOST_DUPLEX_BAD "%d:%d:%02x:%02x", 0xf020
// command#, index, expected char, actual
 
//----------------------------------------------------------------------------
// The data in buffer and the cmd buffer
#ifndef IN_BUFFER_SIZE
# define IN_BUFFER_SIZE 1024
#endif
cyg_uint8 in_buffer[IN_BUFFER_SIZE];
 
cyg_int8 cmd_buffer[128];
 
//----------------------------------------------------------------------------
// Some types specific to the testing protocol.
typedef enum {
MODE_NO_ECHO = 0,
MODE_EOP_ECHO,
MODE_DUPLEX_ECHO
} cyg_mode_t;
 
typedef enum {
TEST_RETURN_OK = ENOERR,
TEST_RETURN_NA
} cyg_test_return_t;
 
typedef struct ser_cfg {
cyg_serial_baud_rate_t baud_rate;
cyg_serial_word_length_t data_bits;
cyg_serial_stop_bits_t stop_bits;
cyg_serial_parity_t parity;
cyg_uint32 flags;
// etc...
} cyg_ser_cfg_t;
 
typedef enum {
OPT_SERIAL_DEBUG = 0,
OPT_VERBOSE_LEVEL
} cyg_option_t;
 
typedef enum {
_NONE = 0,
PROTOCOL_PROGRESS,
PROTOCOL_DATA,
} cyg_verbosity_level_t;
 
 
// A few predifined option macros. Use after test_ping().
#define TEST_OPTIONS(__handle, __array) \
test_options(__handle, sizeof(__array)/8, __array)
 
#define TEST_HOST_DEBUG(__handle) \
CYG_MACRO_START \
cyg_uint32 __options[] = {OPT_SERIAL_DEBUG, 1}; \
test_options((__handle), sizeof(__options)/8, \
__options); \
CYG_MACRO_END
 
#define TEST_HOST_PROGRESS(__handle) \
CYG_MACRO_START \
cyg_uint32 __options[] = \
{OPT_SERIAL_DEBUG, 1, \
OPT_VERBOSE_LEVEL, PROTOCOL_PROGRESS}; \
test_options((__handle), sizeof(__options)/8, \
__options); \
CYG_MACRO_END
 
#define TEST_HOST_DATA(__handle) \
CYG_MACRO_START \
cyg_uint32 __options[] = \
{OPT_SERIAL_DEBUG, 1, \
OPT_VERBOSE_LEVEL, PROTOCOL_DATA}; \
test_options((__handle), sizeof(__options)/8, \
__options); \
CYG_MACRO_END
 
//----------------------------------------------------------------------------
// A few predefined configurations. These must all be valid for any
// given target until change_config is behaving correctly.
cyg_ser_cfg_t test_configs[] = {
#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_9600)
{ CYGNUM_SERIAL_BAUD_9600, CYGNUM_SERIAL_WORD_LENGTH_8,
CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
CYGNUM_SERIAL_FLOW_NONE },
#endif
 
#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_14400)
#if !defined(CYGPKG_HAL_MN10300_AM31) && \
!defined(CYGPKG_HAL_MN10300_AM33)
{ CYGNUM_SERIAL_BAUD_14400, CYGNUM_SERIAL_WORD_LENGTH_8,
CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
CYGNUM_SERIAL_FLOW_NONE },
#endif
#endif
 
{ CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8,
CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
CYGNUM_SERIAL_FLOW_NONE },
 
#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_38400)
{ CYGNUM_SERIAL_BAUD_38400, CYGNUM_SERIAL_WORD_LENGTH_8,
CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
CYGNUM_SERIAL_FLOW_NONE },
#endif
 
#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_57600)
#if !defined(CYGPKG_HAL_MN10300_AM33)
{ CYGNUM_SERIAL_BAUD_57600, CYGNUM_SERIAL_WORD_LENGTH_8,
CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
CYGNUM_SERIAL_FLOW_NONE },
#endif
#endif
 
#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_115200)
#if !defined(CYGPKG_HAL_MN10300_STDEVAL1)
{ CYGNUM_SERIAL_BAUD_115200, CYGNUM_SERIAL_WORD_LENGTH_8,
CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
CYGNUM_SERIAL_FLOW_NONE },
#endif
#endif
 
#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_PARITY_EVEN)
// One stop bit, even parity
{ CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8,
CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_EVEN,
CYGNUM_SERIAL_FLOW_NONE },
#endif
 
#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_PARITY_EVEN)
#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_STOP_2)
// Two stop bits, even parity
{ CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8,
CYGNUM_SERIAL_STOP_2, CYGNUM_SERIAL_PARITY_EVEN,
CYGNUM_SERIAL_FLOW_NONE },
#endif
#endif
 
#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_STOP_2)
// Two stop bits, no parity
{ CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8,
CYGNUM_SERIAL_STOP_2, CYGNUM_SERIAL_PARITY_NONE,
CYGNUM_SERIAL_FLOW_NONE },
#endif
};
 
//----------------------------------------------------------------------------
// Macros to help extract values from the argument string.
// Note: This is probably not an ideal solution, but it was easy to make :)
 
#define INIT_VALUE(__args) \
unsigned int v; \
char *__ptr1, *__ptr2 = (__args)
 
#define SET_VALUE(__slot) \
do { \
__ptr1 = index(__ptr2, (int) ':'); \
if (__ptr1) \
*__ptr1 = 0; \
v = atoi(__ptr2); \
__ptr2 = __ptr1+1; \
(__slot) = v; \
} while (0)
 
 
//----------------------------------------------------------------------------
// CRC magic - it's a bit of a hack for now.
// FIXME: standard definition?
#define ADD_CRC_BYTE(__crc, __c) \
CYG_MACRO_START \
(__crc) = ((__crc) << 1) ^ (__c); \
CYG_MACRO_END
 
// FIXME: Hack to allow easy ASCII transfer.
#define FIX_CRC(__crc, __icrc) \
CYG_MACRO_START \
__icrc = (int) (__crc); \
if (__icrc < 0) \
__icrc = -__icrc; \
CYG_MACRO_END
 
//----------------------------------------------------------------------------
// Macros for read/write to serial with error cheking.
static volatile cyg_uint32 r_stamp;
static volatile int aborted;
 
// This routine will be called if the read "times out"
static void
do_abort(void *handle)
{
cyg_io_handle_t io_handle = (cyg_io_handle_t)handle;
cyg_int32 len = 1; // Need something here
cyg_io_get_config(io_handle, CYG_IO_GET_CONFIG_SERIAL_ABORT, 0, &len);
aborted = 1;
}
#include "timeout.inl"
 
// Read with timeout (__t = timeout in ticks, int* __r = result)
#define Tcyg_io_read_timeout(__h, __d, __l, __t, __r) \
CYG_MACRO_START \
int __res; \
r_stamp = timeout((__t), do_abort, (__h)); \
__res = cyg_io_read((__h), (__d), (__l)); \
if (ENOERR != __res && -EINTR != __res) { \
TEST_CRASH(__h, TEST_CRASH_IO_READ, \
"cyg_io_read/timeout failed", __res); \
} \
*(__r) = __res; \
untimeout(r_stamp); \
CYG_MACRO_END
 
#define Tcyg_io_read(__h, __d, __l) \
CYG_MACRO_START \
int __res = cyg_io_read((__h), (__d), (__l)); \
if (ENOERR != __res) { \
TEST_CRASH(__h, TEST_CRASH_IO_READ, \
"cyg_io_read failed", __res); \
} \
CYG_MACRO_END
 
#define Tcyg_io_write(__h, __d, __l) \
CYG_MACRO_START \
int __res; \
cyg_uint32 __len = 1; \
__res = cyg_io_write((__h), (__d), (__l)); \
if (ENOERR != __res) { \
TEST_CRASH(__h, TEST_CRASH_IO_WRITE, \
"cyg_io_write failed", __res); \
} \
__res = cyg_io_get_config((__h), \
CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN, \
0, &__len); \
if (ENOERR != __res) { \
TEST_CRASH(__h, TEST_CRASH_IO_DRAIN, \
"DRAIN failed", __res); \
} \
CYG_MACRO_END
 
 
//----------------------------------------------------------------------------
// Some libc like functions that are handy to have around.
static int
strlen(const char *c)
{
int l = 0;
while (*c++) l++;
return l;
}
 
static char*
strcpy(char* dest, const char* src)
{
char c;
while ((c = *src++)) {
*dest++ = c;
}
*dest = c;
 
return dest;
}
 
static char*
itoa(char* dest, int v)
{
char b[16];
char* p = &b[16];
 
*--p = 0;
if (v) {
while (v){
*--p = (v % 10) + '0';
v = v / 10;
}
} else
*--p = '0';
 
return strcpy(dest, p);
}
 
#define min(_a, _b) ((_a) < (_b)) ? (_a) : (_b)
 
void
hang(void)
{
while (1);
}
 
//-----------------------------------------------------------------------------
// Configuration changing function.
//
// First change to the new config and back again to determine if the driver
// can handle the config.
// If not, return error.
//
// Then query the host for its capability to use the config:
// Format out:
// "@CONFIG:<baud rate code>:<#data bits>:<#stop bits>:<parity on/off>:<flow control code>!"
// Format in:
// OK/ER
//
// On ER, return error.
//
// On OK, change to the new configuration. Resynchronize with the host:
// Target waits for host to send S(ync)
// [host will delay at least .1 secs after changing baud rate so the
// line has time to settle.]
//
// When receiving S(ync), target replies OK to the host which then
// acknowledges with D(one).
//
// Host can also send R(esync) which means it didn't receieve the OK. If
// so the target resends its S(ync) message.
//
// If the synchronization has not succeeded within 1 second
// (configurable in the protocol), both host and target will revert to
// the previous configuration and attempt to synchronize again. If
// this fails, this call will hang and the host will consider the test
// a failure.
//
// To Do:
// Host&protocol currently only supports:
// - no/even parity
int
change_config(cyg_io_handle_t handle, cyg_ser_cfg_t* cfg)
{
cyg_serial_info_t old_cfg, new_cfg;
const char cmd[] = "@CONFIG:";
char reply[2];
int msglen;
int res, len;
cyg_uint8 *p1;
 
// Prepare the command.
p1 = &cmd_buffer[0];
p1 = strcpy(p1, &cmd[0]);
p1 = itoa(p1, cfg->baud_rate);
*p1++ = ':';
p1 = itoa(p1, cfg->data_bits);
*p1++ = ':';
p1 = itoa(p1, cfg->stop_bits);
*p1++ = ':';
p1 = itoa(p1, cfg->parity);
*p1++ = ':';
p1 = itoa(p1, cfg->flags);
*p1++ = '!';
*p1 = 0; // note: we may append to this later
 
// Tell user what we're up to.
CYG_TEST_INFO(&cmd_buffer[1]);
 
// Change to new config and then back to determine if the driver likes it.
len = sizeof(old_cfg);
res = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_SERIAL_INFO,
&old_cfg, &len);
res = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_SERIAL_INFO,
&new_cfg, &len);
 
if (res != ENOERR) {
TEST_CRASH(handle, TEST_CRASH_IO_GET_CFG,
"Can't get serial config", res);
}
 
new_cfg.baud = cfg->baud_rate;
new_cfg.word_length = cfg->data_bits;
new_cfg.stop = cfg->stop_bits;
new_cfg.parity = cfg->parity;
new_cfg.flags = cfg->flags;
 
res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO,
&new_cfg, &len);
cyg_thread_delay(10); // Some chips don't like changes to happen to fast...
 
// Driver didn't like it. It will not have changed anything, so it's
// safe to return now.
if (ENOERR != res) {
// Let user know that the config was skipped due to the target.
const char txt_tskipped[] = "- skipped by target!";
p1 = strcpy(p1, txt_tskipped);
*p1 = 0;
CYG_TEST_INFO(&cmd_buffer[1]);
return res;
}
 
// Succeeded. Change back to the original config so we can communicate
// with the host.
res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO,
&old_cfg, &len);
cyg_thread_delay(10); // Some chips don't like changes to happen to fast...
 
if (res != ENOERR) {
TEST_CRASH(handle, TEST_CRASH_IO_SET_CFG,
"Can't set serial config", res);
}
 
// Send command to host and read host's reply.
msglen = strlen(&cmd_buffer[0]);
Tcyg_io_write(handle, &cmd_buffer[0], &msglen);
msglen = 2;
Tcyg_io_read(handle, &reply[0], &msglen);
 
// Did host accept configuration?
if ('O' != reply[0] || 'K' != reply[1]) {
// Let user know that the config was skipped due to the host.
const char txt_hskipped[] = "- skipped by host!";
p1 = strcpy(p1, txt_hskipped);
*p1 = 0;
CYG_TEST_INFO(&cmd_buffer[1]);
diag_printf("Host didn't accept config (%02x, %02x).\n",
reply[0], reply[1]);
 
res = ENOSUPP;
return res;
}
 
// Now change config and wait for host to send us a S(ync)
// character.
// Loop until protocol exchange completed. This may hang (as seen
// from the host), but only when we get totally lost, in which
// case there's not much else to do really. In this case the host
// will consider the test a FAIL.
len = sizeof(new_cfg);
res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO,
&new_cfg, &len);
cyg_thread_delay(10); // Some chips don't like changes to happen to fast...
if (res != ENOERR) {
TEST_CRASH(handle, TEST_CRASH_IO_SET_CFG,
"Can't set serial config/2", res);
}
 
{
int change_succeeded = 0;
int using_old_config = 0;
char in_buf[1];
int len;
int saw_host_sync;
 
for (;;) {
aborted = 0; // global abort flag
 
// FIXME: Timeout time needs to be configurable, and needs to
// be sent to the host before getting here. That would allow
// changing the timeout by just rebuilding the test - without
// changing the host software.
saw_host_sync = 0;
r_stamp = timeout(100, do_abort, handle);
while(!aborted) {
len = 1;
in_buf[0] = 0;
res = cyg_io_read(handle, in_buf, &len);
if (ENOERR != res && -EINTR != res) {
// We may have to reset the driver here if the fail
// was due to a framing or parity error.
break;
}
if ('R' == in_buf[0]) {
// Resync - host didn't see our message. Try again.
saw_host_sync = 0;
} else if ('S' == in_buf[0] && !saw_host_sync) {
// In sync - reply to host if we haven't already
char ok_msg[2] = "OK";
int ok_len = 2;
Tcyg_io_write(handle, ok_msg, &ok_len);
saw_host_sync = 1;
} else if ('D' == in_buf[0] && saw_host_sync) {
// Done - exchange completed.
change_succeeded = 1;
break;
}
}
untimeout(r_stamp);
 
if (change_succeeded) {
// If we had to revert to the old configuration, return error.
if (using_old_config)
return -EIO;
else
return ENOERR;
}
 
// We didn't synchronize with the host. Due to an IO error?
if (ENOERR != res && -EINTR != res) {
// We may have to reset the driver if the fail was due to
// a framing or parity error.
}
 
// Revert to the old configuration and try again.
len = sizeof(old_cfg);
res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO,
&old_cfg, &len);
cyg_thread_delay(10); // Some chips don't like changes to happen to fast...
if (res != ENOERR) {
TEST_CRASH(handle, TEST_CRASH_IO_SET_CFG,
"Can't set serial config/3", res);
}
using_old_config = 1;
}
 
}
}
 
 
//-----------------------------------------------------------------------------
// Host sends CRC in decimal ASCII, terminated with !
int
read_host_crc(cyg_io_handle_t handle)
{
int crc, len;
cyg_uint8 ch;
 
crc = 0;
while (1) {
len = 1;
Tcyg_io_read(handle, &ch, &len);
if ('!' == ch)
break;
 
if (!((ch >= '0' && ch <= '9'))){
TEST_CRASH(handle, TEST_CRASH_CRC_CHAR,
"Illegal CRC format from host", ch);
}
 
crc = crc*10 + (ch - '0');
}
 
return crc;
}
 
//---------------------------------------------------------------------------
// Test binary data transmission.
// Format out:
// "@BINARY:<byte size>:<mode>!"
// Format in:
// <checksum>!<#size bytes data>
// For echo modes, also:
// Format out:
// <#size bytes data>
// Format in:
// OK/ER
// Format out:
// DONE
//
// The last DONE allows the host to eat bytes if target is sending too many.
//
// Mode:
// MODE_NO_ECHO:
// Just receive data and verify CRC.
// MODE_EOP_ECHO:
// Receive data, verify CRC, resend data.
// Expect OK/ER reply from host when done.
// MODE_DUPLEX_ECHO:
// Receive data, echo data, verify CRC.
// Expect OK/ER reply from host when done.
//
// Note:
// Using diag_printf while talking with the host may cause some funky
// errors (bytes from the host side being lost!?!?)
//
// To Do:
// MODE_DUPLEX_ECHO:
// The current implementation is simple and may not stress the
// driver enough. Also, it's command packet format doesn't match
// that of the other modes.
 
cyg_test_return_t
test_binary(cyg_io_handle_t handle, int size, cyg_mode_t mode)
{
const char cmd[] = "@BINARY:";
int msglen;
cyg_uint32 xcrc;
int icrc, host_crc;
cyg_uint8 *p1;
cyg_int8 host_status = 'O'; // host is happy by default
 
// Verify that the test can be run with available ressources.
if (MODE_EOP_ECHO == mode && size > IN_BUFFER_SIZE)
return TEST_RETURN_NA;
 
// Prepare and send the command.
p1 = &cmd_buffer[0];
p1 = strcpy(p1, &cmd[0]);
p1 = itoa(p1, size);
*p1++ = ':';
p1 = itoa(p1, mode);
*p1++ = '!';
*p1++ = 0;
 
CYG_TEST_INFO(&cmd_buffer[1]);
msglen = strlen(&cmd_buffer[0]);
Tcyg_io_write(handle, &cmd_buffer[0], &msglen);
 
// Get CRC back.
host_crc = read_host_crc(handle);
 
// Depending on mode, start reading data.
xcrc = 0;
switch (mode) {
case MODE_NO_ECHO:
{
// Break transfers into chunks no larger than the buffer size.
int tx_len, chunk_len, i;
while (size > 0) {
chunk_len = min(IN_BUFFER_SIZE, size);
tx_len = chunk_len;
size -= chunk_len;
 
Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
 
for (i = 0; i < tx_len; i++) {
ADD_CRC_BYTE(xcrc, in_buffer[i]);
}
}
 
// Reply that we have completed the test.
{
const char msg_done[] = "DONE";
 
chunk_len = strlen(&msg_done[0]);
Tcyg_io_write(handle, &msg_done[0], &chunk_len);
}
 
}
break;
case MODE_EOP_ECHO:
{
// We have already checked that the in buffer is large enough.
int i, tx_len, chunk_len;
chunk_len = tx_len = size;
Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
 
for (i = 0; i < tx_len; i++) {
ADD_CRC_BYTE(xcrc, in_buffer[i]);
}
 
// Echo data back.
chunk_len = size;
Tcyg_io_write(handle, &in_buffer[0], &chunk_len);
// Now read host side's status
chunk_len = 2;
Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
host_status = in_buffer[0];
 
// Reply that we have completed the test.
{
const char msg_done[] = "DONE";
 
chunk_len = strlen(&msg_done[0]);
Tcyg_io_write(handle, &msg_done[0], &chunk_len);
}
}
break;
case MODE_DUPLEX_ECHO:
{
int chunk_len;
int block_size = 64;
 
// This is a simple implementation (maybe too simple).
// Host sends 4 packets with the same size (64 bytes atm).
// Target echoes in this way:
// packet1 -> packet1
// packet2 -> packet2, packet2
// packet3 -> packet3
// packet4 -> /dev/null
//
// The reads/writes are interleaved in a way that should ensure
// the target out buffer to be full before the target starts to read
// packet3. That is, the target should be both receiving (packet3)
// and sending (packet2) at the same time.
 
while (size--) {
// block_size -> block_size
chunk_len = block_size;
Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
chunk_len = block_size;
Tcyg_io_write(handle, &in_buffer[0], &chunk_len);
 
// block_size -> 2 x block_size
chunk_len = block_size;
Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
chunk_len = block_size;
Tcyg_io_write(handle, &in_buffer[0], &chunk_len);
chunk_len = block_size;
Tcyg_io_write(handle, &in_buffer[0], &chunk_len);
 
// block_size -> block_size
chunk_len = block_size;
Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
chunk_len = block_size;
Tcyg_io_write(handle, &in_buffer[0], &chunk_len);
// block_size -> 0
chunk_len = block_size;
Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
}
 
// Kill the CRC. Leave packet verification to the host for now.
xcrc = host_crc = 0;
 
// Now read host side's status
chunk_len = 2;
Tcyg_io_read(handle, &in_buffer[0], &chunk_len);
host_status = in_buffer[0];
 
// Reply that we have completed the test.
{
const char msg_done[] = "DONE";
 
chunk_len = strlen(&msg_done[0]);
Tcyg_io_write(handle, &msg_done[0], &chunk_len);
}
}
break;
default:
TEST_CRASH(handle, TEST_CRASH_PROT_BIN_MODE,
"Unknown mode", mode);
break;
}
 
 
// Verify that the CRC matches the one from the host.
FIX_CRC(xcrc, icrc);
if (host_crc != icrc) {
TEST_CRASH(handle, TEST_CRASH_CRC_BAD,
"Input CRC failed", icrc, host_crc);
}
 
// Verify that the host is happy with the data we echoed.
if ('O' != host_status) {
TEST_CRASH(handle, TEST_CRASH_CRC_HOST,
"Output CRC failed");
}
 
CYG_TEST_PASS("Binary test completed");
return TEST_RETURN_OK;
}
 
//---------------------------------------------------------------------------
// Test transformations on text transmissions
// Format out:
// "@TEXT:<mode>!<4 bytes binary checksum><C string>"
// Format in:
// "<C string>"
// OK/ER
//
// Mode:
// MODE_EOP_ECHO:
// Receive data, verify CRC, resend data.
// Expect OK/ER reply from host when done.
// MODE_DUPLEX_ECHO:
// Receive data, echo data, verify CRC.
// Expect OK/ER reply from host when done.
//
cyg_test_return_t
test_text(cyg_io_handle_t handle, cyg_mode_t mode, const char* s_base,
const char* s_out, const char* s_in)
{
return TEST_RETURN_NA;
}
 
//---------------------------------------------------------------------------
// Send PING to host, verifying the filter's presence.
// Format out:
// "@PING:<crash id>!"
// Format in:
// "OK"
// or
// No response if directly connected to GDB.
//
// This call only returns if the ser_filter is listening. Otherwise it
// sends N/A and hangs.
void
test_ping(cyg_io_handle_t handle)
{
char msg[] = "@PING:" TEST_CRASH_ID "!";
char msg2[] = "\n";
int msglen = strlen(msg);
int res;
 
msglen = strlen(msg);
Tcyg_io_write(handle, msg, &msglen);
 
// Now read host side's status
msglen = 2;
Tcyg_io_read_timeout(handle, &in_buffer[0], &msglen, 100, &res);
if (ENOERR == res && 'O' == in_buffer[0] && 'K' == in_buffer[1])
return;
 
msglen = strlen(msg2);
Tcyg_io_write(handle, msg2, &msglen);
 
CYG_TEST_NA("No host side testing harness detected.");
}
 
 
//---------------------------------------------------------------------------
// Send OPT to host, setting options in the filter.
// Format out:
// "@OPT:option1,value1:...:optionN,valueN!"
// Format in:
// "OK"
//
// Only integer values can be used. Any option not recognized by the
// filter will be silently ignored.
void
test_options(cyg_io_handle_t handle, int count, cyg_uint32* options)
{
const char cmd[] = "@OPT:";
int msglen;
cyg_uint8 *p1;
 
// Prepare and send the command.
p1 = &cmd_buffer[0];
p1 = strcpy(p1, &cmd[0]);
while(count--) {
p1 = itoa(p1, *options++); // option
*p1++ = ':';
p1 = itoa(p1, *options++); // value
*p1++ = ':';
}
*(p1-1) = '!';
*p1++ = 0;
 
CYG_TEST_INFO(&cmd_buffer[1]);
msglen = strlen(&cmd_buffer[0]);
Tcyg_io_write(handle, &cmd_buffer[0], &msglen);
 
// Now read host side's status
msglen = 2;
Tcyg_io_read(handle, &in_buffer[0], &msglen);
}
 
 
//---------------------------------------------------------------------------
// Some helper functions to get a test started.
void
test_open_ser( cyg_io_handle_t* handle )
{
#if defined(CYGPKG_IO_SERIAL_DEVICES) && !defined(SER_NOP_TEST)
Cyg_ErrNo res;
 
if (cyg_test_is_simulator)
CYG_TEST_NA("Cannot run from simulator");
 
#if defined(HAL_VSR_SET_TO_ECOS_HANDLER)
# if defined(CYGPRI_SER_TEST_OVERRIDE_INT_1)
HAL_VSR_SET_TO_ECOS_HANDLER(CYGPRI_SER_TEST_OVERRIDE_INT_1, NULL);
# endif
# if defined(CYGPRI_SER_TEST_OVERRIDE_INT_2)
HAL_VSR_SET_TO_ECOS_HANDLER(CYGPRI_SER_TEST_OVERRIDE_INT_2, NULL);
# endif
#endif
 
res = cyg_io_lookup(TEST_SER_DEV, handle);
if (res != ENOERR) {
CYG_TEST_FAIL_FINISH("Can't lookup " TEST_SER_DEV);
}
#else
CYG_TEST_NA(NA_MSG);
#endif
}
 
void
test_open_tty( cyg_io_handle_t* handle )
{
#if defined(CYGPKG_IO_SERIAL_TTY) && !defined(TTY_NOP_TEST)
Cyg_ErrNo res;
 
if (cyg_test_is_simulator)
CYG_TEST_NA("Cannot run from simulator");
 
#if defined(HAL_VSR_SET_TO_ECOS_HANDLER)
# if defined(CYGPRI_SER_TEST_OVERRIDE_INT_1)
HAL_VSR_SET_TO_ECOS_HANDLER(CYGPRI_SER_TEST_OVERRIDE_INT_1, NULL);
# endif
# if defined(CYGPRI_SER_TEST_OVERRIDE_INT_2)
HAL_VSR_SET_TO_ECOS_HANDLER(CYGPRI_SER_TEST_OVERRIDE_INT_2, NULL);
# endif
#endif
 
res = cyg_io_lookup(TEST_TTY_DEV, handle);
if (res != ENOERR) {
CYG_TEST_FAIL_FINISH("Can't lookup " TEST_TTY_DEV);
}
#else
CYG_TEST_NA(NA_MSG);
#endif
}
 
//---------------------------------------------------------------------------
// end of ser_test_protocol.inl
/tests/README
0,0 → 1,285
Serial Testing with ser_filter
 
Rationale
~~~~~~~~~
Since some targets only have one serial connection, a serial testing
harness needs to be able to share the connection with GDB (however,
the test and GDB can also run on separate lines).
 
The serial filter (ser_filter) sits between the serial port and GDB
and monitors the exchange of data between GDB and the
target. Normally, no changes are made to the data.
 
When a test request packet is sent from the test on the target, it is
intercepted by the filter. The filter and target then enter a loop,
exchanging protocol data between them which GDB never sees.
 
In the event of a timeout, or a crash on the target, the filter falls
back into its pass-through mode. If this happens due to a crash it
should be possible to start regular debugging with GDB. The filter
will then stay in the pass-though mode until GDB disconnects.
 
 
Adding A New Platform
~~~~~~~~~~~~~~~~~~~~~
The file ser_test_protocol.inl contains information about how to run
the serial tests on supported platforms. When adding a new serial
driver to eCos, ser_test_protocol.inl should be updated accordingly
so the driver can be tested.
 
The definitions TEST_SER_DEV and TEST_TTY_DEV are set according to
platform:
 
TEST_SER_DEV is the name of the serial device over which the serial
test protocol runs. The definition should be conditional on all
required configuration options.
 
TEST_TTY_DEV is the name of the TTY device over which the TTY test
protocol runs. The definition should be conditional on all required
configuration options. Note that this device is layered on top of a
serial device and must be conditional on that device's config
options as well as its own.
 
Here's an example for the PowerPC/Cogent where GDB is connected via
serial connector B:
#if defined(CYGPKG_HAL_POWERPC_COGENT) \
&& defined(CYGPKG_IO_SERIAL_POWERPC_COGENT) \
&& defined(CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_B)
# define TEST_SER_DEV CYGDAT_IO_SERIAL_POWERPC_COGENT_SERIAL_B_NAME
# if defined(CYGPKG_IO_SERIAL_TTY_TTY2)
# define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY2_DEV
# endif
#endif
 
On some targets it may also be necessary to intialize interrupt
vectors which are otherwise used by CygMon or an eCos GDB stub to
monitor characters from the host (looking for Control-C):
 
# define SER_OVERRIDE_INT_1 CYGNUM_HAL_INTERRUPT_9
# define SER_OVERRIDE_INT_2 CYGNUM_HAL_INTERRUPT_10
 
These definitions cause the serial test to restore the eCos handler
on the specified vectors before opening the serial device.
 
 
The file ser_test_protocol.inl also contains an array of serial
configurations (test_configs). It may be necessary to comment some of
these out for the platform if the driver or hardware cannot handle
all the given serial configurations.
 
 
The Protocol
~~~~~~~~~~~~
The protocol commands are prefixed with an @-character which the
serial filter is looking for. The protocol commands include:
 
PING
Allows the test on the target to probe for the filter. The filter
responds with OK, while GDB would just ignore the command. This
allows the tests to do nothing if they require the filter and it is
not present.
 
CONFIG
Requests a change of serial line configuration. Arguments of the
command specify baud rate, data bits, stop bits, and parity.
 
OPT
Requests changes in the filter's options. This allows various
amounts of tracing to be recorded when running tests without
requiring the filter to be restarted.
 
BINARY
Requests data to be sent from the filter to the target. The data is
checksummed, allowing errors in the transfer to be detected.
Sub-options of this command control how the data transfer is made:
 
NO_ECHO (serial driver receive test)
Just send data from the filter to the target. The test verifies
the checksum and PASS/FAIL depending on the result.
 
EOP_ECHO (serial driver half-duplex receive and send test)
As NO_ECHO but the test echoes back the data to the filter. The
filter does a checksum on the received data and sends the result
to the target. The test PASS/FAIL depending on the result of both
checksum verifications.
 
DUPLEX_ECHO (serial driver duplex receive and send test)
Smaller packets of data are sent back and forth in a pattern that
ensures that the serial driver will be both sending and receiving
at the same time. Again, checksums are computed and verified
resulting in PASS/FAIL.
 
TEXT
This is a test of the text translations in the TTY layer.
Requests a transfer of text data from the target to the filter and
possibly back again. The filter treats this as a binary transfer,
while the target may be doing translations on the data. The target
provides the filter with checksums for what it should expect to
see.
[This test is not implemented yet]
 
The above commands may be extended, and new commands added, as
required to test (new) parts of the serial drivers in eCos.
 
See ser_test_protocol.inl for further details on the protocols.
 
 
The Serial Tests
~~~~~~~~~~~~~~~~
The serial tests are built as any other eCos test. After running the
'make tests' command, the tests can be found in:
 
install/tests/io_serial/
 
serial1
A simple API test.
 
serial2
A simple serial send test. It writes out two strings, one raw and
one encoded as a GDB O-packet.
 
serial3 [requires the serial filter]
This tests the half-duplex send and receive capabilities of the
serial driver.
serial4 [requires the serial filter]
This test attempts to use a few different serial configurations,
testing the driver's configuration/setup functionality.
 
serial5 [requires the serial filter]
This tests the duplex send and receive capabilities of the serial
driver.
 
All tests should complete in less than 30 seconds.
 
 
Serial Filter Usage
~~~~~~~~~~~~~~~~~~~
Running the ser_filter program with no (or wrong) arguments results
in the below output:
 
Usage: ser_filter [-t -c -g -S] TcpIPport SerialPort BaudRate
or: ser_filter -n [-t -c -g -S] SerialPort BaudRate
-t: Enable tracing.
-f: Enable filter output tracing.
-g: Enable GDB tracing.
-S: Output data read from serial line.
-c: Output data on console instead of via GDB.
-n: No GDB.
 
The normal way to use it with GDB is to start the filter:
 
ser_filter -t 9000 com1 38400
 
In this case, the filter will be listening on port 9000 and connect
to the target via the serial port COM1 at 38400 baud. On a UNIX host,
replace "com1" with a device such as "/dev/ttyS0".
 
The '-t' option enables tracing which will cause the filter to
describe its actions on the console.
 
Now start GDB with one of the tests as an argument:
 
$ mips-tx39-elf-gdb -nw install/tests/io_serial/serial3
Then connect to the filter:
 
(gdb) target remote localhost:9000
 
This should result in a connection in exactly the same way as if you
had connected directly to the target on the serial line.
 
(gdb) load
...
(gdb) cont
 
Which should result in output similar to the below:
 
Continuing.
INFO:<BINARY:16:1!>
PASS:<Binary test completed>
INFO:<BINARY:128:1!>
PASS:<Binary test completed>
INFO:<BINARY:256:1!>
PASS:<Binary test completed>
INFO:<BINARY:1024:1!>
PASS:<Binary test completed>
INFO:<BINARY:512:0!>
PASS:<Binary test completed>
...
PASS:<Binary test completed>
INFO:<BINARY:16384:0!>
PASS:<Binary test completed>
PASS:<serial3 test OK>
EXIT:<done>
 
If any of the individual tests fail the testing will terminate with
a FAIL.
 
With tracing enabled, you would also see the filter's status output:
 
The PING command sent from the target to determine the presence of
the filter:
[400 11:35:16] Dispatching command PING
[400 11:35:16] Responding with status OK
 
Each of the binary commands result in output similar to:
[400 11:35:16] Dispatching command BINARY
[400 11:35:16] Binary data (Size:16, Flags:1).
[400 11:35:16] Sending CRC: '170231!', len: 7.
[400 11:35:16] Reading 16 bytes from target.
[400 11:35:16] Done. in_crc 170231, out_crc 170231.
[400 11:35:16] Responding with status OK
[400 11:35:16] Received DONE from target.
 
This tracing output is normally sent as O-packets to GDB which will
display the tracing text. By using the -c option, the tracing text
can be redirected to the console from which ser_filter was started.
 
 
The trace options -f, -g, and -S cause data sent from filter, GDB or
target to be output in hexadecimal form.
 
 
A Note on Failures
~~~~~~~~~~~~~~~~~~
A serial connection (especially when driven at a high baud rate) can
garble the transmitted data because of noise from the environment. It
is not the job of the serial driver to ensure data integrity - that
is the job of protocols layering on top of the serial driver.
 
In the current implementation the serial tests and the serial filter
are not resilient to such data errors. This means that the test may
crash or hang (possibly without reporting a FAIL). It also means that
you should be aware of random errors - a FAIL is not necessarily
caused by a bug in the serial driver.
 
Ideally, the serial testing infrastructure should be able to
distinguish random errors from consistent errors - the former are
most likely due to noise in the transfer medium, while the latter are
more likely to be caused by faulty drivers. The current
implementation of the infrastructure does not have this capability.
 
 
Debugging
~~~~~~~~~
If a test fails, the serial filter's output may provide some hints
about what the problem is. If the option '-S' is used when starting
the filter, data received from the target is printed out:
 
[400 11:35:16] 0000 50 41 53 53 3a 3c 42 69 'PASS:<Bi'
[400 11:35:16] 0008 6e 61 72 79 20 74 65 73 'nary.tes'
[400 11:35:16] 0010 74 20 63 6f 6d 70 6c 65 't.comple'
[400 11:35:16] 0018 74 65 64 3e 0d 0a 49 4e 'ted>..IN'
[400 11:35:16] 0020 46 4f 3a 3c 42 49 4e 41 'FO:<BINA'
[400 11:35:16] 0028 52 59 3a 31 32 38 3a 31 'RY:128:1'
[400 11:35:16] 0030 21 3e 0d 0a 40 42 49 4e '!>..@BIN'
[400 11:35:16] 0038 41 52 59 3a 31 32 38 3a 'ARY:128:'
[400 11:35:16] 0040 31 21 .. .. .. .. .. .. '1!'
 
In the case of an error during a testing command the data received by
the filter will be printed out, as will the data that was
expected. This allows the two data sets to be compared which may give
some idea of what the problem is.
/tests/serial_echo.c
0,0 → 1,127
//==========================================================================
//
// serial_echo.c
//
// Simple interactive echo test.
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): jskov
// Contributors: jskov
// Date: 2000-04-11
// Description: Simple echo test.
//
//####DESCRIPTIONEND####
 
#include <pkgconf/system.h>
 
#include <cyg/infra/testcase.h> // test macros
#include <cyg/infra/cyg_ass.h> // assertion macros
 
// Package requirements
#if defined(CYGPKG_IO_SERIAL) && defined(CYGPKG_KERNEL)
 
#include <pkgconf/kernel.h>
 
// Package option requirements
#if defined(CYGFUN_KERNEL_API_C)
 
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
#include <cyg/kernel/kapi.h>
unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
cyg_thread thread_data;
cyg_handle_t thread_handle;
 
#include "ser_test_protocol.inl"
 
//---------------------------------------------------------------------------
// Serial test main function.
void
serial_test( void )
{
cyg_io_handle_t ser_handle;
cyg_uint8 in_buffer[1];
int len = 1;
 
test_open_ser(&ser_handle);
 
CYG_TEST_INFO("Kill GDB and open a terminal emulator.");
CYG_TEST_INFO("This test will echo all data.");
 
while (1) {
len = 1;
Tcyg_io_read(ser_handle, in_buffer, &len);
len = 1;
Tcyg_io_write(ser_handle, in_buffer, &len);
}
 
}
 
void
cyg_start(void)
{
CYG_TEST_INIT();
cyg_thread_create(10, // Priority - just a number
(cyg_thread_entry_t*)serial_test, // entry
0, //
"serial_thread", // Name
&stack[0], // Stack
CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size
&thread_handle, // Handle
&thread_data // Thread data structure
);
cyg_thread_resume(thread_handle);
cyg_scheduler_start();
}
 
#else // CYGFUN_KERNEL_API_C
#define N_A_MSG "Needs kernel C API"
#endif
 
#else // CYGPKG_IO_SERIAL && CYGPKG_KERNEL
#define N_A_MSG "Needs IO/serial and Kernel"
#endif
 
#ifdef N_A_MSG
void
cyg_start( void )
{
CYG_TEST_INIT();
CYG_TEST_NA( N_A_MSG);
}
#endif // N_A_MSG
// EOF serial3.c
/include/serial.h
0,0 → 1,276
#ifndef CYGONCE_SERIAL_H
#define CYGONCE_SERIAL_H
// ====================================================================
//
// serial.h
//
// Device I/O
//
// ====================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
// ====================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): gthomas
// Contributors: gthomas
// Date: 1999-02-04
// Purpose: Internal interfaces for serial I/O drivers
// Description:
//
//####DESCRIPTIONEND####
//
// ====================================================================
 
// Serial I/O interfaces
 
#include <pkgconf/system.h>
#include <pkgconf/io_serial.h>
 
#include <cyg/infra/cyg_type.h>
#include <cyg/io/io.h>
#include <cyg/io/serialio.h>
#include <cyg/hal/drv_api.h>
 
#ifdef CYGPKG_IO_SERIAL_SELECT_SUPPORT
#include <cyg/fileio/fileio.h>
#endif
 
typedef struct serial_channel serial_channel;
typedef struct serial_funs serial_funs;
 
// The block transfer request functions may fail for one of two
// reasons. It's important for the caller to know which.
typedef enum {
CYG_RCV_OK,
CYG_RCV_FULL,
CYG_RCV_DISABLED
} rcv_req_reply_t;
 
typedef enum {
CYG_XMT_OK,
CYG_XMT_EMPTY,
CYG_XMT_DISABLED
} xmt_req_reply_t;
 
// Pointers into upper-level driver which interrupt handlers need
typedef struct {
// Initialize the channel
void (*serial_init)(serial_channel *chan);
// Cause an additional character to be output if one is available
void (*xmt_char)(serial_channel *chan);
// Consume an input character
void (*rcv_char)(serial_channel *chan, unsigned char c);
#if CYGINT_IO_SERIAL_BLOCK_TRANSFER
// Request space for input characters
rcv_req_reply_t (*data_rcv_req)(serial_channel *chan, int avail,
int* space_avail, unsigned char** space);
// Receive operation completed
void (*data_rcv_done)(serial_channel *chan, int chars_rcvd);
// Request characters for transmission
xmt_req_reply_t (*data_xmt_req)(serial_channel *chan, int space,
int* chars_avail, unsigned char** chars);
// Transmit operation completed
void (*data_xmt_done)(serial_channel *chan, int chars_sent);
#endif
#if defined(CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS)
void (*indicate_status)(serial_channel *chan, cyg_serial_line_status_t *s );
#endif
} serial_callbacks_t;
 
#if CYGINT_IO_SERIAL_BLOCK_TRANSFER
# ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
# define SERIAL_CALLBACKS(_l,_init,_xmt_char,_rcv_char, _data_rcv_req, _data_rcv_done, _data_xmt_req, _data_xmt_done, _indicate_status) \
serial_callbacks_t _l = { \
_init, \
_xmt_char, \
_rcv_char, \
_data_rcv_req, \
_data_rcv_done, \
_data_xmt_req, \
_data_xmt_done, \
_indicate_status \
};
# else
# define SERIAL_CALLBACKS(_l,_init,_xmt_char,_rcv_char, _data_rcv_req, _data_rcv_done, _data_xmt_req, _data_xmt_done) \
serial_callbacks_t _l = { \
_init, \
_xmt_char, \
_rcv_char, \
_data_rcv_req, \
_data_rcv_done, \
_data_xmt_req, \
_data_xmt_done \
};
# endif
#else
# ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
# define SERIAL_CALLBACKS(_l,_init,_xmt_char,_rcv_char,_indicate_status) \
serial_callbacks_t _l = { \
_init, \
_xmt_char, \
_rcv_char, \
_indicate_status \
};
# else
# define SERIAL_CALLBACKS(_l,_init,_xmt_char,_rcv_char) \
serial_callbacks_t _l = { \
_init, \
_xmt_char, \
_rcv_char \
};
# endif
#endif
 
extern serial_callbacks_t cyg_io_serial_callbacks;
 
typedef struct {
unsigned char *data;
volatile int put;
volatile int get;
int len;
volatile int nb; // count of bytes currently in buffer
int low_water; // For tx: min space in buffer before restart
// For rx: max buffer used before flow unthrottled
#ifdef CYGPKG_IO_SERIAL_FLOW_CONTROL
int high_water; // For tx: unused
// For rx: min buffer used before throttle
#endif
cyg_drv_cond_t wait;
cyg_drv_mutex_t lock;
bool waiting;
#ifdef CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
bool blocking;
#endif
volatile bool abort; // Set by an outsider to kill processing
volatile cyg_int32 pending; // This many bytes waiting to be sent
#ifdef CYGPKG_IO_SERIAL_SELECT_SUPPORT
struct CYG_SELINFO_TAG selinfo; // select info
#endif
 
#ifdef CYGDBG_USE_ASSERTS
#ifdef CYGINT_IO_SERIAL_BLOCK_TRANSFER
bool block_mode_xfer_running;
#endif // CYGINT_IO_SERIAL_BLOCK_TRANSFER
#endif // CYGDBG_USE_ASSERTS
} cbuf_t;
 
#define CBUF_INIT(_data, _len) \
{_data, 0, 0, _len}
 
#ifdef CYGPKG_IO_SERIAL_FLOW_CONTROL
typedef struct {
cyg_uint32 flags;
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE
cyg_uint8 xchar;
#endif
} flow_desc_t;
#endif
 
// Private data which describes this channel
struct serial_channel {
serial_funs *funs;
serial_callbacks_t *callbacks;
void *dev_priv; // Whatever is needed by actual device routines
cyg_serial_info_t config; // Current configuration
bool init;
cbuf_t out_cbuf;
cbuf_t in_cbuf;
#ifdef CYGPKG_IO_SERIAL_FLOW_CONTROL
flow_desc_t flow_desc;
#endif
#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
cyg_serial_line_status_callback_fn_t status_callback;
CYG_ADDRWORD status_callback_priv;
#endif
};
 
// Flow descriptor flag values
#define CYG_SERIAL_FLOW_OUT_THROTTLED (1<<0)
#define CYG_SERIAL_FLOW_IN_THROTTLED (1<<1)
 
// Initialization macro for serial channel
#define SERIAL_CHANNEL(_l, \
_funs, \
_dev_priv, \
_baud, _stop, _parity, _word_length, _flags) \
serial_channel _l = { \
&_funs, \
&cyg_io_serial_callbacks, \
&(_dev_priv), \
CYG_SERIAL_INFO_INIT(_baud, _stop, _parity, _word_length, _flags), \
};
 
#define SERIAL_CHANNEL_USING_INTERRUPTS(_l, \
_funs, \
_dev_priv, \
_baud, _stop, _parity, _word_length, _flags, \
_out_buf, _out_buflen, \
_in_buf, _in_buflen) \
serial_channel _l = { \
&_funs, \
&cyg_io_serial_callbacks, \
&(_dev_priv), \
CYG_SERIAL_INFO_INIT(_baud, _stop, _parity, _word_length, _flags), \
false, \
CBUF_INIT(_out_buf, _out_buflen), \
CBUF_INIT(_in_buf, _in_buflen) \
};
 
// Low level interface functions
struct serial_funs {
// Send one character to the output device, return true if consumed
bool (*putc)(serial_channel *priv, unsigned char c);
// Fetch one character from the device
unsigned char (*getc)(serial_channel *priv);
// Change hardware configuration (baud rate, etc)
Cyg_ErrNo (*set_config)(serial_channel *priv, cyg_uint32 key, const void *xbuf,
cyg_uint32 *len);
// Enable the transmit channel and turn on transmit interrupts
void (*start_xmit)(serial_channel *priv);
// Disable the transmit channel and turn transmit interrupts off
void (*stop_xmit)(serial_channel *priv);
};
 
#define SERIAL_FUNS(_l,_putc,_getc,_set_config,_start_xmit,_stop_xmit) \
serial_funs _l = { \
_putc, \
_getc, \
_set_config, \
_start_xmit, \
_stop_xmit \
};
 
extern cyg_devio_table_t cyg_io_serial_devio;
 
#endif // CYGONCE_SERIAL_H
/include/serialio.h
0,0 → 1,210
#ifndef CYGONCE_SERIALIO_H
#define CYGONCE_SERIALIO_H
// ====================================================================
//
// serialio.h
//
// Device I/O
//
// ====================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
// ====================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): gthomas
// Contributors: gthomas
// Date: 1999-02-04
// Purpose: Special support for serial I/O devices
// Description:
//
//####DESCRIPTIONEND####
//
// ====================================================================
 
// This file contains the user-level visible I/O interfaces
 
#include <pkgconf/hal.h>
#include <cyg/infra/cyg_type.h>
#include <cyg/io/config_keys.h>
 
#ifdef __cplusplus
extern "C" {
#endif
 
// Supported baud rates
typedef enum {
CYGNUM_SERIAL_BAUD_50 = 1,
CYGNUM_SERIAL_BAUD_75,
CYGNUM_SERIAL_BAUD_110,
CYGNUM_SERIAL_BAUD_134_5,
CYGNUM_SERIAL_BAUD_150,
CYGNUM_SERIAL_BAUD_200,
CYGNUM_SERIAL_BAUD_300,
CYGNUM_SERIAL_BAUD_600,
CYGNUM_SERIAL_BAUD_1200,
CYGNUM_SERIAL_BAUD_1800,
CYGNUM_SERIAL_BAUD_2400,
CYGNUM_SERIAL_BAUD_3600,
CYGNUM_SERIAL_BAUD_4800,
CYGNUM_SERIAL_BAUD_7200,
CYGNUM_SERIAL_BAUD_9600,
CYGNUM_SERIAL_BAUD_14400,
CYGNUM_SERIAL_BAUD_19200,
CYGNUM_SERIAL_BAUD_38400,
CYGNUM_SERIAL_BAUD_57600,
CYGNUM_SERIAL_BAUD_115200,
CYGNUM_SERIAL_BAUD_230400
} cyg_serial_baud_rate_t;
#define CYGNUM_SERIAL_BAUD_MIN CYGNUM_SERIAL_BAUD_50
#define CYGNUM_SERIAL_BAUD_MAX CYGNUM_SERIAL_BAUD_230400
 
// Note: two levels of macro are required to get proper expansion.
#define _CYG_SERIAL_BAUD_RATE(n) CYGNUM_SERIAL_BAUD_##n
#define CYG_SERIAL_BAUD_RATE(n) _CYG_SERIAL_BAUD_RATE(n)
 
// Stop bit selections
typedef enum {
CYGNUM_SERIAL_STOP_1 = 1,
CYGNUM_SERIAL_STOP_1_5,
CYGNUM_SERIAL_STOP_2
} cyg_serial_stop_bits_t;
 
// Parity modes
typedef enum {
CYGNUM_SERIAL_PARITY_NONE = 0,
CYGNUM_SERIAL_PARITY_EVEN,
CYGNUM_SERIAL_PARITY_ODD,
CYGNUM_SERIAL_PARITY_MARK,
CYGNUM_SERIAL_PARITY_SPACE
} cyg_serial_parity_t;
 
// Word length
typedef enum {
CYGNUM_SERIAL_WORD_LENGTH_5 = 5,
CYGNUM_SERIAL_WORD_LENGTH_6,
CYGNUM_SERIAL_WORD_LENGTH_7,
CYGNUM_SERIAL_WORD_LENGTH_8
} cyg_serial_word_length_t;
 
typedef struct {
cyg_serial_baud_rate_t baud;
cyg_serial_stop_bits_t stop;
cyg_serial_parity_t parity;
cyg_serial_word_length_t word_length;
cyg_uint32 flags;
} cyg_serial_info_t;
 
// cyg_serial_info_t flags
#define CYGNUM_SERIAL_FLOW_NONE (0)
// receive flow control, send xon/xoff when necessary:
#define CYGNUM_SERIAL_FLOW_XONXOFF_RX (1<<0)
// transmit flow control, act on received xon/xoff:
#define CYGNUM_SERIAL_FLOW_XONXOFF_TX (1<<1)
// receive flow control, send RTS when necessary:
#define CYGNUM_SERIAL_FLOW_RTSCTS_RX (1<<2)
// transmit flow control, act when not CTS:
#define CYGNUM_SERIAL_FLOW_RTSCTS_TX (1<<3)
// receive flow control, send DTR when necessary:
#define CYGNUM_SERIAL_FLOW_DSRDTR_RX (1<<4)
// transmit flow control, act when not DSR:
#define CYGNUM_SERIAL_FLOW_DSRDTR_TX (1<<5)
 
// arguments for CYG_IO_SET_CONFIG_SERIAL_FLOW_CONTROL_FORCE
#define CYGNUM_SERIAL_FLOW_THROTTLE_RX 0
#define CYGNUM_SERIAL_FLOW_RESTART_RX 1
#define CYGNUM_SERIAL_FLOW_THROTTLE_TX 2
#define CYGNUM_SERIAL_FLOW_RESTART_TX 3
 
// arguments for CYG_IO_SET_CONFIG_SERIAL_HW_RX_FLOW_THROTTLE
#define CYGNUM_SERIAL_FLOW_HW_UNTHROTTLE 0
#define CYGNUM_SERIAL_FLOW_HW_THROTTLE 0
#define CYGNUM_SERIAL_FLOW_HW_UNTHROTTLE 0
 
typedef struct {
cyg_int32 rx_bufsize;
cyg_int32 rx_count;
cyg_int32 tx_bufsize;
cyg_int32 tx_count;
} cyg_serial_buf_info_t;
 
#define CYG_SERIAL_INFO_INIT(_baud,_stop,_parity,_word_length,_flags) \
{ _baud, _stop, _parity, _word_length, _flags}
 
#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
 
# define CYGNUM_SERIAL_STATUS_FLOW 0
# define CYGNUM_SERIAL_STATUS_BREAK 1
# define CYGNUM_SERIAL_STATUS_FRAMEERR 2
# define CYGNUM_SERIAL_STATUS_PARITYERR 3
# define CYGNUM_SERIAL_STATUS_OVERRUNERR 4
# define CYGNUM_SERIAL_STATUS_CARRIERDETECT 5
# define CYGNUM_SERIAL_STATUS_RINGINDICATOR 6
 
typedef struct {
cyg_uint32 which; // one of CYGNUM_SERIAL_STATUS_* above
cyg_uint32 value; // and its value
} cyg_serial_line_status_t;
 
typedef void (*cyg_serial_line_status_callback_fn_t)(
cyg_serial_line_status_t *s,
CYG_ADDRWORD priv );
typedef struct {
cyg_serial_line_status_callback_fn_t fn;
CYG_ADDRWORD priv;
} cyg_serial_line_status_callback_t;
 
#endif // ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
 
// Default configuration
#define CYG_SERIAL_BAUD_DEFAULT CYGNUM_SERIAL_BAUD_38400
#define CYG_SERIAL_STOP_DEFAULT CYGNUM_SERIAL_STOP_1
#define CYG_SERIAL_PARITY_DEFAULT CYGNUM_SERIAL_PARITY_NONE
#define CYG_SERIAL_WORD_LENGTH_DEFAULT CYGNUM_SERIAL_WORD_LENGTH_8
 
#ifdef CYGDAT_IO_SERIAL_FLOW_CONTROL_DEFAULT_XONXOFF
# define CYG_SERIAL_FLAGS_DEFAULT (CYGNUM_SERIAL_FLOW_XONXOFF_RX|CYGNUM_SERIAL_FLOW_XONXOFF_TX)
#elif defined(CYGDAT_IO_SERIAL_FLOW_CONTROL_DEFAULT_RTSCTS)
# define CYG_SERIAL_FLAGS_DEFAULT (CYGNUM_SERIAL_FLOW_RTSCTS_RX|CYGNUM_SERIAL_FLOW_RTSCTS_TX)
#elif defined(CYGDAT_IO_SERIAL_FLOW_CONTROL_DEFAULT_DSRDTR)
# define CYG_SERIAL_FLAGS_DEFAULT (CYGNUM_SERIAL_FLOW_DSRDTR_RX|CYGNUM_SERIAL_FLOW_DSRDTR_TX)
#else
# define CYG_SERIAL_FLAGS_DEFAULT 0
#endif
 
#ifdef __cplusplus
}
#endif
 
#endif /* CYGONCE_SERIALIO_H */
/* EOF serialio.h */
/include/ttyio.h
0,0 → 1,89
#ifndef CYGONCE_TTYIO_H
#define CYGONCE_TTYIO_H
// ====================================================================
//
// ttyio.h
//
// Device I/O
//
// ====================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
// ====================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): gthomas
// Contributors: gthomas
// Date: 1999-02-04
// Purpose: Special support for tty I/O devices
// Description:
//
//####DESCRIPTIONEND####
//
// ====================================================================
 
// This file contains the user-level visible I/O interfaces
 
#include <pkgconf/hal.h>
#include <cyg/infra/cyg_type.h>
#include <cyg/io/serialio.h>
#include <cyg/io/config_keys.h>
 
#ifdef __cplusplus
extern "C" {
#endif
 
typedef struct {
cyg_uint32 tty_out_flags;
cyg_uint32 tty_in_flags;
} cyg_tty_info_t;
 
// TTY flags - used to control behaviour when sending data to tty
#define CYG_TTY_OUT_FLAGS_CRLF 0x0001 // Map '\n' => '\r\n' on output
 
#define CYG_TTY_OUT_FLAGS_DEFAULT (CYG_TTY_OUT_FLAGS_CRLF)
 
// TTY flags - used to control behaviour when receiving data from tty
#define CYG_TTY_IN_FLAGS_CR 0x0001 // Map '\r' => '\n' on input
#define CYG_TTY_IN_FLAGS_CRLF 0x0002 // Map '\r\n' => '\n' on input
#define CYG_TTY_IN_FLAGS_ECHO 0x0004 // Echo characters as processed
#define CYG_TTY_IN_FLAGS_BINARY 0x0008 // No input processing
 
#define CYG_TTY_IN_FLAGS_DEFAULT (CYG_TTY_IN_FLAGS_CR|CYG_TTY_IN_FLAGS_ECHO)
 
#ifdef __cplusplus
}
#endif
 
#endif /* CYGONCE_TTYIO_H */
/* EOF ttyio.h */
/src/common/serial.c
0,0 → 1,1175
//==========================================================================
//
// io/serial/common/serial.c
//
// High level serial driver
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): gthomas
// Contributors: gthomas, grante, jlarmour, jskov
// Date: 1999-02-04
// Purpose: Top level serial driver
// Description:
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
#include <pkgconf/io.h>
#include <pkgconf/io_serial.h>
 
#include <cyg/io/io.h>
#include <cyg/io/devtab.h>
#include <cyg/io/serial.h>
#include <cyg/infra/cyg_ass.h> // assertion support
#include <cyg/infra/diag.h> // diagnostic output
 
static Cyg_ErrNo serial_write(cyg_io_handle_t handle, const void *buf, cyg_uint32 *len);
static Cyg_ErrNo serial_read(cyg_io_handle_t handle, void *buf, cyg_uint32 *len);
static Cyg_ErrNo serial_select(cyg_io_handle_t handle, cyg_uint32 which, CYG_ADDRWORD info);
static Cyg_ErrNo serial_get_config(cyg_io_handle_t handle, cyg_uint32 key, void *buf, cyg_uint32 *len);
static Cyg_ErrNo serial_set_config(cyg_io_handle_t handle, cyg_uint32 key, const void *buf, cyg_uint32 *len);
 
DEVIO_TABLE(cyg_io_serial_devio,
serial_write,
serial_read,
serial_select,
serial_get_config,
serial_set_config
);
 
static void serial_init(serial_channel *chan);
static void serial_xmt_char(serial_channel *chan);
static void serial_rcv_char(serial_channel *chan, unsigned char c);
#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
static void serial_indicate_status(serial_channel *chan,
cyg_serial_line_status_t *s);
#endif
#if CYGINT_IO_SERIAL_BLOCK_TRANSFER
static rcv_req_reply_t serial_data_rcv_req(serial_channel *chan, int avail,
int* space_avail,
unsigned char** space);
static void serial_data_rcv_done(serial_channel *chan, int chars_rcvd);
static xmt_req_reply_t serial_data_xmt_req(serial_channel *chan, int space,
int* chars_avail,
unsigned char** chars);
static void serial_data_xmt_done(serial_channel *chan, int chars_sent);
# ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
SERIAL_CALLBACKS(cyg_io_serial_callbacks,
serial_init,
serial_xmt_char,
serial_rcv_char,
serial_data_rcv_req,
serial_data_rcv_done,
serial_data_xmt_req,
serial_data_xmt_done,
serial_indicate_status);
 
# else
SERIAL_CALLBACKS(cyg_io_serial_callbacks,
serial_init,
serial_xmt_char,
serial_rcv_char,
serial_data_rcv_req,
serial_data_rcv_done,
serial_data_xmt_req,
serial_data_xmt_done);
# endif
#else
# ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
SERIAL_CALLBACKS(cyg_io_serial_callbacks,
serial_init,
serial_xmt_char,
serial_rcv_char,
serial_indicate_status);
# else
SERIAL_CALLBACKS(cyg_io_serial_callbacks,
serial_init,
serial_xmt_char,
serial_rcv_char);
# endif
#endif
 
// ---------------------------------------------------------------------------
 
#ifdef CYGPKG_IO_SERIAL_FLOW_CONTROL
 
static __inline__ void
throttle_tx( serial_channel *chan )
{
chan->flow_desc.flags |= CYG_SERIAL_FLOW_OUT_THROTTLED;
// the throttling itself occurs in the serial_xmt_char() callback
}
 
static __inline__ void
restart_tx( serial_channel *chan )
{
serial_funs *funs = chan->funs;
 
chan->flow_desc.flags &= ~CYG_SERIAL_FLOW_OUT_THROTTLED;
 
#ifdef CYGPKG_IO_SERIAL_SELECT_SUPPORT
// See if there is now enough room to say it is available
// for writing
{
cbuf_t *cbuf = &chan->out_cbuf;
int space;
space = cbuf->len - cbuf->nb;
if (space >= cbuf->low_water)
cyg_selwakeup( &cbuf->selinfo );
}
#endif
if ( chan->out_cbuf.nb > 0 )
(funs->start_xmit)(chan);
}
 
static __inline__ void
throttle_rx( serial_channel *chan, cyg_bool force )
{
serial_funs *funs = chan->funs;
 
chan->flow_desc.flags |= CYG_SERIAL_FLOW_IN_THROTTLED;
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE
// send an xoff
if ( force || chan->config.flags & CYGNUM_SERIAL_FLOW_XONXOFF_RX ) {
chan->flow_desc.xchar = CYGDAT_IO_SERIAL_FLOW_CONTROL_XOFF_CHAR;
// Make sure xmit is running so we can send it
(funs->start_xmit)(chan);
}
#endif
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW
{
cyg_uint32 i=1;
cyg_uint32 len = sizeof(i);
// set hardware flow control - don't care if it fails
if ( force || (chan->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_RX) ||
(chan->config.flags & CYGNUM_SERIAL_FLOW_DSRDTR_RX) )
(funs->set_config)(chan,
CYG_IO_SET_CONFIG_SERIAL_HW_RX_FLOW_THROTTLE,
&i, &len);
}
#endif
}
 
static __inline__ void
restart_rx( serial_channel *chan, cyg_bool force )
{
serial_funs *funs = chan->funs;
 
chan->flow_desc.flags &= ~CYG_SERIAL_FLOW_IN_THROTTLED;
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE
// send an xon
if ( force || chan->config.flags & CYGNUM_SERIAL_FLOW_XONXOFF_RX ) {
chan->flow_desc.xchar = CYGDAT_IO_SERIAL_FLOW_CONTROL_XON_CHAR;
(funs->start_xmit)(chan); // Make sure xmit is running so we can send it
}
#endif
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW
{
cyg_uint32 i=0;
cyg_uint32 len = sizeof(i);
// set hardware flow control - don't care if it fails
if ( force || (chan->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_RX) ||
(chan->config.flags & CYGNUM_SERIAL_FLOW_DSRDTR_RX) )
(funs->set_config)(chan,
CYG_IO_SET_CONFIG_SERIAL_HW_RX_FLOW_THROTTLE,
&i, &len);
}
#endif
}
 
#endif
 
// ---------------------------------------------------------------------------
 
static void
serial_init(serial_channel *chan)
{
if (chan->init) return;
if (chan->out_cbuf.len != 0) {
#ifdef CYGDBG_IO_INIT
diag_printf("Set output buffer - buf: %x len: %d\n", chan->out_cbuf.data, chan->out_cbuf.len);
#endif
chan->out_cbuf.waiting = false;
chan->out_cbuf.abort = false;
#ifdef CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
chan->out_cbuf.blocking = true;
#endif
chan->out_cbuf.pending = 0;
cyg_drv_mutex_init(&chan->out_cbuf.lock);
cyg_drv_cond_init(&chan->out_cbuf.wait, &chan->out_cbuf.lock);
chan->out_cbuf.low_water = chan->out_cbuf.len / 4;
#ifdef CYGPKG_IO_SERIAL_SELECT_SUPPORT
cyg_selinit( &chan->out_cbuf.selinfo );
#endif
}
if (chan->in_cbuf.len != 0) {
cbuf_t *cbuf = &chan->in_cbuf;
 
#ifdef CYGDBG_IO_INIT
diag_printf("Set input buffer - buf: %x len: %d\n", cbuf->data, cbuf->len);
#endif
cbuf->waiting = false;
cbuf->abort = false;
#ifdef CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
cbuf->blocking = true;
#endif
#ifdef CYGPKG_IO_SERIAL_SELECT_SUPPORT
cyg_selinit( &cbuf->selinfo );
#endif
#ifdef CYGPKG_IO_SERIAL_FLOW_CONTROL
cbuf->low_water =
(CYGNUM_IO_SERIAL_FLOW_CONTROL_LOW_WATER_PERCENT * cbuf->len) / 100;
cbuf->high_water =
(CYGNUM_IO_SERIAL_FLOW_CONTROL_HIGH_WATER_PERCENT * cbuf->len) / 100;
# ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE
// But make sure it is at least 35 below buffer size, to allow
// for 16 byte fifos, twice, plus some latency before s/w flow
// control can kick in. This doesn't apply to h/w flow control
// as it is near-instaneous
if ( (cbuf->len - cbuf->high_water) < 35 )
cbuf->high_water = cbuf->len - 35;
// and just in case...
if ( cbuf->high_water <= 0 )
cbuf->high_water = 1;
if ( cbuf->low_water > cbuf->high_water )
cbuf->low_water = cbuf->high_water;
# endif
#endif
cyg_drv_mutex_init(&cbuf->lock);
cyg_drv_cond_init(&cbuf->wait, &cbuf->lock);
}
#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
chan->status_callback = NULL;
#endif
 
#ifdef CYGDBG_USE_ASSERTS
#if CYGINT_IO_SERIAL_BLOCK_TRANSFER
chan->in_cbuf.block_mode_xfer_running = false;
chan->out_cbuf.block_mode_xfer_running = false;
#endif // CYGINT_IO_SERIAL_BLOCK_TRANSFER
#endif // CYGDBG_USE_ASSERTS
chan->init = true;
}
 
// ---------------------------------------------------------------------------
// FIXME:@@@ Throughout this file there are uses of cyg_drv_cond_signal and
// cyg_drv_cond_broadcast. Does it matter which? -Jifl
 
static Cyg_ErrNo
serial_write(cyg_io_handle_t handle, const void *_buf, cyg_uint32 *len)
{
cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
serial_channel *chan = (serial_channel *)t->priv;
serial_funs *funs = chan->funs;
cyg_int32 size = *len;
cyg_uint8 *buf = (cyg_uint8 *)_buf;
int next;
cbuf_t *cbuf = &chan->out_cbuf;
Cyg_ErrNo res = ENOERR;
 
cyg_drv_mutex_lock(&cbuf->lock);
cbuf->abort = false;
 
if (cbuf->len == 0) {
// Non interrupt driven (i.e. polled) operation
while (size-- > 0) {
#ifdef CYGPKG_IO_SERIAL_FLOW_CONTROL
while ( ( 0 == (chan->flow_desc.flags & CYG_SERIAL_FLOW_OUT_THROTTLED) ) &&
((funs->putc)(chan, *buf) == false) )
; // Ignore full, keep trying
#else
while ((funs->putc)(chan, *buf) == false)
; // Ignore full, keep trying
#endif
buf++;
}
} else {
cyg_drv_dsr_lock(); // Avoid race condition testing pointers
while (size > 0) {
next = cbuf->put + 1;
if (next == cbuf->len) next = 0;
if (cbuf->nb == cbuf->len) {
cbuf->waiting = true;
// Buffer full - wait for space
#ifdef CYGPKG_IO_SERIAL_FLOW_CONTROL
if ( 0 == (chan->flow_desc.flags & CYG_SERIAL_FLOW_OUT_THROTTLED) )
#endif
(funs->start_xmit)(chan); // Make sure xmit is running
 
// Check flag: 'start_xmit' may have obviated the need
// to wait :-)
if (cbuf->waiting) {
#ifdef CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
// Optionally return if configured for non-blocking mode.
if (!cbuf->blocking) {
*len -= size; // number of characters actually sent
cbuf->waiting = false;
res = -EAGAIN;
break;
}
#endif // CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
cbuf->pending += size; // Have this much more to send [eventually]
if( !cyg_drv_cond_wait(&cbuf->wait) )
cbuf->abort = true;
cbuf->pending -= size;
}
if (cbuf->abort) {
// Give up!
*len -= size; // number of characters actually sent
cbuf->abort = false;
cbuf->waiting = false;
res = -EINTR;
break;
}
} else {
cbuf->data[cbuf->put++] = *buf++;
cbuf->put = next;
cbuf->nb++;
size--; // Only count if actually sent!
}
}
#ifdef CYGPKG_IO_SERIAL_FLOW_CONTROL
if ( 0 == (chan->flow_desc.flags & CYG_SERIAL_FLOW_OUT_THROTTLED) )
#endif
(funs->start_xmit)(chan); // Start output as necessary
cyg_drv_dsr_unlock();
}
cyg_drv_mutex_unlock(&cbuf->lock);
return res;
}
 
 
// ---------------------------------------------------------------------------
 
static Cyg_ErrNo
serial_read(cyg_io_handle_t handle, void *_buf, cyg_uint32 *len)
{
cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
serial_channel *chan = (serial_channel *)t->priv;
serial_funs *funs = chan->funs;
cyg_uint8 *buf = (cyg_uint8 *)_buf;
cyg_int32 size = 0;
cbuf_t *cbuf = &chan->in_cbuf;
Cyg_ErrNo res = ENOERR;
#ifdef XX_CYGDBG_DIAG_BUF
extern int enable_diag_uart;
int _enable = enable_diag_uart;
int _time, _stime;
externC cyg_tick_count_t cyg_current_time(void);
#endif // CYGDBG_DIAG_BUF
 
cyg_drv_mutex_lock(&cbuf->lock);
cbuf->abort = false;
 
if (cbuf->len == 0) {
// Non interrupt driven (i.e. polled) operation
while (size++ < *len) {
cyg_uint8 c = (funs->getc)(chan);
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE
// for software flow control, if the driver returns one of the
// characters we act on it and then drop it (the app must not
// see it)
if ( chan->config.flags & CYGNUM_SERIAL_FLOW_XONXOFF_TX ) {
if ( c == CYGDAT_IO_SERIAL_FLOW_CONTROL_XOFF_CHAR ) {
throttle_tx( chan );
} else if ( c == CYGDAT_IO_SERIAL_FLOW_CONTROL_XON_CHAR ) {
restart_tx( chan );
}
else
*buf++ = c;
}
else
*buf++ = c;
#else
*buf++ = c;
#endif
}
} else {
cyg_drv_dsr_lock(); // Avoid races
while (size < *len) {
if (cbuf->nb > 0) {
#ifdef CYGPKG_IO_SERIAL_FLOW_CONTROL
if ( (cbuf->nb <= cbuf->low_water) &&
(chan->flow_desc.flags & CYG_SERIAL_FLOW_IN_THROTTLED) )
restart_rx( chan, false );
#endif
*buf++ = cbuf->data[cbuf->get];
if (++cbuf->get == cbuf->len) cbuf->get = 0;
cbuf->nb--;
size++;
} else {
#ifdef CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
if (!cbuf->blocking) {
*len = size; // characters actually read
res = -EAGAIN;
break;
}
#endif // CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
cbuf->waiting = true;
#ifdef XX_CYGDBG_DIAG_BUF
enable_diag_uart = 0;
HAL_CLOCK_READ(&_time);
_stime = (int)cyg_current_time();
diag_printf("READ wait - get: %d, put: %d, time: %x.%x\n", cbuf->get, cbuf->put, _stime, _time);
enable_diag_uart = _enable;
#endif // CYGDBG_DIAG_BUF
if( !cyg_drv_cond_wait(&cbuf->wait) )
cbuf->abort = true;
#ifdef XX_CYGDBG_DIAG_BUF
enable_diag_uart = 0;
HAL_CLOCK_READ(&_time);
_stime = (int)cyg_current_time();
diag_printf("READ continue - get: %d, put: %d, time: %x.%x\n", cbuf->get, cbuf->put, _stime, _time);
enable_diag_uart = _enable;
#endif // CYGDBG_DIAG_BUF
if (cbuf->abort) {
// Give up!
*len = size; // characters actually read
cbuf->abort = false;
cbuf->waiting = false;
res = -EINTR;
break;
}
}
}
cyg_drv_dsr_unlock();
}
#ifdef XX_CYGDBG_DIAG_BUF
cyg_drv_isr_lock();
enable_diag_uart = 0;
HAL_CLOCK_READ(&_time);
_stime = (int)cyg_current_time();
diag_printf("READ done - size: %d, len: %d, time: %x.%x\n", size, *len, _stime, _time);
enable_diag_uart = _enable;
cyg_drv_isr_unlock();
#endif // CYGDBG_DIAG_BUF
cyg_drv_mutex_unlock(&cbuf->lock);
return res;
}
 
 
// ---------------------------------------------------------------------------
 
static cyg_bool
serial_select(cyg_io_handle_t handle, cyg_uint32 which, CYG_ADDRWORD info)
{
#ifdef CYGPKG_IO_SERIAL_SELECT_SUPPORT
 
cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
serial_channel *chan = (serial_channel *)t->priv;
 
switch( which )
{
case CYG_FREAD:
{
cbuf_t *cbuf = &chan->in_cbuf;
 
// Check for data in the input buffer. If there is none,
// register the select operation, otherwise return true.
 
if( cbuf->nb == 0 )
cyg_selrecord( info, &cbuf->selinfo );
else return true;
}
break;
case CYG_FWRITE:
{
// Check for space in the output buffer. If there is none,
// register the select operation, otherwise return true.
 
cbuf_t *cbuf = &chan->out_cbuf;
int space = cbuf->len - cbuf->nb;
#ifdef CYGPKG_IO_SERIAL_FLOW_CONTROL
if ( (space < cbuf->low_water) ||
(chan->flow_desc.flags & CYG_SERIAL_FLOW_OUT_THROTTLED) )
cyg_selrecord( info, &cbuf->selinfo );
#else
if (space < cbuf->low_water)
cyg_selrecord( info, &cbuf->selinfo );
#endif
else return true;
}
break;
 
case 0: // exceptions - none supported
break;
}
return false;
#else
 
// With no select support, we simply return true.
return true;
#endif
}
 
 
// ---------------------------------------------------------------------------
 
static Cyg_ErrNo
serial_get_config(cyg_io_handle_t handle, cyg_uint32 key, void *xbuf,
cyg_uint32 *len)
{
cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
serial_channel *chan = (serial_channel *)t->priv;
cyg_serial_info_t *buf = (cyg_serial_info_t *)xbuf;
Cyg_ErrNo res = ENOERR;
cbuf_t *out_cbuf = &chan->out_cbuf;
cbuf_t *in_cbuf = &chan->in_cbuf;
serial_funs *funs = chan->funs;
 
switch (key) {
case CYG_IO_GET_CONFIG_SERIAL_INFO:
if (*len < sizeof(cyg_serial_info_t)) {
return -EINVAL;
}
*buf = chan->config;
*len = sizeof(chan->config);
break;
 
case CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO:
// return rx/tx buffer sizes and counts
{
cyg_serial_buf_info_t *p;
if (*len < sizeof(cyg_serial_buf_info_t))
return -EINVAL;
*len = sizeof(cyg_serial_buf_info_t);
p = (cyg_serial_buf_info_t *)xbuf;
p->rx_bufsize = in_cbuf->len;
if (p->rx_bufsize)
p->rx_count = in_cbuf->nb;
else
p->rx_count = 0;
p->tx_bufsize = out_cbuf->len;
if (p->tx_bufsize)
p->tx_count = out_cbuf->nb;
else
p->tx_count = 0;
}
break;
case CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN:
// Wait for any pending output to complete
if (out_cbuf->len == 0) break; // Nothing to do if not buffered
cyg_drv_mutex_lock(&out_cbuf->lock); // Stop any further output processing
cyg_drv_dsr_lock();
while (out_cbuf->pending || (out_cbuf->nb > 0)) {
out_cbuf->waiting = true;
if(!cyg_drv_cond_wait(&out_cbuf->wait) )
res = -EINTR;
}
cyg_drv_dsr_unlock();
cyg_drv_mutex_unlock(&out_cbuf->lock);
break;
 
case CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH:
// Flush any buffered input
if (in_cbuf->len == 0) break; // Nothing to do if not buffered
cyg_drv_mutex_lock(&in_cbuf->lock); // Stop any further input processing
cyg_drv_dsr_lock();
if (in_cbuf->waiting) {
in_cbuf->abort = true;
cyg_drv_cond_signal(&in_cbuf->wait);
in_cbuf->waiting = false;
}
in_cbuf->get = in_cbuf->put = in_cbuf->nb = 0; // Flush buffered input
cyg_drv_dsr_unlock();
cyg_drv_mutex_unlock(&in_cbuf->lock);
break;
 
case CYG_IO_GET_CONFIG_SERIAL_ABORT:
// Abort any outstanding I/O, including blocked reads
// Caution - assumed to be called from 'timeout' (i.e. DSR) code
if (in_cbuf->len != 0) {
in_cbuf->abort = true;
cyg_drv_cond_signal(&in_cbuf->wait);
}
if (out_cbuf->len != 0) {
out_cbuf->abort = true;
cyg_drv_cond_signal(&out_cbuf->wait);
}
break;
 
case CYG_IO_GET_CONFIG_SERIAL_OUTPUT_FLUSH:
// Throw away any pending output
if (out_cbuf->len == 0) break; // Nothing to do if not buffered
cyg_drv_mutex_lock(&out_cbuf->lock); // Stop any further output processing
cyg_drv_dsr_lock();
if (out_cbuf->nb > 0) {
out_cbuf->get = out_cbuf->put = out_cbuf->nb = 0; // Empties queue!
(funs->stop_xmit)(chan); // Done with transmit
}
if (out_cbuf->waiting) {
out_cbuf->abort = true;
cyg_drv_cond_signal(&out_cbuf->wait);
out_cbuf->waiting = false;
}
cyg_drv_dsr_unlock();
cyg_drv_mutex_unlock(&out_cbuf->lock);
break;
 
#ifdef CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
case CYG_IO_GET_CONFIG_READ_BLOCKING:
if (*len < sizeof(cyg_uint32)) {
return -EINVAL;
}
*(cyg_uint32*)xbuf = (in_cbuf->blocking) ? 1 : 0;
break;
 
case CYG_IO_GET_CONFIG_WRITE_BLOCKING:
if (*len < sizeof(cyg_uint32)) {
return -EINVAL;
}
*(cyg_uint32*)xbuf = (out_cbuf->blocking) ? 1 : 0;
break;
#endif // CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
 
default:
res = -EINVAL;
}
return res;
}
 
 
// ---------------------------------------------------------------------------
 
static Cyg_ErrNo
serial_set_config(cyg_io_handle_t handle, cyg_uint32 key, const void *xbuf,
cyg_uint32 *len)
{
Cyg_ErrNo res = ENOERR;
cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
serial_channel *chan = (serial_channel *)t->priv;
#ifdef CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
cbuf_t *out_cbuf = &chan->out_cbuf;
cbuf_t *in_cbuf = &chan->in_cbuf;
#endif
serial_funs *funs = chan->funs;
 
switch (key) {
#ifdef CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
case CYG_IO_SET_CONFIG_READ_BLOCKING:
if (*len < sizeof(cyg_uint32) || 0 == in_cbuf->len) {
return -EINVAL;
}
in_cbuf->blocking = (1 == *(cyg_uint32*)xbuf) ? true : false;
break;
case CYG_IO_SET_CONFIG_WRITE_BLOCKING:
if (*len < sizeof(cyg_uint32) || 0 == out_cbuf->len) {
return -EINVAL;
}
out_cbuf->blocking = (1 == *(cyg_uint32*)xbuf) ? true : false;
break;
#endif // CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
 
#ifdef CYGPKG_IO_SERIAL_FLOW_CONTROL
case CYG_IO_SET_CONFIG_SERIAL_FLOW_CONTROL_METHOD:
{
cyg_uint32 *f = (cyg_uint32 *)xbuf;
 
if (*len < sizeof(*f))
return -EINVAL;
 
cyg_drv_dsr_lock();
 
chan->config.flags &= ~(CYGNUM_SERIAL_FLOW_XONXOFF_RX|
CYGNUM_SERIAL_FLOW_XONXOFF_TX|
CYGNUM_SERIAL_FLOW_RTSCTS_RX|
CYGNUM_SERIAL_FLOW_RTSCTS_TX|
CYGNUM_SERIAL_FLOW_DSRDTR_RX|
CYGNUM_SERIAL_FLOW_DSRDTR_TX);
chan->config.flags |= (*f & (
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE
CYGNUM_SERIAL_FLOW_XONXOFF_RX|
CYGNUM_SERIAL_FLOW_XONXOFF_TX|
#endif
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW
CYGNUM_SERIAL_FLOW_RTSCTS_RX|
CYGNUM_SERIAL_FLOW_RTSCTS_TX|
CYGNUM_SERIAL_FLOW_DSRDTR_RX|
CYGNUM_SERIAL_FLOW_DSRDTR_TX|
#endif
0));
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW
// up to hardware driver to clear flags if rejected
res = (funs->set_config)(chan,
CYG_IO_SET_CONFIG_SERIAL_HW_FLOW_CONFIG,
NULL, NULL);
#endif
cyg_drv_dsr_unlock();
}
break;
 
case CYG_IO_SET_CONFIG_SERIAL_FLOW_CONTROL_FORCE:
{
cyg_uint32 *f = (cyg_uint32 *)xbuf;
 
if (*len < sizeof(*f))
return -EINVAL;
cyg_drv_dsr_lock();
switch (*f) {
case CYGNUM_SERIAL_FLOW_THROTTLE_RX:
throttle_rx( chan, true );
break;
case CYGNUM_SERIAL_FLOW_RESTART_RX:
restart_rx( chan, true );
break;
case CYGNUM_SERIAL_FLOW_THROTTLE_TX:
throttle_tx( chan );
break;
case CYGNUM_SERIAL_FLOW_RESTART_TX:
restart_tx( chan );
break;
default:
res = -EINVAL;
break;
}
cyg_drv_dsr_unlock();
}
break;
#endif // CYGPKG_IO_SERIAL_FLOW_CONTROL
 
#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
case CYG_IO_SET_CONFIG_SERIAL_STATUS_CALLBACK:
{
cyg_serial_line_status_callback_fn_t newfn;
CYG_ADDRWORD newpriv;
cyg_serial_line_status_callback_t *tmp =
(cyg_serial_line_status_callback_t *)xbuf;
if ( *len < sizeof(*tmp) )
return -EINVAL;
 
newfn = tmp->fn;
newpriv = tmp->priv;
 
// prevent callbacks while we do this
cyg_drv_dsr_lock();
// store old callbacks in same structure
tmp->fn = chan->status_callback;
tmp->priv = chan->status_callback_priv;
chan->status_callback = newfn;
chan->status_callback_priv = newpriv;
cyg_drv_dsr_unlock();
*len = sizeof(*tmp);
}
break;
#endif
 
default:
// pass down to lower layers
return (funs->set_config)(chan, key, xbuf, len);
}
return res;
}
 
// ---------------------------------------------------------------------------
 
static void
serial_xmt_char(serial_channel *chan)
{
cbuf_t *cbuf = &chan->out_cbuf;
serial_funs *funs = chan->funs;
unsigned char c;
int space;
 
#if CYGINT_IO_SERIAL_BLOCK_TRANSFER
CYG_ASSERT(false == cbuf->block_mode_xfer_running,
"Attempting char xmt while block transfer is running");
#endif
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE
// if we are required to send an XON/XOFF char, send it before
// anything else
// FIXME: what if XON gets corrupted in transit to the other end?
// Should we resend XON even though the other end may not be wanting
// to send us stuff at this point?
if ( chan->config.flags & CYGNUM_SERIAL_FLOW_XONXOFF_RX ) {
if ( chan->flow_desc.xchar ) {
if ( (funs->putc)(chan, chan->flow_desc.xchar) ) {
chan->flow_desc.xchar = '\0';
} else { // otherwise there's no space and we have to wait
return;
}
}
}
#endif
#ifdef CYGPKG_IO_SERIAL_FLOW_CONTROL
// if we're meant to be throttled, just stop and leave
if ( chan->flow_desc.flags & CYG_SERIAL_FLOW_OUT_THROTTLED ) {
(funs->stop_xmit)(chan); // Stop transmitting for now
return;
}
#endif
while (cbuf->nb > 0) {
c = cbuf->data[cbuf->get];
if ((funs->putc)(chan, c)) {
cbuf->get++;
if (cbuf->get == cbuf->len) cbuf->get = 0;
cbuf->nb--;
} else {
// See if there is now enough room to restart writer
space = cbuf->len - cbuf->nb;
if (space >= cbuf->low_water) {
if (cbuf->waiting) {
cbuf->waiting = false;
cyg_drv_cond_broadcast(&cbuf->wait);
}
#ifdef CYGPKG_IO_SERIAL_SELECT_SUPPORT
cyg_selwakeup( &cbuf->selinfo );
#endif
}
return; // Need to wait for more space
}
}
(funs->stop_xmit)(chan); // Done with transmit
 
// must signal waiters, and wake up selecters for the case when
// this was the last char to be sent and they hadn't been signalled
// before (e.g. because of flow control)
if (cbuf->waiting) {
cbuf->waiting = false;
cyg_drv_cond_signal(&cbuf->wait);
}
#ifdef CYGPKG_IO_SERIAL_SELECT_SUPPORT
cyg_selwakeup( &cbuf->selinfo );
#endif
}
 
// ---------------------------------------------------------------------------
 
static void
serial_rcv_char(serial_channel *chan, unsigned char c)
{
cbuf_t *cbuf = &chan->in_cbuf;
 
#if CYGINT_IO_SERIAL_BLOCK_TRANSFER
CYG_ASSERT(false == cbuf->block_mode_xfer_running,
"Attempting char rcv while block transfer is running");
#endif
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE
// for software flow control, if the driver returns one of the characters
// we act on it and then drop it (the app must not see it)
if ( chan->config.flags & CYGNUM_SERIAL_FLOW_XONXOFF_TX ) {
if ( c == CYGDAT_IO_SERIAL_FLOW_CONTROL_XOFF_CHAR ) {
throttle_tx( chan );
return; // it wasn't a "real" character
} else if ( c == CYGDAT_IO_SERIAL_FLOW_CONTROL_XON_CHAR ) {
restart_tx( chan );
return; // it wasn't a "real" character
}
}
#endif
#ifdef CYGPKG_IO_SERIAL_FLOW_CONTROL
// If we've hit the high water mark, tell the other side to stop
if ( cbuf->nb >= cbuf->high_water ) {
throttle_rx( chan, false );
}
#endif
#ifdef CYGPKG_IO_SERIAL_SELECT_SUPPORT
// Wake up any pending selectors if we are about to
// put some data into a previously empty buffer.
if( cbuf->nb == 0 )
cyg_selwakeup( &cbuf->selinfo );
#endif
 
// If the flow control is not enabled/sufficient and the buffer is
// already full, just throw new characters away.
 
if ( cbuf->nb < cbuf->len ) {
cbuf->data[cbuf->put++] = c;
if (cbuf->put == cbuf->len) cbuf->put = 0;
cbuf->nb++;
} // note trailing else
#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
else {
// Overrun. Report the error.
cyg_serial_line_status_t stat;
stat.which = CYGNUM_SERIAL_STATUS_OVERRUNERR;
serial_indicate_status(chan, &stat);
}
#endif
 
if (cbuf->waiting) {
#ifdef XX_CYGDBG_DIAG_BUF
extern int enable_diag_uart;
int _enable = enable_diag_uart;
int _time, _stime;
externC cyg_tick_count_t cyg_current_time(void);
enable_diag_uart = 0;
HAL_CLOCK_READ(&_time);
_stime = (int)cyg_current_time();
diag_printf("Signal reader - time: %x.%x\n", _stime, _time);
enable_diag_uart = _enable;
#endif // CYGDBG_DIAG_BUF
cbuf->waiting = false;
cyg_drv_cond_signal(&cbuf->wait);
}
}
 
//----------------------------------------------------------------------------
// Flow control indication callback
 
#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
static void
serial_indicate_status(serial_channel *chan, cyg_serial_line_status_t *s )
{
#ifdef CYGPKG_IO_SERIAL_FLOW_CONTROL
if ( CYGNUM_SERIAL_STATUS_FLOW == s->which ) {
if ( s->value )
restart_tx( chan );
else
throttle_tx( chan );
}
#endif
if ( chan->status_callback )
(*chan->status_callback)(s, chan->status_callback_priv);
}
#endif // ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
 
//----------------------------------------------------------------------------
// Block transfer functions. Not all drivers require these. Those that
// do must follow the required semantics:
//
// Attempt to transfer as much via the block transfer function as
// possible, _but_ if that fails, do the remaining bytes via the
// single-char function. That ensures that all policy decisions can be
// made in this driver, and not in the device driver.
//
// Note: if the driver uses DMA for transmission, an initial failing
// call to the xmt_req function must cause the start_xmit function to
// fall-back to regular CPU-interrupt based single-character
// transmission.
 
#if CYGINT_IO_SERIAL_BLOCK_TRANSFER
 
static rcv_req_reply_t
serial_data_rcv_req(serial_channel *chan, int avail,
int* space_avail, unsigned char** space)
{
cbuf_t *cbuf = &chan->in_cbuf;
int gap;
 
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE
// When there is software flow-control, force the serial device
// driver to use the single-char xmt/rcv functions, since these
// have to make policy decision based on the data. Rcv function
// may also have to transmit data to throttle the xmitter.
if (chan->config.flags & (CYGNUM_SERIAL_FLOW_XONXOFF_TX|CYGNUM_SERIAL_FLOW_XONXOFF_RX))
return CYG_RCV_DISABLED;
#endif
 
CYG_ASSERT(false == cbuf->block_mode_xfer_running,
"Attempting new block transfer while another is running");
// Check for space
gap = cbuf->nb;
if (gap == cbuf->len)
return CYG_RCV_FULL;
 
#ifdef CYGDBG_USE_ASSERTS
cbuf->block_mode_xfer_running = true;
#endif
 
if (0 == gap) {
// Buffer is empty. Reset put/get indexes to get max transfer in
// one chunk.
cbuf->get = 0;
cbuf->put = 0;
gap = cbuf->len;
} else {
// Free space (G = get, P = put, x = data, . = empty)
// positive: xxxxP.....Gxxx
// negative: ..GxxxxxP..... [offer last chunk only]
 
// First try for a gap between put and get locations
gap = cbuf->get - cbuf->put;
if (gap < 0) {
// If failed, the gap is between put and the end of buffer
gap = cbuf->len - cbuf->put;
}
}
 
if (avail < gap) gap = avail; // bound by what's available from hw
*space_avail = gap;
*space = &cbuf->data[cbuf->put];
 
CYG_ASSERT((gap+cbuf->nb) <= cbuf->len, "Buffer will overflow");
CYG_ASSERT(cbuf->put < cbuf->len, "Invalid put ptr");
CYG_ASSERT(cbuf->get < cbuf->len, "Invalid get ptr");
 
return CYG_RCV_OK;
}
 
static void
serial_data_rcv_done(serial_channel *chan, int chars_rcvd)
{
cbuf_t *cbuf = &chan->in_cbuf;
 
cbuf->put += chars_rcvd;
cbuf->nb += chars_rcvd;
 
if (cbuf->put == cbuf->len) cbuf->put = 0;
 
CYG_ASSERT(cbuf->nb <= cbuf->len, "Buffer overflow");
CYG_ASSERT(cbuf->put < cbuf->len, "Invalid put ptr");
CYG_ASSERT(cbuf->get < cbuf->len, "Invalid get ptr");
 
if (cbuf->waiting) {
cbuf->waiting = false;
cyg_drv_cond_signal(&cbuf->wait);
}
#ifdef CYGPKG_IO_SERIAL_FLOW_CONTROL
// If we've hit the high water mark, tell the other side to stop
if ( cbuf->nb >= cbuf->high_water ) {
throttle_rx( chan, false );
}
#endif
#ifdef CYGPKG_IO_SERIAL_SELECT_SUPPORT
// Wake up any pending selectors if we have
// put some data into a previously empty buffer.
if (chars_rcvd == cbuf->nb)
cyg_selwakeup( &cbuf->selinfo );
#endif
 
#ifdef CYGDBG_USE_ASSERTS
cbuf->block_mode_xfer_running = false;
#endif
}
 
static xmt_req_reply_t
serial_data_xmt_req(serial_channel *chan, int space,
int* chars_avail, unsigned char** chars)
{
cbuf_t *cbuf = &chan->out_cbuf;
int avail;
 
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE
// When there is software flow-control, force the serial device
// driver to use the single-char xmt/rcv functions, since these
// have to make policy decision based on the data. Rcv function
// may also have to transmit data to throttle the xmitter.
if (chan->config.flags & (CYGNUM_SERIAL_FLOW_XONXOFF_TX|CYGNUM_SERIAL_FLOW_XONXOFF_RX))
return CYG_XMT_DISABLED;
#endif
 
CYG_ASSERT(false == cbuf->block_mode_xfer_running,
"Attempting new block transfer while another is running");
 
// Available data (G = get, P = put, x = data, . = empty)
// 0: no data
// negative: xxxxP.....Gxxx [offer last chunk only]
// positive: ..GxxxxxP.....
if (0 == cbuf->nb)
return CYG_XMT_EMPTY;
 
#ifdef CYGDBG_USE_ASSERTS
cbuf->block_mode_xfer_running = true;
#endif
 
if (cbuf->get >= cbuf->put) {
avail = cbuf->len - cbuf->get;
} else {
avail = cbuf->put - cbuf->get;
}
 
if (avail > space) avail = space; // bound by space in hardware
*chars_avail = avail;
*chars = &cbuf->data[cbuf->get];
 
CYG_ASSERT(avail <= cbuf->len, "Avail overflow");
CYG_ASSERT(cbuf->nb <= cbuf->len, "Buffer overflow");
CYG_ASSERT(cbuf->put < cbuf->len, "Invalid put ptr");
CYG_ASSERT(cbuf->get < cbuf->len, "Invalid get ptr");
 
return CYG_XMT_OK;
}
 
static void
serial_data_xmt_done(serial_channel *chan, int chars_sent)
{
cbuf_t *cbuf = &chan->out_cbuf;
serial_funs *funs = chan->funs;
int space;
 
cbuf->get += chars_sent;
cbuf->nb -= chars_sent;
 
if (cbuf->get == cbuf->len) cbuf->get = 0;
 
CYG_ASSERT(cbuf->nb <= cbuf->len, "Buffer overflow");
CYG_ASSERT(cbuf->nb >= 0, "Buffer underflow");
CYG_ASSERT(cbuf->put < cbuf->len, "Invalid put ptr");
CYG_ASSERT(cbuf->get < cbuf->len, "Invalid get ptr");
 
if (0 == cbuf->nb) {
(funs->stop_xmit)(chan); // Done with transmit
cbuf->get = cbuf->put = 0; // reset ptrs if empty
}
 
// See if there is now enough room to restart writer
space = cbuf->len - cbuf->nb;
if (space >= cbuf->low_water) {
if (cbuf->waiting) {
cbuf->waiting = false;
cyg_drv_cond_broadcast(&cbuf->wait);
}
#ifdef CYGPKG_IO_SERIAL_SELECT_SUPPORT
cyg_selwakeup( &cbuf->selinfo );
#endif
}
 
#ifdef CYGDBG_USE_ASSERTS
cbuf->block_mode_xfer_running = false;
#endif
}
 
#endif // CYGINT_IO_SERIAL_BLOCK_TRANSFER
 
// ---------------------------------------------------------------------------
 
// EOF serial.c
/src/common/tty.c
0,0 → 1,336
//==========================================================================
//
// io/serial/common/tty.c
//
// TTY (terminal-like interface) I/O driver
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): gthomas
// Contributors: gthomas
// Date: 1999-02-04
// Purpose: Device driver for tty I/O, layered on top of serial I/O
// Description:
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
#include <pkgconf/io.h>
#include <pkgconf/io_serial.h>
#ifdef CYGPKG_IO_SERIAL_TTY
#include <cyg/io/io.h>
#include <cyg/io/devtab.h>
#include <cyg/io/ttyio.h>
#include <cyg/infra/diag.h>
 
static bool tty_init(struct cyg_devtab_entry *tab);
static Cyg_ErrNo tty_lookup(struct cyg_devtab_entry **tab,
struct cyg_devtab_entry *sub_tab,
const char *name);
static Cyg_ErrNo tty_write(cyg_io_handle_t handle, const void *buf, cyg_uint32 *len);
static Cyg_ErrNo tty_read(cyg_io_handle_t handle, void *buf, cyg_uint32 *len);
static Cyg_ErrNo tty_select(cyg_io_handle_t handle, cyg_uint32 which, CYG_ADDRWORD info);
static Cyg_ErrNo tty_get_config(cyg_io_handle_t handle, cyg_uint32 key, void *buf, cyg_uint32 *len);
static Cyg_ErrNo tty_set_config(cyg_io_handle_t handle, cyg_uint32 key, const void *buf, cyg_uint32 *len);
 
struct tty_private_info {
cyg_tty_info_t dev_info;
cyg_io_handle_t dev_handle;
};
 
static DEVIO_TABLE(tty_devio,
tty_write,
tty_read,
tty_select,
tty_get_config,
tty_set_config
);
 
#ifdef CYGPKG_IO_SERIAL_TTY_TTYDIAG
static struct tty_private_info tty_private_info_diag;
DEVTAB_ENTRY(tty_io_diag,
// "/dev/console",
// CYGDAT_IO_SERIAL_TTY_CONSOLE, // Based on driver for this device
"/dev/ttydiag",
"/dev/haldiag",
&tty_devio,
tty_init,
tty_lookup, // Execute this when device is being looked up
&tty_private_info_diag);
#endif
 
#ifdef CYGPKG_IO_SERIAL_TTY_TTY0
static struct tty_private_info tty_private_info0;
DEVTAB_ENTRY(tty_io0,
"/dev/tty0",
CYGDAT_IO_SERIAL_TTY_TTY0_DEV,
&tty_devio,
tty_init,
tty_lookup, // Execute this when device is being looked up
&tty_private_info0);
#endif
 
#ifdef CYGPKG_IO_SERIAL_TTY_TTY1
static struct tty_private_info tty_private_info1;
DEVTAB_ENTRY(tty_io1,
"/dev/tty1",
CYGDAT_IO_SERIAL_TTY_TTY1_DEV,
&tty_devio,
tty_init,
tty_lookup, // Execute this when device is being looked up
&tty_private_info1);
#endif
 
#ifdef CYGPKG_IO_SERIAL_TTY_TTY2
static struct tty_private_info tty_private_info2;
DEVTAB_ENTRY(tty_io2,
"/dev/tty2",
CYGDAT_IO_SERIAL_TTY_TTY2_DEV,
&tty_devio,
tty_init,
tty_lookup, // Execute this when device is being looked up
&tty_private_info2);
#endif
 
static bool
tty_init(struct cyg_devtab_entry *tab)
{
struct tty_private_info *priv = (struct tty_private_info *)tab->priv;
#ifdef CYGDBG_IO_INIT
diag_printf("Init tty channel: %x\n", tab);
#endif
priv->dev_info.tty_out_flags = CYG_TTY_OUT_FLAGS_DEFAULT;
priv->dev_info.tty_in_flags = CYG_TTY_IN_FLAGS_DEFAULT;
return true;
}
 
static Cyg_ErrNo
tty_lookup(struct cyg_devtab_entry **tab,
struct cyg_devtab_entry *sub_tab,
const char *name)
{
cyg_io_handle_t chan = (cyg_io_handle_t)sub_tab;
struct tty_private_info *priv = (struct tty_private_info *)(*tab)->priv;
#if 0
cyg_int32 len;
#endif
priv->dev_handle = chan;
#if 0
len = sizeof(cyg_serial_info_t);
// Initialize configuration
cyg_io_get_config(chan, CYG_SERIAL_GET_CONFIG,
(void *)&priv->dev_info.serial_config, &len);
#endif
return ENOERR;
}
 
#define BUFSIZE 64
 
static Cyg_ErrNo
tty_write(cyg_io_handle_t handle, const void *_buf, cyg_uint32 *len)
{
cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
struct tty_private_info *priv = (struct tty_private_info *)t->priv;
cyg_io_handle_t chan = (cyg_io_handle_t)priv->dev_handle;
cyg_int32 size, bytes_successful, actually_written;
cyg_uint8 xbuf[BUFSIZE];
cyg_uint8 c;
cyg_uint8 *buf = (cyg_uint8 *)_buf;
Cyg_ErrNo res = -EBADF;
// assert(chan)
size = 0;
bytes_successful = 0;
actually_written = 0;
while (bytes_successful++ < *len) {
c = *buf++;
if ((c == '\n') &&
(priv->dev_info.tty_out_flags & CYG_TTY_OUT_FLAGS_CRLF)) {
xbuf[size++] = '\r';
}
xbuf[size++] = c;
// Always leave room for possible CR/LF expansion
if ((size >= (BUFSIZE-1)) ||
(bytes_successful == *len)) {
res = cyg_io_write(chan, xbuf, &size);
if (res != ENOERR) {
*len = actually_written;
return res;
}
actually_written += size;
size = 0;
}
}
return res;
}
 
static Cyg_ErrNo
tty_read(cyg_io_handle_t handle, void *_buf, cyg_uint32 *len)
{
cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
struct tty_private_info *priv = (struct tty_private_info *)t->priv;
cyg_io_handle_t chan = (cyg_io_handle_t)priv->dev_handle;
cyg_uint32 clen;
cyg_int32 size;
Cyg_ErrNo res;
cyg_uint8 c;
cyg_uint8 *buf = (cyg_uint8 *)_buf;
// assert(chan)
size = 0;
while (size < *len) {
clen = 1;
res = cyg_io_read(chan, &c, &clen);
if (res != ENOERR) {
*len = size;
return res;
}
buf[size++] = c;
if ((priv->dev_info.tty_in_flags & CYG_TTY_IN_FLAGS_BINARY) == 0) {
switch (c) {
case '\b': /* drop through */
case 0x7f:
size -= 2; // erase one character + 'backspace' char
if (size < 0) {
size = 0;
} else if (priv->dev_info.tty_in_flags & CYG_TTY_IN_FLAGS_ECHO) {
clen = 3;
cyg_io_write(chan, "\b \b", &clen);
}
break;
case '\r':
if (priv->dev_info.tty_in_flags & CYG_TTY_IN_FLAGS_CRLF) {
/* Don't do anything because a '\n' will come next */
break;
}
if (priv->dev_info.tty_in_flags & CYG_TTY_IN_FLAGS_CR) {
c = '\n'; // Map CR -> LF
}
/* drop through */
case '\n':
if (priv->dev_info.tty_in_flags & CYG_TTY_IN_FLAGS_ECHO) {
if (priv->dev_info.tty_out_flags & CYG_TTY_OUT_FLAGS_CRLF) {
clen = 2;
cyg_io_write(chan, "\r\n", &clen);
} else {
clen = 1;
cyg_io_write(chan, &c, &clen);
}
}
buf[size-1] = c;
*len = size;
return ENOERR;
default:
if (priv->dev_info.tty_in_flags & CYG_TTY_IN_FLAGS_ECHO) {
clen = 1;
cyg_io_write(chan, &c, &clen);
}
break;
}
}
}
*len = size;
return ENOERR;
}
 
static cyg_bool
tty_select(cyg_io_handle_t handle, cyg_uint32 which, CYG_ADDRWORD info)
{
cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
struct tty_private_info *priv = (struct tty_private_info *)t->priv;
cyg_io_handle_t chan = (cyg_io_handle_t)priv->dev_handle;
 
// Just pass it on to next driver level
return cyg_io_select( chan, which, info );
}
 
static Cyg_ErrNo
tty_get_config(cyg_io_handle_t handle, cyg_uint32 key, void *buf, cyg_uint32 *len)
{
cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
struct tty_private_info *priv = (struct tty_private_info *)t->priv;
cyg_io_handle_t chan = (cyg_io_handle_t)priv->dev_handle;
Cyg_ErrNo res = ENOERR;
#if 0
cyg_int32 current_len;
#endif
// assert(chan)
switch (key) {
case CYG_IO_GET_CONFIG_TTY_INFO:
if (*len < sizeof(cyg_tty_info_t)) {
return -EINVAL;
}
#if 0
current_len = sizeof(cyg_serial_info_t);
res = cyg_io_get_config(chan, CYG_SERIAL_GET_CONFIG,
(void *)&priv->dev_info.serial_config, &current_len);
if (res != ENOERR) {
return res;
}
#endif
*(cyg_tty_info_t *)buf = priv->dev_info;
*len = sizeof(cyg_tty_info_t);
break;
default: // Assume this is a 'serial' driver control
res = cyg_io_get_config(chan, key, buf, len);
}
return res;
}
 
static Cyg_ErrNo
tty_set_config(cyg_io_handle_t handle, cyg_uint32 key, const void *buf, cyg_uint32 *len)
{
cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
struct tty_private_info *priv = (struct tty_private_info *)t->priv;
cyg_io_handle_t chan = (cyg_io_handle_t)priv->dev_handle;
#if 0
cyg_int32 current_len;
#endif
Cyg_ErrNo res = ENOERR;
// assert(chan)
switch (key) {
case CYG_IO_SET_CONFIG_TTY_INFO:
if (*len != sizeof(cyg_tty_info_t)) {
return -EINVAL;
}
priv->dev_info = *(cyg_tty_info_t *)buf;
break;
default: // Pass on to serial driver
res = cyg_io_set_config(chan, key, buf, len);
}
return res;
}
#endif // CYGPKG_IO_SERIAL_TTY
/src/common/termios.c
0,0 → 1,402
/* ====================================================================
//
// termios.c
//
// POSIX termios API implementation
//
// ====================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
// ====================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): jlarmour
// Contributors:
// Date: 2000-07-22
// Purpose: POSIX termios API support
// Description: Most of the real work happens in the POSIX termios tty
// drivers
//
//####DESCRIPTIONEND####
//
// ==================================================================*/
 
// CONFIGURATION
 
#include <pkgconf/io_serial.h>
 
#ifdef CYGPKG_IO_SERIAL_TERMIOS
 
// INCLUDES
 
#include <termios.h> // Header for this file
#include <cyg/infra/cyg_type.h> // Common stuff
#include <cyg/infra/cyg_ass.h> // Assertion support
#include <cyg/infra/cyg_trac.h> // Tracing support
#include <cyg/io/serialio.h> // eCos serial implementation
#include <cyg/fileio/fileio.h> // file operations
#include <cyg/io/io.h>
#include <errno.h> // errno
#include <unistd.h> // isatty()
 
// TYPES
 
typedef struct {
const struct termios *termios_p;
int optact;
} setattr_struct;
 
// FUNCTIONS
 
extern speed_t
cfgetospeed( const struct termios *termios_p )
{
CYG_REPORT_FUNCTYPE( "returning speed code %d" );
CYG_CHECK_DATA_PTRC( termios_p );
CYG_REPORT_FUNCARG1XV( termios_p );
CYG_REPORT_RETVAL( termios_p->c_ospeed );
return termios_p->c_ospeed;
} // cfgetospeed()
 
 
extern int
cfsetospeed( struct termios *termios_p, speed_t speed )
{
CYG_REPORT_FUNCTYPE( "returning %d" );
CYG_CHECK_DATA_PTRC( termios_p );
CYG_REPORT_FUNCARG2( "termios_p=%08x, speed=%d", termios_p, speed );
CYG_REPORT_RETVAL( termios_p->c_ospeed );
if ( speed > B4000000 ) {
errno = EINVAL;
CYG_REPORT_RETVAL( -1 );
return -1;
}
termios_p->c_ospeed = speed;
CYG_REPORT_RETVAL( 0 );
return 0;
} // cfsetospeed()
 
 
extern speed_t
cfgetispeed( const struct termios *termios_p )
{
CYG_REPORT_FUNCTYPE( "returning speed code %d" );
CYG_CHECK_DATA_PTRC( termios_p );
CYG_REPORT_FUNCARG1XV( termios_p );
CYG_REPORT_RETVAL( termios_p->c_ispeed );
return termios_p->c_ispeed;
} // cfgetispeed()
 
 
extern int
cfsetispeed( struct termios *termios_p, speed_t speed )
{
CYG_REPORT_FUNCTYPE( "returning %d" );
CYG_CHECK_DATA_PTRC( termios_p );
CYG_REPORT_FUNCARG2( "termios_p=%08x, speed=%d", termios_p, speed );
if ( speed > B115200 ) {
errno = EINVAL;
CYG_REPORT_RETVAL( -1 );
return -1;
}
termios_p->c_ispeed = speed;
CYG_REPORT_RETVAL( 0 );
return 0;
} // cfsetispeed()
 
 
__externC cyg_file *
cyg_fp_get( int fd );
 
__externC void
cyg_fp_free( cyg_file *fp );
 
extern int
tcgetattr( int fildes, struct termios *termios_p )
{
cyg_file *fp;
int ret;
int len = sizeof( *termios_p );
 
CYG_REPORT_FUNCTYPE( "returning %d" );
CYG_REPORT_FUNCARG2( "fildes=%d, termios_p=%08x", fildes, termios_p );
CYG_CHECK_DATA_PTRC( termios_p );
 
if ( !isatty(fildes) ) {
errno = ENOTTY;
CYG_REPORT_RETVAL( -1 );
return -1;
}
fp = cyg_fp_get( fildes );
 
if ( NULL == fp ) {
errno = EBADF;
CYG_REPORT_RETVAL( -1 );
return -1;
}
 
ret = fp->f_ops->fo_getinfo( fp, CYG_IO_GET_CONFIG_TERMIOS, termios_p,
len);
cyg_fp_free( fp );
 
if ( ret > 0 ) {
errno = ret;
CYG_REPORT_RETVAL( -1 );
return -1;
}
CYG_REPORT_RETVAL( 0 );
return 0;
} // tcgetattr()
 
 
extern int
tcsetattr( int fildes, int optact, const struct termios *termios_p )
{
cyg_file *fp;
int ret;
setattr_struct attr;
int len = sizeof( attr );
 
CYG_REPORT_FUNCTYPE( "returning %d" );
CYG_REPORT_FUNCARG3( "fildes=%d, optact=%d, termios_p=%08x",
fildes, optact, termios_p );
CYG_CHECK_DATA_PTRC( termios_p );
 
if ( !isatty(fildes) ) {
errno = ENOTTY;
CYG_REPORT_RETVAL( -1 );
return -1;
}
 
if ( (optact != TCSANOW) && (optact != TCSADRAIN) &&
(optact != TCSAFLUSH) ) {
errno = EINVAL;
CYG_REPORT_RETVAL( -1 );
return -1;
}
fp = cyg_fp_get( fildes );
 
if ( NULL == fp ) {
errno = EBADF;
CYG_REPORT_RETVAL( -1 );
return -1;
}
 
attr.termios_p = termios_p;
attr.optact = optact;
 
ret = fp->f_ops->fo_setinfo( fp, CYG_IO_SET_CONFIG_TERMIOS, &attr,
len);
 
cyg_fp_free( fp );
 
if ( ret > 0 ) {
errno = ret;
CYG_REPORT_RETVAL( -1 );
return -1;
}
CYG_REPORT_RETVAL( 0 );
return 0;
} // tcsetattr()
 
 
extern int
tcsendbreak( int fildes, int duration )
{
// FIXME
return -EINVAL;
} // tcsendbreak()
 
extern int
tcdrain( int fildes )
{
cyg_file *fp;
int ret;
 
CYG_REPORT_FUNCTYPE( "returning %d" );
CYG_REPORT_FUNCARG1DV( fildes );
 
if ( !isatty(fildes) ) {
errno = ENOTTY;
CYG_REPORT_RETVAL( -1 );
return -1;
}
 
fp = cyg_fp_get( fildes );
 
if ( NULL == fp ) {
errno = EBADF;
CYG_REPORT_RETVAL( -1 );
return -1;
}
 
ret = fp->f_ops->fo_getinfo( fp,
CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN,
NULL, 0 );
cyg_fp_free( fp );
 
if ( ret > 0 ) {
errno = ret;
CYG_REPORT_RETVAL( -1 );
return -1;
}
CYG_REPORT_RETVAL( 0 );
return 0;
} // tcdrain()
 
extern int
tcflush( int fildes, int queue_sel )
{
cyg_file *fp;
int ret;
 
CYG_REPORT_FUNCTYPE( "returning %d" );
CYG_REPORT_FUNCARG2DV( fildes, queue_sel );
 
if ( !isatty(fildes) ) {
errno = ENOTTY;
CYG_REPORT_RETVAL( -1 );
return -1;
}
 
fp = cyg_fp_get( fildes );
 
if ( NULL == fp ) {
errno = EBADF;
CYG_REPORT_RETVAL( -1 );
return -1;
}
 
switch( queue_sel ) {
case TCIOFLUSH:
ret = fp->f_ops->fo_getinfo( fp,
CYG_IO_GET_CONFIG_SERIAL_OUTPUT_FLUSH,
NULL, 0 );
// fallthrough
case TCIFLUSH:
ret = fp->f_ops->fo_getinfo( fp,
CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH,
NULL, 0 );
break;
case TCOFLUSH:
ret = fp->f_ops->fo_getinfo( fp,
CYG_IO_GET_CONFIG_SERIAL_OUTPUT_FLUSH,
NULL, 0 );
break;
default:
ret = EINVAL;
break;
}
 
cyg_fp_free( fp );
 
if ( ret > 0 ) {
errno = ret;
CYG_REPORT_RETVAL( -1 );
return -1;
}
CYG_REPORT_RETVAL( 0 );
return 0;
} // tcflush()
 
extern int
tcflow( int fildes, int action )
{
cyg_file *fp;
int ret;
cyg_uint32 forcearg;
int len = sizeof(forcearg);
 
CYG_REPORT_FUNCTYPE( "returning %d" );
CYG_REPORT_FUNCARG2DV( fildes, action );
 
if ( !isatty(fildes) ) {
errno = ENOTTY;
CYG_REPORT_RETVAL( -1 );
return -1;
}
 
fp = cyg_fp_get( fildes );
 
if ( NULL == fp ) {
errno = EBADF;
CYG_REPORT_RETVAL( -1 );
return -1;
}
 
switch( action ) {
case TCOOFF:
forcearg = CYGNUM_SERIAL_FLOW_THROTTLE_TX;
ret = fp->f_ops->fo_setinfo( fp,
CYG_IO_SET_CONFIG_SERIAL_FLOW_CONTROL_FORCE,
&forcearg, len );
break;
case TCOON:
forcearg = CYGNUM_SERIAL_FLOW_RESTART_TX;
ret = fp->f_ops->fo_setinfo( fp,
CYG_IO_SET_CONFIG_SERIAL_FLOW_CONTROL_FORCE,
&forcearg, len );
break;
case TCIOFF:
forcearg = CYGNUM_SERIAL_FLOW_THROTTLE_RX;
ret = fp->f_ops->fo_setinfo( fp,
CYG_IO_SET_CONFIG_SERIAL_FLOW_CONTROL_FORCE,
&forcearg, len );
break;
case TCION:
forcearg = CYGNUM_SERIAL_FLOW_RESTART_RX;
ret = fp->f_ops->fo_setinfo( fp,
CYG_IO_SET_CONFIG_SERIAL_FLOW_CONTROL_FORCE,
&forcearg, len );
break;
default:
ret = EINVAL;
break;
}
 
cyg_fp_free( fp );
 
if ( ret > 0 ) {
errno = ret;
CYG_REPORT_RETVAL( -1 );
return -1;
}
CYG_REPORT_RETVAL( 0 );
return 0;
} // tcflow()
 
#endif // ifdef CYGPKG_IO_SERIAL_TERMIOS
 
// EOF termios.c
/src/common/termiostty.c
0,0 → 1,902
//==========================================================================
//
// termiostty.c
//
// POSIX Termios compatible TTY I/O driver
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2003 Jonathan Larmour
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): jlarmour
// Contributors: gthomas
// Date: 2000-07-22
// Purpose: Device driver for termios emulation tty I/O, layered on
// top of serial I/O
// Description: TODO: Add OPOST support for 80x25 (configurable) windows
// TODO: Support _POSIX_VDISABLE
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
// CONFIGURATION
 
#include <pkgconf/io_serial.h>
 
#ifdef CYGPKG_IO_SERIAL_TERMIOS
 
// INCLUDES
 
#include <cyg/infra/cyg_type.h> // Common types
#include <cyg/infra/cyg_ass.h> // Assertion support
#include <cyg/infra/cyg_trac.h> // Tracing support
#include <cyg/io/io.h>
#include <cyg/io/devtab.h>
#include <cyg/io/serialio.h> // public serial API
#include <termios.h> // Termios header
#include <cyg/hal/drv_api.h>
#include <stdlib.h> // malloc
#include <string.h>
#ifdef CYGSEM_IO_SERIAL_TERMIOS_USE_SIGNALS
# include <signal.h>
#endif
 
//==========================================================================
// FUNCTION PROTOTYPES
 
static bool
termios_init(struct cyg_devtab_entry *tab);
 
static Cyg_ErrNo
termios_lookup(struct cyg_devtab_entry **tab,
struct cyg_devtab_entry *sub_tab,
const char *name);
static Cyg_ErrNo
termios_write(cyg_io_handle_t handle, const void *buf, cyg_uint32 *len);
static Cyg_ErrNo
termios_read(cyg_io_handle_t handle, void *buf, cyg_uint32 *len);
static Cyg_ErrNo
termios_select(cyg_io_handle_t handle, cyg_uint32 which, CYG_ADDRWORD info);
static Cyg_ErrNo
termios_get_config(cyg_io_handle_t handle, cyg_uint32 key, void *buf,
cyg_uint32 *len);
static Cyg_ErrNo
termios_set_config(cyg_io_handle_t handle, cyg_uint32 key, const void *buf,
cyg_uint32 *len);
 
//==========================================================================
// TYPE DEFINITIONS
 
struct termios_private_info {
struct termios termios;
cyg_io_handle_t dev_handle;
cyg_drv_mutex_t lock;
cyg_bool init;
cyg_uint8 *errbuf;
cyg_uint8 *errbufpos;
cyg_uint32 errbufsize;
};
 
typedef struct {
struct termios *termios_p;
int optact;
} setattr_struct;
 
 
//==========================================================================
// STATIC OBJECTS
 
static DEVIO_TABLE(termios_devio,
termios_write,
termios_read,
termios_select,
termios_get_config,
termios_set_config);
 
#ifdef CYGPKG_IO_SERIAL_TERMIOS_TERMIOS0
static struct termios_private_info termios_private_info0;
DEVTAB_ENTRY(termios_io0,
"/dev/termios0",
CYGDAT_IO_SERIAL_TERMIOS_TERMIOS0_DEV,
&termios_devio,
termios_init,
termios_lookup,
&termios_private_info0);
#endif
 
#ifdef CYGPKG_IO_SERIAL_TERMIOS_TERMIOS1
static struct termios_private_info termios_private_info1;
DEVTAB_ENTRY(termios_io1,
"/dev/termios1",
CYGDAT_IO_SERIAL_TERMIOS_TERMIOS1_DEV,
&termios_devio,
termios_init,
termios_lookup,
&termios_private_info1);
#endif
 
#ifdef CYGPKG_IO_SERIAL_TERMIOS_TERMIOS2
static struct termios_private_info termios_private_info2;
DEVTAB_ENTRY(termios_io2,
"/dev/termios2",
CYGDAT_IO_SERIAL_TERMIOS_TERMIOS2_DEV,
&termios_devio,
termios_init,
termios_lookup,
&termios_private_info2);
#endif
 
static const cc_t c_cc_init[ NCCS ] = {
0x04, /* EOF == ^D */
0, /* EOL */
0x08, /* ERASE = BS ; NB DEL=0x7f */
0x03, /* INTR = ^C */
0x15, /* KILL = ^U */
0, /* MIN = 0 */
0x1c, /* QUIT = ^\ */
0x1a, /* SUSP = ^Z ; NB ignored in this impl - no job control */
0, /* TIME = 0 */
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE
CYGDAT_IO_SERIAL_FLOW_CONTROL_XON_CHAR,
CYGDAT_IO_SERIAL_FLOW_CONTROL_XOFF_CHAR,
#else
17,
19,
#endif
};
 
// map eCos bitrates to POSIX bitrates.
static speed_t ecosbaud2posixbaud[] = {
0, B50, B75, B110, B134, B150, B200, B300, B600, B1200, B2400, B3600,
B4800, B7200, B9600, B14400, B19200, B38400, B57600, B115200, B230400 };
 
// map POSIX bitrates to eCos bitrates.
static cyg_serial_baud_rate_t posixbaud2ecosbaud[] = {
0, CYGNUM_SERIAL_BAUD_50, CYGNUM_SERIAL_BAUD_75, CYGNUM_SERIAL_BAUD_110,
CYGNUM_SERIAL_BAUD_134_5, CYGNUM_SERIAL_BAUD_150, CYGNUM_SERIAL_BAUD_200,
CYGNUM_SERIAL_BAUD_300, CYGNUM_SERIAL_BAUD_600, CYGNUM_SERIAL_BAUD_1200,
CYGNUM_SERIAL_BAUD_1800, CYGNUM_SERIAL_BAUD_2400, CYGNUM_SERIAL_BAUD_3600,
CYGNUM_SERIAL_BAUD_4800, CYGNUM_SERIAL_BAUD_7200, CYGNUM_SERIAL_BAUD_9600,
CYGNUM_SERIAL_BAUD_14400, CYGNUM_SERIAL_BAUD_19200,
CYGNUM_SERIAL_BAUD_38400, CYGNUM_SERIAL_BAUD_57600,
CYGNUM_SERIAL_BAUD_115200, CYGNUM_SERIAL_BAUD_230400 };
 
 
//==========================================================================
// FUNCTIONS
 
static __inline__ speed_t
map_ecosbaud_to_posixbaud( cyg_serial_baud_rate_t ebaud )
{
if ( ebaud > (sizeof(ecosbaud2posixbaud) / sizeof(speed_t)) )
return 0;
return ecosbaud2posixbaud[ ebaud ];
}
 
static __inline__ cyg_serial_baud_rate_t
map_posixbaud_to_ecosbaud( speed_t pbaud )
{
if ( pbaud > (sizeof(posixbaud2ecosbaud)/sizeof(cyg_serial_baud_rate_t)) )
return 0;
return posixbaud2ecosbaud[ pbaud ];
}
 
//==========================================================================
// real_termios_init is used to initialize the termios structure. This is
// called at lookup time, and not from termios_init() because it needs
// to query the serial device which may not be set up yet at that point
// in termios_init()
 
#ifdef CYGSEM_IO_SERIAL_TERMIOS_USE_SIGNALS
# define C_IFLAG_INIT (ICRNL|IGNBRK|BRKINT)
#else
# define C_IFLAG_INIT (ICRNL|IGNBRK)
#endif
#define C_OFLAG_INIT (ONLCR)
#define C_CFLAG_INIT (CREAD)
#define C_LFLAG_INIT (ECHO|ECHOE|ECHOK|ICANON)
 
static Cyg_ErrNo
real_termios_init( struct termios_private_info *priv )
{
Cyg_ErrNo res;
struct termios *t;
cyg_serial_info_t dev_conf;
cyg_serial_buf_info_t dev_buf_conf;
cyg_uint32 len = sizeof( dev_conf );
 
CYG_REPORT_FUNCTYPE("returning %d");
CYG_REPORT_FUNCARG1XV( priv );
CYG_CHECK_DATA_PTRC( priv );
 
t = &priv->termios;
 
// Get info from driver
res = cyg_io_get_config( priv->dev_handle, CYG_IO_GET_CONFIG_SERIAL_INFO,
&dev_conf, &len );
if ( ENOERR == res ) {
len = sizeof( dev_buf_conf );
res = cyg_io_get_config( priv->dev_handle,
CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO,
&dev_buf_conf, &len );
}
 
priv->errbuf = (cyg_uint8 *)malloc( dev_buf_conf.rx_bufsize );
if ( NULL == priv->errbuf )
res = ENOMEM; // FIXME: Are we allowed to do this?
priv->errbufpos = priv->errbuf;
priv->errbufsize = dev_buf_conf.rx_bufsize;
 
if ( ENOERR != res ) {
CYG_REPORT_RETVAL( res );
return res;
}
// we only support symmetric baud rates
t->c_ispeed = t->c_ospeed = map_ecosbaud_to_posixbaud( dev_conf.baud );
t->c_iflag = C_IFLAG_INIT;
t->c_oflag = C_OFLAG_INIT;
t->c_cflag = C_CFLAG_INIT;
t->c_lflag = C_LFLAG_INIT;
memcpy( t->c_cc, c_cc_init, sizeof( t->c_cc ) );
switch ( dev_conf.parity ) {
case CYGNUM_SERIAL_PARITY_NONE:
t->c_iflag |= IGNPAR;
break;
case CYGNUM_SERIAL_PARITY_ODD:
t->c_cflag |= PARODD;
// DROPTHROUGH
case CYGNUM_SERIAL_PARITY_EVEN:
t->c_iflag |= PARENB;
break;
default:
CYG_FAIL( "Unsupported default parity" );
break;
}
 
switch( dev_conf.word_length ) {
case CYGNUM_SERIAL_WORD_LENGTH_5:
t->c_cflag |= CS5;
break;
case CYGNUM_SERIAL_WORD_LENGTH_6:
t->c_cflag |= CS6;
break;
case CYGNUM_SERIAL_WORD_LENGTH_7:
t->c_cflag |= CS7;
break;
case CYGNUM_SERIAL_WORD_LENGTH_8:
t->c_cflag |= CS8;
break;
default:
CYG_FAIL( "Unsupported word length" );
break;
}
 
switch ( dev_conf.stop ) {
case CYGNUM_SERIAL_STOP_1:
// Don't need to do anything
break;
case CYGNUM_SERIAL_STOP_2:
t->c_cflag |= CSTOPB;
break;
default:
CYG_FAIL( "Unsupported number of stop bits" );
break;
}
 
switch ( dev_conf.flags ) {
case CYGNUM_SERIAL_FLOW_RTSCTS_RX:
t->c_cflag |= CRTSCTS;
// drop through
case CYGNUM_SERIAL_FLOW_XONXOFF_RX:
t->c_iflag |= IXOFF;
break;
case CYGNUM_SERIAL_FLOW_RTSCTS_TX:
t->c_cflag |= CRTSCTS;
// drop through
case CYGNUM_SERIAL_FLOW_XONXOFF_TX:
t->c_iflag |= IXON;
break;
default:
// Ignore flags we don't grok
break;
}
 
return ENOERR;
} // real_termios_init()
 
//==========================================================================
// set_attr() actually enacts the termios config. We come in here with
// the mutex in priv locked
//
// Possible deviation from standard: POSIX says we should enact which ever
// bits we can and only return EINVAL when none of them can be performed
// Rather than tracking whether *none* of them worked, instead we just
// always claim success. At the very least, setting c_cc is never to
// fail so I'm not sure if this is really non-standard or not!
 
static Cyg_ErrNo
set_attr( struct termios *t, struct termios_private_info *priv )
{
Cyg_ErrNo res = ENOERR;
cyg_serial_info_t dev_conf, new_dev_conf;
cyg_uint32 len = sizeof( dev_conf );
cc_t *tempcc = &priv->termios.c_cc[0];
struct termios *ptermios = &priv->termios;
// Get info from driver
res = cyg_io_get_config( priv->dev_handle, CYG_IO_GET_CONFIG_SERIAL_INFO,
&dev_conf, &len );
 
if ( ENOERR != res )
return res;
// We need to set up each facet of config to change one by one because
// POSIX says we should try and change as much of the config as possible
// This is tedious and has to be done by steam :-(
 
if ( t->c_ospeed != ptermios->c_ospeed ) {
new_dev_conf = dev_conf;
new_dev_conf.baud = map_posixbaud_to_ecosbaud( t->c_ospeed );
if ( 0 != new_dev_conf.baud ) {
len = sizeof( new_dev_conf );
res = cyg_io_set_config( priv->dev_handle,
CYG_IO_SET_CONFIG_SERIAL_INFO,
&new_dev_conf, &len );
if ( ENOERR == res ) {
// It worked, so update dev_conf to reflect the new state
dev_conf.baud = new_dev_conf.baud;
// and termios
ptermios->c_ispeed = t->c_ospeed;
ptermios->c_ospeed = t->c_ospeed;
}
}
}
 
if ( (t->c_cflag & CSTOPB) != (ptermios->c_cflag & CSTOPB) ) {
new_dev_conf = dev_conf;
if ( t->c_cflag & CSTOPB )
new_dev_conf.stop = CYGNUM_SERIAL_STOP_2;
else
new_dev_conf.stop = CYGNUM_SERIAL_STOP_1;
len = sizeof( new_dev_conf );
res = cyg_io_set_config( priv->dev_handle,
CYG_IO_SET_CONFIG_SERIAL_INFO,
&new_dev_conf, &len );
if ( ENOERR == res ) {
// It worked, so update dev_conf to reflect the new state
dev_conf.stop = new_dev_conf.stop;
// and termios
ptermios->c_cflag &= ~CSTOPB;
ptermios->c_cflag |= t->c_cflag & CSTOPB;
}
}
 
if ( ((t->c_cflag & PARENB) != (ptermios->c_cflag & PARENB)) ||
((t->c_cflag & PARODD) != (ptermios->c_cflag & PARODD)) ) {
new_dev_conf = dev_conf;
if ( t->c_cflag & PARENB )
if ( t->c_cflag & PARODD )
new_dev_conf.parity = CYGNUM_SERIAL_PARITY_ODD;
else
new_dev_conf.parity = CYGNUM_SERIAL_PARITY_EVEN;
else
new_dev_conf.parity = CYGNUM_SERIAL_PARITY_NONE;
len = sizeof( new_dev_conf );
res = cyg_io_set_config( priv->dev_handle,
CYG_IO_SET_CONFIG_SERIAL_INFO,
&new_dev_conf, &len );
if ( ENOERR == res ) {
// It worked, so update dev_conf to reflect the new state
dev_conf.parity = new_dev_conf.parity;
// and termios
ptermios->c_cflag &= ~(PARENB|PARODD);
ptermios->c_cflag |= t->c_cflag & (PARENB|PARODD);
}
}
 
if ( (t->c_cflag & CSIZE) != (ptermios->c_cflag & CSIZE) ) {
new_dev_conf = dev_conf;
switch ( t->c_cflag & CSIZE ) {
case CS5:
new_dev_conf.word_length = CYGNUM_SERIAL_WORD_LENGTH_5;
break;
case CS6:
new_dev_conf.word_length = CYGNUM_SERIAL_WORD_LENGTH_6;
break;
case CS7:
new_dev_conf.word_length = CYGNUM_SERIAL_WORD_LENGTH_7;
break;
case CS8:
new_dev_conf.word_length = CYGNUM_SERIAL_WORD_LENGTH_8;
break;
}
len = sizeof( new_dev_conf );
res = cyg_io_set_config( priv->dev_handle,
CYG_IO_SET_CONFIG_SERIAL_INFO,
&new_dev_conf, &len );
if ( ENOERR == res ) {
// It worked, so update dev_conf to reflect the new state
dev_conf.word_length = new_dev_conf.word_length;
// and termios
ptermios->c_cflag &= ~CSIZE;
ptermios->c_cflag |= t->c_cflag & CSIZE;
}
}
 
if ( (t->c_cflag & IXOFF) != (ptermios->c_cflag & IXOFF) ) {
new_dev_conf = dev_conf;
new_dev_conf.flags &=
~(CYGNUM_SERIAL_FLOW_XONXOFF_RX|CYGNUM_SERIAL_FLOW_RTSCTS_RX);
if ( t->c_cflag & IXOFF )
if ( t->c_cflag & CRTSCTS)
new_dev_conf.flags |= CYGNUM_SERIAL_FLOW_RTSCTS_RX;
else
new_dev_conf.flags |= CYGNUM_SERIAL_FLOW_XONXOFF_RX;
else
new_dev_conf.flags |= CYGNUM_SERIAL_FLOW_NONE;
len = sizeof( new_dev_conf );
res = cyg_io_set_config( priv->dev_handle,
CYG_IO_SET_CONFIG_SERIAL_INFO,
&new_dev_conf, &len );
if ( ENOERR == res ) {
// It worked, so update dev_conf to reflect the new state
dev_conf.flags = new_dev_conf.flags;
// and termios
ptermios->c_cflag &= ~(IXOFF|CRTSCTS);
ptermios->c_cflag |= t->c_cflag & (IXOFF|CRTSCTS);
}
}
 
if ( (t->c_cflag & IXON) != (ptermios->c_cflag & IXON) ) {
new_dev_conf = dev_conf;
new_dev_conf.flags &=
~(CYGNUM_SERIAL_FLOW_XONXOFF_TX|CYGNUM_SERIAL_FLOW_RTSCTS_TX);
if ( t->c_cflag & IXON )
if ( t->c_cflag & CRTSCTS)
new_dev_conf.flags |= CYGNUM_SERIAL_FLOW_RTSCTS_TX;
else
new_dev_conf.flags |= CYGNUM_SERIAL_FLOW_XONXOFF_TX;
else
new_dev_conf.flags |= CYGNUM_SERIAL_FLOW_NONE;
len = sizeof( new_dev_conf );
res = cyg_io_set_config( priv->dev_handle,
CYG_IO_SET_CONFIG_SERIAL_INFO,
&new_dev_conf, &len );
if ( ENOERR == res ) {
// It worked, so update dev_conf to reflect the new state
dev_conf.flags = new_dev_conf.flags;
// and termios
ptermios->c_cflag &= ~(IXON|CRTSCTS);
ptermios->c_cflag |= t->c_cflag & (IXON|CRTSCTS);
}
}
 
// Input/Output processing flags can just be set as we grok them all
// with few exceptions (see lflags below)
ptermios->c_iflag &= ~(BRKINT|ICRNL|IGNBRK|IGNCR|IGNPAR|INLCR|INPCK|
ISTRIP|PARMRK);
ptermios->c_iflag |= t->c_iflag & (
#ifdef CYGSEM_IO_SERIAL_TERMIOS_USE_SIGNALS
BRKINT|
#endif
ICRNL|IGNBRK|IGNCR|IGNPAR|
INLCR|INPCK|ISTRIP|PARMRK );
ptermios->c_oflag &= ~(OPOST|ONLCR);
ptermios->c_oflag |= t->c_oflag & (OPOST|ONLCR);
 
ptermios->c_cflag &= ~(CLOCAL|CREAD|HUPCL);
ptermios->c_cflag |= t->c_cflag & (CLOCAL|CREAD|HUPCL);
 
ptermios->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON|
IEXTEN|ISIG|NOFLSH|TOSTOP);
// Note we don't support IEXTEN nor TOSTOP so we don't set them
ptermios->c_lflag |= t->c_lflag & (ECHO|ECHOE|ECHOK|ECHONL|ICANON|
#ifdef CYGSEM_IO_SERIAL_TERMIOS_USE_SIGNALS
ISIG|
#endif
NOFLSH);
 
// control characters. We don't support changing of VSTART, VSTOP,
// VTIME or VSUSP though
tempcc[VEOF] = t->c_cc[VEOF];
tempcc[VEOL] = t->c_cc[VEOL];
tempcc[VERASE] = t->c_cc[VERASE];
tempcc[VINTR] = t->c_cc[VINTR];
tempcc[VKILL] = t->c_cc[VKILL];
tempcc[VMIN] = t->c_cc[VMIN];
tempcc[VQUIT] = t->c_cc[VQUIT];
return res;
}
 
//==========================================================================
 
static bool
termios_init(struct cyg_devtab_entry *tab)
{
// can't initialize the termios structure because we can't
// query the serial driver yet. Wait until lookup time.
 
return true;
} // termios_init()
 
//==========================================================================
 
static Cyg_ErrNo
termios_lookup(struct cyg_devtab_entry **tab,
struct cyg_devtab_entry *sub_tab,
const char *name)
{
cyg_io_handle_t chan = (cyg_io_handle_t)sub_tab;
struct termios_private_info *priv =
(struct termios_private_info *)(*tab)->priv;
Cyg_ErrNo err = ENOERR;
if ( !priv->init ) {
cyg_drv_mutex_lock( &priv->lock );
if ( !priv->init ) { // retest as we may have been pre-empted
priv->dev_handle = chan;
err = real_termios_init( priv );
}
cyg_drv_mutex_unlock( &priv->lock );
}
return err;
}
 
//==========================================================================
 
#define WRITE_BUFSIZE 100 // FIXME: ->CDL
// #define MAX_CANON 64 FIXME: relevance?
 
 
static Cyg_ErrNo
termios_write(cyg_io_handle_t handle, const void *_buf, cyg_uint32 *len)
{
cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
struct termios_private_info *priv = (struct termios_private_info *)t->priv;
cyg_io_handle_t chan = (cyg_io_handle_t)priv->dev_handle;
cyg_int32 xbufsize, input_bytes_read;
cyg_uint8 xbuf[WRITE_BUFSIZE];
cyg_uint8 *buf = (cyg_uint8 *)_buf;
Cyg_ErrNo res;
 
xbufsize = input_bytes_read = 0;
while (input_bytes_read++ < *len) {
if ( (*buf == '\n') && (priv->termios.c_oflag & (OPOST|ONLCR)) ) {
xbuf[xbufsize++] = '\r';
}
xbuf[xbufsize++] = *buf;
if ((xbufsize >= (WRITE_BUFSIZE-1)) || (input_bytes_read == *len) ||
(*buf == '\n'))
{
cyg_int32 size = xbufsize;
res = cyg_io_write(chan, xbuf, &size);
if (res != ENOERR) {
*len = input_bytes_read - (xbufsize - size);
return res;
}
xbufsize = 0;
}
buf++;
}
// Everything sent, so *len is correct.
return ENOERR;
}
 
 
//==========================================================================
 
static Cyg_ErrNo
termios_read(cyg_io_handle_t handle, void *_buf, cyg_uint32 *len)
{
cyg_devtab_entry_t *dt = (cyg_devtab_entry_t *)handle;
struct termios_private_info *priv = (struct termios_private_info *)dt->priv;
cyg_io_handle_t chan = (cyg_io_handle_t)priv->dev_handle;
struct termios *t = &priv->termios;
cyg_uint32 clen;
cyg_uint32 size;
Cyg_ErrNo res;
cyg_uint8 c;
cyg_uint8 *buf = (cyg_uint8 *)_buf;
cyg_bool discardc; // should c be discarded (not read, not printed)
cyg_bool returnnow = false; // return back to user after this char
// if receiver off
if (0 == (t->c_cflag & CREAD) ) {
*len = 0;
return -EINVAL;
}
 
size = 0;
if ( 0 == (t->c_lflag & ICANON) ) {
// In non-canonical mode we return the min of *len and the
// number of bytes available
// So we query the driver for how many bytes are available - this
// guarantees we won't block
cyg_serial_buf_info_t dev_buf_conf;
cyg_uint32 dbc_len = sizeof( dev_buf_conf );
res = cyg_io_get_config( chan,
CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO,
&dev_buf_conf, &dbc_len );
CYG_ASSERT( res == ENOERR, "Query buffer status failed!" );
*len = *len < dev_buf_conf.rx_count ? *len : dev_buf_conf.rx_count;
} // if
 
while (!returnnow && size < *len) {
clen = 1;
discardc = false;
res = cyg_io_read(chan, &c, &clen);
if (res != ENOERR) {
*len = size;
return res;
}
 
// lock to prevent termios getting corrupted while we read from it
cyg_drv_mutex_lock( &priv->lock );
 
if ( t->c_iflag & ISTRIP )
c &= 0x7f;
 
// canonical mode: erase, kill, and newline processing
if ( t->c_lflag & ICANON ) {
if ( t->c_cc[ VERASE ] == c ) {
discardc = true;
// erase on display?
if ( (t->c_lflag & ECHO) && (t->c_lflag & ECHOE) ) {
cyg_uint8 erasebuf[3];
erasebuf[0] = erasebuf[2] = t->c_cc[ VERASE ];
erasebuf[1] = ' ';
clen = sizeof(erasebuf);
// FIXME: what about error or non-blocking?
cyg_io_write(chan, erasebuf, &clen);
}
if ( size )
size--;
} // if
else if ( t->c_cc[ VKILL ] == c ) {
// kill line on display?
if ( (t->c_lflag & ECHO) && (t->c_lflag & ECHOK) ) {
 
// we could try and be more efficient here and
// output a stream of erases, and then a stream
// of spaces and then more erases. But this is poor
// because on a slow terminal the user will see characters
// delete from the middle forward in chunks!
// But at least we try and chunk up sets of writes
cyg_uint8 erasebuf[30];
cyg_uint8 erasechunks;
cyg_uint8 i;
 
erasechunks = size < (sizeof(erasebuf)/3) ?
size : (sizeof(erasebuf)/3);
 
for (i=0; i<erasechunks; i++) {
erasebuf[i*3] = erasebuf[i*3+2] = t->c_cc[ VERASE ];
erasebuf[i*3+1] = ' ';
}
 
while( size ) {
cyg_uint8 j;
 
j = size < (sizeof(erasebuf)/3) ?
size : (sizeof(erasebuf)/3);
clen = (j*3);
// FIXME: what about error or non-blocking?
cyg_io_write( chan, erasebuf, &clen );
size -= j;
}
} else
size = 0;
discardc = true;
} // else if
// CR
else if ( '\r' == c ) {
if ( t->c_iflag & IGNCR )
discardc = true;
else if ( t->c_iflag & ICRNL )
c = '\n';
}
// newlines or similar.
// Note: not an else if to catch CRNL conversion
if ( (t->c_cc[ VEOF ] == c) || (t->c_cc[ VEOL ] == c) ||
('\n' == c) ) {
if ( t->c_cc[ VEOF ] == c )
discardc = true;
if ( t->c_lflag & ECHONL ) { // don't check ECHO in this case
clen = 1;
// FIXME: what about error or non-blocking?
// FIXME: what if INLCR is set?
cyg_io_write( chan, "\n", &clen );
}
if ( t->c_iflag & INLCR )
c = '\r';
returnnow = true; // FIXME: true even for INLCR?
} // else if
} else { // non-canonical mode
if ( t->c_cc[ VMIN ] && (size+1 >= t->c_cc[ VMIN ]) )
returnnow = true;
} // else
 
#ifdef CYGSEM_IO_SERIAL_TERMIOS_USE_SIGNALS
if ( (t->c_lflag & ISIG) && (t->c_cc[ VINTR ] == c) ) {
discardc = true;
if ( 0 == (t->c_lflag & NOFLSH) )
size = 0;
// raise could be a non-local jump - we should unlock mutex
cyg_drv_mutex_unlock( &priv->lock );
 
// FIXME: what if raise returns != 0?
raise( SIGINT );
cyg_drv_mutex_lock( &priv->lock );
}
 
if ( (t->c_lflag & ISIG) && (t->c_cc[ VQUIT ] == c) ) {
discardc = true;
if ( 0 == (t->c_lflag & NOFLSH) )
size = 0;
// raise could be a non-local jump - we should unlock mutex
cyg_drv_mutex_unlock( &priv->lock );
 
// FIXME: what if raise returns != 0?
raise( SIGQUIT );
cyg_drv_mutex_lock( &priv->lock );
}
#endif
if (!discardc) {
buf[size++] = c;
if ( t->c_lflag & ECHO ) {
clen = 1;
// FIXME: what about error or non-blocking?
termios_write( handle, &c, &clen );
}
}
cyg_drv_mutex_unlock( &priv->lock );
} // while
 
*len = size;
return ENOERR;
}
 
 
//==========================================================================
 
static cyg_bool
termios_select(cyg_io_handle_t handle, cyg_uint32 which, CYG_ADDRWORD info)
{
cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
struct termios_private_info *priv = (struct termios_private_info *)t->priv;
cyg_io_handle_t chan = (cyg_io_handle_t)priv->dev_handle;
 
// Just pass it on to next driver level
return cyg_io_select( chan, which, info );
}
 
 
//==========================================================================
 
static Cyg_ErrNo
termios_get_config(cyg_io_handle_t handle, cyg_uint32 key, void *buf,
cyg_uint32 *len)
{
cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
struct termios_private_info *priv = (struct termios_private_info *)t->priv;
cyg_io_handle_t chan = (cyg_io_handle_t)priv->dev_handle;
Cyg_ErrNo res = ENOERR;
 
switch (key) {
case CYG_IO_GET_CONFIG_TERMIOS:
{
if ( *len < sizeof(struct termios) ) {
return -EINVAL;
}
cyg_drv_mutex_lock( &priv->lock );
*(struct termios *)buf = priv->termios;
cyg_drv_mutex_unlock( &priv->lock );
*len = sizeof(struct termios);
}
break;
default: // Assume this is a 'serial' driver control
res = cyg_io_get_config(chan, key, buf, len);
} // switch
return res;
}
 
 
//==========================================================================
 
 
static Cyg_ErrNo
termios_set_config(cyg_io_handle_t handle, cyg_uint32 key, const void *buf, cyg_uint32 *len)
{
cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
struct termios_private_info *priv = (struct termios_private_info *)t->priv;
cyg_io_handle_t chan = (cyg_io_handle_t)priv->dev_handle;
Cyg_ErrNo res = ENOERR;
 
switch (key) {
case CYG_IO_SET_CONFIG_TERMIOS:
{
setattr_struct *attr = (setattr_struct *)buf;
int optact = attr->optact;
 
if ( *len != sizeof( *attr ) ) {
return -EINVAL;
}
 
CYG_ASSERT( (optact == TCSAFLUSH) || (optact == TCSADRAIN) ||
(optact == TCSANOW), "Invalid optact" );
cyg_drv_mutex_lock( &priv->lock );
if ( ( TCSAFLUSH == optact ) ||
( TCSADRAIN == optact ) ) {
res = cyg_io_get_config( chan,
CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN,
NULL, NULL );
CYG_ASSERT( ENOERR == res, "Drain request failed" );
}
if ( TCSAFLUSH == optact ) {
res = cyg_io_get_config( chan,
CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH,
NULL, NULL );
CYG_ASSERT( ENOERR == res, "Flush request failed" );
}
res = set_attr( attr->termios_p, priv );
cyg_drv_mutex_unlock( &priv->lock );
return res;
}
default: // Pass on to serial driver
res = cyg_io_set_config(chan, key, buf, len);
}
return res;
}
 
 
//==========================================================================
 
#endif // ifdef CYGPKG_IO_SERIAL_TERMIOS
 
// EOF termiostty.c
/src/common/haldiag.c
0,0 → 1,138
//==========================================================================
//
// io/serial/common/haldiag.c
//
// Serial I/O interface module using HAL I/O routines
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): gthomas
// Contributors: gthomas
// Date: 1999-02-04
// Purpose: HAL/diag serial driver
// Description:
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
#include <pkgconf/io.h>
#include <pkgconf/io_serial.h>
#ifdef CYGPKG_IO_SERIAL_HALDIAG
#include <cyg/io/io.h>
#include <cyg/io/devtab.h>
#include <cyg/io/serial.h>
#include <cyg/infra/diag.h>
#include <cyg/hal/hal_diag.h>
 
static bool haldiag_init(struct cyg_devtab_entry *tab);
static bool haldiag_putc(serial_channel *chan, unsigned char c);
static unsigned char haldiag_getc(serial_channel *chan);
static Cyg_ErrNo haldiag_set_config(serial_channel *chan, cyg_uint32 key,
const void *xbuf, cyg_uint32 *len);
 
static SERIAL_FUNS(haldiag_funs,
haldiag_putc,
haldiag_getc,
haldiag_set_config,
0, // start xmit - not used
0 // stop xmit - not used
);
 
static int _no_data;
static SERIAL_CHANNEL(haldiag_channel0,
haldiag_funs,
_no_data,
CYG_SERIAL_BAUD_DEFAULT,
CYG_SERIAL_STOP_DEFAULT,
CYG_SERIAL_PARITY_DEFAULT,
CYG_SERIAL_WORD_LENGTH_DEFAULT,
CYG_SERIAL_FLAGS_DEFAULT
);
DEVTAB_ENTRY(haldiag_io0,
"/dev/haldiag",
0, // Does not depend on a lower level interface
&cyg_io_serial_devio,
haldiag_init,
0, // No initialization/lookup needed
&haldiag_channel0);
 
static void
haldiag_config_port(serial_channel *chan)
{
}
 
static bool
haldiag_init(struct cyg_devtab_entry *tab)
{
serial_channel *chan = (serial_channel *)tab->priv;
#ifdef CYGDBG_IO_INIT
diag_printf("HAL/diag SERIAL init\n");
#endif
haldiag_config_port(chan);
return true;
}
 
// Return 'true' if character is sent to device
static bool
haldiag_putc(serial_channel *chan, unsigned char c)
{
HAL_DIAG_WRITE_CHAR(c);
return true;
}
 
static unsigned char
haldiag_getc(serial_channel *chan)
{
unsigned char c;
HAL_DIAG_READ_CHAR(c);
return c;
}
 
static Cyg_ErrNo
haldiag_set_config(serial_channel *chan, cyg_uint32 key, const void *xbuf,
cyg_uint32 *len)
{
switch (key) {
case CYG_IO_SET_CONFIG_SERIAL_INFO:
diag_printf("%s\n", __FUNCTION__);
return ENOERR;
default:
return -EINVAL;
}
}
#endif // CYGPKG_IO_SERIAL_HALDIAG
/ChangeLog
0,0 → 1,1452
2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
 
* cdl/io_serial.cdl: Fix doc link.
 
2003-02-14 Jonathan Larmour <jifl@eCosCentric.com>
 
* src/common/termiostty.c: Support VMIN > 0 properly.
 
2002-12-10 Gary Thomas <gthomas@ecoscentric.com>
 
* src/common/tty.c (tty_write): Only return number of characters
in original string which were written - don't include any CR/LF
expansion characters.
 
2002-04-23 Jesper Skov <jskov@redhat.com>
 
* tests/serial3.c (serial_test): Use 19200 baud rate when board
cannot handle 38400.
* tests/serial5.c (serial_test): Same.
 
2002-02-19 Jesper Skov <jskov@redhat.com>
 
* cdl/io_serial.cdl: Removed termiostty.c build rule.
 
* cdl/termios.cdl: Make termiostty.c building depending on actual
requirements for its content.
 
2002-02-15 Jesper Skov <jskov@redhat.com>
 
* tests/flow1.c: Also try DSR/DTR flow control (presently
unsupported by Linux though).
* tests/flow2.c: Same.
 
2002-01-11 Jonathan Larmour <jlarmour@redhat.com>
 
* src/common/termiostty.c (termios_read): Don't return after VMIN,
this was a stupid thing to do and decreases performance a lot.
 
2001-08-15 Gary Thomas <gthomas@redhat.com>
 
* tests/ser_test_protocol.inl: Change NONE in 'cyg_verbosity_level_t'
to be _NONE [unused] to avoid name clash with <kernel/kapi.h>.
 
2000-12-08 Jonathan Larmour <jlarmour@redhat.com>
 
* src/common/serial.c: Fix CYGOPT_IO_SERIAL_FLOW_CONTROL_HW ->
CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS typo when declaring callbacks
Thanks to Brian Danilko for reporting.
 
2000-11-22 Jesper Skov <jskov@redhat.com>
 
* src/common/serial.c: Changed #ifdef to #if used on an interface
option.
 
2000-11-06 Jonathan Larmour <jlarmour@redhat.com>
 
* src/common/tty.c (tty_write): Check buffer size appropriately
since when doing \r\n expansion "size" may have been double
incremented as a result.
Thanks to Alex Mathews of Crosstor for the fix.
 
2000-10-20 Jonathan Larmour <jlarmour@redhat.com>
 
* src/common/serial.c: Include cyg/infra/cyg_ass.h for assertion
support since we have assertions here!
 
2000-10-12 Jesper Skov <jskov@redhat.com>
 
* tests/ser_test_protocol.inl: Moved most testing parameters into
device driver CDL.
 
* cdl/io_serial.cdl: Added comment.
 
2000-10-06 Jesper Skov <jskov@redhat.com>
 
* src/common/serial.c (serial_rcv_char): Register overruns.
* src/common/serial.c: Made block request functions return cause
of failure. Necessary for the device driver to be able to
fall-back to other transfer method efficiently.
* include/serial.h: Added enum with failure types.
 
2000-10-03 Jesper Skov <jskov@redhat.co.uk>
 
* tests/ser_test_protocol.inl: Moved testing parameters to device
driver CDL for SH targets.
 
2000-09-29 Jesper Skov <jskov@redhat.com>
 
* include/serialio.h: Fix compiler warning and errors due to
non-default flow control config.
 
2000-09-27 Jesper Skov <jskov@redhat.com>
 
* src/common/serial.c (serial_data_rcv_done,
serial_data_xmt_done): Buffer pointers updated in _done instead of
in _req to avoid race in xmt. Same change in rcv for consistency.
* include/serial.h: Changed prototype accordingly.
 
2000-09-18 Jesper Skov <jskov@redhat.com>
 
* cdl/io_serial.cdl: Added interfaces to allow test tweaking.
* tests/ser_test_protocol.inl: Use interfaces. Moved PID details
to PID serial package.
 
2000-09-15 Jesper Skov <jskov@redhat.com>
 
* tests/ser_test_protocol.inl: Allow drivers to define testing
parameters via CDL.
 
2000-09-13 Jesper Skov <jskov@redhat.com>
 
* include/serial.h (SERIAL_CALLBACKS): Fix typo.
 
2000-09-06 Jesper Skov <jskov@redhat.com>
 
* tests/ser_test_protocol.inl: Renamed some option names due to SH
serial driver reorg.
 
2000-08-09 Jonathan Larmour <jlarmour@redhat.co.uk>
 
* src/common/serial.c (serial_indicate_status): Treat flow control
case conditionally
 
2000-08-08 Jonathan Larmour <jlarmour@redhat.co.uk>
 
* src/common/serial.c (serial_data_rcv_req): Adjust nb in correct
direction
 
2000-08-04 Jonathan Larmour <jlarmour@redhat.co.uk>
 
* cdl/io_serial.cdl: Default software flow control to on (but keep
flow control overall default off)
 
* tests/flow1.c (cyg_start): Fix N_A_MSG -> NA_MSG typo
* tests/flow2.c (cyg_start): Ditto
 
2000-08-03 Jonathan Larmour <jlarmour@redhat.co.uk>
 
* cdl/io_serial.cdl: Should default flow control to off
 
* src/common/serial.c (serial_data_xmt_req): Update cbuf->nb
(serial_data_rcv_req): Update cbuf->nb
 
2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
 
* cdl/io_serial.cdl: Add support for line status queries,
software flow control, hardware flow control and POSIX termios
* include/serial.h: Likewise. Also change prototype for set_config
hardware operations to use keys to be more flexible.
* include/serialio.h: Add lots of types and constants to support
new line status and flow control config key queries
* src/common/haldiag.c (haldiag_set_config): Use keys to be more
flexible.
 
* src/common/serial.c: Many changes to support software/hardware
flow control (with low and high water points), line status and
fix some omissions with select. Also fix bugs in block transfer
functions resulting from EL/IX merge.
 
* tests/flow1.c, tests/flow2.c: New tests for flow control
 
* cdl/termios.cdl: Add to configure termios
* src/termios.c: Add new POSIX Termios API
* src/termiostty.c: Add POSIX Termios tty driver
 
* tests/ser_test_protocol.inl (change_config): Add support for
hardware and software flow control testing, indicated to the
host by an extra CONFIG argument.
 
* tests/serial3.c: Add flow control config
* tests/serial5.c: Add flow control config
 
2000-07-31 Nick Garnett <nickg@cygnus.co.uk>
 
* src/common/serial.c: Changed BLOCKING control definitions to
generic versions.
 
2000-07-03 Jesper Skov <jskov@redhat.com>
 
* src/common/serial.c (serial_data_rcv_req): Fix off-by-1 bug.
 
2000-06-23 Jesper Skov <jskov@redhat.com>
 
* tests/ser_test_protocol.inl: Added cq7708 definitions.
 
2000-06-19 Nick Garnett <nickg@cygnus.co.uk>
 
* include/serial.h:
* src/common/serial.c:
Added nb field to cbuf_t structure. This keeps track of the number of
bytes currently in the buffer. Without this counter, there is no
way to distinguish a totally full buffer from one that is totally
empty, since in both cases put==get.
 
2000-06-15 Nick Garnett <nickg@cygnus.co.uk>
 
* include/serial.h: Added selinfo field to cbuf structure when
select support is enabled.
 
* src/common/serial.c:
* src/common/tty.c:
Added select support.
 
* cdl/io_serial.cdl: Added CYGPKG_IO_SERIAL_SELECT_SUPPORT to
enable select() support. Defaults to on.
Also added component for loopback driver.
 
* tests/ser_test_protocol.inl: Added test setup for loopback
driver.
 
2000-05-28 Gary Thomas <gthomas@redhat.com>
 
* tests/ser_test_protocol.inl: Rename NEC V85x drivers.
 
2000-05-25 Jesper Skov <jskov@redhat.com>
 
* tests/ser_test_protocol.inl: Added rules for REF4955.
 
2000-05-08 Jesper Skov <jskov@redhat.com>
 
* cdl/io_serial.cdl: active_if CYGPKG_IO
 
2000-05-05 Jonathan Larmour <jlarmour@redhat.co.uk>
 
* src/common/serial.c (serial_get_config): Tidy below change a little
 
2000-05-05 Grant Edwards <grante@visi.com>
 
* src/common/serial.c (serial_get_config): Support
CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO key to get buffer information
 
* include/serialio.h: Add cyg_serial_buf_info_t
 
2000-05-04 Jesper Skov <jskov@redhat.com>
 
* cdl/io_serial.cdl: Only build tests when drivers enabled.
 
2000-05-02 Jesper Skov <jskov@redhat.com>
 
* src/common/serial.c (serial_set_config): Set proper parity for
blocking options.
(serial_get_config): Fix copy'n'paste buglet.
2000-05-01 Jesper Skov <jskov@redhat.com>
 
* src/common/serial.c: Added non-blocking config and operation for
read/write calls.
Added block transfer rcv/xmt callbacks.
Added (disabled for now) check for rcv overflow. [need to add
handling]
* include/serial.h: Added non-blocking callbacks.
 
* cdl/io_serial.cdl: Added non-blocking option. Added block
transfer interface.
 
2000-04-17 Hugo Tyson <hmt@cygnus.co.uk>
 
* src/PKGconf.mak: remove; it's obsolete.
 
2000-04-13 Gary Thomas <gthomas@redhat.com>
 
* src/common/serial.c (serial_write): Make safer - only call
'start_xmit' with DSRs disabled.
 
2000-04-11 Hugo Tyson <hmt@cygnus.co.uk>
 
* cdl/io_serial.cdl (CYGPKG_IO_SERIAL_DEVICES): New package which
is a container and control for the real device drivers.
 
2000-04-11 Jesper Skov <jskov@redhat.com>
 
* cdl/io_serial.cdl: Bad hack to build separate test.
* tests/serial_echo.c: Added.
 
2000-04-11 Hugo Tyson <hmt@cygnus.co.uk>
 
* cdl/ser_.... (driver-specific cdl files):
Remove all these; they are no longer needed following the change
below. They do exist in devs/serial/ARCH/PLATFORM/VERSION/cdl/
directories various instead.
 
2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
 
* ecos.db: Re-organize device packages. This is a massive change
involving deleting all the sources for serial and ethernet drivers
from where they used to live in
packages/io/serial/current/src/ARCH/PLATFORM.[ch]
packages/net/drivers/eth/PLATFORM/current/src/...
and reinstating them in
packages/devs/serial/ARCH/PLATFORM/current/src/...
packages/devs/eth/ARCH/PLATFORM/current/src/...
 
All these new packages are properly defined in ecos.db, and are
all of type "hardware" so that a "target" can grab them.
This directory layout is descriptive of the devices we have right
now, arch and platform are separate levels just to make it easier
to navigate in the filesystem and similar to the HAL structure in
the filesystem.
 
It is *not* prescriptive of future work; for example, the mythical
common highly-portable 16550 serial driver which works on many
targets would be called "devs/serial/s16550/current", or a serial
device for a particular board (cogent springs to mind) that can
work with different CPUs fitted is "devs/serial/cogent/current".
 
Changelogs have been preserved and replicated over all the new
packages, so that no history is lost.
 
The contents of individual source files are unchanged; they build
in just the same emvironment except for a very few cases where the
config file name changed in this movement.
 
Targets in ecos.db have been redefined to bring in all relevant
hardware packages including net and serial drivers (but the newly
included packages are only active if their desired parent is
available.)
The names of CDL options (and their #defines of course) stay the
same for the serial drivers, for backward compatibility.
 
* templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
rather than it being in (almost) all target definitions.
2000-04-07 Jonathan Larmour <jlarmour@redhat.co.uk>
 
* src/common/tty.c (tty_read): Correct handling of modes with newlines
 
2000-04-05 Jonathan Larmour <jlarmour@redhat.co.uk>
 
* src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r
(tty_write): Similarly
 
* include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and
CYG_TTY_IN_FLAGS_CRLF to match
 
2000-03-31 Jesper Skov <jskov@redhat.com>
 
* cdl/ser_sh_edk7708.cdl: Limit legal baud rate range.
* src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired
constants.
 
2000-03-28 John Dallaway <jld@cygnus.co.uk>
 
* cdl/io_serial.cdl,
cdl/ser_arm_aeb.cdl,
cdl/ser_arm_cma230.cdl,
cdl/ser_arm_edb7xxx.cdl,
cdl/ser_arm_pid.cdl,
cdl/ser_i386_pc.cdl,
cdl/ser_mips_jmr3904.cdl,
cdl/ser_mips_vrc4373.cdl,
cdl/ser_mn10300.cdl,
cdl/ser_powerpc_cogent.cdl,
cdl/ser_quicc_smc.cdl,
cdl/ser_sh_edk7708.cdl,
cdl/ser_sparclite_sleb.cdl,
cdl/tty.cdl:
 
Adjust documentation URLs.
 
2000-03-07 Jesper Skov <jskov@redhat.com>
 
* cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming.
 
2000-02-29 Jonathan Larmour <jlarmour@redhat.co.uk>
 
* include/serialio.h: Correct baud rate typo: 230400 rather than
234000. Thanks to Grant Edwards for the report.
 
2000-02-28 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'.
 
2000-02-28 Jesper Skov <jskov@redhat.com>
 
* tests/ser_test_protocol.inl: Allow 115200 baud on Cogent
again. Fixed interrupt problem.
 
2000-02-22 Jesper Skov <jskov@redhat.com>
 
* tests/ser_test_protocol.inl: Don't use 115200 baud on
Cogent. Our slower boards can't keep up.
 
2000-02-17 Gary Thomas <gthomas@cygnus.co.uk>
 
* cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency.
 
2000-02-16 Nick Garnett <nickg@cygnus.co.uk>
 
* include/pkgconf/io_serial.h:
Added configury for PC serial device drivers.
 
* cdl/ser_i386_pc.cdl:
* src/i386/pc_serial.c:
* src/i386/pc_serial.h:
Added these files to implement PC serial line drivers.
 
* cdl/io_serial.cdl:
Added CYGPKG_IO_SERIAL_I386_PC.
 
* tests/ser_test_protocol.inl:
Added support for PC serial line testing.
2000-02-11 Jesper Skov <jskov@redhat.com>
 
* src/sh/sh_sci_7708.inl (DEVTAB_ENTRY):
* src/sparclite/sleb_sdtr.c:
serial_devio => cyg_io_serial_devio
 
2000-02-10 Jonathan Larmour <jlarmour@redhat.co.uk>
 
* src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_*
preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form
now.
 
2000-02-03 Jesper Skov <jskov@redhat.com>
 
* src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_...
 
2000-02-02 Jonathan Larmour <jlarmour@redhat.co.uk>
 
* src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper
case macros
 
* src/arm/aeb_serial.c: Update to reflect above
 
2000-01-31 Simon FitzMaurice <sdf@cygnus.co.uk>
* cdl/*.cdl:
 
Adjust help URLs in line with new doc layout.
2000-01-28 Simon FitzMaurice <sdf@cygnus.co.uk>
* cdl/*.cdl:
 
Adjust help URLs in line with new doc layout.
2000-01-28 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/common/tty.c (tty_read): Fix problem with backspace at start
of line (size must be 'signed' for compare to work).
 
2000-01-19 Hugo Tyson <hmt@cygnus.co.uk>
 
* cdl/*.cdl: Add descriptions to a number of options &c which were
lacking same, also tidied up other typos as noticed en passant.
 
2000-01-17 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at
start of line.
 
2000-01-05 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/common/serial.c (serial_write): Avoid potential deadlock if
transmit start actually sends enough characters to signal cond wait.
 
2000-01-03 Gary Thomas <gthomas@cygnus.co.uk>
 
* include/serial.h: Fix namespace pollution -
serial_devio => cyg_io_serial_devio
serial_callbacks => cyg_io_serial_callbacks
 
* src/mips/tx3904_serial.c:
* src/mips/vrc4373_serial.c:
* src/mn10300/mn10300_serial.c:
* src/powerpc/quicc_smc_serial.c:
* src/powerpc/cogent_serial_with_ints.c:
* src/sparclite/sleb_sdtr.c:
* src/arm/aeb_serial.c:
* src/arm/pid_serial_with_ints.c:
* src/arm/edb7xxx_serial.c:
* src/arm/cma230_serial.c:
* src/arm/ebsa285_serial.c:
* src/common/haldiag.c:
* src/common/serial.c: Fix namespace pollution -
serial_devio => cyg_io_serial_devio
 
1999-12-06 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle
case where an interrupt represents multiple events.
 
1999-11-19 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong.
 
1999-11-18 Gary Thomas <gthomas@cygnus.co.uk>
 
* include/pkgconf/io_serial.h: Remove mention of 7209/7212.
 
1999-11-03 John Dallaway <jld@cygnus.co.uk>
 
* cdl/io_serial.cdl: Define build options.
 
1999-10-26 Jesper Skov <jskov@cygnus.co.uk>
* tests/serial5.c (serial_test): Reduce speed in thumb mode.
 
* src/arm/pid_serial.h: Added BE support.
 
* src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what
needs to be compiled.
 
1999-10-25 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/arm/pid_serial.h (ISR_RxTO): Define - character received but
not handled "promptly".
 
* src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts
properly (can't ignore them even with TO bit set).
 
* src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all
input (empty input FIFO) otherwise characters get dropped.
 
1999-10-15 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus.
 
1999-10-11 Nick Garnett <nickg@cygnus.co.uk>
 
* tests/ser_test_protocol.inl: Added configury for VR4300 testing.
 
* src/mips/vrc4373_serial.c: Added Bi-endian support.
 
* include/pkgconf/io_serial.h: Adjusted default baud rates to
38400.
 
1999-10-06 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/ser_test_protocol.inl: Run tests on AEB rev C as well.
 
1999-09-28 Hugo Tyson <hmt@cygnus.co.uk>
 
* src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct
value supplied for interrupt priority - it may be unused, but it
is asserted for range. Initialize the diagnostic channel if on an
MBX and if NOT using SMC1 ourselves, to ensure that diag output
and built-in stubs work correctly; otherwise reset the quicc and
ignore SMC1 as before. Fix various warnings, mostly about
casting/arg-passing/assigning away volatile.
 
1999-08-31 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/ser_test_protocol.inl: Define dummy crash ID.
 
1999-08-30 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/ser_test_protocol.inl: Added crash information which
should help track down repeating errors.
 
1999-08-20 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/README: Added.
 
1999-08-18 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/tty1.c:
* tests/tty2.c:
* tests/serial1.c:
* tests/serial2.c:
* tests/serial3.c:
* tests/serial4.c:
* tests/serial5.c:
* tests/PKGconf.mak:
Require kernel and kernel C API.
1999-08-17 Nick Garnett <nickg@cygnus.co.uk>
 
* src/mn10300/mn10300_serial.c: Added a simple implementation of a
receive FIFO to try and reduce the overhead of receiving bytes.
 
1999-08-16 Jonathan Larmour <jlarmour@cygnus.co.uk>
 
* src/PKGconf.mak:
* src/mn10300/mn10300_serial.c:
* tests/ser_test_protocol.inl:
Rename all am32 -> am31
 
1999-08-12 Nick Garnett <nickg@cygnus.co.uk>
 
Imported following changes from development branch:
1999-08-11 Nick Garnett <nickg@cygnus.co.uk>
 
* tests/serial5.c: Modified config test for boards that need a lower
speed for this test.
 
* tests/ser_test_protocol.inl: Removed 14400 baud tests for all
MN10300 variants. The MN10300 cannot currently do this speed.
 
* src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt
enable/disable code to be variant specific.
 
* include/pkgconf/io_serial.h: Undid Jonathan's change, since the
same options are used for all MN10300 variants.
1999-08-10 Jonathan Larmour <jlarmour@cygnus.co.uk>
 
* include/pkgconf/io_serial.h:
Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to
CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific
 
1999-08-04 Nick Garnett <nickg@cygnus.co.uk>
 
* tests/ser_test_protocol.inl:
Changed names of MN10300 defines tested. Added AM33 definitions.
 
* src/mn10300/mn10300_serial.c:
Modified driver to work on am33 too. This simply requires some
alternate definitions of things like register addresses and some
bits in them plus some extra parameterization of some register
values.
 
* src/PKGconf.mak:
Added am33 to list of architectures supporting serial lines.
1999-07-28 Gary Thomas <gthomas@cygnus.co.uk>
 
* include/pkgconf/io_serial.h: Update descriptions to be more
generic (CL7x11 instead of CL7211).
 
1999-07-28 Jonathan Larmour <jlarmour@cygnus.co.uk>
 
* include/pkgconf/io_serial.h: Correct typos in CDL description
for serial port 2 driver
 
1999-07-26 Hugo Tyson <hmt@cygnus.co.uk>
 
* src/arm/ebsa285_serial.c: New file: device driver for the serial
device of the Intel StrongARM EBSA-285 evaluation board.
 
* include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285):
Config for it.
 
* src/PKGconf.mak (EXTRAS_COMPILE): Compile it.
 
* tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it.
 
1999-07-08 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/ser_test_protocol.inl (change_config): Changed implementation.
 
1999-06-27 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust
initialization, with data cache disabled. This seems to fix the
random failures described below.
 
* tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860.
Added some delays in the configuration change code to make QUICC
happy [didn't help much although the manual says they are required].
 
* src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to
match what the Linux driver uses - still doesn't work well, though.
 
* src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the
serial driver working and robust. At this point it works quite well,
using the default buffer sizes. Changing from the defaults seem to
easily break it though, certainly on input. Also, changing the baud
rate seems to not work reliably.
 
* src/common/serial.c: Add some tracing/debug info to try and debug
problems with QUICC serial driver. These are hard disabled with
"XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information
about how/when data are delivered from the serial driver.
 
* include/pkgconf/io_serial.h: Adjust limits and defaults on number and
size of buffers with values that seem to work.
 
1999-06-21 Jesper Skov <jskov@cygnus.co.uk>
 
* src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit
to avoid compiler warnings.
 
1999-06-21 Gary Thomas <gthomas@cygnus.co.uk>
 
* include/pkgconf/io_serial.h: Fix CDL for number of buffers.
 
* src/powerpc/quicc_smc_serial.c: Force number of buffers = 1.
 
1999-06-20 Gary Thomas <gthomas@cygnus.co.uk>
 
* include/pkgconf/io_serial.h: Some clean up (removed commented
obsolete CDL parenting structure).
Add support for Motorola PowerPC QUICC/SMC.
 
* src/arm/cma230_serial.c:
* src/arm/cl7211_serial.c:
* src/arm/aeb_serial.c:
* src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()'
prototypes.
 
1999-06-17 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which
cause xmitter to get stuck.
 
1999-06-16 Jesper Skov <jskov@cygnus.co.uk>
 
* src/sh/sh_serial.c: [removed]
* src/sh/sh_sci_serial.c: [added]
* src/sh/sh_sci_7708.inl: [added]
* include/pkgconf/io_serial.h:
* src/PKGconf.mak (EXTRAS_COMPILE):
* tests/ser_test_protocol.inl:
Renamed CDL options and restructered driver.
Fixed CDL typo.
1999-06-04 Jesper Skov <jskov@cygnus.co.uk>
 
* include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option.
 
1999-06-04 Gary Thomas <gthomas@cygnus.co.uk>
 
* tests/ser_test_protocol.inl: Disable testing at 115200
for Cogent CMA230 (ARM).
 
* src/arm/cma230_serial.c: Fix interrupt for port B.
 
1999-05-31 Jesper Skov <jskov@cygnus.co.uk>
 
* src/sh/sh_serial.c: Fixed receive interrupts and added handler for
error interrupts.
 
1999-05-28 Jesper Skov <jskov@cygnus.co.uk>
 
* io/serial/current/src/PKGconf.mak:
* io/serial/current/tests/ser_test_protocol.inl:
* include/pkgconf/io_serial.h:
Renamed SH platform package to edk7708.
 
1999-05-27 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/ser_test_protocol.inl: Added ability to change options in
host software.
 
1999-05-27 Jonathan Larmour <jlarmour@cygnus.co.uk>
 
* src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
Wait for the serial device to become acquiescent before disabling
it. This prevents cygmon's outgoing characters getting corrupted
due to transmission being disabled.
Fix for PR 20047
1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
 
* include/pkgconf/io_serial.h:
* tests/ser_test_protocol.inl: Add Cogent CMA230 setup.
* src/arm/cma230_serial.c: Make names compatible with Cogent
PowerPC board.
 
1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
 
* tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup.
1999-05-26 Jesper Skov <jskov@cygnus.co.uk>
 
* src/sh/sh_serial.c: Added more baud rate values. Disabled
interrupt driven receive. Fixed config_port to enable proper
interrupt flags.
 
1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
 
* tests/ser_test_protocol.inl:
Change all mentions of CYGPKG_HAL_TX39_JMR3904 to
CYGPKG_HAL_MIPS_TX39_JMR3904
 
1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
 
* src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to
CYG_HAL_MIPS_TX39
1999-05-25 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/ser_test_protocol.inl: Added sh entry.
 
1999-05-24 Jesper Skov <jskov@cygnus.co.uk>
 
* src/PKGconf.mak:
* include/pkgconf/io_serial.h:
* src/sh/sh_serial.c:
Added sh driver.
 
1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
PR 19926
* src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if
there is one.
 
1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
PR 19926
* src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char
if there is one.
 
1999-05-16 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/arm/cl7211_serial.c: Clean up, first working version.
 
1999-05-14 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/ser_test_protocol.inl: Removed workaround for spurious
Cogent reads.
 
* src/arm/aeb_serial.c:
* src/arm/aeb_serial.h:
* src/arm/pid_serial_with_ints.c:
* src/arm/pid_serial.h:
* src/powerpc/cogent_serial.h:
* src/powerpc/cogent_serial_with_ints.c:
Check for receive interrupt before reading.
 
1999-05-13 Nick Garnett <nickg@cygnus.co.uk>
 
The follow changes were made in a branch an have now been merged:
 
1999-04-21 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/mips/vrc4373_serial.c: Small changes to get working with
interrupts.
1999-04-20 John Dallaway <jld@cygnus.co.uk>
 
* include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904
parent attribute.
 
1999-05-11 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/arm/cl7211_serial.c: Fix compile problems from merged code.
 
1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/ser_test_protocol.inl: Tidied up a bit and added
description of protocol.
 
1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
 
* src/common/serial.c (serial_write, serial_read): Clear abort
flag at entry.
 
1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/serial4.c (serial_test): Handle config fails correctly.
 
* tests/ser_test_protocol.inl: Better change_config
handling. Simple recovery and negotiation isn't timing
dependant.
 
1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/timeout.inl: Updated with the below changes.
 
1999-05-05 Gary Thomas <gthomas@cygnus.co.uk>
 
* misc/timeout.inl (timeout): Timeouts are relative, but alarms
need absolute time values.
 
1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
PR 20018
* tests/serial1.c (serial_test): Always PASS, regardless of
configuration.
 
1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/ser_test_protocol.inl: Reverse order of configurations -
run tests with slow baud rate first.
Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup.
 
1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
* src/mn10300/mn10300_serial.c:
Use interrupt enable/disable feature of serial port2 to allow
coexistence with CygMon/hal_diag.
* tests/ser_test_protocol.inl: Use port2 for MN10300.
 
1999-04-28 Bart Veer <bartv@cygnus.co.uk>
 
* src/PKGconf.mak (EXTRAS_COMPILE):
Use the new rules for generating libextras.a
 
1999-04-26 Gary Thomas <gthomas@cygnus.co.uk>
 
* include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211.
 
 
1999-04-20 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/arm/aeb_serial.c:
* src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered.
1999-04-20 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/ser_test_protocol.inl: Added some comments. Disabled 38400
for SLEB. Only run test on SLEB if CygMon isn't used for diag
output.
1999-04-15 Jesper Skov <jskov@cygnus.co.uk>
PR 19752
* tests/serial3.c:
* tests/serial5.c:
Run these tests at a lower baud rate on ARM AEB.
1999-04-14 Jesper Skov <jskov@cygnus.co.uk>
PR 19839
* src/mn10300/mn10300_serial.c:
Fix compiler warnings.
 
1999-04-14 Bart Veer <bartv@cygnus.co.uk>
 
* include/pkgconf/io_serial.h:
Reparent the board-specific serial devices below the actual boards.
1999-04-13 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/ser_test_protocol.inl:
NA when run from simulator.
 
1999-04-12 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/ser_test_protocol.inl:
Disabled 115200 for MN10300.
Reclaim interrupt vectors from CygMon when testing on SLEB.
 
1999-04-09 Gary Thomas <gthomas@cygnus.co.uk>
 
* include/serial.h: Change SERIAL_CHANNEL setup so all channels
have serial callbacks, regardless of buffering.
 
1999-04-09 Jesper Skov <jskov@cygnus.co.uk>
 
* src/common/tty.c:
* include/pkgconf/io_serial.h:
Added new ttydiag device layered on top of haldiag, so that tty0
can be layered on top of ser0.
 
1999-04-08 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/tty1.c: [added]
* tests/tty2.c: [added]
* tests/PKGconf.mak:
* tests/ser_test_protocol.inl:
Added two simple TTY tests.
 
1999-04-07 Hugo Tyson <hmt@cygnus.co.uk>
 
* src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O
macros instead of hal_diag.h where they had evolved before.
 
1999-04-06 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/serial4.c (serial_test):
* tests/serial3.c (serial_test):
Reduce packet sizes.
 
1999-03-31 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/ser_test_protocol.inl: Added remaining targets to the
test.
 
1999-03-31 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race
when enabling xmit interrupts.
 
1999-03-26 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter
is now always enabled, just the interrupts are masked/unmasked to control it.
This lets the serial driver cooperate with Cygmon on the port used for GDB.
Note that currently serial input does not work for CON1 since Cygmon is
taking all of the receive interrupts for itself.
(sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be
enabled - otherwise it can get enabled incorrectly and we get interrupted
to death!
 
1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/ser_test_protocol.inl: Send a DONE message after a no-echo
binary packet.
 
1999-03-26 Hugo Tyson <hmt@cygnus.co.uk>
 
* tests/serial5.c:
* tests/serial4.c:
* tests/serial3.c:
* tests/serial2.c:
* tests/serial1.c:
Make these build when no kernel present; include of testcase
was the wrong side of the ifdef.
 
1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/serial5.c:
* tests/serial4.c:
* tests/serial3.c:
* tests/serial2.c:
* tests/serial1.c:
Moved NOP check to ser_test_protocol open call.
* tests/ser_test_protocol.inl: Make sure the proper device is
selected for testing. Do NOP check in open call.
 
1999-03-25 Gary Thomas <gthomas@cygnus.co.uk>
 
* include/pkgconf/io_serial.h:
* misc/console.c:
* src/arm/aeb_serial.c:
* src/arm/pid_serial_with_ints.c:
* src/common/tty.c:
* src/mips/tx3904_serial.c:
* src/mn10300/mn10300_serial.c:
* src/powerpc/cogent_serial_with_ints.c:
* src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions.
 
* src/mips/tx3904_serial.c (tx3904_serial_config_port):
Make sure port is enabled (CDL) before using it.
 
* src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
* src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
* src/arm/aeb_serial.c (aeb_serial_config_port):
* src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that
the physical port is not modified unless the provided configuration is valid.
 
* src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port):
Using wrong config data.
 
* include/serialio.h: Add macros to support baud rate from CDL.
 
* include/pkgconf/io_serial.h:
* src/mn10300/mn10300_serial.c:
* src/mips/tx3904_serial.c (tx3904_serial_ISR):
* src/sparclite/sleb_sdtr.c:
* src/powerpc/cogent_serial_with_ints.c:
* src/arm/pid_serial_with_ints.c:
* src/arm/aeb_serial.c: Add configury for baud rate and buffer size.
 
1999-03-24 Nick Garnett <nickg@cygnus.co.uk>
 
* src/mips/tx3904_serial.c:
Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU
frequency. This is a little more accurate than using
CYGHWR_HAL_MIPS_CPU_FREQ.
 
1999-03-24 Gary Thomas <gthomas@cygnus.co.uk>
 
* include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness.
 
* src/arm/aeb_serial.c (aeb_serial_stop_xmit):
* src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment.
 
1999-03-24 Jesper Skov <jskov@cygnus.co.uk>
 
* tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't
like.
 
* src/powerpc/cogent_serial.h:
Added copyright header.
* tests/ser_test_protocol.inl:
* tests/serial1.c:
* tests/serial2.c:
* tests/serial3.c:
* tests/serial4.c:
* tests/serial5.c:
Don't try to run tests when no IO device has been specified.
1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
 
* misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c,
* misc/serial5.c, misc/ser_test_protocol.inl
Deleted.
 
1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
 
* misc/PKGconf.mak:
* tests/timeout.inl:
* tests/PKGconf.mak:
* tests/serial1.c:
* tests/serial2.c:
* tests/serial3.c:
* tests/serial4.c:
* tests/serial5.c:
* tests/ser_test_protocol.inl:
Moved the serial tests from the misc directory to the tests
directory.
 
1999-03-23 Nick Garnett <nickg@cygnus.co.uk>
 
* src/mn10300/mn10300_serial.c: Now initially mask TX interrupts
at initialization and unmask/remask in start/stop xmit
routines. This has no real effect on the hardware, but the
simulator does not implement the LCR_TXE bit properly, resulting
in spurious TX interrupts during diagnostic output.
This was the cause of the slow output reported in PR 19559.
 
1999-03-23 Gary Thomas <gthomas@cygnus.co.uk>
 
* include/pkgconf/io_serial.h: Fix "display" strings to have appropriate
case - mostly lower case.
 
1999-03-22 Hugo Tyson <hmt@cygnus.co.uk>
 
* misc/console.c:
* misc/serial.c:
* misc/serial1.c:
* misc/serial2.c:
* misc/serial3.c:
* misc/serial4.c:
* misc/serial5.c:
Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of
CYGNUM_HAL_MINIMUM_STACK_SIZE.
 
1999-03-22 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/mn10300/mn10300_serial.c:
* src/mips/tx3904_serial.c: Add CDL configury.
 
* include/pkgconf/io_serial.h: Update CDL to add device name
configurability for all devices.
 
* src/sparclite/sleb_sdtr.c:
* src/powerpc/cogent_serial_with_ints.c:
* src/arm/aeb_serial.c:
* src/arm/pid_serial_with_ints.c: Use CDL configured device names.
 
1999-03-22 Jesper Skov <jskov@lassi.cygnus.co.uk>
 
* misc/serial1.c:
* misc/serial2.c:
* misc/serial3.c:
* misc/serial4.c:
* misc/serial5.c:
Requires kernel as well.
 
1999-03-22 Jesper Skov <jskov@cygnus.co.uk>
 
* src/sparclite/sleb_sdtr.c:
Moved include statement to avoid warnings.
 
1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
 
* misc/ser_test_protocol.inl:
* misc/serial5.c:
* misc/PKGconf.mak:
Replace complex and not very stable duplex test with a simpler
test that works better.
Added serial5 using that test.
1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
 
* misc/PKGconf.mak:
* misc/serial1.c:
* misc/serial2.c:
Added API test and made serial2 do simple string output.
1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
 
* src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment.
 
1999-03-19 Jesper Skov <jskov@lassi.cygnus.co.uk>
 
* src/powerpc/cogent_serial_with_ints.c:
* src/arm/aeb_serial.c:
* src/arm/pid_serial_with_ints.c:
Moved include statement to avoid warnings.
 
1999-03-19 Gary Thomas <gthomas@cygnus.co.uk>
 
* include/pkgconf/io_serial.h: More CDL problems.
 
1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
 
* include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB.
 
* src/powerpc/cogent_serial_with_ints.c:
* src/arm/pid_serial_with_ints.c:
* src/arm/aeb_serial.c: Update device names to match CDL.
 
* include/pkgconf/io_serial.h: Change names for serial ports to
be CYGPKG_IO_SERIAL_<arch>_<platform>_<port>.
 
1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
 
* misc/ser_test_protocol.inl:
* misc/serial2.c:
First stab at the duplex binary test. Still much fun to be had...
 
1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
 
* misc/ser_test_protocol.inl: Added timeout for PING.
 
1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/common/serial.c: Change ABORT functionality to be DSR safe.
(serial_get_config): Fix typo!
 
* include/pkgconf/io_serial.h: Small change in CDL to make serial
devices tied to the platform and not the serial I/O package. This
means that only the devices appropriate to a given platform can be
enabled.
 
* misc/serial.c: Better use of alarms - only trigger at the time of
the next timeout. Moved timeout functions to new file "timeout.inl".
 
* src/common/serial.c (serial_get_config): Add support for
CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT.
* misc/serial.c: Add simple timeout mechanisms.
 
1999-03-17 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/powerpc/cogent_serial_with_ints.c:
* src/arm/aeb_serial.c:
* src/arm/pid_serial_with_ints.c: Conditionalize based on CDL.
 
* include/pkgconf/io_serial.h: Add some CDL configury - not perfect
because of current ~CDL limitations.
 
1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
 
* misc/serial2.c: Cleaned up a bit. Used for hacking new tests.
 
1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
 
* misc/PKGconf.mak:
* misc/ser_test_protocol.inl:
* misc/serial2.c:
* misc/serial3.c:
* misc/serial4.c:
Put testing protocol implementation in a separate file. Split the
tests in serial2 into separate files.
 
1999-03-16 Nick Garnett <nickg@cygnus.co.uk>
 
* src/mn10300/mn10300_serial.c: Fixed some compiler warnings.
 
1999-03-15 Gary Thomas <gthomas@cygnus.co.uk>
 
* include/pkgconf/io_serial.h: Change default configurations.
No serial drivers enabled for PID port A or AEB.
 
* src/sparclite/sleb_sdtr.c:
* src/powerpc/cogent_serial_with_ints.c:
* src/arm/aeb_serial.c:
* src/arm/pid_serial_with_ints.c:
* src/common/haldiag.c:
* src/common/tty.c:
* src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init
messages.
 
* src/powerpc/cogent_serial_with_ints.c:
* src/sparclite/sleb_sdtr.c:
* src/arm/aeb_serial.c:
* src/arm/pid_serial_with_ints.c: Don't include <cyg/kernel/kapi.h>
 
1999-03-15 Jesper Skov <jskov@cygnus.co.uk>
 
* misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part
of binary protocol.
 
1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
 
* misc/serial2.c: Play a bit with timing. Think I broke it :(
Added DONE to BINARY packet.
Proper call to DRAIN.
 
1999-03-12 Nick Garnett <nickg@cygnus.co.uk>
 
* src/mips/tx3904_serial.c: Tidied away some debugging code.
 
1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
 
* misc/serial2.c: Removed bogus config changes.
 
1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
 
* misc/serial2.c (serial_test): Check for ser_filter on host (PING
packet).
 
1999-03-11 Jesper Skov <jskov@cygnus.co.uk>
 
* src/powerpc/cogent_serial_with_ints.c: Added note.
 
* misc/serial2.c:
Added (almost) proper configuration handling.
Run tests on varying configurations.
 
1999-03-11 Nick Garnett <nickg@cygnus.co.uk>
 
* src/mips/tx3904_serial.c:
Many changes to get working.
 
* misc/console.c (console_test): Fixed compiler warning.
 
* misc/serial2.c:
Added device name for TX39 testing.
Fixed some bugs in Tcyg_io_write() macro.
 
1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
 
* misc/serial2.c: Added target specific test device name.
 
1999-03-10 John Dallaway <jld@cygnus.co.uk>
 
* include/pkgconf/io_serial.h: Correct CDL description spelling.
 
1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
 
* src/powerpc/cogent_serial_with_ints.c:
* misc/console.c:
Fixed compiler warnings.
 
1999-03-10 Gary Thomas <gthomas@cygnus.co.uk>
 
* include/pkgconf/io_serial.h: Improve CDL descriptions.
 
1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
 
* misc/serial2.c (serial_test): Do some more tests with changed
baud rates.
 
1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
 
* misc/serial2.c (serial_test): Added workaround for spurious byte
problem. Added a few more tests to run.
 
* src/powerpc/cogent_serial_with_ints.c
(cogent_serial_config_port): Remove interrupt enabling.
 
1999-03-09 Nick Garnett <nickg@cygnus.co.uk>
 
* src/PKGconf.mak:
* src/mips/tx3904_serial.c:
Added initial version of TX39 device driver. Currently untested
but eliminates PR19445.
 
1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
 
* misc/serial2.c: DRAIN function works now.
 
1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
 
* include/pkgconf/io_serial.h: Only enable one serial driver per
default.
 
1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
 
* misc/serial2.c (serial_test): Be a bit more aggressive.
 
* src/powerpc/cogent_serial_with_ints.c: Check that configuration
is sensible.
 
1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
 
* src/powerpc/cogent_serial_with_ints.c:
Added support for both ports.
 
* include/pkgconf/io_serial.h: Added simple defines for cogent
serial ports. No CDL yet.
 
1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
 
* misc/serial.c: Removed PID references. Fixed compiler warnings.
 
1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
 
* src/powerpc/cogent_serial_with_ints.c: Cleaned up a
bit. Actually works now.
 
1999-03-08 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/common/serial.c: Change in cyg_drv_cond_wait() behaviour
means DSR lock should be left alone.
 
1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
PR 19400
* src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set
valid interrupt priority.
 
1999-03-05 Nick Garnett <nickg@cygnus.co.uk>
 
* src/mn10300/mn10300_serial.c (mn10300_serial_init):
Added extra test to avoid initializing serial 2 when CYGMON is
present.
Include hal_intr.h explicitly for use in non-kernel
configurations.
 
* src/common/serial.c:
Added extra test before calls to cyg_drv_cond_wait() to avoid race
condition. This is not, however, a complete solution to this
problem. A better solution will be forthcoming.
 
* include/serial.h:
Changed include files used to permit non-kernel configurations to
be built.
 
1999-03-05 Jesper Skov <jskov@cygnus.co.uk>
 
* src/common/haldiag.c: Removed diag_printf declaration.
 
1999-03-05 Jonathan Larmour <jlarmour@cygnus.co.uk>
 
* src/mn10300/mn10300_serial.c:
Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile!
 
1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
Fix renaming of interrupt vectors.
 
1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/arm/pid_serial_with_ints.c: Fix interrupt vectors.
 
1999-03-03 Gary Thomas <gthomas@cygnus.co.uk>
 
* serial/current/src/arm/pid_serial_with_ints.c:
New [somewhat] configurable drivers for PID.
 
//===========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//===========================================================================
/misc/serial.c
0,0 → 1,257
//==========================================================================
//
// serial.c
//
// Initial device I/O tests
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): gthomas
// Contributors: gthomas
// Date: 1999-02-05
// Description: Minimal testing of "serial" I/O
//####DESCRIPTIONEND####
 
#include <pkgconf/kernel.h>
#include <pkgconf/io.h>
#include <cyg/io/io.h>
#include <cyg/io/ttyio.h>
#include <cyg/infra/diag.h>
#include <cyg/infra/testcase.h>
#ifdef CYGFUN_KERNEL_API_C
#include <cyg/kernel/kapi.h>
#include <cyg/hal/hal_arch.h>
#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
unsigned char stack[STACK_SIZE];
cyg_thread thread_data;
cyg_handle_t thread_handle;
 
// This routine will be called if the read "times out"
static void
do_abort(void *handle)
{
cyg_io_handle_t io_handle = (cyg_io_handle_t)handle;
cyg_int32 len = 1; // Need something here
cyg_io_get_config(io_handle, CYG_IO_GET_CONFIG_SERIAL_ABORT, 0, &len);
}
 
#include "timeout.inl"
#endif
 
static void
dump_buf_with_offset(unsigned char *p,
int s,
unsigned char *base)
{
int i, c;
if ((unsigned int)s > (unsigned int)p) {
s = (unsigned int)s - (unsigned int)p;
}
while (s > 0) {
if (base) {
diag_printf("%08X: ", (int)p - (int)base);
} else {
diag_printf("%08X: ", p);
}
for (i = 0; i < 16; i++) {
if (i < s) {
diag_printf("%02X", p[i] & 0xFF);
} else {
diag_printf(" ");
}
if ((i % 2) == 1) diag_printf(" ");
if ((i % 8) == 7) diag_printf(" ");
}
diag_printf(" |");
for (i = 0; i < 16; i++) {
if (i < s) {
c = p[i] & 0xFF;
if ((c < 0x20) || (c >= 0x7F)) c = '.';
} else {
c = ' ';
}
diag_printf("%c", c);
}
diag_printf("|\n");
s -= 16;
p += 16;
}
}
 
static void
dump_buf(unsigned char *p, int s)
{
dump_buf_with_offset(p, s, 0);
}
 
void
hang(void)
{
while (true) ;
}
 
static int
strlen(char *c)
{
int l = 0;
while (*c++) l++;
return l;
}
 
void
serial_test( void )
{
Cyg_ErrNo res;
cyg_io_handle_t handle;
char msg[] = "This is a test\n";
int msglen = sizeof(msg)-1;
char in_msg[80];
int in_msglen = sizeof(in_msg)-1;
cyg_serial_info_t serial_info;
cyg_tty_info_t tty_info;
char short_msg[] = "This is a short message\n";
char long_msg[] = "This is a longer message 0123456789abcdefghijklmnopqrstuvwxyz\n";
char filler[] = " ";
char prompt[] = "\nPlease enter some data: ";
int i, len;
#ifdef CYGFUN_KERNEL_API_C
cyg_uint32 stamp;
#endif
 
res = cyg_io_lookup("/dev/tty0", &handle);
if (res != ENOERR) {
diag_printf("Can't lookup - DEVIO error: %d\n", res);
return;
}
len = sizeof(serial_info);
res = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_SERIAL_INFO, &serial_info, &len);
if (res != ENOERR) {
diag_printf("Can't get serial config - DEVIO error: %d\n", res);
hang();
return;
}
len = sizeof(tty_info);
res = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_TTY_INFO, &tty_info, &len);
if (res != ENOERR) {
diag_printf("Can't get tty config - DEVIO error: %d\n", res);
hang();
return;
}
diag_printf("Config - baud: %d, stop: %d, parity: %d, out flags: %x, in flags: %x\n",
serial_info.baud, serial_info.stop, serial_info.parity,
tty_info.tty_out_flags, tty_info.tty_in_flags);
len = sizeof(serial_info);
res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO, &serial_info, &len);
if (res != ENOERR) {
diag_printf("Can't set serial config - DEVIO error: %d\n", res);
hang();
return;
}
len = sizeof(tty_info);
res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_TTY_INFO, &tty_info, &len);
if (res != ENOERR) {
diag_printf("Can't set tty config - DEVIO error: %d\n", res);
hang();
return;
}
msglen = strlen(msg);
res = cyg_io_write(handle, msg, &msglen);
if (res != ENOERR) {
diag_printf("Can't write data - DEVIO error: %d\n", res);
hang();
return;
}
for (i = 0; i < 10; i++) {
len = strlen(short_msg);
res = cyg_io_write(handle, short_msg, &len);
if (res != ENOERR) {
diag_printf("Can't write [short] data - DEVIO error: %d\n", res);
hang();
return;
}
}
for (i = 0; i < 100; i++) {
len = (i % 10) + 1;
cyg_io_write(handle, filler, &len);
len = strlen(long_msg);
res = cyg_io_write(handle, long_msg, &len);
if (res != ENOERR) {
diag_printf("Can't write [long] data - DEVIO error: %d\n", res);
hang();
return;
}
}
len = strlen(prompt);
cyg_io_write(handle, prompt, &len);
#ifdef CYGFUN_KERNEL_API_C
stamp = timeout(1000, do_abort, handle);
#endif
res = cyg_io_read(handle, in_msg, &in_msglen);
if (res != ENOERR) {
diag_printf("Can't read data - DEVIO error: %d\n", res);
hang();
return;
}
#ifdef CYGFUN_KERNEL_API_C
untimeout(stamp);
#endif
diag_printf("Read %d bytes\n", in_msglen);
dump_buf(in_msg, in_msglen);
CYG_TEST_PASS_FINISH("Serial I/O test OK");
}
 
void
cyg_start(void)
{
CYG_TEST_INIT();
#ifdef CYGFUN_KERNEL_API_C
cyg_thread_create(10, // Priority - just a number
(cyg_thread_entry_t*)serial_test, // entry
(cyg_addrword_t) 0, // entry data
"serial_thread", // Name
&stack[0], // Stack
STACK_SIZE, // Size
&thread_handle, // Handle
&thread_data // Thread data structure
);
cyg_thread_resume(thread_handle);
cyg_scheduler_start();
#else
serial_test();
#endif
}
// EOF serial.c
/misc/console.c
0,0 → 1,238
//==========================================================================
//
// console.c
//
// Initial device I/O tests
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): gthomas
// Contributors: gthomas
// Date: 1999-02-05
// Description: Minimal testing of "console" I/O
//####DESCRIPTIONEND####
 
#include <pkgconf/kernel.h>
#include <pkgconf/io.h>
#include <pkgconf/io_serial.h>
#include <cyg/io/io.h>
#include <cyg/io/ttyio.h>
#include <cyg/infra/testcase.h>
#include <cyg/infra/diag.h>
#ifdef CYGFUN_KERNEL_API_C
#include <cyg/kernel/kapi.h>
#include <cyg/hal/hal_arch.h>
#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
unsigned char stack[STACK_SIZE];
cyg_thread thread_data;
cyg_handle_t thread_handle;
#endif
 
static void
dump_buf_with_offset(unsigned char *p,
int s,
unsigned char *base)
{
int i, c;
if ((unsigned int)s > (unsigned int)p) {
s = (unsigned int)s - (unsigned int)p;
}
while (s > 0) {
if (base) {
diag_printf("%08X: ", (int)p - (int)base);
} else {
diag_printf("%08X: ", p);
}
for (i = 0; i < 16; i++) {
if (i < s) {
diag_printf("%02X", p[i] & 0xFF);
} else {
diag_printf(" ");
}
if ((i % 2) == 1) diag_printf(" ");
if ((i % 8) == 7) diag_printf(" ");
}
diag_printf(" |");
for (i = 0; i < 16; i++) {
if (i < s) {
c = p[i] & 0xFF;
if ((c < 0x20) || (c >= 0x7F)) c = '.';
} else {
c = ' ';
}
diag_printf("%c", c);
}
diag_printf("|\n");
s -= 16;
p += 16;
}
}
 
static void
dump_buf(unsigned char *p, int s)
{
dump_buf_with_offset(p, s, 0);
}
 
void
hang(void)
{
while (true) ;
}
 
static int
strlen(char *c)
{
int l = 0;
while (*c++) l++;
return l;
}
 
void
console_test( CYG_ADDRWORD x )
{
Cyg_ErrNo res;
cyg_io_handle_t handle;
char msg[] = "This is a test\n";
int msglen = sizeof(msg)-1;
char in_msg[80];
int in_msglen = sizeof(in_msg)-1;
cyg_serial_info_t serial_info;
cyg_tty_info_t tty_info;
char short_msg[] = "This is a short message\n";
char long_msg[] = "This is a longer message 0123456789abcdefghijklmnopqrstuvwxyz\n";
char filler[] = " ";
char prompt[] = "\nPlease enter some data: ";
int i, len;
 
res = cyg_io_lookup(CYGDAT_IO_SERIAL_TTY_CONSOLE, &handle);
if (res != ENOERR) {
diag_printf("Can't lookup - DEVIO error: %d\n", res);
return;
}
len = sizeof(serial_info);
res = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_SERIAL_INFO, &serial_info, &len);
if (res != ENOERR) {
diag_printf("Can't get serial config - DEVIO error: %d\n", res);
hang();
return;
}
len = sizeof(tty_info);
res = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_TTY_INFO, &tty_info, &len);
if (res != ENOERR) {
diag_printf("Can't get tty config - DEVIO error: %d\n", res);
hang();
return;
}
diag_printf("Config - baud: %d, stop: %d, parity: %d, out flags: %x, in flags: %x\n",
serial_info.baud, serial_info.stop, serial_info.parity,
tty_info.tty_out_flags, tty_info.tty_in_flags);
len = sizeof(serial_info);
res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO, &serial_info, &len);
if (res != ENOERR) {
diag_printf("Can't set serial config - DEVIO error: %d\n", res);
hang();
return;
}
len = sizeof(tty_info);
res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_TTY_INFO, &tty_info, &len);
if (res != ENOERR) {
diag_printf("Can't set tty config - DEVIO error: %d\n", res);
hang();
return;
}
msglen = strlen(msg);
res = cyg_io_write(handle, msg, &msglen);
if (res != ENOERR) {
diag_printf("Can't write data - DEVIO error: %d\n", res);
hang();
return;
}
for (i = 0; i < 10; i++) {
len = strlen(short_msg);
res = cyg_io_write(handle, short_msg, &len);
if (res != ENOERR) {
diag_printf("Can't write [short] data - DEVIO error: %d\n", res);
hang();
return;
}
}
for (i = 0; i < 100; i++) {
len = (i % 10) + 1;
cyg_io_write(handle, filler, &len);
len = strlen(long_msg);
res = cyg_io_write(handle, long_msg, &len);
if (res != ENOERR) {
diag_printf("Can't write [long] data - DEVIO error: %d\n", res);
hang();
return;
}
}
len = strlen(prompt);
cyg_io_write(handle, prompt, &len);
res = cyg_io_read(handle, in_msg, &in_msglen);
if (res != ENOERR) {
diag_printf("Can't read data - DEVIO error: %d\n", res);
hang();
return;
}
diag_printf("Read %d bytes\n", in_msglen);
dump_buf(in_msg, in_msglen);
CYG_TEST_PASS_FINISH("Console I/O test OK");
}
 
void
cyg_start(void)
{
CYG_TEST_INIT();
#ifdef CYGFUN_KERNEL_API_C
cyg_thread_create(10, // Priority - just a number
(cyg_thread_entry_t*)console_test, // entry
0, //
"console_thread", // Name
&stack[0], // Stack
STACK_SIZE, // Size
&thread_handle, // Handle
&thread_data // Thread data structure
);
cyg_thread_resume(thread_handle);
cyg_scheduler_start();
#else
console_test();
#endif
}
// EOF console.c
/misc/timeout.inl
0,0 → 1,143
#ifndef CYGONCE_IO_SERIAL_MISC_TIMEOUT_INL
#define CYGONCE_IO_SERIAL_MISC_TIMEOUT_INL
//==========================================================================
//
// timeout.inl
//
// Simple timeout support for serial I/O testing.
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): gthomas
// Contributors: gthomas
// Date: 1999-02-05
// Description: Simple timeout functions
//####DESCRIPTIONEND####
 
// Timeout support
 
typedef void (timeout_fun)(void *);
#ifndef NTIMEOUTS
#define NTIMEOUTS 8
#endif
typedef struct {
cyg_int32 delta; // Number of "ticks" in the future for this timeout
timeout_fun *fun; // Function to execute when it expires
void *arg; // Argument to pass when it does
} timeout_entry;
static timeout_entry timeouts[NTIMEOUTS];
static cyg_handle_t timeout_alarm_handle;
static cyg_alarm timeout_alarm;
static cyg_int32 last_delta;
 
static void
do_timeout(cyg_handle_t alarm, cyg_addrword_t data)
{
int i;
cyg_int32 min_delta;
timeout_entry *e = timeouts;
min_delta = 0x7FFFFFFF; // Maxint
for (i = 0; i < NTIMEOUTS; i++, e++) {
if (e->delta) {
e->delta -= last_delta;
if (e->delta == 0) {
// Time for this item to 'fire'
(e->fun)(e->arg);
} else {
if (e->delta < min_delta) min_delta = e->delta;
}
}
}
if (min_delta != 0x7FFFFFFF) {
// Still something to do, schedule it
cyg_alarm_initialize(timeout_alarm_handle, cyg_current_time()+min_delta, 0);
last_delta = min_delta;
}
}
 
static cyg_uint32
timeout(cyg_int32 delta, timeout_fun *fun, void *arg)
{
int i;
cyg_int32 min_delta;
static bool init = false;
timeout_entry *e = timeouts;
cyg_uint32 stamp;
if (!init) {
cyg_handle_t h;
cyg_clock_to_counter(cyg_real_time_clock(), &h);
cyg_alarm_create(h, do_timeout, 0, &timeout_alarm_handle, &timeout_alarm);
init = true;
}
stamp = 0; // Assume no slots available
for (i = 0; i < NTIMEOUTS; i++, e++) {
if ((e->delta == 0) && (e->fun == 0)) {
// Free entry
e->delta = delta;
e->fun = fun;
e->arg = arg;
stamp = (cyg_uint32)e;
break;
}
}
e = timeouts;
min_delta = 0x7FFFFFFF;
for (i = 0; i < NTIMEOUTS; i++, e++) {
if (e->delta && (e->delta < min_delta)) min_delta = e->delta;
}
if (min_delta != 0x7FFFFFFF) {
// Still something to do, schedule it
cyg_alarm_initialize(timeout_alarm_handle, cyg_current_time()+min_delta, 0);
last_delta = min_delta;
}
return stamp;
}
 
static void
untimeout(cyg_uint32 stamp)
{
if (stamp != 0) {
timeout_entry *e = (timeout_entry *)stamp;
if (e->fun != 0) {
e->delta = 0;
e->fun = 0;
e->arg = 0;
}
}
}
 
#endif // CYGONCE_IO_SERIAL_MISC_TIMEOUT_INL

powered by: WebSVN 2.1.0

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