Skip to content

Commit f1d1913

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 67d880f commit f1d1913

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
@@ -136,6 +136,27 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME));
136136
*/
137137
#define UARTE_ANY_HIGH_SPEED (UARTE_FOR_EACH_INSTANCE(INSTANCE_IS_HIGH_SPEED, (||), (0)))
138138

139+
#define UARTE_PINS_CROSS_DOMAIN(unused, prefix, idx, _) \
140+
COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(UARTE(prefix##idx)), \
141+
(UARTE_PROP(idx, cross_domain_pins_supported)), \
142+
(0))
143+
144+
#if UARTE_FOR_EACH_INSTANCE(UARTE_PINS_CROSS_DOMAIN, (||), (0))
145+
#include <hal/nrf_gpio.h>
146+
/* Certain UARTE instances support usage of cross domain pins in form of dedicated pins on
147+
* a port different from the default one.
148+
*/
149+
#define UARTE_CROSS_DOMAIN_PINS_SUPPORTED 1
150+
#endif
151+
152+
#if UARTE_CROSS_DOMAIN_PINS_SUPPORTED && defined(CONFIG_NRF_SYS_EVENT)
153+
#include <nrf_sys_event.h>
154+
/* To use cross domain pins, constant latency mode needs to be applied, which is
155+
* handled via nrf_sys_event requests.
156+
*/
157+
#define UARTE_CROSS_DOMAIN_PINS_HANDLE 1
158+
#endif
159+
139160
#ifdef UARTE_ANY_CACHE
140161
/* uart120 instance does not retain BAUDRATE register when ENABLE=0. When this instance
141162
* is used then baudrate must be set after enabling the peripheral and not before.
@@ -357,6 +378,10 @@ struct uarte_nrfx_config {
357378
#endif
358379
uint8_t *poll_out_byte;
359380
uint8_t *poll_in_byte;
381+
#if UARTE_CROSS_DOMAIN_PINS_SUPPORTED
382+
bool cross_domain;
383+
int8_t default_port;
384+
#endif
360385
};
361386

362387
/* Using Macro instead of static inline function to handle NO_OPTIMIZATIONS case
@@ -430,6 +455,31 @@ static void uarte_disable_locked(const struct device *dev, uint32_t dis_mask)
430455
nrf_uarte_disable(get_uarte_instance(dev));
431456
}
432457

458+
#if UARTE_CROSS_DOMAIN_PINS_SUPPORTED
459+
static bool uarte_has_cross_domain_connection(const struct uarte_nrfx_config *config)
460+
{
461+
const struct pinctrl_dev_config *pcfg = config->pcfg;
462+
const struct pinctrl_state *state;
463+
int ret;
464+
465+
ret = pinctrl_lookup_state(pcfg, PINCTRL_STATE_DEFAULT, &state);
466+
if (ret < 0) {
467+
LOG_ERR("Unable to read pin state");
468+
return false;
469+
}
470+
471+
for (uint8_t i = 0U; i < state->pin_cnt; i++) {
472+
uint32_t pin = NRF_GET_PIN(state->pins[i]);
473+
474+
if (nrf_gpio_pin_port_number_extract(&pin) != config->default_port) {
475+
return true;
476+
}
477+
}
478+
479+
return false;
480+
}
481+
#endif
482+
433483
#if defined(UARTE_ANY_NONE_ASYNC) && !defined(CONFIG_UART_NRFX_UARTE_NO_IRQ)
434484
/**
435485
* @brief Interrupt service routine.
@@ -713,6 +763,19 @@ static void uarte_periph_enable(const struct device *dev)
713763
#ifdef CONFIG_SOC_NRF54H20_GPD
714764
nrf_gpd_retain_pins_set(config->pcfg, false);
715765
#endif
766+
#if UARTE_CROSS_DOMAIN_PINS_SUPPORTED
767+
if (config->cross_domain && uarte_has_cross_domain_connection(config)) {
768+
#if UARTE_CROSS_DOMAIN_PINS_HANDLE
769+
int err;
770+
771+
err = nrf_sys_event_request_global_constlat();
772+
(void)err;
773+
__ASSERT_NO_MSG(err >= 0);
774+
#else
775+
__ASSERT(false, "NRF_SYS_EVENT needs to be enabled to use cross domain pins.\n");
776+
#endif
777+
}
778+
#endif
716779
#if UARTE_BAUDRATE_RETENTION_WORKAROUND
717780
nrf_uarte_baudrate_set(uarte,
718781
COND_CODE_1(CONFIG_UART_USE_RUNTIME_CONFIGURE,
@@ -2367,6 +2430,19 @@ static void uarte_pm_suspend(const struct device *dev)
23672430
#ifdef CONFIG_SOC_NRF54H20_GPD
23682431
nrf_gpd_retain_pins_set(cfg->pcfg, true);
23692432
#endif
2433+
#if UARTE_CROSS_DOMAIN_PINS_SUPPORTED
2434+
if (cfg->cross_domain && uarte_has_cross_domain_connection(cfg)) {
2435+
#if UARTE_CROSS_DOMAIN_PINS_HANDLE
2436+
int err;
2437+
2438+
err = nrf_sys_event_release_global_constlat();
2439+
(void)err;
2440+
__ASSERT_NO_MSG(err >= 0);
2441+
#else
2442+
__ASSERT(false, "NRF_SYS_EVENT needs to be enabled to use cross domain pins.\n");
2443+
#endif
2444+
}
2445+
#endif
23702446

23712447
nrf_uarte_disable(uarte);
23722448

@@ -2649,6 +2725,11 @@ static int uarte_instance_init(const struct device *dev,
26492725
.accuracy = 0, \
26502726
.precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT,\
26512727
},)) \
2728+
IF_ENABLED(UARTE_PINS_CROSS_DOMAIN(_, /*empty*/, idx, _), \
2729+
(.cross_domain = true, \
2730+
.default_port = \
2731+
DT_PROP_OR(DT_PHANDLE(UARTE(idx), \
2732+
default_gpio_port), port, -1),)) \
26522733
}; \
26532734
UARTE_DIRECT_ISR_DECLARE(idx) \
26542735
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/common/nordic/nrf54l_05_10_15.dtsi

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

326328
i2c21: i2c@c7000 {
@@ -360,6 +362,8 @@
360362
status = "disabled";
361363
endtx-stoptx-supported;
362364
frame-timeout-supported;
365+
default-gpio-port = <&gpio1>;
366+
cross-domain-pins-supported;
363367
};
364368

365369
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)