Skip to content

Commit cee404d

Browse files
mstasiaknordicnordicjm
authored andcommitted
[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 6736396 commit cee404d

File tree

5 files changed

+136
-0
lines changed

5 files changed

+136
-0
lines changed

drivers/serial/uart_nrfx_uarte.c

Lines changed: 82 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,32 @@ 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 ((pin != NRF_PIN_DISCONNECTED) &&
489+
(nrf_gpio_pin_port_number_extract(&pin) != config->default_port)) {
490+
return true;
491+
}
492+
}
493+
494+
return false;
495+
}
496+
#endif
497+
447498
#if defined(UARTE_ANY_NONE_ASYNC) && !defined(CONFIG_UART_NRFX_UARTE_NO_IRQ)
448499
/**
449500
* @brief Interrupt service routine.
@@ -727,6 +778,19 @@ static void uarte_periph_enable(const struct device *dev)
727778
#ifdef CONFIG_SOC_NRF54H20_GPD
728779
nrf_gpd_retain_pins_set(config->pcfg, false);
729780
#endif
781+
#if UARTE_CROSS_DOMAIN_PINS_SUPPORTED
782+
if (config->cross_domain && uarte_has_cross_domain_connection(config)) {
783+
#if UARTE_CROSS_DOMAIN_PINS_HANDLE
784+
int err;
785+
786+
err = nrf_sys_event_request_global_constlat();
787+
(void)err;
788+
__ASSERT_NO_MSG(err >= 0);
789+
#else
790+
__ASSERT(false, "NRF_SYS_EVENT needs to be enabled to use cross domain pins.\n");
791+
#endif
792+
}
793+
#endif
730794
#if UARTE_BAUDRATE_RETENTION_WORKAROUND
731795
nrf_uarte_baudrate_set(uarte,
732796
COND_CODE_1(CONFIG_UART_USE_RUNTIME_CONFIGURE,
@@ -2411,6 +2475,19 @@ static void uarte_pm_suspend(const struct device *dev)
24112475
#ifdef CONFIG_SOC_NRF54H20_GPD
24122476
nrf_gpd_retain_pins_set(cfg->pcfg, true);
24132477
#endif
2478+
#if UARTE_CROSS_DOMAIN_PINS_SUPPORTED
2479+
if (cfg->cross_domain && uarte_has_cross_domain_connection(cfg)) {
2480+
#if UARTE_CROSS_DOMAIN_PINS_HANDLE
2481+
int err;
2482+
2483+
err = nrf_sys_event_release_global_constlat();
2484+
(void)err;
2485+
__ASSERT_NO_MSG(err >= 0);
2486+
#else
2487+
__ASSERT(false, "NRF_SYS_EVENT needs to be enabled to use cross domain pins.\n");
2488+
#endif
2489+
}
2490+
#endif
24142491

24152492
nrf_uarte_disable(uarte);
24162493

@@ -2698,6 +2775,11 @@ static int uarte_instance_init(const struct device *dev,
26982775
.accuracy = 0, \
26992776
.precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT,\
27002777
},)) \
2778+
IF_ENABLED(UARTE_PINS_CROSS_DOMAIN(_, /*empty*/, idx, _), \
2779+
(.cross_domain = true, \
2780+
.default_port = \
2781+
DT_PROP_OR(DT_PHANDLE(UARTE(idx), \
2782+
default_gpio_port), port, -1),)) \
27012783
}; \
27022784
UARTE_DIRECT_ISR_DECLARE(idx) \
27032785
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: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,12 @@ tests:
9797
extra_configs:
9898
- CONFIG_DUAL_UART_TEST=y
9999
- CONFIG_SETUP_MISMATCH_TEST=y
100+
drivers.uart.uart_elementary_cross_domain:
101+
filter: CONFIG_SERIAL_SUPPORT_INTERRUPT
102+
harness_config:
103+
fixture: uart_p1_p2_loopback
104+
platform_allow:
105+
- nrf54l15dk/nrf54l15/cpuapp
106+
extra_args: DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuapp_cross_domain.overlay"
107+
extra_configs:
108+
- CONFIG_NRF_SYS_EVENT=y

0 commit comments

Comments
 (0)