diff --git a/arch/arm/soc/st_stm32/stm32f3/Makefile b/arch/arm/soc/st_stm32/stm32f3/Makefile index baf5eb3074e..00e22c015a1 100644 --- a/arch/arm/soc/st_stm32/stm32f3/Makefile +++ b/arch/arm/soc/st_stm32/stm32f3/Makefile @@ -17,4 +17,5 @@ obj-y += soc.o -obj-$(CONFIG_PINMUX) += soc_config.o \ No newline at end of file +obj-$(CONFIG_PINMUX) += soc_config.o +obj-$(CONFIG_GPIO) += soc_gpio.o \ No newline at end of file diff --git a/arch/arm/soc/st_stm32/stm32f3/gpio_registers.h b/arch/arm/soc/st_stm32/stm32f3/gpio_registers.h new file mode 100644 index 00000000000..dfeaf41ea84 --- /dev/null +++ b/arch/arm/soc/st_stm32/stm32f3/gpio_registers.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2016 RnDity Sp. z o.o. + * + * 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 _STM32F3X_GPIO_REGISTERS_H_ +#define _STM32F3X_GPIO_REGISTERS_H_ + +/** + * @brief + * + * Based on reference manual: + * STM32F303xB/C/D/E, STM32F303x6/8, STM32F328x8, STM32F358xC, + * STM32F398xE advanced ARM ® -based MCUs + * + * Chapter 11: General-purpose I/Os + */ + +struct stm32f3x_gpio { + uint32_t moder; + uint32_t otyper; + uint32_t ospeedr; + uint32_t pupdr; + uint32_t idr; + uint32_t odr; + uint32_t bsrr; + uint32_t lckr; + uint32_t afrl; + uint32_t afrh; + uint32_t brr; +}; + +union syscfg_cfgr1 { + uint32_t val; + struct { + uint32_t mem_mode :2 __packed; + uint32_t rsvd__2_5 :4 __packed; + uint32_t tim1_itr3_rmo :1 __packed; + uint32_t dac_trig_rmp :1 __packed; + uint32_t rsvd__8_10 :3 __packed; + uint32_t tim16_dma_rmp :1 __packed; + uint32_t tim17_dma_rmp :1 __packed; + uint32_t tim16_dac1_dma_rmp :1 __packed; + uint32_t tim17_dac2_dma_rmp :1 __packed; + uint32_t dac2_ch1_dma_rmp :1 __packed; + uint32_t i2c_pb6_fmp :1 __packed; + uint32_t i2c_pb7_fmp :1 __packed; + uint32_t i2c_pb8_fmp :1 __packed; + uint32_t i2c_pb9_fmp :1 __packed; + uint32_t i2c1_fmp :1 __packed; + uint32_t rsvd__21 :1 __packed; + uint32_t encoder_mode :2 __packed; + uint32_t rsvd__24_25 :2 __packed; + uint32_t fpu_ie :6 __packed; + } bit; +}; + +union syscfg_rcr { + uint32_t val; + struct { + uint32_t page0_wp :1 __packed; + uint32_t page1_wp :1 __packed; + uint32_t page2_wp :1 __packed; + uint32_t page3_wp :1 __packed; + uint32_t rsvd__4_31 :28 __packed; + } bit; +}; + +union syscfg__exticr { + uint32_t val; + struct { + uint16_t exti; + uint16_t rsvd__16_31; + } bit; +}; + +struct stm32f3x_syscfg { + union syscfg_cfgr1 cfgr1; + union syscfg_rcr rcr; + union syscfg__exticr exticr1; + union syscfg__exticr exticr2; + union syscfg__exticr exticr3; + union syscfg__exticr exticr4; + uint32_t cfgr2; + uint32_t rsvd_0x1C; + uint32_t rsvd_0x20; + uint32_t rsvd_0x24; + uint32_t rsvd_0x28; + uint32_t rsvd_0x2C; + uint32_t rsvd_0x30; + uint32_t rsvd_0x34; + uint32_t rsvd_0x38; + uint32_t rsvd_0x3C; + uint32_t rsvd_0x40; + uint32_t rsvd_0x44; + uint32_t rsvd_0x48; + uint32_t rsvd_0x4C; + uint32_t cfgr3; +}; + +#endif /* _STM32F3X_GPIO_REGISTERS_H_ */ diff --git a/arch/arm/soc/st_stm32/stm32f3/rcc_registers.h b/arch/arm/soc/st_stm32/stm32f3/rcc_registers.h index dfe11fd9e83..808a724abf9 100644 --- a/arch/arm/soc/st_stm32/stm32f3/rcc_registers.h +++ b/arch/arm/soc/st_stm32/stm32f3/rcc_registers.h @@ -29,8 +29,8 @@ */ /** - * @brief Reset and Clock Control - */ + * @brief Reset and Clock Control + */ union __rcc_cr { uint32_t val; diff --git a/arch/arm/soc/st_stm32/stm32f3/soc_config.c b/arch/arm/soc/st_stm32/stm32f3/soc_config.c index c4f25ec2504..d22b3f9fd4d 100644 --- a/arch/arm/soc/st_stm32/stm32f3/soc_config.c +++ b/arch/arm/soc/st_stm32/stm32f3/soc_config.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include int stm32_get_pin_config(int pin, int func) { @@ -36,6 +36,28 @@ int stm32_get_pin_config(int pin, int func) return -EINVAL; } - /* ToDo: encode and return the 'real' alternate function number */ - return -EINVAL; + /* encode and return the 'real' alternate function number */ + return STM32_PINFUNC(func, STM32F3X_PIN_CONFIG_AF); +} + +clock_control_subsys_t stm32_get_port_clock(int port) +{ + const clock_control_subsys_t ports_to_clock[STM32_PORTS_MAX] = { + UINT_TO_POINTER(STM32F3X_CLOCK_SUBSYS_IOPA), + UINT_TO_POINTER(STM32F3X_CLOCK_SUBSYS_IOPB), + UINT_TO_POINTER(STM32F3X_CLOCK_SUBSYS_IOPC), + UINT_TO_POINTER(STM32F3X_CLOCK_SUBSYS_IOPD), +#ifdef CONFIG_SOC_STM32F334X8 + UINT_TO_POINTER(0), +#else + UINT_TO_POINTER(STM32F3X_CLOCK_SUBSYS_IOPE), +#endif + UINT_TO_POINTER(STM32F3X_CLOCK_SUBSYS_IOPF), + }; + + if (port > STM32_PORTF) { + return NULL; + } + + return ports_to_clock[port]; } diff --git a/arch/arm/soc/st_stm32/stm32f3/soc_gpio.c b/arch/arm/soc/st_stm32/stm32f3/soc_gpio.c new file mode 100644 index 00000000000..3d57542c3dc --- /dev/null +++ b/arch/arm/soc/st_stm32/stm32f3/soc_gpio.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2016 RnDity Sp. z o.o. + * + * 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. + */ + +/** + * @brief + * + * Based on reference manual: + * STM32F303xB/C/D/E, STM32F303x6/8, STM32F328x8, STM32F358xC, + * STM32F398xE advanced ARM ® -based MCUs + * + * Chapter 11: General-purpose I/Os (GPIO) + */ + +#include + +#include +#include "soc.h" +#include "soc_registers.h" +#include +#include + +/** + * @brief map pin function to MODE register value + */ +static uint32_t func_to_mode(int func) +{ + switch (func) { + case STM32F3X_PIN_CONFIG_ANALOG: + return 0x3; + case STM32F3X_PIN_CONFIG_BIAS_HIGH_IMPEDANCE: + case STM32F3X_PIN_CONFIG_BIAS_PULL_UP: + case STM32F3X_PIN_CONFIG_BIAS_PULL_DOWN: + return 0x0; + case STM32F3X_PIN_CONFIG_DRIVE_OPEN_DRAIN: + case STM32F3X_PIN_CONFIG_DRIVE_PUSH_PULL: + case STM32F3X_PIN_CONFIG_DRIVE_PUSH_PULL_PU: + case STM32F3X_PIN_CONFIG_DRIVE_PUSH_PULL_PD: + case STM32F3X_PIN_CONFIG_DRIVE_OPEN_DRAIN_PU: + case STM32F3X_PIN_CONFIG_DRIVE_OPEN_DRAIN_PD: + return 0x1; + case STM32F3X_PIN_CONFIG_AF: + return 0x2; + } + return 0; +} + +int stm32_gpio_flags_to_conf(int flags, int *pincfg) +{ + int direction = flags & GPIO_DIR_MASK; + + if (!pincfg) { + return -EINVAL; + } + + int pud = flags & GPIO_PUD_MASK; + + if (direction == GPIO_DIR_OUT) { + int type = flags & GPIO_PP_OD_MASK; + + if (type == GPIO_PUSH_PULL) { + *pincfg = STM32F3X_PIN_CONFIG_DRIVE_PUSH_PULL; + if (pud == GPIO_PUD_PULL_UP) { + *pincfg = STM32F3X_PIN_CONFIG_DRIVE_PUSH_PULL_PU; + } else if (pud == GPIO_PUD_PULL_DOWN) { + *pincfg = STM32F3X_PIN_CONFIG_DRIVE_PUSH_PULL_PD; + } + } else if (type == GPIO_OPEN_DRAIN) { + *pincfg = STM32F3X_PIN_CONFIG_DRIVE_OPEN_DRAIN; + if (pud == GPIO_PUD_PULL_UP) { + *pincfg = STM32F3X_PIN_CONFIG_DRIVE_OPEN_DRAIN_PU; + } else if (pud == GPIO_PUD_PULL_DOWN) { + *pincfg = STM32F3X_PIN_CONFIG_DRIVE_OPEN_DRAIN_PD; + } + } + } else if (direction == GPIO_DIR_IN) { + if (pud == GPIO_PUD_PULL_UP) { + *pincfg = STM32F3X_PIN_CONFIG_BIAS_PULL_UP; + } else if (pud == GPIO_PUD_PULL_DOWN) { + *pincfg = STM32F3X_PIN_CONFIG_BIAS_PULL_DOWN; + } else { + /* floating */ + *pincfg = STM32F3X_PIN_CONFIG_BIAS_HIGH_IMPEDANCE; + } + } else { + return -ENOTSUP; + } + + return 0; +} + +int stm32_gpio_configure(uint32_t *base_addr, int pin, int conf, int altf) +{ + volatile struct stm32f3x_gpio *gpio = + (struct stm32f3x_gpio *)(base_addr); + int mode, cmode; + + cmode = STM32_MODE(conf); + mode = func_to_mode(cmode); + + /* clear bits */ + gpio->moder &= ~(0x3 << (pin * 2)); + /* set bits */ + gpio->moder |= (mode << (pin * 2)); + + if (cmode == STM32F3X_PIN_CONFIG_AF) { + /* alternate function setup */ + int af = STM32_AF(conf); + volatile uint32_t *afr = &gpio->afrl; + int crpin = pin; + + if (crpin > 7) { + afr = &gpio->afrh; + crpin -= 7; + } + + /* clear AF bits */ + *afr &= ~(0xf << (crpin * 4)); + /* set AF */ + *afr |= (af << (crpin * 4)); + } else if (cmode == STM32F3X_PIN_CONFIG_ANALOG) { + gpio->pupdr &= ~(0x3 << (pin * 2)); + } else { + /* clear typer */ + gpio->otyper &= ~(1 << pin); + + if (cmode == STM32F3X_PIN_CONFIG_DRIVE_OPEN_DRAIN || + cmode == STM32F3X_PIN_CONFIG_DRIVE_OPEN_DRAIN_PU || + cmode == STM32F3X_PIN_CONFIG_DRIVE_OPEN_DRAIN_PD) { + /* configure pin as output open-drain */ + gpio->otyper |= 1 << pin; + } + + /* configure pin as floating by clearing pupd flags */ + gpio->pupdr &= ~(0x3 << (pin * 2)); + + if (cmode == STM32F3X_PIN_CONFIG_BIAS_PULL_UP || + cmode == STM32F3X_PIN_CONFIG_DRIVE_PUSH_PULL_PU || + cmode == STM32F3X_PIN_CONFIG_DRIVE_OPEN_DRAIN_PU) { + /* enable pull up */ + gpio->pupdr |= (1 << (pin * 2)); + } else if (cmode == STM32F3X_PIN_CONFIG_BIAS_PULL_DOWN || + cmode == STM32F3X_PIN_CONFIG_DRIVE_PUSH_PULL_PD || + cmode == STM32F3X_PIN_CONFIG_DRIVE_OPEN_DRAIN_PD) { + /* or pull down */ + gpio->pupdr |= (2 << (pin * 2)); + } + } + + return 0; +} + +int stm32_gpio_set(uint32_t *base, int pin, int value) +{ + struct stm32f3x_gpio *gpio = (struct stm32f3x_gpio *)base; + + int pval = 1 << (pin & 0xf); + + if (value) { + gpio->odr |= pval; + } else { + gpio->odr &= ~pval; + } + + return 0; +} + +int stm32_gpio_get(uint32_t *base, int pin) +{ + struct stm32f3x_gpio *gpio = (struct stm32f3x_gpio *)base; + + return (gpio->idr >> pin) & 0x1; +} + +int stm32_gpio_enable_int(int port, int pin) +{ + volatile struct stm32f3x_syscfg *syscfg = + (struct stm32f3x_syscfg *)SYSCFG_BASE; + volatile union syscfg__exticr *exticr; + + /* Enable System Configuration Controller clock. */ + struct device *clk = + device_get_binding(STM32_CLOCK_CONTROL_NAME); + + clock_control_on(clk, UINT_TO_POINTER(STM32F3X_CLOCK_SUBSYS_SYSCFG)); + + int shift = 0; + + if (pin <= 3) { + exticr = &syscfg->exticr1; + } else if (pin <= 7) { + exticr = &syscfg->exticr2; + } else if (pin <= 11) { + exticr = &syscfg->exticr3; + } else if (pin <= 15) { + exticr = &syscfg->exticr4; + } else { + return -EINVAL; + } + + shift = 4 * (pin % 4); + + exticr->val &= ~(0xf << shift); + exticr->val |= port << shift; + + return 0; +} diff --git a/arch/arm/soc/st_stm32/stm32f3/soc_registers.h b/arch/arm/soc/st_stm32/stm32f3/soc_registers.h index 3819ebf5c10..55ba8b21f6e 100644 --- a/arch/arm/soc/st_stm32/stm32f3/soc_registers.h +++ b/arch/arm/soc/st_stm32/stm32f3/soc_registers.h @@ -20,5 +20,6 @@ /* include register mapping headers */ #include "rcc_registers.h" #include "flash_registers.h" +#include "gpio_registers.h" #endif /* _STM32F3X_SOC_REGISTERS_H_ */ diff --git a/drivers/gpio/gpio_stm32.c b/drivers/gpio/gpio_stm32.c index f0199d3e5fc..4fe771952c5 100644 --- a/drivers/gpio/gpio_stm32.c +++ b/drivers/gpio/gpio_stm32.c @@ -13,10 +13,10 @@ #include #include #include -#include #include #include +#include "gpio_stm32.h" #include "gpio_utils.h" /** @@ -188,16 +188,15 @@ static int gpio_stm32_init(struct device *device) struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME); -#if defined(CONFIG_SOC_SERIES_STM32F1X) || defined(CONFIG_SOC_SERIES_STM32L4X) - clock_control_on(clk, cfg->clock_subsys); -#elif CONFIG_SOC_SERIES_STM32F4X +#ifdef CONFIG_SOC_SERIES_STM32F4X clock_control_on(clk, (clock_control_subsys_t *) &cfg->pclken); +#else + clock_control_on(clk, cfg->clock_subsys); #endif - return 0; } -#if defined(CONFIG_SOC_SERIES_STM32F1X) || defined(CONFIG_SOC_SERIES_STM32L4X) +#ifndef CONFIG_SOC_SERIES_STM32F4X /* TODO: Change F1 to work similarly to F4 */ #define GPIO_DEVICE_INIT(__name, __suffix, __base_addr, __port, __clock) \ @@ -216,7 +215,7 @@ DEVICE_AND_API_INIT(gpio_stm32_## __suffix, \ CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ &gpio_stm32_driver); -#elif CONFIG_SOC_SERIES_STM32F4X +#elif /* CONFIG_SOC_SERIES_STM32F4X */ #define GPIO_DEVICE_INIT(__name, __suffix, __base_addr, __port, __cenr) \ static const struct gpio_stm32_config gpio_stm32_cfg_## __suffix = { \ @@ -240,9 +239,11 @@ GPIO_DEVICE_INIT("GPIOA", a, GPIOA_BASE, STM32_PORTA, #ifdef CONFIG_SOC_SERIES_STM32F1X STM32F10X_CLOCK_SUBSYS_IOPA | STM32F10X_CLOCK_SUBSYS_AFIO +#elif CONFIG_SOC_SERIES_STM32F3X + STM32F3X_CLOCK_SUBSYS_IOPA #elif CONFIG_SOC_SERIES_STM32F4X STM32F4X_CLOCK_ENABLE_GPIOA -#elif defined(CONFIG_SOC_SERIES_STM32L4X) +#elif CONFIG_SOC_SERIES_STM32L4X STM32L4X_CLOCK_SUBSYS_GPIOA #endif ); @@ -253,9 +254,11 @@ GPIO_DEVICE_INIT("GPIOB", b, GPIOB_BASE, STM32_PORTB, #ifdef CONFIG_SOC_SERIES_STM32F1X STM32F10X_CLOCK_SUBSYS_IOPB | STM32F10X_CLOCK_SUBSYS_AFIO +#elif CONFIG_SOC_SERIES_STM32F3X + STM32F3X_CLOCK_SUBSYS_IOPB #elif CONFIG_SOC_SERIES_STM32F4X STM32F4X_CLOCK_ENABLE_GPIOB -#elif defined(CONFIG_SOC_SERIES_STM32L4X) +#elif CONFIG_SOC_SERIES_STM32L4X STM32L4X_CLOCK_SUBSYS_GPIOB #endif ); @@ -266,9 +269,11 @@ GPIO_DEVICE_INIT("GPIOC", c, GPIOC_BASE, STM32_PORTC, #ifdef CONFIG_SOC_SERIES_STM32F1X STM32F10X_CLOCK_SUBSYS_IOPC | STM32F10X_CLOCK_SUBSYS_AFIO +#elif CONFIG_SOC_SERIES_STM32F3X + STM32F3X_CLOCK_SUBSYS_IOPC #elif CONFIG_SOC_SERIES_STM32F4X STM32F4X_CLOCK_ENABLE_GPIOC -#elif defined(CONFIG_SOC_SERIES_STM32L4X) +#elif CONFIG_SOC_SERIES_STM32L4X STM32L4X_CLOCK_SUBSYS_GPIOC #endif ); @@ -279,9 +284,11 @@ GPIO_DEVICE_INIT("GPIOD", d, GPIOD_BASE, STM32_PORTD, #ifdef CONFIG_SOC_SERIES_STM32F1X STM32F10X_CLOCK_SUBSYS_IOPD | STM32F10X_CLOCK_SUBSYS_AFIO +#elif CONFIG_SOC_SERIES_STM32F3X + STM32F3X_CLOCK_SUBSYS_IOPD #elif CONFIG_SOC_SERIES_STM32F4X STM32F4X_CLOCK_ENABLE_GPIOD -#elif defined(CONFIG_SOC_SERIES_STM32L4X) +#elif CONFIG_SOC_SERIES_STM32L4X STM32L4X_CLOCK_SUBSYS_GPIOD #endif ); @@ -292,9 +299,11 @@ GPIO_DEVICE_INIT("GPIOE", e, GPIOE_BASE, STM32_PORTE, #ifdef CONFIG_SOC_SERIES_STM32F1X STM32F10X_CLOCK_SUBSYS_IOPE | STM32F10X_CLOCK_SUBSYS_AFIO +#elif CONFIG_SOC_SERIES_STM32F3X + STM32F3X_CLOCK_SUBSYS_IOPE #elif CONFIG_SOC_SERIES_STM32F4X STM32F4X_CLOCK_ENABLE_GPIOE -#elif defined(CONFIG_SOC_SERIES_STM32L4X) +#elif CONFIG_SOC_SERIES_STM32L4X STM32L4X_CLOCK_SUBSYS_GPIOE #endif ); @@ -302,7 +311,9 @@ GPIO_DEVICE_INIT("GPIOE", e, GPIOE_BASE, STM32_PORTE, #ifdef CONFIG_GPIO_STM32_PORTF GPIO_DEVICE_INIT("GPIOF", f, GPIOF_BASE, STM32_PORTF, -#if defined(CONFIG_SOC_SERIES_STM32L4X) +#ifdef CONFIG_SOC_SERIES_STM32F3X + STM32F3X_CLOCK_SUBSYS_IOPF +#elif CONFIG_SOC_SERIES_STM32L4X STM32L4X_CLOCK_SUBSYS_GPIOF #endif ); @@ -310,7 +321,9 @@ GPIO_DEVICE_INIT("GPIOF", f, GPIOF_BASE, STM32_PORTF, #ifdef CONFIG_GPIO_STM32_PORTG GPIO_DEVICE_INIT("GPIOG", g, GPIOG_BASE, STM32_PORTG, -#if defined(CONFIG_SOC_SERIES_STM32L4X) +#ifdef CONFIG_SOC_SERIES_STM32F3X + STM32F3X_CLOCK_SUBSYS_IOPG +#elif CONFIG_SOC_SERIES_STM32L4X STM32L4X_CLOCK_SUBSYS_GPIOG #endif ); @@ -318,7 +331,9 @@ GPIO_DEVICE_INIT("GPIOG", g, GPIOG_BASE, STM32_PORTG, #ifdef CONFIG_GPIO_STM32_PORTH GPIO_DEVICE_INIT("GPIOH", h, GPIOH_BASE, STM32_PORTH, -#if defined(CONFIG_SOC_SERIES_STM32L4X) +#ifdef CONFIG_SOC_SERIES_STM32F3X + STM32F3X_CLOCK_SUBSYS_IOPH +#elif CONFIG_SOC_SERIES_STM32L4X STM32L4X_CLOCK_SUBSYS_GPIOH #endif ); diff --git a/drivers/gpio/gpio_stm32.h b/drivers/gpio/gpio_stm32.h index 57828f205da..a0bdecae29c 100644 --- a/drivers/gpio/gpio_stm32.h +++ b/drivers/gpio/gpio_stm32.h @@ -11,7 +11,6 @@ * @file header for STM32 GPIO */ - #include #include #include @@ -24,11 +23,11 @@ struct gpio_stm32_config { uint32_t *base; /* IO port */ enum stm32_pin_port port; -#if defined(CONFIG_SOC_SERIES_STM32F1X) || defined(CONFIG_SOC_SERIES_STM32L4X) +#ifdef CONFIG_SOC_SERIES_STM32F4X + struct stm32f4x_pclken pclken; +#else /* SOC_SERIES_STM32F1X || SOC_SERIES_STM32F3X || SOC_SERIES_STM32L4X */ /* clock subsystem */ clock_control_subsys_t clock_subsys; -#elif CONFIG_SOC_SERIES_STM32F4X - struct stm32f4x_pclken pclken; #endif }; diff --git a/drivers/pinmux/stm32/pinmux_stm32.h b/drivers/pinmux/stm32/pinmux_stm32.h index 455e4f110d0..485e420a758 100644 --- a/drivers/pinmux/stm32/pinmux_stm32.h +++ b/drivers/pinmux/stm32/pinmux_stm32.h @@ -60,6 +60,7 @@ enum stm32_pin_alt_func { STM32_PINMUX_FUNC_ALT_13, STM32_PINMUX_FUNC_ALT_14, STM32_PINMUX_FUNC_ALT_15, + STM32_PINMUX_FUNC_ALT_16, STM32_PINMUX_FUNC_ALT_MAX }; @@ -227,6 +228,39 @@ struct stm32_pinmux_conf { #define STM32_PIN_CONF(__pin, __funcs) \ {__pin, __funcs, ARRAY_SIZE(__funcs)} +#define STM32_AF_SHIFT 16 +/** + * @brief helper for encoding alternate function with pin config mode + * on stm32_pin_func_t + */ +#define STM32_AS_AF(__af) \ + (__af << STM32_AF_SHIFT) + +/** + * @brief helper for extracting alternate function from stm32_pin_func_t + */ +#define STM32_AF(__pinconf) \ + (__pinconf >> STM32_AF_SHIFT) + +/** + * @brief helper for encoding pin mode on stm32_pin_func_t + */ +#define STM32_AS_MODE(__mode) \ + (__mode) + +/** + * @brief helper for extracting pin mode encoded on stm32_pin_func_t + */ +#define STM32_MODE(__pinconf) \ + (__pinconf & ((1 << STM32_AF_SHIFT) - 1)) + +/** + * @brief helper for encoding pin mode and alternate function on + * stm32_pin_func_t + */ +#define STM32_PINFUNC(__af, __mode) \ + (STM32_AS_AF(__af) | STM32_AS_MODE(__mode)) + /** * @brief helper to extract IO port number from STM32PIN() encoded * value @@ -300,11 +334,11 @@ void stm32_setup_pins(const struct pin_config *pinconf, #ifdef CONFIG_SOC_SERIES_STM32F1X #include "pinmux_stm32f1.h" +#elif CONFIG_SOC_SERIES_STM32F3X +#include "pinmux_stm32f3.h" #elif CONFIG_SOC_SERIES_STM32F4X #include "pinmux_stm32f4.h" -#endif - -#ifdef CONFIG_SOC_SERIES_STM32L4X +#elif CONFIG_SOC_SERIES_STM32L4X #include "pinmux_stm32l4x.h" #endif diff --git a/drivers/pinmux/stm32/pinmux_stm32f3.h b/drivers/pinmux/stm32/pinmux_stm32f3.h new file mode 100644 index 00000000000..aecc1f1c0ec --- /dev/null +++ b/drivers/pinmux/stm32/pinmux_stm32f3.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2017 RnDity Sp. z o.o. + * + * 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 _STM32F3_PINMUX_H_ +#define _STM32F3_PINMUX_H_ + +/** + * @file Header for STM32F3 pin multiplexing helper + */ + +#define STM32F3_PINMUX_FUNC_PA9_USART1_TX STM32_PINMUX_FUNC_ALT_7 +#define STM32F3_PINMUX_FUNC_PA10_USART1_RX STM32_PINMUX_FUNC_ALT_7 + +#define STM32F3_PINMUX_FUNC_PA2_USART2_TX STM32_PINMUX_FUNC_ALT_7 +#define STM32F3_PINMUX_FUNC_PA3_USART2_RX STM32_PINMUX_FUNC_ALT_7 + +#ifndef CONFIG_SOC_STM32F334X8 +#define STM32F3_PINMUX_FUNC_PD5_USART2_TX STM32_PINMUX_FUNC_ALT_7 +#define STM32F3_PINMUX_FUNC_PD6_USART2_RX STM32_PINMUX_FUNC_ALT_7 +#endif + +#if CONFIG_SOC_STM32F303XC +#define STM32F3_PINMUX_FUNC_PB10_USART3_TX STM32_PINMUX_FUNC_ALT_7 +#define STM32F3_PINMUX_FUNC_PB11_USART3_RX STM32_PINMUX_FUNC_ALT_7 +#elif CONFIG_SOC_STM32F334X8 +#define STM32F3_PINMUX_FUNC_PB8_USART3_RX STM32_PINMUX_FUNC_ALT_7 +#define STM32F3_PINMUX_FUNC_PB9_USART3_TX STM32_PINMUX_FUNC_ALT_7 +#define STM32F3_PINMUX_FUNC_PB10_USART3_TX STM32_PINMUX_FUNC_ALT_7 +#define STM32F3_PINMUX_FUNC_PB11_USART3_RX STM32_PINMUX_FUNC_ALT_7 +#elif CONFIG_SOC_STM32F373XC +#define STM32F3_PINMUX_FUNC_PB8_USART3_TX STM32_PINMUX_FUNC_ALT_7 +#define STM32F3_PINMUX_FUNC_PB9_USART3_RX STM32_PINMUX_FUNC_ALT_7 +#define STM32F3_PINMUX_FUNC_PB10_USART3_TX STM32_PINMUX_FUNC_ALT_7 +#endif + +#endif /* _STM32F3_PINMUX_H_ */ diff --git a/include/gpio.h b/include/gpio.h index 52b3c5d46c7..e6075dc130e 100644 --- a/include/gpio.h +++ b/include/gpio.h @@ -120,6 +120,20 @@ extern "C" { /** Disable GPIO pin. */ #define GPIO_PIN_DISABLE (1 << 11) +/** @cond INTERNAL_HIDDEN */ +#define GPIO_PP_OD_POS 12 +/** @endcond */ + +/** Enable GPIO pin push-pull. */ +#define GPIO_PUSH_PULL (0 << GPIO_PP_OD_POS) + +/** Enable GPIO pin open drain. */ +#define GPIO_OPEN_DRAIN (1 << GPIO_PP_OD_POS) + +/** @cond INTERNAL_HIDDEN */ +#define GPIO_PP_OD_MASK (1 << GPIO_PP_OD_POS) +/** @endcond */ + struct gpio_callback; /**