Linux USBLPT


.
這是個有趣的應用, 雖然簡單, 不過有一定的技術含量. 這些參考資料來源, 他們都有不同的目的, 有天文愛好者, 有電子愛好, 但是同樣遇到問題, 卻有大小異同的解決方法. 證明從人家的成果學習是最快最好的方法.
.
.
近代的 PC 已經很少有 LPT PORT / PARALLEL PORT / EEE1248 / printer port, 替代的是 USB <-> LPT,
.
不過很多坊間的 USB <-> LPT 都只能用作打印機的連接線, 不能單獨控制 USB 轉接成的 printer port 的每個 I/O.
.
.
最近有需要用到簡單的應用, 所以搜尋了 GOOGLE. 找到幾個參考的資料. 這個是最快捷的方法之一. 用 linux 內建的 usblp, PL2305, USS720 等等 IC 都在 kernel 內建驅動程式, 隨插即用. 透過特別的方法, 依然可以 單獨控制 printer port 的每個 I/O.
.
.
Add TTL outputs to your USB Laptop ( linux  / windows), 這個很詳細介紹原理實作
http://thx8411.over-blog.com/pages/Add_TTL_outputs_to_your_USB_Laptop_Part_3_Software_on_Windows-4514042.html
.
.
Parallel port flatbed scanner works under USB, CH341 and application
http://myweb.polyu.edu.hk/~06900664r/ch341epp.htm
.
.
.
.
.
.
這個是最快的, 源碼俺需要改一下, 因為 /dev/usblp0 不存在, 卻有一個 /dev/usb/lp0
試驗證明, USS720 的線 比 PL-2305 的線穩定
.
Programming using IOCTL to interface with Linux kernel drivers

.

usblp-hack.h

// how to compile : gcc -o usblp-hack usblp-hack.c
// how to uses : sudo ./usblp-hack

#ifndef USBLP_HACK_H
#define USBLP_HACK_H

#include <linux/ioctl.h>

/* ioctls: */
#define IOCNR_GET_DEVICE_ID     1
#define IOCNR_GET_PROTOCOLS     2
#define IOCNR_SET_PROTOCOL      3
#define IOCNR_HP_SET_CHANNEL        4
#define IOCNR_GET_BUS_ADDRESS       5
#define IOCNR_GET_VID_PID       6
#define IOCNR_SOFT_RESET        7
/* Get device_id string: */
#define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len)
/* The following ioctls were added for http://hpoj.sourceforge.net: */
/* Get two-int array:
 * [0]=current protocol (1=7/1/1, 2=7/1/2, 3=7/1/3),
 * [1]=supported protocol mask (mask&(1<<n)!=0 means 7/1/n supported): */
#define LPIOC_GET_PROTOCOLS(len) _IOC(_IOC_READ, 'P', IOCNR_GET_PROTOCOLS, len)
/* Set protocol (arg: 1=7/1/1, 2=7/1/2, 3=7/1/3): */
#define LPIOC_SET_PROTOCOL _IOC(_IOC_WRITE, 'P', IOCNR_SET_PROTOCOL, 0)
/* Set channel number (HP Vendor-specific command): */
#define LPIOC_HP_SET_CHANNEL _IOC(_IOC_WRITE, 'P', IOCNR_HP_SET_CHANNEL, 0)
/* Get two-int array: [0]=bus number, [1]=device address: */
#define LPIOC_GET_BUS_ADDRESS(len) _IOC(_IOC_READ, 'P', IOCNR_GET_BUS_ADDRESS, len)
/* Get two-int array: [0]=vendor ID, [1]=product ID: */
#define LPIOC_GET_VID_PID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_VID_PID, len)
/* Perform class specific soft reset */
#define LPIOC_SOFT_RESET _IOC(_IOC_NONE, 'P', IOCNR_SOFT_RESET, 0)
#endif

.
.
.
usblp-hack.c

#include "usblp-hack.h"
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>		/* open */
#include <unistd.h>		/* exit */
#include <sys/ioctl.h>		/* ioctl */

main()
{
	int fd;
	int twoints[2];

//	fd = open("/dev/usblp0", O_RDONLY | O_NONBLOCK);
	fd = open("/dev/usb/lp0", O_RDONLY | O_NONBLOCK); //俺的系統沒有 /dev/usblp0, 只有 /dev/usb/lp0, Fedora 17
	if (fd < 0) {
		printf("Cannot open device.\n");
		exit(-1);
	}

	if(ioctl(fd, LPIOC_GET_PROTOCOLS(sizeof(int[2])), &twoints) >= 0)
		printf("Great success: %d / %d\n", twoints[0], twoints[1]);
	else {
		printf("Fail!\n");
		exit(-1);
	}

	if(ioctl(fd, LPIOC_SET_PROTOCOL, 2) >= 0)
		printf("set protocol to version 2\n");
	else {
		printf("Fail!\n");
		exit(-1);
	}

	if(ioctl(fd, LPIOC_GET_PROTOCOLS(sizeof(int[2])), &twoints) >= 0)
		printf("Great success: %d / %d\n", twoints[0], twoints[1]);
	else {
		printf("Fail!\n");
		exit(-1);
	}

	if(ioctl(fd, LPIOC_SOFT_RESET) >= 0)
	{
		printf("Success reset device\n");
	} else {
		printf("Could not reset device\n");
		exit(-1);
	}

	close(fd);
	exit(0);
}
廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s