Skip to content

Commit 7916b21

Browse files
committedMar 21, 2025·
drivers: serial: uart_mcux_lpuart: add DTR, DSR, and DCD signals
Add support for additional line control signals. Improved configuring uart_config_flow_control options. Signed-off-by: Derek Snell <derek.snell@nxp.com>
1 parent d19abff commit 7916b21

File tree

1 file changed

+115
-30
lines changed

1 file changed

+115
-30
lines changed
 

‎drivers/serial/uart_mcux_lpuart.c

+115-30
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,14 @@ LOG_MODULE_REGISTER(uart_mcux_lpuart, LOG_LEVEL_ERR);
3030

3131
#define PINCTRL_STATE_FLOWCONTROL PINCTRL_STATE_PRIV_START
3232

33-
#if defined(CONFIG_UART_LINE_CTRL) && \
34-
defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && \
35-
(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT)
36-
#define UART_LINE_CTRL_ENABLE
33+
/* Helper macros */
34+
#if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && \
35+
FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT
36+
#define LPUART_HAS_MODEM 1
37+
#endif
38+
39+
#if defined(FSL_FEATURE_LPUART_HAS_MCR) && FSL_FEATURE_LPUART_HAS_MCR
40+
#define LPUART_HAS_MCR 1
3741
#endif
3842

3943
#if defined(CONFIG_UART_ASYNC_API) && defined(CONFIG_UART_INTERRUPT_DRIVEN)
@@ -970,9 +974,43 @@ static void mcux_lpuart_isr(const struct device *dev)
970974
}
971975
#endif /* CONFIG_UART_MCUX_LPUART_ISR_SUPPORT */
972976

977+
#if LPUART_HAS_MODEM
978+
static int mcux_lpuart_config_flowctrl(uint8_t flow_ctrl, lpuart_config_t *uart_config)
979+
{
980+
switch (flow_ctrl) {
981+
case UART_CFG_FLOW_CTRL_NONE:
982+
case UART_CFG_FLOW_CTRL_RS485:
983+
uart_config->enableTxCTS = false;
984+
uart_config->enableRxRTS = false;
985+
break;
986+
987+
case UART_CFG_FLOW_CTRL_RTS_CTS:
988+
uart_config->enableTxCTS = true;
989+
uart_config->enableRxRTS = true;
990+
break;
991+
992+
default:
993+
return -ENOTSUP;
994+
}
995+
996+
return 0;
997+
}
998+
#else
999+
static int mcux_lpuart_config_flowctrl(uint8_t flow_ctrl, lpuart_config_t *uart_config)
1000+
{
1001+
if (flow_ctrl != UART_CFG_FLOW_CTRL_NONE) {
1002+
return -ENOTSUP;
1003+
}
1004+
1005+
return 0;
1006+
}
1007+
#endif /* LPUART_HAS_MODEM */
1008+
9731009
static int mcux_lpuart_configure_basic(const struct device *dev, const struct uart_config *cfg,
9741010
lpuart_config_t *uart_config)
9751011
{
1012+
int ret;
1013+
9761014
/* Translate UART API enum to LPUART enum from HAL */
9771015
switch (cfg->parity) {
9781016
case UART_CFG_PARITY_NONE:
@@ -1016,22 +1054,15 @@ static int mcux_lpuart_configure_basic(const struct device *dev, const struct ua
10161054
}
10171055
#endif
10181056

1019-
#if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && \
1020-
FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT
1021-
switch (cfg->flow_ctrl) {
1022-
case UART_CFG_FLOW_CTRL_NONE:
1023-
case UART_CFG_FLOW_CTRL_RS485:
1024-
uart_config->enableTxCTS = false;
1025-
uart_config->enableRxRTS = false;
1026-
break;
1027-
case UART_CFG_FLOW_CTRL_RTS_CTS:
1028-
uart_config->enableTxCTS = true;
1029-
uart_config->enableRxRTS = true;
1030-
break;
1031-
default:
1057+
/* Configure for Flow Control option */
1058+
if (!IS_ENABLED(LPUART_HAS_MCR) && cfg->flow_ctrl == UART_CFG_FLOW_CTRL_DTR_DSR) {
10321059
return -ENOTSUP;
10331060
}
1034-
#endif
1061+
1062+
ret = mcux_lpuart_config_flowctrl(cfg->flow_ctrl, uart_config);
1063+
if (ret) {
1064+
return ret;
1065+
}
10351066

10361067
uart_config->baudRate_Bps = cfg->baudrate;
10371068
uart_config->enableRx = true;
@@ -1105,8 +1136,7 @@ static int mcux_lpuart_configure_init(const struct device *dev, const struct uar
11051136

11061137
LPUART_Init(config->base, &uart_config, clock_freq);
11071138

1108-
#if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && \
1109-
FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT
1139+
#ifdef LPUART_HAS_MODEM
11101140
if (cfg->flow_ctrl == UART_CFG_FLOW_CTRL_RS485) {
11111141
/* Set the LPUART into RS485 mode (tx driver enable using RTS) */
11121142
config->base->MODIR |= LPUART_MODIR_TXRTSE(true);
@@ -1185,10 +1215,15 @@ static int mcux_lpuart_configure(const struct device *dev,
11851215
}
11861216
#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
11871217

1188-
#ifdef UART_LINE_CTRL_ENABLE
1189-
static void mcux_lpuart_line_ctrl_set_rts(const struct mcux_lpuart_config *config,
1190-
uint32_t val)
1218+
#ifdef CONFIG_UART_LINE_CTRL
1219+
#if LPUART_HAS_MODEM
1220+
static void mcux_lpuart_line_ctrl_set_rts(const struct device *dev, uint32_t val)
11911221
{
1222+
const struct mcux_lpuart_config *config = dev->config;
1223+
1224+
/* Disable Transmitter and Receiver */
1225+
config->base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK);
1226+
11921227
if (val >= 1U) {
11931228
/* Reset TXRTS to set RXRTSE bit, this provides high-level on RTS line */
11941229
config->base->MODIR &= ~(LPUART_MODIR_TXRTSPOL_MASK | LPUART_MODIR_TXRTSE_MASK);
@@ -1199,20 +1234,62 @@ static void mcux_lpuart_line_ctrl_set_rts(const struct mcux_lpuart_config *confi
11991234
config->base->MODIR |= (LPUART_MODIR_TXRTSPOL_MASK | LPUART_MODIR_TXRTSE_MASK);
12001235
}
12011236
}
1237+
#else
1238+
#define mcux_lpuart_line_ctrl_set_rts(dev, val) ret = -ENOTSUP
1239+
#endif /* LPUART_HAS_MODEM */
1240+
1241+
#if LPUART_HAS_MCR
1242+
static void mcux_lpuart_set_dtr(const struct device *dev, uint32_t val)
1243+
{
1244+
const struct mcux_lpuart_config *config = dev->config;
1245+
1246+
if (val >= 1U) {
1247+
/* assert DTR_b */
1248+
config->base->MCR &= ~LPUART_MCR_DTR_MASK;
1249+
} else {
1250+
/* deassert DTR_b */
1251+
config->base->MCR |= LPUART_MCR_DTR_MASK;
1252+
}
1253+
}
1254+
#else
1255+
#define mcux_lpuart_set_dtr(dev, val) ret = -ENOTSUP
1256+
#endif /* LPUART_HAS_MCR */
12021257

12031258
static int mcux_lpuart_line_ctrl_set(const struct device *dev,
12041259
uint32_t ctrl, uint32_t val)
12051260
{
1206-
const struct mcux_lpuart_config *config = dev->config;
12071261
int ret = 0;
12081262

12091263
switch (ctrl) {
12101264
case UART_LINE_CTRL_RTS:
1211-
/* Disable Transmitter and Receiver */
1212-
config->base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK);
1265+
mcux_lpuart_line_ctrl_set_rts(dev, val);
1266+
break;
12131267

1214-
mcux_lpuart_line_ctrl_set_rts(config, val);
1268+
case UART_LINE_CTRL_DTR:
1269+
mcux_lpuart_set_dtr(dev, val);
1270+
break;
1271+
1272+
default:
1273+
ret = -ENOTSUP;
1274+
}
1275+
1276+
return ret;
1277+
}
12151278

1279+
#if LPUART_HAS_MCR
1280+
static int mcux_lpuart_line_ctrl_get(const struct device *dev,
1281+
uint32_t ctrl, uint32_t *val)
1282+
{
1283+
const struct mcux_lpuart_config *config = dev->config;
1284+
int ret = 0;
1285+
1286+
switch (ctrl) {
1287+
case UART_LINE_CTRL_DSR:
1288+
*val = (config->base->MSR & LPUART_MSR_DSR_MASK) >> LPUART_MSR_DSR_SHIFT;
1289+
break;
1290+
1291+
case UART_LINE_CTRL_DCD:
1292+
*val = (config->base->MSR & LPUART_MSR_DCD_MASK) >> LPUART_MSR_DCD_SHIFT;
12161293
break;
12171294

12181295
default:
@@ -1221,7 +1298,14 @@ static int mcux_lpuart_line_ctrl_set(const struct device *dev,
12211298

12221299
return ret;
12231300
}
1224-
#endif /* UART_LINE_CTRL_ENABLE */
1301+
#else
1302+
static int mcux_lpuart_line_ctrl_get(const struct device *dev,
1303+
uint32_t ctrl, uint32_t *val)
1304+
{
1305+
return -ENOTSUP;
1306+
}
1307+
#endif /* LPUART_HAS_MCR */
1308+
#endif /* CONFIG_UART_LINE_CTRL */
12251309

12261310
static int mcux_lpuart_init(const struct device *dev)
12271311
{
@@ -1301,9 +1385,10 @@ static DEVICE_API(uart, mcux_lpuart_driver_api) = {
13011385
.rx_buf_rsp = mcux_lpuart_rx_buf_rsp,
13021386
.rx_disable = mcux_lpuart_rx_disable,
13031387
#endif /* CONFIG_UART_ASYNC_API */
1304-
#ifdef UART_LINE_CTRL_ENABLE
1388+
#ifdef CONFIG_UART_LINE_CTRL
13051389
.line_ctrl_set = mcux_lpuart_line_ctrl_set,
1306-
#endif /* UART_LINE_CTRL_ENABLE */
1390+
.line_ctrl_get = mcux_lpuart_line_ctrl_get,
1391+
#endif /* CONFIG_UART_LINE_CTRL */
13071392
};
13081393

13091394

0 commit comments

Comments
 (0)
Please sign in to comment.