Cleaning up uart driver
This commit is contained in:
parent
2c49f5cec3
commit
f65ea0f131
1 changed files with 37 additions and 27 deletions
|
@ -1,42 +1,52 @@
|
||||||
//
|
|
||||||
// low-level driver routines for 16550a UART.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "param.h"
|
|
||||||
#include "memlayout.h"
|
#include "memlayout.h"
|
||||||
#include "riscv.h"
|
|
||||||
#include "spinlock.h"
|
#include "spinlock.h"
|
||||||
#include "proc.h"
|
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
// the UART control registers are memory-mapped
|
// the UART control registers are memory-mapped
|
||||||
// at address UART0. this macro returns the
|
// at address UART0. this macro returns the
|
||||||
// address of one of the registers.
|
// address of one of the registers.
|
||||||
#define Reg(reg) ((volatile unsigned char *)(UART0 + reg))
|
|
||||||
|
|
||||||
// the UART control registers.
|
|
||||||
// some have different meanings for
|
|
||||||
// read vs write.
|
|
||||||
// see http://byterunner.com/16550.html
|
|
||||||
#define RHR 0 // receive holding register (for input bytes)
|
|
||||||
#define THR 0 // transmit holding register (for output bytes)
|
|
||||||
#define IER 1 // interrupt enable register
|
|
||||||
#define IER_RX_ENABLE (1 << 0)
|
#define IER_RX_ENABLE (1 << 0)
|
||||||
#define IER_TX_ENABLE (1 << 1)
|
#define IER_TX_ENABLE (1 << 1)
|
||||||
#define FCR 2 // FIFO control register
|
|
||||||
#define FCR_FIFO_ENABLE (1 << 0)
|
#define FCR_FIFO_ENABLE (1 << 0)
|
||||||
#define FCR_FIFO_CLEAR (3 << 1) // clear the content of the two FIFOs
|
#define FCR_FIFO_CLEAR (3 << 1) // clear the content of the two FIFOs
|
||||||
#define ISR 2 // interrupt status register
|
|
||||||
#define LCR 3 // line control register
|
|
||||||
#define LCR_EIGHT_BITS (3 << 0)
|
#define LCR_EIGHT_BITS (3 << 0)
|
||||||
#define LCR_BAUD_LATCH (1 << 7) // special mode to set baud rate
|
#define LCR_BAUD_LATCH (1 << 7) // special mode to set baud rate
|
||||||
#define LSR 5 // line status register
|
|
||||||
#define LSR_RX_READY (1 << 0) // input is waiting to be read from RHR
|
#define LSR_RX_READY (1 << 0) // input is waiting to be read from RHR
|
||||||
#define LSR_TX_IDLE (1 << 5) // THR can accept another character to send
|
#define LSR_TX_IDLE (1 << 5) // THR can accept another character to send
|
||||||
|
|
||||||
#define ReadReg(reg) (*(Reg(reg)))
|
/*
|
||||||
#define WriteReg(reg, v) (*(Reg(reg)) = (v))
|
* Keep in mind that some of these registers share locations, but have different
|
||||||
|
* meaning depending on direction
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
volatile u8 rbr_thr_dll; // 0x00: RBR (read), THR (write), DLL (when DLAB=1)
|
||||||
|
volatile u8 ier_dlm; // 0x01: IER (when DLAB=0), DLM (when DLAB=1)
|
||||||
|
volatile u8 iir_fcr; // 0x02: Interrupt Identification Register (read), FIFO Control Register (write)
|
||||||
|
volatile u8 lcr; // 0x03: Line Control Register
|
||||||
|
volatile u8 mcr; // 0x04: Modem Control Register
|
||||||
|
volatile u8 lsr; // 0x05: Line Status Register
|
||||||
|
volatile u8 msr; // 0x06: Modem Status Register
|
||||||
|
volatile u8 scr; // 0x07: Scratch Register
|
||||||
|
} uart16550_t;
|
||||||
|
|
||||||
|
#define UART ((uart16550_t *)UART0)
|
||||||
|
|
||||||
|
#define THR rbr_thr_dll
|
||||||
|
#define RBR rbr_thr_dll
|
||||||
|
#define DLL rbr_thr_dll
|
||||||
|
#define IER ier_dlm
|
||||||
|
#define DLM ier_dlm
|
||||||
|
#define FCR iir_fcr
|
||||||
|
#define IIR iir_fcr
|
||||||
|
#define LCR lcr
|
||||||
|
#define LSR lsr
|
||||||
|
#define RHR THR
|
||||||
|
|
||||||
|
// TODO: Remove these
|
||||||
|
#define ReadReg(reg) ((UART)->reg)
|
||||||
|
#define WriteReg(reg, v) ((UART)->reg = (v))
|
||||||
|
|
||||||
// the transmit output buffer.
|
// the transmit output buffer.
|
||||||
struct spinlock uart_tx_lock;
|
struct spinlock uart_tx_lock;
|
||||||
|
@ -52,17 +62,17 @@ void uartstart();
|
||||||
void
|
void
|
||||||
uartinit(void)
|
uartinit(void)
|
||||||
{
|
{
|
||||||
// disable interrupts.
|
// WriteReg(IER, 0x00);
|
||||||
WriteReg(IER, 0x00);
|
UART->ier_dlm = 0x00; // disable interrupts.
|
||||||
|
|
||||||
// special mode to set baud rate.
|
UART->lcr = LCR_BAUD_LATCH; // special mode to set baud rate.
|
||||||
WriteReg(LCR, LCR_BAUD_LATCH);
|
// WriteReg(LCR, LCR_BAUD_LATCH);
|
||||||
|
|
||||||
// LSB for baud rate of 38.4K.
|
// LSB for baud rate of 38.4K.
|
||||||
WriteReg(0, 0x03);
|
WriteReg(DLL, 0x03);
|
||||||
|
|
||||||
// MSB for baud rate of 38.4K.
|
// MSB for baud rate of 38.4K.
|
||||||
WriteReg(1, 0x00);
|
WriteReg(DLL, 0x00);
|
||||||
|
|
||||||
// leave set-baud mode,
|
// leave set-baud mode,
|
||||||
// and set word length to 8 bits, no parity.
|
// and set word length to 8 bits, no parity.
|
||||||
|
|
Loading…
Add table
Reference in a new issue