Changeset f4ef3c2 in mainline
- Timestamp:
- 2010-05-12T13:49:21Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f619943a
- Parents:
- 08d9525a
- Location:
- uspace
- Files:
-
- 1 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/drivers/serial/serial.c
r08d9525a rf4ef3c2 59 59 #include <ipc/devman.h> 60 60 #include <device/hw_res.h> 61 #include <ipc/serial_ctl.h> 61 62 62 63 #include "cyclic_buffer.h" … … 65 66 66 67 #define REG_COUNT 7 68 #define MAX_BAUD_RATE 115200 67 69 68 70 typedef struct serial_dev_data { … … 307 309 } 308 310 311 static inline void serial_port_interrupts_enable(ioport8_t *port) 312 { 313 pio_write_8(port + 1 , 0x01); // Interrupt when data received 314 pio_write_8(port + 4, 0x0B); 315 } 316 317 static inline void serial_port_interrupts_disable(ioport8_t *port) 318 { 319 pio_write_8(port + 1, 0x00); // Disable all interrupts 320 } 321 309 322 static int serial_interrupt_enable(device_t *dev) 310 323 { … … 318 331 319 332 // enable interrupt on the serial port 320 pio_write_8(data->port + 1 , 0x01); // Interrupt when data received 321 pio_write_8(data->port + 4, 0x0B); 333 serial_port_interrupts_enable(data->port); 322 334 323 335 return EOK; 324 336 } 325 337 338 static int serial_port_set_baud_rate(ioport8_t *port, unsigned int baud_rate) 339 { 340 uint16_t divisor; 341 uint8_t div_low, div_high; 342 343 if (50 > baud_rate || 0 != MAX_BAUD_RATE % baud_rate) { 344 return EINVAL; 345 } 346 347 divisor = MAX_BAUD_RATE / baud_rate; 348 div_low = (uint8_t)divisor; 349 div_high = (uint8_t)(divisor >> 8); 350 351 pio_write_8(port + 3, 0x80); // Enable DLAB (set baud rate divisor) 352 353 pio_write_8(port + 0, div_low); // Set divisor low byte 354 pio_write_8(port + 1, div_high); // Set divisor high byte 355 356 pio_write_8(port + 3, pio_read_8(port + 3) & (~0x80)); // Clear DLAB 357 358 return EOK; 359 } 360 361 static int serial_set_baud_rate(device_t *dev, unsigned int baud_rate) 362 { 363 serial_dev_data_t *data = (serial_dev_data_t *)dev->driver_data; 364 ioport8_t *port = data->port; 365 int ret; 366 367 fibril_mutex_lock(&data->mutex); 368 serial_port_interrupts_disable(port); // Disable all interrupts 369 ret = serial_port_set_baud_rate(port, baud_rate); 370 serial_port_interrupts_enable(port); 371 fibril_mutex_unlock(&data->mutex); 372 373 return ret; 374 } 375 326 376 static void serial_initialize_port(device_t *dev) 327 377 { … … 329 379 ioport8_t *port = data->port; 330 380 331 pio_write_8(port + 1, 0x00); // Disable all interrupts 332 pio_write_8(port + 3, 0x80); // Enable DLAB (set baud rate divisor) 333 pio_write_8(port + 0, 0x60); // Set divisor to 96 (lo byte) 1200 baud 334 pio_write_8(port + 1, 0x00); // (hi byte) 381 serial_port_interrupts_disable(port); // Disable all interrupts 382 serial_port_set_baud_rate(port, 1200); 335 383 pio_write_8(port + 3, 0x07); // 8 bits, no parity, two stop bits 336 384 pio_write_8(port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold … … 479 527 } 480 528 529 /** Default handler for client requests which are not handled by the standard interfaces. 530 * 531 * Configure the parameters of the serial communication. 532 */ 533 static void serial_default_handler(device_t *dev, ipc_callid_t callid, ipc_call_t *call) 534 { 535 ipcarg_t method = IPC_GET_METHOD(*call); 536 int ret; 537 538 switch(method) { 539 case SERIAL_SET_BAUD_RATE: 540 ret = serial_set_baud_rate(dev, IPC_GET_ARG1(*call)); 541 ipc_answer_0(callid, ret); 542 break; 543 case SERIAL_SET_PARITY: 544 // TODO 545 break; 546 case SERIAL_SET_STOP_BITS: 547 // TODO 548 break; 549 default: 550 ipc_answer_0(callid, ENOTSUP); 551 } 552 } 553 481 554 /** Initialize the serial port driver. 482 555 * … … 492 565 493 566 serial_dev_class.interfaces[CHAR_DEV_IFACE] = &serial_char_iface; 567 serial_dev_class.default_handler = &serial_default_handler; 494 568 } 495 569
Note:
See TracChangeset
for help on using the changeset viewer.