📄 dm320_serial.c
字号:
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; uint16 status; int passes = 0; 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(;;) { /* Get the current UART status and check for loop * termination conditions */ status = up_serialin(priv, UART_SR); status &= (UART_SR_RFTI | UART_SR_TFTI); if (status == 0 || passes > 256) { return OK; } /* Handline incoming, receive bytes */ if (status & UART_SR_RFTI) { uart_recvchars(dev); } /* Handle outgoing, transmit bytes */ if (status & UART_SR_TFTI) { uart_xmitchars(dev); } /* Keep track of how many times we do this in case there * is some hardware failure condition. */ passes++; }}/**************************************************************************** * 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; uint16 dtrr; dtrr = up_serialin(priv, UART_DTRR); *status = dtrr; return dtrr & UART_DTRR_DTR_MASK;}/**************************************************************************** * 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->msr |= UART_MSR_RFTIE;#endif } else { priv->msr &= ~UART_MSR_RFTIE; } up_serialout(priv, UART_MSR, priv->msr);}/**************************************************************************** * 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, UART_SR) & UART_SR_RFNEF) != 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, UART_DTRR, (uint16)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->msr |= UART_MSR_TFTIE;#endif } else { priv->msr &= ~UART_MSR_TFTIE; } up_serialout(priv, UART_MSR, priv->msr);}/**************************************************************************** * 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, UART_SR) & UART_SR_TFTI) != 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, UART_SR) & UART_SR_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_DTRR, (uint16)ch); /* Check for LF */ if (ch == '\n') { /* Add CR */ up_waittxready(priv); up_serialout(priv, UART_DTRR, '\r'); } up_waittxready(priv); up_restoreuartint(priv, ier); return ch;}#else /* CONFIG_NFILE_DESCRIPTORS > 0 *//**************************************************************************** * Definitions ****************************************************************************/# ifdef CONFIG_UART1_SERIAL_CONSOLE# define DM320_REGISTER_BASE DM320_UART1_REGISTER_BASE# else# define DM320_REGISTER_BASE DM320_UART0_REGISTER_BASE# endif/**************************************************************************** * Private Functions ****************************************************************************/static inline void up_waittxready(void){ int tmp; for (tmp = 1000 ; tmp > 0 ; tmp--) { if ((getreg16(DM320_REGISTER_BASE + UART_SR) & UART_SR_TFTI) != 0) { break; } }}/**************************************************************************** * Public Functions ****************************************************************************/int up_putc(int ch){ up_waittxready(); putreg16((uint16)ch, DM320_REGISTER_BASE + UART_DTRR); /* Check for LF */ if (ch == '\n') { /* Add CR */ up_waittxready(); putreg16((uint16)'\r', DM320_REGISTER_BASE + UART_DTRR); } up_waittxready(); return ch;}#endif /* CONFIG_NFILE_DESCRIPTORS > 0 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -