Mercurial > flash_v2
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
