Direct support for serial mouse in kernel - it is recognized as /dev/mousecom; added...
[ZeXOS.git] / kernel / drivers / char / rs232 / rs232.c
blob5f804545d16d38b839c7633cc352986e4a1d338b
1 /*
2 * ZeX/OS
3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
4 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
5 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include <build.h>
23 #include <config.h>
24 #include <system.h>
25 #include <arch/io.h>
26 #include <rs232.h>
28 #ifdef ARCH_arm
29 typedef struct {
30 unsigned char c : 8;
31 unsigned fr_err : 1;
32 unsigned par_err : 1;
33 unsigned break_err : 1;
34 unsigned ovrrun_err : 1;
35 } __attribute__ ((__packed__)) arm_rcv_block;
36 #endif
38 unsigned int init_rs232 ()
40 #ifdef ARCH_i386
41 int baud = CONFIG_DRV_RS232BAUDS; // Set to 9600 baud
43 unsigned divisor = (unsigned) (115200L / baud);
45 outb (PORT + 1, 0x00); // Disable all interrupts
46 outb (PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
47 outb (PORT + 0, divisor); // Set divisor to 3 (lo byte) 38400 baud
48 divisor >>= 8;
49 outb (PORT + 1, divisor); // (hi byte)
50 outb (PORT + 3, 0x03); // 8 bits, no parity, one stop bit
51 outb (PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
52 outb (PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
53 #endif
54 #ifdef ARCH_arm
56 #endif
57 return 1;
60 int serial_recieved()
62 #ifdef ARCH_i386
63 return inb (PORT + 5) & 1;
64 #endif
67 #ifdef ARCH_arm
68 int arm_uart_write (int port, unsigned char c)
70 unsigned char *uart_addr = (unsigned char *) ARM9_INTEGRATOR_UART0_ADDR;
72 if (port)
73 uart_addr = (unsigned char *) ARM9_INTEGRATOR_UART1_ADDR;
75 uart_addr += ARM_PL011_UARTDR * 4;
77 *uart_addr = c;
79 return 1;
82 unsigned char arm_uart_received (int port)
84 unsigned *uart_addr = (unsigned *) ARM9_INTEGRATOR_UART0_ADDR;
86 if (port)
87 uart_addr = (unsigned *) ARM9_INTEGRATOR_UART1_ADDR;
89 uart_addr += 6;
91 //kprintf ("uart: 0x%x : RXFE %d / TXFE %d\n", *uart_addr, (*uart_addr & ARM_PL011_UARTFLAG_RXFE) ? 1 : 0, (*uart_addr & ARM_PL011_UARTFLAG_TXFE) ? 1 : 0);
93 if (*uart_addr & ARM_PL011_UARTFLAG_RXFE)
94 return 0;
96 return 1;
99 unsigned char arm_uart_read (int port)
101 arm_rcv_block *uart_addr = (arm_rcv_block *) ARM9_INTEGRATOR_UART0_ADDR;
103 if (port)
104 uart_addr = (arm_rcv_block *) ARM9_INTEGRATOR_UART1_ADDR;
106 //unsigned char err = 0;
108 /* there is error on uart, lets clean it */
109 /*if (uart_addr->ovrrun_err)
110 err ++;
112 if (uart_addr->break_err)
113 err ++;
115 if (uart_addr->par_err)
116 err ++;
118 if (uart_addr->fr_err) {
119 err ++;*/
121 return uart_addr->c;
123 #endif
125 char rs232_read_nonblock ()
127 #ifdef ARCH_i386
128 int r = serial_recieved ();
130 if (r == 0)
131 return 0;
133 return inb (PORT);
134 #endif
135 #ifdef ARCH_arm
136 return (char) arm_uart_read (0);
137 #endif
141 char rs232_read ()
143 #ifdef ARCH_i386
144 while (serial_recieved () == 0)
145 schedule ();
147 return inb (PORT);
148 #endif
149 #ifdef ARCH_arm
150 if (arm_uart_received (0))
151 return (char) arm_uart_read (0);
152 else
153 return 0;
155 #endif
158 #ifdef ARCH_i386
159 int is_transmit_empty ()
161 return inb (PORT + 5) & 0x20;
163 #endif
165 void rs232_write (char a)
167 #ifdef ARCH_i386
168 while (is_transmit_empty() == 0) {
169 schedule ();
170 continue;
173 outb (PORT, a);
174 #endif
176 #ifdef ARCH_arm
177 arm_uart_write (0, (unsigned char) a);
178 #endif
181 bool rs232_acthandler (unsigned act, char *block, unsigned block_len)
183 switch (act) {
184 case DEV_ACT_INIT:
186 init_rs232 ();
188 return 1;
190 break;
191 case DEV_ACT_READ:
193 unsigned len = 0;
195 while (len != block_len) {
196 block[len] = rs232_read ();
197 len ++;
200 return 1;
202 break;
203 case DEV_ACT_WRITE:
205 unsigned len = 0;
207 while (len != block_len) {
208 rs232_write (block[len]);
209 len ++;
212 return 1;
214 break;
217 return 0;