iPXE
uart.h
Go to the documentation of this file.
00001 #ifndef _IPXE_UART_H
00002 #define _IPXE_UART_H
00003 
00004 /** @file
00005  *
00006  * 16550-compatible UART
00007  *
00008  */
00009 
00010 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00011 
00012 #include <stdint.h>
00013 
00014 /** Transmitter holding register */
00015 #define UART_THR 0x00
00016 
00017 /** Receiver buffer register */
00018 #define UART_RBR 0x00
00019 
00020 /** Interrupt enable register */
00021 #define UART_IER 0x01
00022 
00023 /** FIFO control register */
00024 #define UART_FCR 0x02
00025 #define UART_FCR_FE     0x01    /**< FIFO enable */
00026 
00027 /** Line control register */
00028 #define UART_LCR 0x03
00029 #define UART_LCR_WLS0   0x01    /**< Word length select bit 0 */
00030 #define UART_LCR_WLS1   0x02    /**< Word length select bit 1 */
00031 #define UART_LCR_STB    0x04    /**< Number of stop bits */
00032 #define UART_LCR_PEN    0x08    /**< Parity enable */
00033 #define UART_LCR_EPS    0x10    /**< Even parity select */
00034 #define UART_LCR_DLAB   0x80    /**< Divisor latch access bit */
00035 
00036 #define UART_LCR_WORD_LEN(x)    ( ( (x) - 5 ) << 0 )    /**< Word length */
00037 #define UART_LCR_STOP_BITS(x)   ( ( (x) - 1 ) << 2 )    /**< Stop bits */
00038 #define UART_LCR_PARITY(x)      ( ( (x) - 0 ) << 3 )    /**< Parity */
00039 
00040 /**
00041  * Calculate line control register value
00042  *
00043  * @v word_len          Word length (5-8)
00044  * @v parity            Parity (0=none, 1=odd, 3=even)
00045  * @v stop_bits         Stop bits (1-2)
00046  * @ret lcr             Line control register value
00047  */
00048 #define UART_LCR_WPS( word_len, parity, stop_bits )     \
00049         ( UART_LCR_WORD_LEN ( (word_len) ) |            \
00050           UART_LCR_PARITY ( (parity) ) |                \
00051           UART_LCR_STOP_BITS ( (stop_bits) ) )
00052 
00053 /** Default LCR value: 8 data bits, no parity, one stop bit */
00054 #define UART_LCR_8N1 UART_LCR_WPS ( 8, 0, 1 )
00055 
00056 /** Modem control register */
00057 #define UART_MCR 0x04
00058 #define UART_MCR_DTR    0x01    /**< Data terminal ready */
00059 #define UART_MCR_RTS    0x02    /**< Request to send */
00060 
00061 /** Line status register */
00062 #define UART_LSR 0x05
00063 #define UART_LSR_DR     0x01    /**< Data ready */
00064 #define UART_LSR_THRE   0x20    /**< Transmitter holding register empty */
00065 #define UART_LSR_TEMT   0x40    /**< Transmitter empty */
00066 
00067 /** Scratch register */
00068 #define UART_SCR 0x07
00069 
00070 /** Divisor latch (least significant byte) */
00071 #define UART_DLL 0x00
00072 
00073 /** Divisor latch (most significant byte) */
00074 #define UART_DLM 0x01
00075 
00076 /** Maximum baud rate */
00077 #define UART_MAX_BAUD 115200
00078 
00079 /** A 16550-compatible UART */
00080 struct uart {
00081         /** I/O port base address */
00082         void *base;
00083         /** Baud rate divisor */
00084         uint16_t divisor;
00085         /** Line control register */
00086         uint8_t lcr;
00087 };
00088 
00089 /** Symbolic names for port indexes */
00090 enum uart_port {
00091         COM1 = 1,
00092         COM2 = 2,
00093         COM3 = 3,
00094         COM4 = 4,
00095 };
00096 
00097 #include <bits/uart.h>
00098 
00099 void uart_write ( struct uart *uart, unsigned int addr, uint8_t data );
00100 uint8_t uart_read ( struct uart *uart, unsigned int addr );
00101 int uart_select ( struct uart *uart, unsigned int port );
00102 
00103 /**
00104  * Check if received data is ready
00105  *
00106  * @v uart              UART
00107  * @ret ready           Data is ready
00108  */
00109 static inline int uart_data_ready ( struct uart *uart ) {
00110         uint8_t lsr;
00111 
00112         lsr = uart_read ( uart, UART_LSR );
00113         return ( lsr & UART_LSR_DR );
00114 }
00115 
00116 /**
00117  * Receive data
00118  *
00119  * @v uart              UART
00120  * @ret data            Data
00121  */
00122 static inline uint8_t uart_receive ( struct uart *uart ) {
00123 
00124         return uart_read ( uart, UART_RBR );
00125 }
00126 
00127 extern void uart_transmit ( struct uart *uart, uint8_t data );
00128 extern void uart_flush ( struct uart *uart );
00129 extern int uart_exists ( struct uart *uart );
00130 extern int uart_init ( struct uart *uart, unsigned int baud, uint8_t lcr );
00131 
00132 #endif /* _IPXE_UART_H */