Problem with Prolific PL2303 Driver and soft flow control

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dear experts,

I've got several of these Prolific PL2303 USB to Serial adapters (lsusb output below) and have found that they do not send any data when the IXON bit is set.

What I've done so far:

A Null-Modem Cable (pins 2--3, 3--2, 5--5 connected) connects an on-board serial (RS232) port (/dev/ttyS0) to a PL2303-based USB to serial adapter (/dev/ttyUSB0).

When running sender.c on ttyS0 for transmitting and IXON is set, and receiver.c on ttyUSB0 for receiving everything works fine: some data is being received, then a short break and then the rest of the data arrives.(sender.c and receiver.c are attached)

When I reverse the direction: sender.c on ttyUSB0 for transmitting and IXON is set, and receiver.c on ttyS0 used for receiving, no data arrives. Checking with an oscilloscope on the rx/tx lines reveals that the problem lies within the transmitting USB to serial adapter as no data (pulses) are present on the lines. Sending VSTART or VSTOP from the receiver site has no effect.

For comparison: clearing the IXON bit (in sender.c on ttyUSB0) makes the data flow albeit disabling soft flow control. So a hardware or user space (libc) problem can be ruled out, right?

I hope this is of any help and I'd be willing to carry out further testing if needed.

Marcin

[marcin@carbon18 ~]$ lsusb
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 002: ID 0bda:0328 Realtek Semiconductor Corp. USB3.0-CRW
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 005: ID 06cb:009a Synaptics, Inc. Metallica MIS Touch Fingerprint Reader
Bus 001 Device 004: ID 5986:2115 Acer, Inc Integrated Camera
Bus 001 Device 006: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port / Mobile Action MA-8910P
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

[marcin@carbon18 ~]$ uname -a
Linux carbon18 5.11.18-1-MANJARO #1 SMP PREEMPT Sun May 2 11:48:22 UTC 2021 x86_64 GNU/Linux

--
*Marcin Mleczko*
Hochschule Hannover
Fakultät I, Elektro- und Informationstechnik
Ricklinger Stadtweg 120
30459 Hannover
Tel.: +49 511 9296 1298
marcin.mleczko@xxxxxxxxxxxxxx
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <termios.h>

#define DEV_FILE1 "/dev/ttyUSB0"
//#define DEV_FILE1 "/dev/ttyS0"

int set_interface_attribs(int, int);
int vStart, vStop;
int main (){
	char txt[20] = "lkdkf\n";
	char rBuf[300];
	int fid, bw, br, i,k;
	


	fid = open(DEV_FILE1, O_RDWR);
	if (fid < 0) {
		printf("fid: %d\n", fid);
		perror("open: ");
		printf("%s\n", strerror(errno));
		return -1;
	}
	set_interface_attribs(fid, B9600);

	for (i=0; i<8; i++){		// 1st loop - start receiving some data
		for (k=0; k<4; k++){

			br = read(fid, rBuf, sizeof(rBuf));
			printf("%d %s, ", *rBuf, rBuf); fflush(stdout);
			memset(rBuf, 0, 300);
		}
		printf("--1\n"); fflush(stdout);
	}

	txt[0] = vStop;
	bw = write(fid, txt, 1);	// simulate receive buffer full


	for (i=0; i<2; i++){		// 2nd loop - continue trying to receive data (with VTIME timeout) to check that no data are being sent
		for (k=0; k<4; k++){
			br = read(fid, rBuf, sizeof(rBuf));
			printf("%d %s, ", *rBuf, rBuf); fflush(stdout);
			memset(rBuf, 0, 300);
		}
		printf("--2\n"); fflush(stdout);
	}

	txt[0] = vStart;
	bw = write(fid, txt, 1);	// signal "receiver ready again" to sender

	for (i=0; i<50; i++){		// 3rd loop - receiving data goes on
		for (k=0; k<4; k++){
			br = read(fid, rBuf, sizeof(rBuf));
			printf("%d %s, ", *rBuf, rBuf); fflush(stdout);
			memset(rBuf, 0, 300);
		}
		printf("--3\n"); fflush(stdout);
	}


	close(fid);
	return 0;
	}


int set_interface_attribs(int fd, int speed)
{
    struct termios tty;

    if (tcgetattr(fd, &tty) < 0) {
        printf("Error from tcgetattr: %s\n", strerror(errno));
        return -1;
    }

    cfsetospeed(&tty, (speed_t)speed);
    cfsetispeed(&tty, (speed_t)speed);
/*c_iflag*/

	tty.c_iflag &= ~INPCK;						/* don't Enable input parity checking. */
	tty.c_iflag &= ~ISTRIP;						/* don't Strip off eighth bit. */
	tty.c_iflag &= ~INLCR;						/* don't Translate NL to CR on input. */
	tty.c_iflag &= ~ICRNL;						/* don't Translate carriage return to newline on input. */
	//~ tty.c_iflag |= ICRNL;						/* Translate carriage return to newline on input. */
	tty.c_iflag &= ~IUCLC;						/* don't Map uppercase characters to lowercase on input. */
	tty.c_iflag &= ~IXON;						/* don't Enable XON/XOFF flow control on output. */
	//~ tty.c_iflag |= IXON;						/* Enable XON/XOFF flow control on output. */
	tty.c_iflag &= ~IXOFF;						/* don't Enable XON/XOFF flow control on input. */
	//~ tty.c_iflag |= IXOFF;						/* Enable XON/XOFF flow control on input. */
	tty.c_iflag &= ~IXANY;						/* don't Enable XON/XOFF flow control on input. */
	//~ tty.c_iflag |= IXANY;						/* Enable XON/XOFF flow control on input. */

/*c_oflag*/    
	tty.c_oflag &= ~INPCK;						/* don't Enable implementation-defined output processing. */

/*c_cflag*/
              

	// clear what needs to be cleard
	tty.c_cflag &= ~CSTOPB;						/* only need 1 stop bit */
	tty.c_cflag &= ~PARENB;						/* no parity bit */
	tty.c_cflag &= ~CRTSCTS;					/* no hardware flowcontrol */
	tty.c_cflag &= ~(CS5 | CS6 | CS7 | CS8);	/* clear all CSIZE bits */
	
	// set what needs to be set
	tty.c_cflag |= CS8;							/* Character size mask.  Values are CS5, CS6, CS7, or CS8.*/
	tty.c_cflag |= CLOCAL;						/* ignore modem control lines */
	tty.c_cflag |= CREAD;						/* enable receiver */
	

/*c_lflag*/
	tty.c_lflag &= ~ISIG;			/* don't generate the corresponding signal on INTR, QUIT, SUSP, or DSUSP */
	//~ tty.c_lflag |=  ICANON;			/* Enable canonical mode */
	tty.c_lflag &= ~ICANON;			/* don't Enable canonical mode */
	tty.c_lflag &= ~IEXTEN;			/* don't Enable implementation-defined input processing */
	tty.c_lflag &=  ~ECHO;			/* don't Echo input characters */
	//~ tty.c_lflag |=  ECHO;			/* don't Echo input characters */

    /* only for non canonical mode; fetch bytes as they become available */
    tty.c_cc[VMIN] = 0;
    tty.c_cc[VTIME] = 20;
    vStart = tty.c_cc[VSTART];
    vStop = tty.c_cc[VSTOP];
	printf("VSTART: %d, VSTOP: %d\n", tty.c_cc[VSTART], tty.c_cc[VSTOP]); fflush(stdout);

    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
        printf("Error from tcsetattr: %s\n", strerror(errno));
        return -1;
    }
    return 0;
}
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <termios.h>

#define DEV_FILE0 "/dev/ttyS0"
//#define DEV_FILE0 "/dev/ttyUSB0"

int set_interface_attribs(int, int);

int main (){
	char txt[300] = "lg  ";
	char rBuf[300];
	int fid, bw, br;
	

	fid = open(DEV_FILE0, O_RDWR | O_NDELAY | O_NOCTTY);
	if (fid < 0) {
		printf("fid: %d\n", fid);
		perror("open: ");
		printf("%s\n", strerror(errno));
		return -1;
	}
	if ( ! isatty(fid) ) {
        printf("Not a TTY device.n");
        return -1;
     }
	set_interface_attribs(fid, B9600);

	while (1){
	bw = write(fid, txt, strlen(txt)); 
	if (bw < 0) {
		printf("bw: %d\n", bw);
		perror("write: ");
		printf("%s", strerror(errno));
		return -1;
	}

	printf("%d bytes: %s\n", bw, txt); fflush(stdout);
	txt[3]++;
	sleep(1);
	}

	close(fid);
	return 0;
	}


int set_interface_attribs(int fd, int speed)
{
    struct termios tty;

    if (tcgetattr(fd, &tty) < 0) {
        printf("Error from tcgetattr: %s\n", strerror(errno));
        return -1;
    }

    cfsetospeed(&tty, (speed_t)speed);
    cfsetispeed(&tty, (speed_t)speed);
/*c_iflag*/

	tty.c_iflag &= ~INPCK;						/* don't Enable input parity checking. */
	tty.c_iflag &= ~ISTRIP;						/* don't Strip off eighth bit. */
	tty.c_iflag &= ~INLCR;						/* don't Translate NL to CR on input. */
	tty.c_iflag |=  IGNCR;						/* Ignore carriage return on input. */	
	tty.c_iflag &= ~ICRNL;						/* don't Translate carriage return to newline on input. */
	tty.c_iflag &= ~IUCLC;						/* don't Map uppercase characters to lowercase on input. */
	//tty.c_iflag &= ~IXON;						/* don't Enable XON/XOFF flow control on output. */
	tty.c_iflag |= IXON;						/* Enable XON/XOFF flow control on output. */
	//tty.c_iflag &= ~IXOFF;						/* don't Enable XON/XOFF flow control on input. */
	tty.c_iflag |= IXOFF;						/* Enable XON/XOFF flow control on input. */
	tty.c_iflag &= ~IXANY;						/* don't (XSI) Typing any character will restart stopped output. */
	//~ tty.c_iflag |= IXANY;						/* (XSI) Typing any character will restart stopped output. */


/*c_oflag*/    
	tty.c_oflag &= ~INPCK;						/* don't Enable implementation-defined output processing. */


/*c_cflag*/
	// clear what needs to be cleard
	tty.c_cflag &= ~CSTOPB;						/* only need 1 stop bit */
	tty.c_cflag &= ~PARENB;						/* no parity bit */
	tty.c_cflag &= ~CRTSCTS;					/* no hardware flowcontrol */
	tty.c_cflag &= ~(CS5 | CS6 | CS7 | CS8);	/* clear all CSIZE bits */
	
	// set what needs to be set
	tty.c_cflag |= CS8;							/* Character size mask.  Values are CS5, CS6, CS7, or CS8.*/
	tty.c_cflag |= CLOCAL;					/* ignore modem control lines */
	tty.c_cflag |= CREAD;						/* enable receiver */
	

/*c_lflag	*/
	tty.c_lflag &= ~ISIG;			/* don't generate the corresponding signal on INTR, QUIT, SUSP, or DSUSP */
	tty.c_lflag |=  ICANON;			/* Enable canonical mode */
	//~ tty.c_lflag &=  ~ICANON;			/* Enable canonical mode */
	tty.c_lflag &= ~IEXTEN;			/* don't Enable implementation-defined input processing */
	tty.c_lflag &=  ~ECHO;			/* don't Echo input characters */


    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
        printf("Error from tcsetattr: %s\n", strerror(errno));
        return -1;
    }
    return 0;
}

[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux