2016年2月4日 星期四

usb2TTL PL2303 詳細研究



這顆IC 可以把USB 轉成 RS232/RS485等等....

他是採用usb bulk mode...

支援的data format 如下:



看完了datasheet之後...找不到register table.......

不過沒關係...就直接從 linux driver code下手來分析....


首先來看 pl2303_device 這個變數....他會跟linux kernel 註冊function 的進入點...
static struct usb_serial_driver pl2303_device = {
         .driver = {
                 .owner =        THIS_MODULE,
                 .name =         "pl2303",
         },
         .id_table =             id_table,
         .num_ports =            1,
         .bulk_in_size =         256,
         .bulk_out_size =        256,
         .open =                 pl2303_open,
         .close =                pl2303_close,
         .dtr_rts =              pl2303_dtr_rts,
         .carrier_raised =       pl2303_carrier_raised,
         .ioctl =                pl2303_ioctl,
         .break_ctl =            pl2303_break_ctl,
         .set_termios =          pl2303_set_termios,
         .tiocmget =             pl2303_tiocmget,
         .tiocmset =             pl2303_tiocmset,
         .tiocmiwait =           usb_serial_generic_tiocmiwait,
         .process_read_urb =     pl2303_process_read_urb,
         .read_int_callback =    pl2303_read_int_callback,
         .probe =                pl2303_probe,
         .attach =               pl2303_startup,
         .release =              pl2303_release,
         .port_probe =           pl2303_port_probe,
         .port_remove =          pl2303_port_remove,
 };

接下來看  pl2303_open 這個function


Setup termios

static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
         struct usb_serial *serial = port->serial;
         struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
         int result;
 
         if (spriv->quirks & PL2303_QUIRK_LEGACY) {
                 usb_clear_halt(serial->dev, port->write_urb->pipe);
                 usb_clear_halt(serial->dev, port->read_urb->pipe);
         } else {
                 /* reset upstream data pipes */
                 pl2303_vendor_write(serial, 8, 0);
                 pl2303_vendor_write(serial, 9, 0);
         }
 
         /* Setup termios */
         if (tty)
                 pl2303_set_termios(tty, port, NULL);
 
         result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
         if (result) {
                 dev_err(&port->dev, "failed to submit interrupt urb: %d\n",
                         result);
                 return result;
         }
 
         result = usb_serial_generic_open(tty, port);
         if (result) {
                 usb_kill_urb(port->interrupt_in_urb);
                 return result;
         }
 
         return 0;
 }



Reference : PL2303_datasheet

Reference : pl2303_linux_code

沒有留言:

張貼留言