drivers: serial: stm32 uart implements driver enable

Enables the use of the hardware DE pin provided by an stm32 UART using
device tree flags.

Signed-off-by: Abram Early <abram.early@gmail.com>
diff --git a/drivers/serial/uart_stm32.c b/drivers/serial/uart_stm32.c
index 55d6b22..653e520 100644
--- a/drivers/serial/uart_stm32.c
+++ b/drivers/serial/uart_stm32.c
@@ -1705,6 +1705,23 @@
 	}
 #endif
 
+#ifdef USART_CR3_DEM
+	if (config->de_enable) {
+		if (!IS_UART_DRIVER_ENABLE_INSTANCE(config->usart)) {
+			LOG_ERR("%s does not support driver enable", dev->name);
+			return -EINVAL;
+		}
+
+		LL_USART_EnableDEMode(config->usart);
+		LL_USART_SetDEAssertionTime(config->usart, config->de_assert_time);
+		LL_USART_SetDEDeassertionTime(config->usart, config->de_deassert_time);
+
+		if (config->de_invert) {
+			LL_USART_SetDESignalPolarity(config->usart, LL_USART_DE_POLARITY_LOW);
+		}
+	}
+#endif
+
 	LL_USART_Enable(config->usart);
 
 #ifdef USART_ISR_TEACK
@@ -1918,6 +1935,10 @@
 	.tx_rx_swap = DT_INST_PROP_OR(index, tx_rx_swap, false),	\
 	.rx_invert = DT_INST_PROP(index, rx_invert),			\
 	.tx_invert = DT_INST_PROP(index, tx_invert),			\
+	.de_enable = DT_INST_PROP(index, de_enable),			\
+	.de_assert_time = DT_INST_PROP(index, de_assert_time),		\
+	.de_deassert_time = DT_INST_PROP(index, de_deassert_time),	\
+	.de_invert = DT_INST_PROP(index, de_invert),			\
 	STM32_UART_IRQ_HANDLER_FUNC(index)				\
 	STM32_UART_PM_WAKEUP(index)					\
 };									\
diff --git a/drivers/serial/uart_stm32.h b/drivers/serial/uart_stm32.h
index 9a4a4e7..15cf0a5 100644
--- a/drivers/serial/uart_stm32.h
+++ b/drivers/serial/uart_stm32.h
@@ -36,6 +36,14 @@
 	bool rx_invert;
 	/* enable tx pin inversion */
 	bool tx_invert;
+	/* enable de signal */
+	bool de_enable;
+	/* de signal assertion time in 1/16 of a bit */
+	uint8_t de_assert_time;
+	/* de signal deassertion time in 1/16 of a bit */
+	uint8_t de_deassert_time;
+	/* enable de pin inversion */
+	bool de_invert;
 	const struct pinctrl_dev_config *pcfg;
 #if defined(CONFIG_UART_INTERRUPT_DRIVEN) || defined(CONFIG_UART_ASYNC_API) || \
 	defined(CONFIG_PM)
diff --git a/dts/bindings/serial/st,stm32-uart-base.yaml b/dts/bindings/serial/st,stm32-uart-base.yaml
index fbe5973..ed8a6e1 100644
--- a/dts/bindings/serial/st,stm32-uart-base.yaml
+++ b/dts/bindings/serial/st,stm32-uart-base.yaml
@@ -58,3 +58,31 @@
       configured masked at boot (sm32wl55 for instance), preventing the device to wakeup
       the core from stop mode(s).
       Valid range: 0 - 31
+
+  de-enable:
+    type: boolean
+    description: |
+      Enable activating an external transeiver through the DE pin which must also be configured
+      using pinctrl.
+
+  de-assert-time:
+    type: int
+    default: 0
+    description: |
+      Defines the time between the activation of the DE signal and the beginning of the start bit.
+      It is expressed in 16th of a bit time.
+      Valid range: 0 - 31
+
+  de-deassert-time:
+    type: int
+    default: 0
+    description: |
+      Defines the time between the activation of the DE signal and the beginning of the start bit.
+      It is expressed in 16th of a bit time.
+      Valid range: 0 - 31
+
+  de-invert:
+    type: boolean
+    description: |
+      Invert the binary logic of the de pin. When enabled, physical logic levels are inverted and
+      we use 1=Low, 0=High instead of 1=High, 0=Low.