Skip to content

Commit 7af5b29

Browse files
committed
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 7af5b29

File tree

1 file changed

+119
-30
lines changed

1 file changed

+119
-30
lines changed

drivers/serial/uart_mcux_lpuart.c

+119-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,47 @@ 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+
uart_config->enableTxCTS = false;
983+
uart_config->enableRxRTS = false;
984+
break;
985+
986+
case UART_CFG_FLOW_CTRL_RS485:
987+
uart_config->enableTxCTS = false;
988+
uart_config->enableRxRTS = false;
989+
break;
990+
991+
case UART_CFG_FLOW_CTRL_RTS_CTS:
992+
uart_config->enableTxCTS = true;
993+
uart_config->enableRxRTS = true;
994+
break;
995+
996+
default:
997+
return -ENOTSUP;
998+
}
999+
1000+
return 0;
1001+
}
1002+
#else
1003+
static int mcux_lpuart_config_flowctrl(uint8_t flow_ctrl, lpuart_config_t *uart_config)
1004+
{
1005+
if (flow_ctrl == UART_CFG_FLOW_CTRL_NONE) {
1006+
return 0;
1007+
}
1008+
1009+
return -ENOTSUP;
1010+
}
1011+
#endif /* LPUART_HAS_MODEM */
1012+
9731013
static int mcux_lpuart_configure_basic(const struct device *dev, const struct uart_config *cfg,
9741014
lpuart_config_t *uart_config)
9751015
{
1016+
int ret;
1017+
9761018
/* Translate UART API enum to LPUART enum from HAL */
9771019
switch (cfg->parity) {
9781020
case UART_CFG_PARITY_NONE:
@@ -1016,22 +1058,15 @@ static int mcux_lpuart_configure_basic(const struct device *dev, const struct ua
10161058
}
10171059
#endif
10181060

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:
1061+
/* Configure for Flow Control option */
1062+
if (!IS_ENABLED(LPUART_HAS_MCR) && cfg->flow_ctrl == UART_CFG_FLOW_CTRL_DTR_DSR) {
10321063
return -ENOTSUP;
10331064
}
1034-
#endif
1065+
1066+
ret = mcux_lpuart_config_flowctrl(cfg->flow_ctrl, uart_config);
1067+
if (ret) {
1068+
return ret;
1069+
}
10351070

10361071
uart_config->baudRate_Bps = cfg->baudrate;
10371072
uart_config->enableRx = true;
@@ -1105,8 +1140,7 @@ static int mcux_lpuart_configure_init(const struct device *dev, const struct uar
11051140

11061141
LPUART_Init(config->base, &uart_config, clock_freq);
11071142

1108-
#if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && \
1109-
FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT
1143+
#ifdef LPUART_HAS_MODEM
11101144
if (cfg->flow_ctrl == UART_CFG_FLOW_CTRL_RS485) {
11111145
/* Set the LPUART into RS485 mode (tx driver enable using RTS) */
11121146
config->base->MODIR |= LPUART_MODIR_TXRTSE(true);
@@ -1185,10 +1219,15 @@ static int mcux_lpuart_configure(const struct device *dev,
11851219
}
11861220
#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
11871221

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)
1222+
#ifdef CONFIG_UART_LINE_CTRL
1223+
#if LPUART_HAS_MODEM
1224+
static void mcux_lpuart_line_ctrl_set_rts(const struct device *dev, uint32_t val)
11911225
{
1226+
const struct mcux_lpuart_config *config = dev->config;
1227+
1228+
/* Disable Transmitter and Receiver */
1229+
config->base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK);
1230+
11921231
if (val >= 1U) {
11931232
/* Reset TXRTS to set RXRTSE bit, this provides high-level on RTS line */
11941233
config->base->MODIR &= ~(LPUART_MODIR_TXRTSPOL_MASK | LPUART_MODIR_TXRTSE_MASK);
@@ -1199,20 +1238,62 @@ static void mcux_lpuart_line_ctrl_set_rts(const struct mcux_lpuart_config *confi
11991238
config->base->MODIR |= (LPUART_MODIR_TXRTSPOL_MASK | LPUART_MODIR_TXRTSE_MASK);
12001239
}
12011240
}
1241+
#else
1242+
#define mcux_lpuart_line_ctrl_set_rts(dev, val) ret = -ENOTSUP
1243+
#endif /* LPUART_HAS_MODEM */
1244+
1245+
#if LPUART_HAS_MCR
1246+
static void mcux_lpuart_set_dtr(const struct device *dev, uint32_t val)
1247+
{
1248+
const struct mcux_lpuart_config *config = dev->config;
1249+
1250+
if (val >= 1U) {
1251+
/* assert DTR_b */
1252+
config->base->MCR &= ~LPUART_MCR_DTR_MASK;
1253+
} else {
1254+
/* deassert DTR_b */
1255+
config->base->MCR |= LPUART_MCR_DTR_MASK;
1256+
}
1257+
}
1258+
#else
1259+
#define mcux_lpuart_set_dtr(dev, val) ret = -ENOTSUP
1260+
#endif /* LPUART_HAS_MCR */
12021261

12031262
static int mcux_lpuart_line_ctrl_set(const struct device *dev,
12041263
uint32_t ctrl, uint32_t val)
12051264
{
1206-
const struct mcux_lpuart_config *config = dev->config;
12071265
int ret = 0;
12081266

12091267
switch (ctrl) {
12101268
case UART_LINE_CTRL_RTS:
1211-
/* Disable Transmitter and Receiver */
1212-
config->base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK);
1269+
mcux_lpuart_line_ctrl_set_rts(dev, val);
1270+
break;
12131271

1214-
mcux_lpuart_line_ctrl_set_rts(config, val);
1272+
case UART_LINE_CTRL_DTR:
1273+
mcux_lpuart_set_dtr(dev, val);
1274+
break;
1275+
1276+
default:
1277+
ret = -ENOTSUP;
1278+
}
1279+
1280+
return ret;
1281+
}
12151282

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

12181299
default:
@@ -1221,7 +1302,14 @@ static int mcux_lpuart_line_ctrl_set(const struct device *dev,
12211302

12221303
return ret;
12231304
}
1224-
#endif /* UART_LINE_CTRL_ENABLE */
1305+
#else
1306+
static int mcux_lpuart_line_ctrl_get(const struct device *dev,
1307+
uint32_t ctrl, uint32_t *val)
1308+
{
1309+
return -ENOTSUP;
1310+
}
1311+
#endif /* LPUART_HAS_MCR */
1312+
#endif /* CONFIG_UART_LINE_CTRL */
12251313

12261314
static int mcux_lpuart_init(const struct device *dev)
12271315
{
@@ -1301,9 +1389,10 @@ static DEVICE_API(uart, mcux_lpuart_driver_api) = {
13011389
.rx_buf_rsp = mcux_lpuart_rx_buf_rsp,
13021390
.rx_disable = mcux_lpuart_rx_disable,
13031391
#endif /* CONFIG_UART_ASYNC_API */
1304-
#ifdef UART_LINE_CTRL_ENABLE
1392+
#ifdef CONFIG_UART_LINE_CTRL
13051393
.line_ctrl_set = mcux_lpuart_line_ctrl_set,
1306-
#endif /* UART_LINE_CTRL_ENABLE */
1394+
.line_ctrl_get = mcux_lpuart_line_ctrl_get,
1395+
#endif /* CONFIG_UART_LINE_CTRL */
13071396
};
13081397

13091398

0 commit comments

Comments
 (0)