Changeset f4ef3c2 in mainline for uspace/srv/drivers/serial/serial.c


Ignore:
Timestamp:
2010-05-12T13:49:21Z (14 years ago)
Author:
Lenka Trochtova <trochtova.lenka@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f619943a
Parents:
08d9525a
Message:

add default client connection handler to serial port driver (for setting the parameters of the serial communication)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/drivers/serial/serial.c

    r08d9525a rf4ef3c2  
    5959#include <ipc/devman.h>
    6060#include <device/hw_res.h>
     61#include <ipc/serial_ctl.h>
    6162
    6263#include "cyclic_buffer.h"
     
    6566
    6667#define REG_COUNT 7
     68#define MAX_BAUD_RATE 115200
    6769
    6870typedef struct serial_dev_data {
     
    307309}
    308310
     311static 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
     317static inline void serial_port_interrupts_disable(ioport8_t *port)
     318{
     319        pio_write_8(port + 1, 0x00);    // Disable all interrupts
     320}
     321
    309322static int serial_interrupt_enable(device_t *dev)
    310323{
     
    318331       
    319332        // 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);
    322334       
    323335        return EOK;
    324336}
    325337
     338static 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
     361static 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
    326376static void serial_initialize_port(device_t *dev)
    327377{
     
    329379        ioport8_t *port = data->port;
    330380       
    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);
    335383        pio_write_8(port + 3, 0x07);    // 8 bits, no parity, two stop bits
    336384        pio_write_8(port + 2, 0xC7);    // Enable FIFO, clear them, with 14-byte threshold
     
    479527}
    480528
     529/** Default handler for client requests which are not handled by the standard interfaces.
     530 *
     531 * Configure the parameters of the serial communication.
     532 */
     533static 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
    481554/** Initialize the serial port driver.
    482555 *
     
    492565       
    493566        serial_dev_class.interfaces[CHAR_DEV_IFACE] = &serial_char_iface;
     567        serial_dev_class.default_handler = &serial_default_handler;
    494568}
    495569
Note: See TracChangeset for help on using the changeset viewer.