📄 shscifsio.c
字号:
/* shScifSio.c - Hitachi SH SCIF (Serial Communications Interface) driver *//* Copyright 1984-2001 Wind River Systems, Inc. *//*modification history--------------------01h,06mar02,h_k added clear overrun error for SH7615, SH7750 and SH7751 SCIF (SPR #73777).01g,02nov01,zl corrected NULL usage and callback declaration.01f,16nov00,zl make BRR=0 invalid for baud rate setting.01e,24aug99,zl set initial baud rate01d,29dec98,hk changed to use smr/scr/fcr size macros for SH7750.01c,12aug98,jmb debugged, use FIFOs at max triggering level.01b,10aug98,jmb completed.01a,31may98,jmb derived from shScifSio.c.*//*DESCRIPTIONThis is the driver for the Hitachi SH series on-chip SCIF (Serial CommunicationInterface with FIFO). It uses the SCIF in asynchronous mode only.USAGEA SCIF_CHAN structure is used to describe the chip. The BSP's sysHwInit() routine typically calls sysSerialHwInit()which initializes all the values in the SCIF_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 drv/sio/shScifSio.h sioLib.h*/#include "vxWorks.h"#include "sioLib.h"#include "intLib.h"#include "errnoLib.h"#include "drv/sio/shScifSio.h"/* external data */IMPORT SCI_BAUD sysBaudTable[]; /* BSP specific baud-rate constants *//* forward static declarations */static int shScifTxStartup (SIO_CHAN * pSioChan);static int shScifCallbackInstall (SIO_CHAN * pSioChan, int callbackType, STATUS (*callback)(void *, ...), void * callbackArg);static int shScifPollOutput (SIO_CHAN * pSioChan, char outChar);static int shScifPollInput (SIO_CHAN * pSioChan, char * thisChar);static int shScifIoctl (SIO_CHAN * pSioChan, int request, void * arg);LOCAL STATUS shScifOptsSet (SCIF_CHAN * pChan, UINT options);static STATUS dummyCallback (void);/* local variables */static SIO_DRV_FUNCS shSioDrvFuncs = { shScifIoctl, shScifTxStartup, shScifCallbackInstall, shScifPollInput, shScifPollOutput };#define SSC_DELAY 100000/******************************************************************************** shScifDevInit - 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 SCIF_CHAN structure before passing it to* this routine.** RETURNS: N/A*/void shScifDevInit ( SCIF_CHAN * pChan ) { /* initialize a channel's driver function pointers */ pChan->pDrvFuncs = &shSioDrvFuncs; /* install dummy driver callbacks */ pChan->getTxChar = dummyCallback; pChan->putRcvChar = dummyCallback; /* Clear and disable the FIFOs */ *(pChan->fcr2) |= (SZ_FCR2) (SCIF_FCR2_TFRST | SCIF_FCR2_RFRST); /* Set the FIFO depth to maximum value */ *(pChan->fcr2) |= (SZ_FCR2) (SCIF_FCR2_RTRG | SCIF_FCR2_TTRG); /* reset the chip to 8-none-1, no interrupts enabled */ *(pChan->scr2) &= 0x3; /* Keep clock bits */ *(pChan->smr2) &= 0x3; /* Keep clock bits */ *(pChan->smr2) |= (SZ_SMR2)(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 */ shScifIoctl ((SIO_CHAN *)pChan, SIO_BAUD_SET, (void *)pChan->baud); /* setting polled mode is one way to make the device quiet */ shScifIoctl ((SIO_CHAN *)pChan, SIO_MODE_SET, (void *)SIO_MODE_POLL); }/******************************************************************************** shScifIntRcv - handle a channel's receive-character interrupt.** RETURNS: N/A*/ void shScifIntRcv ( SCIF_CHAN * pChan /* channel generating the interrupt */ ) { int rcvCount; char inChar; volatile UINT16 ssr = *(pChan->ssr2); /* Get number of bytes in FIFO * The low five bits of the FIFO data register contain the * receive count. */ rcvCount = *(pChan->fdr2) & 0x1f; /* * Empty the receive FIFO a character at a time. */ while (rcvCount--) { inChar = *(pChan->frdr2); /* grab the character */ (*(pChan->putRcvChar)) (pChan->putRcvArg, inChar); /* hand it off */ } /* Acknowledge the interrupt by clearing the receive-data-fifo full bit */ *(pChan->ssr2) = ssr & (UINT16) ~(SCIF_SSR2_RDF | SCIF_SSR2_DR); }/******************************************************************************** shScifIntTx - handle a channels transmitter-ready interrupt.** RETURNS: N/A*/ void shScifIntTx ( SCIF_CHAN * pChan /* channel generating the interrupt */ ) { char outChar; UINT count; volatile UINT16 ssr = *(pChan->ssr2); /* * If there's a character to transmit then write it out, else reset * the transmitter. Keep writing characters until the ring buffer * is empty or the FIFO is full. */ if (ssr & SCIF_SSR2_TDFE) { count = SCIF_FIFO_LEN - ((*(pChan->fdr2) >> 8) & 0x0ff); while (count--) { if ((*(pChan->getTxChar)) (pChan->getTxArg, &outChar) != ERROR) { *(pChan->sfdr2) = outChar; } else { /* no more chars to xmit now. reset the tx int, * so the SCI does not keep interrupting. */ *(pChan->scr2) &= (SZ_SCR2)~SCI_SCR_TIE; break; } } *(pChan->ssr2) = ssr & (UINT16)~SCIF_SSR2_TDFE; } }/******************************************************************************** shScifIntErr - handle a channel's error interrupt.** RETURNS: N/A*/ void shScifIntErr ( SCIF_CHAN * pChan /* channel generating the interrupt */ ) { volatile UINT16 ssr; char dummy; ssr = *(pChan->ssr2); if (ssr & SCIF_SSR2_DR) dummy = *(pChan->frdr2); /* Read stray data */ *(pChan->ssr2) = (UINT16) NULL; /* reset errors */ if (pChan->lsr2 != NULL) { if (*pChan->lsr2 & (UINT16)SCIF_LSR2_ORER) *pChan->lsr2 &= ~(UINT16)SCIF_LSR2_ORER; /* clear overrun error */ } if (pChan->ss2r2 != NULL) { if (*pChan->ss2r2 & (UINT8)SCIF_SS2R2_ORER) *pChan->ss2r2 &= ~(UINT8)SCIF_SS2R2_ORER; /* clear overrun error */ } }/******************************************************************************** shScifTxStartup - start the interrupt transmitter.** RETURNS: OK on success, ENOSYS if the device is polled-only, or* EIO on hardware error.*/static int shScifTxStartup ( SIO_CHAN * pSioChan /* channel to start */ ) { SCIF_CHAN * pChan = (SCIF_CHAN *)pSioChan; *(pChan->scr2) |= (SZ_SCR2)SCI_SCR_TIE; /* only need to enable int */ return (OK); }/******************************************************************************** shScifCallbackInstall - 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 shScifCallbackInstall ( SIO_CHAN * pSioChan, /* channel */ int callbackType, /* type of callback */ STATUS (*callback)(void *, ...), /* callback */ void * callbackArg /* parameter to callback */ ) { SCIF_CHAN * pChan = (SCIF_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); } }/******************************************************************************** shScifPollOutput - 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 shScifPollOutput
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -