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

📄 m5200pscsio.c

📁 mpc5200 for bsp,it is have passed built.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* m5200PscSio.c - Motorola MPC5200 PSC UART driver *//* Copyright 1984-1996 Wind River Systems, Inc. *//*modification history--------------------01c,25Jun03,pkr	 adopted from 5204Sio01b,05may97,mem  changed baud rate calculation to round rather than		 truncate when dividing.  Reduces error at high baud rates.01a,10dec96,mem  written.*//*DESCRIPTIONThis is the driver for the UART contained in the MPC 5200 Microcontroller.Only asynchronous serial operation is supported by this driver.  Thedefault serial settings are 8 data bits, 1 stop bit, no parity, 9600buad, and software flow control.  These default settings can beoverridden by setting the M5200_PSC_CHAN options and baudRate fields tothe desired values before calling m5200PscSioDevInit.  See sioLib.h foroptions values.  The defaults for the module can be changed byredefining the macros M5200_DEFAULT_OPTIONS and M5200_DEFAULT_BAUD andrecompiling this driver.This driver uses the system clock as the input to the baud rategenerator.  The clkRate field must be set to the system clock rate inHZ for the baud rate calculations to work correctly.  The actual rangeof supported baud rates depends on the system clock speed.  For example,with a 25MHz system clock, the lowest baud rate is 24, and the highestis over 38400.  Because the baud rate values are calculated on request,there is no checking that the requested baud rate is standard, you canset the UART to operate at 4357 baud if you wish.USAGEA M5200_PSC_CHAN structure is used to describe the chip.The BSP's sysHwInit() routine typically calls sysSerialHwInit()which initializes all the H/W addresses in the M5200_PSC_CHAN structurebefore calling m5200PscSioDevInit().  This enables the chip to operate inpolled mode, but not interrupt mode.  Calling m5200PscSioDevInit2() fromthe sysSerialHwInit2() routine allows interrupts to be enabled andinterrupt mode operation to be used..CSi.e.#include "drv/sio/m5200PscSio.h"M5200_PSC_CHAN m5200Uart;			/@ my device structure @/#define INT_VEC_UART	(24+3)		/@ use single vector, #27 @/sysSerialHwInit()    {    /@ initialize the register pointers/data for uart @/    m5200Uart.clkRate	= MASTER_CLOCK;    m5200Uart.intVec	= INT_VEC_UART;    m5200Uart.portNum	= PORT_NUM_UART;    m5200Uart.mr	= PSC_UART_MR(SIM_BASE);    m5200Uart.sr	= PSC_UART_SR(SIM_BASE);    m5200Uart.csr	= PSC_UART_CSR(SIM_BASE);    m5200Uart.cr	= PSC_UART_CR(SIM_BASE);    m5200Uart.rb	= PSC_UART_RB(SIM_BASE);    m5200Uart.tb	= PSC_UART_TB(SIM_BASE);    m5200Uart.ipcr	= PSC_UART_IPCR(SIM_BASE);    m5200Uart.acr	= PSC_UART_ACR(SIM_BASE);    m5200Uart.isr	= PSC_UART_ISR(SIM_BASE);    m5200Uart.ivr	= PSC_UART_IVR(SIM_BASE);    m5200Uart.op1	= PSC_UART_OP1(SIM_BASE);    m5200Uart.sicr	= PSC_UART_SICR(SIM_BASE);    m5200Uart.dp	= PSC_UART_DP(SIM_BASE);    m5200Uart.dl	= PSC_UART_DP(SIM_BASE);    m5200Uart.rfalarm = PSC_UART_RFALARM(SIM_BASE);    m5200Uart.tfalarm = PSC_UART_TFALARM(SIM_BASE);     m5200PscSioDevInit (&m5200Uart);    }.CEThe BSP's sysHwInit2() routine typically calls sysSerialHwInit2() whichconnects the chips interrupts via intConnect() to the singleinterrupt handler m5200PscSioInt.  After the interrupt service routines are connected, the user then calls m5200PscSioDevInit2() to allow the driver to turn on interrupt enable bits..CSi.e.sysSerialHwInit2 ()    {    /@ connect single vector for 5200 @/    intConnect (INUM_TO_IVEC(MY_VEC), m5200PscSioInt, (int)&m5200Uart);    ...    /@ allow interrupts to be enabled @/    m5200PscSioDevInit2 (&m5200Uart);    }.CESPECIAL CONSIDERATIONS:The CLOCAL hardware option presumes that CTS outputs are wired asnecessary.  If not wired correctly, then the user must not select theCLOCAL option.  CLOCAL is not one of the default options for thisreason.As to the output port, this driver does not manipulate the output port,or it's configuration register in any way.  As stated above, if the userselects the CLOCAL option then the output port bit must be wired correctlyor the hardware flow control will not function as desired.INCLUDE FILES: drv/sio/m5200PscSio.h*/#include "vxWorks.h"#include "sioLib.h"#include "intLib.h"#include "errno.h"#include "arch/ppc/m5200.h"#include "drv/sio/m5200PscSio.h"#include "arch/ppc/vxPpcLib.h"/* forward static declarations */LOCAL STATUS m5200ModeSet (M5200_PSC_CHAN *, UINT);LOCAL STATUS m5200BaudSet (M5200_PSC_CHAN *, UINT);LOCAL STATUS m5200OptsSet (M5200_PSC_CHAN *, UINT);LOCAL int    m5200Ioctl (M5200_PSC_CHAN *, int, void *);LOCAL int    m5200TxStartup (M5200_PSC_CHAN *);LOCAL int    m5200CallbackInstall (M5200_PSC_CHAN *, int, STATUS (*)(), void *);LOCAL int    m5200PollInput (M5200_PSC_CHAN *, char *);LOCAL int    m5200PollOutput (M5200_PSC_CHAN*, char);LOCAL STATUS m5200DummyCallback (void);LOCAL void   m5200AcrSetClr (M5200_PSC_CHAN * pChan, UCHAR setBits, UCHAR clearBits);LOCAL void   m5200ImrSetClr (M5200_PSC_CHAN * pChan, USHORT setBits, USHORT clearBits);/* driver functions */LOCAL SIO_DRV_FUNCS m5200PscSioDrvFuncs =    {    (int (*)(SIO_CHAN *, int, void *))m5200Ioctl,    (int (*)(SIO_CHAN *))m5200TxStartup,    (int (*)())m5200CallbackInstall,    (int (*)(SIO_CHAN *, char*))m5200PollInput,    (int (*)(SIO_CHAN *, char))m5200PollOutput    };/* typedefs *//* defines */#ifndef M5200_DEFAULT_BAUD#   define M5200_DEFAULT_BAUD  115200#endif#ifndef M5200_DEFAULT_OPTIONS    /* no handshake, rcvr enabled, 8 data bits, 1 stop bit, no parity */#   define M5200_DEFAULT_OPTIONS (CREAD | CS8)#endif/* Hardware read/write routines.  Can be redefined to create drivers * for boards with special i/o access procedures. The reg pointer * arguments are the register pointers from the M5200_PSC_CHAN structure. */#ifndef M5200_READ#   define M5200_READ(x)	(*x)	/* argument is register pointer */#endif#ifndef M5200_WRITE#   define M5200_WRITE(x,y)	(*x = y) /* args are reg ptr and data */#endif#define MAX_OPTIONS	(0xff)/******************************************************************************** m5200PscSioDevInit - intialize a M5200_PSC_CHAN** The BSP must have already initialized all the device addresses, etc in* m5200_CHAN structure. This routine initializes some transmitter &* receiver status values to be used in the interrupt mask register and then* resets the chip to a quiescent state.** RETURNS: N/A*/void m5200PscSioDevInit    (    M5200_PSC_CHAN * pChan    )    {    int oldlevel;#if 0    ULONG gpio_wkup;#endif        pChan->pDrvFuncs	= &m5200PscSioDrvFuncs;    pChan->getTxChar	= m5200DummyCallback;    pChan->putRcvChar	= m5200DummyCallback;    pChan->mode		= 0; /* undefined */    pChan->intEnable	= FALSE;    pChan->acrCopy	= 0;    pChan->imrCopy	= 0;    if (pChan->options == 0 || pChan->options > MAX_OPTIONS)	pChan->options = M5200_DEFAULT_OPTIONS;    /* baud rate range is determined by calculation. */    if (pChan->baudRate)	{	UINT val;	val = ((pChan->clkRate / pChan->baudRate) + 16) / 32;	if ((val < 2) || (val > 0xffff))	    pChan->baudRate = M5200_DEFAULT_BAUD;	}    else	pChan->baudRate = M5200_DEFAULT_BAUD;    oldlevel =  intLock ();#if 0	gpio_wkup = GPIO_WKUP_BASE_ADRS;		if( MPC4200_GPIO_WKUP_USE)	{		M5200_WRITE (gpio_wkup + GPIO_WKUP_WE, 0x10000000);		M5200_WRITE (gpio_wkup + GPIO_WKUP_OD, 0x00000000);		M5200_WRITE (gpio_wkup + GPIO_WKUP_DD, 0x10000000);		M5200_WRITE (gpio_wkup + GPIO_WKUP_DO, 0x10000000);	}#endif    m5200ImrSetClr (pChan, 0, ~0);    m5200AcrSetClr (pChan, 0, PSC_UART_ACR_IEC);    M5200_WRITE (pChan->sicr, 0x00);		/* SIM2 = uart mode,dcd does not affect rx */    /* Use internal timer */    M5200_WRITE (pChan->csr,		 PSC_UART_CSR_TIMER_RX | PSC_UART_CSR_TIMER_TX);    /* Reset the transmitters  & receivers  */    M5200_WRITE (pChan->cr, PSC_UART_CR_RESET_RX);    M5200_WRITE (pChan->cr, PSC_UART_CR_RESET_TX);    M5200_WRITE (pChan->cr, PSC_UART_CR_RESET_ERR);    M5200_WRITE (pChan->cr, PSC_UART_CR_RESET_BRK);    M5200_WRITE (pChan->cr, PSC_UART_CR_RESET_MODE_PTR);	M5200_WRITE (pChan->op1, 1);    M5200_WRITE (pChan->imr, 0x0000);        /* Mask RxRDY and TxRDY from causing an interrupt */#if 0    M5200_WRITE (pChan->rfalarm, 0x01f0);    /* assert rx alarm when # full  >= 496 */    M5200_WRITE (pChan->tfalarm, 0x00f0);    /* assert tx alarm when # empty >= 240 */#else    M5200_WRITE (pChan->tfalarm, 0);   	     /* assert tx alarm when # empty >= 240 */#endif    /* TX is disabled */    m5200OptsSet (pChan, pChan->options);    m5200BaudSet (pChan, pChan->baudRate);	{	    ULONG aPortConfig;	    int aPortNum = pChan->portNum;	    volatile ULONG *pStdPortConfig;	   	    pStdPortConfig = (volatile ULONG *)(GPIO_STD_BASE_ADRS + GPIO_STD_PORT_CONFIG);		           	/* Enable the GPIO as UART w/o for PSC n*/		aPortConfig = M5200_READ(pStdPortConfig);       			if (aPortNum == PSC6_PORT)	/* special case for PSC6 */			{			aPortConfig &= ~GPIO_STD_PC_PSC6_MASK;			aPortConfig |= GPIO_STD_PC_PSC6_UART;			}		else			{			aPortConfig &= ~GPIO_STD_PC_PSC_MASK(aPortNum);			aPortConfig |= GPIO_STD_PC_PSC_UART(aPortNum);			}				M5200_WRITE(pStdPortConfig, aPortConfig);    }    intUnlock (oldlevel);    }/******************************************************************************** m5200PscSioDevInit2 - intialize a M5200_PSC_CHAN, part 2** This routine is called as part of sysSerialHwInit2() and tells* the driver that interrupt vectors are connected and that it is* safe to allow interrupts to be enabled.** RETURNS: N/A*/void m5200PscSioDevInit2    (    M5200_PSC_CHAN * pChan    )    {    /* Allow interrupt mode */    pChan->intEnable = TRUE;    m5200ModeSet (pChan, pChan->mode);    }/******************************************************************************** m5200ImrSetClr - set and clear bits in the UART's interrupt mask register** This routine sets and clears bits in the UART's IMR.** This routine sets and clears bits in a local copy of the IMR, then* writes that local copy to the UART.  This means that all changes to* the IMR must go through this routine.  Otherwise, any direct changes* to the IMR would be lost the next time this routine is called.** Set has priority over clear.  Thus you can use this routine to update* multiple bit fields by specifying the field mask as the clear bits.** RETURNS: N/A*/void m5200ImrSetClr    (    M5200_PSC_CHAN * pChan,    USHORT setBits,       /* which bits to set in the IMR   */    USHORT clearBits      /* which bits to clear in the IMR */    )    {    pChan->imrCopy = ((pChan->imrCopy & ~clearBits) | setBits);    M5200_WRITE (pChan->imr, pChan->imrCopy);    }/******************************************************************************** m5200Imr - return current interrupt mask register contents** This routine returns the interrupt mask register contents.  The imr* is not directly readable, a copy of the last value written is kept* in the UART data structure.** RETURNS: Returns interrupt mask register contents.*/USHORT m5200Imr    (    M5200_PSC_CHAN * pChan    )    {    return pChan->imrCopy;    }/******************************************************************************** m5200AcrSetClr - set and clear bits in the UART's aux control register** This routine sets and clears bits in the UART's ACR.** This routine sets and clears bits in a local copy of the ACR, then* writes that local copy to the UART.  This means that all changes to* the ACR must go through this routine.  Otherwise, any direct changes* to the ACR would be lost the next time this routine is called.** Set has priority over clear.  Thus you can use this routine to update* multiple bit fields by specifying the field mask as the clear bits.** RETURNS: N/A*/void m5200AcrSetClr    (    M5200_PSC_CHAN * pChan,    UCHAR setBits,       /* which bits to set in the ACR   */    UCHAR clearBits      /* which bits to clear in the ACR */    )    {    pChan->acrCopy = ((pChan->acrCopy &  ~clearBits) | setBits);    M5200_WRITE (pChan->acr, pChan->acrCopy);    }/******************************************************************************** m5200Acr - return aux control register contents** This routine returns the auxilliary control register contents.  The acr* is not directly readable, a copy of the last value written is kept* in the UART data structure.** RETURNS: Returns auxilliary control register (acr) contents.*/UCHAR m5200Acr    (    M5200_PSC_CHAN * pChan    )    {    return pChan->acrCopy;    }/******************************************************************************** m5200DummyCallback - dummy callback routine.** RETURNS:* Always returns ERROR*/LOCAL STATUS m5200DummyCallback (void)    {    return (ERROR);    }/******************************************************************************** m5200TxStartup - start the interrupt transmitter.** This routine enables the transmitters for the specified UART channel so that* the UART channel will interrupt the CPU when TxRDY bit in the status* register is set.** Just enable the transmitter, don't output.  The driver may have just* switched from POLL mode and may still be outputting a character.** RETURNS:* Returns OK on success, or EIO on hardware error.*/LOCAL int m5200TxStartup    (    M5200_PSC_CHAN * pChan    )    {#if 0    UCHAR outChar;

⌨️ 快捷键说明

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