@@ -333,6 +333,13 @@ struct uarte_nrfx_config {
333333 uint8_t * poll_in_byte ;
334334};
335335
336+ /* Using Macro instead of static inline function to handle NO_OPTIMIZATIONS case
337+ * where static inline fails on linking.
338+ */
339+ #define HW_RX_COUNTING_ENABLED (config ) \
340+ (IS_ENABLED(UARTE_ANY_HW_ASYNC) ? \
341+ (config->flags & UARTE_CFG_FLAG_HW_BYTE_COUNTING) : false)
342+
336343static inline NRF_UARTE_Type * get_uarte_instance (const struct device * dev )
337344{
338345 const struct uarte_nrfx_config * config = dev -> config ;
@@ -355,6 +362,44 @@ static void endtx_isr(const struct device *dev)
355362
356363}
357364
365+ /** @brief Disable UARTE peripheral is not used by RX or TX.
366+ *
367+ * It must be called with interrupts locked so that deciding if no direction is
368+ * using the UARTE is atomically performed with UARTE peripheral disabling. Otherwise
369+ * it would be possible that after clearing flags we get preempted and UARTE is
370+ * enabled from the higher priority context and when we come back UARTE is disabled
371+ * here.
372+ * @param dev Device.
373+ * @param dis_mask Mask of direction (RX or TX) which now longer uses the UARTE instance.
374+ */
375+ static void uarte_disable_locked (const struct device * dev , uint32_t dis_mask )
376+ {
377+ struct uarte_nrfx_data * data = dev -> data ;
378+
379+ data -> flags &= ~dis_mask ;
380+ if (data -> flags & UARTE_FLAG_LOW_POWER ) {
381+ return ;
382+ }
383+
384+ #if defined(UARTE_ANY_ASYNC ) && !defined(CONFIG_UART_NRFX_UARTE_ENHANCED_RX )
385+ const struct uarte_nrfx_config * config = dev -> config ;
386+
387+ if (data -> async && HW_RX_COUNTING_ENABLED (config )) {
388+ nrfx_timer_disable (& config -> timer );
389+ /* Timer/counter value is reset when disabled. */
390+ data -> async -> rx .total_byte_cnt = 0 ;
391+ data -> async -> rx .total_user_byte_cnt = 0 ;
392+ }
393+ #endif
394+
395+ #ifdef CONFIG_SOC_NRF54H20_GPD
396+ const struct uarte_nrfx_config * cfg = dev -> config ;
397+
398+ nrf_gpd_retain_pins_set (cfg -> pcfg , true);
399+ #endif
400+ nrf_uarte_disable (get_uarte_instance (dev ));
401+ }
402+
358403#ifdef UARTE_ANY_NONE_ASYNC
359404/**
360405 * @brief Interrupt service routine.
@@ -390,7 +435,7 @@ static void uarte_nrfx_isr_int(const void *arg)
390435 pm_device_runtime_put_async (dev , K_NO_WAIT );
391436 }
392437 } else {
393- nrf_uarte_disable ( uarte );
438+ uarte_disable_locked ( dev , UARTE_FLAG_LOW_POWER_TX );
394439 }
395440#ifdef UARTE_INTERRUPT_DRIVEN
396441 if (!data -> int_driven )
@@ -610,13 +655,6 @@ static int wait_tx_ready(const struct device *dev)
610655 return key ;
611656}
612657
613- /* Using Macro instead of static inline function to handle NO_OPTIMIZATIONS case
614- * where static inline fails on linking.
615- */
616- #define HW_RX_COUNTING_ENABLED (config ) \
617- (IS_ENABLED(UARTE_ANY_HW_ASYNC) ? \
618- (config->flags & UARTE_CFG_FLAG_HW_BYTE_COUNTING) : false)
619-
620658static void uarte_periph_enable (const struct device * dev )
621659{
622660 NRF_UARTE_Type * uarte = get_uarte_instance (dev );
@@ -719,44 +757,6 @@ static void tx_start(const struct device *dev, const uint8_t *buf, size_t len)
719757}
720758
721759#if defined(UARTE_ANY_ASYNC )
722- /** @brief Disable UARTE peripheral is not used by RX or TX.
723- *
724- * It must be called with interrupts locked so that deciding if no direction is
725- * using the UARTE is atomically performed with UARTE peripheral disabling. Otherwise
726- * it would be possible that after clearing flags we get preempted and UARTE is
727- * enabled from the higher priority context and when we come back UARTE is disabled
728- * here.
729- * @param dev Device.
730- * @param dis_mask Mask of direction (RX or TX) which now longer uses the UARTE instance.
731- */
732- static void uarte_disable_locked (const struct device * dev , uint32_t dis_mask )
733- {
734- struct uarte_nrfx_data * data = dev -> data ;
735-
736- data -> flags &= ~dis_mask ;
737- if (data -> flags & UARTE_FLAG_LOW_POWER ) {
738- return ;
739- }
740-
741- #if !defined(CONFIG_UART_NRFX_UARTE_ENHANCED_RX )
742- const struct uarte_nrfx_config * config = dev -> config ;
743-
744- if (data -> async && HW_RX_COUNTING_ENABLED (config )) {
745- nrfx_timer_disable (& config -> timer );
746- /* Timer/counter value is reset when disabled. */
747- data -> async -> rx .total_byte_cnt = 0 ;
748- data -> async -> rx .total_user_byte_cnt = 0 ;
749- }
750- #endif
751-
752- #ifdef CONFIG_SOC_NRF54H20_GPD
753- const struct uarte_nrfx_config * cfg = dev -> config ;
754-
755- nrf_gpd_retain_pins_set (cfg -> pcfg , true);
756- #endif
757- nrf_uarte_disable (get_uarte_instance (dev ));
758- }
759-
760760static void rx_timeout (struct k_timer * timer );
761761static void tx_timeout (struct k_timer * timer );
762762
0 commit comments