changeset 1153:2baeb5095c81

New package to support the serial device on a Samsung ARM9/SMDK2410 development board.
author nickg
date Wed, 06 Aug 2003 17:23:02 +0000
parents 74ebd002d7bd
children 04a7d2f9dd69
files packages/devs/serial/arm/smdk2410/current/ChangeLog packages/devs/serial/arm/smdk2410/current/cdl/ser_arm_smdk2410.cdl packages/devs/serial/arm/smdk2410/current/src/smdk2410_serial.c packages/devs/serial/arm/smdk2410/current/src/smdk2410_serial.h
diffstat 4 files changed, 719 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/packages/devs/serial/arm/smdk2410/current/ChangeLog
@@ -0,0 +1,7 @@
+2003-08-06  Michael Anburaj <embeddedeng@hotmail.com>
+
+	* cdl/ser_arm_smdk2410.cdl:
+	* src/smdk2410_serial.c:
+	* src/smdk2410_serial.h:
+	New package to support the serial device on a Samsung
+	ARM9/SMDK2410 development board.
new file mode 100644
--- /dev/null
+++ b/packages/devs/serial/arm/smdk2410/current/cdl/ser_arm_smdk2410.cdl
@@ -0,0 +1,199 @@
+# ====================================================================
+#
+#      ser_arm_smdk2410.cdl
+#
+#      eCos serial ARM/SMDK2410 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):      michael anburaj <michaelanburaj@hotmail.com>
+# Contributors:   michael anburaj <michaelanburaj@hotmail.com>
+# Date:           2003-08-01
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_ARM_SMDK2410 {
+    display       "Samsung ARM9/SMDK2410 board serial device drivers"
+
+    parent        CYGPKG_IO_SERIAL_DEVICES
+    active_if     CYGPKG_IO_SERIAL
+    active_if     CYGPKG_HAL_ARM_ARM9_SMDK2410
+
+    requires      CYGPKG_ERROR
+    include_dir   cyg/io
+    include_files ; # none _exported_ whatsoever
+    description   "
+           This option enables the serial device drivers for the
+           Samsung SMDK2410 and S3c2410x (ARM9) based development boards."
+
+    compile       -library=libextras.a   smdk2410_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_arm_smdk2410.h>"
+        puts $::cdl_system_header "/*****  serial driver proc output end  *****/"
+    }
+
+    cdl_component CYGPKG_IO_SERIAL_ARM_SMDK2410_SERIAL0 {
+        display       "Samsung SMDK2410 serial port 0 driver"
+        flavor        bool
+        default_value 1
+        description   "
+            This option includes the serial device driver for the Samsung SMDK2410 port 0."
+
+        cdl_option CYGDAT_IO_SERIAL_ARM_SMDK2410_SERIAL0_NAME {
+            display       "Device name for the Samsung SMDK2410 serial port 0 driver"
+            flavor        data
+            default_value {"\"/dev/ser0\""}
+            description   "
+                This option specifies the name of serial device for the Samsung SMDK2410 port 0."
+        }
+
+        cdl_option CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL0_BAUD {
+            display       "Baud rate for the Samsung SMDK2410 serial port 0 driver"
+            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 Samsung SMDK2410 port 0."
+        }
+
+        cdl_option CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL0_BUFSIZE {
+            display       "Buffer size for the Samsung SMDK2410 serial port 0 driver"
+            flavor        data
+            legal_values  0 to 8192
+            default_value 128
+            description   "
+                This option specifies the size of the internal buffers used for
+                the Samsung SMDK2410 port 0."
+        }
+    }
+
+    cdl_component CYGPKG_IO_SERIAL_ARM_SMDK2410_SERIAL1 {
+        display       "Samsung SMDK2410 serial port 1 driver"
+        flavor        bool
+        default_value 1
+        description   "
+            This option includes the serial device driver for the Samsung SMDK2410 port 1."
+
+        cdl_option CYGDAT_IO_SERIAL_ARM_SMDK2410_SERIAL1_NAME {
+            display       "Device name for the Samsung SMDK2410 serial port 1 driver"
+            flavor        data
+            default_value {"\"/dev/ser1\""}
+            description   "
+                This option specifies the name of serial device for the Samsung SMDK2410 port 1."
+        }
+
+        cdl_option CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL1_BAUD {
+            display       "Baud rate for the Samsung SMDK2410 serial port 1 driver"
+            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 Samsung SMDK2410 port 1."
+        }
+
+        cdl_option CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL1_BUFSIZE {
+            display       "Buffer size for the Samsung SMDK2410 serial port 1 driver"
+            flavor        data
+            legal_values  0 to 8192
+            default_value 128
+            description   "
+                This option specifies the size of the internal buffers used for
+                the Samsung SMDK2410 port 1."
+        }
+    }
+
+    cdl_component CYGPKG_IO_SERIAL_ARM_SMDK2410_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_ARM_SMDK2410_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_ARM_SMDK2410_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_ARM_SMDK2410_TESTING {
+        display    "Testing parameters"
+        flavor     bool
+        calculated 1
+        active_if  CYGPKG_IO_SERIAL_ARM_SMDK2410_SERIAL1
+        
+        cdl_option CYGPRI_SER_TEST_SER_DEV {
+            display       "Serial device used for testing"
+            flavor        data
+            default_value { CYGDAT_IO_SERIAL_ARM_SMDK2410_SERIAL1_NAME }
+        }
+
+        define_proc {
+            puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"smdk2410\""
+            puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV  \"/dev/tty1\""
+        }
+    }
+}
+
+# EOF ser_arm_smdk2410.cdl
new file mode 100644
--- /dev/null
+++ b/packages/devs/serial/arm/smdk2410/current/src/smdk2410_serial.c
@@ -0,0 +1,385 @@
+//==========================================================================
+//
+//      io/serial/arm/smdk2410_serial.c
+//
+//      Samsung SMDK2410 Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+//####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):    michael anburaj <michaelanburaj@hotmail.com>
+// Contributors: michael anburaj <michaelanburaj@hotmail.com>
+// Date:         2003-08-01
+// Purpose:      SMDK2410 Serial I/O module (interrupt driven version)
+// 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>           // interrupt
+#include <cyg/hal/hal_io.h>             // register base
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+
+#ifdef CYGPKG_IO_SERIAL_ARM_SMDK2410
+
+#include "smdk2410_serial.h"
+
+typedef struct smdk2410_serial_info {
+    CYG_ADDRWORD   base;
+    CYG_WORD       int_num;
+    cyg_uint32     bit_sub_rxd;
+    cyg_interrupt  serial_interrupt;
+    cyg_handle_t   serial_interrupt_handle;
+} smdk2410_serial_info;
+
+static bool smdk2410_serial_init(struct cyg_devtab_entry *tab);
+static bool smdk2410_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo smdk2410_serial_lookup(struct cyg_devtab_entry **tab, 
+                                        struct cyg_devtab_entry *sub_tab,
+                                        const char *name);
+static unsigned char smdk2410_serial_getc(serial_channel *chan);
+static Cyg_ErrNo smdk2410_serial_set_config(serial_channel *chan, 
+                                            cyg_uint32 key,
+                                            const void *xbuf, cyg_uint32 *len);
+static void smdk2410_serial_start_xmit(serial_channel *chan);
+static void smdk2410_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 smdk2410_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void       smdk2410_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(smdk2410_serial_funs, 
+                   smdk2410_serial_putc, 
+                   smdk2410_serial_getc,
+                   smdk2410_serial_set_config,
+                   smdk2410_serial_start_xmit,
+                   smdk2410_serial_stop_xmit
+    );
+
+#ifdef CYGPKG_IO_SERIAL_ARM_SMDK2410_SERIAL0
+static smdk2410_serial_info smdk2410_serial_info0 = {(cyg_uint32)ULCON0,
+                                                     CYGNUM_HAL_INTERRUPT_UART0,
+                                                     BIT_SUB_RXD0};
+#if CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL0_BUFSIZE > 0
+static unsigned char smdk2410_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL0_BUFSIZE];
+static unsigned char smdk2410_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(smdk2410_serial_channel0,
+                                       smdk2410_serial_funs, 
+                                       smdk2410_serial_info0,
+                                       CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL0_BAUD),
+                                       CYG_SERIAL_STOP_DEFAULT,
+                                       CYG_SERIAL_PARITY_DEFAULT,
+                                       CYG_SERIAL_WORD_LENGTH_DEFAULT,
+                                       CYG_SERIAL_FLAGS_DEFAULT,
+                                       &smdk2410_serial_out_buf0[0], sizeof(smdk2410_serial_out_buf0),
+                                       &smdk2410_serial_in_buf0[0], sizeof(smdk2410_serial_in_buf0)
+    );
+#else
+static SERIAL_CHANNEL(smdk2410_serial_channel0,
+                      smdk2410_serial_funs, 
+                      smdk2410_serial_info0,
+                      CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL0_BAUD),
+                      CYG_SERIAL_STOP_DEFAULT,
+                      CYG_SERIAL_PARITY_DEFAULT,
+                      CYG_SERIAL_WORD_LENGTH_DEFAULT,
+                      CYG_SERIAL_FLAGS_DEFAULT
+    );
+#endif
+
+DEVTAB_ENTRY(smdk2410_serial_io0, 
+             CYGDAT_IO_SERIAL_ARM_SMDK2410_SERIAL0_NAME,
+             0,                          // Does not depend on a lower level interface
+             &cyg_io_serial_devio, 
+             smdk2410_serial_init, 
+             smdk2410_serial_lookup,     // Serial driver may need initializing
+             &smdk2410_serial_channel0
+    );
+#endif //  CYGPKG_IO_SERIAL_ARM_SMDK2410_SERIAL0
+
+#ifdef CYGPKG_IO_SERIAL_ARM_SMDK2410_SERIAL1
+static smdk2410_serial_info smdk2410_serial_info1 = {(cyg_uint32)ULCON1,
+                                                     CYGNUM_HAL_INTERRUPT_UART1,
+                                                     BIT_SUB_RXD1};
+#if CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL1_BUFSIZE > 0
+static unsigned char smdk2410_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL1_BUFSIZE];
+static unsigned char smdk2410_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(smdk2410_serial_channel1,
+                                       smdk2410_serial_funs, 
+                                       smdk2410_serial_info1,
+                                       CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL1_BAUD),
+                                       CYG_SERIAL_STOP_DEFAULT,
+                                       CYG_SERIAL_PARITY_DEFAULT,
+                                       CYG_SERIAL_WORD_LENGTH_DEFAULT,
+                                       CYG_SERIAL_FLAGS_DEFAULT,
+                                       &smdk2410_serial_out_buf1[0], sizeof(smdk2410_serial_out_buf1),
+                                       &smdk2410_serial_in_buf1[0], sizeof(smdk2410_serial_in_buf1)
+    );
+#else
+static SERIAL_CHANNEL(smdk2410_serial_channel1,
+                      smdk2410_serial_funs, 
+                      smdk2410_serial_info1,
+                      CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL1_BAUD),
+                      CYG_SERIAL_STOP_DEFAULT,
+                      CYG_SERIAL_PARITY_DEFAULT,
+                      CYG_SERIAL_WORD_LENGTH_DEFAULT,
+                      CYG_SERIAL_FLAGS_DEFAULT
+    );
+#endif
+
+DEVTAB_ENTRY(smdk2410_serial_io1, 
+             CYGDAT_IO_SERIAL_ARM_SMDK2410_SERIAL1_NAME,
+             0,                          // Does not depend on a lower level interface
+             &cyg_io_serial_devio, 
+             smdk2410_serial_init, 
+             smdk2410_serial_lookup,     // Serial driver may need initializing
+             &smdk2410_serial_channel1
+    );
+#endif //  CYGPKG_IO_SERIAL_ARM_SMDK2410_SERIAL1
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+smdk2410_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+    smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
+    CYG_ADDRWORD base = smdk2410_chan->base;
+    unsigned short baud_divisor = select_baud[new_config->baud];
+    cyg_uint32 _lcr;
+
+    if (baud_divisor == 0) return false;
+
+    if (init) {
+        //UART FIFO control register
+        HAL_WRITE_UINT32(base+OFS_UFCON, (3<<6) | (3<<4) | (1<<2) | (1<<1) | (1<<0));
+
+        //UART modem control register
+        HAL_WRITE_UINT32(base+OFS_UMCON, 0);
+    }
+
+    _lcr = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] | 
+        select_stop_bits[new_config->stop] |
+        select_parity[new_config->parity];
+    HAL_WRITE_UINT32(base+OFS_ULCON, _lcr);
+
+    //UART control register, Enable Rx Timeout Int
+    HAL_WRITE_UINT32(base+OFS_UCON, 0x085);
+
+    if (new_config != &chan->config) {
+        chan->config = *new_config;
+    }
+    return true;
+}
+
+// Function to initialize the device.  Called at bootstrap time.
+static bool 
+smdk2410_serial_init(struct cyg_devtab_entry *tab)
+{
+    serial_channel *chan = (serial_channel *)tab->priv;
+    smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
+    cyg_uint32 _intsubm;
+#ifdef CYGDBG_IO_INIT
+    diag_printf("SMDK2410 SERIAL init - dev: 0x%08x.%d\n", 
+                smdk2410_chan->base, smdk2410_chan->int_num);
+#endif
+    (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices
+    if (chan->out_cbuf.len != 0) {
+        cyg_drv_interrupt_create(smdk2410_chan->int_num,
+                                 1,                    // Priority - unused
+                                 (cyg_addrword_t)chan, //  Data item passed to interrupt handler
+                                 smdk2410_serial_ISR,
+                                 smdk2410_serial_DSR,
+                                 &smdk2410_chan->serial_interrupt_handle,
+                                 &smdk2410_chan->serial_interrupt);
+        cyg_drv_interrupt_attach(smdk2410_chan->serial_interrupt_handle);
+        cyg_drv_interrupt_unmask(smdk2410_chan->int_num);
+
+        HAL_READ_UINT32(INTSUBMSK, _intsubm);
+        _intsubm &= ~(smdk2410_chan->bit_sub_rxd<<0);         // BIT_SUB_RXD
+        HAL_WRITE_UINT32(INTSUBMSK, _intsubm);
+    }
+    smdk2410_serial_config_port(chan, &chan->config, true);
+    return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo 
+smdk2410_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;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+smdk2410_serial_putc(serial_channel *chan, unsigned char c)
+{
+    smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
+    CYG_ADDRWORD base = smdk2410_chan->base;
+    cyg_uint32 _status;
+
+    HAL_READ_UINT32(base+OFS_UFSTAT, _status);
+    if (_status & 0x200) {
+        // No space
+        return false;
+    } else {
+        // Transmit buffer is not full
+        HAL_WRITE_UINT8(base+OFS_UTXH, (cyg_uint32)c);
+        return true;
+    }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char 
+smdk2410_serial_getc(serial_channel *chan)
+{
+    smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
+    CYG_ADDRWORD base = smdk2410_chan->base;
+    cyg_uint32 _status;
+    cyg_uint8 _c;
+
+    do {
+        HAL_READ_UINT32(base+OFS_UFSTAT, _status);
+    } while ((_status & 0xf) == 0);
+
+    HAL_READ_UINT8(base+OFS_URXH, _c);
+    return (unsigned char)_c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+smdk2410_serial_set_config(serial_channel *chan, cyg_uint32 key,
+                      const void *xbuf, cyg_uint32 *len)
+{
+    switch (key) {
+    case CYG_IO_SET_CONFIG_SERIAL_INFO:
+      {
+        cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+        if ( *len < sizeof(cyg_serial_info_t) ) {
+            return -EINVAL;
+        }
+        *len = sizeof(cyg_serial_info_t);
+        if ( true != smdk2410_serial_config_port(chan, config, false) )
+            return -EINVAL;
+      }
+      break;
+    default:
+        return -EINVAL;
+    }
+    return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+smdk2410_serial_start_xmit(serial_channel *chan)
+{
+    smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
+    cyg_uint32 _intsubm;
+
+    HAL_READ_UINT32(INTSUBMSK, _intsubm);
+    _intsubm &= ~(smdk2410_chan->bit_sub_rxd<<1);         // BIT_SUB_TXD
+    HAL_WRITE_UINT32(INTSUBMSK, _intsubm);
+}
+
+// Disable the transmitter on the device
+static void 
+smdk2410_serial_stop_xmit(serial_channel *chan)
+{
+    smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
+    cyg_uint32 _intsubm;
+
+    HAL_READ_UINT32(INTSUBMSK, _intsubm);
+    _intsubm |= (smdk2410_chan->bit_sub_rxd<<1);          // BIT_SUB_TXD
+    HAL_WRITE_UINT32(INTSUBMSK, _intsubm);
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32 
+smdk2410_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+    serial_channel *chan = (serial_channel *)data;
+    smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
+    cyg_drv_interrupt_mask(smdk2410_chan->int_num);
+    cyg_drv_interrupt_acknowledge(smdk2410_chan->int_num);
+    return CYG_ISR_CALL_DSR;  // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void       
+smdk2410_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+    serial_channel *chan = (serial_channel *)data;
+    smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
+    CYG_ADDRWORD base = smdk2410_chan->base;
+    cyg_uint32 _intsubpnd, _status, _c;
+    cyg_uint32 _rxd_bit = (smdk2410_chan->bit_sub_rxd<<0), _txd_bit=(smdk2410_chan->bit_sub_rxd<<1);
+
+    HAL_READ_UINT32(SUBSRCPND, _intsubpnd);
+
+    // Empty Rx FIFO
+    if (_intsubpnd & _rxd_bit) {
+        HAL_READ_UINT32(base+OFS_UFSTAT, _status);
+        while((_status & 0x0f) != 0) {
+            HAL_READ_UINT8(base+OFS_URXH, _c);
+            (chan->callbacks->rcv_char)(chan, (unsigned char)_c);
+            HAL_READ_UINT32(base+OFS_UFSTAT, _status);
+        }
+        HAL_WRITE_UINT32(SUBSRCPND, _rxd_bit);
+    }
+
+    // Fill into Tx FIFO. xmt_char will mask the interrupt when it
+    // runs out of chars, so doing this in a loop is OK.
+    if (_intsubpnd & _txd_bit) {
+        (chan->callbacks->xmt_char)(chan);
+        HAL_WRITE_UINT32(SUBSRCPND, _txd_bit);
+    }
+
+    cyg_drv_interrupt_unmask(smdk2410_chan->int_num);
+}
+
+#endif // CYGPKG_IO_SERIAL_ARM_SMDK2410
+
+// EOF smdk2410_serial.c
new file mode 100644
--- /dev/null
+++ b/packages/devs/serial/arm/smdk2410/current/src/smdk2410_serial.h
@@ -0,0 +1,128 @@
+#ifndef CYGONCE_ARM_SMDK2410_SERIAL_H
+#define CYGONCE_ARM_SMDK2410_SERIAL_H
+
+// ====================================================================
+//
+//      smdk2410_serial.h
+//
+//      Device I/O - Description of Samsung SMDK2410 serial hardware
+//
+// ====================================================================
+//####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):    michael anburaj <michaelanburaj@hotmail.com>
+// Contributors: michael anburaj <michaelanburaj@hotmail.com>
+// Date:         2003-08-01
+// Purpose:      Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+// Baud rate divisor registers values
+// (PCLK/16./BAUD_RATE+0.5) -1)
+#define UBRDIV_50     ((PCLK/16./50)-1)
+#define UBRDIV_75     ((PCLK/16./75)-1)
+#define UBRDIV_110    ((PCLK/16./110)-1)
+#define UBRDIV_134_5  ((PCLK/16./134.5)-1)
+#define UBRDIV_150    ((PCLK/16./150)-1)
+#define UBRDIV_200    ((PCLK/16./200)-1)
+#define UBRDIV_300    ((PCLK/16./300)-1)
+#define UBRDIV_600    ((PCLK/16./600)-1)
+#define UBRDIV_1200   ((PCLK/16./1200)-1)
+#define UBRDIV_1800   ((PCLK/16./1800)-1)
+#define UBRDIV_2400   ((PCLK/16./2400)-1)
+#define UBRDIV_3600   ((PCLK/16./3600)-1)
+#define UBRDIV_4800   ((PCLK/16./4800)-1)
+#define UBRDIV_7200   ((PCLK/16./7200)-1)
+#define UBRDIV_9600   ((PCLK/16./9600)-1)
+#define UBRDIV_14400  ((PCLK/16./14400)-1)
+#define UBRDIV_19200  ((PCLK/16./19200)-1)
+#define UBRDIV_38400  ((PCLK/16./38400)-1)
+#define UBRDIV_57600  ((PCLK/16./57600)-1)
+#define UBRDIV_115200 ((PCLK/16./115200)-1)
+#define UBRDIV_230400 ((PCLK/16./230400)-1)
+
+static unsigned char select_word_length[] = {
+    VAL_ULCON_WL_5,
+    VAL_ULCON_WL_6,
+    VAL_ULCON_WL_7,
+    VAL_ULCON_WL_8
+};
+
+static unsigned char select_stop_bits[] = {
+    0,                 // Unused
+    VAL_ULCON_SB_1,    // 1 stop bit
+    0,                 // 1.5 stop bit (not supported)
+    VAL_ULCON_SB_2     // 2 stop bits
+};
+
+static unsigned char select_parity[] = {
+    VAL_ULCON_PM_N,     // No parity
+    VAL_ULCON_PM_E,     // Even parity
+    VAL_ULCON_PM_O,     // Odd parity
+    VAL_ULCON_PM_FC1,   // Mark parity
+    VAL_ULCON_PM_FC0,   // Space parity
+};
+
+// Baud rate values, based on PCLK
+static unsigned short select_baud[] = {
+            0,    // Unused
+    UBRDIV_50,    // 50
+    UBRDIV_75,    // 75
+    UBRDIV_110,   // 110
+    UBRDIV_134_5, // 134.5
+    UBRDIV_150,   // 150
+    UBRDIV_200,   // 200
+    UBRDIV_300,   // 300
+    UBRDIV_600,   // 600
+    UBRDIV_1200,  // 1200
+    UBRDIV_1800,  // 1800
+    UBRDIV_2400,  // 2400
+    UBRDIV_3600,  // 3600
+    UBRDIV_4800,  // 4800
+    UBRDIV_7200,  // 7200
+    UBRDIV_9600,  // 9600
+    UBRDIV_14400, // 14400
+    UBRDIV_19200, // 19200
+    UBRDIV_38400, // 38400
+    UBRDIV_57600, // 57600
+    UBRDIV_115200,// 115200
+    UBRDIV_230400,// 230400
+};
+
+#endif // CYGONCE_ARM_SMDK2410_SERIAL_H