OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/trunk/rtos/rtems/c/src/libchip/serial
    from Rev 30 to Rev 173
    Reverse comparison

Rev 30 → Rev 173

/mc68681_p.h
0,0 → 1,316
/*
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id: mc68681_p.h,v 1.2 2001-09-27 12:01:42 chris Exp $
*/
 
#ifndef _MC68681_P_H_
#define _MC68681_P_H_
 
#ifdef __cplusplus
extern "C" {
#endif
 
/*
* Define MC68681_STATIC to nothing while debugging so the entry points
* will show up in the symbol table.
*/
 
#define MC68681_STATIC
 
/* #define MC68681_STATIC static */
 
/*
* mc68681 register offsets Read/Write Addresses
*/
 
#define MC68681_MODE_REG_1A 0 /* MR1A-MR Prior to Read */
#define MC68681_MODE_REG_2A 0 /* MR2A-MR After Read */
 
#define MC68681_COUNT_MODE_CURRENT_MSB 6 /* CTU */
#define MC68681_COUNTER_TIMER_UPPER_REG 6 /* CTU */
#define MC68681_COUNT_MODE_CURRENT_LSB 7 /* CTL */
#define MC68681_COUNTER_TIMER_LOWER_REG 7 /* CTL */
#define MC68681_INTERRUPT_VECTOR_REG 12 /* IVR */
 
#define MC68681_MODE_REG_1B 8 /* MR1B-MR Prior to Read */
#define MC68681_MODE_REG_2B 8 /* MR2BA-MR After Read */
 
/*
* mc68681 register offsets Read Only Addresses
*/
 
#define MC68681_STATUS_REG_A 1 /* SRA */
#define MC68681_MASK_ISR_REG 2 /* MISR */
#define MC68681_RECEIVE_BUFFER_A 3 /* RHRA */
#define MC68681_INPUT_PORT_CHANGE_REG 4 /* IPCR */
#define MC68681_INTERRUPT_STATUS_REG 5 /* ISR */
#define MC68681_STATUS_REG_B 9 /* SRB */
#define MC68681_RECEIVE_BUFFER_B 11 /* RHRB */
#define MC68681_INPUT_PORT 13 /* IP */
#define MC68681_START_COUNT_CMD 14 /* SCC */
#define MC68681_STOP_COUNT_CMD 15 /* STC */
 
/*
* mc68681 register offsets Write Only Addresses
*/
 
#define MC68681_CLOCK_SELECT_REG_A 1 /* CSRA */
#define MC68681_COMMAND_REG_A 2 /* CRA */
#define MC68681_TRANSMIT_BUFFER_A 3 /* THRA */
#define MC68681_AUX_CTRL_REG 4 /* ACR */
#define MC68681_INTERRUPT_MASK_REG 5 /* IMR */
#define MC68681_CLOCK_SELECT_REG_B 9 /* CSRB */
#define MC68681_COMMAND_REG_B 10 /* CRB */
#define MC68681_TRANSMIT_BUFFER_B 11 /* THRB */
#define MC68681_OUTPUT_PORT_CONFIG_REG 13 /* OPCR */
#define MC68681_OUTPUT_PORT_SET_REG 14 /* SOPBC */
#define MC68681_OUTPUT_PORT_RESET_BITS 15 /* COPBC */
 
/*
* DUART Command Register Definitions:
*
* MC68681_COMMAND_REG_A,MC68681_COMMAND_REG_B
*/
 
#define MC68681_MODE_REG_ENABLE_RX 0x01
#define MC68681_MODE_REG_DISABLE_RX 0x02
#define MC68681_MODE_REG_ENABLE_TX 0x04
#define MC68681_MODE_REG_DISABLE_TX 0x08
#define MC68681_MODE_REG_RESET_MR_PTR 0x10
#define MC68681_MODE_REG_RESET_RX 0x20
#define MC68681_MODE_REG_RESET_TX 0x30
#define MC68681_MODE_REG_RESET_ERROR 0x40
#define MC68681_MODE_REG_RESET_BREAK 0x50
#define MC68681_MODE_REG_START_BREAK 0x60
#define MC68681_MODE_REG_STOP_BREAK 0x70
#define MC68681_MODE_REG_SET_RX_BRG 0x80
#define MC68681_MODE_REG_CLEAR_RX_BRG 0x90
#define MC68681_MODE_REG_SET_TX_BRG 0xa0
#define MC68681_MODE_REG_CLEAR_TX_BRG 0xb0
#define MC68681_MODE_REG_SET_STANDBY 0xc0
#define MC68681_MODE_REG_SET_ACTIVE 0xd0
 
/*
* Mode Register Definitions
*
* MC68681_MODE_REG_1A
* MC68681_MODE_REG_1B
*/
 
#define MC68681_5BIT_CHARS 0x00
#define MC68681_6BIT_CHARS 0x01
#define MC68681_7BIT_CHARS 0x02
#define MC68681_8BIT_CHARS 0x03
 
#define MC68681_ODD_PARITY 0x00
#define MC68681_EVEN_PARITY 0x04
 
#define MC68681_WITH_PARITY 0x00
#define MC68681_FORCE_PARITY 0x08
#define MC68681_NO_PARITY 0x10
#define MC68681_MULTI_DROP 0x18
 
#define MC68681_ERR_MODE_CHAR 0x00
#define MC68681_ERR_MODE_BLOCK 0x20
 
#define MC68681_RX_INTR_RX_READY 0x00
#define MC68681_RX_INTR_FFULL 0x40
 
#define MC68681_NO_RX_RTS_CTL 0x00
#define MC68681_RX_RTS_CTRL 0x80
 
/*
* Mode Register Definitions
*
* MC68681_MODE_REG_2A
* MC68681_MODE_REG_2B
*/
 
#define MC68681_STOP_BIT_LENGTH__563 0x00
#define MC68681_STOP_BIT_LENGTH__625 0x01
#define MC68681_STOP_BIT_LENGTH__688 0x02
#define MC68681_STOP_BIT_LENGTH__75 0x03
#define MC68681_STOP_BIT_LENGTH__813 0x04
#define MC68681_STOP_BIT_LENGTH__875 0x05
#define MC68681_STOP_BIT_LENGTH__938 0x06
#define MC68681_STOP_BIT_LENGTH_1 0x07
#define MC68681_STOP_BIT_LENGTH_1_563 0x08
#define MC68681_STOP_BIT_LENGTH_1_625 0x09
#define MC68681_STOP_BIT_LENGTH_1_688 0x0a
#define MC68681_STOP_BIT_LENGTH_1_75 0x0b
#define MC68681_STOP_BIT_LENGTH_1_813 0x0c
#define MC68681_STOP_BIT_LENGTH_1_875 0x0d
#define MC68681_STOP_BIT_LENGTH_1_938 0x0e
#define MC68681_STOP_BIT_LENGTH_2 0x0f
 
#define MC68681_CTS_ENABLE_TX 0x10
#define MC68681_TX_RTS_CTRL 0x20
 
#define MC68681_CHANNEL_MODE_NORMAL 0x00
#define MC68681_CHANNEL_MODE_ECHO 0x40
#define MC68681_CHANNEL_MODE_LOCAL_LOOP 0x80
#define MC68681_CHANNEL_MODE_REMOTE_LOOP 0xc0
 
/*
* Status Register Definitions
*
* MC68681_STATUS_REG_A, MC68681_STATUS_REG_B
*/
 
#define MC68681_RX_READY 0x01
#define MC68681_FFULL 0x02
#define MC68681_TX_READY 0x04
#define MC68681_TX_EMPTY 0x08
#define MC68681_OVERRUN_ERROR 0x10
#define MC68681_PARITY_ERROR 0x20
#define MC68681_FRAMING_ERROR 0x40
#define MC68681_RECEIVED_BREAK 0x80
 
#define MC68681_RX_ERRORS \
(MC68681_OVERRUN_ERROR|MC68681_PARITY_ERROR| \
MC68681_FRAMING_ERROR|MC68681_RECEIVED_BREAK)
 
/*
* Interupt Status Register Definitions.
*
* MC68681_INTERRUPT_STATUS_REG
*/
 
/*
* Interupt Mask Register Definitions
*
* MC68681_INTERRUPT_MASK_REG
*/
 
/* These are passed to mc68681_build_imr */
#define MC68681_IR_TX_READY 0x01
#define MC68681_IR_RX_READY 0x02
#define MC68681_IR_BREAK 0x04
#define MC68681_IMR_ENABLE_ALL 0x07
#define MC68681_IMR_DISABLE_ALL 0x00
#define MC68681_IMR_ENABLE_ALL_EXCEPT_TX 0x06
 
#define MC68681_IR_TX_READY_A 0x01
#define MC68681_IR_RX_READY_A 0x02
#define MC68681_IR_BREAK_A 0x04
#define MC68681_IR_COUNTER_READY 0x08
#define MC68681_IR_TX_READY_B 0x10
#define MC68681_IR_RX_READY_B 0x20
#define MC68681_IR_BREAK_B 0x40
#define MC68681_IR_INPUT_PORT_CHANGE 0x80
 
/*
* Status Register Definitions.
*
* MC68681_STATUS_REG_A,MC68681_STATUS_REG_B
*/
 
#define MC68681_STATUS_RXRDY 0x01
#define MC68681_STATUS_FFULL 0x02
#define MC68681_STATUS_TXRDY 0x04
#define MC68681_STATUS_TXEMT 0x08
#define MC68681_STATUS_OVERRUN_ERROR 0x10
#define MC68681_STATUS_PARITY_ERROR 0x20
#define MC68681_STATUS_FRAMING_ERROR 0x40
#define MC68681_STATUS_RECEIVED_BREAK 0x80
 
/*
* Definitions for the Interrupt Vector Register:
*
* MC68681_INTERRUPT_VECTOR_REG
*/
 
#define MC68681_INTERRUPT_VECTOR_INIT 0x0f
 
/*
* Definitions for the Auxiliary Control Register
*
* MC68681_AUX_CTRL_REG
*/
 
#define MC68681_AUX_BRG_SET1 0x00
#define MC68681_AUX_BRG_SET2 0x80
 
/*
* Per chip context control
*/
 
typedef struct _mc68681_context
{
int mate;
unsigned char imr;
} mc68681_context;
 
/*
* Driver functions
*/
MC68681_STATIC boolean mc68681_probe(int minor);
 
MC68681_STATIC int mc68681_set_attributes(
int minor,
const struct termios *t
);
 
MC68681_STATIC void mc68681_init(int minor);
 
MC68681_STATIC int mc68681_open(
int major,
int minor,
void * arg
);
 
MC68681_STATIC int mc68681_close(
int major,
int minor,
void * arg
);
 
MC68681_STATIC void mc68681_write_polled(
int minor,
char cChar
);
 
MC68681_STATIC void mc68681_initialize_interrupts(int minor);
 
MC68681_STATIC int mc68681_write_support_int(
int minor,
const char *buf,
int len
);
 
MC68681_STATIC int mc68681_write_support_polled(
int minor,
const char *buf,
int len
);
 
MC68681_STATIC int mc68681_inbyte_nonblocking_polled(
int minor
);
 
MC68681_STATIC unsigned int mc68681_build_imr(
int minor,
int enable_flag
);
 
MC68681_STATIC void mc68681_process(
int minor
);
 
MC68681_STATIC void mc68681_enable_interrupts(
int minor,
int imr_mask
);
 
#ifdef __cplusplus
}
#endif
 
#endif /* _MC68681_P_H_ */
/z85c30.h
0,0 → 1,78
/*
* This include file contains all console driver definitions for the
* Zilog z85c30.
*
* COPYRIGHT (c) 1998 by Radstone Technology
*
*
* THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
* AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
*
* You are hereby granted permission to use, copy, modify, and distribute
* this file, provided that this notice, plus the above copyright notice
* and disclaimer, appears in all copies. Radstone Technology will provide
* no support for this code.
*
* COPYRIGHT (c) 1989-1997.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may in
* the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id:
*/
 
#ifndef __Z85C30_H
#define __Z85C30_H
 
#ifdef __cplusplus
extern "C" {
#endif
 
/*
* Driver function table
*/
 
extern console_fns z85c30_fns;
extern console_fns z85c30_fns_polled;
 
/*
* Flow control function tables
*/
 
extern console_flow z85c30_flow_RTSCTS;
extern console_flow z85c30_flow_DTRCTS;
 
/*
* Default register access routines
*/
 
unsigned8 z85c30_get_register( /* registers are byte-wide */
unsigned32 ulCtrlPort,
unsigned8 ucRegNum
);
 
void z85c30_set_register(
unsigned32 ulCtrlPort,
unsigned8 ucRegNum,
unsigned8 ucData
);
 
unsigned8 z85c30_get_data(
unsigned32 ulDataPort
);
 
void z85c30_set_data(
unsigned32 ulDataPort,
unsigned8 ucData
);
 
#ifdef __cplusplus
}
#endif
 
#endif
/mc68681_reg8.c
0,0 → 1,24
/*
* This file contains a typical set of register access routines which may be
* used with the mc68681 chip if accesses to the chip are as follows:
*
* + registers are accessed as bytes
* + registers are on 64-bit boundaries
*
* COPYRIGHT (c) 1989-1997.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id: mc68681_reg8.c,v 1.2 2001-09-27 12:01:42 chris Exp $
*/
 
#define _MC68681_MULTIPLIER 8
#define _MC68681_NAME(_X) _X##_8
#define _MC68681_TYPE unsigned8
 
#include "mc68681_reg.c"
 
/STATUS
0,0 → 1,52
#
# $Id: STATUS,v 1.2 2001-09-27 12:01:42 chris Exp $
#
 
General
=======
 
+ Hardware flow control is not currently supported. Some of the chip
drivers (in particular the z8530) have support for hardware flow control
but this has not been tested in the libchip context. There will need
to be a way to totally disabled hardware flow control which is not
currently in this.
 
+ "ulClockSpeed" configuration item field to become a pointer to a table
of chip specific information. For example, the z8530 should specify
clock speed and clock divisor setting.
 
+ A termios structure should be included to specify the initial settings.
Right now all drivers default to 9600, 8N1.
+ Need to switch to passing pointers rather than a minor number to
functions which are strictly internal to each chip driver. This
should be a performance win.
 
+ Need a test which prompts you for termios settings and tests them. Until
this happens, testing for the variety of settings possible will be limited.
This test should be able to test any serial port while prompts come to the
console.
 
MC68681
=======
 
+ Works interrupt and polled.
 
+ Hardware flow control not included.
 
NS16650
=======
 
+ ns16550_set-attributes function is untested.
 
+ Hardware flow control included but is currently disabled in ISR.
 
Z85C30
======
 
+ Works polled and interrupt.
 
+ Hardware flow control included but is currently disabled in ISR.
 
+ Needs to support mode where more specific vectors are generated.
 
/ns16550_p.h
0,0 → 1,239
/*
* COPYRIGHT (c) 1998 by Radstone Technology
*
*
* THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
* AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
*
* You are hereby granted permission to use, copy, modify, and distribute
* this file, provided that this notice, plus the above copyright notice
* and disclaimer, appears in all copies. Radstone Technology will provide
* no support for this code.
*
* $Id: ns16550_p.h,v 1.2 2001-09-27 12:01:42 chris Exp $
*/
 
#ifndef _NS16550_P_H_
#define _NS16550_P_H_
 
#ifdef __cplusplus
extern "C" {
#endif
 
/*
* Define NS16550_STATIC to nothing while debugging so the entry points
* will show up in the symbol table.
*/
 
#define NS16550_STATIC
 
/* #define NS16550_STATIC static */
 
/*
* Define serial port read registers structure.
*/
 
typedef volatile struct _SP_READ_REGISTERS {
unsigned char ReceiveBuffer;
unsigned char InterruptEnable;
unsigned char InterruptId;
unsigned char LineControl;
unsigned char ModemControl;
unsigned char LineStatus;
unsigned char ModemStatus;
unsigned char ScratchPad;
} SP_READ_REGISTERS, *PSP_READ_REGISTERS;
 
#define NS16550_RECEIVE_BUFFER 0
#define NS16550_INTERRUPT_ENABLE 1
#define NS16550_INTERRUPT_ID 2
#define NS16550_LINE_CONTROL 3
#define NS16550_MODEM_CONTROL 4
#define NS16550_LINE_STATUS 5
#define NS16550_MODEM_STATUS 6
#define NS16550_SCRATCH_PAD 7
 
/*
* Define serial port write registers structure.
*/
 
typedef volatile struct _SP_WRITE_REGISTERS {
unsigned char TransmitBuffer;
unsigned char InterruptEnable;
unsigned char FifoControl;
unsigned char LineControl;
unsigned char ModemControl;
unsigned char Reserved1;
unsigned char ModemStatus;
unsigned char ScratchPad;
} SP_WRITE_REGISTERS, *PSP_WRITE_REGISTERS;
 
#define NS16550_TRANSMIT_BUFFER 0
#define NS16550_FIFO_CONTROL 2
 
/*
* Define serial port interrupt enable register structure.
*/
 
#define SP_INT_RX_ENABLE 0x01
#define SP_INT_TX_ENABLE 0x02
#define SP_INT_LS_ENABLE 0x04
#define SP_INT_MS_ENABLE 0x08
 
#define NS16550_ENABLE_ALL_INTR (SP_INT_RX_ENABLE | SP_INT_TX_ENABLE)
#define NS16550_DISABLE_ALL_INTR 0x00
#define NS16550_ENABLE_ALL_INTR_EXCEPT_TX (SP_INT_RX_ENABLE)
 
/*
* Define serial port interrupt id register structure.
*/
 
typedef struct _SP_INTERRUPT_ID {
unsigned char InterruptPending : 1;
unsigned char Identification : 3;
unsigned char Reserved1 : 2;
unsigned char FifoEnabled : 2;
} SP_INTERRUPT_ID, *PSP_INTERRUPT_ID;
 
/*
* Define serial port fifo control register structure.
*/
 
#define SP_FIFO_ENABLE 0x01
#define SP_FIFO_RXRST 0x02
#define SP_FIFO_TXRST 0x04
#define SP_FIFO_DMA 0x08
#define SP_FIFO_RXLEVEL 0xc0
 
/*
* Define serial port line control register structure.
*/
 
#define SP_LINE_SIZE 0x03
#define SP_LINE_STOP 0x04
#define SP_LINE_PAR 0x08
#define SP_LINE_ODD 0x10
#define SP_LINE_STICK 0x20
#define SP_LINE_BREAK 0x40
#define SP_LINE_DLAB 0x80
 
/*
* Line status register character size definitions.
*/
 
#define FIVE_BITS 0x0 /* five bits per character */
#define SIX_BITS 0x1 /* six bits per character */
#define SEVEN_BITS 0x2 /* seven bits per character */
#define EIGHT_BITS 0x3 /* eight bits per character */
 
/*
* Line speed divisor definition.
*/
 
#define NS16550_Baud(_clock, _baud_rate) \
((((_clock) == 0) ? 115200 : (_clock))/(_baud_rate))
 
/*
* Define serial port modem control register structure.
*/
 
#define SP_MODEM_DTR 0x01
#define SP_MODEM_RTS 0x02
#define SP_MODEM_IRQ 0x08
#define SP_MODEM_LOOP 0x10
#define SP_MODEM_DIV4 0x80
 
/*
* Define serial port line status register structure.
*/
 
#define SP_LSR_RDY 0x01
#define SP_LSR_EOVRUN 0x02
#define SP_LSR_EPAR 0x04
#define SP_LSR_EFRAME 0x08
#define SP_LSR_BREAK 0x10
#define SP_LSR_THOLD 0x20
#define SP_LSR_TX 0x40
#define SP_LSR_EFIFO 0x80
 
typedef struct _ns16550_context
{
unsigned8 ucModemCtrl;
} ns16550_context;
 
/*
* Driver functions
*/
 
NS16550_STATIC boolean ns16550_probe(int minor);
 
NS16550_STATIC void ns16550_init(int minor);
 
NS16550_STATIC int ns16550_open(
int major,
int minor,
void * arg
);
 
NS16550_STATIC int ns16550_close(
int major,
int minor,
void * arg
);
 
NS16550_STATIC void ns16550_write_polled(
int minor,
char cChar
);
 
NS16550_STATIC int ns16550_assert_RTS(
int minor
);
 
NS16550_STATIC int ns16550_negate_RTS(
int minor
);
 
NS16550_STATIC int ns16550_assert_DTR(
int minor
);
 
NS16550_STATIC int ns16550_negate_DTR(
int minor
);
 
NS16550_STATIC void ns16550_initialize_interrupts(int minor);
 
NS16550_STATIC int ns16550_write_support_int(
int minor,
const char *buf,
int len
);
 
NS16550_STATIC int ns16550_write_support_polled(
int minor,
const char *buf,
int len
);
 
NS16550_STATIC int ns16550_inbyte_nonblocking_polled(
int minor
);
 
NS16550_STATIC void ns16550_enable_interrupts(
int minor,
int mask
);
 
NS16550_STATIC int ns16550_set_attributes(
int minor,
const struct termios *t
);
 
#ifdef __cplusplus
}
#endif
 
#endif /* _NS16550_P_H_ */
/sersupp.h
0,0 → 1,22
/*
* $Id: sersupp.h,v 1.2 2001-09-27 12:01:42 chris Exp $
*/
 
#ifndef __LIBCHIP_SERIAL_SUPPORT_h
#define __LIBCHIP_SERIAL_SUPPORT_h
 
int termios_baud_to_index(
int termios_baud
);
 
int termios_baud_to_number(
int termios_baud
);
 
boolean libchip_serial_default_probe(
int minor
);
 
 
#endif
/* end of include file */
/README.z85c30
0,0 → 1,78
#
# $Id: README.z85c30,v 1.2 2001-09-27 12:01:42 chris Exp $
#
 
Configuration Table Use
=======================
 
sDeviceName
 
The name of this device.
 
deviceType
 
This field must be SERIAL_Z85C30.
 
pDeviceFns
 
The device interface control table. This may be:
+ z85c30_fns for interrupt driven IO
+ z85c30_fns_polled for polled IO
 
deviceProbe
 
This is the address of the routine which probes to see if the device
is present.
 
pDeviceFlow
 
This field is set to one of the following values:
+ NULL for no hardware flow control
+ z85c30_flow_RTSCTS for RTS/CTS based flow control
+ z85c30_flow_DTRCTS for DTR/CTS based flow control
 
ulMargin
 
This is currently unused.
 
ulHysteresis
 
This is currently unused.
 
pDeviceParams
 
This is set to the default settings.
 
ulCtrlPort1
 
This field is the address of the control register for this port.
 
ulCtrlPort2
 
This field is the address of the control register for chip.
 
ulDataPort
 
This field is the address of the data register for this port.
 
getRegister
setRegister
 
These follow standard conventions.
 
getData
setData
 
These follow standard conventions.
 
ulClock
 
This is the clock speed of the baud rate clock.
NULL, then the CSR/ACR/X bit mappings shown in the 68681 and 88681
manuals are used. Otherwise, the board specific baud rate mapping
is used.
 
ulIntVector
 
This is the interrupt vector number associated with this chip.
 
/mc68681_baud.c
0,0 → 1,107
/*
* MC68681 Default Baud Rate Table
*
* $Id: mc68681_baud.c,v 1.2 2001-09-27 12:01:42 chris Exp $
*/
 
#include <rtems.h>
#include <libchip/serial.h>
#include <libchip/mc68681.h>
 
/* major index of 0 : ACR[7] = 0, X = 0 -- 68c681 only has these */
/* major index of 1 : ACR[7] = 1, X = 0 -- 68c681 only has these */
/* major index of 2 : ACR[7] = 0, X = 1 */
/* major index of 3 : ACR[7] = 1, X = 1 */
 
/* mc68681_baud_table_t mc68681_baud_rate_table[4] = { */
mc68681_baud_t mc68681_baud_rate_table[4][RTEMS_TERMIOS_NUMBER_BAUD_RATES] = {
{ /* ACR[7] = 0, X = 0 */
MC68681_BAUD_NOT_VALID, /* B0 */
0x00, /* B50 */
MC68681_BAUD_NOT_VALID, /* B75 */
0x01, /* B110 */
0x02, /* B134 */
MC68681_BAUD_NOT_VALID, /* B150 */
0x03, /* B200 */
0x04, /* B300 */
0x05, /* B600 */
0x06, /* B1200 */
MC68681_BAUD_NOT_VALID, /* B1800 */
0x08, /* B2400 */
0x09, /* B4800 */
0x0B, /* B9600 */
MC68681_BAUD_NOT_VALID, /* B19200 */
0x0C, /* B38400 */
MC68681_BAUD_NOT_VALID, /* B57600 */
MC68681_BAUD_NOT_VALID, /* B115200 */
MC68681_BAUD_NOT_VALID, /* B230400 */
MC68681_BAUD_NOT_VALID /* B460800 */
},
{ /* ACR[7] = 1, X = 0 */
MC68681_BAUD_NOT_VALID, /* B0 */
MC68681_BAUD_NOT_VALID, /* B50 */
0x00, /* B75 */
0x01, /* B110 */
0x02, /* B134 */
0x03, /* B150 */
MC68681_BAUD_NOT_VALID, /* B200 */
0x04, /* B300 */
0x05, /* B600 */
0x06, /* B1200 */
0x0A, /* B1800 */
0x08, /* B2400 */
0x09, /* B4800 */
0x0B, /* B9600 */
0x0C, /* B19200 */
MC68681_BAUD_NOT_VALID, /* B38400 */
MC68681_BAUD_NOT_VALID, /* B57600 */
MC68681_BAUD_NOT_VALID, /* B115200 */
MC68681_BAUD_NOT_VALID, /* B230400 */
MC68681_BAUD_NOT_VALID /* B460800 */
},
{ /* ACR[7] = 0, X = 1 */
MC68681_BAUD_NOT_VALID, /* B0 */
MC68681_BAUD_NOT_VALID, /* B50 */
0x00, /* B75 */
0x01, /* B110 */
0x02, /* B134 */
0x03, /* B150 */
MC68681_BAUD_NOT_VALID, /* B200 */
MC68681_BAUD_NOT_VALID, /* B300 */
MC68681_BAUD_NOT_VALID, /* B600 */
MC68681_BAUD_NOT_VALID, /* B1200 */
0x0A, /* B1800 */
MC68681_BAUD_NOT_VALID, /* B2400 */
0x08, /* B4800 */
0x0B, /* B9600 */
0x0C, /* B19200 */
MC68681_BAUD_NOT_VALID, /* B38400 */
0x07, /* B57600 */
0x08, /* B115200 */
MC68681_BAUD_NOT_VALID, /* B230400 */
MC68681_BAUD_NOT_VALID /* B460800 */
},
{ /* ACR[7] = 1, X = 1 */
MC68681_BAUD_NOT_VALID, /* B0 */
0x00, /* B50 */
MC68681_BAUD_NOT_VALID, /* B75 */
0x01, /* B110 */
0x02, /* B134 */
MC68681_BAUD_NOT_VALID, /* B150 */
0x03, /* B200 */
MC68681_BAUD_NOT_VALID, /* B300 */
MC68681_BAUD_NOT_VALID, /* B600 */
MC68681_BAUD_NOT_VALID, /* B1200 */
MC68681_BAUD_NOT_VALID, /* B1800 */
MC68681_BAUD_NOT_VALID, /* B2400 */
0x09, /* B4800 */
0x0B, /* B9600 */
MC68681_BAUD_NOT_VALID, /* B19200 */
0x0C, /* B38400 */
0x07, /* B57600 */
0x08, /* B115200 */
MC68681_BAUD_NOT_VALID, /* B230400 */
MC68681_BAUD_NOT_VALID /* B460800 */
},
};
 
/mc68681_reg.c
0,0 → 1,61
/*
* This file contains a typical set of register access routines which may be
* used with the mc68681 chip if accesses to the chip are as follows:
*
* + registers are accessed as bytes
* + registers are only byte-aligned (no address gaps)
*
* COPYRIGHT (c) 1989-1997.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id: mc68681_reg.c,v 1.2 2001-09-27 12:01:42 chris Exp $
*/
 
#include <rtems.h>
 
#ifndef _MC68681_MULTIPLIER
#define _MC68681_MULTIPLIER 1
#define _MC68681_NAME(_X) _X
#define _MC68681_TYPE unsigned8
#endif
 
#define CALCULATE_REGISTER_ADDRESS( _base, _reg ) \
(_MC68681_TYPE *)((_base) + ((_reg) * _MC68681_MULTIPLIER ))
 
/*
* MC68681 Get Register Routine
*/
 
unsigned8 _MC68681_NAME(mc68681_get_register)(
unsigned32 ulCtrlPort,
unsigned8 ucRegNum
)
{
_MC68681_TYPE *port;
 
port = CALCULATE_REGISTER_ADDRESS( ulCtrlPort, ucRegNum );
 
return *port;
}
 
/*
* MC68681 Set Register Routine
*/
 
void _MC68681_NAME(mc68681_set_register)(
unsigned32 ulCtrlPort,
unsigned8 ucRegNum,
unsigned8 ucData
)
{
_MC68681_TYPE *port;
 
port = CALCULATE_REGISTER_ADDRESS( ulCtrlPort, ucRegNum );
 
*port = ucData;
}
/README
0,0 → 1,17
#
# $Id: README,v 1.2 2001-09-27 12:01:42 chris Exp $
#
 
This is the serial controller portion of the libchip library. This
directory contains the source code for reusable console driver
support code. Each individual driver is configured using the
console_tbl data structure. This structure is defined and explained
in the console.h file.
 
The reusable chip drivers do not directly access the serial controller.
They access the registers on the controller via a set of up to four
functions which are provided by the BSP. These functins set and get
general registers and data buffers. Some chips can access the data
buffers as general registers and thus the driver may not require
those interface routines.
 
/mc68681.c
0,0 → 1,755
/*
* This file contains the termios TTY driver for the Motorola MC68681.
*
* This part is available from a number of secondary sources.
* In particular, we know about the following:
*
* + Exar 88c681 and 68c681
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id: mc68681.c,v 1.2 2001-09-27 12:01:42 chris Exp $
*/
 
#include <rtems.h>
#include <rtems/libio.h>
#include <stdlib.h>
 
#include <libchip/serial.h>
#include <libchip/mc68681.h>
#include "sersupp.h"
#include "mc68681_p.h"
 
/*
* Flow control is only supported when using interrupts
*/
 
console_fns mc68681_fns =
{
libchip_serial_default_probe, /* deviceProbe */
mc68681_open, /* deviceFirstOpen */
NULL, /* deviceLastClose */
NULL, /* deviceRead */
mc68681_write_support_int, /* deviceWrite */
mc68681_initialize_interrupts, /* deviceInitialize */
mc68681_write_polled, /* deviceWritePolled */
mc68681_set_attributes, /* deviceSetAttributes */
TRUE /* deviceOutputUsesInterrupts */
};
 
console_fns mc68681_fns_polled =
{
libchip_serial_default_probe, /* deviceProbe */
mc68681_open, /* deviceFirstOpen */
mc68681_close, /* deviceLastClose */
mc68681_inbyte_nonblocking_polled, /* deviceRead */
mc68681_write_support_polled, /* deviceWrite */
mc68681_init, /* deviceInitialize */
mc68681_write_polled, /* deviceWritePolled */
mc68681_set_attributes, /* deviceSetAttributes */
FALSE, /* deviceOutputUsesInterrupts */
};
 
extern void set_vector( rtems_isr_entry, rtems_vector_number, int );
 
/*
* Console Device Driver Entry Points
*/
 
/*
* mc68681_baud_rate
*
* This routine returns the proper ACR bit and baud rate field values
* based on the requested baud rate. The baud rate set to be used
* must be configured by the user.
*/
 
MC68681_STATIC int mc68681_baud_rate(
int minor,
int baud,
unsigned int *baud_mask_p,
unsigned int *acr_bit_p,
unsigned int *command
);
 
/*
* mc68681_set_attributes
*
* This function sets the DUART channel to reflect the requested termios
* port settings.
*/
 
MC68681_STATIC int mc68681_set_attributes(
int minor,
const struct termios *t
)
{
unsigned32 pMC68681_port;
unsigned32 pMC68681;
unsigned int mode1;
unsigned int mode2;
unsigned int baud_mask;
unsigned int acr_bit;
unsigned int cmd;
setRegister_f setReg;
rtems_interrupt_level Irql;
 
pMC68681 = Console_Port_Tbl[minor].ulCtrlPort1;
pMC68681_port = Console_Port_Tbl[minor].ulCtrlPort2;
setReg = Console_Port_Tbl[minor].setRegister;
 
/*
* Set the baud rate
*/
 
if (mc68681_baud_rate( minor, t->c_cflag, &baud_mask, &acr_bit, &cmd ) == -1)
return -1;
 
baud_mask |= baud_mask << 4;
acr_bit <<= 7;
 
/*
* Parity
*/
 
mode1 = 0;
mode2 = 0;
 
if (t->c_cflag & PARENB) {
if (t->c_cflag & PARODD)
mode1 |= 0x04;
else
mode1 |= 0x04;
} else {
mode1 |= 0x10;
}
 
/*
* Character Size
*/
 
if (t->c_cflag & CSIZE) {
switch (t->c_cflag & CSIZE) {
case CS5: break;
case CS6: mode1 |= 0x01; break;
case CS7: mode1 |= 0x02; break;
case CS8: mode1 |= 0x03; break;
}
} else {
mode1 |= 0x03; /* default to 9600,8,N,1 */
}
 
/*
* Stop Bits
*/
if (t->c_cflag & CSTOPB) {
mode2 |= 0x07; /* 2 stop bits */
} else {
if ((t->c_cflag & CSIZE) == CS5) /* CS5 and 2 stop bits not supported */
return -1;
mode2 |= 0x0F; /* 1 stop bit */
}
 
rtems_interrupt_disable(Irql);
(*setReg)( pMC68681, MC68681_AUX_CTRL_REG, acr_bit );
(*setReg)( pMC68681_port, MC68681_CLOCK_SELECT, baud_mask );
if ( cmd ) {
(*setReg)( pMC68681_port, MC68681_COMMAND, cmd ); /* RX */
(*setReg)( pMC68681_port, MC68681_COMMAND, cmd | 0x20 ); /* TX */
}
(*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_MR_PTR );
(*setReg)( pMC68681_port, MC68681_MODE, mode1 );
(*setReg)( pMC68681_port, MC68681_MODE, mode2 );
rtems_interrupt_enable(Irql);
return 0;
}
 
/*
* mc68681_initialize_context
*
* This function sets the default values of the per port context structure.
*/
 
MC68681_STATIC void mc68681_initialize_context(
int minor,
mc68681_context *pmc68681Context
)
{
int port;
unsigned int pMC68681;
unsigned int pMC68681_port;
pMC68681 = Console_Port_Tbl[minor].ulCtrlPort1;
pMC68681_port = Console_Port_Tbl[minor].ulCtrlPort2;
 
pmc68681Context->mate = -1;
 
for (port=0 ; port<Console_Port_Count ; port++ ) {
if ( Console_Port_Tbl[port].ulCtrlPort1 == pMC68681 &&
Console_Port_Tbl[port].ulCtrlPort2 != pMC68681_port ) {
pmc68681Context->mate = port;
pmc68681Context->imr = 0;
break;
}
}
 
}
 
/*
* mc68681_init
*
* This function initializes the DUART to a quiecsent state.
*/
 
MC68681_STATIC void mc68681_init(int minor)
{
unsigned32 pMC68681_port;
unsigned32 pMC68681;
mc68681_context *pmc68681Context;
setRegister_f setReg;
getRegister_f getReg;
 
pmc68681Context = (mc68681_context *) malloc(sizeof(mc68681_context));
 
Console_Port_Data[minor].pDeviceContext = (void *)pmc68681Context;
 
mc68681_initialize_context( minor, pmc68681Context );
 
pMC68681 = Console_Port_Tbl[minor].ulCtrlPort1;
pMC68681_port = Console_Port_Tbl[minor].ulCtrlPort2;
setReg = Console_Port_Tbl[minor].setRegister;
getReg = Console_Port_Tbl[minor].getRegister;
 
/*
* Reset everything and leave this port disabled.
*/
 
(*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_RX );
(*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_TX );
(*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_ERROR );
(*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_BREAK );
(*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_STOP_BREAK );
(*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_DISABLE_TX );
(*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_DISABLE_RX );
 
 
(*setReg)( pMC68681_port, MC68681_MODE_REG_1A, 0x00 );
(*setReg)( pMC68681_port, MC68681_MODE_REG_2A, 0x02 );
 
/*
* Disable interrupts on RX and TX for this port
*/
 
mc68681_enable_interrupts( minor, MC68681_IMR_DISABLE_ALL );
}
 
/*
* mc68681_open
*
* This function opens a port for communication.
*
* Default state is 9600 baud, 8 bits, No parity, and 1 stop bit.
*/
 
MC68681_STATIC int mc68681_open(
int major,
int minor,
void *arg
)
{
unsigned32 pMC68681;
unsigned32 pMC68681_port;
unsigned int baud;
unsigned int acr;
unsigned int vector;
unsigned int command;
rtems_interrupt_level Irql;
setRegister_f setReg;
 
pMC68681 = Console_Port_Tbl[minor].ulCtrlPort1;
pMC68681_port = Console_Port_Tbl[minor].ulCtrlPort2;
setReg = Console_Port_Tbl[minor].setRegister;
vector = Console_Port_Tbl[minor].ulIntVector;
 
/* XXX default baud rate should be from configuration table */
 
(void) mc68681_baud_rate( minor, B9600, &baud, &acr, &command );
 
/*
* Set the DUART channel to a default useable state
*/
 
rtems_interrupt_disable(Irql);
(*setReg)( pMC68681, MC68681_AUX_CTRL_REG, acr );
(*setReg)( pMC68681_port, MC68681_CLOCK_SELECT, baud );
if ( command ) {
(*setReg)( pMC68681_port, MC68681_COMMAND, command ); /* RX */
(*setReg)( pMC68681_port, MC68681_COMMAND, command | 0x20 ); /* TX */
}
(*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_MR_PTR );
(*setReg)( pMC68681_port, MC68681_MODE, 0x13 );
(*setReg)( pMC68681_port, MC68681_MODE, 0x07 );
rtems_interrupt_enable(Irql);
 
(*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_ENABLE_TX );
(*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_ENABLE_RX );
 
(*setReg)( pMC68681, MC68681_INTERRUPT_VECTOR_REG, vector );
 
return RTEMS_SUCCESSFUL;
}
 
/*
* mc68681_close
*
* This function shuts down the requested port.
*/
 
MC68681_STATIC int mc68681_close(
int major,
int minor,
void *arg
)
{
unsigned32 pMC68681;
unsigned32 pMC68681_port;
setRegister_f setReg;
 
pMC68681 = Console_Port_Tbl[minor].ulCtrlPort1;
pMC68681_port = Console_Port_Tbl[minor].ulCtrlPort2;
setReg = Console_Port_Tbl[minor].setRegister;
 
/*
* Disable interrupts from this channel and then disable it totally.
*/
 
#if 0
(*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_DISABLE_TX );
(*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_DISABLE_RX );
#endif
 
return(RTEMS_SUCCESSFUL);
}
 
/*
* mc68681_write_polled
*
* This routine polls out the requested character.
*/
 
MC68681_STATIC void mc68681_write_polled(
int minor,
char cChar
)
{
unsigned32 pMC68681_port;
unsigned char ucLineStatus;
int iTimeout;
getRegister_f getReg;
setRegister_f setReg;
 
pMC68681_port = Console_Port_Tbl[minor].ulCtrlPort2;
getReg = Console_Port_Tbl[minor].getRegister;
setReg = Console_Port_Tbl[minor].setRegister;
 
/*
* wait for transmitter holding register to be empty
*/
iTimeout = 1000;
ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
while ((ucLineStatus & (MC68681_TX_READY|MC68681_TX_EMPTY)) == 0) {
 
if ((ucLineStatus & 0xF0))
(*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_ERROR );
 
/*
* Yield while we wait
*/
 
#if 0
if(_System_state_Is_up(_System_state_Get())) {
rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
}
#endif
ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
if(!--iTimeout) {
break;
}
}
 
/*
* transmit character
*/
 
(*setReg)(pMC68681_port, MC68681_TX_BUFFER, cChar);
}
 
/*
* mc68681_isr
*
* This is the single interrupt entry point which parcels interrupts
* out to the various ports.
*/
 
MC68681_STATIC rtems_isr mc68681_isr(
rtems_vector_number vector
)
{
int minor;
 
for(minor=0 ; minor<Console_Port_Count ; minor++) {
if(Console_Port_Tbl[minor].ulIntVector == vector &&
Console_Port_Tbl[minor].deviceType == SERIAL_MC68681 ) {
mc68681_process(minor);
}
}
}
 
/*
* mc68681_initialize_interrupts
*
* This routine initializes the console's receive and transmit
* ring buffers and loads the appropriate vectors to handle the interrupts.
*/
 
MC68681_STATIC void mc68681_initialize_interrupts(int minor)
{
mc68681_init(minor);
 
Console_Port_Data[minor].bActive = FALSE;
 
set_vector(mc68681_isr, Console_Port_Tbl[minor].ulIntVector, 1);
 
mc68681_enable_interrupts(minor,MC68681_IMR_ENABLE_ALL_EXCEPT_TX);
}
 
/*
* mc68681_write_support_int
*
* Console Termios output entry point when using interrupt driven output.
*/
 
MC68681_STATIC int mc68681_write_support_int(
int minor,
const char *buf,
int len
)
{
unsigned32 Irql;
unsigned32 pMC68681_port;
setRegister_f setReg;
 
pMC68681_port = Console_Port_Tbl[minor].ulCtrlPort2;
setReg = Console_Port_Tbl[minor].setRegister;
 
/*
* We are using interrupt driven output and termios only sends us
* one character at a time.
*/
 
if ( !len )
return 0;
 
/*
* Put the character out and enable interrupts if necessary.
*/
 
rtems_interrupt_disable(Irql);
if ( Console_Port_Data[minor].bActive == FALSE ) {
Console_Port_Data[minor].bActive = TRUE;
mc68681_enable_interrupts(minor, MC68681_IMR_ENABLE_ALL);
}
(*setReg)(pMC68681_port, MC68681_TX_BUFFER, *buf);
rtems_interrupt_enable(Irql);
 
return 1;
}
 
/*
* mc68681_write_support_polled
*
* Console Termios output entry point when using polled output.
*
*/
 
MC68681_STATIC int mc68681_write_support_polled(
int minor,
const char *buf,
int len
)
{
int nwrite = 0;
 
/*
* poll each byte in the string out of the port.
*/
while (nwrite < len) {
/*
* transmit character
*/
mc68681_write_polled(minor, *buf++);
nwrite++;
}
 
/*
* return the number of bytes written.
*/
return nwrite;
}
 
/*
* mc68681_inbyte_nonblocking_polled
*
* Console Termios polling input entry point.
*/
 
MC68681_STATIC int mc68681_inbyte_nonblocking_polled(
int minor
)
{
unsigned32 pMC68681_port;
unsigned char ucLineStatus;
unsigned char cChar;
getRegister_f getReg;
 
pMC68681_port = Console_Port_Tbl[minor].ulCtrlPort2;
getReg = Console_Port_Tbl[minor].getRegister;
 
ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
if(ucLineStatus & MC68681_RX_READY) {
cChar = (*getReg)(pMC68681_port, MC68681_RX_BUFFER);
return (int)cChar;
} else {
return -1;
}
}
 
/*
* mc68681_baud_rate
*/
 
MC68681_STATIC int mc68681_baud_rate(
int minor,
int baud,
unsigned int *baud_mask_p,
unsigned int *acr_bit_p,
unsigned int *command
)
{
unsigned int baud_mask;
unsigned int acr_bit;
int status;
int is_extended;
int baud_requested;
mc68681_baud_table_t *baud_tbl;
 
baud_mask = 0;
acr_bit = 0;
status = 0;
 
if ( !(Console_Port_Tbl[minor].ulDataPort & MC68681_DATA_BAUD_RATE_SET_1) )
acr_bit = 1;
 
is_extended = 0;
 
switch (Console_Port_Tbl[minor].ulDataPort & MC68681_XBRG_MASK) {
case MC68681_XBRG_IGNORED:
*command = 0x00;
break;
case MC68681_XBRG_ENABLED:
*command = 0x80;
is_extended = 1;
break;
case MC68681_XBRG_DISABLED:
*command = 0x90;
break;
}
 
baud_requested = baud & CBAUD;
if (!baud_requested)
baud_requested = B9600; /* default to 9600 baud */
baud_requested = termios_baud_to_index( baud_requested );
 
baud_tbl = (mc68681_baud_table_t *) Console_Port_Tbl[minor].ulClock;
if (!baud_tbl)
rtems_fatal_error_occurred(RTEMS_INVALID_ADDRESS);
 
if ( is_extended )
baud_mask = (unsigned int)baud_tbl[ acr_bit + 2 ][ baud_requested ];
else
baud_mask = baud_tbl[ acr_bit ][ baud_requested ];
 
if ( baud_mask == MC68681_BAUD_NOT_VALID )
status = -1;
 
/*
* upper nibble is receiver and lower nibble is transmitter
*/
 
*baud_mask_p = (baud_mask << 4) | baud_mask;
*acr_bit_p = acr_bit;
return status;
}
 
/*
* mc68681_process
*
* This routine is the per port console interrupt handler.
*/
 
MC68681_STATIC void mc68681_process(
int minor
)
{
unsigned32 pMC68681;
unsigned32 pMC68681_port;
volatile unsigned8 ucLineStatus;
unsigned char cChar;
getRegister_f getReg;
setRegister_f setReg;
 
pMC68681 = Console_Port_Tbl[minor].ulCtrlPort1;
pMC68681_port = Console_Port_Tbl[minor].ulCtrlPort2;
getReg = Console_Port_Tbl[minor].getRegister;
setReg = Console_Port_Tbl[minor].setRegister;
 
/*
* Deal with any received characters
*/
while(TRUE) {
ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
if(!(ucLineStatus & MC68681_RX_READY)) {
break;
}
/*
* If there is a RX error, then dump all the data.
*/
if ( ucLineStatus & MC68681_RX_ERRORS ) {
do {
cChar = (*getReg)(pMC68681_port, MC68681_RX_BUFFER);
ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
} while ( ucLineStatus & MC68681_RX_READY );
continue;
}
cChar = (*getReg)(pMC68681_port, MC68681_RX_BUFFER);
rtems_termios_enqueue_raw_characters(
Console_Port_Data[minor].termios_data,
&cChar,
1
);
}
 
/*
* Deal with the transmitter
*/
 
ucLineStatus = (*getReg)(pMC68681, MC68681_INTERRUPT_STATUS_REG);
if (pMC68681 != pMC68681_port)
ucLineStatus >>= 4;
 
if(ucLineStatus & MC68681_IR_TX_READY) {
if (rtems_termios_dequeue_characters(
Console_Port_Data[minor].termios_data, 1)) {
Console_Port_Data[minor].bActive = FALSE;
mc68681_enable_interrupts(minor, MC68681_IMR_ENABLE_ALL_EXCEPT_TX);
}
}
 
}
 
/*
* mc68681_build_imr
*
* This function returns the value for the interrupt mask register for this
* DUART. Since this is a shared register, we must look at the other port
* on this chip to determine whether or not it is using interrupts.
*/
 
MC68681_STATIC unsigned int mc68681_build_imr(
int minor,
int enable_flag
)
{
int mate;
int is_a;
unsigned int mask;
unsigned int mate_mask;
unsigned int pMC68681;
unsigned int pMC68681_port;
mc68681_context *pmc68681Context;
mc68681_context *mateContext;
pMC68681 = Console_Port_Tbl[minor].ulCtrlPort1;
pMC68681_port = Console_Port_Tbl[minor].ulCtrlPort2;
pmc68681Context = (mc68681_context *) Console_Port_Data[minor].pDeviceContext;
mate = pmc68681Context->mate;
 
mask = 0;
mate_mask = 0;
 
is_a = (pMC68681 == pMC68681_port);
/*
* If there is a mate for this port, get its IMR mask.
*/
 
if ( mate != -1 ) {
mateContext = Console_Port_Data[mate].pDeviceContext;
if (mateContext)
mate_mask = mateContext->imr;
}
 
/*
* Calculate this port's IMR mask and save it in the context area.
*/
 
if ( Console_Port_Tbl[minor].pDeviceFns->deviceOutputUsesInterrupts )
mask = enable_flag;
 
pmc68681Context->imr = mask;
 
/*
* Now return the full IMR value
*/
 
if (is_a)
return (mate_mask << 4) | mask;
 
return (mask << 4) | mate_mask;
}
 
/*
* mc68681_enable_interrupts
*
* This function enables specific interrupt sources on the DUART.
*/
 
MC68681_STATIC void mc68681_enable_interrupts(
int minor,
int imr_mask
)
{
unsigned32 pMC68681;
setRegister_f setReg;
 
pMC68681 = Console_Port_Tbl[minor].ulCtrlPort1;
setReg = Console_Port_Tbl[minor].setRegister;
 
/*
* Enable interrupts on RX and TX -- not break
*/
 
(*setReg)(
pMC68681,
MC68681_INTERRUPT_MASK_REG,
mc68681_build_imr(minor, imr_mask)
);
}
/termios_baud2num.c
0,0 → 1,39
/*
* $Id: termios_baud2num.c,v 1.2 2001-09-27 12:01:42 chris Exp $
*/
 
#include <sys/termios.h>
 
int termios_baud_to_number(
int termios_baud
)
{
int baud;
 
switch (termios_baud) {
case B0: baud = 0; break;
case B50: baud = 50; break;
case B75: baud = 75; break;
case B110: baud = 110; break;
case B134: baud = 135; break;
case B150: baud = 150; break;
case B200: baud = 200; break;
case B300: baud = 300; break;
case B600: baud = 600; break;
case B1200: baud = 1200; break;
case B1800: baud = 1800; break;
case B2400: baud = 2400; break;
case B4800: baud = 4800; break;
case B9600: baud = 9600; break;
case B19200: baud = 19200; break;
case B38400: baud = 38400; break;
case B57600: baud = 57600; break;
case B115200: baud = 115200; break;
case B230400: baud = 230400; break;
case B460800: baud = 460800; break;
default: baud = -1; break;
}
 
return baud;
}
 
/z85c30_p.h
0,0 → 1,410
/*
* This include file contains all private driver definitions for the
* Zilog z85c30.
*
* COPYRIGHT (c) 1998 by Radstone Technology
*
*
* THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
* AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
*
* You are hereby granted permission to use, copy, modify, and distribute
* this file, provided that this notice, plus the above copyright notice
* and disclaimer, appears in all copies. Radstone Technology will provide
* no support for this code.
*
* COPYRIGHT (c) 1989-1997.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may in
* the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id: z85c30_p.h,v 1.2 2001-09-27 12:01:42 chris Exp $
*/
 
#ifndef __Z85C30_P_H
#define __Z85C30_P_H
 
#ifdef __cplusplus
extern "C" {
#endif
 
/*
* Define Z85C30_STATIC to nothing while debugging so the entry points
* will show up in the symbol table.
*/
 
#define Z85C30_STATIC
 
/* #define Z85C30_STATIC static */
 
/* bit values for write register 0 */
/* command register */
 
#define SCC_WR0_SEL_WR0 0x00
#define SCC_WR0_SEL_WR1 0x01
#define SCC_WR0_SEL_WR2 0x02
#define SCC_WR0_SEL_WR3 0x03
#define SCC_WR0_SEL_WR4 0x04
#define SCC_WR0_SEL_WR5 0x05
#define SCC_WR0_SEL_WR6 0x06
#define SCC_WR0_SEL_WR7 0x07
#define SCC_WR0_SEL_WR8 0x08
#define SCC_WR0_SEL_WR9 0x09
#define SCC_WR0_SEL_WR10 0x0a
#define SCC_WR0_SEL_WR11 0x0b
#define SCC_WR0_SEL_WR12 0x0c
#define SCC_WR0_SEL_WR13 0x0d
#define SCC_WR0_SEL_WR14 0x0e
#define SCC_WR0_SEL_WR15 0x0f
#define SCC_WR0_SEL_RD0 0x00
#define SCC_WR0_SEL_RD1 0x01
#define SCC_WR0_SEL_RD2 0x02
#define SCC_WR0_SEL_RD3 0x03
#define SCC_WR0_SEL_RD4 0x04
#define SCC_WR0_SEL_RD5 0x05
#define SCC_WR0_SEL_RD6 0x06
#define SCC_WR0_SEL_RD7 0x07
#define SCC_WR0_SEL_RD8 0x08
#define SCC_WR0_SEL_RD9 0x09
#define SCC_WR0_SEL_RD10 0x0a
#define SCC_WR0_SEL_RD11 0x0b
#define SCC_WR0_SEL_RD12 0x0c
#define SCC_WR0_SEL_RD13 0x0d
#define SCC_WR0_SEL_RD14 0x0e
#define SCC_WR0_SEL_RD15 0x0f
#define SCC_WR0_NULL_CODE 0x00
#define SCC_WR0_RST_INT 0x10
#define SCC_WR0_SEND_ABORT 0x18
#define SCC_WR0_EN_INT_RX 0x20
#define SCC_WR0_RST_TX_INT 0x28
#define SCC_WR0_ERR_RST 0x30
#define SCC_WR0_RST_HI_IUS 0x38
#define SCC_WR0_RST_RX_CRC 0x40
#define SCC_WR0_RST_TX_CRC 0x80
#define SCC_WR0_RST_TX_UND 0xc0
 
/* write register 2 */
/* interrupt vector */
 
/* bit values for write register 1 */
/* tx/rx interrupt and data transfer mode definition */
 
#define SCC_WR1_EXT_INT_EN 0x01
#define SCC_WR1_TX_INT_EN 0x02
#define SCC_WR1_PARITY 0x04
#define SCC_WR1_RX_INT_DIS 0x00
#define SCC_WR1_RX_INT_FIR 0x08
#define SCC_WR1_INT_ALL_RX 0x10
#define SCC_WR1_RX_INT_SPE 0x18
#define SCC_WR1_RDMA_RECTR 0x20
#define SCC_WR1_RDMA_FUNC 0x40
#define SCC_WR1_RDMA_EN 0x80
 
#define SCC_ENABLE_ALL_INTR \
(SCC_WR1_EXT_INT_EN | SCC_WR1_TX_INT_EN | SCC_WR1_INT_ALL_RX)
 
#define SCC_DISABLE_ALL_INTR 0x00
 
#define SCC_ENABLE_ALL_INTR_EXCEPT_TX \
(SCC_WR1_EXT_INT_EN | SCC_WR1_INT_ALL_RX)
 
/* bit values for write register 3 */
/* receive parameters and control */
 
#define SCC_WR3_RX_EN 0x01
#define SCC_WR3_SYNC_CHAR 0x02
#define SCC_WR3_ADR_SEARCH 0x04
#define SCC_WR3_RX_CRC_EN 0x08
#define SCC_WR3_ENTER_HUNT 0x10
#define SCC_WR3_AUTO_EN 0x20
#define SCC_WR3_RX_5_BITS 0x00
#define SCC_WR3_RX_7_BITS 0x40
#define SCC_WR3_RX_6_BITS 0x80
#define SCC_WR3_RX_8_BITS 0xc0
 
/* bit values for write register 4 */
/* tx/rx misc parameters and modes */
 
#define SCC_WR4_PAR_EN 0x01
#define SCC_WR4_PAR_EVEN 0x02
#define SCC_WR4_SYNC_EN 0x00
#define SCC_WR4_1_STOP 0x04
#define SCC_WR4_2_STOP 0x0c
#define SCC_WR4_8_SYNC 0x00
#define SCC_WR4_16_SYNC 0x10
#define SCC_WR4_SDLC 0x20
#define SCC_WR4_EXT_SYNC 0x30
#define SCC_WR4_1_CLOCK 0x00
#define SCC_WR4_16_CLOCK 0x40
#define SCC_WR4_32_CLOCK 0x80
#define SCC_WR4_64_CLOCK 0xc0
 
/* bit values for write register 5 */
/* transmit parameter and controls */
 
#define SCC_WR5_TX_CRC_EN 0x01
#define SCC_WR5_RTS 0x02
#define SCC_WR5_SDLC 0x04
#define SCC_WR5_TX_EN 0x08
#define SCC_WR5_SEND_BRK 0x10
 
#define SCC_WR5_TX_5_BITS 0x00
#define SCC_WR5_TX_7_BITS 0x20
#define SCC_WR5_TX_6_BITS 0x40
#define SCC_WR5_TX_8_BITS 0x60
#define SCC_WR5_DTR 0x80
 
/* write register 6 */
/* sync chars or sdlc address field */
 
/* write register 7 */
/* sync char or sdlc flag */
 
/* write register 8 */
/* transmit buffer */
 
/* bit values for write register 9 */
/* master interrupt control */
 
#define SCC_WR9_VIS 0x01
#define SCC_WR9_NV 0x02
#define SCC_WR9_DLC 0x04
#define SCC_WR9_MIE 0x08
#define SCC_WR9_STATUS_HI 0x10
#define SCC_WR9_NO_RST 0x00
#define SCC_WR9_CH_B_RST 0x40
#define SCC_WR9_CH_A_RST 0x80
#define SCC_WR9_HDWR_RST 0xc0
 
/* bit values for write register 10 */
/* misc tx/rx control bits */
 
#define SCC_WR10_6_BIT_SYNC 0x01
#define SCC_WR10_LOOP_MODE 0x02
#define SCC_WR10_ABORT_UND 0x04
#define SCC_WR10_MARK_IDLE 0x08
#define SCC_WR10_ACT_POLL 0x10
#define SCC_WR10_NRZ 0x00
#define SCC_WR10_NRZI 0x20
#define SCC_WR10_FM1 0x40
#define SCC_WR10_FM0 0x60
#define SCC_WR10_CRC_PRESET 0x80
 
/* bit values for write register 11 */
/* clock mode control */
 
#define SCC_WR11_OUT_XTAL 0x00
#define SCC_WR11_OUT_TX_CLK 0x01
#define SCC_WR11_OUT_BR_GEN 0x02
#define SCC_WR11_OUT_DPLL 0x03
#define SCC_WR11_TRXC_OI 0x04
#define SCC_WR11_TX_RTXC 0x00
#define SCC_WR11_TX_TRXC 0x08
#define SCC_WR11_TX_BR_GEN 0x10
#define SCC_WR11_TX_DPLL 0x18
#define SCC_WR11_RX_RTXC 0x00
#define SCC_WR11_RX_TRXC 0x20
#define SCC_WR11_RX_BR_GEN 0x40
#define SCC_WR11_RX_DPLL 0x60
#define SCC_WR11_RTXC_XTAL 0x80
 
/* write register 12 */
/* lower byte of baud rate generator time constant */
 
/* write register 13 */
/* upper byte of baud rate generator time constant */
 
/* bit values for write register 14 */
/* misc control bits */
 
#define SCC_WR14_BR_EN 0x01
#define SCC_WR14_BR_SRC 0x02
#define SCC_WR14_DTR_FUNC 0x04
#define SCC_WR14_AUTO_ECHO 0x08
#define SCC_WR14_LCL_LOOP 0x10
#define SCC_WR14_NULL 0x00
#define SCC_WR14_SEARCH 0x20
#define SCC_WR14_RST_CLK 0x40
#define SCC_WR14_DIS_DPLL 0x60
#define SCC_WR14_SRC_BR 0x80
#define SCC_WR14_SRC_RTXC 0xa0
#define SCC_WR14_FM_MODE 0xc0
#define SCC_WR14_NRZI 0xe0
 
/* bit values for write register 15 */
/* external/status interrupt control */
 
#define SCC_WR15_ZERO_CNT 0x02
#define SCC_WR15_CD_IE 0x08
#define SCC_WR15_SYNC_IE 0x10
#define SCC_WR15_CTS_IE 0x20
#define SCC_WR15_TX_UND_IE 0x40
#define SCC_WR15_BREAK_IE 0x80
 
/* bit values for read register 0 */
/* tx/rx buffer status and external status */
 
#define SCC_RR0_RX_AVAIL 0x01
#define SCC_RR0_ZERO_CNT 0x02
#define SCC_RR0_TX_EMPTY 0x04
#define SCC_RR0_CD 0x08
#define SCC_RR0_SYNC 0x10
#define SCC_RR0_CTS 0x20
#define SCC_RR0_TX_UND 0x40
#define SCC_RR0_BREAK 0x80
 
/* bit values for read register 1 */
 
#define SCC_RR1_ALL_SENT 0x01
#define SCC_RR1_RES_CD_2 0x02
#define SCC_RR1_RES_CD_1 0x01
#define SCC_RR1_RES_CD_0 0x08
#define SCC_RR1_PAR_ERR 0x10
#define SCC_RR1_RX_OV_ERR 0x20
#define SCC_RR1_CRC_ERR 0x40
#define SCC_RR1_END_FRAME 0x80
 
/* read register 2 */
/* interrupt vector */
 
/* bit values for read register 3 */
/* interrupt pending register */
 
#define SCC_RR3_B_EXT_IP 0x01
#define SCC_RR3_B_TX_IP 0x02
#define SCC_RR3_B_RX_IP 0x04
#define SCC_RR3_A_EXT_IP 0x08
#define SCC_RR3_A_TX_IP 0x10
#define SCC_RR3_A_RX_IP 0x20
 
/* read register 8 */
/* receive data register */
 
/* bit values for read register 10 */
/* misc status bits */
 
#define SCC_RR10_ON_LOOP 0x02
#define SCC_RR10_LOOP_SEND 0x10
#define SCC_RR10_2_CLK_MIS 0x40
#define SCC_RR10_1_CLK_MIS 0x80
 
/* read register 12 */
/* lower byte of time constant */
 
/* read register 13 */
/* upper byte of time constant */
 
/* bit values for read register 15 */
/* external/status ie bits */
 
#define SCC_RR15_ZERO_CNT 0x02
#define SCC_RR15_CD_IE 0x08
#define SCC_RR15_SYNC_IE 0x10
#define SCC_RR15_CTS_IE 0x20
#define SCC_RR15_TX_UND_IE 0x40
#define SCC_RR15_BREAK_IE 0x80
 
typedef struct _z85c30_context
{
unsigned8 ucModemCtrl;
} z85c30_context;
 
/*
* The following macro calculates the Baud constant. For the Z85C30 chip.
*
* Note: baud constant = ((clock frequency / Clock_X) / (2 * Baud Rate)) - 2
* eg ((10,000,000 / 16) / (2 * Baud Rate)) - 2
*/
 
#define Z85C30_Baud( _clock, _baud_rate ) \
( ((_clock) /( 16 * 2 * _baud_rate)) - 2)
 
#define Z85C30_Status_Is_RX_character_available(_status) \
((_status) & SCC_RR0_RX_AVAIL)
 
#define Z85C30_Status_Is_TX_buffer_empty(_status) \
((_status) & SCC_RR0_TX_EMPTY)
 
#define Z85C30_Status_Is_CTS_asserted(_status) \
((_status) & SCC_RR0_CTS)
 
#define Z85C30_Status_Is_break_abort(_status) \
((_status) & SCC_RR0_BREAK)
 
/*
* Private routines
*/
 
Z85C30_STATIC void z85c30_init(int minor);
 
Z85C30_STATIC int z85c30_set_attributes(
int minor,
const struct termios *t
);
 
Z85C30_STATIC int z85c30_open(
int major,
int minor,
void * arg
);
 
Z85C30_STATIC int z85c30_close(
int major,
int minor,
void * arg
);
 
Z85C30_STATIC void z85c30_write_polled(
int minor,
char cChar
);
 
Z85C30_STATIC int z85c30_assert_RTS(
int minor
);
 
Z85C30_STATIC int z85c30_negate_RTS(
int minor
);
 
Z85C30_STATIC int z85c30_assert_DTR(
int minor
);
 
Z85C30_STATIC int z85c30_negate_DTR(
int minor
);
 
Z85C30_STATIC void z85c30_initialize_interrupts(int minor);
 
Z85C30_STATIC int z85c30_write_support_int(
int minor,
const char *buf,
int len
);
 
Z85C30_STATIC int z85c30_write_support_polled(
int minor,
const char *buf,
int len
);
 
Z85C30_STATIC int z85c30_inbyte_nonblocking_polled(
int minor
);
 
Z85C30_STATIC void z85c30_enable_interrupts(
int minor,
int interrupt_mask
);
 
#ifdef __cplusplus
}
#endif
 
#endif
/serprobe.c
0,0 → 1,20
/*
* $Id: serprobe.c,v 1.2 2001-09-27 12:01:42 chris Exp $
*/
 
#include <rtems.h>
#include <libchip/serial.h>
#include "sersupp.h"
 
boolean libchip_serial_default_probe(int minor)
{
/*
* If the configuration dependent probe has located the device then
* assume it is there
*/
 
return TRUE;
}
 
 
 
/mc68681.h
0,0 → 1,122
/*
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id: mc68681.h,v 1.2 2001-09-27 12:01:42 chris Exp $
*/
 
#ifndef _MC68681_H_
#define _MC68681_H_
 
#ifdef __cplusplus
extern "C" {
#endif
 
/*
* These are just used in the interface between this driver and
* the read/write register routines when accessing the first
* control port.
*/
 
#define MC68681_STATUS 1
#define MC68681_RX_BUFFER 3
 
#define MC68681_MODE 0
#define MC68681_CLOCK_SELECT 1
#define MC68681_COMMAND 2
#define MC68681_TX_BUFFER 3
 
/*
* Data Port bit map configuration
*
* D0 : Baud Rate Set Selection
* D1 - D2 : Extended Baud Rate Setting
*/
 
#define MC68681_DATA_BAUD_RATE_SET_1 0 /* ACR[7] = 0 */
#define MC68681_DATA_BAUD_RATE_SET_2 1 /* ACR[7] = 1 */
 
#define MC68681_XBRG_IGNORED (0 << 1)
#define MC68681_XBRG_ENABLED (1 << 1)
#define MC68681_XBRG_DISABLED (2 << 1)
#define MC68681_XBRG_MASK (3 << 1)
 
/*
* Custom baud rate table information
*/
 
typedef unsigned char mc68681_baud_t;
typedef mc68681_baud_t mc68681_baud_table_t[RTEMS_TERMIOS_NUMBER_BAUD_RATES];
 
#define MC68681_BAUD_NOT_VALID 0xFF
 
extern mc68681_baud_t
mc68681_baud_rate_table[4][RTEMS_TERMIOS_NUMBER_BAUD_RATES];
 
 
/*
* Driver function table
*/
 
extern console_fns mc68681_fns;
extern console_fns mc68681_fns_polled;
 
/*
* Default register access routines
*/
 
unsigned8 mc68681_get_register( /* registers are at 1 byte boundaries */
unsigned32 ulCtrlPort, /* and accessed as bytes */
unsigned8 ucRegNum
);
 
void mc68681_set_register(
unsigned32 ulCtrlPort,
unsigned8 ucRegNum,
unsigned8 ucData
);
 
unsigned8 mc68681_get_register_2( /* registers are at 2 byte boundaries */
unsigned32 ulCtrlPort, /* and accessed as bytes */
unsigned8 ucRegNum
);
 
void mc68681_set_register_2(
unsigned32 ulCtrlPort,
unsigned8 ucRegNum,
unsigned8 ucData
);
 
unsigned8 mc68681_get_register_4( /* registers are at 4 byte boundaries */
unsigned32 ulCtrlPort, /* and accessed as bytes */
unsigned8 ucRegNum
);
 
void mc68681_set_register_4(
unsigned32 ulCtrlPort,
unsigned8 ucRegNum,
unsigned8 ucData
);
 
unsigned8 mc68681_get_register_8( /* registers are at 8 byte boundaries */
unsigned32 ulCtrlPort, /* and accessed as bytes */
unsigned8 ucRegNum
);
 
void mc68681_set_register_8(
unsigned32 ulCtrlPort,
unsigned8 ucRegNum,
unsigned8 ucData
);
 
 
#ifdef __cplusplus
}
#endif
 
#endif /* _MC68681_H_ */
/ns16550.c
0,0 → 1,667
/*
* This file contains the TTY driver for the National Semiconductor NS16550.
*
* This part is widely cloned and second sourced. It is found in a number
* of "Super IO" controllers.
*
* COPYRIGHT (c) 1998 by Radstone Technology
*
*
* THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
* AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
*
* You are hereby granted permission to use, copy, modify, and distribute
* this file, provided that this notice, plus the above copyright notice
* and disclaimer, appears in all copies. Radstone Technology will provide
* no support for this code.
*
* This driver uses the termios pseudo driver.
*/
 
#include <rtems.h>
#include <rtems/libio.h>
#include <stdlib.h>
#include <ringbuf.h>
 
#include <libchip/serial.h>
#include "ns16550_p.h"
#include "sersupp.h"
 
/*
* Flow control is only supported when using interrupts
*/
 
console_flow ns16550_flow_RTSCTS = {
ns16550_negate_RTS, /* deviceStopRemoteTx */
ns16550_assert_RTS /* deviceStartRemoteTx */
};
 
console_flow ns16550_flow_DTRCTS = {
ns16550_negate_DTR, /* deviceStopRemoteTx */
ns16550_assert_DTR /* deviceStartRemoteTx */
};
 
console_fns ns16550_fns = {
libchip_serial_default_probe, /* deviceProbe */
ns16550_open, /* deviceFirstOpen */
NULL, /* deviceLastClose */
NULL, /* deviceRead */
ns16550_write_support_int, /* deviceWrite */
ns16550_initialize_interrupts, /* deviceInitialize */
ns16550_write_polled, /* deviceWritePolled */
ns16550_set_attributes, /* deviceSetAttributes */
TRUE /* deviceOutputUsesInterrupts */
};
 
console_fns ns16550_fns_polled = {
libchip_serial_default_probe, /* deviceProbe */
ns16550_open, /* deviceFirstOpen */
ns16550_close, /* deviceLastClose */
ns16550_inbyte_nonblocking_polled, /* deviceRead */
ns16550_write_support_polled, /* deviceWrite */
ns16550_init, /* deviceInitialize */
ns16550_write_polled, /* deviceWritePolled */
ns16550_set_attributes, /* deviceSetAttributes */
FALSE /* deviceOutputUsesInterrupts */
};
 
extern void set_vector( rtems_isr_entry, rtems_vector_number, int );
 
/*
* ns16550_init
*/
 
NS16550_STATIC void ns16550_init(int minor)
{
unsigned32 pNS16550;
unsigned8 ucTrash;
unsigned8 ucDataByte;
unsigned32 ulBaudDivisor;
ns16550_context *pns16550Context;
setRegister_f setReg;
getRegister_f getReg;
 
pns16550Context=(ns16550_context *)malloc(sizeof(ns16550_context));
 
Console_Port_Data[minor].pDeviceContext=(void *)pns16550Context;
pns16550Context->ucModemCtrl=SP_MODEM_IRQ;
 
pNS16550 = Console_Port_Tbl[minor].ulCtrlPort1;
setReg = Console_Port_Tbl[minor].setRegister;
getReg = Console_Port_Tbl[minor].getRegister;
 
/* Clear the divisor latch, clear all interrupt enables,
* and reset and
* disable the FIFO's.
*/
 
(*setReg)(pNS16550, NS16550_LINE_CONTROL, 0x0);
ns16550_enable_interrupts(minor, NS16550_DISABLE_ALL_INTR);
 
/* Set the divisor latch and set the baud rate. */
 
ulBaudDivisor = NS16550_Baud(
(unsigned32) Console_Port_Tbl[minor].ulClock,
(unsigned32) Console_Port_Tbl[minor].pDeviceParams
);
ucDataByte = SP_LINE_DLAB;
(*setReg)(pNS16550, NS16550_LINE_CONTROL, ucDataByte);
 
/* XXX */
(*setReg)(pNS16550, NS16550_TRANSMIT_BUFFER, ulBaudDivisor&0xff);
(*setReg)(pNS16550, NS16550_INTERRUPT_ENABLE, (ulBaudDivisor>>8)&0xff);
 
/* Clear the divisor latch and set the character size to eight bits */
/* with one stop bit and no parity checking. */
ucDataByte = EIGHT_BITS;
(*setReg)(pNS16550, NS16550_LINE_CONTROL, ucDataByte);
 
/* Enable and reset transmit and receive FIFOs. TJA */
ucDataByte = SP_FIFO_ENABLE;
(*setReg)(pNS16550, NS16550_FIFO_CONTROL, ucDataByte);
 
ucDataByte = SP_FIFO_ENABLE | SP_FIFO_RXRST | SP_FIFO_TXRST;
(*setReg)(pNS16550, NS16550_FIFO_CONTROL, ucDataByte);
 
ns16550_enable_interrupts(minor, NS16550_DISABLE_ALL_INTR);
 
/* Set data terminal ready. */
/* And open interrupt tristate line */
(*setReg)(pNS16550, NS16550_MODEM_CONTROL,pns16550Context->ucModemCtrl);
 
ucTrash = (*getReg)(pNS16550, NS16550_LINE_STATUS );
ucTrash = (*getReg)(pNS16550, NS16550_RECEIVE_BUFFER );
}
 
/*
* ns16550_open
*/
 
NS16550_STATIC int ns16550_open(
int major,
int minor,
void * arg
)
{
/*
* Assert DTR
*/
 
if(Console_Port_Tbl[minor].pDeviceFlow != &ns16550_flow_DTRCTS) {
ns16550_assert_DTR(minor);
}
 
return(RTEMS_SUCCESSFUL);
}
 
/*
* ns16550_close
*/
 
NS16550_STATIC int ns16550_close(
int major,
int minor,
void * arg
)
{
/*
* Negate DTR
*/
if(Console_Port_Tbl[minor].pDeviceFlow != &ns16550_flow_DTRCTS) {
ns16550_negate_DTR(minor);
}
 
return(RTEMS_SUCCESSFUL);
}
 
/*
* ns16550_write_polled
*/
 
NS16550_STATIC void ns16550_write_polled(
int minor,
char cChar
)
{
unsigned32 pNS16550;
unsigned char ucLineStatus;
int iTimeout;
getRegister_f getReg;
setRegister_f setReg;
 
pNS16550 = Console_Port_Tbl[minor].ulCtrlPort1;
getReg = Console_Port_Tbl[minor].getRegister;
setReg = Console_Port_Tbl[minor].setRegister;
 
/*
* wait for transmitter holding register to be empty
*/
iTimeout=1000;
ucLineStatus = (*getReg)(pNS16550, NS16550_LINE_STATUS);
while ((ucLineStatus & SP_LSR_THOLD) == 0) {
/*
* Yield while we wait
*/
#if 0
if(_System_state_Is_up(_System_state_Get())) {
rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
}
#endif
ucLineStatus = (*getReg)(pNS16550, NS16550_LINE_STATUS);
if(!--iTimeout) {
break;
}
}
 
/*
* transmit character
*/
(*setReg)(pNS16550, NS16550_TRANSMIT_BUFFER, cChar);
}
 
/*
* These routines provide control of the RTS and DTR lines
*/
 
/*
* ns16550_assert_RTS
*/
 
NS16550_STATIC int ns16550_assert_RTS(int minor)
{
unsigned32 pNS16550;
unsigned32 Irql;
ns16550_context *pns16550Context;
setRegister_f setReg;
 
pns16550Context=(ns16550_context *) Console_Port_Data[minor].pDeviceContext;
 
pNS16550 = Console_Port_Tbl[minor].ulCtrlPort1;
setReg = Console_Port_Tbl[minor].setRegister;
 
/*
* Assert RTS
*/
rtems_interrupt_disable(Irql);
pns16550Context->ucModemCtrl|=SP_MODEM_RTS;
(*setReg)(pNS16550, NS16550_MODEM_CONTROL, pns16550Context->ucModemCtrl);
rtems_interrupt_enable(Irql);
return 0;
}
 
/*
* ns16550_negate_RTS
*/
 
NS16550_STATIC int ns16550_negate_RTS(int minor)
{
unsigned32 pNS16550;
unsigned32 Irql;
ns16550_context *pns16550Context;
setRegister_f setReg;
 
pns16550Context=(ns16550_context *) Console_Port_Data[minor].pDeviceContext;
 
pNS16550 = Console_Port_Tbl[minor].ulCtrlPort1;
setReg = Console_Port_Tbl[minor].setRegister;
 
/*
* Negate RTS
*/
rtems_interrupt_disable(Irql);
pns16550Context->ucModemCtrl&=~SP_MODEM_RTS;
(*setReg)(pNS16550, NS16550_MODEM_CONTROL, pns16550Context->ucModemCtrl);
rtems_interrupt_enable(Irql);
return 0;
}
 
/*
* These flow control routines utilise a connection from the local DTR
* line to the remote CTS line
*/
 
/*
* ns16550_assert_DTR
*/
 
NS16550_STATIC int ns16550_assert_DTR(int minor)
{
unsigned32 pNS16550;
unsigned32 Irql;
ns16550_context *pns16550Context;
setRegister_f setReg;
 
pns16550Context=(ns16550_context *) Console_Port_Data[minor].pDeviceContext;
 
pNS16550 = Console_Port_Tbl[minor].ulCtrlPort1;
setReg = Console_Port_Tbl[minor].setRegister;
 
/*
* Assert DTR
*/
rtems_interrupt_disable(Irql);
pns16550Context->ucModemCtrl|=SP_MODEM_DTR;
(*setReg)(pNS16550, NS16550_MODEM_CONTROL, pns16550Context->ucModemCtrl);
rtems_interrupt_enable(Irql);
return 0;
}
 
/*
* ns16550_negate_DTR
*/
 
NS16550_STATIC int ns16550_negate_DTR(int minor)
{
unsigned32 pNS16550;
unsigned32 Irql;
ns16550_context *pns16550Context;
setRegister_f setReg;
 
pns16550Context=(ns16550_context *) Console_Port_Data[minor].pDeviceContext;
 
pNS16550 = Console_Port_Tbl[minor].ulCtrlPort1;
setReg = Console_Port_Tbl[minor].setRegister;
 
/*
* Negate DTR
*/
rtems_interrupt_disable(Irql);
pns16550Context->ucModemCtrl&=~SP_MODEM_DTR;
(*setReg)(pNS16550, NS16550_MODEM_CONTROL,pns16550Context->ucModemCtrl);
rtems_interrupt_enable(Irql);
return 0;
}
 
/*
* ns16550_set_attributes
*
* This function sets the channel to reflect the requested termios
* port settings.
*/
 
NS16550_STATIC int ns16550_set_attributes(
int minor,
const struct termios *t
)
{
unsigned32 pNS16550;
unsigned32 ulBaudDivisor;
unsigned8 ucLineControl;
unsigned32 baud_requested;
setRegister_f setReg;
getRegister_f getReg;
unsigned32 Irql;
 
pNS16550 = Console_Port_Tbl[minor].ulCtrlPort1;
setReg = Console_Port_Tbl[minor].setRegister;
getReg = Console_Port_Tbl[minor].getRegister;
 
/*
* Calculate the baud rate divisor
*/
 
baud_requested = t->c_cflag & CBAUD;
if (!baud_requested)
baud_requested = B9600; /* default to 9600 baud */
 
ulBaudDivisor = NS16550_Baud(
(unsigned32) Console_Port_Tbl[minor].ulClock,
termios_baud_to_number(baud_requested)
);
 
ucLineControl = 0;
 
/*
* Parity
*/
 
if (t->c_cflag & PARENB) {
ucLineControl |= SP_LINE_PAR;
if (!(t->c_cflag & PARODD))
ucLineControl |= SP_LINE_ODD;
}
 
/*
* Character Size
*/
 
if (t->c_cflag & CSIZE) {
switch (t->c_cflag & CSIZE) {
case CS5: ucLineControl |= FIVE_BITS; break;
case CS6: ucLineControl |= SIX_BITS; break;
case CS7: ucLineControl |= SEVEN_BITS; break;
case CS8: ucLineControl |= EIGHT_BITS; break;
}
} else {
ucLineControl |= EIGHT_BITS; /* default to 9600,8,N,1 */
}
 
/*
* Stop Bits
*/
 
if (t->c_cflag & CSTOPB) {
ucLineControl |= SP_LINE_STOP; /* 2 stop bits */
} else {
; /* 1 stop bit */
}
 
/*
* Now actually set the chip
*/
 
rtems_interrupt_disable(Irql);
 
/*
* Set the baud rate
*/
 
(*setReg)(pNS16550, NS16550_LINE_CONTROL, SP_LINE_DLAB);
/* XXX are these registers right? */
(*setReg)(pNS16550, NS16550_TRANSMIT_BUFFER, ulBaudDivisor&0xff);
(*setReg)(pNS16550, NS16550_INTERRUPT_ENABLE, (ulBaudDivisor>>8)&0xff);
 
/*
* Now write the line control
*/
(*setReg)(pNS16550, NS16550_LINE_CONTROL, ucLineControl );
 
rtems_interrupt_enable(Irql);
 
return 0;
}
 
/*
* ns16550_process
*
* This routine is the console interrupt handler for A port.
*/
 
NS16550_STATIC void ns16550_process(
int minor
)
{
unsigned32 pNS16550;
volatile unsigned8 ucLineStatus;
volatile unsigned8 ucInterruptId;
unsigned char cChar;
getRegister_f getReg;
setRegister_f setReg;
 
pNS16550 = Console_Port_Tbl[minor].ulCtrlPort1;
getReg = Console_Port_Tbl[minor].getRegister;
setReg = Console_Port_Tbl[minor].setRegister;
 
do {
/*
* Deal with any received characters
*/
while(TRUE) {
ucLineStatus = (*getReg)(pNS16550, NS16550_LINE_STATUS);
if(~ucLineStatus & SP_LSR_RDY) {
break;
}
cChar = (*getReg)(pNS16550, NS16550_RECEIVE_BUFFER);
rtems_termios_enqueue_raw_characters(
Console_Port_Data[minor].termios_data,
&cChar,
1
);
}
 
/*
* TX all the characters we can
*/
 
while(TRUE) {
ucLineStatus = (*getReg)(pNS16550, NS16550_LINE_STATUS);
if(~ucLineStatus & SP_LSR_THOLD) {
/*
* We'll get another interrupt when
* the transmitter holding reg. becomes
* free again
*/
break;
}
 
#if 0
/* XXX flow control not completely supported in libchip */
 
if(Console_Port_Tbl[minor].pDeviceFlow != &ns16550_flow_RTSCTS) {
ns16550_negate_RTS(minor);
}
#endif
 
rtems_termios_dequeue_characters(Console_Port_Data[minor].termios_data, 1);
if (rtems_termios_dequeue_characters(
Console_Port_Data[minor].termios_data, 1)) {
if (Console_Port_Tbl[minor].pDeviceFlow != &ns16550_flow_RTSCTS) {
ns16550_negate_RTS(minor);
}
Console_Port_Data[minor].bActive = FALSE;
ns16550_enable_interrupts(minor, NS16550_ENABLE_ALL_INTR_EXCEPT_TX);
break;
}
 
ucInterruptId = (*getReg)(pNS16550, NS16550_INTERRUPT_ID);
}
} while((ucInterruptId&0xf)!=0x1);
}
 
/*
* ns16550_isr
*/
 
NS16550_STATIC rtems_isr ns16550_isr(
rtems_vector_number vector
)
{
int minor;
 
for(minor=0;minor<Console_Port_Count;minor++) {
if(Console_Port_Tbl[minor].ulIntVector == vector &&
Console_Port_Tbl[minor].deviceType == SERIAL_NS16550 ) {
ns16550_process(minor);
}
}
}
 
/*
* ns16550_enable_interrupts
*
* This routine initializes the port to have the specified interrupts masked.
*/
 
NS16550_STATIC void ns16550_enable_interrupts(
int minor,
int mask
)
{
unsigned32 pNS16550;
setRegister_f setReg;
 
pNS16550 = Console_Port_Tbl[minor].ulCtrlPort1;
setReg = Console_Port_Tbl[minor].setRegister;
 
(*setReg)(pNS16550, NS16550_INTERRUPT_ENABLE, mask);
}
 
/*
* ns16550_initialize_interrupts
*
* This routine initializes the port to operate in interrupt driver mode.
*/
 
NS16550_STATIC void ns16550_initialize_interrupts(int minor)
{
ns16550_init(minor);
 
Console_Port_Data[minor].bActive = FALSE;
 
set_vector(ns16550_isr, Console_Port_Tbl[minor].ulIntVector, 1);
 
ns16550_enable_interrupts(minor, NS16550_ENABLE_ALL_INTR);
}
 
/*
* ns16550_write_support_int
*
* Console Termios output entry point.
*/
 
NS16550_STATIC int ns16550_write_support_int(
int minor,
const char *buf,
int len
)
{
unsigned32 Irql;
unsigned32 pNS16550;
setRegister_f setReg;
 
setReg = Console_Port_Tbl[minor].setRegister;
pNS16550 = Console_Port_Tbl[minor].ulCtrlPort1;
 
/*
* We are using interrupt driven output and termios only sends us
* one character at a time.
*/
 
if ( !len )
return 0;
 
if(Console_Port_Tbl[minor].pDeviceFlow != &ns16550_flow_RTSCTS) {
ns16550_assert_RTS(minor);
}
 
rtems_interrupt_disable(Irql);
if ( Console_Port_Data[minor].bActive == FALSE) {
Console_Port_Data[minor].bActive = TRUE;
ns16550_enable_interrupts(minor, NS16550_ENABLE_ALL_INTR);
}
(*setReg)(pNS16550, NS16550_TRANSMIT_BUFFER, *buf);
rtems_interrupt_enable(Irql);
 
return 1;
}
 
/*
* ns16550_write_support_polled
*
* Console Termios output entry point.
*
*/
 
NS16550_STATIC int ns16550_write_support_polled(
int minor,
const char *buf,
int len
)
{
int nwrite = 0;
 
/*
* poll each byte in the string out of the port.
*/
while (nwrite < len) {
/*
* transmit character
*/
ns16550_write_polled(minor, *buf++);
nwrite++;
}
 
/*
* return the number of bytes written.
*/
return nwrite;
}
 
/*
* ns16550_inbyte_nonblocking_polled
*
* Console Termios polling input entry point.
*/
 
NS16550_STATIC int ns16550_inbyte_nonblocking_polled(
int minor
)
{
unsigned32 pNS16550;
unsigned char ucLineStatus;
char cChar;
getRegister_f getReg;
 
pNS16550 = Console_Port_Tbl[minor].ulCtrlPort1;
getReg = Console_Port_Tbl[minor].getRegister;
 
ucLineStatus = (*getReg)(pNS16550, NS16550_LINE_STATUS);
if(ucLineStatus & SP_LSR_RDY) {
cChar = (*getReg)(pNS16550, NS16550_RECEIVE_BUFFER);
return (int)cChar;
} else {
return -1;
}
}
/README.xr88681
0,0 → 1,6
#
# $Id: README.xr88681,v 1.2 2001-09-27 12:01:42 chris Exp $
#
 
The Exar XR88681 is an enhanced version of the Motorola MC68681 and is
supported by the mc68681 driver.
/serial.h
0,0 → 1,151
/*
* This file contains the TTY driver table definition
*
* This driver uses the termios pseudo driver.
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id: serial.h,v 1.2 2001-09-27 12:01:42 chris Exp $
*/
 
#ifndef __LIBCHIP_SERIAL_h
#define __LIBCHIP_SERIAL_h
 
#include <termios.h>
 
/*
* Types for get and set register routines
*/
 
typedef unsigned8 (*getRegister_f)(unsigned32 port, unsigned8 register);
typedef void (*setRegister_f)(
unsigned32 port, unsigned8 reg, unsigned8 value);
typedef unsigned8 (*getData_f)(unsigned32 port);
typedef void (*setData_f)(unsigned32 port, unsigned8 value);
 
typedef struct _console_fns {
boolean (*deviceProbe)(int minor);
int (*deviceFirstOpen)(int major, int minor, void *arg);
int (*deviceLastClose)(int major, int minor, void *arg);
int (*deviceRead)(int minor);
int (*deviceWrite)(int minor, const char *buf, int len);
void (*deviceInitialize)(int minor);
void (*deviceWritePolled)(int minor, char cChar);
int (*deviceSetAttributes)(int minor, const struct termios *t);
int deviceOutputUsesInterrupts;
} console_fns;
 
typedef struct _console_flow {
int (*deviceStopRemoteTx)(int minor);
int (*deviceStartRemoteTx)(int minor);
} console_flow;
 
typedef enum {
SERIAL_MC68681, /* Motorola MC68681 or Exar 88681 */
SERIAL_NS16550, /* National Semiconductor NS16550 */
SERIAL_Z85C30, /* Zilog Z85C30 */
SERIAL_CUSTOM /* BSP specific driver */
} console_devs;
 
/*
* Each field is interpreted thus:
*
* sDeviceName This is the name of the device.
*
* deviceType This indicates the chip type. It is especially important when
* multiple devices share the same interrupt vector and must be
* distinguished.
*
* pDeviceFns This is a pointer to the set of driver routines to use.
*
* pDeviceFlow This is a pointer to the set of flow control routines to
* use. Serial device drivers will typically supply RTSCTS
* and DTRCTS handshake routines for DCE to DCE communication,
* however for DCE to DTE communication, no such routines
* should be necessary as RTS will be driven automatically
* when the transmitter is active.
*
* ulMargin The high water mark in the input buffer is set to the buffer
* size less ulMargin. Once this level is reached, the driver's
* flow control routine used to stop the remote transmitter will
* be called. This figure should be greater than or equal to
* the number of stages of FIFO between the transmitter and
* receiver.
*
* NOTE: At the current time, this parameter is hard coded
* in termios and this number is ignored.
*
* ulHysteresis After the high water mark specified by ulMargin has been
* reached, the driver's routine to re-start the remote
* transmitter will be called once the level in the input
* buffer has fallen by ulHysteresis bytes.
*
* NOTE: At the current time, this parameter is hard coded
* in termios and this number is ignored.
*
* pDeviceParams This contains either device specific data or a pointer to a
* device specific structure containing additional information
* not provided in this table.
*
* ulCtrlPort1 This is the primary control port number for the device. This
* may be used to specify different instances of the same device
* type.
*
* ulCtrlPort2 This is the secondary control port number, of use when a given
* device has more than one available channel.
*
* ulDataPort This is the port number for the data port of the device
*
* getRegister This is the routine used to read register values.
*
* setRegister This is the routine used to write register values.
*
* getData This is the routine used to read the data register (RX).
*
* setData This is the routine used to write the data register (TX).
*
* ulClock This is the baud rate clock speed.
*
* ulIntVector This encodes the interrupt vector of the device.
*/
 
typedef struct _console_tbl {
char *sDeviceName;
console_devs deviceType;
console_fns *pDeviceFns;
boolean (*deviceProbe)(int minor);
console_flow *pDeviceFlow;
unsigned32 ulMargin;
unsigned32 ulHysteresis;
void *pDeviceParams;
unsigned32 ulCtrlPort1;
unsigned32 ulCtrlPort2;
unsigned32 ulDataPort;
getRegister_f getRegister;
setRegister_f setRegister;
getData_f getData;
setData_f setData;
unsigned32 ulClock;
unsigned int ulIntVector;
} console_tbl;
 
typedef struct _console_data {
void *termios_data;
volatile boolean bActive;
/*
* This field may be used for any purpose required by the driver
*/
void *pDeviceContext;
} console_data;
 
extern console_tbl Console_Port_Tbl[];
extern console_data Console_Port_Data[];
extern unsigned long Console_Port_Count;
 
#endif
/* end of include file */
/ns16550.h
0,0 → 1,42
/*
* COPYRIGHT (c) 1998 by Radstone Technology
*
*
* THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
* AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
*
* You are hereby granted permission to use, copy, modify, and distribute
* this file, provided that this notice, plus the above copyright notice
* and disclaimer, appears in all copies. Radstone Technology will provide
* no support for this code.
*
*/
 
#ifndef _NS16550_H_
#define _NS16550_H_
 
#ifdef __cplusplus
extern "C" {
#endif
 
/*
* Driver function table
*/
 
extern console_fns ns16550_fns;
extern console_fns ns16550_fns_polled;
 
/*
* Flow control function tables
*/
 
extern console_flow ns16550_flow_RTSCTS;
extern console_flow ns16550_flow_DTRCTS;
 
#ifdef __cplusplus
}
#endif
 
#endif /* _NS16550_H_ */
/README.mc68681
0,0 → 1,87
#
# $Id: README.mc68681,v 1.2 2001-09-27 12:01:42 chris Exp $
#
 
Configuration Table Use
=======================
 
sDeviceName
 
The name of this device.
 
deviceType
 
This field must be SERIAL_MC68681.
 
pDeviceFns
 
The device interface control table. This may be:
+ mc68681_fns for interrupt driven IO
+ mc68681_fns_polled for polled IO
 
deviceProbe
 
This is the address of the routine which probes to see if the device
is present.
 
pDeviceFlow
 
This field is ignored as hardware flow control is not currently supported.
 
ulMargin
 
This is currently unused.
 
ulHysteresis
 
This is currently unused.
 
pDeviceParams
 
This is set to the default settings.
 
ulCtrlPort1
 
This field is the base address of the entire DUART.
 
ulCtrlPort2
 
This field is the base address of the port specific registers.
 
ulDataPort
 
This field is bit mapped as follows:
bit 0: baud rate set a or b
bit 1-2: BRG selection ("Select Extend bit")
 
Note: If both ports on single DUART are not configured for the same
baud rate set, then unexpected results will occur.
 
Note: On the Exar 88c681, if a standard clock of 3.6864 Mhz is used
and the "Select Extend bit" is 0 (disabled), then the default
MC68681 baud rate table is selected.
 
getRegister
setRegister
 
These follow standard conventions.
 
getData
setData
 
These are unused since the TX and RX data registers can be accessed
as regular registers.
 
ulClock
 
This is a pointer to a baud rate mapping table. If set to
mc68681_baud_rate_table, then the CSR/ACR/X bit mappings shown
in the 68681 and 88681 manuals are used. Otherwise, the board
specific baud rate mapping is used.
 
NULL is not a valid value.
 
ulIntVector
 
This is the interrupt vector number associated with this chip.
 
/termios_baud2index.c
0,0 → 1,39
/*
* $Id: termios_baud2index.c,v 1.2 2001-09-27 12:01:42 chris Exp $
*/
 
#include <sys/termios.h>
 
int termios_baud_to_index(
int termios_baud
)
{
int baud_index;
 
switch (termios_baud) {
case B0: baud_index = 0; break;
case B50: baud_index = 1; break;
case B75: baud_index = 2; break;
case B110: baud_index = 3; break;
case B134: baud_index = 4; break;
case B150: baud_index = 5; break;
case B200: baud_index = 6; break;
case B300: baud_index = 7; break;
case B600: baud_index = 8; break;
case B1200: baud_index = 9; break;
case B1800: baud_index = 10; break;
case B2400: baud_index = 11; break;
case B4800: baud_index = 12; break;
case B9600: baud_index = 13; break;
case B19200: baud_index = 14; break;
case B38400: baud_index = 15; break;
case B57600: baud_index = 16; break;
case B115200: baud_index = 17; break;
case B230400: baud_index = 18; break;
case B460800: baud_index = 19; break;
default: baud_index = -1; break;
}
 
return baud_index;
}
 
/Makefile.am
0,0 → 1,53
#
# $Id: Makefile.am,v 1.2 2001-09-27 12:01:42 chris Exp $
#
 
AUTOMAKE_OPTIONS = foreign 1.4
 
LIBNAME = libserialio
LIB = ${ARCH}/${LIBNAME}.a
 
C_FILES = mc68681.c mc68681_baud.c mc68681_reg.c mc68681_reg2.c \
mc68681_reg4.c mc68681_reg8.c ns16550.c z85c30.c z85c30_reg.c serprobe.c \
termios_baud2index.c termios_baud2num.c
C_O_FILES = $(C_FILES:%.c=${ARCH}/%.o)
 
H_FILES = mc68681_p.h ns16550_p.h sersupp.h z85c30_p.h
INSTALLED_H_FILES = mc68681.h ns16550.h z85c30.h serial.h
noinst_HEADERS = $(H_FILES) $(INSTALLED_H_FILES)
 
OBJS = $(C_O_FILES)
 
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../automake/lib.am
 
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libchip \
$(INSTALLED_H_FILES:%=$(PROJECT_INCLUDE)/libchip/%)
 
TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/$(LIBNAME)$(LIB_VARIANT).a
 
$(PROJECT_INCLUDE)/libchip:
@$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/libchip/%.h: %.h
$(INSTALL_DATA) $< $@
 
#
# Add local stuff here using +=
#
 
AM_CFLAGS += $(LIBC_DEFINES)
 
$(LIB): ${OBJS}
$(make-library)
 
$(PROJECT_RELEASE)/lib/$(LIBNAME)$(LIB_VARIANT).a: $(LIB)
$(INSTALL_DATA) $< $@
 
all-local: ${ARCH} $(PREINSTALL_FILES) $(TMPINSTALL_FILES)
 
DOC_FILES = README.mc68681 README.ns16550 README.xr88681 README.z85c30 \
STATUS
 
EXTRA_DIST = $(C_FILES) $(DOC_FILES)
 
include $(top_srcdir)/../../../automake/local.am
/z85c30_reg.c
0,0 → 1,73
/*
* This file contains a typical set of register access routines which may be
* used with the z85c30 chip if accesses to the chip are as follows:
*
* + registers are accessed as bytes
*
* COPYRIGHT (c) 1989-1997.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id: z85c30_reg.c,v 1.2 2001-09-27 12:01:42 chris Exp $
*/
 
#include <rtems.h>
 
#ifndef _Z85C30_MULTIPLIER
#define _Z85C30_MULTIPLIER 1
#define _Z85C30_NAME(_X) _X
#define _Z85C30_TYPE unsigned8
#endif
 
/*
* Z85C30 Get Register Routine
*/
 
unsigned8 _Z85C30_NAME(z85c30_get_register)(
unsigned32 ulCtrlPort,
unsigned8 ucRegNum
)
{
_Z85C30_TYPE *port;
unsigned8 data;
rtems_interrupt_level level;
 
port = (_Z85C30_TYPE *)ulCtrlPort;
 
rtems_interrupt_disable(level);
 
if(ucRegNum) {
*port = ucRegNum;
}
data = *port;
rtems_interrupt_enable(level);
 
return data;
}
 
/*
* Z85C30 Set Register Routine
*/
 
void _Z85C30_NAME(z85c30_set_register)(
unsigned32 ulCtrlPort,
unsigned8 ucRegNum,
unsigned8 ucData
)
{
_Z85C30_TYPE *port;
rtems_interrupt_level level;
 
port = (_Z85C30_TYPE *)ulCtrlPort;
 
rtems_interrupt_disable(level);
if(ucRegNum) {
*port = ucRegNum;
}
*port = ucData;
rtems_interrupt_enable(level);
}
/mc68681_reg2.c
0,0 → 1,24
/*
* This file contains a typical set of register access routines which may be
* used with the mc68681 chip if accesses to the chip are as follows:
*
* + registers are accessed as bytes
* + registers are on 16-bit boundaries
*
* COPYRIGHT (c) 1989-1997.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id: mc68681_reg2.c,v 1.2 2001-09-27 12:01:42 chris Exp $
*/
 
#define _MC68681_MULTIPLIER 2
#define _MC68681_NAME(_X) _X##_2
#define _MC68681_TYPE unsigned8
 
#include "mc68681_reg.c"
 
/README.ns16550
0,0 → 1,95
#
# $Id: README.ns16550,v 1.2 2001-09-27 12:01:42 chris Exp $
#
 
Status
======
 
This driver appears to work OK for polled output at this point.
 
It needs to be tested for:
 
+ polled input
+ interrupt driver output
+ interrupt driver input
 
This driver does not support the new style RTEMS interrupt processing
used on the i386 and some PowerPC models.
 
Configuration Table Use
=======================
 
sDeviceName
 
The name of this device.
 
deviceType
 
This field must be SERIAL_NS16550.
 
pDeviceFns
 
The device interface control table. This may be:
+ ns16550_fns for interrupt driven IO
+ ns16550_fns_polled for polled IO
 
deviceProbe
 
This is the address of the routine which probes to see if the device
is present.
 
pDeviceFlow
 
This field is ignored as hardware flow control is not currently supported.
 
ulMargin
 
This is currently unused.
 
ulHysteresis
 
This is currently unused.
 
pDeviceParams
 
This is set to the default settings. At this point, it is the default
baud rate cast as a (void *).
 
ulCtrlPort1
 
This field is the base address of this port on the UART.
 
ulCtrlPort2
 
This field is unused for the NS16550.
 
ulDataPort
 
This field is the base address of this port on the UART.
 
getRegister
setRegister
 
These follow standard conventions.
 
getData
setData
 
These are unused since the TX and RX data registers can be accessed
as regular registers.
 
ulClock
 
This is the clock constant which is divided by the desired baud
to get the value programmed into the part. The formula for this
for 9600 baud is:
 
chip_divisor_value = ulClock / 9600.
 
NOTE: When ulClock is 0, the correct value for a PC (115,200) is
used.
 
ulIntVector
 
This is the interrupt vector number associated with this chip.
 
/z85c30.c
0,0 → 1,889
/*
* This file contains the console driver chip level routines for the
* Zilog z85c30 chip.
*
* The Zilog Z8530 is also available as:
*
* + Intel 82530
* + AMD ???
*
* COPYRIGHT (c) 1998 by Radstone Technology
*
*
* THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
* AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
*
* You are hereby granted permission to use, copy, modify, and distribute
* this file, provided that this notice, plus the above copyright notice
* and disclaimer, appears in all copies. Radstone Technology will provide
* no support for this code.
*
* COPYRIGHT (c) 1989-1997.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id: z85c30.c,v 1.2 2001-09-27 12:01:42 chris Exp $
*/
 
#include <rtems.h>
#include <rtems/libio.h>
#include <stdlib.h>
 
#include <libchip/serial.h>
#include "z85c30_p.h"
#include "sersupp.h"
 
/*
* Flow control is only supported when using interrupts
*/
 
console_flow z85c30_flow_RTSCTS = {
z85c30_negate_RTS, /* deviceStopRemoteTx */
z85c30_assert_RTS /* deviceStartRemoteTx */
};
 
console_flow z85c30_flow_DTRCTS = {
z85c30_negate_DTR, /* deviceStopRemoteTx */
z85c30_assert_DTR /* deviceStartRemoteTx */
};
 
/*
* Exported driver function table
*/
 
console_fns z85c30_fns = {
libchip_serial_default_probe, /* deviceProbe */
z85c30_open, /* deviceFirstOpen */
NULL, /* deviceLastClose */
NULL, /* deviceRead */
z85c30_write_support_int, /* deviceWrite */
z85c30_initialize_interrupts, /* deviceInitialize */
z85c30_write_polled, /* deviceWritePolled */
NULL, /* deviceSetAttributes */
TRUE /* deviceOutputUsesInterrupts */
};
 
console_fns z85c30_fns_polled = {
libchip_serial_default_probe, /* deviceProbe */
z85c30_open, /* deviceFirstOpen */
z85c30_close, /* deviceLastClose */
z85c30_inbyte_nonblocking_polled, /* deviceRead */
z85c30_write_support_polled, /* deviceWrite */
z85c30_init, /* deviceInitialize */
z85c30_write_polled, /* deviceWritePolled */
NULL, /* deviceSetAttributes */
FALSE /* deviceOutputUsesInterrupts */
};
 
extern void set_vector( rtems_isr_entry, rtems_vector_number, int );
 
/*
* z85c30_initialize_port
*
* initialize a z85c30 Port
*/
 
Z85C30_STATIC void z85c30_initialize_port(
int minor
)
{
unsigned32 ulCtrlPort;
unsigned32 ulBaudDivisor;
setRegister_f setReg;
 
ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort1;
setReg = Console_Port_Tbl[minor].setRegister;
 
/*
* Using register 4
* Set up the clock rate is 16 times the data
* rate, 8 bit sync char, 1 stop bit, no parity
*/
 
(*setReg)( ulCtrlPort, SCC_WR0_SEL_WR4, SCC_WR4_1_STOP | SCC_WR4_16_CLOCK );
 
/*
* Set up for 8 bits/character on receive with
* receiver disable via register 3
*/
(*setReg)( ulCtrlPort, SCC_WR0_SEL_WR3, SCC_WR3_RX_8_BITS );
 
/*
* Set up for 8 bits/character on transmit
* with transmitter disable via register 5
*/
(*setReg)( ulCtrlPort, SCC_WR0_SEL_WR5, SCC_WR5_TX_8_BITS );
 
/*
* Clear misc control bits
*/
(*setReg)( ulCtrlPort, SCC_WR0_SEL_WR10, 0x00 );
 
/*
* Setup the source of the receive and xmit
* clock as BRG output and the transmit clock
* as the output source for TRxC pin via register 11
*/
(*setReg)(
ulCtrlPort,
SCC_WR0_SEL_WR11,
SCC_WR11_OUT_BR_GEN | SCC_WR11_TRXC_OI |
SCC_WR11_TX_BR_GEN | SCC_WR11_RX_BR_GEN
);
 
ulBaudDivisor = Z85C30_Baud(
(unsigned32) Console_Port_Tbl[minor].ulClock,
(unsigned32) Console_Port_Tbl[minor].pDeviceParams
);
 
/*
* Setup the lower 8 bits time constants=1E.
* If the time constans=1E, then the desire
* baud rate will be equilvalent to 9600, via register 12.
*/
(*setReg)( ulCtrlPort, SCC_WR0_SEL_WR12, ulBaudDivisor & 0xff );
 
/*
* using register 13
* Setup the upper 8 bits time constant
*/
(*setReg)( ulCtrlPort, SCC_WR0_SEL_WR13, (ulBaudDivisor>>8) & 0xff );
/*
* Enable the baud rate generator enable with clock from the
* SCC's PCLK input via register 14.
*/
(*setReg)(
ulCtrlPort,
SCC_WR0_SEL_WR14,
SCC_WR14_BR_EN | SCC_WR14_BR_SRC | SCC_WR14_NULL
);
 
/*
* We are only interested in CTS state changes
*/
(*setReg)( ulCtrlPort, SCC_WR0_SEL_WR15, SCC_WR15_CTS_IE );
 
/*
* Reset errors
*/
(*setReg)( ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_INT );
 
(*setReg)( ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_ERR_RST );
 
/*
* Enable the receiver via register 3
*/
(*setReg)( ulCtrlPort, SCC_WR0_SEL_WR3, SCC_WR3_RX_8_BITS | SCC_WR3_RX_EN );
 
/*
* Enable the transmitter pins set via register 5.
*/
(*setReg)( ulCtrlPort, SCC_WR0_SEL_WR5, SCC_WR5_TX_8_BITS | SCC_WR5_TX_EN );
 
/*
* Disable interrupts
*/
(*setReg)( ulCtrlPort, SCC_WR0_SEL_WR1, 0 );
 
/*
* Reset TX CRC
*/
(*setReg)( ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_TX_CRC );
 
/*
* Reset interrupts
*/
(*setReg)( ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_INT );
}
 
/*
* z85c30_open
*/
 
Z85C30_STATIC int z85c30_open(
int major,
int minor,
void *arg
)
{
 
z85c30_initialize_port(minor);
 
/*
* Assert DTR
*/
 
if (Console_Port_Tbl[minor].pDeviceFlow !=&z85c30_flow_DTRCTS) {
z85c30_assert_DTR(minor);
}
 
return(RTEMS_SUCCESSFUL);
}
 
/*
* z85c30_close
*/
 
Z85C30_STATIC int z85c30_close(
int major,
int minor,
void *arg
)
{
/*
* Negate DTR
*/
 
if (Console_Port_Tbl[minor].pDeviceFlow !=&z85c30_flow_DTRCTS) {
z85c30_negate_DTR(minor);
}
 
return(RTEMS_SUCCESSFUL);
}
 
/*
* z85c30_init
*/
 
Z85C30_STATIC void z85c30_init(int minor)
{
unsigned32 ulCtrlPort;
unsigned8 dummy;
z85c30_context *pz85c30Context;
setRegister_f setReg;
getRegister_f getReg;
 
setReg = Console_Port_Tbl[minor].setRegister;
getReg = Console_Port_Tbl[minor].getRegister;
 
pz85c30Context = (z85c30_context *)malloc(sizeof(z85c30_context));
 
Console_Port_Data[minor].pDeviceContext = (void *)pz85c30Context;
 
pz85c30Context->ucModemCtrl = SCC_WR5_TX_8_BITS | SCC_WR5_TX_EN;
 
ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort1;
if ( ulCtrlPort == Console_Port_Tbl[minor].ulCtrlPort2 ) {
/*
* This is channel A
*/
/*
* Ensure port state machine is reset
*/
dummy = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
 
(*setReg)(ulCtrlPort, SCC_WR0_SEL_WR9, SCC_WR9_CH_A_RST);
 
} else {
/*
* This is channel B
*/
/*
* Ensure port state machine is reset
*/
dummy = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
 
(*setReg)(ulCtrlPort, SCC_WR0_SEL_WR9, SCC_WR9_CH_B_RST);
}
}
 
/*
* These routines provide control of the RTS and DTR lines
*/
 
/*
* z85c30_assert_RTS
*/
 
Z85C30_STATIC int z85c30_assert_RTS(int minor)
{
rtems_interrupt_level Irql;
z85c30_context *pz85c30Context;
setRegister_f setReg;
 
setReg = Console_Port_Tbl[minor].setRegister;
 
pz85c30Context = (z85c30_context *) Console_Port_Data[minor].pDeviceContext;
/*
* Assert RTS
*/
 
rtems_interrupt_disable(Irql);
pz85c30Context->ucModemCtrl|=SCC_WR5_RTS;
(*setReg)(
Console_Port_Tbl[minor].ulCtrlPort1,
SCC_WR0_SEL_WR5,
pz85c30Context->ucModemCtrl
);
rtems_interrupt_enable(Irql);
return 0;
}
 
/*
* z85c30_negate_RTS
*/
 
Z85C30_STATIC int z85c30_negate_RTS(int minor)
{
rtems_interrupt_level Irql;
z85c30_context *pz85c30Context;
setRegister_f setReg;
 
setReg = Console_Port_Tbl[minor].setRegister;
 
pz85c30Context = (z85c30_context *) Console_Port_Data[minor].pDeviceContext;
/*
* Negate RTS
*/
 
rtems_interrupt_disable(Irql);
pz85c30Context->ucModemCtrl&=~SCC_WR5_RTS;
(*setReg)(
Console_Port_Tbl[minor].ulCtrlPort1,
SCC_WR0_SEL_WR5,
pz85c30Context->ucModemCtrl
);
rtems_interrupt_enable(Irql);
return 0;
}
 
/*
* These flow control routines utilise a connection from the local DTR
* line to the remote CTS line
*/
 
/*
* z85c30_assert_DTR
*/
 
Z85C30_STATIC int z85c30_assert_DTR(int minor)
{
rtems_interrupt_level Irql;
z85c30_context *pz85c30Context;
setRegister_f setReg;
 
setReg = Console_Port_Tbl[minor].setRegister;
 
pz85c30Context = (z85c30_context *) Console_Port_Data[minor].pDeviceContext;
/*
* Assert DTR
*/
 
rtems_interrupt_disable(Irql);
pz85c30Context->ucModemCtrl|=SCC_WR5_DTR;
(*setReg)(
Console_Port_Tbl[minor].ulCtrlPort1,
SCC_WR0_SEL_WR5,
pz85c30Context->ucModemCtrl
);
rtems_interrupt_enable(Irql);
return 0;
}
 
/*
* z85c30_negate_DTR
*/
 
Z85C30_STATIC int z85c30_negate_DTR(int minor)
{
rtems_interrupt_level Irql;
z85c30_context *pz85c30Context;
setRegister_f setReg;
 
setReg = Console_Port_Tbl[minor].setRegister;
 
pz85c30Context = (z85c30_context *) Console_Port_Data[minor].pDeviceContext;
/*
* Negate DTR
*/
 
rtems_interrupt_disable(Irql);
pz85c30Context->ucModemCtrl&=~SCC_WR5_DTR;
(*setReg)(
Console_Port_Tbl[minor].ulCtrlPort1,
SCC_WR0_SEL_WR5,
pz85c30Context->ucModemCtrl
);
rtems_interrupt_enable(Irql);
return 0;
}
 
/*
* z85c30_set_attributes
*
* This function sets the SCC channel to reflect the requested termios
* port settings.
*/
 
Z85C30_STATIC int z85c30_set_attributes(
int minor,
const struct termios *t
)
{
unsigned32 ulCtrlPort;
unsigned32 ulBaudDivisor;
unsigned32 wr3;
unsigned32 wr4;
unsigned32 wr5;
int baud_requested;
setRegister_f setReg;
rtems_interrupt_level Irql;
 
ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort1;
setReg = Console_Port_Tbl[minor].setRegister;
 
/*
* Calculate the baud rate divisor
*/
 
baud_requested = t->c_cflag & CBAUD;
if (!baud_requested)
baud_requested = B9600; /* default to 9600 baud */
 
ulBaudDivisor = Z85C30_Baud(
(unsigned32) Console_Port_Tbl[minor].ulClock,
(unsigned32) termios_baud_to_number( baud_requested )
);
 
wr3 = SCC_WR3_RX_EN;
wr4 = SCC_WR4_16_CLOCK;
wr5 = SCC_WR5_TX_EN;
 
/*
* Parity
*/
 
if (t->c_cflag & PARENB) {
wr4 |= SCC_WR4_PAR_EN;
if (!(t->c_cflag & PARODD))
wr4 |= SCC_WR4_PAR_EVEN;
}
 
/*
* Character Size
*/
 
if (t->c_cflag & CSIZE) {
switch (t->c_cflag & CSIZE) {
case CS5: break;
case CS6: wr3 |= SCC_WR3_RX_6_BITS; wr5 |= SCC_WR5_TX_6_BITS; break;
case CS7: wr3 |= SCC_WR3_RX_7_BITS; wr5 |= SCC_WR5_TX_7_BITS; break;
case CS8: wr3 |= SCC_WR3_RX_8_BITS; wr5 |= SCC_WR5_TX_8_BITS; break;
}
} else {
wr3 |= SCC_WR3_RX_8_BITS; /* default to 9600,8,N,1 */
wr5 |= SCC_WR5_TX_8_BITS; /* default to 9600,8,N,1 */
}
 
/*
* Stop Bits
*/
 
if (t->c_cflag & CSTOPB) {
wr4 |= SCC_WR4_2_STOP; /* 2 stop bits */
} else {
wr4 |= SCC_WR4_1_STOP; /* 1 stop bits */
}
 
/*
* Now actually set the chip
*/
 
rtems_interrupt_disable(Irql);
(*setReg)( ulCtrlPort, SCC_WR0_SEL_WR4, wr4 );
(*setReg)( ulCtrlPort, SCC_WR0_SEL_WR3, wr3 );
(*setReg)( ulCtrlPort, SCC_WR0_SEL_WR5, wr5 );
 
/*
* Setup the lower 8 bits time constants=1E.
* If the time constans=1E, then the desire
* baud rate will be equilvalent to 9600, via register 12.
*/
 
(*setReg)( ulCtrlPort, SCC_WR0_SEL_WR12, ulBaudDivisor & 0xff );
 
/*
* using register 13
* Setup the upper 8 bits time constant
*/
 
(*setReg)( ulCtrlPort, SCC_WR0_SEL_WR13, (ulBaudDivisor>>8) & 0xff );
 
rtems_interrupt_enable(Irql);
 
return 0;
}
 
/*
* z85c30_process
*
* This is the per port ISR handler.
*/
 
Z85C30_STATIC void z85c30_process(
int minor,
unsigned8 ucIntPend
)
{
unsigned32 ulCtrlPort;
volatile unsigned8 z85c30_status;
unsigned char cChar;
setRegister_f setReg;
getRegister_f getReg;
 
ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort1;
setReg = Console_Port_Tbl[minor].setRegister;
getReg = Console_Port_Tbl[minor].getRegister;
 
/*
* Deal with any received characters
*/
 
while (ucIntPend&SCC_RR3_B_RX_IP)
{
z85c30_status = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
if (!Z85C30_Status_Is_RX_character_available(z85c30_status)) {
break;
}
 
/*
* Return the character read.
*/
 
cChar = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD8);
 
rtems_termios_enqueue_raw_characters(
Console_Port_Data[minor].termios_data,
&cChar,
1
);
}
 
/*
* There could be a race condition here if there is not yet a TX
* interrupt pending but the buffer is empty. This condition has
* been seen before on other z8530 drivers but has not been seen
* with this one. The typical solution is to use "vector includes
* status" or to only look at the interrupts actually pending
* in RR3.
*/
 
while (TRUE) {
z85c30_status = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
if (!Z85C30_Status_Is_TX_buffer_empty(z85c30_status)) {
/*
* We'll get another interrupt when
* the transmitter holding reg. becomes
* free again and we are clear to send
*/
break;
}
#if 0
if (!Z85C30_Status_Is_CTS_asserted(z85c30_status)) {
/*
* We can't transmit yet
*/
(*setReg)(ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_TX_INT);
/*
* The next state change of CTS will wake us up
*/
break;
}
#endif
rtems_termios_dequeue_characters(Console_Port_Data[minor].termios_data, 1);
if (rtems_termios_dequeue_characters(
Console_Port_Data[minor].termios_data, 1)) {
if (Console_Port_Tbl[minor].pDeviceFlow != &z85c30_flow_RTSCTS) {
z85c30_negate_RTS(minor);
}
Console_Port_Data[minor].bActive = FALSE;
z85c30_enable_interrupts(minor, SCC_ENABLE_ALL_INTR_EXCEPT_TX);
(*setReg)(ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_TX_INT);
break;
}
 
}
 
if (ucIntPend & SCC_RR3_B_EXT_IP) {
/*
* Clear the external status interrupt
*/
(*setReg)(ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_INT);
z85c30_status = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
}
 
/*
* Reset interrupts
*/
(*setReg)(ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_HI_IUS);
}
 
/*
* z85c30_isr
*
* This is the ISR handler for each Z8530.
*/
 
Z85C30_STATIC rtems_isr z85c30_isr(
rtems_vector_number vector
)
{
int minor;
unsigned32 ulCtrlPort;
volatile unsigned8 ucIntPend;
volatile unsigned8 ucIntPendPort;
getRegister_f getReg;
 
for (minor=0;minor<Console_Port_Count;minor++) {
if(Console_Port_Tbl[minor].ulIntVector == vector &&
Console_Port_Tbl[minor].deviceType == SERIAL_Z85C30 ) {
ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort2;
getReg = Console_Port_Tbl[minor].getRegister;
do {
ucIntPend = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD3);
 
/*
* If this is channel A select channel A status
*/
 
if (ulCtrlPort == Console_Port_Tbl[minor].ulCtrlPort1) {
ucIntPendPort = ucIntPend>>3;
ucIntPendPort = ucIntPendPort&=7;
} else {
ucIntPendPort = ucIntPend &= 7;
}
 
if (ucIntPendPort) {
z85c30_process(minor, ucIntPendPort);
}
} while (ucIntPendPort);
}
}
}
 
/*
* z85c30_enable_interrupts
*
* This routine enables the specified interrupts for this minor.
*/
 
Z85C30_STATIC void z85c30_enable_interrupts(
int minor,
int interrupt_mask
)
{
unsigned32 ulCtrlPort;
setRegister_f setReg;
 
ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort1;
setReg = Console_Port_Tbl[minor].setRegister;
 
(*setReg)(ulCtrlPort, SCC_WR0_SEL_WR1, interrupt_mask);
}
 
/*
* z85c30_initialize_interrupts
*
* This routine initializes the port to use interrupts.
*/
 
Z85C30_STATIC void z85c30_initialize_interrupts(
int minor
)
{
unsigned32 ulCtrlPort1;
unsigned32 ulCtrlPort2;
setRegister_f setReg;
 
ulCtrlPort1 = Console_Port_Tbl[minor].ulCtrlPort1;
ulCtrlPort2 = Console_Port_Tbl[minor].ulCtrlPort2;
setReg = Console_Port_Tbl[minor].setRegister;
 
 
z85c30_init(minor);
 
Console_Port_Data[minor].bActive=FALSE;
 
z85c30_initialize_port( minor );
 
if (Console_Port_Tbl[minor].pDeviceFlow != &z85c30_flow_RTSCTS) {
z85c30_negate_RTS(minor);
}
 
set_vector(z85c30_isr, Console_Port_Tbl[minor].ulIntVector, 1);
 
z85c30_enable_interrupts(minor, SCC_ENABLE_ALL_INTR_EXCEPT_TX);
 
(*setReg)(ulCtrlPort1, SCC_WR0_SEL_WR2, 0); /* XXX vector */
(*setReg)(ulCtrlPort1, SCC_WR0_SEL_WR9, SCC_WR9_MIE);
 
/*
* Reset interrupts
*/
 
(*setReg)(ulCtrlPort1, SCC_WR0_SEL_WR0, SCC_WR0_RST_INT);
}
 
/*
* z85c30_write_support_int
*
* Console Termios output entry point.
*
*/
 
Z85C30_STATIC int z85c30_write_support_int(
int minor,
const char *buf,
int len)
{
unsigned32 Irql;
unsigned32 ulCtrlPort;
setRegister_f setReg;
 
ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort1;
setReg = Console_Port_Tbl[minor].setRegister;
 
/*
* We are using interrupt driven output and termios only sends us
* one character at a time.
*/
 
if ( !len )
return 0;
 
/*
* Put the character out and enable interrupts if necessary.
*/
 
if (Console_Port_Tbl[minor].pDeviceFlow != &z85c30_flow_RTSCTS) {
z85c30_assert_RTS(minor);
}
rtems_interrupt_disable(Irql);
if ( Console_Port_Data[minor].bActive == FALSE) {
Console_Port_Data[minor].bActive = TRUE;
z85c30_enable_interrupts(minor, SCC_ENABLE_ALL_INTR);
}
(*setReg)(ulCtrlPort, SCC_WR0_SEL_WR8, *buf);
rtems_interrupt_enable(Irql);
 
return 1;
}
 
/*
* z85c30_inbyte_nonblocking_polled
*
* This routine polls for a character.
*/
 
Z85C30_STATIC int z85c30_inbyte_nonblocking_polled(
int minor
)
{
volatile unsigned8 z85c30_status;
unsigned32 ulCtrlPort;
getRegister_f getReg;
 
ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort1;
getReg = Console_Port_Tbl[minor].getRegister;
 
/*
* return -1 if a character is not available.
*/
z85c30_status = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
if (!Z85C30_Status_Is_RX_character_available(z85c30_status)) {
return -1;
}
 
/*
* Return the character read.
*/
 
return (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD8);
}
 
/*
* z85c30_write_support_polled
*
* Console Termios output entry point.
*
*/
 
Z85C30_STATIC int z85c30_write_support_polled(
int minor,
const char *buf,
int len)
{
int nwrite=0;
 
/*
* poll each byte in the string out of the port.
*/
while (nwrite < len) {
z85c30_write_polled(minor, *buf++);
nwrite++;
}
 
/*
* return the number of bytes written.
*/
return nwrite;
}
 
/*
* z85c30_write_polled
*
* This routine transmits a character using polling.
*/
 
Z85C30_STATIC void z85c30_write_polled(
int minor,
char cChar
)
{
volatile unsigned8 z85c30_status;
unsigned32 ulCtrlPort;
getRegister_f getReg;
setRegister_f setReg;
 
ulCtrlPort = Console_Port_Tbl[minor].ulCtrlPort1;
getReg = Console_Port_Tbl[minor].getRegister;
setReg = Console_Port_Tbl[minor].setRegister;
 
/*
* Wait for the Transmit buffer to indicate that it is empty.
*/
 
z85c30_status = (*getReg)( ulCtrlPort, SCC_WR0_SEL_RD0 );
 
while (!Z85C30_Status_Is_TX_buffer_empty(z85c30_status)) {
/*
* Yield while we wait
*/
#if 0
if (_System_state_Is_up(_System_state_Get())) {
rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
}
#endif
z85c30_status = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
}
 
/*
* Write the character.
*/
 
(*setReg)( ulCtrlPort, SCC_WR0_SEL_WR8, cChar );
}
 
/mc68681_reg4.c
0,0 → 1,24
/*
* This file contains a typical set of register access routines which may be
* used with the mc68681 chip if accesses to the chip are as follows:
*
* + registers are accessed as bytes
* + registers are on 32-bit boundaries
*
* COPYRIGHT (c) 1989-1997.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id: mc68681_reg4.c,v 1.2 2001-09-27 12:01:42 chris Exp $
*/
 
#define _MC68681_MULTIPLIER 4
#define _MC68681_NAME(_X) _X##_4
#define _MC68681_TYPE unsigned8
 
#include "mc68681_reg.c"
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.