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

📄 sysduart.c

📁 cpc-1631的BSP包for VxWorks操作系统
💻 C
字号:
/* sysDuart.c -  MPC 8245/8241 Duart device initialization */

/* Copyright 1984-2002 Wind River Systems, Inc. */

/*
modification history
--------------------
01a,08jan02,jnz  created for sp824x BSP, MPC8241/8245.
*/

/*
DESCRIPTION
This file contains board-specific routines for Motorola MPC8245/8241
Duart device initialization. 
*/

#include "vxWorks.h"
#include "config.h"
#include "intLib.h"
#include "iv.h"
#include "sysLib.h"
#include "config.h"

#include "sysDuart.h"		        /* MPC8241/8245 duart driver */
#include "ns16552Sio.h"		/* ns16552Sio driver */

#include "i8250Sio.h"

/* external variables */


/* device description structs */

typedef struct
    {
    USHORT vector;			/* Interrupt vector */
    ULONG  baseAdrs;			/* Register base address */
    USHORT regSpace;			/* Address Interval */
    USHORT intLevel;			/* Interrupt level */
    } NS16552_CHAN_PARAS;


/* external variable */

IMPORT int epicIntTrace;                /* trace epic internal interrupts */

/* global variable */

NS16550_CHAN  ns16550Chan[N_DUART_CHANNELS];

char  *eumbbar_base;                    /* eumbbar base address */

/* static variables */

LOCAL NS16552_CHAN_PARAS devDuartParas[] = 
    {
    {EPIC_DUART1_INT_VECT, COM3_ADR, DUART_REG_ADDR_INTERVAL,EPIC_DUART1_INT_VECT},
    {EPIC_DUART2_INT_VECT, COM4_ADR, DUART_REG_ADDR_INTERVAL, EPIC_DUART2_INT_VECT}
    };

/*
 * Array of pointers to all serial channels configured in PPMC 8245 module.
 * See sysDuartChanGet(). It is this array that maps channel pointers
 * to standard device names.  The first entry will become "/tyCo/2",
 * the second "/tyCo/3".
 */

SIO_CHAN * sysDuartSioChans [N_SIO_CHANNELS] =
    {
    (SIO_CHAN *)&ns16550Chan[0].pDrvFuncs,	/* /tyCo/2 */
    (SIO_CHAN *)&ns16550Chan[1].pDrvFuncs,	/* /tyCo/3 */
    };


/* definitions */

#define DUART_REG(reg, chan) \
        *(volatile UINT8 *)(devDuartParas[chan].baseAdrs + reg * devDuartParas[chan].regSpace)

#define	SERIAL_BASE(_x)		0xfc004500 

#define UART_REG(reg,chan) 		(SERIAL_BASE(chan) + reg)

/******************************************************************************
 *
 * Utility routines
 */

UCHAR sysSerialInByte(int addr)
{
    return *(UCHAR *) addr;
}

void sysSerialOutByte(int addr, UCHAR c)
{
    *(UCHAR *) addr = c;
}

/******************************************************************************
 *
 * Serial debugging print routines
 *
 * The following routines are for debugging, especially useful in early
 * boot ROM and ISR code.
 *
 * sysSerialPutc
 * sysSerialGetc
 * sysSerialPrintString
 * sysSerialPrintHex
 *
 * The sysSerialPrintString and sysSerialPrintHex routines should
 * basically ALWAYS work.  They re-initialize the UART and turn off
 * interrupts every time.
 */

#define SS_CHAN		0

void sysSerialDelay(void)
{
    volatile int i;
    for (i = 0; i < 0x10000; i++)
	;
}

void sysSerialPutc(int c)
{
    int i = 10000;
    while (!(sysSerialInByte(UART_REG(UART_LST, SS_CHAN)) & 0x40) && i--)
        ;
    sysSerialOutByte(UART_REG(UART_THR, SS_CHAN), c);
}

int sysSerialGetc(void)
{
    while (!(sysSerialInByte(UART_REG(UART_LST, SS_CHAN)) & 0x01))
        ;
    return sysSerialInByte(UART_REG(UART_RDR, SS_CHAN));
}

void sysSerialPrintString(char *s)
{
    int c, il;
    il = intLock();
    /*QDIMCZH debug start
    sysSerialOutByte(UART_REG(UART_LCR, SS_CHAN), 0x83);
    sysSerialOutByte(UART_REG(UART_BRDL, SS_CHAN), 0x78);
    sysSerialOutByte(UART_REG(UART_BRDH, SS_CHAN), 0x00);
    sysSerialOutByte(UART_REG(UART_LCR, SS_CHAN), 0x03);
    sysSerialOutByte(UART_REG(UART_MDC, SS_CHAN), 0xb);
    QDIMCZH debug end */
    /*QDIMCZH debug start */
    sysSerialOutByte(UART_REG(UART_UDCR, SS_CHAN), 0x00);
    sysSerialOutByte(UART_REG(UART_LCR, SS_CHAN), 0x80);
    sysSerialOutByte(UART_REG(UART_UAFR, SS_CHAN), 0x00);
    sysSerialOutByte(UART_REG(UART_BRDL, SS_CHAN), 0x8b);
    sysSerialOutByte(UART_REG(UART_BRDH, SS_CHAN), 0x02);
    sysSerialOutByte(UART_REG(UART_LCR, SS_CHAN), 0x03);
    sysSerialOutByte(UART_REG(UART_IER, SS_CHAN), 0x00);
    /*QDIMCZH debug end */
    while ((c = *s++) != 0) {
        if (c == '\n')
            sysSerialPutc('\r');
        sysSerialPutc(c);
    }
    sysSerialDelay();	/* Allow last char to flush */
    intUnlock(il);
}

/******************************************************************************
*
* sysDuartHwInit - initialize 8245 duart devices to a quiescent state
*
* This routine initializes the MPC 8245 Duart device descriptors and puts
* the devices in a quiescent state.  It is called from sysHwInit() with
* interrupts locked.   Polled mode serial operations are possible, but
* not interrupt mode operations which are enabled by sysDuartHwInit2().
*
* RETURNS: N/A
*
* SEE ALSO: sysHwInit()
*/ 

void sysDuartHwInit (void)
    {
    int i;

    eumbbar_base = (char *)EUMBBAR_VAL;

    for (i = 0; i < N_DUART_CHANNELS; i++)
        {
	ns16550Chan[i].regs        = (UINT8 *)devDuartParas[i].baseAdrs;
	ns16550Chan[i].level	   = devDuartParas[i].intLevel;

	ns16550Chan[i].ier	   = DUART_REG(IER,i);
	ns16550Chan[i].lcr	   = DUART_REG(LCR,i);
	ns16550Chan[i].mcr	   = DUART_REG(MCR,i);
	/*ns16550Chan[i].channelMode = SIO_MODE_POLL;*/

	ns16550Chan[i].channelMode = SIO_MODE_INT;
	ns16550Chan[i].regDelta    = devDuartParas[i].regSpace;
	ns16550Chan[i].baudRate	   = DUART_BAUD;
	ns16550Chan[i].xtal	   = XTAL;

	ns16550DevInit (&ns16550Chan[i]);
        }

    if (ns16550Chan[0].channelMode == SIO_MODE_INT)
	{
        eumbbar_base[UDCR1] = 0x01;  /* set duart mode */
        eumbbar_base[ULCR1] = 0x80;  /* open DLAB */
        eumbbar_base[UAFR1] = 0x00;
        eumbbar_base[UDMB1] = 0x02;  /* for mpc8245 MSB, 9600bps @100Mhz */
	eumbbar_base[UDLB1] = 0x8b;  /* LSB */
	eumbbar_base[ULCR1] = 0x03;  /* clear DLAB, no-parity, 1stop bit, 8bit data */
	eumbbar_base[UMCR1] = 0x02;  /* diable loopback mode */
	eumbbar_base[UIER1] = 0x03;  /* Tx empty, Rx interrupt enable */
	}

    if (ns16550Chan[1].channelMode == SIO_MODE_INT)
	{
        eumbbar_base[UDCR2] = 0x01;  /* set duart mode */
        eumbbar_base[ULCR2] = 0x80;  /* open DLAB */
        eumbbar_base[UAFR2] = 0x00;
        eumbbar_base[UDMB2] = 0x02;  /* for mpc8245 MSB, 9600bps @100Mhz */
	eumbbar_base[UDLB2] = 0x8b;  /* LSB */
	eumbbar_base[ULCR2] = 0x03;  /* clear DLAB, no-parity, 1stop bit, 8bit data */
	eumbbar_base[UMCR2] = 0x02;  /* diable loopback mode */
	eumbbar_base[UIER2] = 0x03;  /* Tx empty, Rx interrupt enable */
	}

    } /* sysDuartHwInit () */


/******************************************************************************
*
* sysDuartHwInit2 - connect MPC8241/8245 duart device interrupts
*
* This routine connects the MPC8241/8245 duart device interrupts. It is called
* from sysHwInit2().  
*
* Serial device interrupts cannot be connected in sysDuartHwInit() because
* the kernel memory allocator is not initialized at that point and
* intConnect() calls malloc().
*
* RETURNS: N/A
*
* SEE ALSO: sysHwInit2()
*/ 

void sysDuartHwInit2 (void)
    {
    int i;

    /* connect serial interrupts */
    for (i = 0; i < N_DUART_CHANNELS; i++)
        {
        (void) intConnect ((VOIDFUNCPTR *)((int)devDuartParas[i].vector),
                           ns16550Int, (int)&ns16550Chan[i] );

        intEnable (devDuartParas[i].vector); 
        }

    } /* sysDuartHwInit2 () */


/******************************************************************************
*
* sysDuartChanGet - get the SIO_CHAN device associated with MPC8245 duart channel
*
* This routine returns a pointer to the SIO_CHAN device associated
* with a specified serial channel on MPC8245.  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 * sysDuartChanGet
    (
    int channel         /* serial channel */
    )
    {
    if ( (channel < 0) ||
         (channel >= NELEMENTS(sysDuartSioChans)) )
	return (SIO_CHAN *) ERROR;

    return sysDuartSioChans[channel];
    }

⌨️ 快捷键说明

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