0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux系统LPT打印口批量产测工具

jf_49670627 来源:jf_49670627 作者:jf_49670627 2023-04-12 11:44 次阅读

1 软件功能

该软件用于在Linux平台测试CH35X/CH38X(PCI/PCIe转串并口)的并口各引脚功能是否正常。方便对设备进行出厂测试。

2 并口测试硬件治具

在测试前,需要制作单独的硬件治具,按下表连接信号线:

2.png

引脚连接示意图:

3 软件使用方法

  • 插入待测试PCI/PCIe转并口设备。
  • 输入lspci –v命令查看设备的枚举信息,若找到厂商ID为[1C00]或[4348]的设备,则表示已经正常识别到该硬件。

  • 通过lsmod命令查看设备关联驱动是否已加载,设备所需驱动包括:parport、parport_pc、lp驱动。驱动加载后,查看系统/dev目录,会多出parportX(X为数字)节点,示例:

  • 编译测试程序,生成目标可执行程序,输入./parport_test -D /dev/parport0 –h命令查看帮助,输出其他命令无效。运行程序:[可执行文件名] -D [设备节点名称] –s

4 测试错误码说明

根据输出的错误码和终端输出信息可判断故障信号线,下表为错误码和说明。

错误码 错误码说明
0 STB-D0通讯错误
1 AFD-D1通讯错误
2 INIT-D2通讯错误
3 SIN-D3通讯错误
4 D6-ERR通讯错误
5 D4-SELT通讯错误
6 D5-PE通讯错误
7 D6-ACK通讯错误
8 D7-BUSY通讯错误

5 测试实例

测试成功实例

测试错误实例

根据输出信息,D4-SELT、D5-PE、D6-ACK和D7-BUSY信号通讯存在错误。

根据输出信息,STB-D0信号通讯存在错误。

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;
}

​审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    10990

    浏览量

    206738
  • PCIe
    +关注

    关注

    13

    文章

    1083

    浏览量

    80854
  • 命令
    +关注

    关注

    5

    文章

    638

    浏览量

    21849
  • 并口
    +关注

    关注

    0

    文章

    32

    浏览量

    17319
  • LPT
    LPT
    +关注

    关注

    0

    文章

    6

    浏览量

    3885
收藏 人收藏

    评论

    相关推荐

    Linux系统串口批量产工具

    本文针对Linux系统上如何对各类串口硬件进行出厂测试进行硬件连接和软件使用说明,提供的软件测试工具wchsertest,适用于USB、PCI、PCIe转串口设备等、同样也适用于原生ttyS串口。
    的头像 发表于 04-12 11:38 3136次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>系统</b>串口<b class='flag-5'>批量产</b>测<b class='flag-5'>工具</b>

    80C51和CH375的USB打印机驱动设计

    和USB打印机的连接。本文利用单片机和USB总线接口芯片实现LPT-USB打印机的驱动器设计。利用该设计将能够实现并行打印口数据可以在USB打印
    发表于 03-03 17:43

    打印口虚拟驱动库_WinIO

    打印口虚拟驱动库_WinIO[attach]***[/attach]
    发表于 04-13 21:13

    求助各位大侠主板上25针LPT连接并口编程器问题

    确定以下条件是否满足:1. 与编程器通讯前,接通编程器电源.2. 编程器与计算机的打印口相连.3. 计算机打印口地址为0x278,0x378或0x3bc.我确认我接了电源,接线没有出错,并口地址是0x378.哪位大侠知道这是为什么,求指教啊!!
    发表于 06-28 10:00

    给大家推荐个 性价比较好的 PCIE 总线双串口及打印口芯片

    资料在附件 ,CH382 是PCI-Express总线的双串口及打印口芯片,包含两个兼容16C550或者16C750 的异步串口和一个EPP/ECP 增强型双向并口。异步串口提供收发独立的256字节
    发表于 12-30 09:19

    采用CH375接口电路实现LPT-USB打印机驱动器设计

    和USB总线接口器件实现LPT-USB打印机驱动器的设计。利用该设计将能够实现并行打印口数据在USB打印机上的直接打印,克服了有些并口仪器必
    发表于 06-18 05:00

    如何利用单片机和USB总线接口芯片实现LPT-USB打印机的驱动器设计

    本文利用单片机和USB总线接口芯片实现LPT-USB打印机的驱动器设计。利用该设计将能够实现并行打印口数据可以在USB打印机上的直接打印工作
    发表于 04-26 06:36

    如何通过打印口读写I2C存储器

    当前版本 Quit 退出至DOS 同时在屏幕的底部显示调入的文件名,起始及结束地址,以及校验和。 24CXX.EXE约26.7Kbytes,使用打印口LPT1(即地址为378H),支持ATMEL
    发表于 05-14 06:03

    调试打印口硬件接的是UART5要怎样修改才能用printf()函数 ?

    调试打印口硬件接的是 UART5 要怎样修改才能用printf()函数 ? 用的是官方列程,默认是UART0 可以打印,现在要改到UART5 上 去 。 用的是Keil 5开发环境
    发表于 08-22 08:04

    基于VB6.0的打印口(LPT)的应用

             在 VB6.0 编程环境下,调用动态链接库,通过打印口LPT)实现PC 机对89C2051 单片机的编程。关键词: VB6.0 语言 89C2051 单片机动态链接库(DL
    发表于 09-11 09:13 39次下载

    打印口底视图

    打印口底视图   打印口底视图:  
    发表于 05-31 14:26 897次阅读

    什么是LPT

    什么是LPT打印口,一般打印机用LTP1口,打印接口模式可在BIOS下调动,有EPP,ECP等模式。但现在越来越多的打印机采用了USB
    发表于 01-22 13:58 2402次阅读

    PC机打印口与便携式数据采集系统接口设计

    介绍了PC 机打印口与外设的接口设计方法,巧妙地解决了打印口对大容量存储器的数据读取问题,并利用双端口RAM 在板存储技术,设计了基于PC 机打印口的便携式数据采集系统。文章阐
    发表于 07-19 15:11 36次下载
    PC机<b class='flag-5'>打印口</b>与便携式数据采集<b class='flag-5'>系统</b>接口设计

    Batchplot免费版下载(CAD批量打印工具

    Batchplot是一个专门针对AutoCAD2000以上版本设计的单DWG多图纸的批量打印批量生成布局、批量分图工具。Batchplot
    发表于 12-07 18:29 0次下载
    Batchplot免费版下载(CAD<b class='flag-5'>批量</b><b class='flag-5'>打印</b><b class='flag-5'>工具</b>)

    Gladius 3D打印口罩开源分享

    电子发烧友网站提供《Gladius 3D打印口罩开源分享.zip》资料免费下载
    发表于 06-19 16:26 0次下载
    Gladius 3D<b class='flag-5'>打印口</b>罩开源分享