eclipse / mraa

Linux Library for low speed IO Communication in C with bindings for C++, Python, Node.js & Java. Supports generic io platforms, as well as Intel Edison, Intel Joule, Raspberry Pi and many more.
http://mraa.io
MIT License
1.37k stars 614 forks source link

Implement UART flow control functionality #646

Open nicola-lunghi opened 7 years ago

nicola-lunghi commented 7 years ago

in the file https://github.com/intel-iot-devkit/mraa/blob/master/src/uart/uart.c

on function

mraa_uart_context
mraa_uart_init(int index)

...

 if (!plat->no_bus_mux) {
        int pos = plat->uart_dev[index].rx;
        if (pos >= 0) {
            if (plat->pins[pos].uart.mux_total > 0) {
                if (mraa_setup_mux_mapped(plat->pins[pos].uart) != MRAA_SUCCESS) {
                    syslog(LOG_ERR, "uart%i: init: failed to setup muxes for RX pin", index);
                    return NULL;
                }
            }
        }

The pin for rx and tx are checked if they are gpio but not the pin for CTS/RTS hardware flow control.

So we need a way to know if there are CTS/RTS pin defined in the pin config and if you want to use the hardware flow control module the module need to configure those pins as CTS/RTS

I don't know if the best place to put this is in the init function (but we need to know the mode before the init) or in the set_flowcontrol function (or in other functions?)

mraa_result_t
mraa_uart_set_flowcontrol(mraa_uart_context dev, mraa_boolean_t xonxoff, mraa_boolean_t rtscts)
{
    if (!dev) {
        syslog(LOG_ERR, "uart: set_flowcontrol: context is NULL");
        return MRAA_ERROR_INVALID_HANDLE;
    }

    if (IS_FUNC_DEFINED(dev, uart_set_flowcontrol_replace)) {
        return dev->advance_func->uart_set_flowcontrol_replace(dev, xonxoff, rtscts);
    }

    // hardware flow control
    int action = TCIOFF;
    if (xonxoff) {
        action = TCION;
    }
    if (tcflow(dev->fd, action)) {
        return MRAA_ERROR_FEATURE_NOT_SUPPORTED;
    }

    // rtscts
    struct termios termio;

    // get current modes
    if (tcgetattr(dev->fd, &termio)) {
        syslog(LOG_ERR, "uart%i: set_flowcontrol: tcgetattr() failed: %s", dev->index, strerror(errno));
         return MRAA_ERROR_INVALID_RESOURCE;
    }

    if (rtscts) {
        termio.c_cflag |= CRTSCTS;
    } else {
        termio.c_cflag &= ~CRTSCTS;
    }

    if (tcsetattr(dev->fd, TCSAFLUSH, &termio) < 0) {
        syslog(LOG_ERR, "uart%i: set_flowcontrol: tcsetattr() failed: %s", dev->index, strerror(errno));
        return MRAA_ERROR_FEATURE_NOT_SUPPORTED;
    }

    return MRAA_SUCCESS;
}
nicola-lunghi commented 7 years ago

see also this question https://github.com/intel-iot-devkit/mraa/issues/588

alext-mkrs commented 7 years ago

@nicolalunghiemutex in view of your PR on the same matter, do you still need this one opened?

alext-mkrs commented 7 years ago

@nicolalunghiemutex, ping.

alext-mkrs commented 7 years ago

Looks like Nicola is not going to pursue this further, but I think this functionality could be useful enough, so let me keep this open and classify as an enhancement. If you are reading this and want this functionality - feel free to vote this up to show your interest.

nicola-lunghi commented 7 years ago

Hi Sorry for my disappearance! I've committed a pull request https://github.com/intel-iot-devkit/mraa/pull/685

I still not sure if its better to initialize the pin in the init flow controlfunction or to pass to the init uart a parameter to indicate the flow control status and initialize the pin on start.... In this manner the compatibility should be mantained

Also I cannot find where the uart pins are de-initialized if you close the uart. Any help on that?