?? lpc2204sio.c
字號:
/* 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 + -