UART flow control with WP7608

Hi jyijyi,@jyijyi

Please answer Tanoue-san’s questions.

Thank you.

–TAK

didn’t i already answer?

Hi jyijyi,

Sorry for missing read since my browse still not be updated.

I think your answer is only for “how to read GPIO pins from Legato API”.
And also, you suggestion is based on adding GPIO by the modification of “yocto/kernel/driver/gpio/gpiolib.c.”

Is my understanding correct?

If so , the customer needs to know all GPIO numbers of following pins.

RTS, DTR, DCD, RI, TxD , CTS, DSR, RxD

We know only DCD,DTR and DSR.

And, if you provide above information, I think we can read them by “cat” commands.

Thank you.

–TAK

Hi Tanoue-san,

I think the best way to check all 8-wire UART’s pins with just one command.
It means I want to avoid mixing some type commands(echo/) on a program, if possible.

If we can provide GPIO numbers, I think you can read it by “cat” that I and jyijyi mentioned before.
If you’d like to read it on command, you should make C source or shell like usual Linux application.

Thank you.

–TAK

I don’t recommend your suggestion.
Here I have tried to put RTS/CTS/TXD/RXD inside “yocto/kernel/driver/gpio/gpiolib.c", after that if you turn them into GPIO, later you cannot use it to communicate as UART in legato application.
That is why i suggest another way for accessing RTS (i.e. using AT comnand) and CTS (i.e. ioctl())pins.

Hi @jyijyi

Here I have tried to put RTS/CTS/TXD/RXD inside “yocto/kernel/driver/gpio/gpiolib.c",
after that if you turn them into GPIO, later you cannot use it to communicate as UART in legato application.
That is why i suggest another way for RTS and CTS pins.

I wait this information !!!
I understand why you suggested AT command to read RTS/CTS.

Hmm, is there any ways else to read RTS and CTS?
There is no description of your suggested command in the latest AT command manual.
So, we are not sure which parameter of return is read value.

Thank you.

–TAK

I cannot find another way to access RTS and CTS other than my previous suggestion.

I think using ioctl() to set CTS is the most proper way and standard way.
Currently I have no idea why RTS cannot be read by ioctl().
Below is the code to read the RTS status by AT command, let me know if you accept this.
If no, we need a FW fix on this so that we can read RTS status by ioctl().

int get_RTS_status()
{

	 int     fd_rts;
	 int     sel,len,i;
	 int     wrote = 0;
	 char * pch;

	 fd_set  rfds;
	 unsigned char buf[1024];
	 unsigned char cmd[100];
	 struct timeval timeout;
	 fd_rts = open ("/dev/ttyAT", O_RDWR | O_NOCTTY | O_NDELAY);
      struct termios options;
      fcntl (fd_rts, F_SETFL, 0);
      tcgetattr (fd_rts, &options);
	  options.c_cflag |= (CLOCAL | CREAD);
	  options.c_cflag &= ~PARENB;
	  options.c_cflag &= ~CSTOPB;
	  options.c_cflag &= ~CSIZE;
	  options.c_cflag |= CS8;
	  options.c_cflag |= CRTSCTS;
	  options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
	  options.c_iflag &= ~(INLCR | ICRNL | IGNCR);
	  options.c_oflag &= ~OPOST;
	  options.c_oflag &= ~OLCUC;
	  options.c_oflag &= ~ONLRET;
	  options.c_oflag &= ~ONOCR;
	  options.c_oflag &= ~OCRNL;
	  tcsetattr (fd_rts, TCSANOW, &options);


	  memset(cmd,0,sizeof(cmd));
	  strncpy(cmd,"AT!entercnd=\"A710\";!BSGPIO?6\r\n",30);
	  wrote = write (fd_rts, cmd, strlen (cmd));
	  LE_INFO("wrote  %d ",wrote);
	  if (wrote<0)
	  {
		  LE_INFO("RTS = -1 ");
              close(fd_rts);
		  return -1;
	  }

	  tcdrain (fd_rts);
	   usleep (100000);

	   for (i = 0; i < 100; i++) {

	     FD_ZERO (&rfds);
	     FD_SET (fd_rts, &rfds);

	     timeout.tv_sec = 0;
	     timeout.tv_usec =10000 ;

	     if ((sel = select (fd_rts + 1, &rfds, NULL, NULL, &timeout)) > 0)
	     {
	       if (FD_ISSET (fd_rts, &rfds)) {
				memset (buf, 0, sizeof (buf));
				len = read (fd_rts, buf, sizeof (buf));
	       }

	     }
	   }

	     close(fd_rts);

	 	pch = strstr(buf, "State:     0");
	 	if (pch != NULL)
	 		{
	 		 	 LE_INFO("RTS =0 ");
	 		 	return 0;
	 		}
	 		else /* Substring not found */
	 		{
	 			LE_INFO("RTS =1 ");
	 			return 1;
	 		}




}

Hi, jyijyi

Thank you for suggesting a way to control CTS/RTS.
I have two question.

According to “AirPrime_WP76xx_Product_Technical_Specification_Rev9_3.pdf”, There is the following note.

Note: UART signals are named with respect to the host device, and directions are listed with
respect to the module. For example, UART1_RX is an output from the module to the host.

I think that RTS is output and CTS is input.
Is it correct?

If RTS is output, how to modify the following sentence?

strncpy(cmd,“AT!entercnd="A710";!BSGPIO?6\r\n”,30);

BR,
Tanoue

From the description of here about UART serial communication:

If “UART1_RX is an output from the module to the host”, that means the PTS is assuming the module to be DCE.

For your question 1, it is not correct.
According to the pinout table in PTS, UART1_RTS is input and UART1_CTS is output.

For your question 2, actually the RTS is input as stated above.

Hi, jyijyi

Thank you for kind explanation.

I could solve how to control RS232C’s pin about DTR, DSR, DCD and RI.

But CTS and RTS remain.

At first, I checked CTS control by reference to the following topic.

However, I could not see changing voltage of CTS output.

Could you check my program?

#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <string.h>

int fd;

void ttyHS0_Init()
{
struct termios options;

fd = open(“/dev/ttyHS0”, O_RDWR | O_NOCTTY);
if(fd < 0) {
printf(“open /dev/ttyHS0 ERROR…\n”);
}

fcntl (fd, F_SETFL, 0);
tcgetattr (fd, &options);
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~CRTSCTS;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_iflag &= ~(INLCR | ICRNL | IGNCR);
options.c_oflag &= ~OPOST;
options.c_oflag &= ~OLCUC;
options.c_oflag &= ~ONLRET;
options.c_oflag &= ~ONOCR;
options.c_oflag &= ~OCRNL;
tcsetattr (fd, TCSANOW, &options);
}

void set_CTS_High()
{
int serialStatus = 0;

ioctl(fd, TIOCMGET, &serialStatus);

serialStatus |= TIOCM_RTS;
ioctl(fd, TIOCMSET, &serialStatus);
}

void set_CTS_Low()
{
int serialStatus = 0;

ioctl(fd, TIOCMGET, &serialStatus);

serialStatus &= ~TIOCM_RTS;
ioctl(fd, TIOCMSET, &serialStatus);
}

int main(void) {

// 5s CTS high low change
while(1) {
ttyHS0_Init();
set_CTS_High();
printf(“============[HIGH] CTS========================\n”);
printf(“[HIGH → LOW] after 5s\n”);
sleep(5);
close(fd);
ttyHS0_Init();
set_CTS_Low();
printf(“============[LOW] CTS=========================\n”);
printf(“[LOW → HIGH] after 5s\n”);
sleep(5);
close(fd);
}
return 0;
}

BR,
Tanoue

Maybe you can run my sample application attached here.
It will change the status of CTS every three seconds.
It is working on my WP7608 FW R12.UART_Test1.rar (99.5 KB)

Hi, jyijyi

I could see changing voltage of CTS output with your program.
Next, I will check RTS input signal by AT command.

Thank you very much.

Hi, jyijyi
From your reply, I think using ioctl() can set the CTS pin。
But if I want to get RTS pin status, Can I use the output of ioctl(fd1, TIOCMGET, &arg) ?
Or the only way I can do is using AT command?

I think so, i remember only AT command works for RTS.

Hi, jyijyi
Thanks for your answer 。
But I still don’t know the following AT command’s meanings

I find nothing with “!BSGPIO?” in the file named 【4118047 WPx5xx-76xx-77xx AT Command Reference_r7.1.pdf】
Can you tell me more information about this AT command?
Thanks!

I don’t have full information.
But you can refer to UART_Test1.rar on how to read the status.