📄 lpc214x_serial.c
字号:
/* Attach and enable the IRQ */ ret = irq_attach(priv->irq, up_interrupt); if (ret == OK) { /* Enable the interrupt (RX and TX interrupts are still disabled * in the UART */ up_enable_irq(priv->irq); } return ret;}/**************************************************************************** * Name: up_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 up_detach(struct uart_dev_s *dev){ struct up_dev_s *priv = (struct up_dev_s*)dev->priv; up_disable_irq(priv->irq); irq_detach(priv->irq);}/**************************************************************************** * Name: up_interrupt * * Description: * This is the UART interrupt handler. It will be invoked * when an interrupt received on the 'irq' It should call * uart_transmitchars or uart_receivechar to perform the * appropriate data transfers. The interrupt handling logic\ * must be able to map the 'irq' number into the approprite * uart_dev_s structure in order to call these functions. * ****************************************************************************/static int up_interrupt(int irq, void *context){ struct uart_dev_s *dev = NULL; struct up_dev_s *priv; ubyte status; int passes; if (g_uart1priv.irq == irq) { dev = &g_uart1port; } else if (g_uart0priv.irq == irq) { dev = &g_uart0port; } else { PANIC(OSERR_INTERNAL); } priv = (struct up_dev_s*)dev->priv; /* Loop until there are no characters to be transferred or, * until we have been looping for a long time. */ for( passes = 0; passes < 256; passes++) { /* Get the current UART status and check for loop * termination conditions */ status = up_serialin(priv, LPC214X_UART_IIR_OFFSET); /* The NO INTERRUPT should be zero */ if (status != LPC214X_IIR_NO_INT) { /* Handline incoming, receive bytes (with or without timeout) */ if (status == LPC214X_IIR_RDA_INT || status == LPC214X_IIR_CTI_INT) { uart_recvchars(dev); } /* Handle outgoing, transmit bytes */ else if (status == LPC214X_IIR_THRE_INT) { uart_xmitchars(dev); } /* Just clear modem status interrupts */ else if (status == LPC214X_IIR_MS_INT) { /* Read the modem status regisgter (MSR) to clear */ (void)up_serialin(priv, LPC214X_UART_MSR_OFFSET); } /* Just clear any line status interrupts */ else if (status == LPC214X_IIR_RLS_INT) { /* Read the line status register (LSR) to clear */ (void)up_serialin(priv, LPC214X_UART_LSR_OFFSET); } } } return OK;}/**************************************************************************** * Name: up_ioctl * * Description: * All ioctl calls will be routed through this method * ****************************************************************************/static int up_ioctl(struct file *filep, int cmd, unsigned long arg){ struct inode *inode = filep->f_inode; struct uart_dev_s *dev = inode->i_private; struct up_dev_s *priv = (struct up_dev_s*)dev->priv; int ret = OK; switch (cmd) { case TIOCSERGSTRUCT: { struct up_dev_s *user = (struct up_dev_s*)arg; if (!user) { *get_errno_ptr() = EINVAL; ret = ERROR; } else { memcpy(user, dev, sizeof(struct up_dev_s)); } } break; case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ { irqstate_t flags = irqsave(); up_enablebreaks(priv, TRUE); irqrestore(flags); } break; case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ { irqstate_t flags; flags = irqsave(); up_enablebreaks(priv, FALSE); irqrestore(flags); } break; default: *get_errno_ptr() = ENOTTY; ret = ERROR; break; } return ret;}/**************************************************************************** * Name: up_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 the return 'status'. * ****************************************************************************/static int up_receive(struct uart_dev_s *dev, uint32 *status){ struct up_dev_s *priv = (struct up_dev_s*)dev->priv; ubyte rbr; rbr = up_serialin(priv, LPC214X_UART_RBR_OFFSET); *status = up_serialin(priv, LPC214X_UART_RBR_OFFSET); return rbr;}/**************************************************************************** * Name: up_rxint * * Description: * Call to enable or disable RX interrupts * ****************************************************************************/static void up_rxint(struct uart_dev_s *dev, boolean enable){ struct up_dev_s *priv = (struct up_dev_s*)dev->priv; if (enable) {#ifndef CONFIG_SUPPRESS_SERIAL_INTS priv->ier |= LPC214X_IER_ERBFI;#endif } else { priv->ier &= ~LPC214X_IER_ERBFI; } up_serialout(priv, LPC214X_UART_IER_OFFSET, priv->ier);}/**************************************************************************** * Name: up_rxavailable * * Description: * Return TRUE if the receive fifo is not empty * ****************************************************************************/static boolean up_rxavailable(struct uart_dev_s *dev){ struct up_dev_s *priv = (struct up_dev_s*)dev->priv; return ((up_serialin(priv, LPC214X_UART_LSR_OFFSET) & LPC214X_LSR_RDR) != 0);}/**************************************************************************** * Name: up_send * * Description: * This method will send one byte on the UART * ****************************************************************************/static void up_send(struct uart_dev_s *dev, int ch){ struct up_dev_s *priv = (struct up_dev_s*)dev->priv; up_serialout(priv, LPC214X_UART_THR_OFFSET, (ubyte)ch);}/**************************************************************************** * Name: up_txint * * Description: * Call to enable or disable TX interrupts * ****************************************************************************/static void up_txint(struct uart_dev_s *dev, boolean enable){ struct up_dev_s *priv = (struct up_dev_s*)dev->priv; if (enable) {#ifndef CONFIG_SUPPRESS_SERIAL_INTS priv->ier |= LPC214X_IER_ETBEI;#endif } else { priv->ier &= ~LPC214X_IER_ETBEI; } up_serialout(priv, LPC214X_UART_IER_OFFSET, priv->ier);}/**************************************************************************** * Name: up_txready * * Description: * Return TRUE if the tranmsit fifo is not full * ****************************************************************************/static boolean up_txready(struct uart_dev_s *dev){ struct up_dev_s *priv = (struct up_dev_s*)dev->priv; return ((up_serialin(priv, LPC214X_UART_LSR_OFFSET) & LPC214X_LSR_THRE) != 0);}/**************************************************************************** * Name: up_txempty * * Description: * Return TRUE if the transmit fifo is empty * ****************************************************************************/static boolean up_txempty(struct uart_dev_s *dev){ struct up_dev_s *priv = (struct up_dev_s*)dev->priv; return ((up_serialin(priv, LPC214X_UART_LSR_OFFSET) & LPC214X_LSR_THRE) != 0);}/**************************************************************************** * Public Funtions ****************************************************************************//**************************************************************************** * Name: up_serialinit * * 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 up_serialinit. * ****************************************************************************/void up_earlyserialinit(void){ /* Enable UART0 and 1 */ uint32 pinsel = getreg32(LPC214X_PINSEL0); pinsel &= ~(LPC214X_UART0_PINMASK|LPC214X_UART1_PINMASK); pinsel |= (LPC214X_UART0_PINSEL|LPC214X_UART1_PINSEL); putreg32(pinsel, LPC214X_PINSEL0); /* Disable both UARTS */ up_disableuartint(TTYS0_DEV.priv, NULL); up_disableuartint(TTYS1_DEV.priv, NULL); /* Configuration whichever on is the console */ CONSOLE_DEV.isconsole = TRUE; up_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){ struct up_dev_s *priv = (struct up_dev_s*)CONSOLE_DEV.priv; ubyte ier; up_disableuartint(priv, &ier); up_waittxready(priv); up_serialout(priv, LPC214X_UART_THR_OFFSET, (ubyte)ch); /* Check for LF */ if (ch == '\n') { /* Add CR */ up_waittxready(priv); up_serialout(priv, LPC214X_UART_THR_OFFSET, '\r'); } up_waittxready(priv); up_restoreuartint(priv, ier); return ch;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -