This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
Rattler & MPC8xxx - serial I/O driver
- From: Gary Thomas <gary at mlbassoc dot com>
- To: eCos patches <ecos-patches at ecos dot sourceware dot org>
- Date: 09 Nov 2003 16:13:33 -0700
- Subject: Rattler & MPC8xxx - serial I/O driver
- Organization: MLB Associates
--
Gary Thomas <gary@mlbassoc.com>
MLB Associates
Index: ChangeLog
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/ChangeLog,v
retrieving revision 1.126
diff -u -5 -p -r1.126 ChangeLog
--- ChangeLog 4 Nov 2003 09:36:25 -0000 1.126
+++ ChangeLog 9 Nov 2003 23:08:03 -0000
@@ -1,5 +1,9 @@
+2003-11-09 Gary Thomas <gary@mlbassoc.com>
+
+ * ecos.db: Add serial I/O package for Motorola MPC8xxx (QUICC-II)
+
2003-11-04 Andrew Lunn <andrew.lunn@ascom.ch>
* ecos.db: Modified the e7t to use the new 39VFXXX flash driver
2003-11-04 Andrew Lunn <andrew.lunn@ascom.ch>
Index: ecos.db
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/ecos.db,v
retrieving revision 1.110
diff -u -5 -p -r1.110 ecos.db
--- ecos.db 4 Nov 2003 09:36:25 -0000 1.110
+++ ecos.db 9 Nov 2003 23:07:53 -0000
@@ -916,10 +916,19 @@ package CYGPKG_IO_SERIAL_POWERPC_QUICC_S
directory devs/serial/powerpc/quicc
script ser_quicc_smc.cdl
description "PowerPC QUICC/SMC serial device drivers"
}
+package CYGPKG_IO_SERIAL_POWERPC_MPC8XXX {
+ alias { "PowerPC MPC8XXX (QUICC-II) serial device drivers"
+ devs_serial_powerpc_mpc8xxx mpc8xxx_serial_driver }
+ hardware
+ directory devs/serial/powerpc/mpc8xxx
+ script ser_mpc8xxx.cdl
+ description "PowerPC MPC8XXX (QUICC-II) serial device drivers"
+}
+
package CYGPKG_IO_SERIAL_POWERPC_QUICC2_SCC {
alias { "PowerPC VADS QUICC2/SCC serial device drivers"
devs_serial_quicc2_scc quicc2_scc_serial_driver
devs_serial_powerpc_quicc2_scc
devs_serial_powerpc_quicc2 quicc2_serial_driver }
@@ -5175,10 +5184,11 @@ target rattler {
CYGPKG_DEVS_FLASH_POWERPC_RATTLER
CYGPKG_DEVS_FLASH_AMD_AM29XXXXX
CYGPKG_DEVS_ETH_POWERPC_FCC
CYGPKG_DEVS_ETH_POWERPC_RATTLER
CYGPKG_DEVS_ETH_PHY
+ CYGPKG_IO_SERIAL_POWERPC_MPC8XXX
}
description "
The rattler target provides the packages needed to run
eCos on an Analogue & Micro Rattler (MPC8250) board."
}
Index: devs/serial/powerpc/mpc8xxx/current/ChangeLog
===================================================================
RCS file: devs/serial/powerpc/mpc8xxx/current/ChangeLog
diff -N devs/serial/powerpc/mpc8xxx/current/ChangeLog
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ devs/serial/powerpc/mpc8xxx/current/ChangeLog 9 Nov 2003 22:55:08 -0000
@@ -0,0 +1,40 @@
+2003-11-09 Gary Thomas <gary@mlbassoc.com>
+
+ * src/mpc8xxx_serial.h:
+ * src/mpc8xxx_serial.c:
+ * cdl/ser_mpc8xxx.cdl: New package - serial I/O for MPC8xxx
+
+//===========================================================================
+//####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####
+//===========================================================================
Index: devs/serial/powerpc/mpc8xxx/current/cdl/ser_mpc8xxx.cdl
===================================================================
RCS file: devs/serial/powerpc/mpc8xxx/current/cdl/ser_mpc8xxx.cdl
diff -N devs/serial/powerpc/mpc8xxx/current/cdl/ser_mpc8xxx.cdl
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ devs/serial/powerpc/mpc8xxx/current/cdl/ser_mpc8xxx.cdl 9 Nov 2003 22:59:19 -0000
@@ -0,0 +1,513 @@
+# ====================================================================
+#
+# ser_mpc8xxx.cdl
+#
+# eCos serial PowerPC MPC8XXX (QUICC-II) configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2002, 2003 Gary Thomas
+##
+## 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-14
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_POWERPC_MPC8XXX {
+ display "PowerPC MPC8XXX (QUICC-II) serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_POWERPC_MPC8XXX
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ PowerPC MPC8XXX (QUICC-II) SMC/SCC."
+
+ compile -library=libextras.a mpc8xxx_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_powerpc_mpc8xxx.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SMC1 {
+ display "PowerPC MPC8XXX/SMC serial port 1 driver"
+ flavor bool
+ active_if CYGNUM_HAL_MPC8XXX_SMC1
+ default_value 1
+ description "
+ This option includes the serial device driver for the PowerPC
+ MPC8XXX/SMC port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_MPC8XXX_SMC1_NAME {
+ display "Device name for PowerPC MPC8XXX/SMC serial port 1"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the device name for the PowerPC
+ MPC8XXX/SMC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_BAUD {
+ display "Baud rate for the PowerPC MPC8XXX/SMC serial port 1"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ PowerPC MPC8XXX/SMC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_BUFSIZE {
+ display "Buffer size for the PowerPC MPC8XXX/SMC serial port 1"
+ flavor data
+ legal_values 0 to 8192
+ default_value 256
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC MPC8XXX/SMC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_TxSIZE {
+ display "Output buffer size for the PowerPC MPC8XXX/SMC serial port 1"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per
+ transmit request to be used for the PowerPC MPC8XXX/SMC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_TxNUM {
+ display "Number of output buffers for the PowerPC MPC8XXX/SMC serial port 1"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC MPC8XXX/SMC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_RxSIZE {
+ display "Input buffer size for the PowerPC MPC8XXX/SMC serial port 1"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per receive
+ request to be used for the PowerPC MPC8XXX/SMC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_RxNUM {
+ display "Number of input buffers for the PowerPC MPC8XXX/SMC serial port 1"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC MPC8XXX/SMC port 1."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SMC2 {
+ display "PowerPC MPC8XXX/SMC serial port 2 driver"
+ flavor bool
+ active_if CYGNUM_HAL_MPC8XXX_SMC2
+ default_value 1
+ description "
+ This option includes the serial device driver for the PowerPC
+ MPC8XXX/SMC port 2."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_MPC8XXX_SMC2_NAME {
+ display "Device name for PowerPC MPC8XXX/SMC serial port 2"
+ flavor data
+ default_value {"\"/dev/ser2\""}
+ description "
+ This option specifies the device name for the PowerPC
+ MPC8XXX/SMC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_BAUD {
+ display "Baud rate for the PowerPC MPC8XXX/SMC serial port 2"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ PowerPC MPC8XXX/SMC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_BUFSIZE {
+ display "Buffer size for the PowerPC MPC8XXX/SMC serial port 2"
+ flavor data
+ legal_values 0 to 8192
+ default_value 256
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC MPC8XXX/SMC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_TxSIZE {
+ display "Output buffer size for the PowerPC MPC8XXX/SMC serial port 2"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per
+ transmit request to be used for the PowerPC MPC8XXX/SMC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_TxNUM {
+ display "Number of output buffers for the PowerPC MPC8XXX/SMC serial port 2"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC MPC8XXX/SMC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_RxSIZE {
+ display "Input buffer size for the PowerPC MPC8XXX/SMC serial port 2"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per receive
+ request to be used for the PowerPC MPC8XXX/SMC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_RxNUM {
+ display "Number of output buffers for the PowerPC MPC8XXX/SMC serial port 2"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC MPC8XXX/SMC port 2."
+ }
+}
+
+ cdl_component CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_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_POWERPC_MPC8XXX_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC1 {
+ display "PowerPC MPC8XXX/SCC serial port 1 driver"
+ flavor bool
+ active_if CYGNUM_HAL_MPC8XXX_SCC1
+ default_value 1
+ description "
+ This option includes the serial device driver for the PowerPC
+ MPC8XXX/SCC port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_MPC8XXX_SCC1_NAME {
+ display "Device name for PowerPC MPC8XXX/SCC serial port 1"
+ flavor data
+ default_value {"\"/dev/scc1\""}
+ description "
+ This option specifies the device name for the PowerPC
+ MPC8XXX/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_BAUD {
+ display "Baud rate for the PowerPC MPC8XXX/SCC serial port 1"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ PowerPC MPC8XXX/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_BUFSIZE {
+ display "Buffer size for the PowerPC MPC8XXX/SCC serial port 1"
+ flavor data
+ legal_values 0 to 8192
+ default_value 256
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC MPC8XXX/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_TxSIZE {
+ display "Output buffer size for the PowerPC MPC8XXX/SCC serial port 1"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per
+ transmit request to be used for the PowerPC MPC8XXX/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_TxNUM {
+ display "Number of output buffers for the PowerPC MPC8XXX/SCC serial port 1"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC MPC8XXX/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_RxSIZE {
+ display "Input buffer size for the PowerPC MPC8XXX/SCC serial port 1"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per receive
+ request to be used for the PowerPC MPC8XXX/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_RxNUM {
+ display "Number of input buffers for the PowerPC MPC8XXX/SCC serial port 1"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC MPC8XXX/SCC port 1."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC2 {
+ display "PowerPC MPC8XXX/SCC serial port 2 driver"
+ flavor bool
+ active_if CYGNUM_HAL_MPC8XXX_SCC2
+ default_value 1
+ description "
+ This option includes the serial device driver for the PowerPC
+ MPC8XXX/SCC port 2."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_MPC8XXX_SCC2_NAME {
+ display "Device name for PowerPC MPC8XXX/SCC serial port 2"
+ flavor data
+ default_value {"\"/dev/scc2\""}
+ description "
+ This option specifies the device name for the PowerPC
+ MPC8XXX/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_BAUD {
+ display "Baud rate for the PowerPC MPC8XXX/SCC serial port 2"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ PowerPC MPC8XXX/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_BUFSIZE {
+ display "Buffer size for the PowerPC MPC8XXX/SCC serial port 2"
+ flavor data
+ legal_values 0 to 8192
+ default_value 256
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC MPC8XXX/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_TxSIZE {
+ display "Output buffer size for the PowerPC MPC8XXX/SCC serial port 2"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per
+ transmit request to be used for the PowerPC MPC8XXX/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_TxNUM {
+ display "Number of output buffers for the PowerPC MPC8XXX/SCC serial port 2"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC MPC8XXX/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_RxSIZE {
+ display "Input buffer size for the PowerPC MPC8XXX/SCC serial port 2"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per receive
+ request to be used for the PowerPC MPC8XXX/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_RxNUM {
+ display "Number of input buffers for the PowerPC MPC8XXX/SCC serial port 2"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC MPC8XXX/SCC port 2."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC3 {
+ display "PowerPC MPC8XXX/SCC serial port 3 driver"
+ flavor bool
+ active_if CYGNUM_HAL_MPC8XXX_SCC3
+ default_value 1
+ description "
+ This option includes the serial device driver for the PowerPC
+ MPC8XXX/SCC port 3."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_MPC8XXX_SCC3_NAME {
+ display "Device name for PowerPC MPC8XXX/SCC serial port 3"
+ flavor data
+ default_value {"\"/dev/scc3\""}
+ description "
+ This option specifies the device name for the PowerPC
+ MPC8XXX/SCC port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_BAUD {
+ display "Baud rate for the PowerPC MPC8XXX/SCC serial port 3"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ PowerPC MPC8XXX/SCC port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_BUFSIZE {
+ display "Buffer size for the PowerPC MPC8XXX/SCC serial port 3"
+ flavor data
+ legal_values 0 to 8192
+ default_value 256
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC MPC8XXX/SCC port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_TxSIZE {
+ display "Output buffer size for the PowerPC MPC8XXX/SCC serial port 3"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per
+ transmit request to be used for the PowerPC MPC8XXX/SCC port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_TxNUM {
+ display "Number of output buffers for the PowerPC MPC8XXX/SCC serial port 3"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC MPC8XXX/SCC port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_RxSIZE {
+ display "Input buffer size for the PowerPC MPC8XXX/SCC serial port 3"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per receive
+ request to be used for the PowerPC MPC8XXX/SCC port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_RxNUM {
+ display "Number of input buffers for the PowerPC MPC8XXX/SCC serial port 3"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC MPC8XXX/SCC port 3."
+ }
+}
+
+# EOF ser_mpc8xxx_smc.cdl
Index: devs/serial/powerpc/mpc8xxx/current/src/mpc8xxx_serial.c
===================================================================
RCS file: devs/serial/powerpc/mpc8xxx/current/src/mpc8xxx_serial.c
diff -N devs/serial/powerpc/mpc8xxx/current/src/mpc8xxx_serial.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ devs/serial/powerpc/mpc8xxx/current/src/mpc8xxx_serial.c 9 Nov 2003 22:57:59 -0000
@@ -0,0 +1,1016 @@
+//==========================================================================
+//
+// io/serial/powerpc/mpc8xxx_serial.c
+//
+// PowerPC MPC8XXX (QUICC-II) (SMC/SCC) Serial I/O Interface Module
+//
+//==========================================================================
+//####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 Gary Thomas
+//
+// 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-06-20
+// Purpose: MPC8XXX Serial I/O module
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/mpc8xxx.h>
+#include CYGBLD_HAL_PLATFORM_H
+
+#include "mpc8xxx_serial.h"
+
+typedef struct mpc8xxx_sxx_serial_info {
+ CYG_ADDRWORD channel; // Which channel SMCx/SCCx
+ short int_num; // Interrupt number
+ short type; // Channel type - SCC or SMC
+ unsigned long *brg; // Which baud rate generator
+ void *pram; // Parameter RAM pointer
+ void *ctl; // SMC/SCC control registers
+ volatile struct cp_bufdesc *txbd, *rxbd; // Next Tx,Rx descriptor to use
+ struct cp_bufdesc *tbase, *rbase; // First Tx,Rx descriptor
+ int txsize, rxsize; // Length of individual buffers
+ cyg_interrupt serial_interrupt;
+ cyg_handle_t serial_interrupt_handle;
+} mpc8xxx_sxx_serial_info;
+
+static bool mpc8xxx_sxx_serial_init(struct cyg_devtab_entry *tab);
+static bool mpc8xxx_sxx_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo mpc8xxx_sxx_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char mpc8xxx_sxx_serial_getc(serial_channel *chan);
+static Cyg_ErrNo mpc8xxx_sxx_serial_set_config(serial_channel *chan,
+ cyg_uint32 key, const void *xbuf,
+ cyg_uint32 *len);
+static void mpc8xxx_sxx_serial_start_xmit(serial_channel *chan);
+static void mpc8xxx_sxx_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 mpc8xxx_sxx_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void mpc8xxx_sxx_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_putc,
+ mpc8xxx_sxx_serial_getc,
+ mpc8xxx_sxx_serial_set_config,
+ mpc8xxx_sxx_serial_start_xmit,
+ mpc8xxx_sxx_serial_stop_xmit
+ );
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SMC1
+static mpc8xxx_sxx_serial_info mpc8xxx_sxx_serial_info_smc1 = {
+ SMC1_PAGE_SUBBLOCK, // Channel indicator
+ CYGNUM_HAL_INTERRUPT_SMC1, // interrupt
+ _SMC_CHAN
+};
+#if CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_BUFSIZE > 0
+static unsigned char mpc8xxx_smc_serial_out_buf_smc1[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_BUFSIZE];
+static unsigned char mpc8xxx_smc_serial_in_buf_smc1[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(mpc8xxx_sxx_serial_channel_smc1,
+ mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_info_smc1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &mpc8xxx_smc_serial_out_buf_smc1[0], sizeof(mpc8xxx_smc_serial_out_buf_smc1),
+ &mpc8xxx_smc_serial_in_buf_smc1[0], sizeof(mpc8xxx_smc_serial_in_buf_smc1)
+ );
+#else
+static SERIAL_CHANNEL(mpc8xxx_sxx_serial_channel_smc1,
+ mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_info_smc1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+static unsigned char mpc8xxx_smc1_txbuf[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_TxNUM*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_TxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static unsigned char mpc8xxx_smc1_rxbuf[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_RxNUM*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_RxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+
+DEVTAB_ENTRY(mpc8xxx_smc_serial_io_smc1,
+ CYGDAT_IO_SERIAL_POWERPC_MPC8XXX_SMC1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ mpc8xxx_sxx_serial_init,
+ mpc8xxx_sxx_serial_lookup, // Serial driver may need initializing
+ &mpc8xxx_sxx_serial_channel_smc1
+ );
+#endif // CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SMC1
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SMC2
+static mpc8xxx_sxx_serial_info mpc8xxx_sxx_serial_info_smc2 = {
+ SMC2_PAGE_SUBBLOCK, // Channel indicator
+ CYGNUM_HAL_INTERRUPT_SMC2, // interrupt
+ _SMC_CHAN
+};
+#if CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_BUFSIZE > 0
+static unsigned char mpc8xxx_smc_serial_out_buf_smc2[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_BUFSIZE];
+static unsigned char mpc8xxx_smc_serial_in_buf_smc2[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(mpc8xxx_sxx_serial_channel_smc2,
+ mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_info_smc2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &mpc8xxx_smc_serial_out_buf_smc2[0], sizeof(mpc8xxx_smc_serial_out_buf_smc2),
+ &mpc8xxx_smc_serial_in_buf_smc2[0], sizeof(mpc8xxx_smc_serial_in_buf_smc2)
+ );
+#else
+static SERIAL_CHANNEL(mpc8xxx_sxx_serial_channel_smc2,
+ mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_info_smc2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+static unsigned char mpc8xxx_smc2_txbuf[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_TxNUM*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_TxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static unsigned char mpc8xxx_smc2_rxbuf[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_RxNUM*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_RxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+
+DEVTAB_ENTRY(mpc8xxx_smc_serial_io_smc2,
+ CYGDAT_IO_SERIAL_POWERPC_MPC8XXX_SMC2_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ mpc8xxx_sxx_serial_init,
+ mpc8xxx_sxx_serial_lookup, // Serial driver may need initializing
+ &mpc8xxx_sxx_serial_channel_smc2
+ );
+#endif // CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SMC2
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC1
+static mpc8xxx_sxx_serial_info mpc8xxx_sxx_serial_info_scc1 = {
+ SCC1_PAGE_SUBBLOCK, // Channel indicator
+ CYGNUM_HAL_INTERRUPT_SCC1, // interrupt
+ _SCC_CHAN
+};
+#if CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_BUFSIZE > 0
+static unsigned char mpc8xxx_smc_serial_out_buf_scc1[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_BUFSIZE];
+static unsigned char mpc8xxx_smc_serial_in_buf_scc1[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(mpc8xxx_sxx_serial_channel_scc1,
+ mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_info_scc1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &mpc8xxx_smc_serial_out_buf_scc1[0], sizeof(mpc8xxx_smc_serial_out_buf_scc1),
+ &mpc8xxx_smc_serial_in_buf_scc1[0], sizeof(mpc8xxx_smc_serial_in_buf_scc1)
+ );
+#else
+static SERIAL_CHANNEL(mpc8xxx_sxx_serial_channel_scc1,
+ mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_info_scc1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+static unsigned char mpc8xxx_scc1_txbuf[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_TxNUM*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_TxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static unsigned char mpc8xxx_scc1_rxbuf[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_RxNUM*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_RxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+
+DEVTAB_ENTRY(mpc8xxx_smc_serial_io_scc1,
+ CYGDAT_IO_SERIAL_POWERPC_MPC8XXX_SCC1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ mpc8xxx_sxx_serial_init,
+ mpc8xxx_sxx_serial_lookup, // Serial driver may need initializing
+ &mpc8xxx_sxx_serial_channel_scc1
+ );
+#endif // CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC1
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC2
+static mpc8xxx_sxx_serial_info mpc8xxx_sxx_serial_info_scc2 = {
+ SCC2_PAGE_SUBBLOCK, // Channel indicator
+ CYGNUM_HAL_INTERRUPT_SCC2, // interrupt
+ _SCC_CHAN
+};
+#if CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_BUFSIZE > 0
+static unsigned char mpc8xxx_smc_serial_out_buf_scc2[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_BUFSIZE];
+static unsigned char mpc8xxx_smc_serial_in_buf_scc2[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(mpc8xxx_sxx_serial_channel_scc2,
+ mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_info_scc2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &mpc8xxx_smc_serial_out_buf_scc2[0], sizeof(mpc8xxx_smc_serial_out_buf_scc2),
+ &mpc8xxx_smc_serial_in_buf_scc2[0], sizeof(mpc8xxx_smc_serial_in_buf_scc2)
+ );
+#else
+static SERIAL_CHANNEL(mpc8xxx_sxx_serial_channel_scc2,
+ mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_info_scc2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+static unsigned char mpc8xxx_scc2_txbuf[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_TxNUM*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_TxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static unsigned char mpc8xxx_scc2_rxbuf[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_RxNUM*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_RxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+
+DEVTAB_ENTRY(mpc8xxx_smc_serial_io_scc2,
+ CYGDAT_IO_SERIAL_POWERPC_MPC8XXX_SCC2_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ mpc8xxx_sxx_serial_init,
+ mpc8xxx_sxx_serial_lookup, // Serial driver may need initializing
+ &mpc8xxx_sxx_serial_channel_scc2
+ );
+#endif // CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC2
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC3
+static mpc8xxx_sxx_serial_info mpc8xxx_sxx_serial_info_scc3 = {
+ SCC3_PAGE_SUBBLOCK, // Channel indicator
+ CYGNUM_HAL_INTERRUPT_SCC3, // interrupt
+ _SCC_CHAN
+};
+#if CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_BUFSIZE > 0
+static unsigned char mpc8xxx_smc_serial_out_buf_scc3[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_BUFSIZE];
+static unsigned char mpc8xxx_smc_serial_in_buf_scc3[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(mpc8xxx_sxx_serial_channel_scc3,
+ mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_info_scc3,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &mpc8xxx_smc_serial_out_buf_scc3[0], sizeof(mpc8xxx_smc_serial_out_buf_scc3),
+ &mpc8xxx_smc_serial_in_buf_scc3[0], sizeof(mpc8xxx_smc_serial_in_buf_scc3)
+ );
+#else
+static SERIAL_CHANNEL(mpc8xxx_sxx_serial_channel_scc3,
+ mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_info_scc3,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+static unsigned char mpc8xxx_scc3_txbuf[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_TxNUM*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_TxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static unsigned char mpc8xxx_scc3_rxbuf[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_RxNUM*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_RxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+
+DEVTAB_ENTRY(mpc8xxx_smc_serial_io_scc3,
+ CYGDAT_IO_SERIAL_POWERPC_MPC8XXX_SCC3_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ mpc8xxx_sxx_serial_init,
+ mpc8xxx_sxx_serial_lookup, // Serial driver may need initializing
+ &mpc8xxx_sxx_serial_channel_scc3
+ );
+#endif // CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC3
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+mpc8xxx_smc_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ unsigned int baud_divisor = select_baud[new_config->baud];
+ cyg_uint32 _lcr;
+ volatile struct smc_regs_8260 *ctl = (volatile struct smc_regs_8260*)smc_chan->ctl;
+
+ if (baud_divisor == 0) return false;
+ // Disable channel during setup
+ ctl->smc_smcmr = MPC8XXX_SMCMR_UART; // Disabled, UART mode
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ // Disable port interrupts while changing hardware
+ _lcr = smc_select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] |
+ smc_select_stop_bits[new_config->stop] |
+ smc_select_parity[new_config->parity];
+ // Stop transmitter while changing baud rate
+ IMM->cpm_cpcr = smc_chan->channel | CPCR_STOP_TX | CPCR_FLG;
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ // Set baud rate generator
+ *smc_chan->brg = 0x10000 | (UART_BITRATE(baud_divisor)<<1);
+
+ // Enable channel with new configuration
+ ctl->smc_smcmr = MPC8XXX_SMCMR_UART|MPC8XXX_SMCMR_TEN|MPC8XXX_SMCMR_REN|_lcr;
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ IMM->cpm_cpcr = smc_chan->channel | CPCR_INIT_TX_RX_PARAMS | CPCR_FLG;
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+// Function to set up internal tables for device.
+static void
+mpc8xxx_smc_serial_init_info(mpc8xxx_sxx_serial_info *smc_chan,
+ t_Smc_Pram *uart_pram,
+ volatile struct smc_regs_8260 *ctl,
+ unsigned long *brg,
+ int TxBD, int TxNUM, int TxSIZE,
+ cyg_uint8 *TxBUF,
+ int RxBD, int RxNUM, int RxSIZE,
+ cyg_uint8 *RxBUF)
+{
+ struct cp_bufdesc *txbd, *rxbd;
+ int i;
+
+ smc_chan->pram = (void *)uart_pram;
+ smc_chan->ctl = (void *)ctl;
+
+ // Set up baud rate generator
+ smc_chan->brg = (void *)brg;
+
+ // Disable channel during setup
+ ctl->smc_smcmr = MPC8XXX_SMCMR_UART; // Disabled, UART mode
+
+ // Rx, Tx function codes (used for access)
+ uart_pram->rfcr = 0x18;
+ uart_pram->tfcr = 0x18;
+
+ // Pointers to Rx & Tx buffer descriptor rings
+ uart_pram->rbase = RxBD;
+ uart_pram->tbase = TxBD;
+
+ /* tx and rx buffer descriptors */
+ txbd = (struct cp_bufdesc *)((char *)IMM + TxBD);
+ rxbd = (struct cp_bufdesc *)((char *)IMM + RxBD);
+ smc_chan->txbd = txbd;
+ smc_chan->tbase = txbd;
+ smc_chan->txsize = TxSIZE;
+ smc_chan->rxbd = rxbd;
+ smc_chan->rbase = rxbd;
+ smc_chan->rxsize = RxSIZE;
+
+ /* set max_idle feature - generate interrupt after 4 chars idle period */
+ uart_pram->max_idl = 4;
+
+ /* no last brk char received */
+ uart_pram->brkln = 0;
+
+ /* no break condition occurred */
+ uart_pram->brkec = 0;
+
+ /* 1 break char sent on top XMIT */
+ uart_pram->brkcr = 1;
+
+ /* setup RX buffer descriptors */
+ for (i = 0; i < RxNUM; i++) {
+ rxbd->length = 0;
+ rxbd->buffer = RxBUF;
+ rxbd->ctrl = _BD_CTL_Ready | _BD_CTL_Int;
+ if (i == (RxNUM-1)) rxbd->ctrl |= _BD_CTL_Wrap; // Last buffer
+ RxBUF += RxSIZE;
+ rxbd++;
+ }
+ /* setup TX buffer descriptors */
+ for (i = 0; i < TxNUM; i++) {
+ txbd->length = 0;
+ txbd->buffer = TxBUF;
+ txbd->ctrl = 0;
+ if (i == (TxNUM-1)) txbd->ctrl |= _BD_CTL_Wrap; // Last buffer
+ TxBUF += TxSIZE;
+ txbd++;
+ }
+ /*
+ * Reset Rx & Tx params
+ */
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ IMM->cpm_cpcr = smc_chan->channel | CPCR_INIT_TX_RX_PARAMS | CPCR_FLG;
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ /*
+ * Clear any previous events. Enable interrupts.
+ * (Section 16.15.7.14 and 16.15.7.15)
+ */
+ ctl->smc_smce = 0xFF;
+ ctl->smc_smcm = SMCE_Bsy|SMCE_Tx|SMCE_Rx;
+}
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+mpc8xxx_scc_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ mpc8xxx_sxx_serial_info *scc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ unsigned int baud_divisor = select_baud[new_config->baud];
+ volatile struct scc_regs_8260 *regs = (volatile struct scc_regs_8260*)scc_chan->ctl;
+
+ if (baud_divisor == 0) return false;
+ // Set baud rate generator
+ *scc_chan->brg = 0x10000 | (UART_BITRATE(baud_divisor)<<1);
+ // Disable channel during setup
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ regs->gsmr_l = 0;
+ regs->psmr = MPC8XXX_SCC_PSMR_ASYNC |
+ scc_select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] |
+ scc_select_stop_bits[new_config->stop] |
+ scc_select_parity[new_config->parity];
+
+ // Enable channel with new configuration
+ regs->gsmr_h = 0x20; // 8bit FIFO
+ regs->gsmr_l = 0x00028004; // 16x TxCLK, 16x RxCLK, UART
+
+ /*
+ * Init Rx & Tx params for SCCX
+ */
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ IMM->cpm_cpcr = CPCR_INIT_TX_RX_PARAMS | scc_chan->channel | CPCR_FLG;
+
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ regs->gsmr_l |= GSMR_L1_ENT | GSMR_L1_ENR; // Enable Rx, Tx
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+// Function to set up internal tables for device.
+static void
+mpc8xxx_scc_serial_init_info(mpc8xxx_sxx_serial_info *scc_chan,
+ volatile t_Scc_Pram *uart_pram,
+ volatile struct scc_regs_8260 *ctl,
+ unsigned long *brg,
+ int TxBD, int TxNUM, int TxSIZE,
+ cyg_uint8 *TxBUF,
+ int RxBD, int RxNUM, int RxSIZE,
+ cyg_uint8 *RxBUF)
+{
+ struct cp_bufdesc *txbd, *rxbd;
+ int i;
+
+ // Disable channel during setup
+ ctl->gsmr_l = 0;
+ scc_chan->pram = (void *)uart_pram;
+ scc_chan->ctl = (void *)ctl;
+
+ // Set up baud rate generator
+ scc_chan->brg = brg;
+
+ /*
+ * Set Rx and Tx function code
+ * (Section 16.15.4.2)
+ */
+ uart_pram->rfcr = 0x18;
+ uart_pram->tfcr = 0x18;
+ /*
+ * Set pointers to buffer descriptors.
+ * (Sections 16.15.4.1, 16.15.7.12, and 16.15.7.13)
+ */
+ uart_pram->rbase = RxBD;
+ uart_pram->tbase = TxBD;
+ /* tx and rx buffer descriptors */
+ txbd = (struct cp_bufdesc *)((char *)IMM + TxBD);
+ rxbd = (struct cp_bufdesc *)((char *)IMM + RxBD);
+ scc_chan->txbd = txbd;
+ scc_chan->tbase = txbd;
+ scc_chan->txsize = TxSIZE;
+ scc_chan->rxbd = rxbd;
+ scc_chan->rbase = rxbd;
+ scc_chan->rxsize = RxSIZE;
+ /* max receive buffer length */
+ uart_pram->mrblr = RxSIZE;
+ /* set max_idle feature - generate interrupt after 4 chars idle period */
+ uart_pram->SpecificProtocol.u.max_idl = 4;
+ /* no last brk char received */
+ uart_pram->SpecificProtocol.u.brkln = 0;
+ /* no break condition occurred */
+ uart_pram->SpecificProtocol.u.brkec = 0;
+ /* 1 break char sent on top XMIT */
+ uart_pram->SpecificProtocol.u.brkcr = 1;
+ /* character mask */
+ uart_pram->SpecificProtocol.u.rccm = 0xC0FF;
+ /* control characters */
+ for (i = 0; i < 8; i++) {
+ uart_pram->SpecificProtocol.u.cc[i] = 0x8000; // Mark unused
+ }
+ /* setup RX buffer descriptors */
+ for (i = 0; i < RxNUM; i++) {
+ rxbd->length = 0;
+ rxbd->buffer = RxBUF;
+ rxbd->ctrl = _BD_CTL_Ready | _BD_CTL_Int;
+ if (i == (RxNUM-1)) rxbd->ctrl |= _BD_CTL_Wrap; // Last buffer
+ RxBUF += RxSIZE;
+ rxbd++;
+ }
+ /* setup TX buffer descriptors */
+ for (i = 0; i < TxNUM; i++) {
+ txbd->length = 0;
+ txbd->buffer = TxBUF;
+ txbd->ctrl = 0;
+ if (i == (TxNUM-1)) txbd->ctrl |= _BD_CTL_Wrap; // Last buffer
+ TxBUF += TxSIZE;
+ txbd++;
+ }
+ /*
+ * Reset Rx & Tx params
+ */
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ IMM->cpm_cpcr = scc_chan->channel | CPCR_INIT_TX_RX_PARAMS | CPCR_FLG;
+ /*
+ * Clear any previous events. Enable interrupts.
+ * (Section 16.15.7.14 and 16.15.7.15)
+ */
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ ctl->scce = 0xFFFF;
+ ctl->sccm = (SCCE_Bsy | SCCE_Tx | SCCE_Rx);
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+mpc8xxx_sxx_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ int TxBD, RxBD;
+ int cache_state;
+
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+#ifdef CYGDBG_IO_INIT
+ diag_printf("MPC8XXX_SMC SERIAL init - dev: %x.%d = %s\n", smc_chan->channel, smc_chan->int_num, tab->name);
+#endif
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SMC1
+ if (chan == &mpc8xxx_sxx_serial_channel_smc1) {
+ TxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_TxNUM);
+ RxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_RxNUM);
+ mpc8xxx_smc_serial_init_info(&mpc8xxx_sxx_serial_info_smc1,
+ (t_Smc_Pram *)((char *)IMM + DPRAM_SMC1_OFFSET),
+ &IMM->smc_regs[SMC1],
+ (unsigned long *)&IMM->brgs_brgc7,
+ TxBD,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_TxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_TxSIZE,
+ &mpc8xxx_smc1_txbuf[0],
+ RxBD,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_RxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_RxSIZE,
+ &mpc8xxx_smc1_rxbuf[0]
+ );
+ }
+#endif
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SMC2
+#warning "Serial driver on SMC2 is unverified"
+ if (chan == &mpc8xxx_sxx_serial_channel_smc2) {
+ TxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_TxNUM);
+ RxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_RxNUM);
+ mpc8xxx_smc_serial_init_info(&mpc8xxx_sxx_serial_info_smc2,
+ &IMM->pram[3].scc.pothers.smc_modem.psmc.u, // PRAM
+ &IMM->smc_regs[1], // Control registers
+ &IMM->brgs_brgc7,
+ TxBD,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_TxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_TxSIZE,
+ &mpc8xxx_smc2_txbuf[0],
+ RxBD,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_RxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_RxSIZE,
+ &mpc8xxx_smc2_rxbuf[0]
+ );
+ }
+#endif
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC1
+ if (chan == &mpc8xxx_sxx_serial_channel_scc1) {
+ TxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_TxNUM);
+ RxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_RxNUM);
+ mpc8xxx_scc_serial_init_info(&mpc8xxx_sxx_serial_info_scc1,
+ &IMM->pram.serials.scc_pram[SCC1],
+ &IMM->scc_regs[SCC1],
+ (unsigned long *)&IMM->brgs_brgc1,
+ TxBD,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_TxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_TxSIZE,
+ &mpc8xxx_scc1_txbuf[0],
+ RxBD,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_RxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_RxSIZE,
+ &mpc8xxx_scc1_rxbuf[0]
+ );
+ }
+#endif
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC2
+#warning "Serial driver on SCC2 is unverified"
+ if (chan == &mpc8xxx_sxx_serial_channel_scc2) {
+ TxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_TxNUM);
+ RxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_RxNUM);
+ mpc8xxx_scc_serial_init_info(&mpc8xxx_sxx_serial_info_scc2,
+ &IMM->pram[1].scc.pscc.u, // PRAM
+ &IMM->scc_regs[1], // Control registers
+ &IMM->brgs_brgc2,
+ TxBD,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_TxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_TxSIZE,
+ &mpc8xxx_scc2_txbuf[0],
+ RxBD,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_RxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_RxSIZE,
+ &mpc8xxx_scc2_rxbuf[0]
+ );
+ }
+#endif
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC3
+#warning "Serial driver on SCC3 is unverified"
+ if (chan == &mpc8xxx_sxx_serial_channel_scc3) {
+ TxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_TxNUM);
+ RxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_RxNUM);
+ mpc8xxx_scc_serial_init_info(&mpc8xxx_sxx_serial_info_scc3,
+ &IMM->pram[2].scc.pscc.u, // PRAM
+ &IMM->scc_regs[2], // Control registersn
+ &IMM->brgs_brgc3,
+ TxBD,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_TxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_TxSIZE,
+ &mpc8xxx_scc3_txbuf[0],
+ RxBD,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_RxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_RxSIZE,
+ &mpc8xxx_scc3_rxbuf[0]
+ );
+ }
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(smc_chan->int_num,
+ 0, // Priority - unused (but asserted)
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ mpc8xxx_sxx_serial_ISR,
+ mpc8xxx_sxx_serial_DSR,
+ &smc_chan->serial_interrupt_handle,
+ &smc_chan->serial_interrupt);
+ cyg_drv_interrupt_attach(smc_chan->serial_interrupt_handle);
+ cyg_drv_interrupt_unmask(smc_chan->int_num);
+ }
+ if (smc_chan->type == _SMC_CHAN) {
+ mpc8xxx_smc_serial_config_port(chan, &chan->config, true);
+ } else {
+ mpc8xxx_scc_serial_config_port(chan, &chan->config, true);
+ }
+ if (cache_state)
+ HAL_DCACHE_ENABLE();
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+mpc8xxx_sxx_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Force the current transmit buffer to be sent
+static void
+mpc8xxx_sxx_serial_flush(mpc8xxx_sxx_serial_info *smc_chan)
+{
+ volatile struct cp_bufdesc *txbd = smc_chan->txbd;
+ int cache_state;
+
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ if (cache_state) {
+ HAL_DCACHE_FLUSH(txbd->buffer, smc_chan->txsize);
+ }
+ if ((txbd->length > 0) &&
+ ((txbd->ctrl & (_BD_CTL_Ready|_BD_CTL_Int)) == 0)) {
+ txbd->ctrl |= _BD_CTL_Ready|_BD_CTL_Int; // Signal buffer ready
+ if (txbd->ctrl & _BD_CTL_Wrap) {
+ txbd = smc_chan->tbase;
+ } else {
+ txbd++;
+ }
+ smc_chan->txbd = txbd;
+ }
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+mpc8xxx_sxx_serial_putc(serial_channel *chan, unsigned char c)
+{
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ volatile struct cp_bufdesc *txbd, *txfirst;
+ volatile t_Smc_Pram *pram = (volatile t_Smc_Pram *)smc_chan->pram;
+ bool res;
+
+ cyg_drv_dsr_lock(); // Avoid race condition testing pointers
+ txbd = (struct cp_bufdesc *)((char *)IMM + pram->tbptr);
+ txfirst = txbd;
+ // Scan for a non-busy buffer
+ while (txbd->ctrl & _BD_CTL_Ready) {
+ // This buffer is busy, move to next one
+ if (txbd->ctrl & _BD_CTL_Wrap) {
+ txbd = smc_chan->tbase;
+ } else {
+ txbd++;
+ }
+ if (txbd == txfirst) break; // Went all the way around
+ }
+ smc_chan->txbd = txbd;
+ if ((txbd->ctrl & (_BD_CTL_Ready|_BD_CTL_Int)) == 0) {
+ // Transmit buffer is not full/busy
+ txbd->buffer[txbd->length++] = c;
+ if (txbd->length == smc_chan->txsize) {
+ // This buffer is now full, tell SMC to start processing it
+ mpc8xxx_sxx_serial_flush(smc_chan);
+ }
+ res = true;
+ } else {
+ // No space
+ res = false;
+ }
+ cyg_drv_dsr_unlock();
+ return res;
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+mpc8xxx_sxx_serial_getc(serial_channel *chan)
+{
+ unsigned char c;
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ volatile struct cp_bufdesc *rxbd = smc_chan->rxbd;
+
+ while ((rxbd->ctrl & _BD_CTL_Ready) != 0) ;
+ c = rxbd->buffer[0];
+ rxbd->length = smc_chan->rxsize;
+ rxbd->ctrl |= _BD_CTL_Ready;
+ if (rxbd->ctrl & _BD_CTL_Wrap) {
+ rxbd = smc_chan->rbase;
+ } else {
+ rxbd++;
+ }
+ smc_chan->rxbd = (struct cp_bufdesc *)rxbd;
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+mpc8xxx_sxx_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ int res;
+
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ // FIXME - The documentation says that you can't change the baud rate
+ // again until at least two BRG input clocks have occurred.
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if (smc_chan->type == _SMC_CHAN) {
+ res = mpc8xxx_smc_serial_config_port(chan, config, true);
+ } else {
+ res = mpc8xxx_scc_serial_config_port(chan, config, true);
+ }
+ if ( true != res )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter (interrupt) on the device
+static void
+mpc8xxx_sxx_serial_start_xmit(serial_channel *chan)
+{
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ cyg_drv_dsr_lock();
+ if (smc_chan->txbd->length == 0) {
+ // See if there is anything to put in this buffer, just to get it going
+ (chan->callbacks->xmt_char)(chan);
+ }
+ if (smc_chan->txbd->length != 0) {
+ // Make sure it gets started
+ mpc8xxx_sxx_serial_flush(smc_chan);
+ }
+ cyg_drv_dsr_unlock();
+}
+
+// Disable the transmitter on the device
+static void
+mpc8xxx_sxx_serial_stop_xmit(serial_channel *chan)
+{
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ // If anything is in the last buffer, need to get it started
+ if (smc_chan->txbd->length != 0) {
+ mpc8xxx_sxx_serial_flush(smc_chan);
+ }
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32
+mpc8xxx_sxx_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(smc_chan->int_num);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void
+mpc8xxx_smc_serial_DSR(serial_channel *chan)
+{
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ volatile struct smc_regs_8260 *ctl = (volatile struct smc_regs_8260 *)smc_chan->ctl;
+ volatile struct cp_bufdesc *txbd;
+ volatile struct cp_bufdesc *rxbd = smc_chan->rxbd;
+ volatile t_Smc_Pram *pram = (volatile t_Smc_Pram *)smc_chan->pram;
+ struct cp_bufdesc *rxlast;
+ int i, cache_state;
+
+ if (ctl->smc_smce & SMCE_Tx) {
+ // Transmit interrupt
+ ctl->smc_smce = SMCE_Tx; // Reset interrupt state;
+ txbd = smc_chan->tbase; // First buffer
+ while (true) {
+ if ((txbd->ctrl & (_BD_CTL_Ready|_BD_CTL_Int)) == _BD_CTL_Int) {
+ txbd->length = 0;
+ txbd->ctrl &= ~_BD_CTL_Int; // Reset interrupt bit
+ }
+ if (txbd->ctrl & _BD_CTL_Wrap) {
+ txbd = smc_chan->tbase;
+ break;
+ } else {
+ txbd++;
+ }
+ }
+ (chan->callbacks->xmt_char)(chan);
+ }
+ while (ctl->smc_smce & SMCE_Rx) {
+ // Receive interrupt
+ ctl->smc_smce = SMCE_Rx; // Reset interrupt state;
+ rxlast = (struct cp_bufdesc *) (
+ (char *)IMM + pram->rbptr );
+ while (rxbd != rxlast) {
+ if ((rxbd->ctrl & _BD_CTL_Ready) == 0) {
+ for (i = 0; i < rxbd->length; i++) {
+ (chan->callbacks->rcv_char)(chan, rxbd->buffer[i]);
+ }
+ // Note: the MBX860 does not seem to snoop/invalidate the data cache properly!
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ if (cache_state) {
+ HAL_DCACHE_INVALIDATE(rxbd->buffer, smc_chan->rxsize); // Make sure no stale data
+ }
+ rxbd->length = 0;
+ rxbd->ctrl |= _BD_CTL_Ready;
+ }
+ if (rxbd->ctrl & _BD_CTL_Wrap) {
+ rxbd = smc_chan->rbase;
+ } else {
+ rxbd++;
+ }
+ }
+ smc_chan->rxbd = (struct cp_bufdesc *)rxbd;
+ }
+ if (ctl->smc_smce & SMCE_Bsy) {
+ ctl->smc_smce = SMCE_Bsy; // Reset interrupt state;
+ }
+ cyg_drv_interrupt_acknowledge(smc_chan->int_num);
+ cyg_drv_interrupt_unmask(smc_chan->int_num);
+}
+
+static void
+mpc8xxx_scc_serial_DSR(serial_channel *chan)
+{
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ volatile struct scc_regs_8260 *ctl = (volatile struct scc_regs_8260 *)smc_chan->ctl;
+ volatile struct cp_bufdesc *txbd;
+ volatile struct cp_bufdesc *rxbd = smc_chan->rxbd;
+ volatile t_Smc_Pram *pram = (volatile t_Smc_Pram *)smc_chan->pram;
+ struct cp_bufdesc *rxlast;
+ int i, cache_state;
+
+ if (ctl->scce & SCCE_Tx) {
+ // Transmit interrupt
+ ctl->scce = SCCE_Tx; // Reset interrupt state;
+ txbd = smc_chan->tbase; // First buffer
+ while (true) {
+ if ((txbd->ctrl & (_BD_CTL_Ready|_BD_CTL_Int)) == _BD_CTL_Int) {
+ txbd->length = 0;
+ txbd->ctrl &= ~_BD_CTL_Int; // Reset interrupt bit
+ }
+ if (txbd->ctrl & _BD_CTL_Wrap) {
+ txbd = smc_chan->tbase;
+ break;
+ } else {
+ txbd++;
+ }
+ }
+ (chan->callbacks->xmt_char)(chan);
+ }
+ while (ctl->scce & SCCE_Rx) {
+ // Receive interrupt
+ ctl->scce = SCCE_Rx; // Reset interrupt state;
+ rxlast = (struct cp_bufdesc *) ((char *)IMM + pram->rbptr);
+ while (rxbd != rxlast) {
+ if ((rxbd->ctrl & _BD_CTL_Ready) == 0) {
+ for (i = 0; i < rxbd->length; i++) {
+ (chan->callbacks->rcv_char)(chan, rxbd->buffer[i]);
+ }
+ // Note: the MBX860 does not seem to snoop/invalidate the data cache properly!
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ if (cache_state) {
+ HAL_DCACHE_INVALIDATE(rxbd->buffer, smc_chan->rxsize); // Make sure no stale data
+ }
+ rxbd->length = 0;
+ rxbd->ctrl |= _BD_CTL_Ready;
+ }
+ if (rxbd->ctrl & _BD_CTL_Wrap) {
+ rxbd = smc_chan->rbase;
+ } else {
+ rxbd++;
+ }
+ }
+ smc_chan->rxbd = (struct cp_bufdesc *)rxbd;
+ }
+ if (ctl->scce & SCCE_Bsy) {
+ ctl->scce = SCCE_Bsy; // Reset interrupt state;
+ }
+ cyg_drv_interrupt_acknowledge(smc_chan->int_num);
+ cyg_drv_interrupt_unmask(smc_chan->int_num);
+}
+
+static void
+mpc8xxx_sxx_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+
+ if (smc_chan->type == _SMC_CHAN) {
+ mpc8xxx_smc_serial_DSR(chan);
+ } else {
+ mpc8xxx_scc_serial_DSR(chan);
+ }
+}
+
+// ------------------------------------------------------------------------
+// EOF powerpc/mpc8xxx_smc_serial.c
Index: devs/serial/powerpc/mpc8xxx/current/src/mpc8xxx_serial.h
===================================================================
RCS file: devs/serial/powerpc/mpc8xxx/current/src/mpc8xxx_serial.h
diff -N devs/serial/powerpc/mpc8xxx/current/src/mpc8xxx_serial.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ devs/serial/powerpc/mpc8xxx/current/src/mpc8xxx_serial.h 9 Nov 2003 22:55:31 -0000
@@ -0,0 +1,155 @@
+#ifndef CYGONCE_POWERPC_MPC8XXX_SERIAL_H
+#define CYGONCE_POWERPC_MPC8XXX_SERIAL_H
+
+// ====================================================================
+//
+// mpc8xxx_serial.h
+//
+// Device I/O - Description of PowerPC MPC8XXX (QUICC-II) serial hardware
+//
+// ====================================================================
+//####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 Gary Thomas
+//
+// 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-06-21
+// Purpose: Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+// Description of serial ports using MPC8XXX (QUICC-II)
+
+// SMC Mode Register
+#define MPC8XXX_SMCMR_CLEN(n) ((n+1)<<11) // Character length
+#define MPC8XXX_SMCMR_SB(n) ((n-1)<<10) // Stop bits (1 or 2)
+#define MPC8XXX_SMCMR_PE(n) (n<<9) // Parity enable (0=disable, 1=enable)
+#define MPC8XXX_SMCMR_PM(n) (n<<8) // Parity mode (0=odd, 1=even)
+#define MPC8XXX_SMCMR_UART (2<<4) // UART mode
+#define MPC8XXX_SMCMR_TEN (1<<1) // Enable transmitter
+#define MPC8XXX_SMCMR_REN (1<<0) // Enable receiver
+
+static unsigned int smc_select_word_length[] = {
+ MPC8XXX_SMCMR_CLEN(5), // 5 bits / word (char)
+ MPC8XXX_SMCMR_CLEN(6),
+ MPC8XXX_SMCMR_CLEN(7),
+ MPC8XXX_SMCMR_CLEN(8)
+};
+
+static unsigned int smc_select_stop_bits[] = {
+ 0,
+ MPC8XXX_SMCMR_SB(1), // 1 stop bit
+ MPC8XXX_SMCMR_SB(1), // 1.5 stop bit
+ MPC8XXX_SMCMR_SB(2) // 2 stop bits
+};
+
+static unsigned int smc_select_parity[] = {
+ MPC8XXX_SMCMR_PE(0), // No parity
+ MPC8XXX_SMCMR_PE(1)|MPC8XXX_SMCMR_PM(1), // Even parity
+ MPC8XXX_SMCMR_PE(1)|MPC8XXX_SMCMR_PM(0), // Odd parity
+ 0, // Mark parity
+ 0, // Space parity
+};
+
+// SCC PSMR masks ....
+#define MPC8XXX_SCC_PSMR_ASYNC 0x8000
+#define MPC8XXX_SCC_PSMR_SB(n) ((n-1)<<14) // Stop bits (1=1sb, 2=2sb)
+#define MPC8XXX_SCC_PSMR_CLEN(n) ((n-5)<<12) // Character Length (5-8)
+#define MPC8XXX_SCC_PSMR_PE(n) (n<<4) // Parity enable(0=disabled, 1=enabled)
+#define MPC8XXX_SCC_PSMR_RPM(n) (n<<2) // Rx Parity mode (0=odd, 1=low, 2=even, 3=high)
+#define MPC8XXX_SCC_PSMR_TPM(n) (n) // Tx Parity mode (0=odd, 1=low, 2=even, 3=high)
+
+static unsigned int scc_select_word_length[] = {
+ MPC8XXX_SCC_PSMR_CLEN(5), // 5 bits / word (char)
+ MPC8XXX_SCC_PSMR_CLEN(6),
+ MPC8XXX_SCC_PSMR_CLEN(7),
+ MPC8XXX_SCC_PSMR_CLEN(8)
+};
+
+static unsigned int scc_select_stop_bits[] = {
+ MPC8XXX_SCC_PSMR_SB(1), // 0.5 stop bit ??
+ MPC8XXX_SCC_PSMR_SB(1), // 1 stop bit
+ MPC8XXX_SCC_PSMR_SB(2), // 1.5 stop bit
+ MPC8XXX_SCC_PSMR_SB(2) // 2 stop bits
+};
+
+
+static unsigned int scc_select_parity[] = {
+ MPC8XXX_SCC_PSMR_PE(0), // No parity
+ MPC8XXX_SCC_PSMR_PE(1)|MPC8XXX_SCC_PSMR_TPM(2)|MPC8XXX_SCC_PSMR_RPM(2), // Even parity
+ MPC8XXX_SCC_PSMR_PE(1)|MPC8XXX_SCC_PSMR_TPM(0)|MPC8XXX_SCC_PSMR_RPM(0), // Odd parity
+ MPC8XXX_SCC_PSMR_PE(1)|MPC8XXX_SCC_PSMR_TPM(3)|MPC8XXX_SCC_PSMR_RPM(3), // High (mark) parity
+ MPC8XXX_SCC_PSMR_PE(1)|MPC8XXX_SCC_PSMR_TPM(1)|MPC8XXX_SCC_PSMR_RPM(1), // Low (space) parity
+};
+
+// Baud rate values, based on board clock
+
+static cyg_int32 select_baud[] = {
+ 0, // Unused
+ 50, // 50
+ 75, // 75
+ 110, // 110
+ 0, // 134.5
+ 150, // 150
+ 200, // 200
+ 300, // 300
+ 600, // 600
+ 1200, // 1200
+ 1800, // 1800
+ 2400, // 2400
+ 3600, // 3600
+ 4800, // 4800
+ 7200, // 7200
+ 9600, // 9600
+ 14400, // 14400
+ 19200, // 19200
+ 38400, // 38400
+ 57600, // 57600
+ 115200, // 115200
+ 0, // 230400
+};
+
+#define UART_BITRATE(n) \
+ ((((int)(((CYGHWR_HAL_POWERPC_CPM_SPEED*2)*1000000)/16))/(n * 16))-1)
+
+// Channel type select
+#define _SCC_CHAN 0
+#define _SMC_CHAN 1
+
+#endif // CYGONCE_POWERPC_MPC8XXX_SERIAL_H
Index: hal/powerpc/mpc8xxx/current/ChangeLog
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/hal/powerpc/mpc8xxx/current/ChangeLog,v
retrieving revision 1.3
diff -u -5 -p -r1.3 ChangeLog
--- hal/powerpc/mpc8xxx/current/ChangeLog 8 Sep 2003 14:55:35 -0000 1.3
+++ hal/powerpc/mpc8xxx/current/ChangeLog 9 Nov 2003 23:06:15 -0000
@@ -1,5 +1,10 @@
+2003-11-09 Gary Thomas <gary@mlbassoc.com>
+
+ * src/quicc2_diag.c:
+ * include/mpc8xxx.h: Move some serial definitions to common file.
+
2003-09-08 Gary Thomas <gary@mlbassoc.com>
* src/quicc2_diag.c: Fix baud rate clock setup - was off by 1.
Reported by Tord Andersson <Tord.Andersson@combitechsystems.com>
Index: hal/powerpc/mpc8xxx/current/include/mpc8xxx.h
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/hal/powerpc/mpc8xxx/current/include/mpc8xxx.h,v
retrieving revision 1.2
diff -u -5 -p -r1.2 mpc8xxx.h
--- hal/powerpc/mpc8xxx/current/include/mpc8xxx.h 26 Aug 2003 17:04:03 -0000 1.2
+++ hal/powerpc/mpc8xxx/current/include/mpc8xxx.h 9 Nov 2003 23:05:40 -0000
@@ -64,36 +64,10 @@
#define DPRAM_SMC1_OFFSET 0x2000
#define DPRAM_SMC2_OFFSET 0x2100
#define DPRAM_BD_OFFSET 0x2200
-/*--------------------------*/
-/* Buffer Descriptor Format */
-/*--------------------------*/
-
-typedef struct BufferDescriptor
-
-{
- CYG_WORD16 bd_cstatus; /* control and status */
- CYG_WORD16 bd_length; /* transfer length */
- volatile CYG_BYTE *bd_addr; /* buffer address */
-
-} BD;
-
-
-/*-------------------------------*/
-/* Buffer Descriptor Ring format */
-/*-------------------------------*/
-
-typedef struct BufferDescRings
-
-{
- BD RxBD; /* Rx BD ring */
- BD TxBD; /* Tx BD ring */
-
-} BDRINGS;
-
#define _Packed
#define _PackedType __attribute__((packed))
/******************************************************************************
*
@@ -1361,10 +1335,33 @@ extern volatile t_PQ2IMM *IMM; /* IMM
#define GSMR_L1_ENT 0x00000010 /* ENT bit for the GSMR low register */
#define GSMR_L1_ENR 0x00000020 /* ENR bit for the GSMR low register */
#define ALL_ONES 0xFFFF
+
+struct cp_bufdesc {
+ volatile unsigned short ctrl; /* status/control register */
+ volatile unsigned short length; /* buffer length */
+ volatile char *buffer; /* buffer pointer */
+};
+
+// Buffer descriptor control bits
+#define _BD_CTL_Ready 0x8000 // Buffer contains data (tx) or is empty (rx)
+#define _BD_CTL_Wrap 0x2000 // Last buffer in list
+#define _BD_CTL_Int 0x1000 // Generate interrupt when empty (tx) or full (rx)
+#define _BD_CTL_Last 0x0800 // Last buffer in a sequence
+#define _BD_CTL_MASK 0xB000 // User settable bits
+
+//
+// Event masks
+//
+#define SCCE_Bsy 0x0004 // Rx error
+#define SCCE_Tx 0x0002 // Tx buffer interrupt
+#define SCCE_Rx 0x0001 // Rx buffer interrupt
+#define SMCE_Bsy 0x0004 // Rx error
+#define SMCE_Tx 0x0002 // Tx buffer interrupt
+#define SMCE_Rx 0x0001 // Rx buffer interrupt
//
// Routines which help manage the CPM
//
externC void _mpc8xxx_reset_cpm(void);
Index: hal/powerpc/mpc8xxx/current/src/quicc2_diag.c
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/hal/powerpc/mpc8xxx/current/src/quicc2_diag.c,v
retrieving revision 1.2
diff -u -5 -p -r1.2 quicc2_diag.c
--- hal/powerpc/mpc8xxx/current/src/quicc2_diag.c 8 Sep 2003 14:55:36 -0000 1.2
+++ hal/powerpc/mpc8xxx/current/src/quicc2_diag.c 9 Nov 2003 21:51:08 -0000
@@ -60,26 +60,10 @@
#include <cyg/hal/drv_api.h> // CYG_ISR_HANDLED
#include <cyg/hal/hal_intr.h>
#include <cyg/hal/mpc8xxx.h> // Needed for IMMR structure
-struct cp_bufdesc {
- volatile unsigned short ctrl; /* status/control register */
- volatile unsigned short length; /* buffer length */
- volatile char *buffer; /* buffer pointer */
-};
-
-// Buffer descriptor control bits
-#define _BD_CTL_Ready 0x8000 // Buffer contains data (tx) or is empty (rx)
-#define _BD_CTL_Wrap 0x2000 // Last buffer in list
-#define _BD_CTL_Int 0x1000 // Generate interrupt when empty (tx) or full (rx)
-#define _BD_CTL_Last 0x0800 // Last buffer in a sequence
-#define _BD_CTL_MASK 0xB000 // User settable bits
-
-#define SCCE_Rx 0x0001 // Rx buffer interrupt
-#define SMCE_Rx 0x0001 // Rx buffer interrupt
-
#define PORT_IS_SMC 1
#define PORT_IS_SCC 0
#define NUM(t) sizeof(t)/sizeof(t[0])