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

📄 s3c2410xsio.c

📁 S3C2410开发板的VXWORKS开发包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* s3c2410xSio.c - Samsung S3C2410X serial driver */#include "copyright_wrs.h"#include "vxWorks.h"#include "sioLib.h"#include "intLib.h"#include "errno.h"#include "s3c2410xSio.h"#include "ioLib.h"#define S3C2410X_BAUD_MIN         1200#define S3C2410X_BAUD_MAX         460860#define S3C2410X_SIO_DEFAULT_BAUD 9600#ifndef s3c2410x_UART_REG#define s3c2410x_UART_REG(pChan, reg) \	(*(volatile UINT32 *)((UINT32)(pChan)->regs + (reg)))#endif#ifndef S3C2410X_SIO_REG_READ#define S3C2410X_SIO_REG_READ(pChan, reg, result) \    ((result) = (*(volatile UINT32 *)((UINT32)(pChan)->regs + (reg))))#endif   #ifndef S3C2410X_SIO_REG_WRITE#define S3C2410X_SIO_REG_WRITE(pChan, reg, data) \    ((*(volatile UINT32 *)((UINT32)(pChan)->regs + (reg))) = (data))#endif   #ifndef s3c2410x_UART_REG_READ#define s3c2410x_UART_REG_READ(pChan, reg, result) \	(result) = (s3c2410x_UART_REG(pChan, reg))#endif#ifndef s3c2410x_UART_REG_WRITE#define s3c2410x_UART_REG_WRITE(pChan, reg, data) \	(s3c2410x_UART_REG(pChan, reg)) = (data)#endif#ifndef s3c2410x_UART_REG_BIT_SET#define s3c2410x_UART_REG_BIT_SET(pChan, reg, data) \	(s3c2410x_UART_REG(pChan, reg)) |= (data)#endif#ifndef s3c2410x_UART_REG_BIT_CLR#define s3c2410x_UART_REG_BIT_CLR(pChan, reg, data) \	(s3c2410x_UART_REG(pChan, reg)) &= ~(data)#endif#ifndef s3c2410x_INT_REG_READ#define s3c2410x_INT_REG_READ(reg,result) \	((result) = *(volatile UINT32 *)(reg))#endif#ifndef s3c2410x_INT_REG_WRITE#define s3c2410x_INT_REG_WRITE(reg,data) \	(*((volatile UINT32 *)(reg)) = (data))#endif#define _IS_USER_FIFO_/* for backward compatibility */#ifndef    SIO_HUP#   define SIO_OPEN    0x100A    #   define SIO_HUP     0x100B   #endifLOCAL int    s3c2410xTxStartup (SIO_CHAN * pSioChan);LOCAL int    s3c2410xCallbackInstall (SIO_CHAN *pSioChan, int callbackType,                                      STATUS (*callback)(), void *callbackArg);LOCAL int    s3c2410xPollOutput (SIO_CHAN *pSioChan, char    outChar);LOCAL int    s3c2410xPollInput (SIO_CHAN *pSioChan, char *thisChar);LOCAL int    s3c2410xIoctl (SIO_CHAN *pSioChan, int request, void *arg);LOCAL STATUS dummyCallback (void);/* local variables */LOCAL    SIO_DRV_FUNCS s3c2410xSioDrvFuncs =    {    s3c2410xIoctl,    s3c2410xTxStartup,    s3c2410xCallbackInstall,    s3c2410xPollInput,    s3c2410xPollOutput    };LOCAL BOOL s3c2410xIntrMode = FALSE;   /******************************************************************************** s3c2410xDevInit - initialize a S3C2410X_DUSART*** RETURNS: N/A*/void s3c2410xDevInit(S3C2410X_CHAN * pChan)    {    pChan->sio.pDrvFuncs    = &s3c2410xSioDrvFuncs;    pChan->getTxChar     = dummyCallback;    pChan->putRcvChar    = dummyCallback;    	S3C2410X_SIO_REG_WRITE(pChan,S3C2410X_ULCON,(INFRA_RED_NONE | PARITY_NONE | ONE_STOP | WORD_LEN));	S3C2410X_SIO_REG_WRITE(pChan,S3C2410X_UCON,0x005);	#ifdef _IS_USER_FIFO_	S3C2410X_SIO_REG_WRITE(pChan,S3C2410X_UFCON,0xd7);		#else	S3C2410X_SIO_REG_WRITE(pChan,S3C2410X_UFCON,0x00);		#endif	S3C2410X_SIO_REG_WRITE(pChan,S3C2410X_UMCON,0);    s3c2410xIoctl ((SIO_CHAN *)pChan, SIO_MODE_SET, (void *)SIO_MODE_POLL);    s3c2410xIoctl ((SIO_CHAN *)pChan, SIO_BAUD_SET, (void *)S3C2410X_SIO_DEFAULT_BAUD);	    }/******************************************************************************** s3c2410xDevInit2 - initialize a S3C2410X_DUSART, part 2*** RETURNS: N/A* ARGSUSED*/void s3c2410xDevInit2    (    S3C2410X_CHAN * pChan        /* device to initialize */    )    {    char      outchar = '\0';	UINT32	tempUINT32;    S3C2410X_SIO_REG_WRITE(pChan,S3C2410X_ULCON,(INFRA_RED_NONE | PARITY_NONE | ONE_STOP | WORD_LEN));    S3C2410X_SIO_REG_WRITE(pChan,S3C2410X_UTXBUF,outchar);    S3C2410X_SIO_REG_WRITE(pChan,S3C2410X_UCON,UCON_RX|UCON_TX|0x80);		s3c2410x_INT_REG_READ(S3C2410X_INTSUBMSK,tempUINT32);	switch((int)(pChan->regs))	{	case SERIAL_B_BASE_ADR:		tempUINT32 &= ~((1<<SUBINT_LVL_RXD1)|(1<<SUBINT_LVL_TXD1));		break;	case SERIAL_A_BASE_ADR:	default:		tempUINT32 &= ~((1<<SUBINT_LVL_RXD0)|(1<<SUBINT_LVL_TXD0));	}	s3c2410x_INT_REG_WRITE(S3C2410X_INTSUBMSK,tempUINT32);	s3c2410xIntrMode = TRUE;	#ifdef _IS_USER_FIFO_	S3C2410X_SIO_REG_WRITE(pChan,S3C2410X_UFCON,0xd7);		#else	S3C2410X_SIO_REG_WRITE(pChan,S3C2410X_UFCON,0x00);		#endif	S3C2410X_SIO_REG_WRITE(pChan,S3C2410X_UCON,UCON_RX|UCON_TX|0x80);	s3c2410xIoctl ((SIO_CHAN *)pChan, SIO_BAUD_SET, (void *)S3C2410X_SIO_DEFAULT_BAUD);		s3c2410xIoctl ((SIO_CHAN *)pChan, SIO_MODE_SET, (void *)SIO_MODE_INT);		s3c2410x_UART_REG_READ(pChan, S3C2410X_URXBUF, tempUINT32);	    }/******************************************************************************** s3c2410xIntRcv - handle a channel's receive-character interrupt** RETURNS: N/A*/ void s3c2410xIntRcv    (    S3C2410X_CHAN *    pChan        /* channel generating the interrupt */    ){    char            inChar;    UINT32        status;        switch((int)(pChan->regs))	{				case SERIAL_B_BASE_ADR:			s3c2410x_INT_REG_WRITE(S3C2410X_SUBSRCPND, (1<<SUBINT_LVL_RXD1));			break;		case SERIAL_A_BASE_ADR:		default:			s3c2410x_INT_REG_WRITE(S3C2410X_SUBSRCPND, (1<<SUBINT_LVL_RXD0));	}    #ifdef _IS_USER_FIFO_	while(1)	{		S3C2410X_SIO_REG_READ(pChan,S3C2410X_UFSTAT, status);    	if((status & UFSTAT_RX_COUNT) == 0) 			break;        S3C2410X_SIO_REG_READ(pChan,S3C2410X_URXBUF, inChar);		        (*pChan->putRcvChar) (pChan->putRcvArg, inChar);    }        #else    S3C2410X_SIO_REG_READ(pChan,S3C2410X_USTAT, status);    if((status & USTAT_RX_READY) == USTAT_RX_READY)    {        S3C2410X_SIO_REG_READ(pChan,S3C2410X_URXBUF, inChar);        (*pChan->putRcvChar) (pChan->putRcvArg, inChar);    }	#endif	}static int sending = 0;		/******************************************************************************** s3c2410xIntTx - handle a channels transmitter-ready interrupt** RETURNS: N/A*/ void s3c2410xIntTx    (    S3C2410X_CHAN *    pChan        /* channel generating the interrupt */    )    {    char      outChar;    UINT32    status;    FAST int     oldlevel; 		    switch((int)(pChan->regs))	{				case SERIAL_B_BASE_ADR:			s3c2410x_INT_REG_WRITE(S3C2410X_SUBSRCPND, (1<<SUBINT_LVL_TXD1));			break;		case SERIAL_A_BASE_ADR:		default:			s3c2410x_INT_REG_WRITE(S3C2410X_SUBSRCPND, (1<<SUBINT_LVL_TXD0));	}	#ifdef _IS_USER_FIFO_     	S3C2410X_SIO_REG_READ(pChan,S3C2410X_UFSTAT, status);		if((status & UFSTAT_TX_FULL) == UFSTAT_TX_FULL) 		return;	#else	S3C2410X_SIO_REG_READ(pChan,S3C2410X_USTAT, status);		if((status & USTAT_TX_READY) != USTAT_TX_READY) 		return;	#endif	oldlevel = intLock ();    if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR)	{		#ifdef _IS_USER_FIFO_        S3C2410X_SIO_REG_WRITE(pChan, S3C2410X_UTXBUF, outChar);		while(1)		{						S3C2410X_SIO_REG_READ(pChan,S3C2410X_UFSTAT, status);        		if((status & UFSTAT_TX_FULL) == UFSTAT_TX_FULL) 				break;						if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) == ERROR) 				break;						S3C2410X_SIO_REG_WRITE(pChan, S3C2410X_UTXBUF, outChar);		}		#else		S3C2410X_SIO_REG_WRITE(pChan, S3C2410X_UTXBUF, outChar);		#endif    }	        intUnlock (oldlevel);}/********************************************/void    s3c2410xInt    (S3C2410X_CHAN *pChan){	UINT32 intId;		s3c2410x_INT_REG_READ(S3C2410X_SUBSRCPND , intId);	if(intId & ((1<<SUBINT_LVL_TXD0)|(1<<SUBINT_LVL_TXD1)))	{		s3c2410xIntTx(pChan);			}	if(intId & ((1<<SUBINT_LVL_RXD0)|(1<<SUBINT_LVL_RXD1)))	{		s3c2410xIntRcv (pChan);	}	s3c2410x_INT_REG_WRITE(S3C2410X_INTSUBMSK , 0);}/******************************************************************************** s3c2410xTxStartup - start the interrupt transmitter** RETURNS: OK on success, ENOSYS if the device is polled-only, or* EIO on hardware error.*/LOCAL int s3c2410xTxStartup    (    SIO_CHAN * pSioChan                 /* channel to start */    )    {    S3C2410X_CHAN * pChan = (S3C2410X_CHAN *)pSioChan;		if(pChan->mode == SIO_MODE_INT)	{		intEnable(pChan->intLevelTx);		s3c2410xIntTx(pChan);		return OK;	}	else	{		return ERROR;	}    }/******************************************************************************** s3c2410xCallbackInstall - install ISR callbacks to get/put chars*** RETURNS: OK on success, or ENOSYS for an unsupported callback type.*/ LOCAL int s3c2410xCallbackInstall    (    SIO_CHAN *    pSioChan,                   int           callbackType,              STATUS        (*callback)(),              void *        callbackArg               )    {    S3C2410X_CHAN * pChan = (S3C2410X_CHAN *)pSioChan;    switch (callbackType)    {    case SIO_CALLBACK_GET_TX_CHAR:        pChan->getTxChar    = callback;        pChan->getTxArg     = callbackArg;        return (OK);    case SIO_CALLBACK_PUT_RCV_CHAR:        pChan->putRcvChar    = callback;        pChan->putRcvArg     = callbackArg;        return (OK);    default:        return (ENOSYS);    }    }/********************************************************************************* s3c2410xPollOutput - output a character in polled mode** RETURNS: OK if a character arrived, EIO on device error, EAGAIN* if the output buffer if full. ENOSYS if the device is* interrupt-only.*/LOCAL int s3c2410xPollOutput    (    SIO_CHAN *pSioChan,    char      outChar    )    {    S3C2410X_CHAN * pChan = (S3C2410X_CHAN *)pSioChan;    UINT32    status;    S3C2410X_SIO_REG_READ (pChan, S3C2410X_USTAT, status);    if ((status & USTAT_TX_READY) == 0x00)        return (EAGAIN);    S3C2410X_SIO_REG_WRITE(pChan, S3C2410X_UTXBUF, outChar);	    return (OK);    }/******************************************************************************** s3c2410xPollInput - poll the device for input** RETURNS: OK if a character arrived, EIO on device error, EAGAIN* if the input buffer if empty, ENOSYS if the device is* interrupt-only.

⌨️ 快捷键说明

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