Skip to content

Commit 4c2bc42

Browse files
Martinhoff-makerfabiobaltieri
authored andcommitted
drivers: serial: silabs: Change poll_out function to blocking mode
Since the UART API explicitly states that the poll_out function needs to block until the character is sent, change the mechanism and add a busy-wait loop to ensure transmission completion before proceeding. Signed-off-by: Martin Hoff <[email protected]>
1 parent c37ffd3 commit 4c2bc42

File tree

2 files changed

+19
-29
lines changed

2 files changed

+19
-29
lines changed

drivers/serial/uart_silabs_eusart.c

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ struct eusart_config {
4747

4848
enum eusart_pm_lock {
4949
EUSART_PM_LOCK_TX,
50-
EUSART_PM_LOCK_TX_POLL,
5150
EUSART_PM_LOCK_RX,
5251
EUSART_PM_LOCK_COUNT,
5352
};
@@ -82,7 +81,7 @@ static int eusart_pm_action(const struct device *dev, enum pm_device_action acti
8281
*
8382
* @return true if lock was taken, false otherwise
8483
*/
85-
static bool eusart_pm_lock_get(const struct device *dev, enum eusart_pm_lock lock)
84+
static __maybe_unused bool eusart_pm_lock_get(const struct device *dev, enum eusart_pm_lock lock)
8685
{
8786
#ifdef CONFIG_PM
8887
struct eusart_data *data = dev->data;
@@ -108,7 +107,7 @@ static bool eusart_pm_lock_get(const struct device *dev, enum eusart_pm_lock loc
108107
*
109108
* @return true if lock was released, false otherwise
110109
*/
111-
static bool eusart_pm_lock_put(const struct device *dev, enum eusart_pm_lock lock)
110+
static __maybe_unused bool eusart_pm_lock_put(const struct device *dev, enum eusart_pm_lock lock)
112111
{
113112
#ifdef CONFIG_PM
114113
struct eusart_data *data = dev->data;
@@ -142,13 +141,13 @@ static void eusart_poll_out(const struct device *dev, unsigned char c)
142141
{
143142
const struct eusart_config *config = dev->config;
144143

145-
if (eusart_pm_lock_get(dev, EUSART_PM_LOCK_TX_POLL)) {
146-
EUSART_IntEnable(config->eusart, EUSART_IF_TXC);
147-
}
148144
/* EUSART_Tx function already waits for the transmit buffer being empty
149145
* and waits for the bus to be free to transmit.
150146
*/
151147
EUSART_Tx(config->eusart, c);
148+
149+
while (!(config->eusart->STATUS & EUSART_STATUS_TXC)) {
150+
}
152151
}
153152

154153
static int eusart_err_check(const struct device *dev)
@@ -761,17 +760,12 @@ static int eusart_async_init(const struct device *dev)
761760
static void eusart_isr(const struct device *dev)
762761
{
763762
__maybe_unused struct eusart_data *data = dev->data;
763+
#ifdef CONFIG_UART_SILABS_EUSART_ASYNC
764764
const struct eusart_config *config = dev->config;
765765
EUSART_TypeDef *eusart = config->eusart;
766766
uint32_t flags = EUSART_IntGet(eusart);
767-
__maybe_unused struct dma_status stat;
768-
769-
if (flags & EUSART_IF_TXC) {
770-
if (eusart_pm_lock_put(dev, EUSART_PM_LOCK_TX_POLL)) {
771-
EUSART_IntDisable(eusart, EUSART_IEN_TXC);
772-
EUSART_IntClear(eusart, EUSART_IF_TXC);
773-
}
774-
}
767+
struct dma_status stat;
768+
#endif
775769
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
776770
if (data->callback) {
777771
data->callback(dev, data->cb_data);

drivers/serial/uart_silabs_usart.c

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ struct uart_silabs_config {
5353

5454
enum uart_silabs_pm_lock {
5555
UART_SILABS_PM_LOCK_TX,
56-
UART_SILABS_PM_LOCK_TX_POLL,
5756
UART_SILABS_PM_LOCK_RX,
5857
UART_SILABS_PM_LOCK_COUNT,
5958
};
@@ -88,7 +87,8 @@ static int uart_silabs_pm_action(const struct device *dev, enum pm_device_action
8887
*
8988
* @return true if lock was taken, false otherwise
9089
*/
91-
static bool uart_silabs_pm_lock_get(const struct device *dev, enum uart_silabs_pm_lock lock)
90+
static __maybe_unused bool uart_silabs_pm_lock_get(const struct device *dev,
91+
enum uart_silabs_pm_lock lock)
9292
{
9393
#ifdef CONFIG_PM
9494
struct uart_silabs_data *data = dev->data;
@@ -114,7 +114,8 @@ static bool uart_silabs_pm_lock_get(const struct device *dev, enum uart_silabs_p
114114
*
115115
* @return true if lock was released, false otherwise
116116
*/
117-
static bool uart_silabs_pm_lock_put(const struct device *dev, enum uart_silabs_pm_lock lock)
117+
static __maybe_unused bool uart_silabs_pm_lock_put(const struct device *dev,
118+
enum uart_silabs_pm_lock lock)
118119
{
119120
#ifdef CONFIG_PM
120121
struct uart_silabs_data *data = dev->data;
@@ -149,11 +150,13 @@ static void uart_silabs_poll_out(const struct device *dev, unsigned char c)
149150
{
150151
const struct uart_silabs_config *config = dev->config;
151152

152-
if (uart_silabs_pm_lock_get(dev, UART_SILABS_PM_LOCK_TX_POLL)) {
153-
USART_IntEnable(config->base, USART_IF_TXC);
154-
}
155-
153+
/* USART_Tx function already waits for the transmit buffer being empty
154+
* and waits for the bus to be free to transmit.
155+
*/
156156
USART_Tx(config->base, c);
157+
158+
while (!(config->base->STATUS & USART_STATUS_TXC)) {
159+
}
157160
}
158161

159162
static int uart_silabs_err_check(const struct device *dev)
@@ -746,19 +749,12 @@ static int uart_silabs_async_init(const struct device *dev)
746749
static void uart_silabs_isr(const struct device *dev)
747750
{
748751
__maybe_unused struct uart_silabs_data *data = dev->data;
752+
#ifdef CONFIG_UART_SILABS_USART_ASYNC
749753
const struct uart_silabs_config *config = dev->config;
750754
USART_TypeDef *usart = config->base;
751755
uint32_t flags = USART_IntGet(usart);
752-
#ifdef CONFIG_UART_SILABS_USART_ASYNC
753756
struct dma_status stat;
754757
#endif
755-
756-
if (flags & USART_IF_TXC) {
757-
if (uart_silabs_pm_lock_put(dev, UART_SILABS_PM_LOCK_TX_POLL)) {
758-
USART_IntDisable(usart, USART_IEN_TXC);
759-
USART_IntClear(usart, USART_IF_TXC);
760-
}
761-
}
762758
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
763759
if (data->callback) {
764760
data->callback(dev, data->cb_data);

0 commit comments

Comments
 (0)