📄 shscisio.c
字号:
*(pChan->tdr) = outChar; *pChan->ssr = ssr & (UINT8)~SCI_SSR_TDRE; return (OK); }/******************************************************************************** shSciPollInput - 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 shSciPollInput ( SIO_CHAN * pSioChan, char * thisChar /* where to put the input character */ ) { SCI_CHAN * pChan = (SCI_CHAN *)pSioChan; volatile UINT8 ssr = *(pChan->ssr); /* If a receive overrun condition is set, the SCI does not receive * any more characters. Since it is likely to happen in polling * mode, we have to check and clear the overrun status. */ if (ssr & SCI_SSR_ORER) *(pChan->ssr) = ssr & (UINT8)~SCI_SSR_ORER; if ((ssr & SCI_SSR_RDRF) == 0x00) return (EAGAIN); /* got a character */ *thisChar = *(pChan->rdr); *pChan->ssr = ssr & (UINT8)~SCI_SSR_RDRF; return (OK); }/******************************************************************************** shSciModeSet - toggle between interrupt and polled mode.** RETURNS: OK on success, EIO on unsupported mode.*/static int shSciModeSet ( SCI_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->scr) = (UINT8)(SCI_SCR_RIE | SCI_SCR_TXE | SCI_SCR_RXE); else *(pChan->scr) = (UINT8)(SCI_SCR_TXE | SCI_SCR_RXE); intUnlock (oldlevel); /* UNLOCK INTERRUPTS */ return (OK); }/********************************************************************************* shSciIoctl - special device control** RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed* request.*/static int shSciIoctl ( SIO_CHAN * pSioChan, /* channel to control */ int request, /* request code */ void * someArg /* some argument */ ) { SCI_CHAN * pChan = (SCI_CHAN *)pSioChan; int oldlevel, delay; UINT8 oldScr, 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->scr); /* save old scr */ *(pChan->scr) = (UINT8) 0; *(pChan->smr) = (UINT8)((*(pChan->smr) & SCI_SMR_CKS_MASK) | cks); *(pChan->brr) = (UINT8)brr; pChan->baud = arg; for (delay = 0; delay < (SSC_DELAY / arg); delay++) delay = delay; /* spin wheels for a moment */ *(pChan->scr) = 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 (shSciModeSet (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 = shSciOptsSet (pChan, arg); if (pChan->baud) for (delay = 0; delay < (SSC_DELAY / pChan->baud); delay++) delay = delay; /* spin wheels for a moment */ shSciModeSet (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); }/********************************************************************************* shSciOptsSet - set the serial options** Set the channel operating mode to that specified. These sioLib options* are supported: CSIZE (CS7 and CS8), PARENB, and PARODD.** The unsupported options are CREAD and CLOCAL. CLOCAL is ignored because* SCI does not have hardware flow control. CREAD is also ignored. The* routine to turn on serial I/O is shSciModeSet().** Note, this routine disables all serial interrupts. To re-enable* serial communication, the caller should use shSciModeSet().** RETURNS:* Returns OK to indicate success. ERROR is returned if a bad arg is* detected. ENOSYS is returned for an unsupported option.*/LOCAL STATUS shSciOptsSet ( SCI_CHAN * pChan, /* ptr to channel */ UINT options /* new hardware options */ ) { /* Retain last two bits of serial mode register. These form the * peripheral clock divisor. */ UINT8 smrValue = *(pChan->smr) & 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->scr) &= 0x03; /* Disable xmit, receiver, and all interrupts */ *(pChan->smr) = smrValue; /* Reset data format */ *(pChan->scr) |= (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 + -