Skip to content

Commit 7adc4b6

Browse files
PetervdPerk-NXPnashif
authored andcommitted
drivers: serial: mcux lpuart add (tx/rx)invert and single wire
Adds device tree definitions to enable tx/rx invert and singlewire modes Signed-off-by: Peter van der Perk <[email protected]>
1 parent 73da457 commit 7adc4b6

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

drivers/serial/uart_mcux_lpuart.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ struct mcux_lpuart_config {
5858
uint8_t parity;
5959
bool rs485_de_active_low;
6060
bool loopback_en;
61+
bool single_wire;
62+
bool tx_invert;
63+
bool rx_invert;
6164
#ifdef CONFIG_UART_MCUX_LPUART_ISR_SUPPORT
6265
void (*irq_config_func)(const struct device *dev);
6366
#endif
@@ -1105,8 +1108,30 @@ static int mcux_lpuart_configure_init(const struct device *dev, const struct uar
11051108
/* Set the LPUART into loopback mode */
11061109
config->base->CTRL |= LPUART_CTRL_LOOPS_MASK;
11071110
config->base->CTRL &= ~LPUART_CTRL_RSRC_MASK;
1111+
} else if (config->single_wire) {
1112+
/* Enable the single wire / half-duplex mode, only possible when
1113+
* loopback is disabled. We need a critical section to prevent
1114+
* the UART firing an interrupt during mode switch
1115+
*/
1116+
unsigned int key = irq_lock();
1117+
1118+
config->base->CTRL |= (LPUART_CTRL_LOOPS_MASK | LPUART_CTRL_RSRC_MASK);
1119+
irq_unlock(key);
1120+
} else {
1121+
#ifdef LPUART_CTRL_TXINV
1122+
/* Only invert TX in full-duplex mode */
1123+
if (config->tx_invert) {
1124+
config->base->CTRL |= LPUART_CTRL_TXINV(1);
1125+
}
1126+
#endif
11081127
}
11091128

1129+
#ifdef LPUART_STAT_RXINV
1130+
if (config->rx_invert) {
1131+
config->base->STAT |= LPUART_STAT_RXINV(1);
1132+
}
1133+
#endif
1134+
11101135
/* update internal uart_config */
11111136
data->uart_config = *cfg;
11121137

@@ -1126,6 +1151,9 @@ static int mcux_lpuart_configure(const struct device *dev,
11261151
{
11271152
const struct mcux_lpuart_config *config = dev->config;
11281153

1154+
/* Make sure that RSRC is de-asserted otherwise deinit will hang. */
1155+
config->base->CTRL &= ~LPUART_CTRL_RSRC_MASK;
1156+
11291157
/* disable LPUART */
11301158
LPUART_Deinit(config->base);
11311159

@@ -1330,6 +1358,9 @@ static const struct mcux_lpuart_config mcux_lpuart_##n##_config = { \
13301358
.parity = DT_INST_ENUM_IDX_OR(n, parity, UART_CFG_PARITY_NONE), \
13311359
.rs485_de_active_low = DT_INST_PROP(n, nxp_rs485_de_active_low), \
13321360
.loopback_en = DT_INST_PROP(n, nxp_loopback), \
1361+
.single_wire = DT_INST_PROP(n, single_wire), \
1362+
.rx_invert = DT_INST_PROP(n, rx_invert), \
1363+
.tx_invert = DT_INST_PROP(n, tx_invert), \
13331364
.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
13341365
MCUX_LPUART_IRQ_INIT(n) \
13351366
RX_DMA_CONFIG(n) \

dts/bindings/serial/nxp,kinetis-lpuart.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,26 @@ properties:
1515
disconnected, and transmitter output is internally connected to
1616
the receiver input.
1717
18+
single-wire:
19+
type: boolean
20+
description: |
21+
Enable the single wire half-duplex communication.
22+
Using this mode, TX and RX lines are internally connected and
23+
only TX pin is used afterwards and should be configured.
24+
RX/TX conflicts must be handled on user side.
25+
26+
tx-invert:
27+
type: boolean
28+
description: |
29+
Invert the binary logic of tx pin. When enabled, physical logic levels are inverted and
30+
we use 1=Low, 0=High instead of 1=High, 0=Low.
31+
32+
rx-invert:
33+
type: boolean
34+
description: |
35+
Invert the binary logic of rx pin. When enabled, physical logic levels are inverted and
36+
we use 1=Low, 0=High instead of 1=High, 0=Low.
37+
1838
nxp,rs485-mode:
1939
type: boolean
2040
description: |

0 commit comments

Comments
 (0)