diff --git a/sys/include/tty.h b/sys/include/tty.h index 918e161..6753e85 100644 --- a/sys/include/tty.h +++ b/sys/include/tty.h @@ -211,6 +211,11 @@ int ttyselect (struct tty *tp, int rw); */ void ttyflush (struct tty *tp, int rw); +/* + * Wait for output to drain, and flush input. + */ +void ttywflush (struct tty *tp); + #endif /* KERNEL */ /* internal state bits */ diff --git a/sys/pic32/uart.c b/sys/pic32/uart.c index 26e2cb5..7539d70 100644 --- a/sys/pic32/uart.c +++ b/sys/pic32/uart.c @@ -38,12 +38,12 @@ unsigned int uart_major = 0; #endif const struct uart_irq uirq[NUART] = { - { PIC32_IRQ_U1E, PIC32_IRQ_U1RX, PIC32_IRQ_U1TX }, - { PIC32_IRQ_U2E, PIC32_IRQ_U2RX, PIC32_IRQ_U2TX }, - { PIC32_IRQ_U3E, PIC32_IRQ_U3RX, PIC32_IRQ_U3TX }, - { PIC32_IRQ_U4E, PIC32_IRQ_U4RX, PIC32_IRQ_U4TX }, - { PIC32_IRQ_U5E, PIC32_IRQ_U5RX, PIC32_IRQ_U5TX }, - { PIC32_IRQ_U6E, PIC32_IRQ_U6RX, PIC32_IRQ_U6TX }, + { PIC32_IRQ_U1E, PIC32_IRQ_U1RX, PIC32_IRQ_U1TX }, + { PIC32_IRQ_U2E, PIC32_IRQ_U2RX, PIC32_IRQ_U2TX }, + { PIC32_IRQ_U3E, PIC32_IRQ_U3RX, PIC32_IRQ_U3TX }, + { PIC32_IRQ_U4E, PIC32_IRQ_U4RX, PIC32_IRQ_U4TX }, + { PIC32_IRQ_U5E, PIC32_IRQ_U5RX, PIC32_IRQ_U5TX }, + { PIC32_IRQ_U6E, PIC32_IRQ_U6RX, PIC32_IRQ_U6TX }, }; struct tty uartttys[NUART]; @@ -66,18 +66,19 @@ const struct devspec uartdevs[] = { }; void cnstart (struct tty *tp); + struct uartreg *uart[NUART] = { - (struct uartreg*) &U1MODE, - (struct uartreg*) &U2MODE, - (struct uartreg*) &U3MODE, - (struct uartreg*) &U4MODE, - (struct uartreg*) &U5MODE, - (struct uartreg*) &U6MODE + (struct uartreg*) &U1MODE, + (struct uartreg*) &U2MODE, + (struct uartreg*) &U3MODE, + (struct uartreg*) &U4MODE, + (struct uartreg*) &U5MODE, + (struct uartreg*) &U6MODE }; void uartinit() { - unsigned char unit; + unsigned char unit; int i; // Our first task is to find out what our major @@ -89,17 +90,11 @@ void uartinit() } } - /* - * Setup UART registers. - * Compute the divisor for 115.2 kbaud. - */ - for(unit=0; unitbrg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART1_BAUD); - break; - case 1: + uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART1_BAUD); + break; + case 1: #ifdef UART2_ENA_PORT - /* Enable UART2 phy - pin is assumed to be active low */ - TRIS_CLR(UART2_ENA_PORT) = 1 << UART2_ENA_PIN; - LAT_CLR(UART2_ENA_PORT) = 1 << UART2_ENA_PIN; - udelay(2500); + /* Enable UART2 phy - pin is assumed to be active low */ + TRIS_CLR(UART2_ENA_PORT) = 1 << UART2_ENA_PIN; + LAT_CLR(UART2_ENA_PORT) = 1 << UART2_ENA_PIN; + udelay(2500); #endif - uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART2_BAUD); - break; - case 2: + uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART2_BAUD); + break; + case 2: #ifdef UART3_ENA_PORT - /* Enable UART3 phy - pin is assumed to be active low */ - TRIS_CLR(UART3_ENA_PORT) = 1 << UART3_ENA_PIN; - LAT_CLR(UART3_ENA_PORT) = 1 << UART3_ENA_PIN; - udelay(2500); + /* Enable UART3 phy - pin is assumed to be active low */ + TRIS_CLR(UART3_ENA_PORT) = 1 << UART3_ENA_PIN; + LAT_CLR(UART3_ENA_PORT) = 1 << UART3_ENA_PIN; + udelay(2500); #endif - uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART3_BAUD); - break; - case 3: + uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART3_BAUD); + break; + case 3: #ifdef UART4_ENA_PORT - /* Enable UART4 phy - pin is assumed to be active low */ - TRIS_CLR(UART4_ENA_PORT) = 1 << UART4_ENA_PIN; - LAT_CLR(UART4_ENA_PORT) = 1 << UART4_ENA_PIN; - udelay(2500); + /* Enable UART4 phy - pin is assumed to be active low */ + TRIS_CLR(UART4_ENA_PORT) = 1 << UART4_ENA_PIN; + LAT_CLR(UART4_ENA_PORT) = 1 << UART4_ENA_PIN; + udelay(2500); #endif - uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART4_BAUD); - break; - case 4: + uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART4_BAUD); + break; + case 4: #ifdef UART5_ENA_PORT - /* Enable UART5 phy - pin is assumed to be active low */ - TRIS_CLR(UART5_ENA_PORT) = 1 << UART5_ENA_PIN; - LAT_CLR(UART5_ENA_PORT) = 1 << UART5_ENA_PIN; - udelay(2500); + /* Enable UART5 phy - pin is assumed to be active low */ + TRIS_CLR(UART5_ENA_PORT) = 1 << UART5_ENA_PIN; + LAT_CLR(UART5_ENA_PORT) = 1 << UART5_ENA_PIN; + udelay(2500); #endif - uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART5_BAUD); - break; - case 5: + uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART5_BAUD); + break; + case 5: #ifdef UART6_ENA_PORT - /* Enable UART6 phy - pin is assumed to be active low */ - TRIS_CLR(UART6_ENA_PORT) = 1 << UART6_ENA_PIN; - LAT_CLR(UART6_ENA_PORT) = 1 << UART6_ENA_PIN; - udelay(2500); + /* Enable UART6 phy - pin is assumed to be active low */ + TRIS_CLR(UART6_ENA_PORT) = 1 << UART6_ENA_PIN; + LAT_CLR(UART6_ENA_PORT) = 1 << UART6_ENA_PIN; + udelay(2500); #endif - uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART6_BAUD); - break; + uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART6_BAUD); + break; } - uart[unit]->sta = 0; - uart[unit]->mode = PIC32_UMODE_PDSEL_8NPAR | /* 8-bit data, no parity */ - PIC32_UMODE_ON; /* UART Enable */ - uart[unit]->staset = PIC32_USTA_URXEN | /* Receiver Enable */ - PIC32_USTA_UTXEN; /* Transmit Enable */ - } + uart[unit]->sta = 0; + uart[unit]->mode = + PIC32_UMODE_PDSEL_8NPAR | /* 8-bit data, no parity */ + PIC32_UMODE_ON; /* UART Enable */ + uart[unit]->staset = + PIC32_USTA_URXEN | /* Receiver Enable */ + PIC32_USTA_UTXEN; /* Transmit Enable */ + } } int uartopen(dev_t dev, int flag, int mode) { - register struct uartreg *reg; - register struct tty *tp; - register int unit = minor(dev); + register struct uartreg *reg; + register struct tty *tp; + register int unit = minor(dev); - if (unit >= NUART) - return (ENXIO); + if (unit >= NUART) + return (ENXIO); #ifndef UART1_ENABLED - if (unit==0) - return ENODEV; + if (unit==0) + return ENODEV; #endif #ifndef UART2_ENABLED - if (unit==1) - return ENODEV; + if (unit==1) + return ENODEV; #endif #ifndef UART3_ENABLED - if (unit==2) - return ENODEV; + if (unit==2) + return ENODEV; #endif #ifndef UART4_ENABLED - if (unit==3) - return ENODEV; + if (unit==3) + return ENODEV; #endif #ifndef UART5_ENABLED - if (unit==4) - return ENODEV; + if (unit==4) + return ENODEV; #endif #ifndef UART6_ENABLED - if (unit==5) - return ENODEV; + if (unit==5) + return ENODEV; #endif - if ((SD0_PORT == 2) && (unit==2 || unit==5)) - return (ENODEV); - if ((SD0_PORT == 3) && (unit==0 || unit==3)) - return (ENODEV); - if ((SD0_PORT == 4) && (unit==1 || unit==4)) - return (ENODEV); + if ((SD0_PORT == 2) && (unit==2 || unit==5)) + return (ENODEV); + if ((SD0_PORT == 3) && (unit==0 || unit==3)) + return (ENODEV); + if ((SD0_PORT == 4) && (unit==1 || unit==4)) + return (ENODEV); - tp = &uartttys[unit]; - if (! tp->t_addr) { - switch (unit) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - tp->t_addr = (caddr_t) uart[unit]; - break; - default: - return (ENXIO); - } + tp = &uartttys[unit]; + if (! tp->t_addr) { + switch (unit) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + tp->t_addr = (caddr_t) uart[unit]; + break; + default: + return (ENXIO); } - reg = (struct uartreg*) tp->t_addr; - tp->t_oproc = uartstart; - if ((tp->t_state & TS_ISOPEN) == 0) { - if (tp->t_ispeed == 0) { - switch(unit) - { - case 0: - tp->t_ispeed = BBAUD(UART1_BAUD); - tp->t_ospeed = BBAUD(UART1_BAUD); - break; - case 1: - tp->t_ispeed = BBAUD(UART2_BAUD); - tp->t_ospeed = BBAUD(UART2_BAUD); - break; - case 2: - tp->t_ispeed = BBAUD(UART3_BAUD); - tp->t_ospeed = BBAUD(UART3_BAUD); - break; - case 3: - tp->t_ispeed = BBAUD(UART4_BAUD); - tp->t_ospeed = BBAUD(UART4_BAUD); - break; - case 4: - tp->t_ispeed = BBAUD(UART5_BAUD); - tp->t_ospeed = BBAUD(UART5_BAUD); - break; - case 5: - tp->t_ispeed = BBAUD(UART6_BAUD); - tp->t_ospeed = BBAUD(UART6_BAUD); - break; + } + reg = (struct uartreg*) tp->t_addr; + tp->t_oproc = uartstart; + if ((tp->t_state & TS_ISOPEN) == 0) { + if (tp->t_ispeed == 0) { + switch(unit) { + case 0: + tp->t_ispeed = BBAUD(UART1_BAUD); + tp->t_ospeed = BBAUD(UART1_BAUD); + break; + case 1: + tp->t_ispeed = BBAUD(UART2_BAUD); + tp->t_ospeed = BBAUD(UART2_BAUD); + break; + case 2: + tp->t_ispeed = BBAUD(UART3_BAUD); + tp->t_ospeed = BBAUD(UART3_BAUD); + break; + case 3: + tp->t_ispeed = BBAUD(UART4_BAUD); + tp->t_ospeed = BBAUD(UART4_BAUD); + break; + case 4: + tp->t_ispeed = BBAUD(UART5_BAUD); + tp->t_ospeed = BBAUD(UART5_BAUD); + break; + case 5: + tp->t_ispeed = BBAUD(UART6_BAUD); + tp->t_ospeed = BBAUD(UART6_BAUD); + break; } - } - ttychars(tp); - tp->t_state = TS_ISOPEN | TS_CARR_ON; - tp->t_flags = ECHO | XTABS | CRMOD | CRTBS | CRTERA | CTLECH | CRTKIL; - } - if ((tp->t_state & TS_XCLUDE) && u.u_uid != 0) - return (EBUSY); + } + ttychars(tp); + tp->t_state = TS_ISOPEN | TS_CARR_ON; + tp->t_flags = ECHO | XTABS | CRMOD | CRTBS | CRTERA | CTLECH | CRTKIL; + } + if ((tp->t_state & TS_XCLUDE) && u.u_uid != 0) + return (EBUSY); - reg->sta = 0; - reg->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, speed_bps [tp->t_ospeed]); - reg->mode = PIC32_UMODE_PDSEL_8NPAR | - PIC32_UMODE_ON; - reg->staset = PIC32_USTA_URXEN | PIC32_USTA_UTXEN; + reg->sta = 0; + reg->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, speed_bps [tp->t_ospeed]); + reg->mode = PIC32_UMODE_PDSEL_8NPAR | + PIC32_UMODE_ON; + reg->staset = PIC32_USTA_URXEN | PIC32_USTA_UTXEN; - /* Enable receive interrupt. */ - if (uirq[unit].rx < 32) - { - IECSET(0) = 1 << uirq[unit].rx; - } else if (uirq[unit].rx < 64) - { - IECSET(1) = 1 << (uirq[unit].rx-32); - } else { - IECSET(2) = 1 << (uirq[unit].rx-64); - } - return ttyopen(dev, tp); + /* Enable receive interrupt. */ + if (uirq[unit].rx < 32) { + IECSET(0) = 1 << uirq[unit].rx; + } else if (uirq[unit].rx < 64) { + IECSET(1) = 1 << (uirq[unit].rx-32); + } else { + IECSET(2) = 1 << (uirq[unit].rx-64); + } + return ttyopen(dev, tp); } /*ARGSUSED*/ int -uartclose (dev, flag, mode) - dev_t dev; +uartclose (dev_t dev, int flag, int mode) { - register int unit = minor(dev); - register struct tty *tp = &uartttys[unit]; + register int unit = minor(dev); + register struct tty *tp = &uartttys[unit]; #ifndef UART1_ENABLED - if (unit==0) - return ENODEV; + if (unit==0) + return ENODEV; #endif #ifndef UART2_ENABLED - if (unit==1) - return ENODEV; + if (unit==1) + return ENODEV; #endif #ifndef UART3_ENABLED - if (unit==2) - return ENODEV; + if (unit==2) + return ENODEV; #endif #ifndef UART4_ENABLED - if (unit==3) - return ENODEV; + if (unit==3) + return ENODEV; #endif #ifndef UART5_ENABLED - if (unit==4) - return ENODEV; + if (unit==4) + return ENODEV; #endif #ifndef UART6_ENABLED - if (unit==5) - return ENODEV; + if (unit==5) + return ENODEV; #endif - if ((SD0_PORT == 2) && (unit==2 || unit==5)) - return (ENODEV); - if ((SD0_PORT == 3) && (unit==0 || unit==3)) - return (ENODEV); - if ((SD0_PORT == 4) && (unit==1 || unit==4)) - return (ENODEV); - - ttyclose(tp); - return(0); + ttywflush(tp); + ttyclose(tp); + return(0); } /*ARGSUSED*/ int uartread (dev, uio, flag) - dev_t dev; - struct uio *uio; - int flag; + dev_t dev; + struct uio *uio; + int flag; { - register int unit = minor(dev); - register struct tty *tp = &uartttys[unit]; + register int unit = minor(dev); + register struct tty *tp = &uartttys[unit]; + #ifndef UART1_ENABLED - if (unit==0) - return ENODEV; + if (unit==0) + return ENODEV; #endif #ifndef UART2_ENABLED - if (unit==1) - return ENODEV; + if (unit==1) + return ENODEV; #endif #ifndef UART3_ENABLED - if (unit==2) - return ENODEV; + if (unit==2) + return ENODEV; #endif #ifndef UART4_ENABLED - if (unit==3) - return ENODEV; + if (unit==3) + return ENODEV; #endif #ifndef UART5_ENABLED - if (unit==4) - return ENODEV; + if (unit==4) + return ENODEV; #endif #ifndef UART6_ENABLED - if (unit==5) - return ENODEV; + if (unit==5) + return ENODEV; #endif - if ((SD0_PORT == 2) && (unit==2 || unit==5)) - return (ENODEV); - if ((SD0_PORT == 3) && (unit==0 || unit==3)) - return (ENODEV); - if ((SD0_PORT == 4) && (unit==1 || unit==4)) - return (ENODEV); - - return ttread(tp, uio, flag); + return ttread(tp, uio, flag); } /*ARGSUSED*/ int uartwrite (dev, uio, flag) - dev_t dev; - struct uio *uio; - int flag; + dev_t dev; + struct uio *uio; + int flag; { - register int unit = minor(dev); - register struct tty *tp = &uartttys[unit]; + register int unit = minor(dev); + register struct tty *tp = &uartttys[unit]; #ifndef UART1_ENABLED - if (unit==0) - return ENODEV; + if (unit==0) + return ENODEV; #endif #ifndef UART2_ENABLED - if (unit==1) - return ENODEV; + if (unit==1) + return ENODEV; #endif #ifndef UART3_ENABLED - if (unit==2) - return ENODEV; + if (unit==2) + return ENODEV; #endif #ifndef UART4_ENABLED - if (unit==3) - return ENODEV; + if (unit==3) + return ENODEV; #endif #ifndef UART5_ENABLED - if (unit==4) - return ENODEV; + if (unit==4) + return ENODEV; #endif #ifndef UART6_ENABLED - if (unit==5) - return ENODEV; + if (unit==5) + return ENODEV; #endif - if ((SD0_PORT == 2) && (unit==2 || unit==5)) - return (ENODEV); - if ((SD0_PORT == 3) && (unit==0 || unit==3)) - return (ENODEV); - if ((SD0_PORT == 4) && (unit==1 || unit==4)) - return (ENODEV); - return ttwrite(tp, uio, flag); + return ttwrite(tp, uio, flag); } int uartselect (dev, rw) - register dev_t dev; - int rw; + register dev_t dev; + int rw; { - register int unit = minor(dev); - register struct tty *tp = &uartttys[unit]; + register int unit = minor(dev); + register struct tty *tp = &uartttys[unit]; #ifndef UART1_ENABLED - if (unit==0) - return ENODEV; + if (unit==0) + return ENODEV; #endif #ifndef UART2_ENABLED - if (unit==1) - return ENODEV; + if (unit==1) + return ENODEV; #endif #ifndef UART3_ENABLED - if (unit==2) - return ENODEV; + if (unit==2) + return ENODEV; #endif #ifndef UART4_ENABLED - if (unit==3) - return ENODEV; + if (unit==3) + return ENODEV; #endif #ifndef UART5_ENABLED - if (unit==4) - return ENODEV; + if (unit==4) + return ENODEV; #endif #ifndef UART6_ENABLED - if (unit==5) - return ENODEV; + if (unit==5) + return ENODEV; #endif - if ((SD0_PORT == 2) && (unit==2 || unit==5)) - return (ENODEV); - if ((SD0_PORT == 3) && (unit==0 || unit==3)) - return (ENODEV); - if ((SD0_PORT == 4) && (unit==1 || unit==4)) - return (ENODEV); - return (ttyselect (tp, rw)); + return (ttyselect (tp, rw)); } /*ARGSUSED*/ int uartioctl (dev, cmd, addr, flag) - dev_t dev; - register u_int cmd; - caddr_t addr; + dev_t dev; + register u_int cmd; + caddr_t addr; { - register int unit = minor(dev); - register struct tty *tp = &uartttys[unit]; - register int error; + register int unit = minor(dev); + register struct tty *tp = &uartttys[unit]; + register int error; #ifndef UART1_ENABLED - if (unit==0) - return ENODEV; + if (unit==0) + return ENODEV; #endif #ifndef UART2_ENABLED - if (unit==1) - return ENODEV; + if (unit==1) + return ENODEV; #endif #ifndef UART3_ENABLED - if (unit==2) - return ENODEV; + if (unit==2) + return ENODEV; #endif #ifndef UART4_ENABLED - if (unit==3) - return ENODEV; + if (unit==3) + return ENODEV; #endif #ifndef UART5_ENABLED - if (unit==4) - return ENODEV; + if (unit==4) + return ENODEV; #endif #ifndef UART6_ENABLED - if (unit==5) - return ENODEV; + if (unit==5) + return ENODEV; #endif - if ((SD0_PORT == 2) && (unit==2 || unit==5)) - return (ENODEV); - if ((SD0_PORT == 3) && (unit==0 || unit==3)) - return (ENODEV); - if ((SD0_PORT == 4) && (unit==1 || unit==4)) - return (ENODEV); - error = ttioctl(tp, cmd, addr, flag); - if (error < 0) - error = ENOTTY; - return (error); + error = ttioctl(tp, cmd, addr, flag); + if (error < 0) + error = ENOTTY; + return (error); } void uartintr (dev) - dev_t dev; + dev_t dev; { - register int c; - register int unit = minor(dev); - register struct tty *tp = &uartttys[unit]; - register struct uartreg *reg = (struct uartreg *)tp->t_addr; - -#ifndef UART1_ENABLED - if (unit==0) - return; -#endif -#ifndef UART2_ENABLED - if (unit==1) - return; -#endif -#ifndef UART3_ENABLED - if (unit==2) - return; -#endif -#ifndef UART4_ENABLED - if (unit==3) - return; -#endif -#ifndef UART5_ENABLED - if (unit==4) - return; -#endif -#ifndef UART6_ENABLED - if (unit==5) - return; -#endif - /* Receive */ - while (reg->sta & PIC32_USTA_URXDA) { - c = reg->rxreg; - ttyinput(c, tp); - } - if (reg->sta & PIC32_USTA_OERR) - reg->staclr = PIC32_USTA_OERR; - - if (uirq[unit].rx < 32) - { - IFSCLR(0) = (1 << uirq[unit].rx) | (1 << uirq[unit].er); - } else if (uirq[unit].rx < 64) - { - IFSCLR(1) = (1 << (uirq[unit].rx-32)) | (1 << (uirq[unit].er-32)); - } else { - IFSCLR(2) = (1 << (uirq[unit].rx-64)) | (1 << (uirq[unit].er-64)); - } - - /* Transmit */ - if (reg->sta & PIC32_USTA_TRMT) { - led_control (LED_TTY, 0); - - if (uirq[unit].tx < 32) - { - IECCLR(0) = 1 << uirq[unit].tx; - IFSCLR(0) = 1 << uirq[unit].tx; - } else if (uirq[unit].tx < 64) { - IECCLR(1) = 1 << (uirq[unit].tx - 32); - IFSCLR(1) = 1 << (uirq[unit].tx - 32); - } else { - IECCLR(2) = 1 << (uirq[unit].tx - 64); - IFSCLR(2) = 1 << (uirq[unit].tx - 64); - } - if (tp->t_state & TS_BUSY) { - tp->t_state &= ~TS_BUSY; - ttstart(tp); - } - } -} - -void uartstart (register struct tty *tp) -{ - register struct uartreg *reg = (struct uartreg*) tp->t_addr; - register int c, s; - register int unit = minor(tp->t_dev); + register int c; + register int unit = minor(dev); + register struct tty *tp = &uartttys[unit]; + register struct uartreg *reg = (struct uartreg *)tp->t_addr; #ifndef UART1_ENABLED if (unit==0) @@ -636,31 +533,101 @@ void uartstart (register struct tty *tp) if (unit==5) return; #endif - s = spltty(); - if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) { -out: /* Disable transmit_interrupt. */ - led_control (LED_TTY, 0); - splx (s); - return; - } - ttyowake(tp); - if (tp->t_outq.c_cc == 0) - goto out; - if (reg->sta & PIC32_USTA_TRMT) { - c = getc(&tp->t_outq); - reg->txreg = c & 0xff; - tp->t_state |= TS_BUSY; - } - /* Enable transmit interrupt. */ - if (uirq[unit].tx < 32) { - IECSET(0) = 1 << uirq[unit].tx; - } else if (uirq[unit].tx < 64) { - IECSET(1) = 1 << (uirq[unit].tx - 32); - } else { - IECSET(2) = 1 << (uirq[unit].tx - 64); - } - led_control (LED_TTY, 1); - splx (s); + /* Receive */ + while (reg->sta & PIC32_USTA_URXDA) { + c = reg->rxreg; + ttyinput(c, tp); + } + if (reg->sta & PIC32_USTA_OERR) + reg->staclr = PIC32_USTA_OERR; + + if (uirq[unit].rx < 32) { + IFSCLR(0) = (1 << uirq[unit].rx) | (1 << uirq[unit].er); + } else if (uirq[unit].rx < 64) { + IFSCLR(1) = (1 << (uirq[unit].rx-32)) | (1 << (uirq[unit].er-32)); + } else { + IFSCLR(2) = (1 << (uirq[unit].rx-64)) | (1 << (uirq[unit].er-64)); + } + + /* Transmit */ + if (reg->sta & PIC32_USTA_TRMT) { + led_control (LED_TTY, 0); + + if (uirq[unit].tx < 32) { + IECCLR(0) = 1 << uirq[unit].tx; + IFSCLR(0) = 1 << uirq[unit].tx; + } else if (uirq[unit].tx < 64) { + IECCLR(1) = 1 << (uirq[unit].tx - 32); + IFSCLR(1) = 1 << (uirq[unit].tx - 32); + } else { + IECCLR(2) = 1 << (uirq[unit].tx - 64); + IFSCLR(2) = 1 << (uirq[unit].tx - 64); + } + + if (tp->t_state & TS_BUSY) { + tp->t_state &= ~TS_BUSY; + ttstart(tp); + } + } +} + +void uartstart (register struct tty *tp) +{ + register struct uartreg *reg = (struct uartreg*) tp->t_addr; + register int c, s; + register int unit = minor(tp->t_dev); + +#ifndef UART1_ENABLED + if (unit==0) + return; +#endif +#ifndef UART2_ENABLED + if (unit==1) + return; +#endif +#ifndef UART3_ENABLED + if (unit==2) + return; +#endif +#ifndef UART4_ENABLED + if (unit==3) + return; +#endif +#ifndef UART5_ENABLED + if (unit==4) + return; +#endif +#ifndef UART6_ENABLED + if (unit==5) + return; +#endif + s = spltty(); + if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) { +out: /* Disable transmit_interrupt. */ + led_control (LED_TTY, 0); + splx (s); + return; + } + ttyowake(tp); + if (tp->t_outq.c_cc == 0) + goto out; + + if (reg->sta & PIC32_USTA_TRMT) { + c = getc(&tp->t_outq); + reg->txreg = c & 0xff; + tp->t_state |= TS_BUSY; + } + + /* Enable transmit interrupt. */ + if (uirq[unit].tx < 32) { + IECSET(0) = 1 << uirq[unit].tx; + } else if (uirq[unit].tx < 64) { + IECSET(1) = 1 << (uirq[unit].tx - 32); + } else { + IECSET(2) = 1 << (uirq[unit].tx - 64); + } +led_control (LED_TTY, 1); + splx (s); } void uartputc(dev_t dev, char c) @@ -704,9 +671,10 @@ again: while ((reg->sta & PIC32_USTA_TRMT) == 0) if (--timo == 0) break; + if (tp->t_state & TS_BUSY) { - uartintr (dev); - goto again; + uartintr (dev); + goto again; } led_control (LED_TTY, 1); reg->txreg = c; @@ -717,18 +685,17 @@ again: break; /* Clear TX interrupt. */ - if (uirq[unit].tx < 32) { - IECCLR(0) = 1 << uirq[unit].tx; - } else if (uirq[unit].tx < 64) { - IECCLR(1) = 1 << (uirq[unit].tx - 32); - } else { - IECCLR(2) = 1 << (uirq[unit].tx - 64); - } + if (uirq[unit].tx < 32) { + IECCLR(0) = 1 << uirq[unit].tx; + } else if (uirq[unit].tx < 64) { + IECCLR(1) = 1 << (uirq[unit].tx - 32); + } else { + IECCLR(2) = 1 << (uirq[unit].tx - 64); + } led_control(LED_TTY, 0); splx(s); } - char uartgetc(dev_t dev) { int unit = minor(dev); @@ -767,13 +734,14 @@ char uartgetc(dev_t dev) break; } } - if (uirq[unit].rx < 32) { - IFSCLR(0) = (1 << uirq[unit].rx) | (1 << uirq[unit].er); - } else if (uirq[unit].rx < 64) { - IFSCLR(1) = (1 << (uirq[unit].rx-32)) | (1 << (uirq[unit].er-32)); - } else { - IFSCLR(2) = (1 << (uirq[unit].rx-64)) | (1 << (uirq[unit].er-64)); - } + + if (uirq[unit].rx < 32) { + IFSCLR(0) = (1 << uirq[unit].rx) | (1 << uirq[unit].er); + } else if (uirq[unit].rx < 64) { + IFSCLR(1) = (1 << (uirq[unit].rx-32)) | (1 << (uirq[unit].er-32)); + } else { + IFSCLR(2) = (1 << (uirq[unit].rx-64)) | (1 << (uirq[unit].er-64)); + } splx(s); return (unsigned char) c; }