URL
https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk
Subversion Repositories openrisc_me
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/rtos/ecos-2.0/packages/devs/serial/generic
- from Rev 27 to Rev 174
- ↔ Reverse comparison
Rev 27 → Rev 174
/16x5x/v2_0/cdl/ser_generic_16x5x.cdl
0,0 → 1,133
# ==================================================================== |
# |
# ser_generic_16x5x.cdl |
# |
# eCos serial 16x5x configuration data |
# |
# ==================================================================== |
#####ECOSGPLCOPYRIGHTBEGIN#### |
## ------------------------------------------- |
## This file is part of eCos, the Embedded Configurable Operating System. |
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
## |
## eCos is free software; you can redistribute it and/or modify it under |
## the terms of the GNU General Public License as published by the Free |
## Software Foundation; either version 2 or (at your option) any later version. |
## |
## eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
## WARRANTY; without even the implied warranty of MERCHANTABILITY or |
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
## for more details. |
## |
## You should have received a copy of the GNU General Public License along |
## with eCos; if not, write to the Free Software Foundation, Inc., |
## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
## |
## As a special exception, if other files instantiate templates or use macros |
## or inline functions from this file, or you compile this file and link it |
## with other works to produce a work based on this file, this file does not |
## by itself cause the resulting work to be covered by the GNU General Public |
## License. However the source code for this file must still be made available |
## in accordance with section (3) of the GNU General Public License. |
## |
## This exception does not invalidate any other reasons why a work based on |
## this file might be covered by the GNU General Public License. |
## |
## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
## at http://sources.redhat.com/ecos/ecos-license/ |
## ------------------------------------------- |
#####ECOSGPLCOPYRIGHTEND#### |
# ==================================================================== |
######DESCRIPTIONBEGIN#### |
# |
# Author(s): jskov |
# Original data: gthomas |
# Contributors: |
# Date: 1999-07-07 |
# |
#####DESCRIPTIONEND#### |
# |
# ==================================================================== |
|
|
cdl_package CYGPKG_IO_SERIAL_GENERIC_16X5X { |
display "16x5x generic serial device drivers" |
|
parent CYGPKG_IO_SERIAL_DEVICES |
active_if CYGPKG_IO_SERIAL |
|
active_if CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED |
|
requires CYGPKG_ERROR |
include_dir cyg/io |
include_files ; # none _exported_ whatsoever |
description " |
This option enables the serial device drivers for the |
16x5x compatiple controllers." |
|
compile -library=libextras.a ser_16x5x.c |
|
define_proc { |
puts $::cdl_system_header "/***** serial driver proc output start *****/" |
puts $::cdl_system_header "#ifndef CYGDAT_IO_SERIAL_DEVICE_HEADER" |
puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_generic_16x5x.h>" |
puts $::cdl_system_header "#endif" |
puts $::cdl_system_header "/***** serial driver proc output end *****/" |
puts $::cdl_header "#include <pkgconf/system.h>"; |
puts $::cdl_header "#include CYGDAT_IO_SERIAL_GENERIC_16X5X_CFG"; |
} |
|
cdl_component CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO { |
display "16x5x FIFO support" |
flavor bool |
default_value 1 |
description " |
Options to configure the FIFO on a 16550 (or above) variant." |
|
cdl_option CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO_RX_THRESHOLD { |
display "Threshold for RX interrupt on 16550 FIFO" |
flavor data |
legal_values { 14 8 4 1 } |
default_value 1 |
description " |
This options configures the threshold value at which |
the RX interrupt occurs when a FIFO is used. (16550 and |
above only), this may be after 1, 4, 8 or 14 characters." |
} |
} |
|
cdl_component CYGPKG_IO_SERIAL_GENERIC_16X5X_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_GENERIC_16X5X_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_GENERIC_16X5X_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." |
} |
} |
} |
|
# EOF ser_generic_16x5x.cdl |
/16x5x/v2_0/src/ser_16x5x.c
0,0 → 1,605
//========================================================================== |
// |
// io/serial/generic/16x5x/ser_16x5x.c |
// |
// Generic 16x5x serial driver |
// |
//========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//========================================================================== |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): gthomas |
// Contributors: gthomas, jlarmour, jskov |
// Date: 1999-02-04 |
// Purpose: 16x5x generic serial driver |
// 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/infra/cyg_ass.h> |
#include <cyg/hal/hal_io.h> |
|
// Only compile driver if an inline file with driver details was selected. |
#ifdef CYGDAT_IO_SERIAL_GENERIC_16X5X_INL |
|
#ifndef CYGPRI_IO_SERIAL_GENERIC_16X5X_STEP |
#define CYGPRI_IO_SERIAL_GENERIC_16X5X_STEP 1 |
#endif |
|
#define SER_REG(_x_) ((_x_)*CYGPRI_IO_SERIAL_GENERIC_16X5X_STEP) |
|
// Receive control Registers |
#define REG_rhr SER_REG(0) // Receive holding register |
#define REG_isr SER_REG(2) // Interrupt status register |
#define REG_lsr SER_REG(5) // Line status register |
#define REG_msr SER_REG(6) // Modem status register |
#define REG_scr SER_REG(7) // Scratch register |
|
// Transmit control Registers |
#define REG_thr SER_REG(0) // Transmit holding register |
#define REG_ier SER_REG(1) // Interrupt enable register |
#define REG_fcr SER_REG(2) // FIFO control register |
#define REG_lcr SER_REG(3) // Line control register |
#define REG_mcr SER_REG(4) // Modem control register |
#define REG_ldl SER_REG(0) // LSB of baud rate |
#define REG_mdl SER_REG(1) // MSB of baud rate |
|
// Interrupt Enable Register |
#define IER_RCV 0x01 |
#define IER_XMT 0x02 |
#define IER_LS 0x04 |
#define IER_MS 0x08 |
|
// Line Control Register |
#define LCR_WL5 0x00 // Word length |
#define LCR_WL6 0x01 |
#define LCR_WL7 0x02 |
#define LCR_WL8 0x03 |
#define LCR_SB1 0x00 // Number of stop bits |
#define LCR_SB1_5 0x04 // 1.5 -> only valid with 5 bit words |
#define LCR_SB2 0x04 |
#define LCR_PN 0x00 // Parity mode - none |
#define LCR_PE 0x18 // Parity mode - even |
#define LCR_PO 0x08 // Parity mode - odd |
#define LCR_PM 0x28 // Forced "mark" parity |
#define LCR_PS 0x38 // Forced "space" parity |
#define LCR_DL 0x80 // Enable baud rate latch |
|
// Line Status Register |
#define LSR_RSR 0x01 |
#define LSR_OE 0x02 |
#define LSR_PE 0x04 |
#define LSR_FE 0x08 |
#define LSR_BI 0x10 |
#define LSR_THE 0x20 |
#define LSR_TEMT 0x40 |
#define LSR_FIE 0x80 |
|
// Modem Control Register |
#define MCR_DTR 0x01 |
#define MCR_RTS 0x02 |
#define MCR_INT 0x08 // Enable interrupts |
#define MCR_LOOP 0x10 // Loopback mode |
|
// Interrupt status Register |
#define ISR_MS 0x00 |
#define ISR_nIP 0x01 |
#define ISR_Tx 0x02 |
#define ISR_Rx 0x04 |
#define ISR_LS 0x06 |
#define ISR_RxTO 0x0C |
#define ISR_64BFIFO 0x20 |
#define ISR_FIFOworks 0x40 |
#define ISR_FIFOen 0x80 |
|
// Modem Status Register |
#define MSR_DCTS 0x01 |
#define MSR_DDSR 0x02 |
#define MSR_TERI 0x04 |
#define MSR_DDCD 0x08 |
#define MSR_CTS 0x10 |
#define MSR_DSR 0x20 |
#define MSR_RI 0x40 |
#define MSR_CD 0x80 |
|
// FIFO Control Register |
#define FCR_FE 0x01 // FIFO enable |
#define FCR_CRF 0x02 // Clear receive FIFO |
#define FCR_CTF 0x04 // Clear transmit FIFO |
#define FCR_DMA 0x08 // DMA mode select |
#define FCR_F64 0x20 // Enable 64 byte fifo (16750+) |
#define FCR_RT14 0xC0 // Set Rx trigger at 14 |
#define FCR_RT8 0x80 // Set Rx trigger at 8 |
#define FCR_RT4 0x40 // Set Rx trigger at 4 |
#define FCR_RT1 0x00 // Set Rx trigger at 1 |
|
static unsigned char select_word_length[] = { |
LCR_WL5, // 5 bits / word (char) |
LCR_WL6, |
LCR_WL7, |
LCR_WL8 |
}; |
|
static unsigned char select_stop_bits[] = { |
0, |
LCR_SB1, // 1 stop bit |
LCR_SB1_5, // 1.5 stop bit |
LCR_SB2 // 2 stop bits |
}; |
|
static unsigned char select_parity[] = { |
LCR_PN, // No parity |
LCR_PE, // Even parity |
LCR_PO, // Odd parity |
LCR_PM, // Mark parity |
LCR_PS, // Space parity |
}; |
|
// selec_baud[] must be define by the client |
|
typedef struct pc_serial_info { |
cyg_addrword_t base; |
int int_num; |
cyg_interrupt serial_interrupt; |
cyg_handle_t serial_interrupt_handle; |
#ifdef CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO |
enum { |
sNone = 0, |
s8250, |
s16450, |
s16550, |
s16550a |
} deviceType; |
#endif |
} pc_serial_info; |
|
static bool pc_serial_init(struct cyg_devtab_entry *tab); |
static bool pc_serial_putc(serial_channel *chan, unsigned char c); |
static Cyg_ErrNo pc_serial_lookup(struct cyg_devtab_entry **tab, |
struct cyg_devtab_entry *sub_tab, |
const char *name); |
static unsigned char pc_serial_getc(serial_channel *chan); |
static Cyg_ErrNo pc_serial_set_config(serial_channel *chan, cyg_uint32 key, |
const void *xbuf, cyg_uint32 *len); |
static void pc_serial_start_xmit(serial_channel *chan); |
static void pc_serial_stop_xmit(serial_channel *chan); |
|
static cyg_uint32 pc_serial_ISR(cyg_vector_t vector, cyg_addrword_t data); |
static void pc_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, |
cyg_addrword_t data); |
|
static SERIAL_FUNS(pc_serial_funs, |
pc_serial_putc, |
pc_serial_getc, |
pc_serial_set_config, |
pc_serial_start_xmit, |
pc_serial_stop_xmit |
); |
|
#include CYGDAT_IO_SERIAL_GENERIC_16X5X_INL |
|
// Internal function to actually configure the hardware to desired |
// baud rate, etc. |
static bool |
serial_config_port(serial_channel *chan, |
cyg_serial_info_t *new_config, bool init) |
{ |
pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv; |
cyg_addrword_t base = ser_chan->base; |
unsigned short baud_divisor = select_baud[new_config->baud]; |
unsigned char _lcr, _ier; |
if (baud_divisor == 0) return false; // Invalid configuration |
|
// Disable port interrupts while changing hardware |
HAL_READ_UINT8(base+REG_ier, _ier); |
HAL_WRITE_UINT8(base+REG_ier, 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_UINT8(base+REG_lcr, _lcr | LCR_DL); |
HAL_WRITE_UINT8(base+REG_mdl, baud_divisor >> 8); |
HAL_WRITE_UINT8(base+REG_ldl, baud_divisor & 0xFF); |
HAL_WRITE_UINT8(base+REG_lcr, _lcr); |
if (init) { |
#ifdef CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO |
unsigned char _fcr_thresh; |
cyg_uint8 b; |
|
/* First, find out what kind of device it is. */ |
ser_chan->deviceType = sNone; |
HAL_WRITE_UINT8(base+REG_mcr, MCR_LOOP); // enable loopback mode |
HAL_READ_UINT8(base+REG_msr, b); |
if (0 == (b & 0xF0)) { // see if MSR had CD, RI, DSR or CTS set |
HAL_WRITE_UINT8(base+REG_mcr, MCR_LOOP|MCR_DTR|MCR_RTS); |
HAL_READ_UINT8(base+REG_msr, b); |
if (0xF0 != (b & 0xF0)) // check that all of CD,RI,DSR and CTS set |
ser_chan->deviceType = s8250; |
} |
HAL_WRITE_UINT8(base+REG_mcr, 0); // disable loopback mode |
|
if (ser_chan->deviceType == s8250) { |
// Check for a scratch register; scratch register |
// indicates 16450 or above. |
HAL_WRITE_UINT8(base+REG_scr, 0x55); |
HAL_READ_UINT8(base+REG_scr, b); |
if (b == 0x55) { |
HAL_WRITE_UINT8(base+REG_scr, 0xAA); |
HAL_READ_UINT8(base+REG_scr, b); |
if (b == 0xAA) |
ser_chan->deviceType = s16450; |
} |
} |
|
if (ser_chan->deviceType == s16450) { |
// Check for a FIFO |
HAL_WRITE_UINT8(base+REG_fcr, FCR_FE); |
HAL_READ_UINT8(base+REG_isr, b); |
if (b & ISR_FIFOen) |
ser_chan->deviceType = s16550; // but FIFO doesn't |
// necessarily work |
if (b & ISR_FIFOworks) |
ser_chan->deviceType = s16550a; // 16550a FIFOs work |
} |
|
if (ser_chan->deviceType == s16550a) { |
switch(CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO_RX_THRESHOLD) { |
default: |
case 1: |
_fcr_thresh=FCR_RT1; break; |
case 4: |
_fcr_thresh=FCR_RT4; break; |
case 8: |
_fcr_thresh=FCR_RT8; break; |
case 14: |
_fcr_thresh=FCR_RT14; break; |
} |
_fcr_thresh|=FCR_FE|FCR_CRF|FCR_CTF; |
HAL_WRITE_UINT8(base+REG_fcr, _fcr_thresh); // Enable and clear FIFO |
} |
else |
HAL_WRITE_UINT8(base+REG_fcr, 0); // make sure it's disabled |
#endif |
if (chan->out_cbuf.len != 0) { |
_ier = IER_RCV; |
} else { |
_ier = 0; |
} |
// Master interrupt enable |
HAL_WRITE_UINT8(base+REG_mcr, MCR_INT|MCR_DTR|MCR_RTS); |
} |
#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS |
_ier |= (IER_LS|IER_MS); |
#endif |
HAL_WRITE_UINT8(base+REG_ier, _ier); |
|
if (new_config != &chan->config) { |
chan->config = *new_config; |
} |
return true; |
} |
|
// Function to initialize the device. Called at bootstrap time. |
static bool |
pc_serial_init(struct cyg_devtab_entry *tab) |
{ |
serial_channel *chan = (serial_channel *)tab->priv; |
pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv; |
#ifdef CYGDBG_IO_INIT |
diag_printf("16x5x SERIAL init - dev: %x.%d\n", |
ser_chan->base, ser_chan->int_num); |
#endif |
// Really only required for interrupt driven devices |
(chan->callbacks->serial_init)(chan); |
|
if (chan->out_cbuf.len != 0) { |
cyg_drv_interrupt_create(ser_chan->int_num, |
99, |
(cyg_addrword_t)chan, |
pc_serial_ISR, |
pc_serial_DSR, |
&ser_chan->serial_interrupt_handle, |
&ser_chan->serial_interrupt); |
cyg_drv_interrupt_attach(ser_chan->serial_interrupt_handle); |
cyg_drv_interrupt_unmask(ser_chan->int_num); |
} |
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 |
pc_serial_lookup(struct cyg_devtab_entry **tab, |
struct cyg_devtab_entry *sub_tab, |
const char *name) |
{ |
serial_channel *chan = (serial_channel *)(*tab)->priv; |
|
// Really only required for interrupt driven devices |
(chan->callbacks->serial_init)(chan); |
return ENOERR; |
} |
|
// Send a character to the device output buffer. |
// Return 'true' if character is sent to device |
static bool |
pc_serial_putc(serial_channel *chan, unsigned char c) |
{ |
cyg_uint8 _lsr; |
pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv; |
cyg_addrword_t base = ser_chan->base; |
|
HAL_READ_UINT8(base+REG_lsr, _lsr); |
if (_lsr & LSR_THE) { |
// Transmit buffer is empty |
HAL_WRITE_UINT8(base+REG_thr, c); |
return true; |
} |
// No space |
return false; |
} |
|
// Fetch a character from the device input buffer, waiting if necessary |
static unsigned char |
pc_serial_getc(serial_channel *chan) |
{ |
unsigned char c; |
cyg_uint8 _lsr; |
pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv; |
cyg_addrword_t base = ser_chan->base; |
|
// Wait for char |
do { |
HAL_READ_UINT8(base+REG_lsr, _lsr); |
} while ((_lsr & LSR_RSR) == 0); |
|
HAL_READ_UINT8(base+REG_rhr, c); |
return c; |
} |
|
// Set up the device characteristics; baud rate, etc. |
static Cyg_ErrNo |
pc_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 != serial_config_port(chan, config, false) ) |
return -EINVAL; |
} |
break; |
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW |
case CYG_IO_SET_CONFIG_SERIAL_HW_RX_FLOW_THROTTLE: |
{ |
cyg_uint8 _mcr; |
pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv; |
cyg_addrword_t base = ser_chan->base; |
cyg_uint8 *f = (cyg_uint8 *)xbuf; |
unsigned char mask=0; |
if ( *len < sizeof(*f) ) |
return -EINVAL; |
|
if ( chan->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_RX ) |
mask = MCR_RTS; |
if ( chan->config.flags & CYGNUM_SERIAL_FLOW_DSRDTR_RX ) |
mask |= MCR_DTR; |
HAL_READ_UINT8(base+REG_mcr, _mcr); |
if (*f) // we should throttle |
_mcr &= ~mask; |
else // we should no longer throttle |
_mcr |= mask; |
HAL_WRITE_UINT8(base+REG_mcr, _mcr); |
} |
break; |
case CYG_IO_SET_CONFIG_SERIAL_HW_FLOW_CONFIG: |
// Nothing to do because we do support both RTSCTS and DSRDTR flow |
// control. |
// Other targets would clear any unsupported flags here. |
// We just return ENOERR. |
break; |
#endif |
default: |
return -EINVAL; |
} |
return ENOERR; |
} |
|
// Enable the transmitter on the device |
static void |
pc_serial_start_xmit(serial_channel *chan) |
{ |
pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv; |
cyg_addrword_t base = ser_chan->base; |
cyg_uint8 _ier; |
|
HAL_READ_UINT8(base+REG_ier, _ier); |
_ier |= IER_XMT; // Enable xmit interrupt |
HAL_WRITE_UINT8(base+REG_ier, _ier); |
} |
|
// Disable the transmitter on the device |
static void |
pc_serial_stop_xmit(serial_channel *chan) |
{ |
pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv; |
cyg_addrword_t base = ser_chan->base; |
cyg_uint8 _ier; |
|
HAL_READ_UINT8(base+REG_ier, _ier); |
_ier &= ~IER_XMT; // Disable xmit interrupt |
HAL_WRITE_UINT8(base+REG_ier, _ier); |
} |
|
// Serial I/O - low level interrupt handler (ISR) |
static cyg_uint32 |
pc_serial_ISR(cyg_vector_t vector, cyg_addrword_t data) |
{ |
serial_channel *chan = (serial_channel *)data; |
pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv; |
cyg_drv_interrupt_mask(ser_chan->int_num); |
cyg_drv_interrupt_acknowledge(ser_chan->int_num); |
return CYG_ISR_CALL_DSR; // Cause DSR to be run |
} |
|
// Serial I/O - high level interrupt handler (DSR) |
static void |
pc_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) |
{ |
serial_channel *chan = (serial_channel *)data; |
pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv; |
cyg_addrword_t base = ser_chan->base; |
cyg_uint8 _isr; |
|
// Check if we have an interrupt pending - note that the interrupt |
// is pending of the low bit of the isr is *0*, not 1. |
HAL_READ_UINT8(base+REG_isr, _isr); |
while ((_isr & ISR_nIP) == 0) { |
switch (_isr&0xE) { |
case ISR_Rx: |
case ISR_RxTO: |
{ |
cyg_uint8 _lsr; |
unsigned char c; |
HAL_READ_UINT8(base+REG_lsr, _lsr); |
while(_lsr & LSR_RSR) { |
HAL_READ_UINT8(base+REG_rhr, c); |
(chan->callbacks->rcv_char)(chan, c); |
HAL_READ_UINT8(base+REG_lsr, _lsr); |
} |
break; |
} |
case ISR_Tx: |
(chan->callbacks->xmt_char)(chan); |
break; |
|
#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS |
case ISR_LS: |
{ |
cyg_serial_line_status_t stat; |
cyg_uint8 _lsr; |
HAL_READ_UINT8(base+REG_lsr, _lsr); |
|
// this might look expensive, but it is rarely the case that |
// more than one of these is set |
stat.value = 1; |
if ( _lsr & LSR_OE ) { |
stat.which = CYGNUM_SERIAL_STATUS_OVERRUNERR; |
(chan->callbacks->indicate_status)(chan, &stat ); |
} |
if ( _lsr & LSR_PE ) { |
stat.which = CYGNUM_SERIAL_STATUS_PARITYERR; |
(chan->callbacks->indicate_status)(chan, &stat ); |
} |
if ( _lsr & LSR_FE ) { |
stat.which = CYGNUM_SERIAL_STATUS_FRAMEERR; |
(chan->callbacks->indicate_status)(chan, &stat ); |
} |
if ( _lsr & LSR_BI ) { |
stat.which = CYGNUM_SERIAL_STATUS_BREAK; |
(chan->callbacks->indicate_status)(chan, &stat ); |
} |
} |
break; |
|
case ISR_MS: |
{ |
cyg_serial_line_status_t stat; |
cyg_uint8 _msr; |
|
HAL_READ_UINT8(base+REG_msr, _msr); |
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW |
if ( _msr & MSR_DDSR ) |
if ( chan->config.flags & CYGNUM_SERIAL_FLOW_DSRDTR_TX ) { |
stat.which = CYGNUM_SERIAL_STATUS_FLOW; |
stat.value = (0 != (_msr & MSR_DSR)); |
(chan->callbacks->indicate_status)(chan, &stat ); |
} |
if ( _msr & MSR_DCTS ) |
if ( chan->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_TX ) { |
stat.which = CYGNUM_SERIAL_STATUS_FLOW; |
stat.value = (0 != (_msr & MSR_CTS)); |
(chan->callbacks->indicate_status)(chan, &stat ); |
} |
#endif |
if ( _msr & MSR_DDCD ) { |
stat.which = CYGNUM_SERIAL_STATUS_CARRIERDETECT; |
stat.value = (0 != (_msr & MSR_CD)); |
(chan->callbacks->indicate_status)(chan, &stat ); |
} |
if ( _msr & MSR_RI ) { |
stat.which = CYGNUM_SERIAL_STATUS_RINGINDICATOR; |
stat.value = 1; |
(chan->callbacks->indicate_status)(chan, &stat ); |
} |
if ( _msr & MSR_TERI ) { |
stat.which = CYGNUM_SERIAL_STATUS_RINGINDICATOR; |
stat.value = 0; |
(chan->callbacks->indicate_status)(chan, &stat ); |
} |
} |
break; |
#endif |
default: |
// Yes, this assertion may well not be visible. *But* |
// if debugging, we may still successfully hit a breakpoint |
// on cyg_assert_fail, which _is_ useful |
CYG_FAIL("unhandled serial interrupt state"); |
} |
|
HAL_READ_UINT8(base+REG_isr, _isr); |
} // while |
|
cyg_drv_interrupt_unmask(ser_chan->int_num); |
} |
#endif |
|
// EOF ser_16x5x.c |
/16x5x/v2_0/ChangeLog
0,0 → 1,287
2003-02-24 Jonathan Larmour <jifl@eCosCentric.com> |
|
* cdl/ser_generic_16x5x.cdl: Remove irrelevant doc link. |
|
2001-06-19 Jesper Skov <jskov@redhat.com> |
|
* cdl/ser_generic_16x5x.cdl: Only define |
CYGDAT_IO_SERIAL_DEVICE_HEADER when necessary. |
|
2001-06-18 Jonathan Larmour <jlarmour@redhat.com> |
|
* src/ser_16x5x.c (pc_serial_set_config): Fix length check typo |
|
2001-06-18 Jesper Skov <jskov@masala.cambridge.redhat.com> |
|
* src/ser_16x5x.c (LCR_PE): Set correct bits (from Boris V. Guzhov) |
|
2001-06-08 Jonathan Larmour <jlarmour@redhat.com> |
|
* src/ser_16x5x.c: Support FIFOs better by detecting what we've got, |
and only acting if we have a _working_ FIFO. |
Assert on unhandled serial interrupt type. |
|
2001-03-13 Jonathan Larmour <jlarmour@redhat.com> |
|
* cdl/ser_generic_16x5x.cdl: Rename |
CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO_OPTIONS to |
CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO and make it a boolean. Clarify |
descriptions a little. |
|
* src/ser_16x5x.c (serial_config_port): Only program FCR if FIFO |
support requested. |
Don't bother with intermediate _fifo_thresh. |
Detabify. |
|
2001-03-13 Jesper Skov <jskov@redhat.com> |
|
* cdl/ser_generic_16x5x.cdl: Removed the default value. |
|
2001-03-09 Julian Smart <julians@redhat.com> |
Removed default value for flavor none in |
CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO_OPTIONS since it |
causes an assert in libcdl |
|
2001-03-05 Jesper Skov <jskov@redhat.com> |
2001-02-15 Dave Airlie <airlied@parthus.com> |
|
* src/ser_16x5x.c (serial_config_port): Add support for setting |
a FIFO RX Threshold via CDL |
|
* cdl/ser_generic_16x5x.cdl: Add support for setting a FIFO |
RX threshold via CDL |
|
2001-01-24 Dave Airlie <airlied@parthus.com> |
|
* src/ser_16x5x.c (pc_serial_DSR): Allow RX timeouts to be interpreted |
as RXs. |
|
2000-12-19 Dave Airlie <airlied@parthus.com> |
|
* src/ser_16x5x.c: Add defines for FIFO control register |
(serial_config_port): Use these defines. |
|
2000-12-07 Jesper Skov <jskov@redhat.com> |
|
* src/ser_16x5x.c (ISR_LS): Corrected value. Spotted by Dave Airlie. |
|
2000-09-18 Jesper Skov <jskov@redhat.com> |
|
* src/ser_16x5x.c: Allow clients to specify register |
stepping. Rename a type. Fix compile error. |
|
2000-09-14 Jesper Skov <jskov@redhat.com> |
|
* src/ser_16x5x.c: Moved ARM/PID driver to provide generic 16x5x |
driver. Rewritten to use HAL IO macros. Still needs some polish |
and configury to properly support all the various target |
controllers that may only have a partial set of the features. |
* cdl/ser_generic_16x5x.cdl: Same. |
|
* Removed non-PID related ChangeLog entries. |
|
---------------------------------------------------------------------------- |
2000-08-24 Jonathan Larmour <jlarmour@redhat.co.uk> |
|
* src/pid_serial_with_ints.c (pid_serial_DSR): Remove accidental |
OVERRUNERR check duplication |
|
2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk> |
|
* src/pid_serial_with_ints.c: Throughout, add support for line status |
and modem status callbacks, hardware RTS/CTS and DSR/DTR flow control |
(pid_serial_set_config): Now use keys to make |
more flexible. |
|
* src/pid_serial.h: Add more line status, interrupt status and modem |
status register definitions |
|
* cdl/ser_arm_pid.cdl: Implements flow control and line status |
interfaces |
|
2000-06-22 Hugo Tyson <hmt@cygnus.co.uk> |
|
* cdl/<yournamehere>.cdl: Remove the comment on the empty |
include_files directive; the tools now support this correctly. |
This keeps internal include files internal. |
|
2000-06-09 Jesper Skov <jskov@redhat.com> |
|
* src/pid_serial_with_ints.c: |
* src/pid_serial.h: |
Cleaned up defines and made DSR handle all received characters. |
(Dave Airlie (airlied at parthus dot com)) |
|
2000-04-11 Hugo Tyson <hmt@cygnus.co.uk> |
|
* cdl/ser_arm_pid.cdl: Change the parent from CYGPKG_IO_SERIAL |
(which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES |
(which is not...) thus allowing convenient control independent of |
platform. Also enable all individual devices by default, now, so |
that they can be enabled simply by enabling the above new parent. |
|
2000-04-07 Hugo Tyson <hmt@cygnus.co.uk> |
|
* ecos.db: Re-organize device packages. This is a massive change |
involving deleting all the sources for serial and ethernet drivers |
from where they used to live in |
packages/io/serial/current/src/ARCH/PLATFORM.[ch] |
packages/net/drivers/eth/PLATFORM/current/src/... |
and reinstating them in |
packages/devs/serial/ARCH/PLATFORM/current/src/... |
packages/devs/eth/ARCH/PLATFORM/current/src/... |
|
All these new packages are properly defined in ecos.db, and are |
all of type "hardware" so that a "target" can grab them. |
|
This directory layout is descriptive of the devices we have right |
now, arch and platform are separate levels just to make it easier |
to navigate in the filesystem and similar to the HAL structure in |
the filesystem. |
|
It is *not* prescriptive of future work; for example, the mythical |
common highly-portable 16550 serial driver which works on many |
targets would be called "devs/serial/s16550/current", or a serial |
device for a particular board (cogent springs to mind) that can |
work with different CPUs fitted is "devs/serial/cogent/current". |
|
Changelogs have been preserved and replicated over all the new |
packages, so that no history is lost. |
|
The contents of individual source files are unchanged; they build |
in just the same emvironment except for a very few cases where the |
config file name changed in this movement. |
|
Targets in ecos.db have been redefined to bring in all relevant |
hardware packages including net and serial drivers (but the newly |
included packages are only active if their desired parent is |
available.) |
|
The names of CDL options (and their #defines of course) stay the |
same for the serial drivers, for backward compatibility. |
|
* templates/*/current.ect: these have had CYGPKG_IO_SERIAL added |
rather than it being in (almost) all target definitions. |
|
2000-01-03 Gary Thomas <gthomas@cygnus.co.uk> |
|
* src/arm/pid_serial_with_ints.c: Fix namespace pollution - |
serial_devio => cyg_io_serial_devio |
|
1999-12-06 Gary Thomas <gthomas@cygnus.co.uk> |
|
* src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle |
case where an interrupt represents multiple events. |
|
1999-10-26 Jesper Skov <jskov@cygnus.co.uk> |
|
* src/arm/pid_serial.h: Added BE support. |
|
1999-10-25 Gary Thomas <gthomas@cygnus.co.uk> |
|
* src/arm/pid_serial.h (ISR_RxTO): Define - character received but |
not handled "promptly". |
|
* src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv |
interrupts properly (can't ignore them even with TO bit set). |
|
1999-06-20 Gary Thomas <gthomas@cygnus.co.uk> |
|
* src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()' |
prototypes. |
|
1999-05-14 Jesper Skov <jskov@cygnus.co.uk> |
|
* src/arm/pid_serial_with_ints.c: |
* src/arm/pid_serial.h: |
Check for receive interrupt before reading. |
|
1999-04-20 Gary Thomas <gthomas@cygnus.co.uk> |
|
* src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered. |
|
1999-03-25 Gary Thomas <gthomas@cygnus.co.uk> |
|
* src/arm/pid_serial_with_ints.c: |
Update CDL to follow naming conventions. |
|
* src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change |
so that the physical port is not modified unless the provided |
configuration is valid. |
|
* src/arm/pid_serial_with_ints.c: |
Add configury for baud rate and buffer size. |
|
1999-03-24 Gary Thomas <gthomas@cygnus.co.uk> |
|
* src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo |
in comment. |
|
1999-03-22 Gary Thomas <gthomas@cygnus.co.uk> |
|
* src/arm/pid_serial_with_ints.c: Use CDL configured device names. |
|
1999-03-19 Jesper Skov <jskov@lassi.cygnus.co.uk> |
|
* src/arm/pid_serial_with_ints.c: |
Moved include statement to avoid warnings. |
|
1999-03-18 Gary Thomas <gthomas@cygnus.co.uk> |
|
* src/arm/pid_serial_with_ints.c: |
Update device names to match CDL. |
|
1999-03-17 Gary Thomas <gthomas@cygnus.co.uk> |
|
* src/arm/pid_serial_with_ints.c: Conditionalize based on CDL. |
|
1999-03-15 Gary Thomas <gthomas@cygnus.co.uk> |
|
* src/arm/pid_serial_with_ints.c: Add 'CYGDBG_IO_INIT' for control |
of init messages. |
|
* src/arm/pid_serial_with_ints.c: Don't include <cyg/kernel/kapi.h> |
|
1999-03-05 Gary Thomas <gthomas@cygnus.co.uk> |
|
* src/arm/pid_serial_with_ints.c: Fix interrupt vectors. |
|
1999-03-03 Gary Thomas <gthomas@cygnus.co.uk> |
|
* serial/current/src/arm/pid_serial_with_ints.c: |
New [somewhat] configurable drivers for PID. |
|
//=========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//=========================================================================== |