Private
Public Access
2
0

uart: add a function to query current UART settings

This patch adds a function to query UART settings in an unintrusive way.
It can be used using a uart index or a devpath and it strives to just
read out the settings without affecting the state of the UART.

Signed-off-by: Tapani Utriainen <tapani@technexion.com>
Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
This commit is contained in:
Tapani Utriainen
2017-05-19 21:28:30 +08:00
committed by Brendan Le Foll
parent d6edf76680
commit a6f2464bb1
2 changed files with 126 additions and 0 deletions

View File

@@ -148,6 +148,41 @@ mraa_result_t mraa_uart_set_non_blocking(mraa_uart_context dev, mraa_boolean_t n
*/
const char* mraa_uart_get_dev_path(mraa_uart_context dev);
/**
* Get the current settings of an UART. This is an unintrusive function. Meaning
* it intends not to change anything, only read the values without disturbing.
*
* All but the first index parameter are "outparameters". That means they can
* contain values on return. If any parameter is not interesting, a null pointer
* can be sent instead as a placeholder.
* The devpath parameter can be either in or out parameter. In case of a negative
* index, the UART is identified using *devpath instead. This functionality is
* intended for and needed by for instance USB serial adapters.
*
* In case of a non-success return value, the outparameters are undefined.
*
* @param index uart index to look up, if negative, *devpath will be used instead
* @param devpath points to the device path of the UART, eg: /dev/ttyS0
* @param name outparameter that on return will point to the name of the UART
* @param baudrate pointer to an integer to contain the current baudrate (0--4M)
* @param databits pointer to an integer to contain the number databits (5--8)
* @param stopbits pointer to an integer to contain the number stopbits (1--2)
* @param parity will contain the current parity mode
* @param rtscts will point to non-zero if CTS/RTS flow control is enabled, zero otherwise
* @param xonxoff will point to a non-zero value if xon/xoff flow control is enabled
* @return result
*/
mraa_result_t
mraa_uart_settings(int index,
const char **devpath,
const char **name,
int* baudrate,
int* databits,
int* stopbits,
mraa_uart_parity_t* parity,
unsigned int* rtscts,
unsigned int* xonxoff);
/**
* Destroy a mraa_uart_context
*

View File

@@ -351,6 +351,97 @@ mraa_uart_stop(mraa_uart_context dev)
return MRAA_SUCCESS;
}
mraa_result_t
mraa_uart_settings(int index, const char **devpath, const char **name, int* baudrate, int* databits, int* stopbits, mraa_uart_parity_t* parity, unsigned int* ctsrts, unsigned int* xonxoff) {
struct termios term;
int fd;
if (plat == NULL) {
return MRAA_ERROR_PLATFORM_NOT_INITIALISED;
}
/* Access through UART index? */
if (index >= 0 && index < plat->uart_dev_count) {
if (devpath != NULL) {
*devpath = plat->uart_dev[index].device_path;
}
if (name != NULL) {
*name = plat->uart_dev[index].name;
}
}
/* is any information that requires opening the device requested? */
if (baudrate != NULL || stopbits != NULL || parity != NULL || databits != NULL || ctsrts != NULL || xonxoff != NULL) {
const char *dev;
/* Access UART by index or devpath? */
if (index >=0 && index < plat->uart_dev_count) {
dev = plat->uart_dev[index].device_path;
} else
if (devpath != NULL) {
dev = *devpath;
} else {
return MRAA_ERROR_INVALID_RESOURCE;
}
fd = open(dev, O_RDONLY | O_NOCTTY);
if (fd < 0) {
return MRAA_ERROR_INVALID_RESOURCE;
}
if (tcgetattr(fd, &term)) {
close(fd);
return MRAA_ERROR_INVALID_RESOURCE;
}
if (databits != NULL) {
switch (term.c_cflag & CSIZE) {
case CS8:
*databits = 8;
break;
case CS7:
*databits = 7;
break;
case CS6:
*databits = 6;
break;
case CS5:
*databits = 5;
default: /* Cannot happen? Linux kernel CSIZE mask is exactly two bits wide */
break;
}
}
if (stopbits != NULL) {
*stopbits = term.c_cflag & CSTOPB ? 2 : 1;
}
if (parity != NULL) {
if (term.c_cflag & PARODD) *parity = MRAA_UART_PARITY_ODD;
else
if (term.c_cflag & PARENB) *parity = MRAA_UART_PARITY_EVEN;
else
*parity = MRAA_UART_PARITY_NONE;
}
if (baudrate != NULL) {
*baudrate = speed_to_uint(cfgetospeed(&term));
}
if (ctsrts != NULL) {
*ctsrts = term.c_cflag & CRTSCTS;
}
if (xonxoff != NULL) {
*xonxoff = term.c_cflag & (IXON|IXOFF);
}
close(fd);
}
return MRAA_SUCCESS;
}
mraa_result_t
mraa_uart_flush(mraa_uart_context dev)
{