diff --git a/arch/arm/soc/st_stm32/stm32f4/Makefile b/arch/arm/soc/st_stm32/stm32f4/Makefile index 1ef7b4af355..6ae6e190c48 100644 --- a/arch/arm/soc/st_stm32/stm32f4/Makefile +++ b/arch/arm/soc/st_stm32/stm32f4/Makefile @@ -1,6 +1,7 @@ obj-y += soc.o obj-$(CONFIG_GPIO) += soc_gpio.o +obj-$(CONFIG_PINMUX) += soc_pinmux.o zephyr: $(KERNEL_HEX_NAME) all: $(KERNEL_HEX_NAME) diff --git a/arch/arm/soc/st_stm32/stm32f4/soc_pinmux.c b/arch/arm/soc/st_stm32/stm32f4/soc_pinmux.c new file mode 100644 index 00000000000..e3937d14e1c --- /dev/null +++ b/arch/arm/soc/st_stm32/stm32f4/soc_pinmux.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2016 Linaro Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "soc.h" +#include +#include +#include +#include + +static const stm32_pin_func_t pin_pb6_funcs[] = { + [STM32F4_PINMUX_FUNC_PB6_USART1_TX - 1] = + STM32F4X_PIN_CONFIG_AF_PUSH_UP, +}; + +static const stm32_pin_func_t pin_pb7_funcs[] = { + [STM32F4_PINMUX_FUNC_PB7_USART1_RX - 1] = + STM32F4X_PIN_CONFIG_AF_PUSH_UP, +}; + +static const stm32_pin_func_t pin_pa2_funcs[] = { + [STM32F4_PINMUX_FUNC_PA2_USART2_TX - 1] = + STM32F4X_PIN_CONFIG_AF_PUSH_UP, +}; + +static const stm32_pin_func_t pin_pa3_funcs[] = { + [STM32F4_PINMUX_FUNC_PA3_USART2_RX - 1] = + STM32F4X_PIN_CONFIG_AF_PUSH_UP, +}; + +/** + * @brief pin configuration + */ +static const struct stm32_pinmux_conf pins[] = { + STM32_PIN_CONF(STM32_PIN_PB6, pin_pb6_funcs), + STM32_PIN_CONF(STM32_PIN_PB7, pin_pb7_funcs), + STM32_PIN_CONF(STM32_PIN_PA2, pin_pa2_funcs), + STM32_PIN_CONF(STM32_PIN_PA3, pin_pa3_funcs), +}; + +int stm32_get_pin_config(int pin, int func) +{ + /* GPIO function is always available, to save space it is not + * listed in alternate functions array + */ + if (func == STM32_PINMUX_FUNC_GPIO) { + return STM32F4X_PIN_CONFIG_BIAS_HIGH_IMPEDANCE; + } + + /* analog function is another 'known' setting */ + if (func == STM32_PINMUX_FUNC_ANALOG) { + return STM32F4X_PIN_CONFIG_ANALOG; + } + + func -= 1; + + for (int i = 0; i < ARRAY_SIZE(pins); i++) { + if (pins[i].pin == pin) { + if (func > pins[i].nfuncs) { + return -EINVAL; + } + + return pins[i].funcs[func]; + } + } + + return -EINVAL; +} diff --git a/drivers/pinmux/stm32/pinmux_stm32.c b/drivers/pinmux/stm32/pinmux_stm32.c index 9b5760ad31f..724c49bed2e 100644 --- a/drivers/pinmux/stm32/pinmux_stm32.c +++ b/drivers/pinmux/stm32/pinmux_stm32.c @@ -32,6 +32,19 @@ #include #include +#ifdef CONFIG_SOC_SERIES_STM32F4X +static const uint32_t ports_enable[STM32_PORTS_MAX] = { + STM32F4X_CLOCK_ENABLE_GPIOA, + STM32F4X_CLOCK_ENABLE_GPIOB, + STM32F4X_CLOCK_ENABLE_GPIOC, + STM32F4X_CLOCK_ENABLE_GPIOD, + STM32F4X_CLOCK_ENABLE_GPIOE, + STM32F4X_CLOCK_ENABLE_GPIOF, + STM32F4X_CLOCK_ENABLE_GPIOG, + STM32F4X_CLOCK_ENABLE_GPIOH, +}; +#endif + /** * @brief enable IO port clock * @@ -42,14 +55,26 @@ */ static int enable_port(uint32_t port, struct device *clk) { - clock_control_subsys_t subsys = stm32_get_port_clock(port); - /* enable port clock */ if (!clk) { clk = device_get_binding(STM32_CLOCK_CONTROL_NAME); } + /* TODO: Merge this and move the port clock to the soc file */ +#ifdef CONFIG_SOC_SERIES_STM32F1X + clock_control_subsys_t subsys = stm32_get_port_clock(port); + return clock_control_on(clk, subsys); + +#elif CONFIG_SOC_SERIES_STM32F4X + struct stm32f4x_pclken pclken; + + /* AHB1 bus for all the GPIO ports */ + pclken.bus = STM32F4X_CLOCK_BUS_AHB1; + pclken.enr = ports_enable[port]; + + return clock_control_on(clk, (clock_control_subsys_t *) &pclken); +#endif } static int stm32_pin_configure(int pin, int func, int altf) diff --git a/drivers/pinmux/stm32/pinmux_stm32.h b/drivers/pinmux/stm32/pinmux_stm32.h index 5667e33c2cc..02cfe042b93 100644 --- a/drivers/pinmux/stm32/pinmux_stm32.h +++ b/drivers/pinmux/stm32/pinmux_stm32.h @@ -62,6 +62,14 @@ enum stm32_pin_alt_func { STM32_PINMUX_FUNC_ALT_5, STM32_PINMUX_FUNC_ALT_6, STM32_PINMUX_FUNC_ALT_7, + STM32_PINMUX_FUNC_ALT_8, + STM32_PINMUX_FUNC_ALT_9, + STM32_PINMUX_FUNC_ALT_10, + STM32_PINMUX_FUNC_ALT_11, + STM32_PINMUX_FUNC_ALT_12, + STM32_PINMUX_FUNC_ALT_13, + STM32_PINMUX_FUNC_ALT_14, + STM32_PINMUX_FUNC_ALT_15, STM32_PINMUX_FUNC_ALT_MAX }; @@ -285,6 +293,8 @@ void stm32_setup_pins(const struct pin_config *pinconf, #ifdef CONFIG_SOC_SERIES_STM32F1X #include "pinmux_stm32f1.h" +#elif CONFIG_SOC_SERIES_STM32F4X +#include "pinmux_stm32f4.h" #endif #endif /* _STM32_PINMUX_H_ */ diff --git a/drivers/pinmux/stm32/pinmux_stm32f4.h b/drivers/pinmux/stm32/pinmux_stm32f4.h new file mode 100644 index 00000000000..00c70b32adc --- /dev/null +++ b/drivers/pinmux/stm32/pinmux_stm32f4.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016 Linaro Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _STM32F4_PINMUX_H_ +#define _STM32F4_PINMUX_H_ + +/** + * @file Header for STM32F4 pin multiplexing helper + */ + +#define STM32F4_PINMUX_FUNC_PB6_USART1_TX STM32_PINMUX_FUNC_ALT_7 +#define STM32F4_PINMUX_FUNC_PB7_USART1_RX STM32_PINMUX_FUNC_ALT_7 + +#endif /* _STM32F4_PINMUX_H_ */