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

📄 ks8695sio.c

📁 这是micrel公司宽带路由ARM9芯片的VXWORKS BSP 源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ks8695Sio.c - KS8695/P/X UART tty driver */

/*
modification history
--------------------
11/13/2003  LIQUN RUAN (RLQ) modified for KS8695/X
09/22/2003  Ritter Yeh  created 
*/

#include "vxWorks.h"
#include <stdio.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)
    {
    printf("%s\n", __FUNCTION__);
    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:

⌨️ 快捷键说明

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