OpenNuvoton / NUC980-linux-5.10.y

NUC980 Linux Kernel 5.10.y
Other
11 stars 7 forks source link

serial driver doesn't support SER_RS485_RX_DURING_TX #12

Closed Aptahar closed 1 month ago

Aptahar commented 1 month ago

There is no reaction to SER_RS485_RX_DURING_TX flag, always receiving while transmit.
Other flags are working.
Init code:

if(ioctl(hport, TIOCGRS485, &rs485conf) < 0) return -1;
rs485conf.flags |= SER_RS485_ENABLED;           // Enable RS485 mode
rs485conf.flags |= SER_RS485_RTS_ON_SEND;       // Set logical level for RTS pin equal to 1 when sending
rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);  // set logical level for RTS pin equal to 0 after sending
if(PORT_MODE_RS485_HALF == cfg.port_type[num])
{
  rs485conf.flags &= ~(SER_RS485_RX_DURING_TX); // in halfdup disable rx while tx
}
else
{
  rs485conf.flags |= (SER_RS485_RX_DURING_TX);   // otherwise enable rx while tx
}
if(ioctl(hport, TIOCSRS485, &rs485conf) < 0) return -1;

And there is no code in /drivers/tty/serial/nuc980_serial.c for this flag.

ychuang3 commented 1 month ago

NUC980 RS485 always support RX during TX.

Aptahar commented 1 month ago

But I need to disable Rx during Tx, is it possible?

ychuang3 commented 1 month ago

NUC980 RS485 controller does not support disable RX independently. You may control the NUC980 UART/RS485 RTS pin to achieve half-duplex.

Aptahar commented 1 month ago

Did you mean this functions?

static void rs485_start_rx(struct uart_nuc980_port *port)
{
#if 0  // user can enable to control RTS pin level
    // when enable this define, user need disable auto-flow control
    struct uart_nuc980_port *up = (struct uart_nuc980_port *)port;

    if(port->rs485.flags & SER_RS485_RTS_AFTER_SEND) {
        // Set logical level for RTS pin equal to high
        serial_out(port, UART_REG_MCR, (serial_in(port, UART_REG_MCR) & ~0x200) );
    } else {
        // Set logical level for RTS pin equal to low
        serial_out(port, UART_REG_MCR, (serial_in(port, UART_REG_MCR) | 0x200) );
    }
#endif
}

static void rs485_stop_rx(struct uart_nuc980_port *port)
{
#if 0  // user can enable to control RTS pin level
    // when enable this define, user need disable auto-flow control
    if(port->rs485.flags & SER_RS485_RTS_ON_SEND) {
        // Set logical level for RTS pin equal to high
        serial_out(port, UART_REG_MCR, (serial_in(port, UART_REG_MCR) & ~0x200) );
    } else {
        // Set logical level for RTS pin equal to low
        serial_out(port, UART_REG_MCR, (serial_in(port, UART_REG_MCR) | 0x200) );
    }
#endif
}
mjchen1 commented 1 month ago

RTS is only used to control the transmission or reception of rs485 transceiver. Is there an rs485 transceiver on your platform??

Aptahar commented 1 month ago

RTS is only used to control the transmission or reception of rs485 transceiver. Is there an rs485 transceiver on your platform??

Yes, we use MAX3160EAP chip for RS485. In half duplex mode this chip translate tx (pin 16) to rx (pin 8). Снимок экрана от 2024-07-18 08-27-19

mjchen1 commented 1 month ago

The RTS pin on the NUC980 is currently set to auto mode. When transmitting data (TX), it automatically pulls the RTS pin, enabling the transceiver to enter TX mode without requiring manual intervention. When TX is not actively transmitting data, the RTS pin remains in RX (receive) mode. Additionally, the hardware of the NUC980 does not provide a separate function to disable RX independently

Aptahar commented 1 month ago

Maybe it is possible in driver to drop received data while transmitting?

mjchen1 commented 1 month ago

On an RS485 bus, there should only be one set of data transmitting at any given time, so it should not be possible to both transmit (TX) data and receive (RX) data simultaneously

Aptahar commented 1 month ago

Yes. But the problem in MAX3160EAP that it's connect rx and tx on TTL pins and echoing all while transmitt.

mjchen1 commented 1 month ago

The NUC980 hardware does not have a separate feature to disable RX (receive) functionality. Perhaps you could consider implementing a mechanism in the application code to compare received RX data with TX (transmit) data and exclude matching data accordingly.

Aptahar commented 1 month ago

Ok, thanks