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