z8_serial.c
来自「這是一個實時嵌入式作業系統 實作了MCS51 ARM等MCU」· C语言 代码 · 共 866 行 · 第 1/2 页
C
866 行
* RX and TX interrupts are not enabled when by the attach method (unless the * hardware supports multiple levels of interrupt enabling). The RX and TX * interrupts are not enabled until the txint() and rxint() methods are called. * ****************************************************************************/static int z8_attach(FAR struct uart_dev_s *dev){ struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; int ret; /* Attach the RX IRQ */ ret = irq_attach(priv->rxirq, z8_rxinterrupt); if (ret == OK) { /* Attach the TX IRQ */ ret = irq_attach(priv->txirq, z8_txinterrupt); if (ret != OK) { irq_detach(priv->rxirq); } } return ret;}/**************************************************************************** * Name: z8_detach * * Description: * Detach UART interrupts. This method is called when the serial port is * closed normally just before the shutdown method is called. The exception is * the serial console which is never shutdown. * ****************************************************************************/static void z8_detach(FAR struct uart_dev_s *dev){ struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; up_disable_irq(priv->rxirq); up_disable_irq(priv->txirq); irq_detach(priv->rxirq); irq_detach(priv->txirq);}/**************************************************************************** * Name: z8_rxinterrupt * * Description: * This is the UART interrupt handler. It will be invoked when an RX * event occurs at the z8's LIN-UART. * ****************************************************************************/static int z8_rxinterrupt(int irq, FAR void *context){ struct uart_dev_s *dev = NULL; struct z8_uart_s *priv; ubyte status; if (g_uart1priv.rxirq == irq) { dev = &g_uart1port; } else if (g_uart0priv.rxirq == irq) { dev = &g_uart0port; } else { PANIC(OSERR_INTERNAL); } priv = (struct z8_uart_s*)dev->priv; /* Check the LIN-UART status 0 register to determine whether the source of * the interrupt is error, break, or received data */ status = z8_getuart(priv, Z8_UART_STAT0); /* REVISIT error and break handling */ /* Check if received data is available */ if (status & Z8_UARTSTAT0_RDA) { /* Handline an incoming, receive byte */ uart_recvchars(dev); } return OK;}/**************************************************************************** * Name: z8_txinterrupt * * Description: * This is the UART TX interrupt handler. This interrupt handler will * be invoked when the X16F LIN UART transmit data register is empty. * ****************************************************************************/static int z8_txinterrupt(int irq, FAR void *context){ struct uart_dev_s *dev = NULL; struct z8_uart_s *priv; ubyte status; if (g_uart1priv.txirq == irq) { dev = &g_uart1port; } else if (g_uart0priv.txirq == irq) { dev = &g_uart0port; } else { PANIC(OSERR_INTERNAL); } priv = (struct z8_uart_s*)dev->priv; /* Verify that the transmit data register is empty */ status = z8_getuart(priv, Z8_UART_STAT0); if (status & Z8_UARTSTAT0_TDRE) { /* Handle outgoing, transmit bytes */ uart_xmitchars(dev); } return OK;}/**************************************************************************** * Name: z8_ioctl * * Description: * All ioctl calls will be routed through this method * ****************************************************************************/static int z8_ioctl(FAR struct file *filep, int cmd, unsigned long arg){ *get_errno_ptr() = ENOTTY; return ERROR;}/**************************************************************************** * Name: z8_receive * * Description: * Called (usually) from the interrupt level to receive one character from * the UART. Error bits associated with the receipt are provided in the * return 'status'. * ****************************************************************************/static int z8_receive(FAR struct uart_dev_s *dev, FAR uint32 *status){ struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; ubyte rxd; ubyte stat0; rxd = z8_getuart(priv, Z8_UART_RXD); stat0 = z8_getuart(priv, Z8_UART_STAT0); *status = (uint32)rxd | (((uint32)stat0) << 8); return rxd;}/**************************************************************************** * Name: z8_rxint * * Description: * Call to enable or disable RX interrupts * ****************************************************************************/static void z8_rxint(FAR struct uart_dev_s *dev, boolean enable){ struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; irqstate_t flags = irqsave(); if (enable) {#ifndef CONFIG_SUPPRESS_SERIAL_INTS up_enable_irq(priv->rxirq);#endif } else { up_disable_irq(priv->rxirq); } priv->rxenabled = enable; irqrestore(flags);}/**************************************************************************** * Name: z8_rxavailable * * Description: * Return TRUE if the receive fifo is not empty * ****************************************************************************/static boolean z8_rxavailable(FAR struct uart_dev_s *dev){ struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; return ((z8_getuart(priv, Z8_UART_STAT0) & Z8_UARTSTAT0_RDA) != 0);}/**************************************************************************** * Name: z8_send * * Description: * This method will send one byte on the UART * ****************************************************************************/static void z8_send(FAR struct uart_dev_s *dev, int ch){ struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; z8_putuart(priv, ch, Z8_UART_TXD);}/**************************************************************************** * Name: z8_txint * * Description: * Call to enable or disable TX interrupts * ****************************************************************************/static void z8_txint(FAR struct uart_dev_s *dev, boolean enable){ struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; irqstate_t flags = irqsave(); if (enable) {#ifndef CONFIG_SUPPRESS_SERIAL_INTS up_enable_irq(priv->txirq);#endif } else { up_disable_irq(priv->txirq); } priv->txenabled = enable; irqrestore(flags);}/**************************************************************************** * Name: z8_txready * * Description: * Return TRUE if the tranmsit fifo is not full * ****************************************************************************/static boolean z8_txready(FAR struct uart_dev_s *dev){ struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; return ((z8_getuart(priv, Z8_UART_STAT0) & Z8_UARTSTAT0_TDRE) != 0);}/**************************************************************************** * Name: z8_txempty * * Description: * Return TRUE if the transmit fifo is empty * ****************************************************************************/static boolean z8_txempty(FAR struct uart_dev_s *dev){ struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; return ((z8_getuart(priv, Z8_UART_STAT0) & Z8_UARTSTAT0_TXE) != 0);}/**************************************************************************** * Public Funtions ****************************************************************************//**************************************************************************** * Name: up_earlyserialinit * * Description: * Performs the low level UART initialization early in * debug so that the serial console will be available * during bootup. This must be called before z8_serialinit. * ****************************************************************************/void up_earlyserialinit(void){ (void)z8_disableuartirq(&TTYS0_DEV); (void)z8_disableuartirq(&TTYS1_DEV); CONSOLE_DEV.isconsole = TRUE; z8_setup(&CONSOLE_DEV);}/**************************************************************************** * Name: up_serialinit * * Description: * Register serial console and serial ports. This assumes * that up_earlyserialinit was called previously. * ****************************************************************************/void up_serialinit(void){ (void)uart_register("/dev/console", &CONSOLE_DEV); (void)uart_register("/dev/ttyS0", &TTYS0_DEV); (void)uart_register("/dev/ttyS1", &TTYS1_DEV);}/**************************************************************************** * Name: up_putc * * Description: * Provide priority, low-level access to support OS debug * writes * ****************************************************************************/int up_putc(int ch){ ubyte state; /* Keep interrupts disabled so that we do not interfere with normal * driver operation */ state = z8_disableuartirq(&CONSOLE_DEV); /* Check for LF */ if (ch == '\n') { /* Add CR before LF */ z8_consoleput('\r'); } /* Output the character */ z8_consoleput((ubyte)ch); /* It is important to restore the TX interrupt while the send is pending. * otherwise, TRDE interrupts can be lost since they do not pend after the * TRDE false->true transition. */ z8_restoreuartirq(&CONSOLE_DEV, state); return ch;}#else /* CONFIG_USE_SERIALDRIVER *//**************************************************************************** * Definitions ****************************************************************************/#ifdef CONFIG_UART1_SERIAL_CONSOLE# define z8_contrde() \ ((getreg8(*(Z8_UART1_BASE+Z8_UART_STAT0)) & Z8_UARTSTAT0_TDRE) != 0)# define z8_contxd(ch) \ putreg8((ubyte)(ch), *(Z8_UART1_BASE+Z8_UART_TXD))#else# define z8_contrde() \ ((getreg8(*(Z8_UART0_BASE+Z8_UART_STAT0)) & Z8_UARTSTAT0_TDRE) != 0)# define z8_contxd(ch) \ putreg8((ubyte)(ch), *(Z8_UART0_BASE+Z8_UART_TXD))#endif/**************************************************************************** * Private Function Prototypes ****************************************************************************//**************************************************************************** * Private Variables ****************************************************************************//**************************************************************************** * Private Functions ****************************************************************************//**************************************************************************** * Name: z8_putc ****************************************************************************/static void z8_putc(int ch){ int tmp; for (tmp = 1000 ; tmp > 0 && !z8_contrde(); tmp--); z8_contxd(ch);}/**************************************************************************** * Public Functions ****************************************************************************//**************************************************************************** * Name: up_putc ****************************************************************************/int up_putc(int ch){ /* Check for LF */ if (ch == '\n') { /* Output CR before LF */ z8_putc('\r'); } /* Output character */ z8_putc(ch); return ch;}#endif /* CONFIG_USE_SERIALDRIVER */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?