@@ -104,7 +104,6 @@ struct uarte_async_cb {
104104 const uint8_t * xfer_buf ;
105105 size_t xfer_len ;
106106
107- uint8_t * tx_cache ;
108107 size_t tx_cache_offset ;
109108
110109 struct k_timer tx_timeout_timer ;
@@ -131,7 +130,6 @@ struct uarte_async_cb {
131130 uint8_t rx_flush_cnt ;
132131 volatile bool rx_enabled ;
133132 volatile bool discard_rx_fifo ;
134- bool hw_rx_counting ;
135133 bool pending_tx ;
136134 /* Flag to ensure that RX timeout won't be executed during ENDRX ISR */
137135 volatile bool is_in_irq ;
@@ -179,6 +177,9 @@ struct uarte_nrfx_data {
179177/* If enabled then ENDTX is PPI'ed to TXSTOP */
180178#define UARTE_CFG_FLAG_PPI_ENDTX BIT(1)
181179
180+ /* If enabled then TIMER and PPI is used for byte counting. */
181+ #define UARTE_CFG_FLAG_HW_BYTE_COUNTING BIT(2)
182+
182183/* If enabled then UARTE peripheral is disabled when not used. This allows
183184 * to achieve lowest power consumption in idle.
184185 */
@@ -224,6 +225,7 @@ struct uarte_nrfx_config {
224225#endif
225226#ifdef UARTE_ANY_ASYNC
226227 nrfx_timer_t timer ;
228+ uint8_t * tx_cache ;
227229#endif
228230};
229231
@@ -511,8 +513,8 @@ static int pins_state_change(const struct device *dev, bool on)
511513/* Using Macro instead of static inline function to handle NO_OPTIMIZATIONS case
512514 * where static inline fails on linking.
513515 */
514- #define HW_RX_COUNTING_ENABLED (data ) \
515- (IS_ENABLED(UARTE_HW_ASYNC) ? data->async->hw_rx_counting : false)
516+ #define HW_RX_COUNTING_ENABLED (config ) \
517+ (IS_ENABLED(UARTE_HW_ASYNC) ? (config->flags & UARTE_CFG_FLAG_HW_BYTE_COUNTING) : false)
516518
517519#endif /* UARTE_ANY_ASYNC */
518520
@@ -532,7 +534,7 @@ static int uarte_enable(const struct device *dev, uint32_t mask)
532534 return ret ;
533535 }
534536
535- if (HW_RX_COUNTING_ENABLED (data ) && disabled ) {
537+ if (HW_RX_COUNTING_ENABLED (config ) && disabled ) {
536538 const nrfx_timer_t * timer = & config -> timer ;
537539
538540 nrfx_timer_enable (timer );
@@ -583,7 +585,7 @@ static void uart_disable(const struct device *dev)
583585 const struct uarte_nrfx_config * config = dev -> config ;
584586 struct uarte_nrfx_data * data = dev -> data ;
585587
586- if (data -> async && HW_RX_COUNTING_ENABLED (data )) {
588+ if (data -> async && HW_RX_COUNTING_ENABLED (config )) {
587589 nrfx_timer_disable (& config -> timer );
588590 /* Timer/counter value is reset when disabled. */
589591 data -> async -> rx_total_byte_cnt = 0 ;
@@ -608,7 +610,7 @@ static int uarte_nrfx_rx_counting_init(const struct device *dev)
608610 NRF_UARTE_Type * uarte = get_uarte_instance (dev );
609611 int ret ;
610612
611- if (HW_RX_COUNTING_ENABLED (data )) {
613+ if (HW_RX_COUNTING_ENABLED (cfg )) {
612614 nrfx_timer_config_t tmr_config = NRFX_TIMER_DEFAULT_CONFIG (
613615 NRF_TIMER_BASE_FREQUENCY_GET (cfg -> timer .p_reg ));
614616
@@ -618,20 +620,18 @@ static int uarte_nrfx_rx_counting_init(const struct device *dev)
618620 & tmr_config ,
619621 timer_handler );
620622 if (ret != NRFX_SUCCESS ) {
621- LOG_ERR ("Timer already initialized, "
622- "switching to software byte counting." );
623- data -> async -> hw_rx_counting = false;
623+ LOG_ERR ("Timer already initialized" );
624+ return - EINVAL ;
624625 } else {
625626 nrfx_timer_enable (& cfg -> timer );
626627 nrfx_timer_clear (& cfg -> timer );
627628 }
628629
629630 ret = gppi_channel_alloc (& data -> async -> rx_cnt .ppi );
630631 if (ret != NRFX_SUCCESS ) {
631- LOG_ERR ("Failed to allocate PPI Channel, "
632- "switching to software byte counting." );
633- data -> async -> hw_rx_counting = false;
632+ LOG_ERR ("Failed to allocate PPI Channel" );
634633 nrfx_timer_uninit (& cfg -> timer );
634+ return - EINVAL ;
635635 }
636636
637637#if CONFIG_HAS_HW_NRF_PPI
@@ -729,8 +729,10 @@ static void start_tx_locked(const struct device *dev, struct uarte_nrfx_data *da
729729 *
730730 * @return True if cache was set, false if no more data to put in cache.
731731 */
732- static bool setup_tx_cache (struct uarte_nrfx_data * data )
732+ static bool setup_tx_cache (const struct device * dev )
733733{
734+ struct uarte_nrfx_data * data = dev -> data ;
735+ const struct uarte_nrfx_config * config = dev -> config ;
734736 size_t remaining = data -> async -> tx_size - data -> async -> tx_cache_offset ;
735737
736738 if (!remaining ) {
@@ -740,8 +742,8 @@ static bool setup_tx_cache(struct uarte_nrfx_data *data)
740742 size_t len = MIN (remaining , CONFIG_UART_ASYNC_TX_CACHE_SIZE );
741743
742744 data -> async -> xfer_len = len ;
743- data -> async -> xfer_buf = data -> async -> tx_cache ;
744- memcpy (data -> async -> tx_cache , & data -> async -> tx_buf [data -> async -> tx_cache_offset ], len );
745+ data -> async -> xfer_buf = config -> tx_cache ;
746+ memcpy (config -> tx_cache , & data -> async -> tx_buf [data -> async -> tx_cache_offset ], len );
745747
746748 return true;
747749}
@@ -782,7 +784,7 @@ static int uarte_nrfx_tx(const struct device *dev, const uint8_t *buf,
782784 data -> async -> xfer_len = len ;
783785 } else {
784786 data -> async -> tx_cache_offset = 0 ;
785- (void )setup_tx_cache (data );
787+ (void )setup_tx_cache (dev );
786788 }
787789
788790 start_tx_locked (dev , data );
@@ -1019,7 +1021,7 @@ static void rx_timeout(struct k_timer *timer)
10191021 nrf_uarte_int_disable (get_uarte_instance (dev ),
10201022 NRF_UARTE_INT_ENDRX_MASK );
10211023
1022- if (HW_RX_COUNTING_ENABLED (data )) {
1024+ if (HW_RX_COUNTING_ENABLED (cfg )) {
10231025 read = nrfx_timer_capture (& cfg -> timer , 0 );
10241026 } else {
10251027 read = data -> async -> rx_cnt .cnt ;
@@ -1038,7 +1040,7 @@ static void rx_timeout(struct k_timer *timer)
10381040 int32_t len = data -> async -> rx_total_byte_cnt
10391041 - data -> async -> rx_total_user_byte_cnt ;
10401042
1041- if (!HW_RX_COUNTING_ENABLED (data ) &&
1043+ if (!HW_RX_COUNTING_ENABLED (cfg ) &&
10421044 (len < 0 )) {
10431045 /* Prevent too low value of rx_cnt.cnt which may occur due to
10441046 * latencies in handling of the RXRDY interrupt.
@@ -1374,7 +1376,7 @@ static void txstopped_isr(const struct device *dev)
13741376 */
13751377 if (amount == data -> async -> xfer_len ) {
13761378 data -> async -> tx_cache_offset += amount ;
1377- if (setup_tx_cache (data )) {
1379+ if (setup_tx_cache (dev )) {
13781380 key = irq_lock ();
13791381 start_tx_locked (dev , data );
13801382 irq_unlock (key );
@@ -1412,10 +1414,12 @@ static void uarte_nrfx_isr_async(const void *arg)
14121414{
14131415 const struct device * dev = arg ;
14141416 NRF_UARTE_Type * uarte = get_uarte_instance (dev );
1415- struct uarte_nrfx_data * data = dev -> data ;
1417+ const struct uarte_nrfx_config * config = dev -> config ;
14161418
1417- if (!HW_RX_COUNTING_ENABLED (data )
1419+ if (!HW_RX_COUNTING_ENABLED (config )
14181420 && nrf_uarte_event_check (uarte , NRF_UARTE_EVENT_RXDRDY )) {
1421+ struct uarte_nrfx_data * data = dev -> data ;
1422+
14191423 nrf_uarte_event_clear (uarte , NRF_UARTE_EVENT_RXDRDY );
14201424 data -> async -> rx_cnt .cnt ++ ;
14211425 return ;
@@ -1915,7 +1919,7 @@ static int uarte_nrfx_pm_action(const struct device *dev,
19151919
19161920#ifdef UARTE_ANY_ASYNC
19171921 if (data -> async ) {
1918- if (HW_RX_COUNTING_ENABLED (data )) {
1922+ if (HW_RX_COUNTING_ENABLED (cfg )) {
19191923 nrfx_timer_enable (& cfg -> timer );
19201924 }
19211925
@@ -2054,8 +2058,12 @@ static int uarte_nrfx_pm_action(const struct device *dev,
20542058#define UART_NRF_UARTE_DEVICE (idx ) \
20552059 NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(UARTE(idx)); \
20562060 UARTE_INT_DRIVEN(idx); \
2057- UARTE_ASYNC(idx); \
20582061 PINCTRL_DT_DEFINE(UARTE(idx)); \
2062+ IF_ENABLED(CONFIG_UART_##idx##_ASYNC, ( \
2063+ static uint8_t \
2064+ uarte##idx##_tx_cache[CONFIG_UART_ASYNC_TX_CACHE_SIZE] \
2065+ UARTE_MEMORY_SECTION(idx); \
2066+ struct uarte_async_cb uarte##idx##_async;)) \
20592067 static uint8_t uarte##idx##_char_out UARTE_MEMORY_SECTION(idx); \
20602068 static uint8_t uarte##idx##_rx_data UARTE_MEMORY_SECTION(idx); \
20612069 static struct uarte_nrfx_data uarte_##idx##_data = { \
@@ -2082,8 +2090,12 @@ static int uarte_nrfx_pm_action(const struct device *dev,
20822090 UARTE_CFG_FLAG_GPIO_MGMT : 0) | \
20832091 (IS_ENABLED(CONFIG_UART_##idx##_ENHANCED_POLL_OUT) ? \
20842092 UARTE_CFG_FLAG_PPI_ENDTX : 0) | \
2093+ (IS_ENABLED(CONFIG_UART_##idx##_NRF_HW_ASYNC) ? \
2094+ UARTE_CFG_FLAG_HW_BYTE_COUNTING : 0) | \
20852095 USE_LOW_POWER(idx), \
20862096 UARTE_DISABLE_RX_INIT(UARTE(idx)), \
2097+ IF_ENABLED(CONFIG_UART_##idx##_ASYNC, \
2098+ (.tx_cache = uarte##idx##_tx_cache,)) \
20872099 IF_ENABLED(CONFIG_UART_##idx##_NRF_HW_ASYNC, \
20882100 (.timer = NRFX_TIMER_INSTANCE( \
20892101 CONFIG_UART_##idx##_NRF_HW_ASYNC_TIMER),)) \
@@ -2112,17 +2124,6 @@ static int uarte_nrfx_pm_action(const struct device *dev,
21122124 CONFIG_SERIAL_INIT_PRIORITY, \
21132125 &uart_nrfx_uarte_driver_api)
21142126
2115- #define UARTE_ASYNC (idx ) \
2116- IF_ENABLED(CONFIG_UART_##idx##_ASYNC, ( \
2117- static uint8_t \
2118- uarte##idx##_tx_cache[CONFIG_UART_ASYNC_TX_CACHE_SIZE] \
2119- UARTE_MEMORY_SECTION(idx); \
2120- struct uarte_async_cb uarte##idx##_async = { \
2121- .tx_cache = uarte##idx##_tx_cache, \
2122- .hw_rx_counting = \
2123- IS_ENABLED(CONFIG_UART_##idx##_NRF_HW_ASYNC), \
2124- }))
2125-
21262127#define UARTE_INT_DRIVEN (idx ) \
21272128 IF_ENABLED(CONFIG_UART_##idx##_INTERRUPT_DRIVEN, \
21282129 (static uint8_t uarte##idx##_tx_buffer \
0 commit comments