⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftdi.c

📁 usb to rs232 converter source code
💻 C
字号:
/* * This file is a part of BeOS USB Serial driver project. * Copyright (c) 2003 by Siarzuk Zharski <imker@gmx.li> * * This file may be used under the terms of the BSD License * See the file "License" for details. *  * $Source: /cvsroot/sis4be/usb_serial/ftdi.c,v $ * $Author: zharik $ * $Revision: 1.2 $ * $Date: 2003/10/05 17:44:52 $ * */#include <KernelExport.h>#include <Drivers.h>#include <USB.h>#include <ttylayer.h>#include "driver.h"#include "ftdi.h"#include "uftdireg.h"status_t add_ftdi_device(usb_serial_device *usd,                         const usb_configuration_info *uci){  struct usb_endpoint_info *comm_epi = NULL;  struct usb_endpoint_info *data_out_epi = NULL;  struct usb_endpoint_info *data_in_epi  = NULL;  status_t status = ENODEV;  int i = 0;  TRACE_FUNCALLS("> add_ftdi_device(%08x, %08x)\n", usd, uci);  if(uci->interface_count){    struct usb_interface_info *uii = uci->interface[0].active;    for(i = 0; i < uii->endpoint_count; i++){      if(uii->endpoint[i].descr->attributes == USB_EP_ATTR_BULK){        if((uii->endpoint[i].descr->endpoint_address & USB_EP_ADDR_DIR_IN)                                                       == USB_EP_ADDR_DIR_IN){          data_in_epi = &uii->endpoint[i];        }else{          if(uii->endpoint[i].descr->endpoint_address                          /*USB_EP_ADDR_DIR_OUT = 0x0*/){            comm_epi = data_out_epi = &uii->endpoint[i];          }        }      }    }      if(comm_epi && data_in_epi && data_out_epi){      if(usd->hw->product_id == PROD_8U100AX)        usd->spec.ftdi.hdrlen = 1;      else        usd->spec.ftdi.hdrlen = 0;          usd->read_buffer_size =       usd->write_buffer_size =      usd->interrupt_buffer_size = ROUNDUP(FTDI_BUF_SIZE, 16);      status = add_device(usd, uci, comm_epi, data_out_epi, data_in_epi);    }  }    TRACE_FUNCRET("< add_ftdi_device returns:%08x\n", status);  return status;}status_t reset_ftdi_device(usb_serial_device *usd){  status_t status = B_OK;  size_t len = 0;  TRACE_FUNCALLS("> reset_ftdi_device(%08x)\n", usd);  status = (*usb_m->send_request)(usd->dev,                                  USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,                                  FTDI_SIO_RESET, FTDI_SIO_RESET_SIO,                                  FTDI_PIT_DEFAULT, 0, 0, 0, &len);  TRACE_FUNCRET("< reset_ftdi_device returns:%08x\n", status);  return status;}status_t set_line_coding_ftdi(usb_serial_device *usd,                              usb_serial_line_coding *line_coding){  status_t status = B_OK;  int32 rate, data;  size_t len1 = 0, len2 = 0;  TRACE_FUNCALLS("> set_line_coding_ftdi(%08x, {%d, %02x, %02x, %02x})\n",                                        usd, line_coding->speed,                                        line_coding->stopbits,                                        line_coding->parity,                                        line_coding->databits);    if(usd->hw->product_id == PROD_8U100AX){    switch (line_coding->speed){      case 300: rate = ftdi_sio_b300; break;      case 600: rate = ftdi_sio_b600; break;      case 1200: rate = ftdi_sio_b1200; break;      case 2400: rate = ftdi_sio_b2400; break;      case 4800: rate = ftdi_sio_b4800; break;      case 9600: rate = ftdi_sio_b9600; break;      case 19200: rate = ftdi_sio_b19200; break;      case 38400: rate = ftdi_sio_b38400; break;      case 57600: rate = ftdi_sio_b57600; break;      case 115200: rate = ftdi_sio_b115200; break;      default:        rate = ftdi_sio_b19200;        TRACE_ALWAYS("= set_line_coding_ftdi: Datarate:%d is not supported "                     "by this hardware. Defaulted to %d\n",                                        line_coding->speed, rate);      break;     }  }else{    switch(line_coding->speed){      case 300: rate = ftdi_8u232am_b300; break;      case 600: rate = ftdi_8u232am_b600; break;      case 1200: rate = ftdi_8u232am_b1200; break;      case 2400: rate = ftdi_8u232am_b2400; break;      case 4800: rate = ftdi_8u232am_b4800; break;      case 9600: rate = ftdi_8u232am_b9600; break;      case 19200: rate = ftdi_8u232am_b19200; break;      case 38400: rate = ftdi_8u232am_b38400; break;      case 57600: rate = ftdi_8u232am_b57600; break;      case 115200: rate = ftdi_8u232am_b115200; break;      case 230400: rate = ftdi_8u232am_b230400; break;      case 460800: rate = ftdi_8u232am_b460800; break;      case 921600: rate = ftdi_8u232am_b921600; break;      default:        rate = ftdi_sio_b19200;        TRACE_ALWAYS("= set_line_coding_ftdi: Datarate:%d is not supported "                     "by this hardware. Defaulted to %d\n",                                        line_coding->speed, rate);        break;    }  }    status = (*usb_m->send_request)(usd->dev,                                  USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,                                  FTDI_SIO_SET_BAUD_RATE, rate,                                  FTDI_PIT_DEFAULT, 0, 0, 0, &len1);  if(status != B_OK)    TRACE_ALWAYS("= set_line_coding_ftdi: datarate set request failed:%08x",                                                                     status);    switch(line_coding->stopbits){    case LC_STOP_BIT_2: data = FTDI_SIO_SET_DATA_STOP_BITS_2; break;    case LC_STOP_BIT_1: data = FTDI_SIO_SET_DATA_STOP_BITS_1; break;    default:      TRACE_ALWAYS("= set_line_coding_ftdi: Wrong stopbits param:%d",                                                      line_coding->stopbits);      break;  }    switch(line_coding->parity){    case LC_PARITY_NONE: data |= FTDI_SIO_SET_DATA_PARITY_NONE; break;    case LC_PARITY_EVEN: data |= FTDI_SIO_SET_DATA_PARITY_EVEN; break;    case LC_PARITY_ODD:  data |= FTDI_SIO_SET_DATA_PARITY_ODD; break;    default:      TRACE_ALWAYS("= set_line_coding_ftdi: Wrong parity param:%d",                                                        line_coding->parity);      break;  }    switch(line_coding->databits){    case 8: data |= FTDI_SIO_SET_DATA_BITS(8); break;    case 7: data |= FTDI_SIO_SET_DATA_BITS(7); break;    default:      TRACE_ALWAYS("= set_line_coding_ftdi: Wrong databits param:%d",                                                        line_coding->databits);      break;  }  status = (*usb_m->send_request)(usd->dev,                                  USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,                                  FTDI_SIO_SET_DATA, data,                                  FTDI_PIT_DEFAULT, 0, 0, 0, &len2);  if(status != B_OK)    TRACE_ALWAYS("= set_line_coding_ftdi: data set request failed:%08x",                                                                   status);      TRACE_FUNCRET("< set_line_coding_ftdi returns:%08x\n", status);  return status;}status_t set_control_line_state_ftdi(usb_serial_device *usd, uint16 state){  status_t status = B_OK;  int32 ctrl;  size_t len = 0;  TRACE_FUNCALLS("> set_control_line_state_ftdi(%08x, %04x)\n", usd, state);    ctrl = (state & CLS_LINE_RTS) ?                         FTDI_SIO_SET_RTS_HIGH : FTDI_SIO_SET_RTS_LOW;  ctrl |= (state & CLS_LINE_DTR) ?                         FTDI_SIO_SET_DTR_HIGH : FTDI_SIO_SET_DTR_LOW;  status = (*usb_m->send_request)(usd->dev,                                  USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,                                  FTDI_SIO_MODEM_CTRL, ctrl,                                  FTDI_PIT_DEFAULT, 0, 0, 0, &len);  if(status != B_OK)    TRACE_ALWAYS("= set_control_line_state_ftdi: control set request "                 "failed:%08x", status);      TRACE_FUNCRET("< set_control_line_state_ftdi returns:%08x\n", status);  return status;}void on_read_ftdi(usb_serial_device *usd, char **buf, size_t *num_bytes){  usd->spec.ftdi.status_msr = FTDI_GET_MSR(*buf);  usd->spec.ftdi.status_lsr = FTDI_GET_LSR(*buf);  TRACE("MSR:%02x LSR:%02x\n", usd->spec.ftdi.status_msr,                               usd->spec.ftdi.status_lsr);  *buf += 2;  *num_bytes -= 2;}void on_write_ftdi(usb_serial_device *usd, const char *buf,                   size_t *num_bytes){  char *buf_to = usd->write_buffer;  int hdrlen = usd->spec.ftdi.hdrlen;  TRACE("hdrlen:%d\n", hdrlen);  if(*num_bytes > usd->write_buffer_size - hdrlen)    *num_bytes = usd->write_buffer_size - hdrlen;  if(hdrlen > 0)    *buf_to = FTDI_OUT_TAG(*num_bytes, FTDI_PIT_DEFAULT);  memcpy(buf_to + hdrlen, buf, *num_bytes);  *num_bytes += hdrlen;}void on_close_ftdi(usb_serial_device *usd){  TRACE_FUNCALLS("> on_close_ftdi(%08x)\n", usd);  (*usb_m->cancel_queued_transfers)(usd->pipe_read);  (*usb_m->cancel_queued_transfers)(usd->pipe_write);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -