Hello,
Currently trying to enable full hardware flow control on LPUART4 on a iMX93, I've had success enabling RTS and CTS but haven't been able to get DSR, DCD, and DTR enabled.
My DT pins are defined as follows:
pinctrl_uart4: uart4grp {
fsl,pins = <
MX93_PAD_ENET2_RD0__LPUART4_RX 0x31e
MX93_PAD_ENET2_TD0__LPUART4_TX 0x31e
MX93_PAD_ENET2_TD1__LPUART4_RTS_B 0x31e
MX93_PAD_ENET2_RD2__LPUART4_CTS_B 0x31e
MX93_PAD_ENET2_RX_CTL__LPUART4_DSR_B 0x31e
MX93_PAD_ENET2_TX_CTL__LPUART4_DTR_B 0x31e
>;
};
lpuart4: serial@42580000 {
compatible = "fsl,imx93-lpuart", "fsl,imx8ulp-lpuart", "fsl,imx7ulp-lpuart";
reg = <0x42580000 0x1000>;
interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_LPUART4_GATE>;
clock-names = "ipg";
dmas = <&edma2 19 0 0>, <&edma2 20 0 1>;
dma-names = "tx","rx";
uart-has-rtscts;
status = "ok";
};
]# cat /proc/tty/driver/fsl-lpuart
serinfo:1.0 driver revision:
0: uart:FSL_LPUART mmio:0x44380010 irq:18 tx:12447 rx:43 RTS|CTS|DTR|DSR|CD
1: uart:FSL_LPUART mmio:0x42690010 irq:24 tx:0 rx:0 CTS|DSR|CD
2: uart:FSL_LPUART mmio:0x42570010 irq:20 tx:0 rx:0 CTS|DSR|CD
3: uart:FSL_LPUART mmio:0x42580010 irq:21 tx:0 rx:0 CTS|DSR|CD
4: uart:FSL_LPUART mmio:0x42590010 irq:22 tx:0 rx:0 CTS|DSR|CD
5: uart:FSL_LPUART mmio:0x425A0010 irq:23 tx:0 rx:0 CTS|DSR|CD
6: uart:FSL_LPUART mmio:0x44390010 irq:19 tx:0 rx:0 CTS|DSR|CD
The serial port program is a standard program. Have you configured the serial port properties according to the ioctl provided by the Linux standard program?
Or use stty to set it?
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <termios.h>
int main() {
int fd = open("/dev/ttyS0", O_RDWR); // Change to the correct serial port
if (fd == -1) {
perror("open");
return 1;
}
int status;
// Get current modem control lines
ioctl(fd, TIOCMGET, &status);
// Enable DTR (Data Terminal Ready)
status |= TIOCM_DTR;
// Apply new settings
ioctl(fd, TIOCMSET, &status);
printf("DTR enabled.\n");
close(fd);
return 0;
}
HI @wcastidex!
Thank you for contacting NXP Support!
Unfortunately those functions are not implemented in the driver but the kernel can manage those functions using gpios instead.
You can add the next lines to your device tree:
dtr-gpios = <&gpio4 3 GPIO_ACTIVE_LOW>;
dsr-gpios = <&gpio4 4 GPIO_ACTIVE_LOW>;
dcd-gpios = <&gpio4 6 GPIO_ACTIVE_LOW>;
#Example
Best Regards!
Chavira
gpio cts and rts can be used because the driver implements this function and calls the API provided by serial_mctrl_gpio.c, such as imx.c, another driver of imx.
However, fsl_lpuart.c does not see the API provided by serial_mctrl_gpio.c being called.
In addition, if uart-has-rtscts is not removed, even if the gpio control you mentioned is added, it will not work. Because the serial bindings have uart-has-rtscts; it means that the rts cts of the serial controller is used.
serial.yaml
uart-has-rtscts:
$ref: /schemas/types.yaml#/definitions/flag
description:
The presence of this property indicates that the UART has dedicated lines
for RTS/CTS hardware flow control, and that they are available for use
(wired and enabled by pinmux configuration). This depends on both the
UART hardware and the board wiring.
https://github.com/nxp-imx/linux-imx/blob/lf-6.6.52-2.2.0/drivers/tty/serial/serial_mctrl_gpio.c
https://github.com/nxp-imx/linux-imx/tree/lf-6.6.52-2.2.0/drivers/tty/serial/fsl_lpuart.c
https://github.com/nxp-imx/linux-imx/tree/lf-6.6.52-2.2.0/drivers/tty/serial/imx.c
/* called with port.lock taken and irqs caller dependent */
static void imx_uart_rts_active(struct imx_port *sport, u32 *ucr2)
{
*ucr2 &= ~(UCR2_CTSC | UCR2_CTS);
mctrl_gpio_set(sport->gpios, sport->port.mctrl | TIOCM_RTS);
}
/* called with port.lock taken and irqs caller dependent */
static void imx_uart_rts_inactive(struct imx_port *sport, u32 *ucr2)
{
*ucr2 &= ~UCR2_CTSC;
*ucr2 |= UCR2_CTS;
mctrl_gpio_set(sport->gpios, sport->port.mctrl & ~TIOCM_RTS);
}
Hi all!
The fsl-lpuart driver only can manage the cts and rts pins from hardware.
since the other signals are not commonly used are not implemented in our driver but our hardware is capable to manage those signals.
As you mention, declaring the pins on device tree the Kernel is not solving the signals and for that case we have to do it manually in a c or python program.
Best Regards!
Chavira