summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Podogrocki <adam.podogrocki@rndity.com>2016-12-21 08:56:20 +0000
committerKumar Gala <kumar.gala@linaro.org>2017-01-23 15:15:52 -0600
commitf23492a05939ee720a3991df36d5829d4a47abc7 (patch)
tree2121dabf6d338a409bf1d60b9a456be09cbbd9a3
parent61cc74c425d02af0e43020ca4cb75f539cada82f (diff)
gpio/stm32: provide GPIO driver implementation for STM32F3X family
Implementation includes adding some defines in the pinmux, adjusting gpio driver to specific defines for STM32F3X family, adding specific functionality in the F3X SoC definition. Change-Id: I465c66eb93e7afb43166c4585c852e284b0d6e67 Signed-off-by: Adam Podogrocki <adam.podogrocki@rndity.com>
-rw-r--r--arch/arm/soc/st_stm32/stm32f3/Makefile3
-rw-r--r--arch/arm/soc/st_stm32/stm32f3/gpio_registers.h112
-rw-r--r--arch/arm/soc/st_stm32/stm32f3/rcc_registers.h4
-rw-r--r--arch/arm/soc/st_stm32/stm32f3/soc_config.c28
-rw-r--r--arch/arm/soc/st_stm32/stm32f3/soc_gpio.c219
-rw-r--r--arch/arm/soc/st_stm32/stm32f3/soc_registers.h1
-rw-r--r--drivers/gpio/gpio_stm32.c45
-rw-r--r--drivers/gpio/gpio_stm32.h7
-rw-r--r--drivers/pinmux/stm32/pinmux_stm32.h40
-rw-r--r--drivers/pinmux/stm32/pinmux_stm32f3.h49
-rw-r--r--include/gpio.h14
11 files changed, 494 insertions, 28 deletions
diff --git a/arch/arm/soc/st_stm32/stm32f3/Makefile b/arch/arm/soc/st_stm32/stm32f3/Makefile
index baf5eb307..00e22c015 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 000000000..dfeaf41ea
--- /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 dfe11fd9e..808a724ab 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 c4f25ec25..d22b3f9fd 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 <errno.h>
#include <device.h>
#include <pinmux/stm32/pinmux_stm32.h>
-#include <gpio/gpio_stm32.h>
+#include <drivers/clock_control/stm32_clock_control.h>
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 000000000..3d57542c3
--- /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 <errno.h>
+
+#include <device.h>
+#include "soc.h"
+#include "soc_registers.h"
+#include <gpio.h>
+#include <gpio/gpio_stm32.h>
+
+/**
+ * @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 3819ebf5c..55ba8b21f 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 f0199d3e5..4fe771952 100644
--- a/drivers/gpio/gpio_stm32.c
+++ b/drivers/gpio/gpio_stm32.c
@@ -13,10 +13,10 @@
#include <clock_control/stm32_clock_control.h>
#include <pinmux/stm32/pinmux_stm32.h>
#include <pinmux.h>
-#include <gpio/gpio_stm32.h>
#include <misc/util.h>
#include <interrupt_controller/exti_stm32.h>
+#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 57828f205..a0bdecae2 100644
--- a/drivers/gpio/gpio_stm32.h
+++ b/drivers/gpio/gpio_stm32.h
@@ -11,7 +11,6 @@
* @file header for STM32 GPIO
*/
-
#include <clock_control/stm32_clock_control.h>
#include <pinmux/stm32/pinmux_stm32.h>
#include <gpio.h>
@@ -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 455e4f110..485e420a7 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 000000000..aecc1f1c0
--- /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 52b3c5d46..e6075dc13 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;
/**