@@ -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+
839858static 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
14671510static 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
14801527static 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