📄 scih8.c
字号:
if (brr > 0xff) { cks = 2; brr = ((NutGetCpuClock() / (64UL * 8UL)) / *lvp) - 1; if (brr > 0xff) { cks = 3; brr = ((NutGetCpuClock() / (64UL * 32UL)) / *lvp) - 1; } } } sci->SMR.BIT.CKS = cks; sci->BRR = (u_char) brr; dcb->dcb_baudSelect = brr; NutDelay(2); /* wait for a while */ SciH8Enable(devnum); break; case UART_GETSPEED: switch (sci->SMR.BIT.CKS) { case 0: *lvp = NutGetCpuClock() / ((64UL / 2UL) * (u_long) (sci->BRR + 1)); break; case 1: *lvp = NutGetCpuClock() / ((64UL * 2UL) * (u_long) (sci->BRR + 1)); break; case 2: *lvp = NutGetCpuClock() / ((64UL * 8UL) * (u_long) (sci->BRR + 1)); break; case 3: *lvp = NutGetCpuClock() / ((64UL * 32UL) * (u_long) (sci->BRR + 1)); break; } break; case UART_SETDATABITS: SciH8Disable(devnum); switch (bv) { case 8: /* 8 data bits */ sci->SMR.BIT.CHR = 0; break; case 7: /* 7 data bits */ sci->SMR.BIT.CHR = 1; break; default: rc = -1; } SciH8Enable(devnum); break; case UART_GETDATABITS: switch (sci->SMR.BIT.CHR) { case 0: /* 8 data bits */ *lvp = 8; break; case 1: /* 7 data bits */ *lvp = 7; break; } break; case UART_SETPARITY: SciH8Disable(devnum); switch (bv) { case 'n': /* none */ sci->SMR.BIT.PE = 0; break; case 'e': /* even */ sci->SMR.BIT.PE = 1; sci->SMR.BIT.OE = 0; break; case 'o': /* odd */ sci->SMR.BIT.PE = 1; sci->SMR.BIT.OE = 1; break; default: rc = -1; } SciH8Enable(devnum); break; case UART_GETPARITY: if (sci->SMR.BIT.PE == 0) { /* none */ bv = 'n'; } else if (sci->SMR.BIT.OE == 0) { /* even */ bv = 'e'; } else { /* odd */ bv = 'o'; } break; case UART_SETSTOPBITS: SciH8Disable(devnum); switch (bv) { case 1: /* 1 stop bit */ sci->SMR.BIT.STOP = 0; break; case 2: /* 2 stop bits */ sci->SMR.BIT.STOP = 1; break; default: rc = -1; } SciH8Enable(devnum); break; case UART_GETSTOPBITS: switch (sci->SMR.BIT.STOP) { case 0: /* 1 stop bit */ *lvp = 1; break; case 1: /* 2 stop bits */ *lvp = 2; break; } break; case UART_GETSTATUS: SciH8GetStatus(dev, lvp); break; case UART_SETSTATUS: rc = -1; break; case UART_SETREADTIMEOUT: dcb->dcb_rtimeout = lv; break; case UART_GETREADTIMEOUT: *lvp = dcb->dcb_rtimeout; break; case UART_SETWRITETIMEOUT: dcb->dcb_wtimeout = lv; break; case UART_GETWRITETIMEOUT: *lvp = dcb->dcb_wtimeout; break; case UART_SETLOCALECHO: if (bv) dcb->dcb_modeflags |= UART_MF_LOCALECHO; else dcb->dcb_modeflags &= ~UART_MF_LOCALECHO; break; case UART_GETLOCALECHO: if (dcb->dcb_modeflags & UART_MF_LOCALECHO) *lvp = 1; else *lvp = 0; break; case UART_SETFLOWCONTROL: if (bv) dcb->dcb_modeflags |= UART_MF_LOCALECHO; else dcb->dcb_modeflags &= ~UART_MF_LOCALECHO; break; case UART_GETFLOWCONTROL: break; case UART_SETCOOKEDMODE: if (bv) dcb->dcb_modeflags |= UART_MF_COOKEDMODE; else dcb->dcb_modeflags &= ~UART_MF_COOKEDMODE; break; case UART_GETCOOKEDMODE: if (dcb->dcb_modeflags & UART_MF_COOKEDMODE) *lvp = 1; else *lvp = 0; break; default: rc = -1; break; } return rc;}/*! * \brief Initialize on chip uart device. * * Prepares the device for subsequent reading or writing. * Enables SCI transmitter and receiver interrupts. * * \param dev Identifies the device to initialize. * * \return 0 on success, -1 otherwise. */int SciH8Init(NUTDEVICE * dev){ IFSTREAM *ifs; UARTDCB *dcb; u_long baudrate = 9600; volatile struct st_sci *sci = GET_SCI(dev->dev_base); /* * We only support character devices for on-chip SCIs. */ if (dev->dev_type != IFTYP_STREAM || dev->dev_irq != 0 || (dev->dev_base != 0 && dev->dev_base != 1 && dev->dev_base != 2)) return -1; /* * Initialize interface control block. */ ifs = dev->dev_icb; memset(ifs, 0, sizeof(IFSTREAM)); ifs->if_input = SciH8Input; ifs->if_output = SciH8Output; ifs->if_flush = SciH8Flush; /* * Initialize driver control block. */ dcb = dev->dev_dcb; memset(dcb, 0, sizeof(UARTDCB));/* dcb->dcb_baudSelect = 7; */ dcb->dcb_modeflags = UART_MF_NOBUFFER; /* * Register interrupt handler. */ if (dev->dev_base == 2) { if (NutRegisterIrqHandler(&sig_RXI2, RxComplete, dev)) return -1; if (NutRegisterIrqHandler(&sig_TXI2, TxComplete, dev)) return -1; } else if (dev->dev_base == 1) { if (NutRegisterIrqHandler(&sig_RXI1, RxComplete, dev)) return -1; if (NutRegisterIrqHandler(&sig_TXI1, TxComplete, dev)) return -1; } else if (dev->dev_base == 0) { if (NutRegisterIrqHandler(&sig_RXI0, RxComplete, dev)) return -1; if (NutRegisterIrqHandler(&sig_TXI0, TxComplete, dev)) return -1; } sci->SCR.BYTE = 0; /* Set for Async, data bits, parity, stop bit and an undivided clock. */ sci->SMR.BYTE = DATABITS_8 | NOPARITY | STOP1BIT | NODIVIDE; /* Clear relevant status bits. */ sci->SSR.BYTE = ~(PER | FER | ORER | RDRF); sci->SCR.BYTE = (RXI_ENABLE | RX_ENABLE | TX_ENABLE); /* * Set baudrate and handshake default. This will also * enable the UART functions. */ SciH8IOCtl(dev, UART_SETSPEED, &baudrate); return 0;}/*! * \brief Read from device. */int SciH8Read(NUTFILE * fp, void *buffer, int size){ int rc; NUTDEVICE *dev; IFSTREAM *ifs; UARTDCB *dcb; u_char elmode; u_char ch; u_char *cp = buffer; dev = fp->nf_dev; ifs = (IFSTREAM *) dev->dev_icb; dcb = dev->dev_dcb; if (dcb->dcb_modeflags & UART_MF_COOKEDMODE) elmode = 1; else elmode = 0; /* * Call without data pointer discards receive buffer. */ if (buffer == 0) { ifs->if_rd_idx = ifs->if_rx_idx; return 0; } /* * Get characters from receive buffer. */ for (rc = 0; rc < size;) { if (ifs->if_rd_idx == ifs->if_rx_idx) { if (rc) break; while (ifs->if_rd_idx == ifs->if_rx_idx) { if (SciH8Input(dev)) { return 0; } } } ch = ifs->if_rx_buf[ifs->if_rd_idx++]; if (elmode && (ch == '\r' || ch == '\n')) { if (ifs->if_last_eol == 0 || ifs->if_last_eol == ch) { ifs->if_last_eol = ch; *cp++ = '\n'; rc++; } } else { ifs->if_last_eol = 0; *cp++ = ch; rc++; } } return rc;}/*! * \brief Write to device. */int SciH8Put(NUTDEVICE * dev, CONST void *buffer, int len, int pflg){ int rc; IFSTREAM *ifs; UARTDCB *dcb; CONST u_char *cp; u_char lbmode; u_char elmode; u_char ch; ifs = dev->dev_icb; dcb = dev->dev_dcb; if (dcb->dcb_modeflags & UART_MF_LINEBUFFER) lbmode = 1; else lbmode = 0; if (dcb->dcb_modeflags & UART_MF_COOKEDMODE) elmode = 1; else elmode = 0; /* * Call without data pointer starts transmission. */ if (buffer == 0) { rc = SciH8Flush(dev); return rc; } /* * Put characters in transmit buffer. */ cp = buffer; for (rc = 0; rc < len;) { if ((u_char) (ifs->if_wr_idx + 1) == ifs->if_tx_idx) { if (SciH8Flush(dev)) { return -1; } } ch = pflg ? PRG_RDB(cp) : *cp; if (elmode == 1 && ch == '\n') { elmode = 2; if (lbmode == 1) lbmode = 2; ch = '\r'; } else { if (elmode == 2) elmode = 1; cp++; rc++; } ifs->if_tx_buf[ifs->if_wr_idx++] = ch; } if (lbmode > 1 || (dcb->dcb_modeflags & UART_MF_NOBUFFER) != 0) { if (SciH8Flush(dev)) rc = -1; } return rc;}int SciH8Write(NUTFILE * fp, CONST void *buffer, int len){ return SciH8Put(fp->nf_dev, buffer, len, 0);}/*! * \brief Open a device or file. */NUTFILE *SciH8Open(NUTDEVICE * dev, CONST char *name, int mode, int acc){ NUTFILE *fp = NutHeapAlloc(sizeof(NUTFILE)); UARTDCB *dcb; if (fp == 0) return NUTFILE_EOF; dcb = dev->dev_dcb; if (mode & _O_BINARY) dcb->dcb_modeflags &= ~UART_MF_COOKEDMODE; else dcb->dcb_modeflags |= UART_MF_COOKEDMODE; fp->nf_next = 0; fp->nf_dev = dev; fp->nf_fcb = 0; return fp;}/*! * \brief Close a device or file. */int SciH8Close(NUTFILE * fp){ NutHeapFree(fp); return 0;}/*@}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -