Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RTS-GPIO not working with imx tty driver #76

Open
BrendanSimon opened this issue Nov 22, 2020 · 0 comments
Open

RTS-GPIO not working with imx tty driver #76

BrendanSimon opened this issue Nov 22, 2020 · 0 comments

Comments

@BrendanSimon
Copy link

NOTE: I originally posted this issue in the linux-imx repo here:

ADVANTECH-Corp/linux-imx#1

Now I found this linux-imx6 repo. I'm not sure why there are two "imx" repos, but the problems exists in both.


I'm trying to use the rts-gpio devicetree setting to emulate RTS modem control signals for an RS485 serial bus.

I can NOT use hardware RTS because the Advantech RSB-3430 does not have those signals exposed on the 40-pin connectors (CN1 and CN2).

I'm doing manual gpio sets for RTS from user space (using gpiod) but it is not reliable, especially under processor load. The timing is not reliable and clobbers responses from other devices on the RS485 bus.

The imx tty driver does support the rts-gpio devicetree setting. When I specify it I can see that the gpiod system reports that it is in use (by consumer "rts") and I cannot manually set it high/low anymore from user space.

HOWEVER, the gpio does not toggle when sending data. Looking at the imx tty driver, I can see that there are #ifdef CONFIG_ARCH_ADVANTECH blocks that skip the RS485 handling of RTS. i.e. the functions imx_port_rts_active() and imx_port_rts_inactive() are never called (see code example below).

Why is there special code for Advantech to disable this feature ??

Can it be fixed/patched please so I can use RS485 with my Advantech RSB-3430 board please.

I'm using the adv_4.14.98_2.0.0_ga kernel.

https://github.com/ADVANTECH-Corp/linux-imx6/blob/imx_4.14.98_2.0.0_ga/drivers/tty/serial/imx.c

static void imx_stop_tx(struct uart_port *port)
{
	struct imx_port *sport = (struct imx_port *)port;
	unsigned long temp;

	/*
	 * We are maybe in the SMP context, so if the DMA TX thread is running
	 * on other cpu, we have to wait for it to finish.
	 */
	if (sport->dma_is_enabled && sport->dma_is_txing)
		return;

	temp = readl(port->membase + UCR1);
	writel(temp & ~UCR1_TXMPTYEN, port->membase + UCR1);

	/* in rs485 mode disable transmitter if shifter is empty */
	if (port->rs485.flags & SER_RS485_ENABLED &&
	    readl(port->membase + USR2) & USR2_TXDC) {
		temp = readl(port->membase + UCR2);
#ifdef CONFIG_ARCH_ADVANTECH
		temp &= ~UCR2_CTS;
#else
		if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
			imx_port_rts_active(sport, &temp);
		else
			imx_port_rts_inactive(sport, &temp);
		temp |= UCR2_RXEN;
#endif
		writel(temp, port->membase + UCR2);

		temp = readl(port->membase + UCR4);
		temp &= ~UCR4_TCEN;
		writel(temp, port->membase + UCR4);
	}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant