2016-03-03 15:33:15 +01:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2016 Open-RnD Sp. z o.o.
|
|
|
|
*
|
2017-01-18 17:01:01 -08:00
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
2016-03-03 15:33:15 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief
|
|
|
|
*
|
|
|
|
* A common driver for STM32 pinmux. Each SoC must implement a SoC
|
|
|
|
* specific part of the driver.
|
|
|
|
*/
|
|
|
|
|
2016-04-26 18:20:17 -03:00
|
|
|
#include <errno.h>
|
|
|
|
|
2016-12-04 14:59:37 -06:00
|
|
|
#include <kernel.h>
|
2016-03-03 15:33:15 +01:00
|
|
|
#include <device.h>
|
|
|
|
#include <soc.h>
|
2020-11-20 16:41:20 +01:00
|
|
|
#include <stm32_ll_bus.h>
|
|
|
|
#include <stm32_ll_gpio.h>
|
2019-06-25 15:53:57 -04:00
|
|
|
#include <drivers/pinmux.h>
|
2016-03-21 17:14:15 -03:00
|
|
|
#include <gpio/gpio_stm32.h>
|
2020-01-25 05:34:53 -06:00
|
|
|
#include <drivers/clock_control/stm32_clock_control.h>
|
2016-03-21 17:14:15 -03:00
|
|
|
#include <pinmux/stm32/pinmux_stm32.h>
|
2016-03-03 15:33:15 +01:00
|
|
|
|
2019-04-12 15:25:41 +02:00
|
|
|
#ifdef CONFIG_SOC_SERIES_STM32MP1X
|
|
|
|
#define GPIO_REG_SIZE 0x1000
|
|
|
|
/* 0x1000 between each port, 0x400 gpio registry 0xC00 reserved */
|
|
|
|
#else
|
2019-01-14 09:37:20 +01:00
|
|
|
#define GPIO_REG_SIZE 0x400
|
2019-04-12 15:25:41 +02:00
|
|
|
#endif /* CONFIG_SOC_SERIES_STM32MP1X */
|
2019-01-14 09:37:20 +01:00
|
|
|
/* base address for where GPIO registers start */
|
|
|
|
#define GPIO_PORTS_BASE (GPIOA_BASE)
|
|
|
|
|
2020-05-27 11:26:57 -05:00
|
|
|
static const uint32_t ports_enable[STM32_PORTS_MAX] = {
|
2017-01-23 17:54:57 +01:00
|
|
|
STM32_PERIPH_GPIOA,
|
|
|
|
STM32_PERIPH_GPIOB,
|
|
|
|
STM32_PERIPH_GPIOC,
|
2017-04-28 15:02:03 +02:00
|
|
|
#ifdef GPIOD_BASE
|
2017-01-23 17:54:57 +01:00
|
|
|
STM32_PERIPH_GPIOD,
|
2018-07-31 15:49:17 +02:00
|
|
|
#else
|
|
|
|
STM32_PORT_NOT_AVAILABLE,
|
2017-04-28 15:02:03 +02:00
|
|
|
#endif
|
2017-01-23 17:54:57 +01:00
|
|
|
#ifdef GPIOE_BASE
|
|
|
|
STM32_PERIPH_GPIOE,
|
2018-07-31 15:49:17 +02:00
|
|
|
#else
|
|
|
|
STM32_PORT_NOT_AVAILABLE,
|
2017-01-23 17:54:57 +01:00
|
|
|
#endif
|
|
|
|
#ifdef GPIOF_BASE
|
|
|
|
STM32_PERIPH_GPIOF,
|
2018-07-31 15:49:17 +02:00
|
|
|
#else
|
|
|
|
STM32_PORT_NOT_AVAILABLE,
|
2017-01-23 17:54:57 +01:00
|
|
|
#endif
|
|
|
|
#ifdef GPIOG_BASE
|
|
|
|
STM32_PERIPH_GPIOG,
|
2018-07-31 15:49:17 +02:00
|
|
|
#else
|
|
|
|
STM32_PORT_NOT_AVAILABLE,
|
2017-01-23 17:54:57 +01:00
|
|
|
#endif
|
|
|
|
#ifdef GPIOH_BASE
|
|
|
|
STM32_PERIPH_GPIOH,
|
2018-07-31 15:49:17 +02:00
|
|
|
#else
|
|
|
|
STM32_PORT_NOT_AVAILABLE,
|
2017-01-23 17:54:57 +01:00
|
|
|
#endif
|
2018-12-05 09:26:43 +01:00
|
|
|
#ifdef GPIOI_BASE
|
|
|
|
STM32_PERIPH_GPIOI,
|
|
|
|
#else
|
|
|
|
STM32_PORT_NOT_AVAILABLE,
|
|
|
|
#endif
|
|
|
|
#ifdef GPIOJ_BASE
|
|
|
|
STM32_PERIPH_GPIOJ,
|
|
|
|
#else
|
|
|
|
STM32_PORT_NOT_AVAILABLE,
|
|
|
|
#endif
|
|
|
|
#ifdef GPIOK_BASE
|
|
|
|
STM32_PERIPH_GPIOK,
|
|
|
|
#else
|
|
|
|
STM32_PORT_NOT_AVAILABLE,
|
|
|
|
#endif
|
2017-01-23 17:54:57 +01:00
|
|
|
};
|
2016-08-10 18:28:32 -03:00
|
|
|
|
2016-03-03 15:33:15 +01:00
|
|
|
/**
|
|
|
|
* @brief enable IO port clock
|
|
|
|
*
|
|
|
|
* @param port I/O port ID
|
|
|
|
* @param clk optional clock device
|
|
|
|
*
|
|
|
|
* @return 0 on success, error otherwise
|
|
|
|
*/
|
2020-04-30 20:33:38 +02:00
|
|
|
static int enable_port(uint32_t port, const struct device *clk)
|
2016-03-03 15:33:15 +01:00
|
|
|
{
|
|
|
|
/* enable port clock */
|
|
|
|
if (!clk) {
|
2021-02-11 11:49:24 -06:00
|
|
|
clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
|
2016-03-03 15:33:15 +01:00
|
|
|
}
|
|
|
|
|
2017-01-23 17:54:57 +01:00
|
|
|
struct stm32_pclken pclken;
|
2016-08-10 18:28:32 -03:00
|
|
|
|
2017-01-23 17:54:57 +01:00
|
|
|
pclken.bus = STM32_CLOCK_BUS_GPIO;
|
2016-08-10 18:28:32 -03:00
|
|
|
pclken.enr = ports_enable[port];
|
|
|
|
|
2018-07-31 15:49:17 +02:00
|
|
|
if (pclken.enr == STM32_PORT_NOT_AVAILABLE) {
|
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
|
2016-08-10 18:28:32 -03:00
|
|
|
return clock_control_on(clk, (clock_control_subsys_t *) &pclken);
|
2016-03-03 15:33:15 +01:00
|
|
|
}
|
|
|
|
|
2020-06-04 15:48:48 +02:00
|
|
|
static int stm32_pin_configure(uint32_t pin, uint32_t func, uint32_t altf)
|
2016-03-21 17:14:15 -03:00
|
|
|
{
|
|
|
|
/* determine IO port registers location */
|
2020-05-27 11:26:57 -05:00
|
|
|
uint32_t offset = STM32_PORT(pin) * GPIO_REG_SIZE;
|
|
|
|
uint8_t *port_base = (uint8_t *)(GPIO_PORTS_BASE + offset);
|
2016-03-21 17:14:15 -03:00
|
|
|
|
|
|
|
/* not much here, on STM32F10x the alternate function is
|
|
|
|
* controller by setting up GPIO pins in specific mode.
|
|
|
|
*/
|
2020-05-27 11:26:57 -05:00
|
|
|
return gpio_stm32_configure((uint32_t *)port_base,
|
2016-08-11 04:17:29 -03:00
|
|
|
STM32_PIN(pin), func, altf);
|
2016-03-21 17:14:15 -03:00
|
|
|
}
|
|
|
|
|
2020-06-05 10:55:20 +02:00
|
|
|
/**
|
|
|
|
* @brief helper for converting dt stm32 pinctrl format to existing pin config
|
|
|
|
* format
|
|
|
|
*
|
|
|
|
* @param *pinctrl pointer to soc_gpio_pinctrl list
|
|
|
|
* @param list_size list size
|
2020-10-16 17:20:00 +02:00
|
|
|
* @param base device base register value
|
|
|
|
*
|
|
|
|
* @return 0 on success, -EINVAL otherwise
|
2020-06-05 10:55:20 +02:00
|
|
|
*/
|
2020-10-16 17:20:00 +02:00
|
|
|
int stm32_dt_pinctrl_configure(const struct soc_gpio_pinctrl *pinctrl,
|
|
|
|
size_t list_size, uint32_t base)
|
2020-06-05 10:55:20 +02:00
|
|
|
{
|
|
|
|
const struct device *clk;
|
|
|
|
uint32_t pin, mux;
|
|
|
|
uint32_t func = 0;
|
|
|
|
|
2020-10-16 17:20:00 +02:00
|
|
|
if (!list_size) {
|
|
|
|
/* Empty pinctrl. Exit */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_pinctrl)
|
2020-10-20 22:30:07 +02:00
|
|
|
if (stm32_dt_pinctrl_remap(pinctrl, list_size, base)) {
|
2020-10-16 17:20:00 +02:00
|
|
|
/* Wrong remap config. Exit */
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
ARG_UNUSED(base);
|
|
|
|
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_pinctrl) */
|
|
|
|
|
2020-06-05 10:55:20 +02:00
|
|
|
/* make sure to enable port clock first */
|
2021-02-11 11:49:24 -06:00
|
|
|
clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
|
2020-06-05 10:55:20 +02:00
|
|
|
|
|
|
|
for (int i = 0; i < list_size; i++) {
|
|
|
|
mux = pinctrl[i].pinmux;
|
|
|
|
|
2020-08-12 13:26:06 +02:00
|
|
|
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_pinctrl)
|
|
|
|
uint32_t pupd;
|
|
|
|
|
|
|
|
if (STM32_DT_PINMUX_FUNC(mux) == ALTERNATE) {
|
|
|
|
func = pinctrl[i].pincfg | STM32_MODE_OUTPUT |
|
|
|
|
STM32_CNF_ALT_FUNC;
|
|
|
|
} else if (STM32_DT_PINMUX_FUNC(mux) == ANALOG) {
|
|
|
|
func = pinctrl[i].pincfg | STM32_MODE_INPUT |
|
|
|
|
STM32_CNF_IN_ANALOG;
|
|
|
|
} else if (STM32_DT_PINMUX_FUNC(mux) == GPIO_IN) {
|
|
|
|
func = pinctrl[i].pincfg | STM32_MODE_INPUT;
|
|
|
|
pupd = func & (STM32_PUPD_MASK << STM32_PUPD_SHIFT);
|
|
|
|
if (pupd == STM32_PUPD_NO_PULL) {
|
|
|
|
func = func | STM32_CNF_IN_FLOAT;
|
|
|
|
} else {
|
|
|
|
func = func | STM32_CNF_IN_PUPD;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* Not supported */
|
|
|
|
__ASSERT_NO_MSG(STM32_DT_PINMUX_FUNC(mux));
|
|
|
|
}
|
|
|
|
#else
|
2020-06-05 10:55:20 +02:00
|
|
|
if (STM32_DT_PINMUX_FUNC(mux) < ANALOG) {
|
|
|
|
func = pinctrl[i].pincfg | STM32_MODER_ALT_MODE;
|
|
|
|
} else if (STM32_DT_PINMUX_FUNC(mux) == ANALOG) {
|
|
|
|
func = STM32_MODER_ANALOG_MODE;
|
|
|
|
} else {
|
|
|
|
/* Not supported */
|
|
|
|
__ASSERT_NO_MSG(STM32_DT_PINMUX_FUNC(mux));
|
|
|
|
}
|
2020-08-12 13:26:06 +02:00
|
|
|
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_pinctrl) */
|
2020-06-05 10:55:20 +02:00
|
|
|
|
|
|
|
pin = STM32PIN(STM32_DT_PINMUX_PORT(mux),
|
|
|
|
STM32_DT_PINMUX_LINE(mux));
|
|
|
|
|
|
|
|
enable_port(STM32_PORT(pin), clk);
|
|
|
|
|
|
|
|
stm32_pin_configure(pin, func, STM32_DT_PINMUX_FUNC(mux));
|
|
|
|
}
|
2020-08-12 13:26:06 +02:00
|
|
|
|
2020-10-16 17:20:00 +02:00
|
|
|
return 0;
|
2020-08-12 13:26:06 +02:00
|
|
|
}
|
|
|
|
|
2020-10-16 17:20:00 +02:00
|
|
|
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_pinctrl)
|
2020-08-12 13:26:06 +02:00
|
|
|
/**
|
2020-10-16 17:20:00 +02:00
|
|
|
* @brief Helper function to check and apply provided pinctrl remap
|
|
|
|
* configuration
|
|
|
|
*
|
|
|
|
* Check operation verifies that pin remapping configuration is the same on all
|
|
|
|
* pins. If configuration is valid AFIO clock is enabled and remap is applied
|
2020-08-12 13:26:06 +02:00
|
|
|
*
|
|
|
|
* @param *pinctrl pointer to soc_gpio_pinctrl list
|
|
|
|
* @param list_size list size
|
2020-10-16 17:20:00 +02:00
|
|
|
* @param base device base register value
|
2020-08-12 13:26:06 +02:00
|
|
|
*
|
2020-10-16 17:20:00 +02:00
|
|
|
* @return 0 on success, -EINVAL otherwise
|
2020-08-12 13:26:06 +02:00
|
|
|
*/
|
2020-10-16 17:20:00 +02:00
|
|
|
int stm32_dt_pinctrl_remap(const struct soc_gpio_pinctrl *pinctrl,
|
|
|
|
size_t list_size, uint32_t base)
|
2020-08-12 13:26:06 +02:00
|
|
|
{
|
|
|
|
int remap;
|
|
|
|
uint32_t mux;
|
|
|
|
|
|
|
|
remap = STM32_DT_PINMUX_REMAP(pinctrl[0].pinmux);
|
|
|
|
|
|
|
|
for (int i = 1; i < list_size; i++) {
|
|
|
|
mux = pinctrl[i].pinmux;
|
|
|
|
remap = STM32_DT_PINMUX_REMAP(mux);
|
|
|
|
|
|
|
|
if (STM32_DT_PINMUX_REMAP(mux) != remap) {
|
2020-10-16 17:20:00 +02:00
|
|
|
return -EINVAL;
|
2020-08-12 13:26:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-16 17:20:00 +02:00
|
|
|
/* A valid remapping configuration is available */
|
2020-10-13 16:44:13 +02:00
|
|
|
/* Apply remapping before proceeding with pin configuration */
|
|
|
|
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_AFIO);
|
|
|
|
|
|
|
|
switch (base) {
|
2020-10-19 12:20:45 +02:00
|
|
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(can1), okay)
|
2020-10-13 16:44:13 +02:00
|
|
|
case DT_REG_ADDR(DT_NODELABEL(can1)):
|
|
|
|
if (remap == REMAP_1) {
|
|
|
|
/* PB8/PB9 */
|
|
|
|
LL_GPIO_AF_RemapPartial2_CAN1();
|
|
|
|
} else if (remap == REMAP_2) {
|
|
|
|
/* PD0/PD1 */
|
|
|
|
LL_GPIO_AF_RemapPartial3_CAN1();
|
|
|
|
} else {
|
|
|
|
/* NO_REMAP: PA11/PA12 */
|
|
|
|
LL_GPIO_AF_RemapPartial1_CAN1();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
2020-10-19 12:20:45 +02:00
|
|
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(can2), okay)
|
2020-10-13 16:44:13 +02:00
|
|
|
case DT_REG_ADDR(DT_NODELABEL(can2)):
|
|
|
|
if (remap == REMAP_1) {
|
|
|
|
/* PB5/PB6 */
|
|
|
|
LL_GPIO_AF_EnableRemap_CAN2();
|
|
|
|
} else {
|
|
|
|
/* PB12/PB13 */
|
|
|
|
LL_GPIO_AF_DisableRemap_CAN2();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay)
|
|
|
|
case DT_REG_ADDR(DT_NODELABEL(i2c1)):
|
|
|
|
if (remap == REMAP_1) {
|
|
|
|
LL_GPIO_AF_EnableRemap_I2C1();
|
|
|
|
} else {
|
|
|
|
LL_GPIO_AF_DisableRemap_I2C1();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers1), okay)
|
|
|
|
case DT_REG_ADDR(DT_NODELABEL(timers1)):
|
|
|
|
if (remap == REMAP_1) {
|
|
|
|
LL_GPIO_AF_RemapPartial_TIM1();
|
2020-10-19 12:28:29 +02:00
|
|
|
} else if (remap == REMAP_2) {
|
2020-10-13 16:44:13 +02:00
|
|
|
LL_GPIO_AF_EnableRemap_TIM1();
|
|
|
|
} else {
|
|
|
|
LL_GPIO_AF_DisableRemap_TIM1();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers2), okay)
|
|
|
|
case DT_REG_ADDR(DT_NODELABEL(timers2)):
|
|
|
|
if (remap == REMAP_1) {
|
|
|
|
LL_GPIO_AF_RemapPartial1_TIM2();
|
|
|
|
} else if (remap == REMAP_2) {
|
|
|
|
LL_GPIO_AF_RemapPartial2_TIM2();
|
|
|
|
} else if (remap == REMAP_FULL) {
|
|
|
|
LL_GPIO_AF_EnableRemap_TIM2();
|
|
|
|
} else {
|
|
|
|
LL_GPIO_AF_DisableRemap_TIM2();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers3), okay)
|
|
|
|
case DT_REG_ADDR(DT_NODELABEL(timers3)):
|
|
|
|
if (remap == REMAP_1) {
|
|
|
|
LL_GPIO_AF_RemapPartial_TIM3();
|
2020-10-19 12:28:29 +02:00
|
|
|
} else if (remap == REMAP_2) {
|
2020-10-13 16:44:13 +02:00
|
|
|
LL_GPIO_AF_EnableRemap_TIM3();
|
|
|
|
} else {
|
|
|
|
LL_GPIO_AF_DisableRemap_TIM3();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers4), okay)
|
|
|
|
case DT_REG_ADDR(DT_NODELABEL(timers4)):
|
2020-10-19 12:28:29 +02:00
|
|
|
if (remap == REMAP_1) {
|
2020-10-13 16:44:13 +02:00
|
|
|
LL_GPIO_AF_EnableRemap_TIM4();
|
|
|
|
} else {
|
|
|
|
LL_GPIO_AF_DisableRemap_TIM4();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers9), okay)
|
|
|
|
case DT_REG_ADDR(DT_NODELABEL(timers9)):
|
2020-10-19 12:28:29 +02:00
|
|
|
if (remap == REMAP_1) {
|
2020-10-13 16:44:13 +02:00
|
|
|
LL_GPIO_AF_EnableRemap_TIM9();
|
|
|
|
} else {
|
|
|
|
LL_GPIO_AF_DisableRemap_TIM9();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers10), okay)
|
|
|
|
case DT_REG_ADDR(DT_NODELABEL(timers10)):
|
2020-10-19 12:28:29 +02:00
|
|
|
if (remap == REMAP_1) {
|
2020-10-13 16:44:13 +02:00
|
|
|
LL_GPIO_AF_EnableRemap_TIM10();
|
|
|
|
} else {
|
|
|
|
LL_GPIO_AF_DisableRemap_TIM10();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers11), okay)
|
|
|
|
case DT_REG_ADDR(DT_NODELABEL(timers11)):
|
2020-10-19 12:28:29 +02:00
|
|
|
if (remap == REMAP_1) {
|
2020-10-13 16:44:13 +02:00
|
|
|
LL_GPIO_AF_EnableRemap_TIM11();
|
|
|
|
} else {
|
|
|
|
LL_GPIO_AF_DisableRemap_TIM11();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers12), okay)
|
|
|
|
case DT_REG_ADDR(DT_NODELABEL(timers12)):
|
2020-10-19 12:28:29 +02:00
|
|
|
if (remap == REMAP_1) {
|
2020-10-13 16:44:13 +02:00
|
|
|
LL_GPIO_AF_EnableRemap_TIM12();
|
|
|
|
} else {
|
|
|
|
LL_GPIO_AF_DisableRemap_TIM12();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers13), okay)
|
|
|
|
case DT_REG_ADDR(DT_NODELABEL(timers13)):
|
2020-10-19 12:28:29 +02:00
|
|
|
if (remap == REMAP_1) {
|
2020-10-13 16:44:13 +02:00
|
|
|
LL_GPIO_AF_EnableRemap_TIM13();
|
|
|
|
} else {
|
|
|
|
LL_GPIO_AF_DisableRemap_TIM13();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers14), okay)
|
|
|
|
case DT_REG_ADDR(DT_NODELABEL(timers14)):
|
2020-10-19 12:28:29 +02:00
|
|
|
if (remap == REMAP_1) {
|
2020-10-13 16:44:13 +02:00
|
|
|
LL_GPIO_AF_EnableRemap_TIM14();
|
|
|
|
} else {
|
|
|
|
LL_GPIO_AF_DisableRemap_TIM14();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers15), okay)
|
|
|
|
case DT_REG_ADDR(DT_NODELABEL(timers15)):
|
2020-10-19 12:28:29 +02:00
|
|
|
if (remap == REMAP_1) {
|
2020-10-13 16:44:13 +02:00
|
|
|
LL_GPIO_AF_EnableRemap_TIM15();
|
|
|
|
} else {
|
|
|
|
LL_GPIO_AF_DisableRemap_TIM15();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers16), okay)
|
|
|
|
case DT_REG_ADDR(DT_NODELABEL(timers16)):
|
2020-10-19 12:28:29 +02:00
|
|
|
if (remap == REMAP_1) {
|
2020-10-13 16:44:13 +02:00
|
|
|
LL_GPIO_AF_EnableRemap_TIM16();
|
|
|
|
} else {
|
|
|
|
LL_GPIO_AF_DisableRemap_TIM16();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers17), okay)
|
|
|
|
case DT_REG_ADDR(DT_NODELABEL(timers17)):
|
2020-10-19 12:28:29 +02:00
|
|
|
if (remap == REMAP_1) {
|
2020-10-13 16:44:13 +02:00
|
|
|
LL_GPIO_AF_EnableRemap_TIM17();
|
|
|
|
} else {
|
|
|
|
LL_GPIO_AF_DisableRemap_TIM17();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay)
|
|
|
|
case DT_REG_ADDR(DT_NODELABEL(usart1)):
|
|
|
|
if (remap == REMAP_1) {
|
|
|
|
LL_GPIO_AF_EnableRemap_USART1();
|
|
|
|
} else {
|
|
|
|
LL_GPIO_AF_DisableRemap_USART1();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay)
|
|
|
|
case DT_REG_ADDR(DT_NODELABEL(usart2)):
|
|
|
|
if (remap == REMAP_1) {
|
|
|
|
LL_GPIO_AF_EnableRemap_USART2();
|
|
|
|
} else {
|
|
|
|
LL_GPIO_AF_DisableRemap_USART2();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay)
|
|
|
|
case DT_REG_ADDR(DT_NODELABEL(usart3)):
|
|
|
|
if (remap == REMAP_2) {
|
|
|
|
LL_GPIO_AF_EnableRemap_USART3();
|
|
|
|
} else if (remap == REMAP_1) {
|
|
|
|
LL_GPIO_AF_RemapPartial_USART3();
|
|
|
|
} else {
|
|
|
|
LL_GPIO_AF_DisableRemap_USART3();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay)
|
|
|
|
case DT_REG_ADDR(DT_NODELABEL(spi1)):
|
|
|
|
if (remap == REMAP_1) {
|
|
|
|
LL_GPIO_AF_EnableRemap_SPI1();
|
|
|
|
} else {
|
|
|
|
LL_GPIO_AF_DisableRemap_SPI1();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2020-10-16 17:20:00 +02:00
|
|
|
return 0;
|
2020-10-16 14:28:48 +02:00
|
|
|
}
|
2020-10-16 17:20:00 +02:00
|
|
|
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_pinctrl) */
|
|
|
|
|
2020-06-05 10:55:20 +02:00
|
|
|
|
2016-03-03 15:33:15 +01:00
|
|
|
/**
|
|
|
|
* @brief pin setup
|
|
|
|
*
|
|
|
|
* @param pin STM32PIN() encoded pin ID
|
|
|
|
* @param func SoC specific function assignment
|
|
|
|
* @param clk optional clock device
|
|
|
|
*
|
|
|
|
* @return 0 on success, error otherwise
|
|
|
|
*/
|
2020-05-27 11:26:57 -05:00
|
|
|
int z_pinmux_stm32_set(uint32_t pin, uint32_t func,
|
2020-04-30 20:33:38 +02:00
|
|
|
const struct device *clk)
|
2016-03-03 15:33:15 +01:00
|
|
|
{
|
|
|
|
/* make sure to enable port clock first */
|
|
|
|
if (enable_port(STM32_PORT(pin), clk)) {
|
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
|
2017-07-26 18:10:25 +02:00
|
|
|
return stm32_pin_configure(pin, func, func & STM32_AFR_MASK);
|
2016-03-03 15:33:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief setup pins according to their assignments
|
|
|
|
*
|
|
|
|
* @param pinconf board pin configuration array
|
|
|
|
* @param pins array size
|
|
|
|
*/
|
2016-03-21 17:14:15 -03:00
|
|
|
void stm32_setup_pins(const struct pin_config *pinconf,
|
|
|
|
size_t pins)
|
2016-03-03 15:33:15 +01:00
|
|
|
{
|
2020-04-30 20:33:38 +02:00
|
|
|
const struct device *clk;
|
2016-03-03 15:33:15 +01:00
|
|
|
int i;
|
|
|
|
|
2021-02-11 11:49:24 -06:00
|
|
|
clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
|
2016-03-03 15:33:15 +01:00
|
|
|
|
|
|
|
for (i = 0; i < pins; i++) {
|
2019-03-12 15:15:42 -06:00
|
|
|
z_pinmux_stm32_set(pinconf[i].pin_num,
|
2017-07-26 18:10:25 +02:00
|
|
|
pinconf[i].mode,
|
|
|
|
clk);
|
2016-03-03 15:33:15 +01:00
|
|
|
}
|
|
|
|
}
|