Skip to content

Commit f80b608

Browse files
nordic-krchnordicjm
authored andcommitted
[nrf fromtree] drivers: serial: nrfx_uarte: Add support for frame timeout
Frame timeout is a hardware feature present in newer versions of UARTE (e.g. in NRF54X platforms) for detecting idle state on RX line and ending RX after configurable timeout. Signed-off-by: Krzysztof Chruściński <[email protected]> (cherry picked from commit 1f96e62)
1 parent 22c4f08 commit f80b608

File tree

2 files changed

+59
-10
lines changed

2 files changed

+59
-10
lines changed

drivers/serial/Kconfig.nrfx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,8 @@ config UART_NRFX_UARTE
3131
config UART_NRFX_UARTE_LEGACY_SHIM
3232
bool "Legacy UARTE shim"
3333
depends on UART_NRFX_UARTE
34-
depends on !SOC_SERIES_NRF54LX
3534
depends on !SOC_SERIES_NRF54HX || RISCV
3635
depends on !SOC_SERIES_NRF92X || RISCV
37-
# New shim takes more ROM. Until it is fixed use legacy shim.
3836
default y
3937

4038
config UART_NRFX_UARTE_ENHANCED_RX

drivers/serial/uart_nrfx_uarte.c

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ LOG_MODULE_REGISTER(uart_nrfx_uarte, CONFIG_UART_LOG_LEVEL);
8383
#define UARTE_HAS_ENDTX_STOPTX_SHORT 1
8484
#endif
8585

86+
#if (UARTE_FOR_EACH_INSTANCE(INSTANCE_PROP, (+), (0), frame_timeout_supported)) == \
87+
(UARTE_FOR_EACH_INSTANCE(INSTANCE_PRESENT, (+), (0), frame_timeout_supported))
88+
#define UARTE_HAS_FRAME_TIMEOUT 1
89+
#endif
90+
8691
/*
8792
* RX timeout is divided into time slabs, this define tells how many divisions
8893
* should be made. More divisions - higher timeout accuracy and processor usage.
@@ -113,7 +118,9 @@ struct uarte_async_rx {
113118
uint8_t *next_buf;
114119
size_t next_buf_len;
115120
#ifdef CONFIG_UART_NRFX_UARTE_ENHANCED_RX
121+
#if !defined(UARTE_HAS_FRAME_TIMEOUT)
116122
uint32_t idle_cnt;
123+
#endif
117124
k_timeout_t timeout;
118125
#else
119126
uint32_t total_byte_cnt; /* Total number of bytes received */
@@ -227,6 +234,9 @@ struct uarte_nrfx_config {
227234
/* None-zero in case of high speed instances. Baudrate is adjusted by that ratio. */
228235
uint32_t clock_freq;
229236
#else
237+
#ifdef UARTE_HAS_FRAME_TIMEOUT
238+
uint32_t baudrate;
239+
#endif
230240
nrf_uarte_baudrate_t nrf_baudrate;
231241
nrf_uarte_config_t hw_config;
232242
#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
@@ -373,10 +383,6 @@ static int uarte_nrfx_configure(const struct device *dev,
373383
struct uarte_nrfx_data *data = dev->data;
374384
nrf_uarte_config_t uarte_cfg;
375385

376-
#if NRF_UARTE_HAS_FRAME_TIMEOUT
377-
uarte_cfg.frame_timeout = NRF_UARTE_FRAME_TIMEOUT_DIS;
378-
#endif
379-
380386
#if defined(UARTE_CONFIG_STOP_Msk)
381387
switch (cfg->stop_bits) {
382388
case UART_CFG_STOP_BITS_1:
@@ -433,6 +439,9 @@ static int uarte_nrfx_configure(const struct device *dev,
433439
return -ENOTSUP;
434440
}
435441

442+
#ifdef UARTE_HAS_FRAME_TIMEOUT
443+
uarte_cfg.frame_timeout = NRF_UARTE_FRAME_TIMEOUT_EN;
444+
#endif
436445
nrf_uarte_configure(get_uarte_instance(dev), &uarte_cfg);
437446

438447
data->uart_config = *cfg;
@@ -669,7 +678,8 @@ static int uarte_nrfx_init(const struct device *dev)
669678
NRF_UARTE_INT_RXSTARTED_MASK |
670679
NRF_UARTE_INT_ERROR_MASK |
671680
NRF_UARTE_INT_RXTO_MASK |
672-
(IS_ENABLED(CONFIG_UART_NRFX_UARTE_ENHANCED_RX) ? NRF_UARTE_INT_RXDRDY_MASK : 0);
681+
((IS_ENABLED(CONFIG_UART_NRFX_UARTE_ENHANCED_RX) &&
682+
!IS_ENABLED(UARTE_HAS_FRAME_TIMEOUT)) ? NRF_UARTE_INT_RXDRDY_MASK : 0);
673683

674684
#if !defined(CONFIG_UART_NRFX_UARTE_ENHANCED_RX)
675685
int ret = uarte_nrfx_rx_counting_init(dev);
@@ -836,6 +846,15 @@ static void notify_rx_disable(const struct device *dev)
836846
user_callback(dev, (struct uart_event *)&evt);
837847
}
838848

849+
#ifdef UARTE_HAS_FRAME_TIMEOUT
850+
static uint32_t us_to_bauds(uint32_t baudrate, int32_t timeout)
851+
{
852+
uint64_t bauds = (uint64_t)baudrate * timeout / 1000000;
853+
854+
return MIN((uint32_t)bauds, UARTE_FRAMETIMEOUT_COUNTERTOP_Msk);
855+
}
856+
#endif
857+
839858
static int uarte_nrfx_rx_enable(const struct device *dev, uint8_t *buf,
840859
size_t len,
841860
int32_t timeout)
@@ -859,9 +878,22 @@ static int uarte_nrfx_rx_enable(const struct device *dev, uint8_t *buf,
859878
}
860879

861880
#ifdef CONFIG_UART_NRFX_UARTE_ENHANCED_RX
881+
#ifdef UARTE_HAS_FRAME_TIMEOUT
882+
if (timeout != SYS_FOREVER_US) {
883+
uint32_t baudrate = COND_CODE_1(CONFIG_UART_USE_RUNTIME_CONFIGURE,
884+
(data->uart_config.baudrate), (cfg->baudrate));
885+
886+
async_rx->timeout = K_USEC(timeout);
887+
nrf_uarte_frame_timeout_set(uarte, us_to_bauds(baudrate, timeout));
888+
nrf_uarte_shorts_enable(uarte, NRF_UARTE_SHORT_FRAME_TIMEOUT_STOPRX);
889+
} else {
890+
async_rx->timeout = K_NO_WAIT;
891+
}
892+
#else
862893
async_rx->timeout = (timeout == SYS_FOREVER_US) ?
863894
K_NO_WAIT : K_USEC(timeout / RX_TIMEOUT_DIV);
864895
async_rx->idle_cnt = 0;
896+
#endif /* UARTE_HAS_FRAME_TIMEOUT */
865897
#else
866898
async_rx->timeout_us = timeout;
867899
async_rx->timeout_slab = timeout / RX_TIMEOUT_DIV;
@@ -1018,6 +1050,12 @@ static void rx_timeout(struct k_timer *timer)
10181050
#if CONFIG_UART_NRFX_UARTE_ENHANCED_RX
10191051
NRF_UARTE_Type *uarte = get_uarte_instance(dev);
10201052

1053+
#ifdef UARTE_HAS_FRAME_TIMEOUT
1054+
if (!nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_RXDRDY)) {
1055+
nrf_uarte_task_trigger(uarte, NRF_UARTE_TASK_STOPRX);
1056+
}
1057+
return;
1058+
#else /* UARTE_HAS_FRAME_TIMEOUT */
10211059
struct uarte_nrfx_data *data = dev->data;
10221060
struct uarte_async_rx *async_rx = &data->async->rx;
10231061

@@ -1041,6 +1079,7 @@ static void rx_timeout(struct k_timer *timer)
10411079
}
10421080

10431081
k_timer_start(&async_rx->timer, async_rx->timeout, K_NO_WAIT);
1082+
#endif /* UARTE_HAS_FRAME_TIMEOUT */
10441083
#else /* CONFIG_UART_NRFX_UARTE_ENHANCED_RX */
10451084
const struct uarte_nrfx_config *cfg = dev->config;
10461085
struct uarte_nrfx_data *data = dev->data;
@@ -1154,6 +1193,7 @@ static void rxstarted_isr(const struct device *dev)
11541193
.type = UART_RX_BUF_REQUEST,
11551194
};
11561195

1196+
#ifndef UARTE_HAS_FRAME_TIMEOUT
11571197
struct uarte_nrfx_data *data = dev->data;
11581198
struct uarte_async_rx *async_rx = &data->async->rx;
11591199

@@ -1171,6 +1211,7 @@ static void rxstarted_isr(const struct device *dev)
11711211
k_timer_start(&async_rx->timer, timeout, timeout);
11721212
}
11731213
#endif /* CONFIG_UART_NRFX_UARTE_ENHANCED_RX */
1214+
#endif /* !UARTE_HAS_FRAME_TIMEOUT */
11741215
user_callback(dev, &evt);
11751216
}
11761217

@@ -1370,7 +1411,9 @@ static void rxto_isr(const struct device *dev)
13701411

13711412
#ifdef CONFIG_UART_NRFX_UARTE_ENHANCED_RX
13721413
NRF_UARTE_Type *uarte = get_uarte_instance(dev);
1373-
1414+
#ifdef UARTE_HAS_FRAME_TIMEOUT
1415+
nrf_uarte_shorts_disable(uarte, NRF_UARTE_SHORT_FRAME_TIMEOUT_STOPRX);
1416+
#endif
13741417
nrf_uarte_event_clear(uarte, NRF_UARTE_EVENT_RXDRDY);
13751418
#endif
13761419

@@ -1466,6 +1509,9 @@ static void txstopped_isr(const struct device *dev)
14661509

14671510
static void rxdrdy_isr(const struct device *dev)
14681511
{
1512+
#if !defined(UARTE_HAS_FRAME_TIMEOUT)
1513+
struct uarte_nrfx_data *data = dev->data;
1514+
14691515
#if defined(CONFIG_UART_NRFX_UARTE_ENHANCED_RX)
14701516
NRF_UARTE_Type *uarte = get_uarte_instance(dev);
14711517

@@ -1475,6 +1521,7 @@ static void rxdrdy_isr(const struct device *dev)
14751521
#else
14761522
data->async->rx.cnt.cnt++;
14771523
#endif
1524+
#endif /* !UARTE_HAS_FRAME_TIMEOUT */
14781525
}
14791526

14801527
static bool event_check_clear(NRF_UARTE_Type *uarte, nrf_uarte_event_t event,
@@ -1497,7 +1544,7 @@ static void uarte_nrfx_isr_async(const void *arg)
14971544
struct uarte_async_rx *async_rx = &data->async->rx;
14981545
uint32_t imask = nrf_uarte_int_enable_check(uarte, UINT32_MAX);
14991546

1500-
if (!HW_RX_COUNTING_ENABLED(config)
1547+
if (!(HW_RX_COUNTING_ENABLED(config) || IS_ENABLED(UARTE_HAS_FRAME_TIMEOUT))
15011548
&& event_check_clear(uarte, NRF_UARTE_EVENT_RXDRDY, NRF_UARTE_INT_RXDRDY_MASK, imask)) {
15021549
rxdrdy_isr(dev);
15031550

@@ -2129,6 +2176,8 @@ static int uarte_nrfx_pm_action(const struct device *dev,
21292176
IF_ENABLED(UARTE_HAS_STOP_CONFIG, (.stop = NRF_UARTE_STOP_ONE,))\
21302177
IF_ENABLED(UARTE_ODD_PARITY_ALLOWED, \
21312178
(.paritytype = NRF_UARTE_PARITYTYPE_EVEN,)) \
2179+
IF_ENABLED(UARTE_HAS_FRAME_TIMEOUT, \
2180+
(.frame_timeout = NRF_UARTE_FRAME_TIMEOUT_EN,)) \
21322181
}
21332182

21342183
/* Macro for setting zephyr specific configuration structures. */
@@ -2172,7 +2221,9 @@ static int uarte_nrfx_pm_action(const struct device *dev,
21722221
COND_CODE_1(CONFIG_UART_USE_RUNTIME_CONFIGURE, \
21732222
(IF_ENABLED(DT_CLOCKS_HAS_IDX(UARTE(idx), 0), \
21742223
(.clock_freq = UARTE_GET_FREQ(idx),))), \
2175-
(.nrf_baudrate = UARTE_GET_BAUDRATE(idx), \
2224+
(IF_ENABLED(UARTE_HAS_FRAME_TIMEOUT, \
2225+
(.baudrate = UARTE_PROP(idx, current_speed),)) \
2226+
.nrf_baudrate = UARTE_GET_BAUDRATE(idx), \
21762227
.hw_config = UARTE_NRF_CONFIG(idx),)) \
21772228
.pcfg = PINCTRL_DT_DEV_CONFIG_GET(UARTE(idx)), \
21782229
.uarte_regs = _CONCAT(NRF_UARTE, idx), \

0 commit comments

Comments
 (0)