Skip to content

Commit dbcbd87

Browse files
committed
[nrf fromlist] drivers: serial: nrfx_uarte: Add workaround for BAUDRATE register
On uart120 BAUDRATE register is not retained when ENABLE=0 and because of that BAUDRATE must be set after enabling. Add workaround to the driver. Upstream PR: zephyrproject-rtos/zephyr#75462 Signed-off-by: Krzysztof Chruściński <[email protected]>
1 parent f014711 commit dbcbd87

File tree

1 file changed

+37
-2
lines changed

1 file changed

+37
-2
lines changed

drivers/serial/uart_nrfx_uarte.c

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,16 @@ LOG_MODULE_REGISTER(uart_nrfx_uarte, 0);
103103
#define UARTE_ANY_CACHE 1
104104
#endif
105105

106+
#ifdef UARTE_ANY_CACHE
107+
/* uart120 instance does not retain BAUDRATE register when ENABLE=0. When this instance
108+
* is used then baudrate must be set after enabling the peripheral and not before.
109+
* This approach works for all instances so can be generally applied when uart120 is used.
110+
* It is not default for all because it costs some resources. Since currently only uart120
111+
* needs cache, that is used to determine if workaround shall be applied.
112+
*/
113+
#define UARTE_BAUDRATE_RETENTION_WORKAROUND 1
114+
#endif
115+
106116
/*
107117
* RX timeout is divided into time slabs, this define tells how many divisions
108118
* should be made. More divisions - higher timeout accuracy and processor usage.
@@ -187,6 +197,9 @@ struct uarte_nrfx_int_driven {
187197
struct uarte_nrfx_data {
188198
#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
189199
struct uart_config uart_config;
200+
#ifdef UARTE_BAUDRATE_RETENTION_WORKAROUND
201+
nrf_uarte_baudrate_t nrf_baudrate;
202+
#endif
190203
#endif
191204
#ifdef UARTE_INTERRUPT_DRIVEN
192205
struct uarte_nrfx_int_driven *int_driven;
@@ -387,7 +400,6 @@ static int baudrate_set(const struct device *dev, uint32_t baudrate)
387400
const struct uarte_nrfx_config *config = dev->config;
388401
/* calculated baudrate divisor */
389402
nrf_uarte_baudrate_t nrf_baudrate = NRF_BAUDRATE(baudrate);
390-
NRF_UARTE_Type *uarte = get_uarte_instance(dev);
391403

392404
if (nrf_baudrate == 0) {
393405
return -EINVAL;
@@ -398,7 +410,15 @@ static int baudrate_set(const struct device *dev, uint32_t baudrate)
398410
nrf_baudrate /= config->clock_freq / NRF_UARTE_BASE_FREQUENCY_16MHZ;
399411
}
400412

413+
#ifdef UARTE_BAUDRATE_RETENTION_WORKAROUND
414+
struct uarte_nrfx_data *data = dev->data;
415+
416+
data->nrf_baudrate = nrf_baudrate;
417+
#else
418+
NRF_UARTE_Type *uarte = get_uarte_instance(dev);
419+
401420
nrf_uarte_baudrate_set(uarte, nrf_baudrate);
421+
#endif
402422

403423
return 0;
404424
}
@@ -582,6 +602,13 @@ static void uarte_enable(const struct device *dev, uint32_t act_mask, uint32_t s
582602
}
583603
#endif
584604
nrf_uarte_enable(get_uarte_instance(dev));
605+
#if UARTE_BAUDRATE_RETENTION_WORKAROUND
606+
nrf_uarte_baudrate_t baudrate = COND_CODE_1(CONFIG_UART_USE_RUNTIME_CONFIGURE,
607+
(data->nrf_baudrate),
608+
(((const struct uarte_nrfx_config *)dev->config)->nrf_baudrate));
609+
610+
nrf_uarte_baudrate_set(get_uarte_instance(dev), baudrate);
611+
#endif
585612
}
586613

587614
/* At this point we should have irq locked and any previous transfer completed.
@@ -2140,12 +2167,19 @@ static int uarte_nrfx_pm_action(const struct device *dev,
21402167

21412168
switch (action) {
21422169
case PM_DEVICE_ACTION_RESUME:
2143-
ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
2170+
{
2171+
ret = pins_state_change(dev, true);
21442172
if (ret < 0) {
21452173
return ret;
21462174
}
21472175

21482176
nrf_uarte_enable(uarte);
2177+
#if UARTE_BAUDRATE_RETENTION_WORKAROUND
2178+
nrf_uarte_baudrate_t baudrate = COND_CODE_1(CONFIG_UART_USE_RUNTIME_CONFIGURE,
2179+
(data->nrf_baudrate), (cfg->nrf_baudrate));
2180+
2181+
nrf_uarte_baudrate_set(get_uarte_instance(dev), baudrate);
2182+
#endif
21492183

21502184
#ifdef UARTE_ANY_ASYNC
21512185
if (data->async) {
@@ -2169,6 +2203,7 @@ static int uarte_nrfx_pm_action(const struct device *dev,
21692203
#endif
21702204
}
21712205
break;
2206+
}
21722207
case PM_DEVICE_ACTION_SUSPEND:
21732208
/* Disabling UART requires stopping RX, but stop RX event is
21742209
* only sent after each RX if async UART API is used.

0 commit comments

Comments
 (0)