📄 shscisio.c
字号:
/* shSciSio.c - Hitachi SH SCI (Serial Communications Interface) driver *//* Copyright 1984-2001 Wind River Systems, Inc. *//*modification history--------------------01i,02nov01,zl corrected NULL usage and callback declaration.01h,16nov00,zl make BRR=0 invalid for baud rate setting.01g,24aug99,zl set initial baud rate01f,01apr99,hk fix for receive overruns in polled mode.01e,30may98,jmb Add support for more data formats.01d,22mar97,hk changed to import sysBaudTable[].01c,10mar97,hk renamed as shSciSio.c from shSio.c. changed function names to shSciAbc(). deleted casting for shSioDrvFuncs' members. changed SH_DUSART to SCI_CHAN and made CPU conditional simple. added SH704X support. fixed shSciIoctl() return value. changed baud-rate save value to arg from brr in shSciIoctl(). also saved default baud-rate in shSciDevInit().01b,07mar97,hk fixed shDevInit() to set SIO_MODE_POLL for reboot failure.01a,16dec96,kn derived from templateSio.c.*//*DESCRIPTIONThis is the driver for the Hitachi SH series on-chip SCI (Serial CommunicationInterface). It uses the SCI in asynchronous mode only.USAGEA SCI_CHAN structure is used to describe the chip. The BSP's sysHwInit() routine typically calls sysSerialHwInit()which initializes all the values in the SCI_CHAN structure (exceptthe SIO_DRV_FUNCS) before calling shSciDevInit().The BSP's sysHwInit2() routine typically calls sysSerialHwInit2(), whichconnects the chips interrupts via intConnect(). INCLUDE FILES: drv/sio/shSciSio.h sioLib.h*/#include "vxWorks.h"#include "sioLib.h"#include "intLib.h"#include "errnoLib.h"#include "drv/sio/shSciSio.h"/* external data */IMPORT SCI_BAUD sysBaudTable[]; /* BSP specific baud-rate constants *//* forward static declarations */static int shSciTxStartup (SIO_CHAN * pSioChan);static int shSciCallbackInstall (SIO_CHAN * pSioChan, int callbackType, STATUS (*callback)(void *, ...), void * callbackArg);static int shSciPollOutput (SIO_CHAN * pSioChan, char outChar);static int shSciPollInput (SIO_CHAN * pSioChan, char * thisChar);static int shSciIoctl (SIO_CHAN * pSioChan, int request, void * arg);LOCAL STATUS shSciOptsSet (SCI_CHAN * pChan, UINT options);static STATUS dummyCallback (void);/* local variables */static SIO_DRV_FUNCS shSioDrvFuncs = { shSciIoctl, shSciTxStartup, shSciCallbackInstall, shSciPollInput, shSciPollOutput };#define SSC_DELAY 100000/******************************************************************************** shSciDevInit - initialize a on-chip serial communication interface** This routine initializes the driver* function pointers and then resets the chip in a quiescent state.* The BSP must have already initialized all the device addresses and the* baudFreq fields in the SCI_CHAN structure before passing it to* this routine.** RETURNS: N/A*/void shSciDevInit ( SCI_CHAN * pChan ) { /* initialize a channel's driver function pointers */ pChan->pDrvFuncs = &shSioDrvFuncs; /* install dummy driver callbacks */ pChan->getTxChar = dummyCallback; pChan->putRcvChar = dummyCallback; /* reset the chip to 8-none-1, no interrupts enabled */ *(pChan->scr) = (UINT8) 0; *(pChan->smr) = (UINT8)(SCI_SMR_ASYNC | SCI_SMR_8_BITS | SCI_SMR_PAR_DIS | SCI_SMR_1_STOP | SCI_SMR_MP_DIS); pChan->options = CS8; /* 8-bit, no parity, one stop bit */ /* set initial baud rate */ shSciIoctl ((SIO_CHAN *)pChan, SIO_BAUD_SET, (void *)pChan->baud); /* setting polled mode is one way to make the device quiet */ shSciIoctl ((SIO_CHAN *)pChan, SIO_MODE_SET, (void *)SIO_MODE_POLL); }/******************************************************************************** shSciIntRcv - handle a channel's receive-character interrupt.** RETURNS: N/A*/ void shSciIntRcv ( SCI_CHAN * pChan /* channel generating the interrupt */ ) { volatile UINT8 ssr = *(pChan->ssr); /* * Grab the input character from the chip and hand it off via a * callback. For chips with input FIFO's it is more efficient * to empty the entire FIFO here. */ if (ssr & SCI_SSR_RDRF) { char inChar = *(pChan->rdr); /* grab the character */ *(pChan->ssr) = ssr & (UINT8)~SCI_SSR_RDRF; /* int acknowledge */ (*(pChan->putRcvChar)) (pChan->putRcvArg, inChar); /* hand it off */ } }/******************************************************************************** shSciIntTx - handle a channels transmitter-ready interrupt.** RETURNS: N/A*/ void shSciIntTx ( SCI_CHAN * pChan /* channel generating the interrupt */ ) { volatile UINT8 ssr = *(pChan->ssr); /* * If there's a character to transmit then write it out, else reset * the transmitter. For chips with output FIFO's it is more efficient * to fill the entire FIFO here. */ if (ssr & SCI_SSR_TDRE) { char outChar; if ((*(pChan->getTxChar)) (pChan->getTxArg, &outChar) != ERROR) { *(pChan->tdr) = outChar; *(pChan->ssr) = ssr & (UINT8)~SCI_SSR_TDRE; /* int acknowledge */ } else { /* no more chars to xmit now. reset the tx int, * so the SCI does not keep interrupting. */ *(pChan->scr) &= (UINT8)~SCI_SCR_TIE; } } }/******************************************************************************** shSciIntErr - handle a channel's error interrupt.** RETURNS: N/A*/ void shSciIntErr ( SCI_CHAN * pChan /* channel generating the interrupt */ ) { volatile UINT8 ssr; ssr = *(pChan->ssr); *(pChan->ssr) = (UINT8) 0; /* reset errors */ }/******************************************************************************** shSciTxStartup - start the interrupt transmitter.** RETURNS: OK on success, ENOSYS if the device is polled-only, or* EIO on hardware error.*/static int shSciTxStartup ( SIO_CHAN * pSioChan /* channel to start */ ) { SCI_CHAN * pChan = (SCI_CHAN *)pSioChan; *(pChan->scr) |= (UINT8)SCI_SCR_TIE; /* only need to enable int */ return (OK); }/******************************************************************************** shSciCallbackInstall - 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.*/ static int shSciCallbackInstall ( SIO_CHAN * pSioChan, /* channel */ int callbackType, /* type of callback */ STATUS (*callback)(void *, ...), /* callback */ void * callbackArg /* parameter to callback */ ) { SCI_CHAN * pChan = (SCI_CHAN *)pSioChan; switch (callbackType) { case SIO_CALLBACK_GET_TX_CHAR: pChan->getTxChar = (STATUS (*)(void *, char *))callback; pChan->getTxArg = callbackArg; return (OK); case SIO_CALLBACK_PUT_RCV_CHAR: pChan->putRcvChar = (STATUS (*)(void *, char *))callback; pChan->putRcvArg = callbackArg; return (OK); default: return (ENOSYS); } }/******************************************************************************** shSciPollOutput - 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.*/static int shSciPollOutput ( SIO_CHAN * pSioChan, char outChar ) { SCI_CHAN * pChan = (SCI_CHAN *)pSioChan; volatile UINT8 ssr = *(pChan->ssr ); /* is the transmitter ready to accept a character? */ if ((ssr & (UINT8)SCI_SSR_TDRE) == 0x00) return (EAGAIN); /* write out the character */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -