⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysserial.c

📁 WINDRIVER SBC405 BSP
💻 C
字号:
/* sysSerial.c - IBM 405GP serial device initialization *//*******************************************************************************   This source and object code has been made available to you by IBM on an   AS-IS basis.   IT IS PROVIDED WITHOUT WARRANTY OF ANY KIND, INCLUDING THE WARRANTIES OF   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE OR OF NONINFRINGEMENT   OF THIRD PARTY RIGHTS.  IN NO EVENT SHALL IBM OR ITS LICENSORS BE LIABLE   FOR INCIDENTAL, CONSEQUENTIAL OR PUNITIVE DAMAGES.  IBM'S OR ITS LICENSOR'S   DAMAGES FOR ANY CAUSE OF ACTION, WHETHER IN CONTRACT OR IN TORT, AT LAW OR   AT EQUITY, SHALL BE LIMITED TO A MAXIMUM OF $1,000 PER LICENSE.  No license   under IBM patents or patent applications is to be implied by the copyright   license.   Any user of this software should understand that neither IBM nor its   licensors will be responsible for any consequences resulting from the use   of this software.   Any person who transfers this source code or any derivative work must   include the IBM copyright notice, this paragraph, and the preceding two   paragraphs in the transferred software.   Any person who transfers this object code or any derivative work must   include the IBM copyright notice in the transferred software.   COPYRIGHT   I B M   CORPORATION 2000   LICENSED MATERIAL  -  PROGRAM PROPERTY OF  I B M"*******************************************************************************//* Copyright 1984-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01f,26jun02,mcg  Add CPU:UART divisor values for CPU speeds of 333 and 400MHz.                 Update divisor values for 266MHz.01e,11jan02,pch  merge in wrSbc405gp version of file, make common01d,19nov01,pch  cleanup01c,25may00,mcg  UART clock derived from CPU clock support added01b,15may00,mcg  register name updates to match 405GP User Manual01a,05mar99,mcg  created from Spruce sysSerial.c ver 01a*//*DESCRIPTIONThis library contains board-specific routines for serial devices.There are two serial ports integrated into the IBM 405GP.  Thesedevices are 16550-like. The evbNs16550Sio driver is used for both devices.*/#include "vxWorks.h"#include "config.h"#include "iv.h"#include "intLib.h"#include "sysLib.h"#include "drv/sio/evbNs16550Sio.h"/* device initialization structure */typedef struct    {    USHORT vector;    ULONG  baseAdrs;    USHORT regSpace;    USHORT intLevel;    } EVBNS16550_CHAN_PARAS;/* initialize the structure for each serial device */LOCAL EVBNS16550_CHAN_PARAS dev0Paras =      {0,UART0_BASE,UART_REG_ADDR_INTERVAL,INT_LVL_UART0};LOCAL EVBNS16550_CHAN_PARAS dev1Paras =      {0,UART1_BASE,UART_REG_ADDR_INTERVAL,INT_LVL_UART1};#define UART0_REG(reg)   (dev0Paras.baseAdrs + reg*dev0Paras.regSpace)#define UART1_REG(reg)   (dev1Paras.baseAdrs + reg*dev1Paras.regSpace)LOCAL EVBNS16550_CHAN  evbNs16550Chan0;LOCAL EVBNS16550_CHAN  evbNs16550Chan1;#ifndef UART_CLOCK_EXTERNAL/* forward declarations */STATUS sysSerialCalcDivisor(UINT freqProcMhz, UINT baudRate, UINT *divisor );/* Structure for internal serial clock array */typedef struct    {    UINT freqProcMhz;    UINT baudRate;    UINT uartClkDivisor;    } INT_SERIAL_INFO;/* * Table of CPU speeds and baud rates used to determine the CPU:UART divisor. * The CPU clock is divided by the CPU:UART divisor to get the UART clock which * is fed into the UARTs.  The UART clock is then divided again by the UART to * obtain the baud rate.  The table of CPU:UART divisors below helps to select * a value that will result in the lowest % error on the baud rate. * NOTE: * The CPU:UART divisor must be high enough so the resulting UART clock is * less than 1/2 of the OPB bus frequency. */INT_SERIAL_INFO uartClkTbl[] =    {      /* CPU Freq     Baud   CPU:UART divisor */        {  133,       1200,     15  },        {  133,       2400,     16  },        {  133,       4800,     28  },        {  133,       9600,     14  },        {  133,      19200,     14  },        {  133,      28800,     17  },        {  133,      33600,     31  },        {  133,      38400,     31  },        {  133,      57600,     29  },        {  133,     115200,     12  },        {  133,     307200,     27  },        {  200,       1200,     11  },        {  200,       2400,     28  },        {  200,       4800,     28  },        {  200,       9600,     14  },        {  200,      19200,     31  },        {  200,      28800,     31  },        {  200,      33600,     31  },        {  200,      38400,     25  },        {  200,      57600,     31  },        {  200,     115200,     12  },        {  200,     307200,     20  },        {  266,       1200,     19  },        {  266,       2400,     31  },        {  266,       4800,     28  },        {  266,       9600,     28  },        {  266,      19200,     28  },        {  266,      28800,     29  },        {  266,      33600,     31  },        {  266,      38400,     31  },        {  266,      57600,     29  },        {  266,     115200,     29  },        {  266,     307200,     27  },        {  333,       1200,     27  },        {  333,       2400,     31  },        {  333,       4800,     31  },        {  333,       9600,     31  },        {  333,      19200,     31  },        {  333,      28800,     29  },        {  333,      33600,     31  },        {  333,      38400,     17  },        {  333,      57600,     30  },        {  333,     115200,     30  },        {  333,     307200,     17  },        {  400,       1200,     22  },        {  400,       2400,     31  },        {  400,       4800,     31  },        {  400,       9600,     31  },        {  400,      19200,     31  },        {  400,      28800,     31  },        {  400,      33600,     31  },        {  400,      38400,     31  },        {  400,      57600,     31  },        {  400,     115200,     31  },        {  400,     307200,     27  }    };#endif /* UART_CLOCK_EXTERNAL *//************************************************************************* sysSerialHwInit - initialize the BSP serial devices to a quiescent state** This routine initializes the BSP serial device descriptors and puts the* devices in a quiescent state.  It is called from sysHwInit() with* interrupts locked.** RETURNS: N/A** SEE ALSO: sysHwInit()*/void sysSerialHwInit    (    void    )    {    UINT32 cr0;    #ifndef UART_CLOCK_EXTERNAL    UINT   clkDivisor;    #endif /* UART_CLOCK_EXTERNAL */    /*     * Disable and clear serial interrupts in the UIC for both UARTs     */    intDisable (INT_LVL_UART0);    intDisable (INT_LVL_UART1);    /*     * intialize serial device 0 descriptors (S0)     */    evbNs16550Chan0.int_vec = dev0Paras.vector;    evbNs16550Chan0.channelMode = 0;    evbNs16550Chan0.lcr  = UART0_REG(UART_LCR);    evbNs16550Chan0.data = UART0_REG(UART_RDR);    evbNs16550Chan0.brdl = UART0_REG(UART_BRDL);    evbNs16550Chan0.brdh = UART0_REG(UART_BRDH);    evbNs16550Chan0.ier  = UART0_REG(UART_IER);    evbNs16550Chan0.iid  = UART0_REG(UART_IID);    evbNs16550Chan0.mdc  = UART0_REG(UART_MDC);    evbNs16550Chan0.lst  = UART0_REG(UART_LST);    evbNs16550Chan0.msr  = UART0_REG(UART_MSR);    evbNs16550Chan0.outByte = sysOutByte;    evbNs16550Chan0.inByte  = sysInByte;    /*     * intialize serial device 1 descriptors (S1)     */    evbNs16550Chan1.int_vec = dev1Paras.vector;    evbNs16550Chan1.channelMode = 0;    evbNs16550Chan1.lcr  = UART1_REG(UART_LCR);    evbNs16550Chan1.data = UART1_REG(UART_RDR);    evbNs16550Chan1.brdl = UART1_REG(UART_BRDL);    evbNs16550Chan1.brdh = UART1_REG(UART_BRDH);    evbNs16550Chan1.ier  = UART1_REG(UART_IER);    evbNs16550Chan1.iid  = UART1_REG(UART_IID);    evbNs16550Chan1.mdc  = UART1_REG(UART_MDC);    evbNs16550Chan1.lst  = UART1_REG(UART_LST);    evbNs16550Chan1.msr  = UART1_REG(UART_MSR);    evbNs16550Chan1.outByte = sysOutByte;    evbNs16550Chan1.inByte  = sysInByte;    /*     * Set the the CPC0_CR0 register for internal or external UART clock source.     * Set UART1 to work in CTS/RTS mode by turning on the CTS enable bit     * in the Chip Control Reg 0 plus setting the DEFAULT_UART_1 control     * bit in the Walnut board's FPGA_BRDC register.  The FPGA routes the     * correct signal from the connector to the chip.  Other boards sharing     * this file (wrSbc405gp) may not implement FPGA_BRDC.     */#ifdef UART_CLOCK_EXTERNAL    cr0 = sysDcrCr0Get ();    sysDcrCr0Set (cr0 | CR0_UART1_CTS_EN                      | CR0_UART0_EXT_CLK | CR0_UART1_EXT_CLK);    evbNs16550Chan0.clkFreq = EXT_SER_CLK_FREQ;    evbNs16550Chan1.clkFreq = EXT_SER_CLK_FREQ;#else	/* UART_CLOCK_EXTERNAL */    /* CPU to UART clock divisor is determined and placed into CPC0_CR0 */    cr0 = sysDcrCr0Get ();    cr0 &= ~(CR0_UART_DIV_MASK | CR0_UART0_EXT_CLK | CR0_UART1_EXT_CLK );    sysSerialCalcDivisor (systemInfo.freqProcessor / 1000000,                          CONSOLE_BAUD_RATE,                          &clkDivisor);    sysDcrCr0Set (cr0 | CR0_UART1_CTS_EN | ((clkDivisor - 1) << 1));    evbNs16550Chan0.clkFreq = systemInfo.freqProcessor / clkDivisor;    evbNs16550Chan1.clkFreq = systemInfo.freqProcessor / clkDivisor;#endif /* UART_CLOCK_EXTERNAL */#if defined(FPGA_BRDC) && defined(FPGA_BRDC_DEF_UART1)    sysOutByte(FPGA_BRDC,(sysInByte(FPGA_BRDC) | FPGA_BRDC_DEF_UART1));#endif	/* FPGA_BRDC && FPGA_BRDC_DEF_UART1 */    /*     * reset both devices     */    evbNs16550HrdInit (&evbNs16550Chan0);    evbNs16550HrdInit (&evbNs16550Chan1);    }/************************************************************************* sysSerialHwInit2 - connect BSP serial device interrupts** This routine connects the BSP serial device interrupts.  It is called from* sysHwInit2().** Serial device interrupts cannot be connected in sysSerialHwInit() because* the kernel memory allocator is not initialized at that point, and* intConnect() calls malloc().** RETURNS: N/A** SEE ALSO: sysHwInit2()*/void sysSerialHwInit2    (    void    )    {    int intLevel = intLock ();    /*     * Connect serial interrupt handlers for S0 (UART 0)     * and enable serial interrupts for S0     */    (void) intConnect (INUM_TO_IVEC(INT_VEC_UART0), evbNs16550Int,                       (int) sysSerialChanGet(0));    intEnable (INT_LVL_UART0);    /*     * connect serial interrupt handlers for S1 (UART 1)     * and enable serial interrupts for S1     */    (void) intConnect (INUM_TO_IVEC(INT_VEC_UART1), evbNs16550Int,                       (int) sysSerialChanGet(1));    intEnable (INT_LVL_UART1);    intUnlock (intLevel);    }/************************************************************************* sysSerialChanGet - get the SIO_CHAN device associated with a serial channel** This routine returns a pointer to the SIO_CHAN device associated* with a specified serial channel.  It is called by usrRoot() to obtain* pointers when creating the system serial devices, `/tyCo/x'.  It* is also used by the WDB agent to locate its serial channel.** RETURNS: A pointer to the SIO_CHAN structure for the channel, or ERROR* if the channel is invalid.**/SIO_CHAN * sysSerialChanGet    (    int channel         /* serial channel */    )    {    switch (channel)        {        case 0:                                 /* S0 */            return ((SIO_CHAN *)&evbNs16550Chan0);        case 1:                                 /* S1 */            return ((SIO_CHAN *)&evbNs16550Chan1);        default:            return ((SIO_CHAN *)ERROR);        }    }#ifndef UART_CLOCK_EXTERNAL/************************************************************************* sysSerialCalcDivisor - determines CPU clock to UART clock divisor** This routine determines the optimal CPU clock to UART clock divisor for a* given CPU frequency and desired baud rate.  This function is required only* when the serial clock is being derived from the CPU clock.** RETURNS: The optimal CPU to UART clock divisor, or ERROR**/STATUS sysSerialCalcDivisor    (    UINT freqProcMhz,    UINT baudRate,    UINT *divisor    )    {    int numEntries;    int i;    numEntries = sizeof(uartClkTbl) / sizeof(INT_SERIAL_INFO);    /*     * Search the table of processor frequencies and Baud rates to determine     * the optimal divisor for the UART clock speed     */    for (i=0; i < numEntries; i++)        {        if ((uartClkTbl[i].freqProcMhz == freqProcMhz) &&            (uartClkTbl[i].baudRate == baudRate))            {            *divisor = uartClkTbl[i].uartClkDivisor;            break;            }        }    if (i == numEntries)             /* not found */        return(ERROR);    return(OK);    }#endif /* UART_CLOCK_EXTERNAL */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -