📄 c5471_serial.c
字号:
/* Enable RTS/CTS flow control */ priv->regs.efr |= 0x000000c0; up_serialout(priv, UART_EFR_OFFS, priv->regs.efr); } else { /* Disable RTS/CTS flow control */ priv->regs.efr &= 0xffffff3f; up_serialout(priv, UART_EFR_OFFS, priv->regs.efr); }#endif#endif return OK;}/**************************************************************************** * Name: up_shutdown * * Description: * Disable the UART. This method is called when the serial port is closed * ****************************************************************************/static void up_shutdown(struct uart_dev_s *dev){ struct up_dev_s *priv = (struct up_dev_s*)CONSOLE_DEV.priv; up_disableuartint(priv, NULL);}/**************************************************************************** * Name: up_attach * * Description: * Configure the UART to operation in interrupt driven mode. This method is * called when the serial port is opened. Normally, this is just after the * the setup() method is called, however, the serial console may operate in * a non-interrupt driven mode during the boot phase. * * 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 up_attach(struct uart_dev_s *dev){ struct up_dev_s *priv = (struct up_dev_s*)dev->priv; int ret; /* 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; volatile uint32 cause; if (g_irdapriv.irq == irq) { dev = &g_irdaport; } else if (g_modempriv.irq == irq) { dev = &g_modemport; } else { PANIC(OSERR_INTERNAL); } priv = (struct up_dev_s*)dev->priv; cause = up_inserial(priv, UART_ISR_OFFS) & 0x0000003f; if ((cause & 0x0000000c) == 0x0000000c) { uint32 ier_val = 0; /* Is this an interrupt from the IrDA UART? */ if (irq == C5471_IRQ_UART_IRDA) { /* Save the currently enabled IrDA UART interrupts * so that we can restore the IrDA interrupt state * below. */ ier_val = up_inserial(priv, UART_IER_OFFS); /* Then disable all IrDA UART interrupts */ up_serialout(priv, UART_IER_OFFS, 0); } /* Receive characters from the RX fifo */ uart_recvchars(dev); /* read UART_RHR to clear int condition * toss = up_inserialchar(priv,&status); */ /* Is this an interrupt from the IrDA UART? */ if (irq == C5471_IRQ_UART_IRDA) { /* Restore the IrDA UART interrupt enables */ up_serialout(priv, UART_IER_OFFS, ier_val); } } else if ((cause & 0x0000000c) == 0x00000004) { uart_recvchars(dev); } if ((cause & 0x00000002) != 0) { uart_xmitchars(dev); } 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); irqrestore(flags); } break; case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ { irqstate_t flags; flags = irqsave(); up_disablebreaks(priv); 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, unsigned int *status){ struct up_dev_s *priv = (struct up_dev_s*)dev->priv; uint32 rhr; uint32 lsr; /* Construct a 16bit status word that uses the high byte to * hold the status bits associated with framing,parity,break * and a low byte that holds error bits of LSR for * conditions such as overflow, etc. */ rhr = up_inserial(priv, UART_RHR_OFFS); lsr = up_inserial(priv, UART_LSR_OFFS); *status = (unsigned int)((rhr & 0x0000ff00) | (lsr & 0x000000ff)); return rhr & 0x000000ff;}/**************************************************************************** * 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->regs.ier |= UART_IER_RECVINT; up_serialout(priv, UART_IER_OFFS, priv->regs.ier);#endif } else { priv->regs.ier &= ~UART_IER_RECVINT; up_serialout(priv, UART_IER_OFFS, priv->regs.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_inserial(priv, UART_LSR_OFFS) & UART_RX_FIFO_NOEMPTY;}/**************************************************************************** * 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, UART_THR_OFFS, (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->regs.ier |= UART_IER_XMITINT; up_serialout(priv, UART_IER_OFFS, priv->regs.ier);#endif } else { priv->regs.ier &= ~UART_IER_XMITINT; up_serialout(priv, UART_IER_OFFS, priv->regs.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_inserial(priv, UART_SSR_OFFS) & UART_SSR_TXFULL) == 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_inserial(priv, UART_LSR_OFFS) & UART_LSR_TREF) != 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){ up_disableuartint(TTYS0_DEV.priv, NULL); up_disableuartint(TTYS1_DEV.priv, NULL); 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; uint16 ier; up_disableuartint(priv, &ier); up_waittxready(priv); up_serialout(priv, UART_THR_OFFS, (ubyte)ch); /* Check for LF */ if (ch == '\n') { /* Add CR */ up_waittxready(priv); up_serialout(priv, UART_THR_OFFS, '\r'); } up_waittxready(priv); up_restoreuartint(priv, ier); return ch;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -