stm32samples/F0-nolib/ch340/ch340.sublime-workspace

549 lines
27 KiB
Plaintext
Raw Blame History

{
"auto_complete":
{
"selected_items":
[
[
"usb",
"usb_device\t(ch341.c)"
]
]
},
"buffers":
[
{
"file": "/home/eddy/C-files/stm32samples/F0-nolib/Snippets/fallthru",
"settings":
{
"buffer_size": 30,
"line_ending": "Unix"
}
},
{
"contents": "// SPDX-License-Identifier: GPL-2.0\n/*\n * Copyright 2007, Frank A Kingswood <frank@kingswood-consulting.co.uk>\n * Copyright 2007, Werner Cornelius <werner@cornelius-consult.de>\n * Copyright 2009, Boris Hajduk <boris@hajduk.org>\n *\n * ch341.c implements a serial port driver for the Winchiphead CH341.\n *\n * The CH341 device can be used to implement an RS232 asynchronous\n * serial port, an IEEE-1284 parallel printer port or a memory-like\n * interface. In all cases the CH341 supports an I2C interface as well.\n * This driver only supports the asynchronous serial interface.\n */\n\n#include <linux/kernel.h>\n#include <linux/tty.h>\n#include <linux/module.h>\n#include <linux/slab.h>\n#include <linux/usb.h>\n#include <linux/usb/serial.h>\n#include <linux/serial.h>\n#include <asm/unaligned.h>\n\n#define DEFAULT_BAUD_RATE 9600\n#define DEFAULT_TIMEOUT 1000\n\n/* flags for IO-Bits */\n#define CH341_BIT_RTS (1 << 6)\n#define CH341_BIT_DTR (1 << 5)\n\n/******************************/\n/* interrupt pipe definitions */\n/******************************/\n/* always 4 interrupt bytes */\n/* first irq byte normally 0x08 */\n/* second irq byte base 0x7d + below */\n/* third irq byte base 0x94 + below */\n/* fourth irq byte normally 0xee */\n\n/* second interrupt byte */\n#define CH341_MULT_STAT 0x04 /* multiple status since last interrupt event */\n\n/* status returned in third interrupt answer byte, inverted in data\n from irq */\n#define CH341_BIT_CTS 0x01\n#define CH341_BIT_DSR 0x02\n#define CH341_BIT_RI 0x04\n#define CH341_BIT_DCD 0x08\n#define CH341_BITS_MODEM_STAT 0x0f /* all bits */\n\n/*******************************/\n/* baudrate calculation factor */\n/*******************************/\n#define CH341_BAUDBASE_FACTOR 1532620800\n#define CH341_BAUDBASE_DIVMAX 3\n\n/* Break support - the information used to implement this was gleaned from\n * the Net/FreeBSD uchcom.c driver by Takanori Watanabe. Domo arigato.\n */\n\n#define CH341_REQ_READ_VERSION 0x5F\n#define CH341_REQ_WRITE_REG 0x9A\n#define CH341_REQ_READ_REG 0x95\n#define CH341_REQ_SERIAL_INIT 0xA1\n#define CH341_REQ_MODEM_CTRL 0xA4\n\n#define CH341_REG_BREAK 0x05\n#define CH341_REG_LCR 0x18\n#define CH341_NBREAK_BITS 0x01\n\n#define CH341_LCR_ENABLE_RX 0x80\n#define CH341_LCR_ENABLE_TX 0x40\n#define CH341_LCR_MARK_SPACE 0x20\n#define CH341_LCR_PAR_EVEN 0x10\n#define CH341_LCR_ENABLE_PAR 0x08\n#define CH341_LCR_STOP_BITS_2 0x04\n#define CH341_LCR_CS8 0x03\n#define CH341_LCR_CS7 0x02\n#define CH341_LCR_CS6 0x01\n#define CH341_LCR_CS5 0x00\n\nstatic const struct usb_device_id id_table[] = {\n\t{ USB_DEVICE(0x4348, 0x5523) },\n\t{ USB_DEVICE(0x1a86, 0x7523) },\n\t{ USB_DEVICE(0x1a86, 0x5523) },\n\t{ },\n};\nMODULE_DEVICE_TABLE(usb, id_table);\n\nstruct ch341_private {\n\tspinlock_t lock; /* access lock */\n\tunsigned baud_rate; /* set baud rate */\n\tu8 mcr;\n\tu8 msr;\n\tu8 lcr;\n};\n\nstatic void ch341_set_termios(struct tty_struct *tty,\n\t\t\t struct usb_serial_port *port,\n\t\t\t struct ktermios *old_termios);\n\nstatic int ch341_control_out(struct usb_device *dev, u8 request,\n\t\t\t u16 value, u16 index)\n{\n\tint r;\n\n\tdev_dbg(&dev->dev, \"%s - (%02x,%04x,%04x)\\n\", __func__,\n\t\trequest, value, index);\n\n\tr = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request,\n\t\t\t USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,\n\t\t\t value, index, NULL, 0, DEFAULT_TIMEOUT);\n\tif (r < 0)\n\t\tdev_err(&dev->dev, \"failed to send control message: %d\\n\", r);\n\n\treturn r;\n}\n\nstatic int ch341_control_in(struct usb_device *dev,\n\t\t\t u8 request, u16 value, u16 index,\n\t\t\t char *buf, unsigned bufsize)\n{\n\tint r;\n\n\tdev_dbg(&dev->dev, \"%s - (%02x,%04x,%04x,%u)\\n\", __func__,\n\t\trequest, value, index, bufsize);\n\n\tr = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request,\n\t\t\t USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,\n\t\t\t value, index, buf, bufsize, DEFAULT_TIMEOUT);\n\tif (r < bufsize) {\n\t\tif (r >= 0) {\n\t\t\tdev_err(&dev->dev,\n\t\t\t\t\"short control message received (%d < %u)\\n\",\n\t\t\t\tr, bufsize);\n\t\t\tr = -EIO;\n\t\t}\n\n\t\tdev_err(&dev->dev, \"failed to receive control message: %d\\n\",\n\t\t\tr);\n\t\treturn r;\n\t}\n\n\treturn 0;\n}\n\nstatic int ch341_set_baudrate_lcr(struct usb_device *dev,\n\t\t\t\t struct ch341_private *priv, u8 lcr)\n{\n\tshort a;\n\tint r;\n\tunsigned long factor;\n\tshort divisor;\n\n\tif (!priv->baud_rate)\n\t\treturn -EINVAL;\n\tfactor = (CH341_BAUDBASE_FACTOR / priv->baud_rate);\n\tdivisor = CH341_BAUDBASE_DIVMAX;\n\n\twhile ((factor > 0xfff0) && divisor) {\n\t\tfactor >>= 3;\n\t\tdivisor--;\n\t}\n\n\tif (factor > 0xfff0)\n\t\treturn -EINVAL;\n\n\tfactor = 0x10000 - factor;\n\ta = (factor & 0xff00) | divisor;\n\n\t/*\n\t * CH341A buffers data until a full endpoint-size packet (32 bytes)\n\t * has been received unless bit 7 is set.\n\t */\n\ta |= BIT(7);\n\n\tr = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x1312, a);\n\tif (r)\n\t\treturn r;\n\n\tr = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x2518, lcr);\n\tif (r)\n\t\treturn r;\n\n\treturn r;\n}\n\nstatic int ch341_set_handshake(struct usb_device *dev, u8 control)\n{\n\treturn ch341_control_out(dev, CH341_REQ_MODEM_CTRL, ~control, 0);\n}\n\nstatic int ch341_get_status(struct usb_device *dev, struct ch341_private *priv)\n{\n\tconst unsigned int size = 2;\n\tchar *buffer;\n\tint r;\n\tunsigned long flags;\n\n\tbuffer = kmalloc(size, GFP_KERNEL);\n\tif (!buffer)\n\t\treturn -ENOMEM;\n\n\tr = ch341_control_in(dev, CH341_REQ_READ_REG, 0x0706, 0, buffer, size);\n\tif (r < 0)\n\t\tgoto out;\n\n\tspin_lock_irqsave(&priv->lock, flags);\n\tpriv->msr = (~(*buffer)) & CH341_BITS_MODEM_STAT;\n\tspin_unlock_irqrestore(&priv->lock, flags);\n\nout:\tkfree(buffer);\n\treturn r;\n}\n\n/* -------------------------------------------------------------------------- */\n\nstatic int ch341_configure(struct usb_device *dev, struct ch341_private *priv)\n{\n\tconst unsigned int size = 2;\n\tchar *buffer;\n\tint r;\n\n\tbuffer = kmalloc(size, GFP_KERNEL);\n\tif (!buffer)\n\t\treturn -ENOMEM;\n\n\t/* expect two bytes 0x27 0x00 */\n\tr = ch341_control_in(dev, CH341_REQ_READ_VERSION, 0, 0, buffer, size);\n\tif (r < 0)\n\t\tgoto out;\n\tdev_dbg(&dev->dev, \"Chip version: 0x%02x\\n\", buffer[0]);\n\n\tr = ch341_control_out(dev, CH341_REQ_SERIAL_INIT, 0, 0);\n\tif (r < 0)\n\t\tgoto out;\n\n\tr = ch341_set_baudrate_lcr(dev, priv, priv->lcr);\n\tif (r < 0)\n\t\tgoto out;\n\n\tr = ch341_set_handshake(dev, priv->mcr);\n\nout:\tkfree(buffer);\n\treturn r;\n}\n\nstatic int ch341_port_probe(struct usb_serial_port *port)\n{\n\tstruct ch341_private *priv;\n\tint r;\n\n\tpriv = kzalloc(sizeof(struct ch341_private), GFP_KERNEL);\n\tif (!priv)\n\t\treturn -ENOMEM;\n\n\tspin_lock_init(&priv->lock);\n\tpriv->baud_rate = DEFAULT_BAUD_RATE;\n\t/*\n\t * Some CH340 devices appear unable to change the initial LCR\n\t * settings, so set a sane 8N1 default.\n\t */\n\tpriv->lcr = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX | CH341_LCR_CS8;\n\n\tr = ch341_configure(port->serial->dev, priv);\n\tif (r < 0)\n\t\tgoto error;\n\n\tusb_set_serial_port_data(port, priv);\n\treturn 0;\n\nerror:\tkfree(priv);\n\treturn r;\n}\n\nstatic int ch341_port_remove(struct usb_serial_port *port)\n{\n\tstruct ch341_private *priv;\n\n\tpriv = usb_get_serial_port_data(port);\n\tkfree(priv);\n\n\treturn 0;\n}\n\nstatic int ch341_carrier_raised(struct usb_serial_port *port)\n{\n\tstruct ch341_private *priv = usb_get_serial_port_data(port);\n\tif (priv->msr & CH341_BIT_DCD)\n\t\treturn 1;\n\treturn 0;\n}\n\nstatic void ch341_dtr_rts(struct usb_serial_port *port, int on)\n{\n\tstruct ch341_private *priv = usb_get_serial_port_data(port);\n\tunsigned long flags;\n\n\t/* drop DTR and RTS */\n\tspin_lock_irqsave(&priv->lock, flags);\n\tif (on)\n\t\tpriv->mcr |= CH341_BIT_RTS | CH341_BIT_DTR;\n\telse\n\t\tpriv->mcr &= ~(CH341_BIT_RTS | CH341_BIT_DTR);\n\tspin_unlock_irqrestore(&priv->lock, flags);\n\tch341_set_handshake(port->serial->dev, priv->mcr);\n}\n\nstatic void ch341_close(struct usb_serial_port *port)\n{\n\tusb_serial_generic_close(port);\n\tusb_kill_urb(port->interrupt_in_urb);\n}\n\n\n/* open this device, set default parameters */\nstatic int ch341_open(struct tty_struct *tty, struct usb_serial_port *port)\n{\n\tstruct ch341_private *priv = usb_get_serial_port_data(port);\n\tint r;\n\n\tif (tty)\n\t\tch341_set_termios(tty, port, NULL);\n\n\tdev_dbg(&port->dev, \"%s - submitting interrupt urb\\n\", __func__);\n\tr = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);\n\tif (r) {\n\t\tdev_err(&port->dev, \"%s - failed to submit interrupt urb: %d\\n\",\n\t\t\t__func__, r);\n\t\treturn r;\n\t}\n\n\tr = ch341_get_status(port->serial->dev, priv);\n\tif (r < 0) {\n\t\tdev_err(&port->dev, \"failed to read modem status: %d\\n\", r);\n\t\tgoto err_kill_interrupt_urb;\n\t}\n\n\tr = usb_serial_generic_open(tty, port);\n\tif (r)\n\t\tgoto err_kill_interrupt_urb;\n\n\treturn 0;\n\nerr_kill_interrupt_urb:\n\tusb_kill_urb(port->interrupt_in_urb);\n\n\treturn r;\n}\n\n/* Old_termios contains the original termios settings and\n * tty->termios contains the new setting to be used.\n */\nstatic void ch341_set_termios(struct tty_struct *tty,\n\t\tstruct usb_serial_port *port, struct ktermios *old_termios)\n{\n\tstruct ch341_private *priv = usb_get_serial_port_data(port);\n\tunsigned baud_rate;\n\tunsigned long flags;\n\tu8 lcr;\n\tint r;\n\n\t/* redundant changes may cause the chip to lose bytes */\n\tif (old_termios && !tty_termios_hw_change(&tty->termios, old_termios))\n\t\treturn;\n\n\tbaud_rate = tty_get_baud_rate(tty);\n\n\tlcr = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX;\n\n\tswitch (C_CSIZE(tty)) {\n\tcase CS5:\n\t\tlcr |= CH341_LCR_CS5;\n\t\tbreak;\n\tcase CS6:\n\t\tlcr |= CH341_LCR_CS6;\n\t\tbreak;\n\tcase CS7:\n\t\tlcr |= CH341_LCR_CS7;\n\t\tbreak;\n\tcase CS8:\n\t\tlcr |= CH341_LCR_CS8;\n\t\tbreak;\n\t}\n\n\tif (C_PARENB(tty)) {\n\t\tlcr |= CH341_LCR_ENABLE_PAR;\n\t\tif (C_PARODD(tty) == 0)\n\t\t\tlcr |= CH341_LCR_PAR_EVEN;\n\t\tif (C_CMSPAR(tty))\n\t\t\tlcr |= CH341_LCR_MARK_SPACE;\n\t}\n\n\tif (C_CSTOPB(tty))\n\t\tlcr |= CH341_LCR_STOP_BITS_2;\n\n\tif (baud_rate) {\n\t\tpriv->baud_rate = baud_rate;\n\n\t\tr = ch341_set_baudrate_lcr(port->serial->dev, priv, lcr);\n\t\tif (r < 0 && old_termios) {\n\t\t\tpriv->baud_rate = tty_termios_baud_rate(old_termios);\n\t\t\ttty_termios_copy_hw(&tty->termios, old_termios);\n\t\t} else if (r == 0) {\n\t\t\tpriv->lcr = lcr;\n\t\t}\n\t}\n\n\tspin_lock_irqsave(&priv->lock, flags);\n\tif (C_BAUD(tty) == B0)\n\t\tpriv->mcr &= ~(CH341_BIT_DTR | CH341_BIT_RTS);\n\telse if (old_termios && (old_termios->c_cflag & CBAUD) == B0)\n\t\tpriv->mcr |= (CH341_BIT_DTR | CH341_BIT_RTS);\n\tspin_unlock_irqrestore(&priv->lock, flags);\n\n\tch341_set_handshake(port->serial->dev, priv->mcr);\n}\n\nstatic void ch341_break_ctl(struct tty_struct *tty, int break_state)\n{\n\tconst uint16_t ch341_break_reg =\n\t\t\t((uint16_t) CH341_REG_LCR << 8) | CH341_REG_BREAK;\n\tstruct usb_serial_port *port = tty->driver_data;\n\tint r;\n\tuint16_t reg_contents;\n\tuint8_t *break_reg;\n\n\tbreak_reg = kmalloc(2, GFP_KERNEL);\n\tif (!break_reg)\n\t\treturn;\n\n\tr = ch341_control_in(port->serial->dev, CH341_REQ_READ_REG,\n\t\t\tch341_break_reg, 0, break_reg, 2);\n\tif (r < 0) {\n\t\tdev_err(&port->dev, \"%s - USB control read error (%d)\\n\",\n\t\t\t\t__func__, r);\n\t\tgoto out;\n\t}\n\tdev_dbg(&port->dev, \"%s - initial ch341 break register contents - reg1: %x, reg2: %x\\n\",\n\t\t__func__, break_reg[0], break_reg[1]);\n\tif (break_state != 0) {\n\t\tdev_dbg(&port->dev, \"%s - Enter break state requested\\n\", __func__);\n\t\tbreak_reg[0] &= ~CH341_NBREAK_BITS;\n\t\tbreak_reg[1] &= ~CH341_LCR_ENABLE_TX;\n\t} else {\n\t\tdev_dbg(&port->dev, \"%s - Leave break state requested\\n\", __func__);\n\t\tbreak_reg[0] |= CH341_NBREAK_BITS;\n\t\tbreak_reg[1] |= CH341_LCR_ENABLE_TX;\n\t}\n\tdev_dbg(&port->dev, \"%s - New ch341 break register contents - reg1: %x, reg2: %x\\n\",\n\t\t__func__, break_reg[0], break_reg[1]);\n\treg_contents = get_unaligned_le16(break_reg);\n\tr = ch341_control_out(port->serial->dev, CH341_REQ_WRITE_REG,\n\t\t\tch341_break_reg, reg_contents);\n\tif (r < 0)\n\t\tdev_err(&port->dev, \"%s - USB control write error (%d)\\n\",\n\t\t\t\t__func__, r);\nout:\n\tkfree(break_reg);\n}\n\nstatic int ch341_tiocmset(struct tty_struct *tty,\n\t\t\t unsigned int set, unsigned int clear)\n{\n\tstruct usb_serial_port *port = tty->driver_data;\n\tstruct ch341_private *priv = usb_get_serial_port_data(port);\n\tunsigned long flags;\n\tu8 control;\n\n\tspin_lock_irqsave(&priv->lock, flags);\n\tif (set & TIOCM_RTS)\n\t\tpriv->mcr |= CH341_BIT_RTS;\n\tif (set & TIOCM_DTR)\n\t\tpriv->mcr |= CH341_BIT_DTR;\n\tif (clear & TIOCM_RTS)\n\t\tpriv->mcr &= ~CH341_BIT_RTS;\n\tif (clear & TIOCM_DTR)\n\t\tpriv->mcr &= ~CH341_BIT_DTR;\n\tcontrol = priv->mcr;\n\tspin_unlock_irqrestore(&priv->lock, flags);\n\n\treturn ch341_set_handshake(port->serial->dev, control);\n}\n\nstatic void ch341_update_status(struct usb_serial_port *port,\n\t\t\t\t\tunsigned char *data, size_t len)\n{\n\tstruct ch341_private *priv = usb_get_serial_port_data(port);\n\tstruct tty_struct *tty;\n\tunsigned long flags;\n\tu8 status;\n\tu8 delta;\n\n\tif (len < 4)\n\t\treturn;\n\n\tstatus = ~data[2] & CH341_BITS_MODEM_STAT;\n\n\tspin_lock_irqsave(&priv->lock, flags);\n\tdelta = status ^ priv->msr;\n\tpriv->msr = status;\n\tspin_unlock_irqrestore(&priv->lock, flags);\n\n\tif (data[1] & CH341_MULT_STAT)\n\t\tdev_dbg(&port->dev, \"%s - multiple status change\\n\", __func__);\n\n\tif (!delta)\n\t\treturn;\n\n\tif (delta & CH341_BIT_CTS)\n\t\tport->icount.cts++;\n\tif (delta & CH341_BIT_DSR)\n\t\tport->icount.dsr++;\n\tif (delta & CH341_BIT_RI)\n\t\tport->icount.rng++;\n\tif (delta & CH341_BIT_DCD) {\n\t\tport->icount.dcd++;\n\t\ttty = tty_port_tty_get(&port->port);\n\t\tif (tty) {\n\t\t\tusb_serial_handle_dcd_change(port, tty,\n\t\t\t\t\t\tstatus & CH341_BIT_DCD);\n\t\t\ttty_kref_put(tty);\n\t\t}\n\t}\n\n\twake_up_interruptible(&port->port.delta_msr_wait);\n}\n\nstatic void ch341_read_int_callback(struct urb *urb)\n{\n\tstruct usb_serial_port *port = urb->context;\n\tunsigned char *data = urb->transfer_buffer;\n\tunsigned int len = urb->actual_length;\n\tint status;\n\n\tswitch (urb->status) {\n\tcase 0:\n\t\t/* success */\n\t\tbreak;\n\tcase -ECONNRESET:\n\tcase -ENOENT:\n\tcase -ESHUTDOWN:\n\t\t/* this urb is terminated, clean up */\n\t\tdev_dbg(&urb->dev->dev, \"%s - urb shutting down: %d\\n\",\n\t\t\t__func__, urb->status);\n\t\treturn;\n\tdefault:\n\t\tdev_dbg(&urb->dev->dev, \"%s - nonzero urb status: %d\\n\",\n\t\t\t__func__, urb->status);\n\t\tgoto exit;\n\t}\n\n\tusb_serial_debug_data(&port->dev, __func__, len, data);\n\tch341_update_status(port, data, len);\nexit:\n\tstatus = usb_submit_urb(urb, GFP_ATOMIC);\n\tif (status) {\n\t\tdev_err(&urb->dev->dev, \"%s - usb_submit_urb failed: %d\\n\",\n\t\t\t__func__, status);\n\t}\n}\n\nstatic int ch341_tiocmget(struct tty_struct *tty)\n{\n\tstruct usb_serial_port *port = tty->driver_data;\n\tstruct ch341_private *priv = usb_get_serial_port_data(port);\n\tunsigned long flags;\n\tu8 mcr;\n\tu8 status;\n\tunsigned int result;\n\n\tspin_lock_irqsave(&priv->lock, flags);\n\tmcr = priv->mcr;\n\tstatus = priv->msr;\n\tspin_unlock_irqrestore(&priv->lock, flags);\n\n\tresult = ((mcr & CH341_BIT_DTR)\t\t? TIOCM_DTR : 0)\n\t\t | ((mcr & CH341_BIT_RTS)\t? TIOCM_RTS : 0)\n\t\t | ((status & CH341_BIT_CTS)\t? TIOCM_CTS : 0)\n\t\t | ((status & CH341_BIT_DSR)\t? TIOCM_DSR : 0)\n\t\t | ((status & CH341_BIT_RI)\t? TIOCM_RI : 0)\n\t\t | ((status & CH341_BIT_DCD)\t? TIOCM_CD : 0);\n\n\tdev_dbg(&port->dev, \"%s - result = %x\\n\", __func__, result);\n\n\treturn result;\n}\n\nstatic int ch341_reset_resume(struct usb_serial *serial)\n{\n\tstruct usb_serial_port *port = serial->port[0];\n\tstruct ch341_private *priv = usb_get_serial_port_data(port);\n\tint ret;\n\n\t/* reconfigure ch341 serial port after bus-reset */\n\tch341_configure(serial->dev, priv);\n\n\tif (tty_port_initialized(&port->port)) {\n\t\tret = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);\n\t\tif (ret) {\n\t\t\tdev_err(&port->dev, \"failed to submit interrupt urb: %d\\n\",\n\t\t\t\tret);\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = ch341_get_status(port->serial->dev, priv);\n\t\tif (ret < 0) {\n\t\t\tdev_err(&port->dev, \"failed to read modem status: %d\\n\",\n\t\t\t\tret);\n\t\t}\n\t}\n\n\treturn usb_serial_generic_resume(serial);\n}\n\nstatic struct usb_serial_driver ch341_device = {\n\t.driver = {\n\t\t.owner\t= THIS_MODULE,\n\t\t.name\t= \"ch341-uart\",\n\t},\n\t.id_table = id_table,\n\t.num_ports = 1,\n\t.open = ch341_open,\n\t.dtr_rts\t = ch341_dtr_rts,\n\t.carrier_raised\t = ch341_carrier_raised,\n\t.close = ch341_close,\n\t.set_termios = ch341_set_termios,\n\t.break_ctl = ch341_break_ctl,\n\t.tiocmget = ch341_tiocmget,\n\t.tiocmset = ch341_tiocmset,\n\t.tiocmiwait = usb_serial_generic_tiocmiwait,\n\t.read_int_callback = ch341_read_int_callback,\n\t.port_probe = ch341_port_probe,\n\t.port_remove = ch341_port_remove,\n\t.reset_resume = ch341_reset_resume,\n};\n\nstatic struct usb_serial_driver * const serial_drivers[] = {\n\t&ch341_device, NULL\n};\n\nmodule_usb_serial_driver(serial_drivers, id_table);\n\nMODULE_LICENSE(\"GPL v2\");\n",
"file": "/usr/src/linux/drivers/usb/serial/ch341.c",
"file_size": 16239,
"file_write_time": 131616480330000000,
"settings":
{
"buffer_size": 16239,
"line_ending": "Unix"
}
},
{
"file": "/home/eddy/C-files/stm32samples/F1-nolib/led_blink/Makefile",
"settings":
{
"buffer_size": 3346,
"line_ending": "Unix"
}
},
{
"file": "/usr/src/linux/drivers/usb/serial/pl2303.c",
"settings":
{
"buffer_size": 27410,
"line_ending": "Unix"
}
},
{
"file": "main.c",
"settings":
{
"buffer_size": 4104,
"encoding": "UTF-8",
"line_ending": "Unix"
}
},
{
"file": "usb.c",
"settings":
{
"buffer_size": 4371,
"encoding": "UTF-8",
"line_ending": "Unix"
}
},
{
"file": "usb.h",
"settings":
{
"buffer_size": 1129,
"line_ending": "Unix"
}
},
{
"file": "usb_lib.c",
"settings":
{
"buffer_size": 18311,
"encoding": "Cyrillic (KOI8-R)",
"line_ending": "Windows"
}
},
{
"file": "usb_lib.h",
"settings":
{
"buffer_size": 7155,
"line_ending": "Windows"
}
}
],
"build_system": "",
"build_system_choices":
[
],
"build_varint": "",
"command_palette":
{
"height": 0.0,
"last_filter": "",
"selected_items":
[
[
"Package Control: inst",
"Package Control: Install Package"
],
[
"Package Control: in",
"Package Control: Install Package"
],
[
"Package Control: install",
"Package Control: Install Package"
],
[
"Package Control: ",
"Package Control: Install Package"
],
[
"inst",
"Package Control: Install Package"
]
],
"width": 0.0
},
"console":
{
"height": 143.0,
"history":
[
"import urllib.request,os,hashlib; h = '6f4c264a24d933ce70df5dedcf1dcaee' + 'ebe013ee18cced0ef93d5f746d80ef60'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://packagecontrol.io/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by) "
]
},
"distraction_free":
{
"menu_visible": true,
"show_minimap": false,
"show_open_files": false,
"show_tabs": false,
"side_bar_visible": false,
"status_bar_visible": false
},
"expanded_folders":
[
"/home/eddy/C-files/stm32samples/F0-nolib/ch340"
],
"file_history":
[
"/home/eddy/C-files/stm32samples/<2F><><EFBFBD>.c",
"/home/eddy/.config/sublime-text-3/Packages/All Autocomplete/All Autocomplete.sublime-settings",
"/home/eddy/.config/sublime-text-3/Packages/Package Control/Package Control.sublime-settings",
"/home/eddy/C-files/stm32samples/F0-nolib/ch340/usb_defs.h",
"/home/eddy/C-files/stm32samples/F0-nolib/ch340/hardware.h",
"/home/eddy/C-files/stm32samples/F0-nolib/ch340/hardware.c",
"/home/eddy/C-files/stm32samples/F0-nolib/usbcdc/can.c",
"/home/eddy/C-files/stm32samples/F0-nolib/ch340/usart.c",
"/home/eddy/C-files/stm32samples/F0-nolib/usbcdc/can.h",
"/home/eddy/C-files/stm32samples/F0-nolib/ch340/Readme.md"
],
"find":
{
"height": 43.0
},
"find_in_files":
{
"height": 0.0,
"where_history":
[
]
},
"find_state":
{
"case_sensitive": false,
"find_history":
[
],
"highlight": true,
"in_selection": false,
"preserve_case": false,
"regex": false,
"replace_history":
[
],
"reverse": false,
"show_context": true,
"use_buffer2": true,
"whole_word": false,
"wrap": true
},
"groups":
[
{
"selected": 2,
"sheets":
[
{
"buffer": 0,
"file": "/home/eddy/C-files/stm32samples/F0-nolib/Snippets/fallthru",
"semi_transient": false,
"settings":
{
"buffer_size": 30,
"regions":
{
},
"selection":
[
[
30,
30
]
],
"settings":
{
"syntax": "Packages/Text/Plain text.tmLanguage"
},
"translation.x": 0.0,
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 4,
"type": "text"
},
{
"buffer": 1,
"file": "/usr/src/linux/drivers/usb/serial/ch341.c",
"semi_transient": false,
"settings":
{
"buffer_size": 16239,
"regions":
{
},
"selection":
[
[
4745,
4745
]
],
"settings":
{
"syntax": "Packages/C++/C.sublime-syntax",
"translate_tabs_to_spaces": false
},
"translation.x": 0.0,
"translation.y": 3426.0,
"zoom_level": 1.0
},
"stack_index": 1,
"type": "text"
},
{
"buffer": 2,
"file": "/home/eddy/C-files/stm32samples/F1-nolib/led_blink/Makefile",
"semi_transient": false,
"settings":
{
"buffer_size": 3346,
"regions":
{
},
"selection":
[
[
0,
0
]
],
"settings":
{
"syntax": "Packages/Makefile/Makefile.sublime-syntax"
},
"translation.x": 0.0,
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 0,
"type": "text"
},
{
"buffer": 3,
"file": "/usr/src/linux/drivers/usb/serial/pl2303.c",
"semi_transient": false,
"settings":
{
"buffer_size": 27410,
"regions":
{
},
"selection":
[
[
6587,
6587
]
],
"settings":
{
"syntax": "Packages/C++/C.sublime-syntax",
"translate_tabs_to_spaces": false
},
"translation.x": 0.0,
"translation.y": 3822.0,
"zoom_level": 1.0
},
"stack_index": 2,
"type": "text"
},
{
"buffer": 4,
"file": "main.c",
"semi_transient": false,
"settings":
{
"buffer_size": 4104,
"regions":
{
},
"selection":
[
[
1948,
1948
]
],
"settings":
{
"syntax": "Packages/C++/C.sublime-syntax",
"tab_size": 4,
"translate_tabs_to_spaces": true
},
"translation.x": 0.0,
"translation.y": 330.0,
"zoom_level": 1.0
},
"stack_index": 8,
"type": "text"
},
{
"buffer": 5,
"file": "usb.c",
"semi_transient": false,
"settings":
{
"buffer_size": 4371,
"regions":
{
},
"selection":
[
[
1781,
1781
]
],
"settings":
{
"syntax": "Packages/C++/C.sublime-syntax",
"tab_size": 4,
"translate_tabs_to_spaces": true
},
"translation.x": 0.0,
"translation.y": 818.0,
"zoom_level": 1.0
},
"stack_index": 7,
"type": "text"
},
{
"buffer": 6,
"file": "usb.h",
"semi_transient": false,
"settings":
{
"buffer_size": 1129,
"regions":
{
},
"selection":
[
[
0,
0
]
],
"settings":
{
"syntax": "Packages/C++/C++.sublime-syntax"
},
"translation.x": 0.0,
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 6,
"type": "text"
},
{
"buffer": 7,
"file": "usb_lib.c",
"semi_transient": false,
"settings":
{
"buffer_size": 18311,
"regions":
{
},
"selection":
[
[
6489,
6489
]
],
"settings":
{
"syntax": "Packages/C++/C.sublime-syntax",
"tab_size": 4,
"translate_tabs_to_spaces": true
},
"translation.x": 0.0,
"translation.y": 4469.0,
"zoom_level": 1.0
},
"stack_index": 5,
"type": "text"
},
{
"buffer": 8,
"file": "usb_lib.h",
"semi_transient": false,
"settings":
{
"buffer_size": 7155,
"regions":
{
},
"selection":
[
[
1925,
1925
]
],
"settings":
{
"syntax": "Packages/C++/C++.sublime-syntax",
"tab_size": 4,
"translate_tabs_to_spaces": true
},
"translation.x": 0.0,
"translation.y": 727.0,
"zoom_level": 1.0
},
"stack_index": 3,
"type": "text"
}
]
}
],
"incremental_find":
{
"height": 0.0
},
"input":
{
"height": 37.0
},
"layout":
{
"cells":
[
[
0,
0,
1,
1
]
],
"cols":
[
0.0,
1.0
],
"rows":
[
0.0,
1.0
]
},
"menu_visible": true,
"output.find_results":
{
"height": 0.0
},
"output.unsaved_changes":
{
"height": 114.0
},
"pinned_build_system": "",
"project": "ch340.sublime-project",
"replace":
{
"height": 0.0
},
"save_all_on_build": true,
"select_file":
{
"height": 0.0,
"last_filter": "",
"selected_items":
[
],
"width": 0.0
},
"select_project":
{
"height": 0.0,
"last_filter": "",
"selected_items":
[
],
"width": 0.0
},
"select_symbol":
{
"height": 0.0,
"last_filter": "",
"selected_items":
[
],
"width": 0.0
},
"selected_group": 0,
"settings":
{
},
"show_minimap": true,
"show_open_files": false,
"show_tabs": true,
"side_bar_visible": true,
"side_bar_width": 217.0,
"status_bar_visible": true,
"template_settings":
{
}
}