Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 0 additions & 16 deletions boards/arm/frdm_k22f/pinmux.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,6 @@ static int frdm_k22f_pinmux_init(const struct device *dev)
__ASSERT_NO_MSG(device_is_ready(porte));
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay) && CONFIG_SERIAL
#error "No UART0 is used"
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart1), okay) && CONFIG_SERIAL
/* UART1 RX, TX */
pinmux_pin_set(porte, 0, PORT_PCR_MUX(kPORT_MuxAlt3));
pinmux_pin_set(porte, 1, PORT_PCR_MUX(kPORT_MuxAlt3));
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart2), okay) && CONFIG_SERIAL
/* UART2 RX, TX */
pinmux_pin_set(portd, 2, PORT_PCR_MUX(kPORT_MuxAlt3));
pinmux_pin_set(portd, 3, PORT_PCR_MUX(kPORT_MuxAlt3));
#endif

#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ftm0), nxp_kinetis_ftm_pwm, okay) && CONFIG_PWM
/* Red, green, blue LEDs as PWM channels*/
pinmux_pin_set(porta, 1, PORT_PCR_MUX(kPORT_MuxAlt3));
Expand Down
20 changes: 0 additions & 20 deletions boards/arm/frdm_k64f/pinmux.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,6 @@ static int frdm_k64f_pinmux_init(const struct device *dev)
__ASSERT_NO_MSG(device_is_ready(porte));
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay) && CONFIG_SERIAL
/* UART0 RX, TX */
pinmux_pin_set(portb, 16, PORT_PCR_MUX(kPORT_MuxAlt3));
pinmux_pin_set(portb, 17, PORT_PCR_MUX(kPORT_MuxAlt3));
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart2), okay) && CONFIG_SERIAL
/* UART2 RX, TX */
pinmux_pin_set(portd, 0, PORT_PCR_MUX(kPORT_MuxAlt3));
pinmux_pin_set(portd, 1, PORT_PCR_MUX(kPORT_MuxAlt3));
pinmux_pin_set(portd, 2, PORT_PCR_MUX(kPORT_MuxAlt3));
pinmux_pin_set(portd, 3, PORT_PCR_MUX(kPORT_MuxAlt3));
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart3), okay) && CONFIG_SERIAL
/* UART3 RX, TX */
pinmux_pin_set(portc, 16, PORT_PCR_MUX(kPORT_MuxAlt3));
pinmux_pin_set(portc, 17, PORT_PCR_MUX(kPORT_MuxAlt3));
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi0), okay) && CONFIG_SPI
/* SPI0 CS0, SCK, SOUT, SIN */
pinmux_pin_set(portd, 0, PORT_PCR_MUX(kPORT_MuxAlt2));
Expand Down
6 changes: 0 additions & 6 deletions boards/arm/frdm_kl25z/pinmux.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,6 @@ static int frdm_kl25z_pinmux_init(const struct device *dev)
__ASSERT_NO_MSG(device_is_ready(porte));
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay) && CONFIG_SERIAL
/* UART0 RX, TX */
pinmux_pin_set(porta, 1, PORT_PCR_MUX(kPORT_MuxAlt2));
pinmux_pin_set(porta, 2, PORT_PCR_MUX(kPORT_MuxAlt2));
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c0), okay) && CONFIG_I2C
/* I2C0 SCL, SDA */
pinmux_pin_set(porte, 24, PORT_PCR_MUX(kPORT_MuxAlt5)
Expand Down
12 changes: 0 additions & 12 deletions boards/arm/hexiwear_k64/pinmux.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,6 @@ static int hexiwear_k64_pinmux_init(const struct device *dev)
| PORT_PCR_ODE_MASK);
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay) && CONFIG_SERIAL
/* UART0 RX, TX */
pinmux_pin_set(portb, 16, PORT_PCR_MUX(kPORT_MuxAlt3));
pinmux_pin_set(portb, 17, PORT_PCR_MUX(kPORT_MuxAlt3));
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart4), okay) && CONFIG_SERIAL
/* UART4 RX, TX - BLE */
pinmux_pin_set(porte, 24, PORT_PCR_MUX(kPORT_MuxAlt3));
pinmux_pin_set(porte, 25, PORT_PCR_MUX(kPORT_MuxAlt3));
#endif

#if defined(CONFIG_MAX30101) && DT_NODE_HAS_STATUS(DT_NODELABEL(gpioa), okay)
const struct device *gpioa =
device_get_binding(DT_LABEL(DT_NODELABEL(gpioa)));
Expand Down
27 changes: 27 additions & 0 deletions boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840-pinctrl.dtsi
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
&pinctrl {
/* UART0 */
uart0_default: uart0_default {
pincfg = <PINCTRL_NRF(0, 6, OUT, IDISC, PN, UART_TX)
PINCTRL_NRF(0, 8, INP, ICONN, PU, UART_RX)
PINCTRL_NRF(0, 5, OUT, IDISC, PN, UART_RTS)
PINCTRL_NRF(0, 7, INP, ICONN, PU, UART_CTS)>;
};

uart0_sleep: uart0_sleep {
pincfg = <PINCTRL_NRF(0, 6, INP, IDISC, PN, UART_TX)
PINCTRL_NRF(0, 8, INP, IDISC, PN, UART_RX)
PINCTRL_NRF(0, 5, INP, IDISC, PN, UART_RTS)
PINCTRL_NRF(0, 7, INP, IDISC, PN, UART_CTS)>;
};

/* UART1 */
uart1_default: uart1_default {
pincfg = <PINCTRL_NRF(1, 2, OUT, IDISC, PN, UART_TX)
PINCTRL_NRF(1, 1, INP, ICONN, PU, UART_RX)>;
};

uart1_sleep: uart1_sleep {
pincfg = <PINCTRL_NRF(1, 2, INP, IDISC, PN, UART_TX)
PINCTRL_NRF(1, 1, INP, IDISC, PN, UART_RX)>;
};
};
18 changes: 9 additions & 9 deletions boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

/dts-v1/;
#include <nordic/nrf52840_qiaa.dtsi>
#include "nrf52840dk_nrf52840-pinctrl.dtsi"

/ {
model = "Nordic nRF52840 DK NRF52840";
Expand Down Expand Up @@ -144,20 +145,19 @@
compatible = "nordic,nrf-uarte";
status = "okay";
current-speed = <115200>;
tx-pin = <6>;
rx-pin = <8>;
rx-pull-up;
rts-pin = <5>;
cts-pin = <7>;
cts-pull-up;

pinctrl-0 = <&uart0_default>;
pinctrl-1 = <&uart0_sleep>;
pinctrl-names = "default", "sleep";
};

arduino_serial: &uart1 {
status = "okay";
current-speed = <115200>;
rx-pin = <33>;
rx-pull-up;
tx-pin = <34>;

pinctrl-0 = <&uart1_default>;
pinctrl-1 = <&uart1_sleep>;
pinctrl-names = "default", "sleep";
};

arduino_i2c: &i2c0 {
Expand Down
2 changes: 2 additions & 0 deletions boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ CONFIG_UART_CONSOLE=y

# additional board options
CONFIG_GPIO_AS_PINRESET=y

CONFIG_PINCTRL=y
6 changes: 0 additions & 6 deletions boards/arm/twr_kv58f220m/pinmux.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,6 @@ static int twr_kv58f220m_pinmux_init(const struct device *dev)
| PORT_PCR_ODE_MASK);
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay) && CONFIG_SERIAL
/* UART0 RX, TX */
pinmux_pin_set(portb, 0, PORT_PCR_MUX(kPORT_MuxAlt7));
pinmux_pin_set(portb, 1, PORT_PCR_MUX(kPORT_MuxAlt7));
#endif

return 0;
}

Expand Down
6 changes: 0 additions & 6 deletions boards/arm/usb_kw24d512/pinmux.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,6 @@ static int usb_kw24d512_pinmux_init(const struct device *dev)
__ASSERT_NO_MSG(device_is_ready(porte));
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay) && CONFIG_SERIAL
/* UART0 RX, TX */
pinmux_pin_set(porta, 1, PORT_PCR_MUX(kPORT_MuxAlt2));
pinmux_pin_set(porta, 2, PORT_PCR_MUX(kPORT_MuxAlt2));
#endif

#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI
/* SPI1 CS0, SCK, SOUT, SIN */
pinmux_pin_set(portb, 10, PORT_PCR_MUX(kPORT_MuxAlt2));
Expand Down
1 change: 1 addition & 0 deletions drivers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ add_subdirectory_ifdef(CONFIG_IPM ipm)
add_subdirectory_ifdef(CONFIG_LED led)
add_subdirectory_ifdef(CONFIG_LED_STRIP led_strip)
add_subdirectory_ifdef(CONFIG_MODEM modem)
add_subdirectory_ifdef(CONFIG_PINCTRL pinctrl)
add_subdirectory_ifdef(CONFIG_PINMUX pinmux)
add_subdirectory_ifdef(CONFIG_PWM pwm)
add_subdirectory_ifdef(CONFIG_SENSOR sensor)
Expand Down
2 changes: 2 additions & 0 deletions drivers/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ source "drivers/i2s/Kconfig"

source "drivers/pwm/Kconfig"

source "drivers/pinctrl/Kconfig"

source "drivers/pinmux/Kconfig"

source "drivers/adc/Kconfig"
Expand Down
6 changes: 6 additions & 0 deletions drivers/pinctrl/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: Apache-2.0

zephyr_sources_ifdef(CONFIG_USERSPACE pinctrl_handlers.c)

zephyr_sources_ifdef(CONFIG_PINCTRL_SAM pinctrl_sam.c)
zephyr_library_sources_ifdef(CONFIG_PINCTRL_NRF pinctrl_nrf.c)
21 changes: 21 additions & 0 deletions drivers/pinctrl/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# pinctrl configuration options

# Copyright (c) 2021 Piotr Mienkowski
# SPDX-License-Identifier: Apache-2.0

menuconfig PINCTRL
bool "Pin Controller driver"
help
Enable pinctrl driver.

if PINCTRL

config PINCTRL_SAM
def_bool y
depends on SOC_FAMILY_SAM
help
Enable Atmel SAM pinctrl driver.

source "drivers/pinctrl/Kconfig.nrf"

endif # PINCTRL
9 changes: 9 additions & 0 deletions drivers/pinctrl/Kconfig.nrf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2021 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0

config PINCTRL_NRF
bool "nRF pin controller driver"
depends on SOC_FAMILY_NRF
default y
help
nRF pin controller driver
16 changes: 16 additions & 0 deletions drivers/pinctrl/pinctrl_handlers.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2021 Piotr Mienkowski
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <syscall_handler.h>
#include <drivers/pinctrl.h>

int z_vrfy_pinctrl_pin_configure(const pinctrl_soc_pins_t *pin_spec)
{
Z_SYSCALL_MEMORY_READ(pin_spec, sizeof(pinctrl_soc_pins_t));

return z_impl_pinctrl_pin_configure(pin_spec);
}
#include <syscalls/pinctrl_pin_configure_mrsh.c>
83 changes: 83 additions & 0 deletions drivers/pinctrl/pinctrl_nrf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2021 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <drivers/pinctrl.h>

#include <hal/nrf_gpio.h>
#if CONFIG_NRF_UARTE_PERIPHERAL
#include <hal/nrf_uarte.h>
#endif

#if 0 && CONFIG_NRF_UARTE_PERIPHERAL
static void pinctrl_nrf_uarte_config(NRF_UARTE_Type *uarte,
const uint32_t *pincfgs,
size_t pincfgs_cnt)
{
uint32_t pseltxd = NRF_UARTE_PSEL_DISCONNECTED;
uint32_t pselrxd = NRF_UARTE_PSEL_DISCONNECTED;
uint32_t pselrts = NRF_UARTE_PSEL_DISCONNECTED;
uint32_t pselcts = NRF_UARTE_PSEL_DISCONNECTED;

for (size_t i = 0U; i < pincfgs_cnt; i++) {
switch (PINCTRL_NRF_GET_FUN(pincfgs[i])) {
case PINCTRL_NRF_FUN_UART_TX:
pseltxd = PINCTRL_NRF_GET_PIN(pincfgs[i]);
break;
case PINCTRL_NRF_FUN_UART_RX:
pselrxd = PINCTRL_NRF_GET_PIN(pincfgs[i]);
break;
case PINCTRL_NRF_FUN_UART_RTS:
pselrts = PINCTRL_NRF_GET_PIN(pincfgs[i]);
break;
case PINCTRL_NRF_FUN_UART_CTS:
pselcts = PINCTRL_NRF_GET_PIN(pincfgs[i]);
break;
default:
break;
}
}

nrf_uarte_txrx_pins_set(uarte, pseltxd, pselrxd);
nrf_uarte_hwfc_pins_set(uarte, pselrts, pselcts);

nrf_gpio_pin_write(pseltxd, 1);
}
#endif

int z_impl_pinctrl_pin_configure(const pinctrl_soc_pins_t *pin_spec)
Copy link
Member

@gmarull gmarull Sep 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the case of Nordic (see pinctrl->reg) and STM32F1 (see uint32_t base) the pinctrl_soc_pins_t will not be enough to configure a pin, since knowledge about the peripheral is also required. In case of Nordic, doing the configuration at once per peripheral is more efficient (due to the required "switch/case"). In case of STM32F1 I'm not sure if it would be possible, @erwango ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the case of Nordic (see pinctrl->reg) and STM32F1 (see uint32_t base) the pinctrl_soc_pins_t will not be enough to configure a pin, since knowledge about the peripheral is also required.

True. Thanks for raising it.

In case of Nordic, doing the configuration at once per peripheral is more efficient (due to the required "switch/case"). In case of STM32F1 I'm not sure if it would be possible, @erwango ?

Configuring all pins at once (using an array) would also save some operations in F1 case

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

than whatever reg is needed should be placed in pinctrl_soc_pins_t

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reg is not per-pin, but per pin set. pinctrl_pin_configure configures a single pin.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I follow that comment. If the reg varies between 2 pins than its effectively per-pin.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reg does not vary between 2 pins of the same peripheral.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For F1 case (and NRF as I understand) peripheral reg is required for proper pin configuration.
As a consequence, all pins configured for a peripheral have same reg value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gotcha. So I think we should add void * for user_data. Suggestions on what to call it user_data doesn't seem right.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reg does not vary between 2 pins of the same peripheral.

Understood, how will this work for the runtime case? The user will end having to know what "reg" value to pass?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated #37572 with a PoC (including other changes)

{
#if 0
/* configure peripheral pin selection */
switch (dev->pinctrl->reg) {
#if CONFIG_NRF_UARTE_PERIPHERAL
#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay)
case DT_REG_ADDR(DT_NODELABEL(uart0)):
#endif
#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart1), okay)
case DT_REG_ADDR(DT_NODELABEL(uart1)):
#endif
pinctrl_nrf_uarte_config((NRF_UARTE_Type *)dev->pinctrl->reg,
state->pincfgs,
state->pincfgs_cnt);
break;
#endif
default:
return -ENOTSUP;
}

/* configure pins GPIO settings */
for (size_t i = 0U; i < state->pincfgs_cnt; i++) {
nrf_gpio_cfg(PINCTRL_NRF_GET_PIN(state->pincfgs[i]),
PINCTRL_NRF_GET_DIR(state->pincfgs[i]),
PINCTRL_NRF_GET_INP(state->pincfgs[i]),
PINCTRL_NRF_GET_PULL(state->pincfgs[i]),
NRF_GPIO_PIN_S0S1,
NRF_GPIO_PIN_NOSENSE);
}
#endif

return 0;
}
15 changes: 15 additions & 0 deletions drivers/pinctrl/pinctrl_sam.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2021 Piotr Mienkowski
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <drivers/pinctrl.h>
#include <soc.h>

int z_impl_pinctrl_pin_configure(const pinctrl_soc_pins_t *pin_spec)
{
soc_gpio_configure((const struct soc_gpio_pin *)pin_spec);

return 0;
}
8 changes: 8 additions & 0 deletions drivers/pinmux/pinmux_mcux.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <errno.h>
#include <device.h>
#include <drivers/pinmux.h>
#include <drivers/pinctrl.h>
#include <fsl_common.h>
#include <fsl_clock.h>

Expand All @@ -17,6 +18,13 @@ struct pinmux_mcux_config {
PORT_Type *base;
};

int z_impl_pinctrl_pin_configure(const pinctrl_soc_pins_t *pin_spec)
{
pinmux_pin_set(pin_spec->port, pin_spec->pin, PORT_PCR_MUX(pin_spec->mux));

return 0;
}

static int pinmux_mcux_set(const struct device *dev, uint32_t pin,
uint32_t func)
{
Expand Down
1 change: 1 addition & 0 deletions drivers/serial/Kconfig.usart_sam
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ config USART_SAM
depends on SOC_FAMILY_SAM
select SERIAL_HAS_DRIVER
select SERIAL_SUPPORT_INTERRUPT
select PINCTRL
help
This option enables the USARTx driver for Atmel SAM MCUs.
Loading