summaryrefslogtreecommitdiff
path: root/os/cerf405/uart.c
blob: 3d90f5ad9583e4131b70f976f2b5df90c9e28e15 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include	"u.h"
#include	"../port/lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"io.h"
#include	"ureg.h"

/*
 * uart for initial port
 */

typedef struct Uartregs Uartregs;
struct Uartregs {
	uchar	rbr;
#define	thr	rbr
#define	dll	rbr
	uchar	ier;
#define	dlm	ier
	uchar	fcr;
#define	iir	fcr
	uchar	lcr;
	uchar	mcr;
	uchar	lsr;
	uchar	msr;
	uchar	scr;
};

#define	UARTREGS(n)	((Uartregs*)(PHYSUART0+(n)*0x100))

enum {
	/* ier */
	Edssi=	1<<3,
	Elsi=		1<<2,
	Etbei=	1<<1,
	Erbfi=	1<<0,

	/* iir */
	Fci0=	0<<4,
	Fci3=	3<<4,
	Ipl=		7<<1,
	Ip=		1<<0,

	/* fcr */
	Rftl1=	0<<6,	/* receiver trigger level 1, 16, 32, 56 */
	Rftl16=	1<<6,
	Rftl32=	2<<6,
	Rftl56=	3<<6,
	Dms=	1<<3,	/* =0, single transfer; =1, multiple transfers */
	Tfr=		1<<2,	/* transmitter fifo reset */
	Rfr=		1<<1,	/* receiver fifo reset */
	Fifoe=	1<<0,	/* =0, disable fifos; =1, enable fifos */

	/* lcr */
	Dlab=	1<<7,	/* =0, normal; =1, dll/dlm visible */
	Sb=		1<<6,	/* set break */
	Sp=		1<<5,	/* =1, enable sticky parity */
	Eps=		1<<4,	/* =1, generate even parity */
	Pen=		1<<3,	/* =1, enable parity checking */
	Sbs=		1<<2,	/* =0, 1 stop bit; =1, 1.5 or 2 stop bits (see Wls) */
	Wls=		3<<0,	/* set to nbit-5 for nbit characters */

	/* mcr */
	Afc=		1<<5,	/* =1, auto flow control enabled */
	Loop=	1<<4,	/* =1, loop back mode enabled */
	Out2=	1<<3,	/* =0, OUT2# active */
	Out1=	1<<2,	/* =0, OUT1# active */
	Rts=		1<<1,	/* =0, RTS# inactive (1); =1, RTS# active (0) */
	Dtr=		1<<0,	/* =0, DTS# inactive; =1, DTS# active */

	/* lsr */
	Rfe=		1<<7,	/* error instances in fifo */
	Temt=	1<<6,	/* transmitter empty */
	Thre=	1<<5,	/* transmitter holding register/fifo empty */
	Be=		1<<4,	/* break (interrupt) */
	Fe=		1<<3,	/* framing error */
	Pe=		1<<2,	/* parity error */
	Oe=		1<<1,	/* overrun error */
	Dr=		1<<0,	/* receiver data ready */

	/* msr */
	Dcd=	1<<7,	/* follows Out2 */
	Ri=		1<<6,	/* follows Out1 */
	Dsr=		1<<5,	/* follows Dtr */
	Cts=		1<<4,	/* follows Rts */
	Ddcd=	1<<3,	/* Dcd input changed */
	Teri=	1<<2,	/* Ri changed from 0 to 1 */
	Ddsr=	1<<1,	/* Dsr input changed */
	Dcts=	1<<0,	/* Cts input changed */
};

void (*serwrite)(char*, int) = uartputs;

void
uartinstall(void)
{
}

void
uartspecial(int, int, Queue**, Queue**, int (*)(Queue*, int))
{
}

void
uartputc(int c)
{
	Uartregs *r;

	if(c == 0)
		return;
	r = UARTREGS(0);
	while((r->lsr & Thre) == 0)
		{}
	r->thr = c;
	if(c == '\n')
		while((r->lsr & Thre) == 0)	/* flush xmit fifo */
			{}
}

void
uartputs(char *data, int len)
{
	int s;

//	if(!uartspcl && !redirectconsole)
//		return;
	s = splhi();
	while(--len >= 0){
		if(*data == '\n')
			uartputc('\r');
		uartputc(*data++);
	}
	splx(s);
}

void
uartwait(void)
{
}