Skip to content

Commit a76d225

Browse files
[nrf fromlist] drivers: serial: nrfx_uarte: enable cross domain pins for nRF54L15
UARTE20 and UARTE21 instances enable usage of pins on different port, but require request for constant latency mode. Added handling of such scenario in the driver. Added testcase to cover it. Upstream PR #: 90197 Signed-off-by: Michał Stasiak <[email protected]>
1 parent 80b3635 commit a76d225

File tree

5 files changed

+133
-0
lines changed

5 files changed

+133
-0
lines changed

drivers/serial/uart_nrfx_uarte.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,27 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_CLOCK_CONTROL));
148148
*/
149149
#define UARTE_ANY_HIGH_SPEED (UARTE_FOR_EACH_INSTANCE(INSTANCE_IS_HIGH_SPEED, (||), (0)))
150150

151+
#define UARTE_PINS_CROSS_DOMAIN(unused, prefix, idx, _) \
152+
COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(UARTE(prefix##idx)), \
153+
(UARTE_PROP(idx, cross_domain_pins_supported)), \
154+
(0))
155+
156+
#if UARTE_FOR_EACH_INSTANCE(UARTE_PINS_CROSS_DOMAIN, (||), (0))
157+
#include <hal/nrf_gpio.h>
158+
/* Certain UARTE instances support usage of cross domain pins in form of dedicated pins on
159+
* a port different from the default one.
160+
*/
161+
#define UARTE_CROSS_DOMAIN_PINS_SUPPORTED 1
162+
#endif
163+
164+
#if UARTE_CROSS_DOMAIN_PINS_SUPPORTED && defined(CONFIG_NRF_SYS_EVENT)
165+
#include <nrf_sys_event.h>
166+
/* To use cross domain pins, constant latency mode needs to be applied, which is
167+
* handled via nrf_sys_event requests.
168+
*/
169+
#define UARTE_CROSS_DOMAIN_PINS_HANDLE 1
170+
#endif
171+
151172
#ifdef UARTE_ANY_CACHE
152173
/* uart120 instance does not retain BAUDRATE register when ENABLE=0. When this instance
153174
* is used then baudrate must be set after enabling the peripheral and not before.
@@ -371,6 +392,10 @@ struct uarte_nrfx_config {
371392
#endif
372393
uint8_t *poll_out_byte;
373394
uint8_t *poll_in_byte;
395+
#if UARTE_CROSS_DOMAIN_PINS_SUPPORTED
396+
bool cross_domain;
397+
int8_t default_port;
398+
#endif
374399
};
375400

376401
/* Using Macro instead of static inline function to handle NO_OPTIMIZATIONS case
@@ -444,6 +469,31 @@ static void uarte_disable_locked(const struct device *dev, uint32_t dis_mask)
444469
nrf_uarte_disable(get_uarte_instance(dev));
445470
}
446471

472+
#if UARTE_CROSS_DOMAIN_PINS_SUPPORTED
473+
static bool uarte_has_cross_domain_connection(const struct uarte_nrfx_config *config)
474+
{
475+
const struct pinctrl_dev_config *pcfg = config->pcfg;
476+
const struct pinctrl_state *state;
477+
int ret;
478+
479+
ret = pinctrl_lookup_state(pcfg, PINCTRL_STATE_DEFAULT, &state);
480+
if (ret < 0) {
481+
LOG_ERR("Unable to read pin state");
482+
return false;
483+
}
484+
485+
for (uint8_t i = 0U; i < state->pin_cnt; i++) {
486+
uint32_t pin = NRF_GET_PIN(state->pins[i]);
487+
488+
if (nrf_gpio_pin_port_number_extract(&pin) != config->default_port) {
489+
return true;
490+
}
491+
}
492+
493+
return false;
494+
}
495+
#endif
496+
447497
#if defined(UARTE_ANY_NONE_ASYNC) && !defined(CONFIG_UART_NRFX_UARTE_NO_IRQ)
448498
/**
449499
* @brief Interrupt service routine.
@@ -727,6 +777,19 @@ static void uarte_periph_enable(const struct device *dev)
727777
#ifdef CONFIG_SOC_NRF54H20_GPD
728778
nrf_gpd_retain_pins_set(config->pcfg, false);
729779
#endif
780+
#if UARTE_CROSS_DOMAIN_PINS_SUPPORTED
781+
if (config->cross_domain && uarte_has_cross_domain_connection(config)) {
782+
#if UARTE_CROSS_DOMAIN_PINS_HANDLE
783+
int err;
784+
785+
err = nrf_sys_event_request_global_constlat();
786+
(void)err;
787+
__ASSERT_NO_MSG(err >= 0);
788+
#else
789+
__ASSERT(false, "NRF_SYS_EVENT needs to be enabled to use cross domain pins.\n");
790+
#endif
791+
}
792+
#endif
730793
#if UARTE_BAUDRATE_RETENTION_WORKAROUND
731794
nrf_uarte_baudrate_set(uarte,
732795
COND_CODE_1(CONFIG_UART_USE_RUNTIME_CONFIGURE,
@@ -2411,6 +2474,19 @@ static void uarte_pm_suspend(const struct device *dev)
24112474
#ifdef CONFIG_SOC_NRF54H20_GPD
24122475
nrf_gpd_retain_pins_set(cfg->pcfg, true);
24132476
#endif
2477+
#if UARTE_CROSS_DOMAIN_PINS_SUPPORTED
2478+
if (cfg->cross_domain && uarte_has_cross_domain_connection(cfg)) {
2479+
#if UARTE_CROSS_DOMAIN_PINS_HANDLE
2480+
int err;
2481+
2482+
err = nrf_sys_event_release_global_constlat();
2483+
(void)err;
2484+
__ASSERT_NO_MSG(err >= 0);
2485+
#else
2486+
__ASSERT(false, "NRF_SYS_EVENT needs to be enabled to use cross domain pins.\n");
2487+
#endif
2488+
}
2489+
#endif
24142490

24152491
nrf_uarte_disable(uarte);
24162492

@@ -2693,6 +2769,11 @@ static int uarte_instance_init(const struct device *dev,
26932769
.accuracy = 0, \
26942770
.precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT,\
26952771
},)) \
2772+
IF_ENABLED(UARTE_PINS_CROSS_DOMAIN(_, /*empty*/, idx, _), \
2773+
(.cross_domain = true, \
2774+
.default_port = \
2775+
DT_PROP_OR(DT_PHANDLE(UARTE(idx), \
2776+
default_gpio_port), port, -1),)) \
26962777
}; \
26972778
UARTE_DIRECT_ISR_DECLARE(idx) \
26982779
static int uarte_##idx##_init(const struct device *dev) \

dts/bindings/serial/nordic,nrf-uarte.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,13 @@ properties:
1414
type: boolean
1515
description: |
1616
UARTE has RX frame timeout HW feature.
17+
18+
default-gpio-port:
19+
type: phandle
20+
description: |
21+
UARTE default GPIO port.
22+
23+
cross-domain-pins-supported:
24+
type: boolean
25+
description: |
26+
UARTE allows usage of cross domain pins with constant latency mode required.

dts/vendor/nordic/nrf54l_05_10_15.dtsi

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,8 @@
322322
status = "disabled";
323323
endtx-stoptx-supported;
324324
frame-timeout-supported;
325+
default-gpio-port = <&gpio1>;
326+
cross-domain-pins-supported;
325327
};
326328

327329
i2c21: i2c@c7000 {
@@ -361,6 +363,8 @@
361363
status = "disabled";
362364
endtx-stoptx-supported;
363365
frame-timeout-supported;
366+
default-gpio-port = <&gpio1>;
367+
cross-domain-pins-supported;
364368
};
365369

366370
i2c22: i2c@c8000 {
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* SPDX-License-Identifier: Apache-2.0 */
2+
3+
&pinctrl {
4+
uart21_default: uart21_default {
5+
group1 {
6+
psels = <NRF_PSEL(UART_TX, 2, 8)>,
7+
<NRF_PSEL(UART_RX, 2, 7)>,
8+
<NRF_PSEL(UART_RTS, 2, 10)>,
9+
<NRF_PSEL(UART_CTS, 2, 9)>;
10+
};
11+
};
12+
13+
uart21_sleep: uart21_sleep {
14+
group1 {
15+
psels = <NRF_PSEL(UART_TX, 2, 8)>,
16+
<NRF_PSEL(UART_RX, 2, 7)>,
17+
<NRF_PSEL(UART_RTS, 2, 10)>,
18+
<NRF_PSEL(UART_CTS, 2, 9)>;
19+
low-power-enable;
20+
};
21+
};
22+
};
23+
24+
dut: &uart21 {
25+
status = "okay";
26+
current-speed = <115200>;
27+
pinctrl-0 = <&uart21_default>;
28+
pinctrl-1 = <&uart21_sleep>;
29+
pinctrl-names = "default", "sleep";
30+
hw-flow-control;
31+
};

tests/drivers/uart/uart_elementary/testcase.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,10 @@ tests:
107107
extra_configs:
108108
- CONFIG_DUAL_UART_TEST=y
109109
- CONFIG_SETUP_MISMATCH_TEST=y
110+
drivers.uart.uart_elementary_cross_domain:
111+
filter: CONFIG_SERIAL_SUPPORT_INTERRUPT
112+
platform_allow:
113+
- nrf54l15dk/nrf54l15/cpuapp
114+
extra_args: DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuapp_cross_domain.overlay"
115+
extra_configs:
116+
- CONFIG_NRF_SYS_EVENT=y

0 commit comments

Comments
 (0)