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

📄 lpc2204sio.c

📁 菲利普22系列 vxworks bsp 可以用来可以和其他版本的ARM vxworks bsp(特别是7内核的进行比较)进行比较可以加深对BSP的理解和掌握
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright 1984-2001 Wind River Systems, Inc. */
#include "copyright_wrs.h"

/*
modification history
--------------------
01o,27jul04,a_m  BSP定制 for 精英arm7开发板
01c,30nov01,m_h  Save pChan->baudRate when setting baud
01b,26apr01,m_h  convert tabs to spaces for readability
01a,12apr01,m_h  created from snds100 template.
*/

#include "vxWorks.h"
#include "sioLib.h"
#include "intLib.h"
#include "errno.h"
#include "lpc2210Sio.h"
#include "ioLib.h"

#define OFFSETRBR   0
#define OFFSETTHR   0
#define OFFSETIER   4
#define OFFSETIIR   8
#define OFFSETFCR   8
#define OFFSETLCR   0x0C
#define OFFSETLSR   0x14
#define OFFSETSCR   0x1C
#define OFFSETDLL   0
#define OFFSETDLM   4

#define UARTRBR(BaseAddress)    (*((volatile unsigned char *)((DWORD)BaseAddress+OFFSETRBR)))
#define UARTTHR(BaseAddress)    (*((volatile unsigned char *)((DWORD)BaseAddress+OFFSETTHR)))
#define UARTIER(BaseAddress)    (*((volatile unsigned char *)((DWORD)BaseAddress+OFFSETIER)))
#define UARTIIR(BaseAddress)    (*((volatile unsigned char *)((DWORD)BaseAddress+OFFSETIIR)))
#define UARTFCR(BaseAddress)    (*((volatile unsigned char *)((DWORD)BaseAddress+OFFSETFCR)))
#define UARTLCR(BaseAddress)    (*((volatile unsigned char *)((DWORD)BaseAddress+OFFSETLCR)))
#define UARTLSR(BaseAddress)    (*((volatile unsigned char *)((DWORD)BaseAddress+OFFSETLSR)))
#define UARTSCR(BaseAddress)    (*((volatile unsigned char *)((DWORD)BaseAddress+OFFSETSCR)))
#define UARTDLL(BaseAddress)    (*((volatile unsigned char *)((DWORD)BaseAddress+OFFSETDLL)))
#define UARTDLM(BaseAddress)    (*((volatile unsigned char *)((DWORD)BaseAddress+OFFSETDLM)))


#define LPC2210_BAUD_MIN         1200
#define LPC2210_BAUD_MAX         460860
#define LPC2210_SIO_DEFAULT_BAUD 9600

/* Hardware abstraction macros */

/* local defines  */

/* for backward compatibility */

/* forward static declarations */

LOCAL int    lpc2210TxStartup (SIO_CHAN * pSioChan);
LOCAL int    lpc2210CallbackInstall (SIO_CHAN *pSioChan, int callbackType,
                                      STATUS (*callback)(), void *callbackArg);
LOCAL int    lpc2210PollOutput (SIO_CHAN *pSioChan, char    outChar);
LOCAL int    lpc2210PollInput (SIO_CHAN *pSioChan, char *thisChar);
LOCAL int    lpc2210Ioctl (SIO_CHAN *pSioChan, int request, void *arg);
LOCAL STATUS dummyCallback (void);

/* local variables */

LOCAL    SIO_DRV_FUNCS lpc2210DrvFuncs =
{
    lpc2210Ioctl,
    lpc2210TxStartup,
    lpc2210CallbackInstall,
    lpc2210PollInput,
    lpc2210PollOutput
};

LOCAL BOOL lpc2210IntrMode = FALSE;    /* interrupt mode allowed flag */

static int g_sending = 0;		/*  : added */	

void lpc2210DevInit
(
    LPC2210_CHAN * pChan
)
{
    /* initialize each channel's driver function pointers */
    pChan->sio.pDrvFuncs    = &lpc2210DrvFuncs;

    /* install dummy driver callbacks */
    pChan->getTxChar     = dummyCallback;
    pChan->putRcvChar    = dummyCallback;
    
    /* reset the chip */
    UARTLCR(pChan->regs) = 0x03;    /* 禁止访问分频因子寄存器且设置为8,1,n */
    UARTFCR(pChan->regs) = 0x87;    /* 初始化FIFO */
    /*UARTFCR(pChan->regs) = 0x06;  */   /* 禁止FIFO */
    UARTIER(pChan->regs) = 0x05;     /* 禁止发送中断,允许接收和状态中断 */

    /* setting polled mode is one way to make the device quiet */
    lpc2210Ioctl ((SIO_CHAN *)pChan, SIO_MODE_SET, (void *)SIO_MODE_POLL);
    lpc2210Ioctl ((SIO_CHAN *)pChan, SIO_BAUD_SET, (void *)LPC2210_SIO_DEFAULT_BAUD);
}

void lpc2210DevInit2
    (
    LPC2210_CHAN * pChan        /* device to initialize */
    )
{
    /* Interrupt mode is allowed */
    lpc2210IntrMode = TRUE;
}

/******************************************************************************
*
* lpc2210UARTInt - handle a channel's interrupt
*
* RETURNS: N/A
*/ 
void lpc2210UARTInt
    (
    LPC2210_CHAN *    pChan        /* channel generating the interrupt */
    )
{
    BYTE byteData;
    DWORD dwIIR;
    DWORD dwIntState;
    FAST int oldlevel;    		/*  : added */
    BYTE temp;
 
    oldlevel = intLock ();			/*  : added */

    dwIIR = UARTIIR(pChan->regs);
    if (dwIIR & 0x1)            /* 没有挂起的中断*/
        return;

    dwIntState = (dwIIR & 0x0E) >> 1;

    switch(dwIntState)
    {
        case 3:             /* 线状态中断*/
            temp = UARTLSR(pChan->regs);
            break;
        case 2:         /* 接收到数据中断*/
        case 6:
            while(UARTLSR(pChan->regs) & 0x01)
            {
                byteData = UARTRBR(pChan->regs);
                (pChan->putRcvChar) (pChan->putRcvArg, byteData);
            }
            break;
        case 1:         /* 发送数据中断*/
            if ((pChan->getTxChar) (pChan->getTxArg, &byteData) != ERROR)
            {
                UARTTHR(pChan->regs) = byteData;
            }	
            else
            {
                temp = UARTIER(pChan->regs);
                temp &= ~0x02;
                UARTIER(pChan->regs) = temp;
                g_sending = 0;
            }
            break;
        default:
            break;
    }	
	
    intUnlock (oldlevel);			/*  : added */
}

	

/******************************************************************************
*
* lpc2210TxStartup - start the interrupt transmitter
*
* RETURNS: OK on success, ENOSYS if the device is polled-only, or
* EIO on hardware error.
*/

LOCAL int lpc2210TxStartup
    (
    SIO_CHAN * pSioChan                 /* channel to start */
    )
{
    char      outChar;			/*  : added */
    FAST int     oldlevel;    	/*  : added */

    LPC2210_CHAN * pChan = (LPC2210_CHAN *)pSioChan;

    if(g_sending == 1)
        return OK;

    oldlevel = intLock ();

    UARTIER(pChan->regs) = UARTIER(pChan->regs) | 0x02;

    g_sending = 1;
    if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR)
        UARTTHR(pChan->regs) = outChar;

    intUnlock (oldlevel);

    return (OK);
}

/******************************************************************************
*
* lpc2210CallbackInstall - install ISR callbacks to get/put chars
*
* This driver allows interrupt callbacks for transmitting characters
* and receiving characters. In general, drivers may support other
* types of callbacks too.
*
* RETURNS: OK on success, or ENOSYS for an unsupported callback type.
*/ 

LOCAL int lpc2210CallbackInstall
    (
    SIO_CHAN *    pSioChan,               /* channel */
    int           callbackType,           /* type of callback */
    STATUS        (*callback)(),          /* callback */
    void *        callbackArg             /* parameter to callback */
    )
    {
    LPC2210_CHAN * pChan = (LPC2210_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);
    }
    }

/*******************************************************************************
*
* lpc2210PollOutput - 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 lpc2210PollOutput
    (
    SIO_CHAN *pSioChan,
    char      outChar
    )
{
    LPC2210_CHAN * pChan = (LPC2210_CHAN *)pSioChan;
    UINT32    status;

    /* is the transmitter ready to accept a character? */

    status = UARTLSR(pChan->regs);
    if ((status & (1<<5)) == 0)
        return (EAGAIN);

    /* write out the character */
    UARTTHR(pChan->regs) = outChar;
    return (OK);
}

/******************************************************************************
*
* lpc2210PollInput - 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.
*/
LOCAL int lpc2210PollInput
    (
    SIO_CHAN *    pSioChan,
    char *        thisChar
    )
{
    LPC2210_CHAN * pChan = (LPC2210_CHAN *)pSioChan;
    UINT32    status;

    status = UARTLSR(pChan->regs);
    if ((status & 1) == 0x00)

⌨️ 快捷键说明

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