Skip to content

Commit

Permalink
drivers: stm32-gpio: Provide GPIO driver for stm32f2
Browse files Browse the repository at this point in the history
Add necessary GPIO defines for the stm32f2 series soc

Signed-off-by: qianfan Zhao <[email protected]>
  • Loading branch information
qianfan-Zhao authored and galak committed Jul 5, 2018
1 parent 6091a7f commit 6fb7b04
Show file tree
Hide file tree
Showing 7 changed files with 332 additions and 0 deletions.
1 change: 1 addition & 0 deletions arch/arm/soc/st_stm32/stm32f2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers)
zephyr_sources(
soc.c
)
zephyr_sources_ifdef(CONFIG_GPIO soc_gpio.c)
22 changes: 22 additions & 0 deletions arch/arm/soc/st_stm32/stm32f2/Kconfig.defconfig.series
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,26 @@ gsource "arch/arm/soc/st_stm32/stm32f2/Kconfig.defconfig.stm32f2*"
config SOC_SERIES
default "stm32f2"

if GPIO_STM32

config GPIO_STM32_PORTD
default y

config GPIO_STM32_PORTE
default y

config GPIO_STM32_PORTF
default y

config GPIO_STM32_PORTG
default y

config GPIO_STM32_PORTH
default y

config GPIO_STM32_PORTI
default y

endif # GPIO_STM32

endif # SOC_SERIES_STM32F2X
52 changes: 52 additions & 0 deletions arch/arm/soc/st_stm32/stm32f2/gpio_registers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2018 qianfan Zhao <[email protected]>
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef _STM32F2X_GPIO_REGISTERS_H_
#define _STM32F2X_GPIO_REGISTERS_H_

/**
* @brief
*
* Based on reference manual:
* stm32f2X advanced ARM ® -based 32-bit MCUs
*
* Chapter 6: General-purpose I/Os (GPIO)
* Chapter 7: System configuration controller (SYSCFG)
*/

struct stm32f2x_gpio {
u32_t moder;
u32_t otyper;
u32_t ospeedr;
u32_t pupdr;
u32_t idr;
u32_t odr;
u32_t bsrr;
u32_t lckr;
u32_t afr[2];
};

union syscfg_exticr {
u32_t val;
struct {
u16_t rsvd__16_31;
u16_t exti;
} bit;
};

/* 7.2 SYSCFG registers */
struct stm32f2x_syscfg {
u32_t memrmp;
u32_t pmc;
union syscfg_exticr exticr1;
union syscfg_exticr exticr2;
union syscfg_exticr exticr3;
union syscfg_exticr exticr4;
u32_t cmpcr;
};

#endif /* _STM32F2X_GPIO_REGISTERS_H_ */
144 changes: 144 additions & 0 deletions arch/arm/soc/st_stm32/stm32f2/soc_gpio.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/*
* Copyright (c) 2018 qianfan Zhao <[email protected]>
*
* SPDX-License-Identifier: Apache-2.0
*/

/**
* @brief
*
* Based on reference manual:
* STM32F205xx, STM32F207xx, STM32F215xx and STM32F217xx
* advanced ARM-based 32-bit MCUs
*
* Chapter 6: 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>

int stm32_gpio_flags_to_conf(int flags, int *pincfg)
{
int direction = flags & GPIO_DIR_MASK;
int pud = flags & GPIO_PUD_MASK;

if (!pincfg) {
return -EINVAL;
}

if (direction == GPIO_DIR_OUT) {
*pincfg = STM32_MODER_OUTPUT_MODE;
} else {
/* pull-{up,down} maybe? */
*pincfg = STM32_MODER_INPUT_MODE;
if (pud == GPIO_PUD_PULL_UP) {
*pincfg = *pincfg | STM32_PUPDR_PULL_UP;
} else if (pud == GPIO_PUD_PULL_DOWN) {
*pincfg = *pincfg | STM32_PUPDR_PULL_DOWN;
} else {
/* floating */
*pincfg = *pincfg | STM32_PUPDR_NO_PULL;
}
}

return 0;
}

int stm32_gpio_configure(u32_t *base_addr, int pin, int conf, int altf)
{
volatile struct stm32f2x_gpio *gpio =
(struct stm32f2x_gpio *)(base_addr);
unsigned int mode, otype, ospeed, pupd;
unsigned int pin_shift = pin << 1;
unsigned int afr_bank = pin / 8;
unsigned int afr_shift = (pin % 8) << 2;
u32_t scratch;

mode = (conf >> STM32_MODER_SHIFT) & STM32_MODER_MASK;
otype = (conf >> STM32_OTYPER_SHIFT) & STM32_OTYPER_MASK;
ospeed = (conf >> STM32_OSPEEDR_SHIFT) & STM32_OSPEEDR_MASK;
pupd = (conf >> STM32_PUPDR_SHIFT) & STM32_PUPDR_MASK;

scratch = gpio->moder & ~(STM32_MODER_MASK << pin_shift);
gpio->moder = scratch | (mode << pin_shift);

scratch = gpio->ospeedr & ~(STM32_OSPEEDR_MASK << pin_shift);
gpio->ospeedr = scratch | (ospeed << pin_shift);

scratch = gpio->otyper & ~(STM32_OTYPER_MASK << pin);
gpio->otyper = scratch | (otype << pin);

scratch = gpio->pupdr & ~(STM32_PUPDR_MASK << pin_shift);
gpio->pupdr = scratch | (pupd << pin_shift);

scratch = gpio->afr[afr_bank] & ~(STM32_AFR_MASK << afr_shift);
gpio->afr[afr_bank] = scratch | (altf << afr_shift);

return 0;
}

int stm32_gpio_set(u32_t *base, int pin, int value)
{
struct stm32f2x_gpio *gpio = (struct stm32f2x_gpio *)base;

int pval = 1 << (pin & 0xf);

if (value) {
gpio->odr |= pval;
} else {
gpio->odr &= ~pval;
}

return 0;
}

int stm32_gpio_get(u32_t *base, int pin)
{
struct stm32f2x_gpio *gpio = (struct stm32f2x_gpio *)base;

return (gpio->idr >> pin) & 0x1;
}

int stm32_gpio_enable_int(int port, int pin)
{
volatile struct stm32f2x_syscfg *syscfg =
(struct stm32f2x_syscfg *)SYSCFG_BASE;
volatile union syscfg_exticr *exticr;

/* Enable System Configuration Controller clock. */
struct device *clk =
device_get_binding(STM32_CLOCK_CONTROL_NAME);

struct stm32_pclken pclken = {
.bus = STM32_CLOCK_BUS_APB2,
.enr = LL_APB2_GRP1_PERIPH_SYSCFG
};

clock_control_on(clk, (clock_control_subsys_t *) &pclken);

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;
}
13 changes: 13 additions & 0 deletions arch/arm/soc/st_stm32/stm32f2/soc_registers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright (c) 2018 qianfan Zhao <[email protected]>
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef _STM32F2X_SOC_REGISTERS_H_
#define _STM32F2X_SOC_REGISTERS_H_

/* include register mapping headers */
#include "gpio_registers.h"

#endif /* _STM32F2X_SOC_REGISTERS_H_ */
11 changes: 11 additions & 0 deletions drivers/gpio/gpio_stm32.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,17 @@
#define STM32_PERIPH_GPIOE LL_APB2_GRP1_PERIPH_GPIOE
#define STM32_PERIPH_GPIOF LL_APB2_GRP1_PERIPH_GPIOF
#define STM32_PERIPH_GPIOG LL_APB2_GRP1_PERIPH_GPIOG
#elif CONFIG_SOC_SERIES_STM32F2X
#define STM32_CLOCK_BUS_GPIO STM32_CLOCK_BUS_AHB1
#define STM32_PERIPH_GPIOA LL_AHB1_GRP1_PERIPH_GPIOA
#define STM32_PERIPH_GPIOB LL_AHB1_GRP1_PERIPH_GPIOB
#define STM32_PERIPH_GPIOC LL_AHB1_GRP1_PERIPH_GPIOC
#define STM32_PERIPH_GPIOD LL_AHB1_GRP1_PERIPH_GPIOD
#define STM32_PERIPH_GPIOE LL_AHB1_GRP1_PERIPH_GPIOE
#define STM32_PERIPH_GPIOF LL_AHB1_GRP1_PERIPH_GPIOF
#define STM32_PERIPH_GPIOG LL_AHB1_GRP1_PERIPH_GPIOG
#define STM32_PERIPH_GPIOH LL_AHB1_GRP1_PERIPH_GPIOH
#define STM32_PERIPH_GPIOI LL_AHB1_GRP1_PERIPH_GPIOI
#elif CONFIG_SOC_SERIES_STM32F3X
#define STM32_CLOCK_BUS_GPIO STM32_CLOCK_BUS_AHB1
#define STM32_PERIPH_GPIOA LL_AHB1_GRP1_PERIPH_GPIOA
Expand Down
89 changes: 89 additions & 0 deletions dts/arm/st/stm32f2.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <st/mem.h>
#include <st/stm32f2-pinctrl.dtsi>
#include <dt-bindings/clock/stm32_clock.h>
#include <dt-bindings/gpio/gpio.h>

/ {
cpus {
Expand Down Expand Up @@ -48,5 +49,93 @@
reg = <0x40023800 0x400>;
label = "STM32_CLK_RCC";
};

pinctrl: pin-controller@40020000 {
compatible = "st,stm32-pinmux";
#address-cells = <1>;
#size-cells = <1>;
reg = <0x40020000 0x2000>;

gpioa: gpio@40020000 {
compatible = "st,stm32-gpio";
gpio-controller;
#gpio-cells = <2>;
reg = <0x40020000 0x400>;
clocks = <&rcc STM32_CLOCK_BUS_AHB1 0x00000001>;
label = "GPIOA";
};

gpiob: gpio@40020400 {
compatible = "st,stm32-gpio";
gpio-controller;
#gpio-cells = <2>;
reg = <0x40020400 0x400>;
clocks = <&rcc STM32_CLOCK_BUS_AHB1 0x00000002>;
label = "GPIOB";
};

gpioc: gpio@40020800 {
compatible = "st,stm32-gpio";
gpio-controller;
#gpio-cells = <2>;
reg = <0x40020800 0x400>;
clocks = <&rcc STM32_CLOCK_BUS_AHB1 0x00000004>;
label = "GPIOC";
};

gpiod: gpio@40020c00 {
compatible = "st,stm32-gpio";
gpio-controller;
#gpio-cells = <2>;
reg = <0x40020c00 0x400>;
clocks = <&rcc STM32_CLOCK_BUS_AHB1 0x00000008>;
label = "GPIOD";
};

gpioe: gpio@40021000 {
compatible = "st,stm32-gpio";
gpio-controller;
#gpio-cells = <2>;
reg = <0x40021000 0x400>;
clocks = <&rcc STM32_CLOCK_BUS_AHB1 0x00000010>;
label = "GPIOE";
};

gpiof: gpio@40021400 {
compatible = "st,stm32-gpio";
gpio-controller;
#gpio-cells = <2>;
reg = <0x40021400 0x400>;
clocks = <&rcc STM32_CLOCK_BUS_AHB1 0x00000020>;
label = "GPIOF";
};

gpiog: gpio@40021800 {
compatible = "st,stm32-gpio";
gpio-controller;
#gpio-cells = <2>;
reg = <0x40021800 0x400>;
clocks = <&rcc STM32_CLOCK_BUS_AHB1 0x00000040>;
label = "GPIOG";
};

gpioh: gpio@40021c00 {
compatible = "st,stm32-gpio";
gpio-controller;
#gpio-cells = <2>;
reg = <0x40021c00 0x400>;
clocks = <&rcc STM32_CLOCK_BUS_AHB1 0x00000080>;
label = "GPIOH";
};

gpioi: gpio@40022000 {
compatible = "st,stm32-gpio";
gpio-controller;
#gpio-cells = <2>;
reg = <0x40022000 0x400>;
clocks = <&rcc STM32_CLOCK_BUS_AHB1 0x00000100>;
label = "GPIOI";
};
};
};
};

0 comments on commit 6fb7b04

Please sign in to comment.