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
- from Rev 27 to Rev 174
- ↔ Reverse comparison
Rev 27 → Rev 174
/v2_0/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'." |
} |
} |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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. |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 */ |
/v2_0/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 */ |
/v2_0/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 |
/v2_0/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, ¤t_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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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#### |
//=========================================================================== |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |