📄 shscifsio.c
字号:
( SIO_CHAN * pSioChan, char outChar ) { SCIF_CHAN * pChan = (SCIF_CHAN *)pSioChan; volatile UINT16 ssr = *(pChan->ssr2); /* is the transmitter ready to accept a character? */ if ((ssr & (UINT8)SCIF_SSR2_TDFE) == 0x00) return (EAGAIN); /* write out the character */ *(pChan->sfdr2) = outChar; *(pChan->ssr2) = ssr & (UINT16)~SCIF_SSR2_TDFE; return (OK); }/******************************************************************************** shScifPollInput - 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.*/static int shScifPollInput ( SIO_CHAN * pSioChan, char * thisChar /* where to put the input character */ ) { SCIF_CHAN * pChan = (SCIF_CHAN *)pSioChan; volatile UINT16 ssr = *(pChan->ssr2); if ((ssr & SCIF_SSR2_RDF) == 0x00) if ((ssr & SCIF_SSR2_DR) == 0x00) return (EAGAIN); /* got a character */ *thisChar = *(pChan->frdr2); *(pChan->ssr2) = ssr & (UINT16) ~(SCIF_SSR2_RDF | SCIF_SSR2_DR); return (OK); }/******************************************************************************** shScifModeSet - toggle between interrupt and polled mode.** RETURNS: OK on success, EIO on unsupported mode.*/static int shScifModeSet ( SCIF_CHAN * pChan, /* channel */ uint_t newMode /* new mode */ ) { int oldlevel; if ((newMode != SIO_MODE_POLL) && (newMode != SIO_MODE_INT)) return (EIO); oldlevel = intLock (); /* LOCK INTERRUPTS */ pChan->mode = newMode; /* set the new mode */ if (pChan->mode == SIO_MODE_INT) *(pChan->scr2) = (SZ_SCR2)(SCI_SCR_RIE | SCI_SCR_TXE | SCI_SCR_RXE); else *(pChan->scr2) = (SZ_SCR2)(SCI_SCR_TXE | SCI_SCR_RXE); intUnlock (oldlevel); /* UNLOCK INTERRUPTS */ return (OK); }/********************************************************************************* shScifIoctl - special device control** RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed* request.*/static int shScifIoctl ( SIO_CHAN * pSioChan, /* channel to control */ int request, /* request code */ void * someArg /* some argument */ ) { SCIF_CHAN * pChan = (SCIF_CHAN *)pSioChan; int oldlevel, delay; SZ_SCR2 oldScr; UINT8 cks, brr; STATUS result; int arg = (int)someArg; switch (request) { case SIO_BAUD_SET: /* * Set the baud rate. Return EIO for an invalid baud rate, or * OK on success. */ { int ix, status; for (status = EIO, cks = 0, brr = 0, ix = 0; sysBaudTable[ix].rate != 0; ix++) { if (sysBaudTable[ix].rate == arg) { cks = sysBaudTable[ix].cksVal; /* clock select bits */ brr = sysBaudTable[ix].brrVal; /* bit rate */ status = OK; break; } } if (status == EIO) return (status); /* * Although the zero value for BRR may be aceptable in rare * occasions, we use it as invalid value - for example when the * calculated value overflows (larger than 255). */ if (brr == 0) return (EIO); } oldlevel = intLock (); /* LOCK INTERRUPTS */ oldScr = *(pChan->scr2); /* save old scr */ *(pChan->scr2) = (SZ_SCR2) 0; *(pChan->fcr2) |= (SZ_FCR2) (SCIF_FCR2_TFRST | SCIF_FCR2_RFRST); *(pChan->smr2) = (SZ_SMR2)((*(pChan->smr2) & SCI_SMR_CKS_MASK)|cks); *(pChan->brr2) = (UINT8)brr; pChan->baud = arg; for (delay = 0; delay < (SSC_DELAY / arg); delay++) delay = delay; /* spin wheels for a moment */ *(pChan->fcr2) &= (SZ_FCR2) ~(SCIF_FCR2_TFRST | SCIF_FCR2_RFRST); *(pChan->scr2) = oldScr; /* restore scr */ intUnlock (oldlevel); /* UNLOCK INTERRUPTS */ return (OK); case SIO_BAUD_GET: /* Get the baud rate and return OK */ *(int *)arg = pChan->baud; return (OK); case SIO_MODE_SET: /* * Set the mode (e.g., to interrupt or polled). Return OK * or EIO for an unknown or unsupported mode. */ return (shScifModeSet (pChan, arg)); case SIO_MODE_GET: /* * Get the current mode and return OK. */ *(int *)arg = pChan->mode; return (OK); case SIO_AVAIL_MODES_GET: /* * Get the available modes and return OK. */ *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL; return (OK); case SIO_HW_OPTS_SET: /* change options, then set mode to restart chip correctly */ result = shScifOptsSet (pChan, arg); if (pChan->baud) for (delay = 0; delay < (SSC_DELAY / pChan->baud); delay++) delay = delay; /* spin wheels for a moment */ shScifModeSet (pChan, pChan->mode); return (result); case SIO_HW_OPTS_GET: *(int *)arg = pChan->options; return (OK); default: return (ENOSYS); } }/********************************************************************************* dummyCallback - dummy callback routine.** RETURNS: ERROR.*/STATUS dummyCallback (void) { return (ERROR); }/********************************************************************************* shScifOptsSet - set the serial options** Set the channel operating mode to that specified. These sioLib options* are supported: CLOCAL, CSIZE (CS7 and CS8), PARENB, and PARODD.** One unsupported options is CREAD. The routine* to turn on serial I/O is shScifModeSet().** Note, this routine disables all serial interrupts. To re-enable* serial communication, the caller should use shScifModeSet().** RETURNS:* Returns OK to indicate success. ERROR is returned if a bad arg is* detected. ENOSYS is returned for an unsupported option.*/LOCAL STATUS shScifOptsSet ( SCIF_CHAN * pChan, /* ptr to channel */ UINT options /* new hardware options */ ) { /* Retain last two bits of serial mode register. These form the * peripheral clock divisor. */ SZ_SMR2 smrValue = *(pChan->smr2) & 0x3; int lvl; if (pChan == NULL) return (ERROR); /* Set the data format. SCI supports even/odd parity, 1/2 stop bits, * and 7/8 bit characters. */ switch (options & CSIZE) { case CS5: case CS6: return (ENOSYS); break; case CS7: smrValue |= SCI_SMR_7_BITS; /* 7-bit data */ break; case CS8: default: smrValue &= ~SCI_SMR_7_BITS; /* 8-bit data */ break; } if (options & STOPB) smrValue |= SCI_SMR_2_STOP; /* 2 stop bits */ else smrValue &= ~SCI_SMR_2_STOP; /* 1 stop bit */ switch (options & (PARENB|PARODD)) { case (PARENB|PARODD): case PARODD: smrValue |= SCI_SMR_PAR_EN; /* parity enabled */ smrValue |= SCI_SMR_PAR_ODD; /* parity odd */ break; case PARENB: smrValue |= SCI_SMR_PAR_EN; /* parity enabled */ smrValue &= ~SCI_SMR_PAR_ODD; /* parity even */ break; default: case 0: smrValue &= ~SCI_SMR_PAR_EN; /* parity disabled */ break; } lvl = intLock (); /* LOCK INTERRUPTS */ /* * Set the hardware registers */ *(pChan->scr2) &= 0x03; /* Disable xmit, receiver, and all interrupts */ *(pChan->smr2) = smrValue; /* Reset data format */ if (options & CLOCAL) *(pChan->fcr2) &= ~SCIF_FCR2_MCE; /* Turn off h/w flow control */ else *(pChan->fcr2) |= SCIF_FCR2_MCE; /* Turn on h/w flow control */ *(pChan->scr2) |= (SCI_SCR_TXE | SCI_SCR_RXE); /* Turn on xmit, recv */ intUnlock (lvl); /* UNLOCK INTERRUPTS */ pChan->options = options; return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -