2024年5月11日发(作者:)

USB转串口CH340341驱动源码

#include

#include

#include

#include

#include

#include

#include

#define DEFAULT_BAUD_RATE 2400

static int debug;

static struct usb_device_id id_table [] = {

{ USB_DEVICE(0x4348, 0x5523) },

{ },

};

MODULE_DEVICE_TABLE(usb, id_table);

struct ch341_private {

unsigned baud_rate;

u8 dtr;

u8 rts;

};

static int ch341_control_out(struct usb_device *dev, u8 request,

u16 value, u16 index)

{

int r;

dbg("ch341_control_out(%02x,%02x,%04x,%04x)", USB_DIR_OUT|0x40,

(int)request, (int)value, (int)index);

r = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request,

USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,

value, index, NULL, 0, 1000);

return r;

}

static int ch341_control_in(struct usb_device *dev,

u8 request, u16 value, u16 index,

char *buf, unsigned bufsize)

{

int r;

dbg("ch341_control_in(%02x,%02x,%04x,%04x,%p,%u)", USB_DIR_IN|0x40,

(int)request, (int)value, (int)index, buf, (int)bufsize);

r = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request,

{

{

USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,

value, index, buf, bufsize, 1000);

return r;

}

int ch341_set_baudrate(struct usb_device *dev, struct ch341_private *priv)

short a, b;

int r;

dbg("ch341_set_baudrate(%d)", priv->baud_rate);

switch (priv->baud_rate) {

case 2400:

a = 0xd901;

b = 0x0038;

break;

case 4800:

a = 0x6402;

b = 0x001f;

break;

case 9600:

a = 0xb202;

b = 0x0013;

break;

case 19200:

a = 0xd902;

b = 0x000d;

break;

case 38400:

a = 0x6403;

b = 0x000a;

break;

case 115200:

a = 0xcc03;

b = 0x0008;

break;

default:

return -EINVAL;

}

r = ch341_control_out(dev, 0x9a, 0x1312, a);

if (!r)

r = ch341_control_out(dev, 0x9a, 0x0f2c, b);

return r;

}

int ch341_set_handshake(struct usb_device *dev, struct ch341_private *priv)

dbg("ch341_set_handshake(%d,%d)", priv->dtr, priv->rts);

return ch341_control_out(dev, 0xa4,

~((priv->dtr?1<<5:0)|(priv->rts?1<<6:0)), 0);