Skip to content

Commit ae486de

Browse files
JvanDoorenheinwessels
authored andcommitted
drivers: serial: stm32: add wide data support
Add wide data support to STM32. Validated interrupt driven code on an STM32H743. Signed-off-by: Jeroen van Dooren <[email protected]>
1 parent 6913dcd commit ae486de

File tree

1 file changed

+105
-6
lines changed

1 file changed

+105
-6
lines changed

drivers/serial/uart_stm32.c

Lines changed: 105 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -645,26 +645,50 @@ static void uart_stm32_poll_out_visitor(const struct device *dev, void *out, pol
645645
irq_unlock(key);
646646
}
647647

648-
static void uart_stm32_poll_in_u8(const struct uart_stm32_config *config, void *in)
648+
static void poll_in_u8(const struct uart_stm32_config *config, void *in)
649649
{
650650
*((unsigned char *)in) = (unsigned char)LL_USART_ReceiveData8(config->usart);
651651
}
652652

653-
static void uart_stm32_poll_out_u8(const struct uart_stm32_config *config, void *out)
653+
static void poll_out_u8(const struct uart_stm32_config *config, void *out)
654654
{
655655
LL_USART_TransmitData8(config->usart, *((uint8_t *)out));
656656
}
657657

658658
static int uart_stm32_poll_in(const struct device *dev, unsigned char *c)
659659
{
660-
return uart_stm32_poll_in_visitor(dev, (void *)c, uart_stm32_poll_in_u8);
660+
return uart_stm32_poll_in_visitor(dev, (void *)c, poll_in_u8);
661661
}
662662

663663
static void uart_stm32_poll_out(const struct device *dev, unsigned char c)
664664
{
665-
uart_stm32_poll_out_visitor(dev, (void *)&c, uart_stm32_poll_out_u8);
665+
uart_stm32_poll_out_visitor(dev, (void *)&c, poll_out_u8);
666666
}
667667

668+
#ifdef CONFIG_UART_WIDE_DATA
669+
670+
static void poll_out_u9(const struct uart_stm32_config *config, void *out)
671+
{
672+
LL_USART_TransmitData9(config->usart, *((uint16_t *)out));
673+
}
674+
675+
static void poll_in_u9(const struct uart_stm32_config *config, void *in)
676+
{
677+
*((uint16_t *)in) = LL_USART_ReceiveData9(config->usart);
678+
}
679+
680+
static int uart_stm32_poll_in_u16(const struct device *dev, uint16_t *in_u16)
681+
{
682+
return uart_stm32_poll_in_visitor(dev, (void *)in_u16, poll_in_u9);
683+
}
684+
685+
static void uart_stm32_poll_out_u16(const struct device *dev, uint16_t out_u16)
686+
{
687+
uart_stm32_poll_out_visitor(dev, (void *)&out_u16, poll_out_u9);
688+
}
689+
690+
#endif
691+
668692
static int uart_stm32_err_check(const struct device *dev)
669693
{
670694
const struct uart_stm32_config *config = dev->config;
@@ -828,6 +852,47 @@ static int uart_stm32_fifo_read(const struct device *dev, uint8_t *rx_data, cons
828852
fifo_read_with_u8);
829853
}
830854

855+
#ifdef CONFIG_UART_WIDE_DATA
856+
857+
static void fifo_fill_with_u16(const struct uart_stm32_config *config,
858+
const void *tx_data, const uint8_t offset)
859+
{
860+
const uint16_t *data = (const uint16_t *)tx_data;
861+
862+
/* Send a character (9bit) */
863+
LL_USART_TransmitData9(config->usart, data[offset]);
864+
}
865+
866+
static int uart_stm32_fifo_fill_u16(const struct device *dev, const uint16_t *tx_data, int size)
867+
{
868+
if (uart_stm32_ll2cfg_databits(uart_stm32_get_databits(dev), uart_stm32_get_parity(dev)) !=
869+
UART_CFG_DATA_BITS_9) {
870+
return -ENOTSUP;
871+
}
872+
return uart_stm32_fifo_fill_visitor(dev, (const void *)tx_data, size,
873+
fifo_fill_with_u16);
874+
}
875+
876+
static void fifo_read_with_u16(const struct uart_stm32_config *config, void *rx_data,
877+
const uint8_t offset)
878+
{
879+
uint16_t *data = (uint16_t *)rx_data;
880+
881+
data[offset] = LL_USART_ReceiveData9(config->usart);
882+
}
883+
884+
static int uart_stm32_fifo_read_u16(const struct device *dev, uint16_t *rx_data, const int size)
885+
{
886+
if (uart_stm32_ll2cfg_databits(uart_stm32_get_databits(dev), uart_stm32_get_parity(dev)) !=
887+
UART_CFG_DATA_BITS_9) {
888+
return -ENOTSUP;
889+
}
890+
return uart_stm32_fifo_read_visitor(dev, (void *)rx_data, size,
891+
fifo_read_with_u16);
892+
}
893+
894+
#endif
895+
831896
static void uart_stm32_irq_tx_enable(const struct device *dev)
832897
{
833898
const struct uart_stm32_config *config = dev->config;
@@ -1670,11 +1735,36 @@ static int uart_stm32_async_init(const struct device *dev)
16701735
return 0;
16711736
}
16721737

1738+
#ifdef CONFIG_UART_WIDE_DATA
1739+
1740+
static int uart_stm32_async_tx_u16(const struct device *dev, const uint16_t *tx_data,
1741+
size_t buf_size, int32_t timeout)
1742+
{
1743+
return uart_stm32_async_tx(dev, (const uint8_t *)tx_data, buf_size * 2, timeout);
1744+
}
1745+
1746+
static int uart_stm32_async_rx_enable_u16(const struct device *dev, uint16_t *buf, size_t len,
1747+
int32_t timeout)
1748+
{
1749+
return uart_stm32_async_rx_enable(dev, (uint8_t *)buf, len * 2, timeout);
1750+
}
1751+
1752+
static int uart_stm32_async_rx_buf_rsp_u16(const struct device *dev, uint16_t *buf, size_t len)
1753+
{
1754+
return uart_stm32_async_rx_buf_rsp(dev, (uint8_t *)buf, len * 2);
1755+
}
1756+
1757+
#endif
1758+
16731759
#endif /* CONFIG_UART_ASYNC_API */
16741760

16751761
static const struct uart_driver_api uart_stm32_driver_api = {
16761762
.poll_in = uart_stm32_poll_in,
16771763
.poll_out = uart_stm32_poll_out,
1764+
#ifdef CONFIG_UART_WIDE_DATA
1765+
.poll_in_u16 = uart_stm32_poll_in_u16,
1766+
.poll_out_u16 = uart_stm32_poll_out_u16,
1767+
#endif
16781768
.err_check = uart_stm32_err_check,
16791769
#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
16801770
.configure = uart_stm32_configure,
@@ -1683,6 +1773,10 @@ static const struct uart_driver_api uart_stm32_driver_api = {
16831773
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
16841774
.fifo_fill = uart_stm32_fifo_fill,
16851775
.fifo_read = uart_stm32_fifo_read,
1776+
#ifdef CONFIG_UART_WIDE_DATA
1777+
.fifo_fill_u16 = uart_stm32_fifo_fill_u16,
1778+
.fifo_read_u16 = uart_stm32_fifo_read_u16,
1779+
#endif
16861780
.irq_tx_enable = uart_stm32_irq_tx_enable,
16871781
.irq_tx_disable = uart_stm32_irq_tx_disable,
16881782
.irq_tx_ready = uart_stm32_irq_tx_ready,
@@ -1695,15 +1789,20 @@ static const struct uart_driver_api uart_stm32_driver_api = {
16951789
.irq_is_pending = uart_stm32_irq_is_pending,
16961790
.irq_update = uart_stm32_irq_update,
16971791
.irq_callback_set = uart_stm32_irq_callback_set,
1698-
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
1792+
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
16991793
#ifdef CONFIG_UART_ASYNC_API
17001794
.callback_set = uart_stm32_async_callback_set,
17011795
.tx = uart_stm32_async_tx,
17021796
.tx_abort = uart_stm32_async_tx_abort,
17031797
.rx_enable = uart_stm32_async_rx_enable,
17041798
.rx_disable = uart_stm32_async_rx_disable,
17051799
.rx_buf_rsp = uart_stm32_async_rx_buf_rsp,
1706-
#endif /* CONFIG_UART_ASYNC_API */
1800+
#ifdef CONFIG_UART_WIDE_DATA
1801+
.tx_u16 = uart_stm32_async_tx_u16,
1802+
.rx_enable_u16 = uart_stm32_async_rx_enable_u16,
1803+
.rx_buf_rsp_u16 = uart_stm32_async_rx_buf_rsp_u16,
1804+
#endif
1805+
#endif /* CONFIG_UART_ASYNC_API */
17071806
};
17081807

17091808
/**

0 commit comments

Comments
 (0)