Removed unneeded function.
[AROS.git] / arch / i386-pc / exec / serialrawio.c
blob49c86b9044bd501f6688424af390bc02b4281f04
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: functions for serial RawIOInit/RawPutChar
6 Lang: english
8 Note: serial io from "PC-intern" examples
9 */
10 #include <proto/exec.h>
11 #include <asm/io.h>
13 #undef __save_flags
14 #undef __restore_flags
15 #undef __cli
16 #undef __sti
18 #define __save_flags(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */)
19 #define __restore_flags(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory", "cc")
20 #define __cli() __asm__ __volatile__("cli": : :"memory")
21 #define __sti() __asm__ __volatile__("sti": : :"memory")
23 #define SER_ERRSIGNALS 0x0300
25 #define SER_LSR_OVERRUNERROR 0x02
26 #define SER_LSR_PARITYERROR 0x04
27 #define SER_LSR_FRAMINGERROR 0x08
28 #define SER_LSR_BREAKDETECT 0x10
29 #define SER_LSR_ERRORMSK (SER_LSR_OVERRUNERROR|SER_LSR_PARITYERROR|\
30 SER_LSR_FRAMINGERROR|SER_LSR_BREAKDETECT)
31 #define SER_LSR_TSREMPTY 0x40
33 #define SER_LCR_8BITS 0x03
34 #define SER_LCR_1STOPBIT 0x00
35 #define SER_LCR_NOPARITY 0x00
36 #define SER_LCR_SETDIVISOR 0x80
38 #define SER_TXBUFFER 0x00
39 #define SER_DIVISOR_LSB 0x00
40 #define SER_DIVISOR_MSB 0x01
41 #define SER_IRQ_ENABLE 0x01
42 #define SER_IRQ_ID 0x02
43 #define SER_FIFO 0x02
44 #define SER_2FUNCTION 0x02
45 #define SER_LINE_CONTROL 0x03
46 #define SER_MODEM_CONTROL 0x04
47 #define SER_LINE_STATUS 0x05
48 #define SER_MODEM_STATUS 0x06
49 #define SER_SCRATCH 0x07
51 #define SER_MCR_DTR 0x01
52 #define SER_MCR_RTS 0x02
53 #define SER_MCR_LOOP 0x10
55 #define SER_FIFO_ENABLE 0x01
56 #define SER_FIFO_RESETRECEIVE 0x02
57 #define SER_FIFO_RESETTRANSMIT 0x04
59 #define SER_MAXBAUD 115200L
61 #if AROS_SERIAL_DEBUG == 2
62 UWORD __serial_rawio_port = 0x2F8;
63 #else
64 UWORD __serial_rawio_port = 0x3F8;
65 #endif
67 int ser_UARTType (short);
68 void ser_FIFOLevel(short, BYTE);
69 int ser_Init(short, LONG, BYTE);
71 /*****i***********************************************************************
73 NAME */
74 AROS_LH0(void, SerialRawIOInit,
76 /* LOCATION */
77 struct ExecBase *, SysBase, 84, Exec)
79 /* FUNCTION
80 This is a private function. It initializes raw IO. After you
81 have called this function, you can use (!RawMayGetChar()) and
82 RawPutChar().
84 INPUTS
85 None.
87 RESULT
88 None.
90 NOTES
91 This function is for very low level debugging only.
93 EXAMPLE
95 BUGS
97 SEE ALSO
98 RawPutChar(), RawMayGetChar()
100 INTERNALS
102 HISTORY
104 *****************************************************************************/
106 AROS_LIBFUNC_INIT
107 if (__serial_rawio_port > 0)
109 if (ser_Init(__serial_rawio_port, SER_MAXBAUD, SER_LCR_8BITS | SER_LCR_1STOPBIT | SER_LCR_NOPARITY))
110 ser_FIFOLevel(__serial_rawio_port, 0);
113 return;
114 AROS_LIBFUNC_EXIT
115 } /* RawIOInit */
117 int ser_UARTType (short port) {
119 outb_p(0xAA, port+SER_LINE_CONTROL); /* set Divisor-Latch */
120 if (inb_p(port+SER_LINE_CONTROL) != 0xAA)
121 return 1;
122 outb_p(0x55, port+SER_DIVISOR_MSB); /* write Divisor */
123 if (inb_p(port+SER_DIVISOR_MSB) != 0x55)
124 return 1;
125 outb_p(0x55, port+SER_LINE_CONTROL); /* clear Divisor-Latch */
126 if (inb_p(port+SER_LINE_CONTROL) != 0x55)
127 return 1;
128 outb_p(0x55, port+SER_IRQ_ENABLE);
129 if (inb_p(port+SER_IRQ_ENABLE) != 0x05)
130 return 1;
131 outb_p(0, port+SER_FIFO); /* clear FIFO and IRQ */
132 outb_p(0, port+SER_IRQ_ENABLE);
133 if (inb_p(port+SER_IRQ_ID) != 1)
134 return 1;
135 outb_p(0xF5, port+SER_MODEM_CONTROL);
136 if (inb_p(port+SER_MODEM_CONTROL) != 0x15)
137 return 1;
138 outb_p(SER_MCR_LOOP, port+SER_MODEM_CONTROL); /* Looping */
139 inb_p(port+SER_MODEM_STATUS);
140 if ((inb_p(port+SER_MODEM_STATUS) & 0xF0) != 0)
141 return 1;
142 outb_p(0x1F, port+SER_MODEM_CONTROL);
143 if ((inb_p(port+SER_MODEM_STATUS) & 0xF0) != 0xF0)
144 return 1;
145 outb_p(SER_MCR_DTR | SER_MCR_RTS, port + SER_MODEM_CONTROL);
147 outb_p(0x55, port+SER_SCRATCH); /* Scratch-Register ?*/
148 if (inb_p(port+SER_SCRATCH) != 0x55)
149 return 2; //INS8250;
150 outb_p(0, port+SER_SCRATCH);
152 outb_p(0xCF, port+SER_FIFO); /* FIFO ? */
153 if ((inb_p(port+SER_IRQ_ID) & 0xC0) != 0xC0)
154 return 3; //NS16450;
155 outb_p(0, port+SER_FIFO);
156 /* Alternate-Function Register ? */
157 outb_p(SER_LCR_SETDIVISOR, port+SER_LINE_CONTROL);
158 outb_p(0x07, port+SER_2FUNCTION);
159 if (inb_p(port+SER_2FUNCTION ) != 0x07)
161 outb_p(0, port+SER_LINE_CONTROL);
162 return 4; //NS16550A;
164 outb_p(0, port+SER_LINE_CONTROL); /* reset registers */
165 outb_p(0, port+SER_2FUNCTION);
166 return 5; //NS16C552;
169 void ser_FIFOLevel(short port, BYTE level) {
171 if (level)
172 outb_p(level | SER_FIFO_ENABLE, port+SER_FIFO);
173 else
174 outb_p(SER_FIFO_RESETRECEIVE | SER_FIFO_RESETTRANSMIT, port+SER_FIFO);
177 int ser_Init(short port, LONG baudRate, BYTE params) {
178 WORD uDivisor;
180 if (ser_UARTType(port)!=1)
182 uDivisor=(WORD)(SER_MAXBAUD / baudRate);
183 outb_p(inb_p(port+SER_LINE_CONTROL) | SER_LCR_SETDIVISOR, port+SER_LINE_CONTROL);
184 outb_p(uDivisor & 0xFF, port+SER_DIVISOR_LSB);
185 outb_p(uDivisor>>8, port+SER_DIVISOR_MSB);
186 outb_p(inb_p(port+SER_LINE_CONTROL) & ~SER_LCR_SETDIVISOR, port+SER_LINE_CONTROL);
188 outb_p(params, port+SER_LINE_CONTROL);
189 inb_p(port+SER_TXBUFFER);
190 return 1;
192 return 0;
195 int ser_WriteByte(short, UBYTE , ULONG , BYTE , BYTE );
196 int ser_IsWritingPossible(short);
199 AROS_LH1(void, SerialRawPutChar,
201 /* SYNOPSIS */
202 AROS_LHA(UBYTE, chr, D0),
204 /* LOCATION */
205 struct ExecBase *, SysBase, 86, Exec)
207 /* FUNCTION
208 Emits a single character.
210 INPUTS
211 chr - The character to emit
213 RESULT
214 None.
216 NOTES
217 This function is for very low level debugging only.
219 EXAMPLE
221 BUGS
223 SEE ALSO
224 RawIOInit(), RawPutChar(), RawMayGetChar()
226 INTERNALS
228 HISTORY
230 *****************************************************************************/
232 AROS_LIBFUNC_INIT
234 unsigned long flags;
236 if ((__serial_rawio_port > 0) && (chr))
238 __save_flags(flags);
240 /* stegerg: Don't use Disable/Enable, because we want
241 interrupt enabled flag to stay the same as
242 it was before the Disable() call */
243 __cli();
245 if (chr==0x0A)
247 // Send <CR> before <LF>
248 ser_WriteByte(__serial_rawio_port, 0x0D, 0, 0, 0);
250 ser_WriteByte(__serial_rawio_port, chr, 0, 0, 0);
252 /* Interrupt flag is stored in flags - if it was
253 enabled before, it will be renabled when the flags
254 are restored */
255 __restore_flags(flags);
258 AROS_LIBFUNC_EXIT
259 } /* RawPutChar */
261 int ser_IsWritingPossible(short port) {
263 return inb_p(port+SER_LINE_STATUS) & SER_LSR_TSREMPTY;
266 int ser_WriteByte(short port, UBYTE data, ULONG timeout, BYTE sigmask, BYTE sigvals) {
268 if (timeout)
270 while (!ser_IsWritingPossible(port) && timeout)
271 timeout--;
272 if (!timeout)
273 return 1;
275 else
276 while (!ser_IsWritingPossible(port));
278 if ((inb_p(port+SER_MODEM_STATUS) & sigmask) == sigvals)
280 outb_p(data, port+SER_TXBUFFER);
281 return inb_p(port+SER_LINE_STATUS) & SER_LSR_ERRORMSK;
283 else
284 return SER_ERRSIGNALS;