drivers: serial: native_tty: config_get support
This commit adds config_get support for native_tty. This is helpful as some driver code (e.g. u_blox m8) will error out if they can't read the current configuration. Signed-off-by: Vytautas Virvičius <vytautas@virvicius.dev>
This commit is contained in:
parent
4675f17fa2
commit
e1eaa0e39e
@ -18,6 +18,7 @@
|
||||
#include <zephyr/drivers/uart.h>
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#include <nsi_errno.h>
|
||||
#include <nsi_tracing.h>
|
||||
|
||||
#include "cmdline.h"
|
||||
@ -130,6 +131,73 @@ static int native_tty_conv_to_bottom_cfg(struct native_tty_bottom_cfg *bottom_cf
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert from native_tty_bottom_cfg to uart_config
|
||||
*
|
||||
* @param bottom_cfg
|
||||
* @param cfg
|
||||
*
|
||||
* @return 0 on success, negative errno otherwise.
|
||||
*/
|
||||
int native_tty_conv_from_bottom_cfg(int fd, struct uart_config *cfg)
|
||||
{
|
||||
struct native_tty_bottom_cfg bottom_cfg;
|
||||
int rc = 0;
|
||||
|
||||
rc = native_tty_read_bottom_cfg(fd, &bottom_cfg);
|
||||
if (rc != 0) {
|
||||
return nsi_errno_from_mid(rc);
|
||||
}
|
||||
|
||||
cfg->baudrate = bottom_cfg.baudrate;
|
||||
|
||||
switch (bottom_cfg.parity) {
|
||||
case NTB_PARITY_NONE:
|
||||
cfg->parity = UART_CFG_PARITY_NONE;
|
||||
break;
|
||||
case NTB_PARITY_ODD:
|
||||
cfg->parity = UART_CFG_PARITY_ODD;
|
||||
break;
|
||||
case NTB_PARITY_EVEN:
|
||||
cfg->parity = UART_CFG_PARITY_EVEN;
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
switch (bottom_cfg.stop_bits) {
|
||||
case NTB_STOP_BITS_1:
|
||||
cfg->stop_bits = UART_CFG_STOP_BITS_1;
|
||||
break;
|
||||
case NTB_STOP_BITS_2:
|
||||
cfg->stop_bits = UART_CFG_STOP_BITS_2;
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
switch (bottom_cfg.data_bits) {
|
||||
case NTB_DATA_BITS_5:
|
||||
cfg->data_bits = UART_CFG_DATA_BITS_5;
|
||||
break;
|
||||
case NTB_DATA_BITS_6:
|
||||
cfg->data_bits = UART_CFG_DATA_BITS_6;
|
||||
break;
|
||||
case NTB_DATA_BITS_7:
|
||||
cfg->data_bits = UART_CFG_DATA_BITS_7;
|
||||
break;
|
||||
case NTB_DATA_BITS_8:
|
||||
cfg->data_bits = UART_CFG_DATA_BITS_8;
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
cfg->flow_ctrl = UART_CFG_FLOW_CTRL_NONE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Output a character towards the serial port
|
||||
*
|
||||
@ -177,6 +245,20 @@ static int native_tty_configure(const struct device *dev, const struct uart_conf
|
||||
return native_tty_configure_bottom(fd, &bottom_cfg);
|
||||
}
|
||||
|
||||
static int native_tty_config_get(const struct device *dev, struct uart_config *cfg)
|
||||
{
|
||||
int fd = ((struct native_tty_data *)dev->data)->fd;
|
||||
int rc = 0;
|
||||
|
||||
rc = native_tty_conv_from_bottom_cfg(fd, cfg);
|
||||
if (rc) {
|
||||
WARN("Could not convert native tty bottom cfg to uart config\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
|
||||
static int native_tty_uart_fifo_fill(const struct device *dev,
|
||||
const uint8_t *tx_data,
|
||||
@ -375,6 +457,7 @@ static DEVICE_API(uart, native_tty_uart_driver_api) = {
|
||||
.poll_in = native_tty_uart_poll_in,
|
||||
#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
|
||||
.configure = native_tty_configure,
|
||||
.config_get = native_tty_config_get,
|
||||
#endif
|
||||
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
|
||||
.fifo_fill = native_tty_uart_fifo_fill,
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <nsi_errno.h>
|
||||
#include <nsi_tracing.h>
|
||||
|
||||
#define WARN(...) nsi_print_warning(__VA_ARGS__)
|
||||
@ -90,6 +91,31 @@ static inline void native_tty_baud_speed_set(struct termios *ter, int baudrate)
|
||||
ERROR("Could not set baudrate, as %d is not supported.\n", baudrate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the baud rate speed from the termios structure
|
||||
*
|
||||
* @param ter
|
||||
* @param baudrate
|
||||
*/
|
||||
static inline void native_tty_baud_speed_get(const struct termios *ter, uint32_t *baudrate)
|
||||
{
|
||||
speed_t ispeed = cfgetispeed(ter);
|
||||
speed_t ospeed = cfgetospeed(ter);
|
||||
|
||||
if (ispeed != ospeed) {
|
||||
ERROR("Input and output baud rates differ: %d vs %d\n", ispeed, ospeed);
|
||||
}
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(baudrate_lut); i++) {
|
||||
if (baudrate_lut[i].termios_baudrate == ispeed) {
|
||||
*baudrate = baudrate_lut[i].baudrate;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ERROR("Unsupported termios baudrate: %d\n", ispeed);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set parity setting in the termios structure
|
||||
*
|
||||
@ -117,6 +143,24 @@ static inline void native_tty_baud_parity_set(struct termios *ter,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the parity setting from the termios structure
|
||||
*
|
||||
* @param ter
|
||||
* @param parity
|
||||
*/
|
||||
static inline void native_tty_baud_parity_get(const struct termios *ter,
|
||||
enum native_tty_bottom_parity *parity)
|
||||
{
|
||||
if ((ter->c_cflag & PARENB) == 0) {
|
||||
*parity = NTB_PARITY_NONE;
|
||||
} else if (ter->c_cflag & PARODD) {
|
||||
*parity = NTB_PARITY_ODD;
|
||||
} else {
|
||||
*parity = NTB_PARITY_EVEN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the number of stop bits in the termios structure
|
||||
*
|
||||
@ -140,6 +184,18 @@ static inline void native_tty_stop_bits_set(struct termios *ter,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the number of stop bits from the termios structure
|
||||
*
|
||||
* @param ter
|
||||
* @param stop_bits
|
||||
*/
|
||||
static inline void native_tty_stop_bits_get(const struct termios *ter,
|
||||
enum native_tty_bottom_stop_bits *stop_bits)
|
||||
{
|
||||
*stop_bits = (ter->c_cflag & CSTOPB) ? NTB_STOP_BITS_2 : NTB_STOP_BITS_1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the number of data bits in the termios structure
|
||||
*
|
||||
@ -175,6 +231,33 @@ static inline void native_tty_data_bits_set(struct termios *ter,
|
||||
ter->c_cflag |= data_bits_to_set;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the number of data bits from the termios structure
|
||||
*
|
||||
* @param ter
|
||||
* @param data_bits
|
||||
*/
|
||||
static inline void native_tty_data_bits_get(const struct termios *ter,
|
||||
enum native_tty_bottom_data_bits *data_bits)
|
||||
{
|
||||
switch (ter->c_cflag & CSIZE) {
|
||||
case CS5:
|
||||
*data_bits = NTB_DATA_BITS_5;
|
||||
break;
|
||||
case CS6:
|
||||
*data_bits = NTB_DATA_BITS_6;
|
||||
break;
|
||||
case CS7:
|
||||
*data_bits = NTB_DATA_BITS_7;
|
||||
break;
|
||||
case CS8:
|
||||
*data_bits = NTB_DATA_BITS_8;
|
||||
break;
|
||||
default:
|
||||
ERROR("Unsupported data bits setting in termios.\n");
|
||||
}
|
||||
}
|
||||
|
||||
int native_tty_poll_bottom(int fd)
|
||||
{
|
||||
struct pollfd pfd = { .fd = fd, .events = POLLIN };
|
||||
@ -252,3 +335,26 @@ int native_tty_configure_bottom(int fd, struct native_tty_bottom_cfg *cfg)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int native_tty_read_bottom_cfg(int fd, struct native_tty_bottom_cfg *cfg)
|
||||
{
|
||||
struct termios ter;
|
||||
int rc = 0;
|
||||
|
||||
rc = tcgetattr(fd, &ter);
|
||||
if (rc != 0) {
|
||||
int err = 0;
|
||||
|
||||
err = errno;
|
||||
WARN("Could not read terminal driver settings: %s\n", strerror(err));
|
||||
return -nsi_errno_to_mid(err);
|
||||
}
|
||||
|
||||
native_tty_baud_speed_get(&ter, &cfg->baudrate);
|
||||
native_tty_baud_parity_get(&ter, &cfg->parity);
|
||||
native_tty_data_bits_get(&ter, &cfg->data_bits);
|
||||
native_tty_stop_bits_get(&ter, &cfg->stop_bits);
|
||||
cfg->flow_ctrl = NTB_FLOW_CTRL_NONE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -86,6 +86,16 @@ int native_tty_open_tty_bottom(const char *pathname);
|
||||
*/
|
||||
int native_tty_configure_bottom(int fd, struct native_tty_bottom_cfg *cfg);
|
||||
|
||||
/**
|
||||
* @brief Read bottom tty configuration
|
||||
*
|
||||
* @param fd
|
||||
* @param cfg
|
||||
*
|
||||
* @return 0 on success, negative value on error
|
||||
*/
|
||||
int native_tty_read_bottom_cfg(int fd, struct native_tty_bottom_cfg *cfg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue
Block a user