?? z85c30.c
字號(hào):
/* * 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). * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. * * $Id: z85c30.c,v 1.21.2.1 2003/09/04 18:46:04 joel Exp $ */#include <rtems.h>#include <rtems/libio.h>#include <stdlib.h>#include <libchip/serial.h>#include <libchip/sersupp.h>#include "z85c30_p.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; /*
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -