2003-02-20 Till Straumann <strauman@slac.stanford.edu>

PR 349/bsps
	* console/console.c, console/uart.c, console/uart.h: implement
	IOCTLs for the serial (UART) console to install/retrieve a BREAK-IRQ
	callback.  The callback routine (if installed) is invoked from the
	UART ISR when a BREAK interrupt is detected.  This can be used
	e.g. to enforce a "hotkey" reboot a la vxWorks Ctrl-X (although we
	use the serial line break condition) NOTE: The callback runs in
	ISR context.
This commit is contained in:
Joel Sherrill
2003-02-20 21:38:50 +00:00
parent 254f0552cb
commit 01fdbb1f30
6 changed files with 112 additions and 16 deletions

View File

@@ -11,6 +11,7 @@
#include <bsp/irq.h>
#include <bsp/uart.h>
#include <rtems/libio.h>
#include <rtems/bspIo.h>
#include <assert.h>
/*
@@ -19,9 +20,10 @@
struct uart_data
{
unsigned long ioBase;
int hwFlow;
int baud;
unsigned long ioBase;
int hwFlow;
int baud;
BSP_UartBreakCbRec breakCallback;
};
/*
@@ -74,11 +76,13 @@ uwrite(int uart, int reg, unsigned int val)
out_8((unsigned char*)(uart_data[uart].ioBase + reg), val);
}
#define UARTDEBUG
#ifdef UARTDEBUG
static void
uartError(int uart)
uartError(int uart, void *termiosPrivate)
{
unsigned char uartStatus, dummy;
BSP_UartBreakCbProc h;
uartStatus = uread(uart, LSR);
dummy = uread(uart, RBR);
@@ -89,19 +93,32 @@ uartError(int uart)
printk("********* Parity Error **********\n");
if (uartStatus & FE)
printk("********* Framing Error **********\n");
if (uartStatus & BI)
printk("********* Parity Error **********\n");
if (uartStatus & BI) {
printk("********* BREAK INTERRUPT *********\n");
if ((h=uart_data[uart].breakCallback.handler))
h(uart,
(dummy<<8)|uartStatus,
termiosPrivate,
uart_data[uart].breakCallback.private);
}
if (uartStatus & ERFIFO)
printk("********* Error receive Fifo **********\n");
}
#else
inline void uartError(int uart)
inline void uartError(int uart, void *termiosPrivate)
{
unsigned char uartStatus;
unsigned char uartStatus,dummy;
BSP_UartBreakCbProc h;
uartStatus = uread(uart, LSR);
uartStatus = uread(uart, RBR);
dummy = uread(uart, RBR);
if ((uartStatus & BI) && (h=uart_data[uart].breakCallback.handler))
h(uart,
(dummy<<8)|uartStatus,
termiosPrivate,
uart_data[uart].breakCallback.private);
}
#endif
@@ -644,7 +661,7 @@ BSP_uart_termios_isr_com(int uart)
break;
case RECEIVER_ERROR:
/* RX error: eat character */
uartError(uart);
uartError(uart, termios_ttyp_com[uart]);
break;
default:
/* Should not happen */
@@ -666,3 +683,30 @@ BSP_uart_termios_isr_com2(void)
BSP_uart_termios_isr_com(BSP_UART_COM2);
}
/* retrieve 'break' handler info */
int
BSP_uart_get_break_cb(int uart, rtems_libio_ioctl_args_t *arg)
{
BSP_UartBreakCb cb=arg->buffer;
unsigned long flags;
SANITY_CHECK(uart);
rtems_interrupt_disable(flags);
*cb = uart_data[uart].breakCallback;
rtems_interrupt_enable(flags);
arg->ioctl_return=0;
return RTEMS_SUCCESSFUL;
}
/* install 'break' handler */
int
BSP_uart_set_break_cb(int uart, rtems_libio_ioctl_args_t *arg)
{
BSP_UartBreakCb cb=arg->buffer;
unsigned long flags;
SANITY_CHECK(uart);
rtems_interrupt_disable(flags);
uart_data[uart].breakCallback = *cb;
rtems_interrupt_enable(flags);
arg->ioctl_return=0;
return RTEMS_SUCCESSFUL;
}