2011-12-11 03:34:10 +04:00
|
|
|
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
|
|
|
*
|
2011-02-11 06:45:29 +03:00
|
|
|
* Serial Port Driver
|
|
|
|
*/
|
|
|
|
#include <system.h>
|
2011-12-15 05:06:11 +04:00
|
|
|
#include <logging.h>
|
2011-02-11 06:45:29 +03:00
|
|
|
|
2012-11-29 11:05:19 +04:00
|
|
|
#if 0
|
|
|
|
void serial_handler_a(struct regs *r) {
|
|
|
|
char serial = serial_recv(SERIAL_PORT_A);
|
2012-02-05 08:29:46 +04:00
|
|
|
irq_ack(SERIAL_IRQ);
|
2012-11-29 11:05:19 +04:00
|
|
|
if (serial == 13) serial = '\n';
|
|
|
|
kprintf("%c", serial);
|
|
|
|
serial_send(SERIAL_PORT_B, serial);
|
|
|
|
}
|
|
|
|
void serial_handler_b(struct regs *r) {
|
|
|
|
char serial = serial_recv(SERIAL_PORT_B);
|
|
|
|
irq_ack(SERIAL_IRQ - 1);
|
|
|
|
serial_send(SERIAL_PORT_A, serial);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void serial_enable(int device) {
|
|
|
|
outportb(device + 1, 0x00);
|
|
|
|
outportb(device + 3, 0x80); /* Enable divisor mode */
|
2013-04-15 12:26:03 +04:00
|
|
|
outportb(device + 0, 0x01); /* Div Low: 01 Set the port to 115200 bps */
|
2012-11-29 11:05:19 +04:00
|
|
|
outportb(device + 1, 0x00); /* Div High: 00 */
|
|
|
|
outportb(device + 3, 0x03);
|
|
|
|
outportb(device + 2, 0xC7);
|
|
|
|
outportb(device + 4, 0x0B);
|
2011-02-20 00:27:41 +03:00
|
|
|
}
|
|
|
|
|
2011-02-11 06:45:29 +03:00
|
|
|
void
|
|
|
|
serial_install() {
|
2012-12-08 06:33:07 +04:00
|
|
|
debug_print(NOTICE, "Installing serial communication driver");
|
2012-11-29 11:05:19 +04:00
|
|
|
|
|
|
|
serial_enable(SERIAL_PORT_A);
|
|
|
|
serial_enable(SERIAL_PORT_B);
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
irq_install_handler(SERIAL_IRQ, serial_handler_a); /* Install the serial input handler */
|
|
|
|
irq_install_handler(SERIAL_IRQ - 1, serial_handler_b); /* Install the serial input handler */
|
2011-02-20 00:27:41 +03:00
|
|
|
outportb(SERIAL_PORT_A + 1, 0x01); /* Enable interrupts on receive */
|
2012-11-29 11:05:19 +04:00
|
|
|
outportb(SERIAL_PORT_B + 1, 0x01); /* Enable interrupts on receive */
|
|
|
|
#endif
|
2011-02-11 06:45:29 +03:00
|
|
|
}
|
|
|
|
|
2012-11-29 11:05:19 +04:00
|
|
|
int serial_rcvd(int device) {
|
|
|
|
return inportb(device + 5) & 1;
|
2011-02-11 06:45:29 +03:00
|
|
|
}
|
|
|
|
|
2012-11-29 11:05:19 +04:00
|
|
|
char serial_recv(int device) {
|
|
|
|
while (serial_rcvd(device) == 0) ;
|
|
|
|
return inportb(device);
|
2011-02-11 06:45:29 +03:00
|
|
|
}
|
|
|
|
|
2012-11-29 11:05:19 +04:00
|
|
|
char serial_recv_async(int device) {
|
|
|
|
return inportb(device);
|
2011-02-11 06:45:29 +03:00
|
|
|
}
|
|
|
|
|
2012-11-29 11:05:19 +04:00
|
|
|
int serial_transmit_empty(int device) {
|
|
|
|
return inportb(device + 5) & 0x20;
|
2011-02-11 06:45:29 +03:00
|
|
|
}
|
2011-04-05 03:51:55 +04:00
|
|
|
|
2012-11-29 11:05:19 +04:00
|
|
|
void serial_send(int device, char out) {
|
|
|
|
while (serial_transmit_empty(device) == 0);
|
|
|
|
outportb(device, out);
|
|
|
|
}
|
|
|
|
|
|
|
|
void serial_string(int device, char * out) {
|
2011-11-18 10:00:54 +04:00
|
|
|
for (uint32_t i = 0; i < strlen(out); ++i) {
|
2012-11-29 11:05:19 +04:00
|
|
|
serial_send(device, out[i]);
|
2011-04-05 03:51:55 +04:00
|
|
|
}
|
|
|
|
}
|