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

📄 ks8695sio.c

📁 kedin bsp for vxWorks
💻 C
字号:
/* ks8695Sio.c - KS8695P UART tty driver *//*modification history--------------------9/22/2003  Ritter Yeh  created */#include "vxWorks.h"#include "intLib.h"#include "errnoLib.h"#include "errno.h"#include "sioLib.h"#include "ks8695Sio.h"/* local defines  */#define KS8695P_UART_REG(pChan, reg) \	(*(volatile UINT32 *)((UINT32)(pChan)->regs + (reg)))#define KS8695P_UART_REG_READ(pChan, reg, result) \	(result) = (KS8695P_UART_REG(pChan, reg))#define KS8695P_UART_REG_WRITE(pChan, reg, data) \	(KS8695P_UART_REG(pChan, reg)) = (data)#define KS8695P_UART_REG_BIT_SET(pChan, reg, data) \	(KS8695P_UART_REG(pChan, reg)) |= (data)#define KS8695P_UART_REG_BIT_CLR(pChan, reg, data) \	(KS8695P_UART_REG(pChan, reg)) &= ~(data)/* locals *//* function prototypes */LOCAL STATUS ks8695pDummyCallback (void);LOCAL void ks8695pInitChannel (KS8695P_CHAN * pChan);LOCAL STATUS ks8695pIoctl (SIO_CHAN * pSioChan, int request, int arg);LOCAL int ks8695pTxStartup (SIO_CHAN * pSioChan);LOCAL int ks8695pCallbackInstall (SIO_CHAN * pSioChan, int callbackType,			       STATUS (*callback)(), void * callbackArg);LOCAL int ks8695pPollInput (SIO_CHAN * pSioChan, char *);LOCAL int ks8695pPollOutput (SIO_CHAN * pSioChan, char);/* driver functions */LOCAL SIO_DRV_FUNCS ks8695pSioDrvFuncs =    {    (int (*)())ks8695pIoctl,    ks8695pTxStartup,    ks8695pCallbackInstall,    ks8695pPollInput,    ks8695pPollOutput    };/********************************************************************************* ks8695pDummyCallback - dummy callback routine.** RETURNS: ERROR, always.*/LOCAL STATUS ks8695pDummyCallback (void)    {    return ERROR;    }/********************************************************************************* ks8695pSioDevInit - initialise an AMBA channel** This routine initialises some SIO_CHAN function pointers and then resets* the chip to a quiescent state.  Before this routine is called, the BSP* must already have initialised all the device addresses, etc. in the* KS8695P_CHAN structure.** RETURNS: N/A*/void ks8695pSioDevInit    (    KS8695P_CHAN *	pChan	/* ptr to KS8695P_CHAN describing this channel */    )    {    int oldlevel = intLock();    /* initialise the driver function pointers in the SIO_CHAN */    pChan->sio.pDrvFuncs = &ks8695pSioDrvFuncs;    /* set the non BSP-specific constants */    pChan->getTxChar = ks8695pDummyCallback;    pChan->putRcvChar = ks8695pDummyCallback;    pChan->channelMode = 0;    /* undefined */    /* initialise the chip */    ks8695pInitChannel (pChan);    intUnlock (oldlevel);    }/********************************************************************************* ks8695pInitChannel - initialise UART** This routine performs hardware initialisation of the UART channel.** RETURNS: N/A*/LOCAL void ks8695pInitChannel    (    KS8695P_CHAN *	pChan	/* ptr to KS8695P_CHAN describing this channel */    )    {    /* Program UART line control register        Set 8 bits, 1 stop bit, no parity.    */    KS8695P_UART_REG_WRITE(pChan, REG_UART_LINE_CTRL, 0);    KS8695P_UART_REG_BIT_SET(pChan, REG_UART_LINE_CTRL,REG_URLC_8_BIT);    /* Set baud rate divisor */    switch (pChan->baudRate)	{          case 9600:               KS8695P_UART_REG_WRITE(pChan, REG_UART_DIVISOR, UART_BAUD_RATE_9600);               break;          case 19200:               KS8695P_UART_REG_WRITE(pChan, REG_UART_DIVISOR, UART_BAUD_RATE_19200);               break;          case 38400:               KS8695P_UART_REG_WRITE(pChan, REG_UART_DIVISOR, UART_BAUD_RATE_38400);               break;          case 56000:               KS8695P_UART_REG_WRITE(pChan, REG_UART_DIVISOR, UART_BAUD_RATE_56000);               break;          case 115200:               KS8695P_UART_REG_WRITE(pChan, REG_UART_DIVISOR, UART_BAUD_RATE_115200);               break;          default:               KS8695P_UART_REG_WRITE(pChan, REG_UART_DIVISOR, UART_BAUD_RATE_9600);               break;        }     /* Set the FIFO mode (14 bytes length) ,reset the TX & RX FIFO's ,and enable FIFO mode */    KS8695P_UART_REG_WRITE(pChan, REG_UART_FIFO_CTRL, 0);    KS8695P_UART_REG_BIT_SET(pChan, REG_UART_FIFO_CTRL,                                     REG_URFC_URFRT_14 |                                    REG_URFC_ENABLE);    KS8695P_UART_REG_BIT_SET(pChan, REG_UART_FIFO_CTRL,                                     REG_URFC_TX_RST |                                     REG_URFC_RX_RST );     }/********************************************************************************* ks8695pIoctl - special device control** This routine handles the IOCTL messages from the user.** RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed* request.*/LOCAL STATUS ks8695pIoctl    (    SIO_CHAN *	pSioChan,	/* ptr to SIO_CHAN describing this channel */    int		request,	/* request code */    int		arg		/* some argument */    )    {    int		oldlevel;	/* current interrupt level mask */    STATUS	status;		/* status to return */    KS8695P_CHAN * pChan = (KS8695P_CHAN *)pSioChan;    status = OK;	/* preset to return OK */    switch (request)	{	case SIO_BAUD_SET:	    /*	     * Set the baud rate. Return EIO for an invalid baud rate, or	     * OK on success.	     */								    /* disable interrupts during chip access */	    oldlevel = intLock ();	    pChan->baudRate = arg;	    /* Set baud rate divisor in UART */            switch (pChan->baudRate)    	        {                  case 9600:                       KS8695P_UART_REG_WRITE(pChan, REG_UART_DIVISOR, UART_BAUD_RATE_9600);                       break;                  case 19200:                       KS8695P_UART_REG_WRITE(pChan, REG_UART_DIVISOR, UART_BAUD_RATE_19200);                       break;                  case 38400:                       KS8695P_UART_REG_WRITE(pChan, REG_UART_DIVISOR, UART_BAUD_RATE_38400);                       break;                  case 56000:                       KS8695P_UART_REG_WRITE(pChan, REG_UART_DIVISOR, UART_BAUD_RATE_56000);                       break;                  case 115200:                       KS8695P_UART_REG_WRITE(pChan, REG_UART_DIVISOR, UART_BAUD_RATE_115200);                       break;                  default:                       KS8695P_UART_REG_WRITE(pChan, REG_UART_DIVISOR, UART_BAUD_RATE_9600);                       break;                }	    /*	     * Set word format, enable FIFOs: set 8 bits, 1 stop bit, no parity.	     * This also latches the writes to the two (sub)registers above.	     */            KS8695P_UART_REG_WRITE(pChan, REG_UART_LINE_CTRL, 0);            KS8695P_UART_REG_BIT_SET(pChan, REG_UART_LINE_CTRL,REG_URLC_8_BIT); 	    intUnlock (oldlevel);	    break;	case SIO_BAUD_GET:	    /* Get the baud rate and return OK */	    *(int *)arg = pChan->baudRate;	    break; 	case SIO_MODE_SET:	    /*	     * Set the mode (e.g., to interrupt or polled). Return OK	     * or EIO for an unknown or unsupported mode.	     */	    if ((arg != SIO_MODE_POLL) && (arg != SIO_MODE_INT))		{		status = EIO;		break;		}	   	    oldlevel = intLock ();	    if (arg == SIO_MODE_INT)		{		/* Ensure that only Receive ints are generated. */		intEnable (INT_LVL_UTS);		intEnable (INT_LVL_URS);		/*		 * There is no point in enabling the Tx interrupt, as it		 * will interrupt immediately and be disabled.		 */  		}	    else		{		/* Disable all interrupts for this UART. */ 		intDisable (INT_LVL_UTS);		intDisable (INT_LVL_URS);		}	    pChan->channelMode = arg;	    intUnlock (oldlevel);	    break;	    	case SIO_MODE_GET:	    /* Get the current mode and return OK */	    *(int *)arg = pChan->channelMode;	    break;	case SIO_AVAIL_MODES_GET:	    /* Get the available modes and return OK */	    *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL;	    break;	case SIO_HW_OPTS_SET:	    /*	     * Optional command to set the hardware options (as defined	     * in sioLib.h).	     * Return OK, or ENOSYS if this command is not implemented.	     * Note: several hardware options are specified at once.	     * This routine should set as many as it can and then return	     * OK. The SIO_HW_OPTS_GET is used to find out which options	     * were actually set.	     */	case SIO_HW_OPTS_GET:	    /*	     * Optional command to get the hardware options (as defined	     * in sioLib.h). Return OK or ENOSYS if this command is not	     * implemented.  Note: if this command is unimplemented, it	     * will be assumed that the driver options are CREAD | CS8	     * (e.g., eight data bits, one stop bit, no parity, ints enabled).	     */	default:	    status = ENOSYS;	}    return status;    }/********************************************************************************* ks8695pSioIntTx - handle a transmitter interrupt ** This routine handles write interrupts from the UART.** RETURNS: N/A*/void ks8695pSioIntTx     (    KS8695P_CHAN *	pChan	/* ptr to KS8695P_CHAN describing this channel */    )    {    char outChar;    UINT32 isr;    KS8695P_REG_READ (REG_INT_STATUS, isr);    isr &= KS8695P_INT_CSR_MASK;    if ((isr & REG_INT_UT) == 0)       return ;    KS8695P_REG_BIT_CLR (REG_INT_ENABLE, REG_INT_UT);    KS8695P_REG_WRITE(REG_INT_STATUS, REG_INT_UT);    if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR)        {	/* write char. to Transmit Holding Reg. */	KS8695P_UART_REG_WRITE(pChan, REG_UART_TX_HOLDING, outChar);        KS8695P_REG_BIT_SET (REG_INT_ENABLE, REG_INT_UT);        }     else        {        KS8695P_REG_BIT_CLR (REG_INT_ENABLE, REG_INT_UT);        }	        }/******************************************************************************* ks8695pSioIntRx - handle a receiver interrupt ** This routine handles read interrupts from the UART.** RETURNS: N/A*/void ks8695pSioIntRx    (    KS8695P_CHAN *	pChan	/* ptr to KS8695P_CHAN describing this channel */    )    {    char inchar;    UINT32 flags;    BOOL more_data = FALSE;    UINT32 isr;        KS8695P_REG_READ (REG_INT_STATUS, isr);    isr &= KS8695P_INT_CSR_MASK;    if ((isr & REG_INT_UR) == 0)       return ;    KS8695P_REG_BIT_CLR (REG_INT_ENABLE, REG_INT_UR);    KS8695P_REG_WRITE(REG_INT_STATUS, REG_INT_UR);    /* read characters from Receive Holding Reg. */    do	{	/* While RX FIFO isn't empty, we have more data to read */	KS8695P_UART_REG_READ(pChan, REG_UART_LINE_STATUS, flags);	more_data = ( (flags & REG_URLS_RX_DR) != 0);	if (more_data)	    {	    /* Read from data register. */	    KS8695P_UART_REG_READ(pChan, REG_UART_RX_BUFFER, inchar);	    (*pChan->putRcvChar) (pChan->putRcvArg, inchar);	    }	} while (more_data);     KS8695P_REG_BIT_SET (REG_INT_ENABLE, REG_INT_UR);    }/******************************************************************************* ks8695pSioIntErr - handle a uart line error interrupt ** This routine handles read interrupts from the UART.** RETURNS: N/A*/void ks8695pSioIntErr    (    KS8695P_CHAN *	pChan	/* ptr to KS8695P_CHAN describing this channel */    )    {    UINT32 isr;    KS8695P_REG_READ (REG_INT_STATUS, isr);    isr &= KS8695P_INT_CSR_MASK;    if ((isr & REG_INT_ULE) == 0)       return ;    KS8695P_REG_BIT_CLR (REG_INT_ENABLE, REG_INT_ULE);    KS8695P_REG_WRITE(REG_INT_STATUS, REG_INT_ULE);    KS8695P_REG_BIT_SET (REG_INT_ENABLE, REG_INT_ULE);    }/********************************************************************************* ks8695pTxStartup - transmitter startup routine** Enable interrupt so that interrupt-level char output routine will be called.** RETURNS: OK on success, ENOSYS if the device is polled-only, or* EIO on hardware error.*/int ks8695pTxStartup    (    SIO_CHAN *	pSioChan	/* ptr to SIO_CHAN describing this channel */    )    {    KS8695P_CHAN * pChan = (KS8695P_CHAN *)pSioChan;    char outChar;    if (pChan->channelMode == SIO_MODE_INT)	{        if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR)           {	   /* write char. to Transmit Holding Reg. */	   KS8695P_UART_REG_WRITE(pChan, REG_UART_TX_HOLDING, outChar);	   /* intEnable (pChan->levelTx); */	   intEnable (INT_LVL_UTS);           }	return OK;	}    else	return ENOSYS;    }/******************************************************************************** ks8695pPollOutput - output a character in polled mode.** RETURNS: OK if a character arrived, EIO on device error, EAGAIN* if the output buffer is full, ENOSYS if the device is interrupt-only.*/int ks8695pPollOutput    (    SIO_CHAN *	pSioChan,	/* ptr to SIO_CHAN describing this channel */    char	outChar 	/* char to output */    )    {    KS8695P_CHAN * pChan = (KS8695P_CHAN *)pSioChan;    FAST UINT32 pollStatus;    KS8695P_UART_REG_READ(pChan, REG_UART_LINE_STATUS, pollStatus);    /* is the transmitter ready to accept a character? */    if ((pollStatus & REG_URLS_URTE) == 0)	return EAGAIN;    /* write out the character */    KS8695P_UART_REG_WRITE(pChan, REG_UART_TX_HOLDING, outChar);	/* transmit character */    return OK;    }/******************************************************************************** ks8695pPollInput - poll the device for input.** RETURNS: OK if a character arrived, EIO on device error, EAGAIN* if the input buffer is empty, ENOSYS if the device is interrupt-only.*/int ks8695pPollInput    (    SIO_CHAN *	pSioChan,	/* ptr to SIO_CHAN describing this channel */    char *	thisChar	/* pointer to where to return character */    )    {    KS8695P_CHAN * pChan = (KS8695P_CHAN *)pSioChan;    FAST UINT32 pollStatus;    KS8695P_UART_REG_READ(pChan, REG_UART_LINE_STATUS, pollStatus);    if ((pollStatus & REG_URLS_RX_DR) == 0)	return EAGAIN;    /* got a character */    KS8695P_UART_REG_READ(pChan, REG_UART_RX_BUFFER, *thisChar);    return OK;    }/******************************************************************************** ks8695pCallbackInstall - install ISR callbacks to get/put chars.** This routine installs interrupt callbacks for transmitting characters* and receiving characters.** RETURNS: OK on success, or ENOSYS for an unsupported callback type.**/int ks8695pCallbackInstall    (    SIO_CHAN *	pSioChan,	/* ptr to SIO_CHAN describing this channel */    int		callbackType,	/* type of callback */    STATUS	(*callback)(),	/* callback */    void *	callbackArg	/* parameter to callback */		     )    {    KS8695P_CHAN * pChan = (KS8695P_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;	}    }

⌨️ 快捷键说明

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