0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux系統(tǒng)LPT打印口批量產(chǎn)測(cè)工具

jf_49670627 ? 來源:jf_49670627 ? 作者:jf_49670627 ? 2023-04-12 11:44 ? 次閱讀

1 軟件功能

該軟件用于在Linux平臺(tái)測(cè)試CH35X/CH38X(PCI/PCIe轉(zhuǎn)串并口)的并口各引腳功能是否正常。方便對(duì)設(shè)備進(jìn)行出廠測(cè)試。

2 并口測(cè)試硬件治具

在測(cè)試前,需要制作單獨(dú)的硬件治具,按下表連接信號(hào)線:

2.png

引腳連接示意圖:

?

3 軟件使用方法

  • 插入待測(cè)試PCI/PCIe轉(zhuǎn)并口設(shè)備。
  • 輸入lspci –v命令查看設(shè)備的枚舉信息,若找到廠商ID為[1C00]或[4348]的設(shè)備,則表示已經(jīng)正常識(shí)別到該硬件。

?

  • 通過lsmod命令查看設(shè)備關(guān)聯(lián)驅(qū)動(dòng)是否已加載,設(shè)備所需驅(qū)動(dòng)包括:parport、parport_pc、lp驅(qū)動(dòng)。驅(qū)動(dòng)加載后,查看系統(tǒng)/dev目錄,會(huì)多出parportX(X為數(shù)字)節(jié)點(diǎn),示例:

?

  • 編譯測(cè)試程序,生成目標(biāo)可執(zhí)行程序,輸入./parport_test -D /dev/parport0 –h命令查看幫助,輸出其他命令無效。運(yùn)行程序:[可執(zhí)行文件名] -D [設(shè)備節(jié)點(diǎn)名稱] –s

?

4 測(cè)試錯(cuò)誤碼說明

根據(jù)輸出的錯(cuò)誤碼和終端輸出信息可判斷故障信號(hào)線,下表為錯(cuò)誤碼和說明。

錯(cuò)誤碼 錯(cuò)誤碼說明
0 STB-D0通訊錯(cuò)誤
1 AFD-D1通訊錯(cuò)誤
2 INIT-D2通訊錯(cuò)誤
3 SIN-D3通訊錯(cuò)誤
4 D6-ERR通訊錯(cuò)誤
5 D4-SELT通訊錯(cuò)誤
6 D5-PE通訊錯(cuò)誤
7 D6-ACK通訊錯(cuò)誤
8 D7-BUSY通訊錯(cuò)誤

5 測(cè)試實(shí)例

測(cè)試成功實(shí)例

測(cè)試錯(cuò)誤實(shí)例

?

根據(jù)輸出信息,D4-SELT、D5-PE、D6-ACK和D7-BUSY信號(hào)通訊存在錯(cuò)誤。

?

根據(jù)輸出信息,STB-D0信號(hào)通訊存在錯(cuò)誤。

6、wchparporttest工具源碼

/*
 * parport factory test utility.
 *
 * Copyright (C) 2023 Nanjing Qinheng Microelectronics Co., Ltd.
 * Web:     http://wch.cn
 * Author:  WCH 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define GET_BIT(x, y)	     ((x >> y) & 0x01) /* get y bit value of x */
#define CTRL_REG_INITVAL_OUT 0xc0	       /* control reg value(allow D7-D0 output) */
#define CTRL_REG_INITVAL_IN  0xe0	       /* control reg value(forbid D7-D0 output) */

static unsigned char ctrlval = 0;
static char device_name[20];

/**
 * ctrl_reg_update: update PCR reg
 * @fd: file descriptor
 * @mask: bits to update
 * @val: 0->clear, 1->set
 */
void ctrl_reg_update(int fd, unsigned char mask, unsigned char val)
{
	int ret;

	ctrlval &= ~mask;
	ctrlval |= val & mask;

	ret = ioctl(fd, PPWCONTROL, &ctrlval);
	if (ret < 0) {
		perror("ioctl");
		return;
	}
}

/**
 * data_line_init: data signals direction initialization
 * @fd: file descriptor
 * @dir: direction value
 * 
 * The function return 0 if successful, others if fail.
 */
int data_line_init(int fd, int dir)
{
	int ret;

	if (dir == 0)
		ctrlval = CTRL_REG_INITVAL_IN;
	else
		ctrlval = CTRL_REG_INITVAL_OUT;

	ret = ioctl(fd, PPWCONTROL, &ctrlval);
	if (ret < 0) {
		perror("ioctl");
		return -1;
	}
	return 0;
}

/**
 * data_reg_read: read data signals
 * @fd: file descriptor
 * 
 * The function return positive if successful, negative if fail.
 */
unsigned char data_reg_read(int fd)
{
	int ret;
	unsigned char data_r;

	ret = ioctl(fd, PPRDATA, &data_r);
	if (ret < 0) {
		perror("ioctl");
		return -1;
	}
	return data_r;
}

/**
 * print_err_msg: print message according to error code
 * @err_code: error number
 * 
 */
static void print_err_msg(int err_code)
{
	switch (err_code) {
	case 0:
		printf("[error code: %d] STB-D0 ERROR
", err_code);
		break;
	case 1:
		printf("[error code: %d] AFD-D1 ERROR
", err_code);
		break;
	case 2:
		printf("[error code: %d] INIT-D2 ERROR
", err_code);
		break;
	case 3:
		printf("[error code: %d] SIN-D3 ERROR
", err_code);
		break;
	case 4:
		printf("[error code: %d] D6-ERR ERROR
", err_code);
		break;
	case 5:
		printf("[error code: %d] D4-SELT ERROR
", err_code);
		break;
	case 6:
		printf("[error code: %d] D5-PE ERROR
", err_code);
		break;
	case 7:
		printf("[error code: %d] D6-ACK ERROR
", err_code);
		break;
	case 8:
		printf("[error code: %d] D7-BUSY ERROR
", err_code);
		break;
	default:
		break;
	}
}

/**
 * check_result: detect whether the current register value matches the target value related bits, and print in case of error
 * @type: test type, 0x01: control line output, data line input, 0x02: data line output, status line input
 * @val: current register value
 * @cmp_val: target register value
 * 
 * The function return 0 if successful, negative if fail.
 */
static int check_result(int type, unsigned char val, unsigned char cmp_val)
{
	int i;
	int ret = 0;

	if (type == 0x01) {
		for (i = 0; i < 4; i++) {
			if (GET_BIT(val, i) != GET_BIT(cmp_val, i)) {
				ret = -1;
				print_err_msg(i);
			}
		}
	} else if (type == 0x02) {
		for (i = 3; i < 8; i++) {
			if (GET_BIT(val, i) != GET_BIT(cmp_val, i)) {
				ret = -1;
				print_err_msg(i + 1);
			}
		}
	} else {
		printf("type error.n");
		return -1;
	}

	return ret;
}

static const struct option lopts[] = {
	{ "device name", required_argument, 0, 'd' },
	{ "start test", no_argument, 0, 's' },
	{ "view the usage method", no_argument, 0, 'h' },
	{ NULL, 0, 0, 0 },
};

static void print_usage(const char *prog)
{
	printf("Usage: %s [-dsh]
", prog);
	puts("  -d device name
"
	     "  -s start test
"
	     "  -h view the usage method");
	exit(1);
}

static void help_msg(void)
{
	puts("Pin connection mode of parport test:
"
	     "test1(PDR OUT/PSR IN): D6-ERR D4-SELT D5-PE D6-ACK
"
	     "test2(PCR OUT/PIR IN): STB-D0 AFD-D1 INIT-D2 SIN-D3 D7-BUSY");
	exit(1);
}

static void parse_opts(int argc, char *argv[])
{
	char c;

	if (argc != 4)
		print_usage(argv[0]);

	while (1) {
		c = getopt_long(argc, argv, "d:sh", lopts, NULL);
		if (c == -1)
			break;

		switch (c) {
		case 'd':
			memcpy(device_name, argv[2], strlen(argv[2]));
			break;
		case 's':
			printf("start test...
");
			break;
		case 'h':
			help_msg();
			break;
		default:
			print_usage(argv[0]);
			break;
		}
	}
}

int main(int argc, char **argv)
{
	int fd;
	int retval;
	int ret_check1, ret_check2, ret_check3, ret_check4;
	unsigned char data_w, status_r;

	parse_opts(argc, argv);

	/* Open parport device */
	fd = open(device_name, O_RDWR);
	if (fd < 0) {
		perror("open");
		return -1;
	}

	/* Claim the port */
	if ((retval = ioctl(fd, PPCLAIM)) < 0) {
		perror("PPCLAIM failed");
		goto exit;
	}

	/* Set the direction of D0-D7 to output */
	if ((retval = data_line_init(fd, 0x01)) < 0)
		goto exit;

	/* Set D0-D7 output low level */
	data_w = 0x00;
	if ((retval = ioctl(fd, PPWDATA, &data_w)) < 0) {
		perror("PPWDATA ioctl");
		goto exit;
	}

	/* Read BUSY, ACK, PE, SELT and ERR signal, judge whether they are all low */
	if ((retval = ioctl(fd, PPRSTATUS, &status_r)) < 0) {
		perror("PPRSTATUS ioctl");
		goto exit;
	}
	ret_check1 = check_result(0x02, status_r, 0x87);

	/* Set D4-D7 output high level */
	data_w = 0xf0;
	if ((retval = ioctl(fd, PPWDATA, &data_w)) < 0) {
		perror("PPWDATA ioctl");
		goto exit;
	}

	/* Read BUSY, ACK, PE, SELT and ERR signal, judge whether they are all high */
	if ((retval = ioctl(fd, PPRSTATUS, &status_r)) < 0) {
		perror("PPRSTATUS ioctl");
		goto exit;
	}
	ret_check2 = check_result(0x02, status_r, 0x7b);

	/* Set the direction of D0-D7 to input */
	if ((retval = data_line_init(fd, 0x00)) < 0)
		goto exit;

	/* Set SIN, INIT, AFD and STB output low level */
	ctrl_reg_update(fd, 0x0f, 0x0b);

	/* Read D0-D4 signal, judge whether they are all low */
	ret_check3 = check_result(0x01, data_reg_read(fd), 0xf0);

	/* Set SIN, INIT, AFD and STB output high level */
	ctrl_reg_update(fd, 0x0f, 0x04);

	/* Read D0-D4 signal, judge whether they are all high */
	ret_check4 = check_result(0x01, data_reg_read(fd), 0xff);

	if ((ret_check1 == 0) && (ret_check2 == 0) && (ret_check3 == 0) && (ret_check4 == 0))
		printf("Parport pin test passed
");
	else
		printf("Parport pin test failed
");

exit:
	/* Release the port */
	if (ioctl(fd, PPRELEASE) < 0)
		perror("PPRELEASE failed");

	close(fd);

	return retval;
}

?審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11170

    瀏覽量

    208469
  • PCIe
    +關(guān)注

    關(guān)注

    15

    文章

    1174

    瀏覽量

    82251
  • 命令
    +關(guān)注

    關(guān)注

    5

    文章

    669

    瀏覽量

    21956
  • 并口
    +關(guān)注

    關(guān)注

    0

    文章

    32

    瀏覽量

    17492
  • LPT
    LPT
    +關(guān)注

    關(guān)注

    0

    文章

    6

    瀏覽量

    3934
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    南京沁恒微USB 轉(zhuǎn)打印口芯片 CH340

    CH340 是一個(gè) USB 總線的轉(zhuǎn)接芯片,實(shí)現(xiàn) USB 轉(zhuǎn)串口或者 USB 轉(zhuǎn)打印口。 在打印口方式下,CH340 提供了兼容 USB 規(guī)范和 Windows 操作系統(tǒng)的標(biāo)準(zhǔn) USB 打印口
    發(fā)表于 05-16 13:51

    打印口虛擬驅(qū)動(dòng)庫_WinIO

    打印口虛擬驅(qū)動(dòng)庫_WinIO[attach]***[/attach]
    發(fā)表于 04-13 21:13

    求助各位大俠主板上25針LPT連接并口編程器問題

    確定以下條件是否滿足:1. 與編程器通訊前,接通編程器電源.2. 編程器與計(jì)算機(jī)的打印口相連.3. 計(jì)算機(jī)打印口地址為0x278,0x378或0x3bc.我確認(rèn)我接了電源,接線沒有出錯(cuò),并口地址是0x378.哪位大俠知道這是為什么,求指教?。。?/div>
    發(fā)表于 06-28 10:00

    如何利用單片機(jī)和USB總線接口芯片實(shí)現(xiàn)LPT-USB打印機(jī)的驅(qū)動(dòng)器設(shè)計(jì)

    本文利用單片機(jī)和USB總線接口芯片實(shí)現(xiàn)LPT-USB打印機(jī)的驅(qū)動(dòng)器設(shè)計(jì)。利用該設(shè)計(jì)將能夠?qū)崿F(xiàn)并行打印口數(shù)據(jù)可以在USB打印機(jī)上的直接打印工作
    發(fā)表于 04-26 06:36

    基于VB6.0的打印口(LPT)的應(yīng)用

             在 VB6.0 編程環(huán)境下,調(diào)用動(dòng)態(tài)鏈接庫,通過打印口LPT)實(shí)現(xiàn)PC 機(jī)對(duì)89C2051 單片機(jī)的編程。關(guān)鍵詞: VB6.0 語言 89C2051 單片機(jī)動(dòng)態(tài)鏈接庫(DL
    發(fā)表于 09-11 09:13 ?39次下載

    打印口底視圖

    打印口底視圖   打印口底視圖:  
    發(fā)表于 05-31 14:26 ?966次閱讀

    什么是LPT

    什么是LPT 打印口,一般打印機(jī)用LTP1,打印接口模式可在BIOS下調(diào)動(dòng),有EPP,EC
    發(fā)表于 01-22 13:58 ?2495次閱讀

    PC機(jī)打印口與便攜式數(shù)據(jù)采集系統(tǒng)接口設(shè)計(jì)

    介紹了PC 機(jī)打印口與外設(shè)的接口設(shè)計(jì)方法,巧妙地解決了打印口對(duì)大容量存儲(chǔ)器的數(shù)據(jù)讀取問題,并利用雙端口RAM 在板存儲(chǔ)技術(shù),設(shè)計(jì)了基于PC 機(jī)打印口的便攜式數(shù)據(jù)采集系統(tǒng)。文章闡
    發(fā)表于 07-19 15:11 ?36次下載
    PC機(jī)<b class='flag-5'>打印口</b>與便攜式數(shù)據(jù)采集<b class='flag-5'>系統(tǒng)</b>接口設(shè)計(jì)

    MAX189 PC打印口控制的I-V曲線示蹤儀

    電子元件應(yīng)用筆記——MAX189 PC打印口控制的I-V曲線示蹤儀
    發(fā)表于 08-18 18:24 ?0次下載

    MAX478 PC打印口控制的I-V曲線示蹤儀

    MAX478 PC打印口控制的I-V曲線示蹤儀
    發(fā)表于 08-18 18:24 ?0次下載

    MAX663_664 PC打印口控制的I-V曲線示蹤儀

    MAX663_664 PC打印口控制的I-V曲線示蹤儀
    發(fā)表于 08-18 18:28 ?0次下載

    MAX531 PC打印口控制的I-V曲線示蹤儀

    MAX531 PC打印口控制的I-V曲線示蹤儀
    發(fā)表于 08-18 18:28 ?0次下載

    avr單片機(jī)與pc機(jī)打印口高速雙向數(shù)據(jù)通信接口

    avr單片機(jī)與pc機(jī)打印口高速雙向數(shù)據(jù)通信接口
    發(fā)表于 09-01 16:55 ?5次下載

    PCIE總線雙串口及打印口芯片CH382手冊(cè)

    電子發(fā)燒友網(wǎng)站提供《PCIE總線雙串口及打印口芯片CH382手冊(cè).pdf》資料免費(fèi)下載
    發(fā)表于 09-09 11:45 ?2次下載
    PCIE總線雙串口及<b class='flag-5'>打印口</b>芯片CH382手冊(cè)

    PCIE總線四串打印口芯片CH384手冊(cè)

    電子發(fā)燒友網(wǎng)站提供《PCIE總線四串打印口芯片CH384手冊(cè).pdf》資料免費(fèi)下載
    發(fā)表于 09-09 09:33 ?4次下載
    PCIE總線四串<b class='flag-5'>口</b>及<b class='flag-5'>打印口</b>芯片CH384手冊(cè)