@@ -340,6 +340,13 @@ struct uarte_nrfx_config {
340340 uint8_t * poll_in_byte ;
341341};
342342
343+ /* Using Macro instead of static inline function to handle NO_OPTIMIZATIONS case
344+ * where static inline fails on linking.
345+ */
346+ #define HW_RX_COUNTING_ENABLED (config ) \
347+ (IS_ENABLED(UARTE_ANY_HW_ASYNC) ? \
348+ (config->flags & UARTE_CFG_FLAG_HW_BYTE_COUNTING) : false)
349+
343350static inline NRF_UARTE_Type * get_uarte_instance (const struct device * dev )
344351{
345352 const struct uarte_nrfx_config * config = dev -> config ;
@@ -362,6 +369,44 @@ static void endtx_isr(const struct device *dev)
362369
363370}
364371
372+ /** @brief Disable UARTE peripheral is not used by RX or TX.
373+ *
374+ * It must be called with interrupts locked so that deciding if no direction is
375+ * using the UARTE is atomically performed with UARTE peripheral disabling. Otherwise
376+ * it would be possible that after clearing flags we get preempted and UARTE is
377+ * enabled from the higher priority context and when we come back UARTE is disabled
378+ * here.
379+ * @param dev Device.
380+ * @param dis_mask Mask of direction (RX or TX) which now longer uses the UARTE instance.
381+ */
382+ static void uarte_disable_locked (const struct device * dev , uint32_t dis_mask )
383+ {
384+ struct uarte_nrfx_data * data = dev -> data ;
385+
386+ data -> flags &= ~dis_mask ;
387+ if (data -> flags & UARTE_FLAG_LOW_POWER ) {
388+ return ;
389+ }
390+
391+ #if defined(UARTE_ANY_ASYNC ) && !defined(CONFIG_UART_NRFX_UARTE_ENHANCED_RX )
392+ const struct uarte_nrfx_config * config = dev -> config ;
393+
394+ if (data -> async && HW_RX_COUNTING_ENABLED (config )) {
395+ nrfx_timer_disable (& config -> timer );
396+ /* Timer/counter value is reset when disabled. */
397+ data -> async -> rx .total_byte_cnt = 0 ;
398+ data -> async -> rx .total_user_byte_cnt = 0 ;
399+ }
400+ #endif
401+
402+ #ifdef CONFIG_SOC_NRF54H20_GPD
403+ const struct uarte_nrfx_config * cfg = dev -> config ;
404+
405+ nrf_gpd_retain_pins_set (cfg -> pcfg , true);
406+ #endif
407+ nrf_uarte_disable (get_uarte_instance (dev ));
408+ }
409+
365410#ifdef UARTE_ANY_NONE_ASYNC
366411/**
367412 * @brief Interrupt service routine.
@@ -397,7 +442,7 @@ static void uarte_nrfx_isr_int(const void *arg)
397442 pm_device_runtime_put_async (dev , K_NO_WAIT );
398443 }
399444 } else {
400- nrf_uarte_disable ( uarte );
445+ uarte_disable_locked ( dev , UARTE_FLAG_LOW_POWER_TX );
401446 }
402447#ifdef UARTE_INTERRUPT_DRIVEN
403448 if (!data -> int_driven )
@@ -617,13 +662,6 @@ static int wait_tx_ready(const struct device *dev)
617662 return key ;
618663}
619664
620- /* Using Macro instead of static inline function to handle NO_OPTIMIZATIONS case
621- * where static inline fails on linking.
622- */
623- #define HW_RX_COUNTING_ENABLED (config ) \
624- (IS_ENABLED(UARTE_ANY_HW_ASYNC) ? \
625- (config->flags & UARTE_CFG_FLAG_HW_BYTE_COUNTING) : false)
626-
627665static void uarte_periph_enable (const struct device * dev )
628666{
629667 NRF_UARTE_Type * uarte = get_uarte_instance (dev );
@@ -726,44 +764,6 @@ static void tx_start(const struct device *dev, const uint8_t *buf, size_t len)
726764}
727765
728766#if defined(UARTE_ANY_ASYNC )
729- /** @brief Disable UARTE peripheral is not used by RX or TX.
730- *
731- * It must be called with interrupts locked so that deciding if no direction is
732- * using the UARTE is atomically performed with UARTE peripheral disabling. Otherwise
733- * it would be possible that after clearing flags we get preempted and UARTE is
734- * enabled from the higher priority context and when we come back UARTE is disabled
735- * here.
736- * @param dev Device.
737- * @param dis_mask Mask of direction (RX or TX) which now longer uses the UARTE instance.
738- */
739- static void uarte_disable_locked (const struct device * dev , uint32_t dis_mask )
740- {
741- struct uarte_nrfx_data * data = dev -> data ;
742-
743- data -> flags &= ~dis_mask ;
744- if (data -> flags & UARTE_FLAG_LOW_POWER ) {
745- return ;
746- }
747-
748- #if !defined(CONFIG_UART_NRFX_UARTE_ENHANCED_RX )
749- const struct uarte_nrfx_config * config = dev -> config ;
750-
751- if (data -> async && HW_RX_COUNTING_ENABLED (config )) {
752- nrfx_timer_disable (& config -> timer );
753- /* Timer/counter value is reset when disabled. */
754- data -> async -> rx .total_byte_cnt = 0 ;
755- data -> async -> rx .total_user_byte_cnt = 0 ;
756- }
757- #endif
758-
759- #ifdef CONFIG_SOC_NRF54H20_GPD
760- const struct uarte_nrfx_config * cfg = dev -> config ;
761-
762- nrf_gpd_retain_pins_set (cfg -> pcfg , true);
763- #endif
764- nrf_uarte_disable (get_uarte_instance (dev ));
765- }
766-
767767static void rx_timeout (struct k_timer * timer );
768768static void tx_timeout (struct k_timer * timer );
769769
0 commit comments