drivers: stm32-gpio: Provide GPIO driver for stm32f2
Add necessary GPIO defines for the stm32f2 series soc Signed-off-by: qianfan Zhao <qianfanguijin@163.com>
This commit is contained in:
parent
6091a7fd50
commit
6fb7b04461
7 changed files with 332 additions and 0 deletions
|
@ -2,3 +2,4 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers)
|
|||
zephyr_sources(
|
||||
soc.c
|
||||
)
|
||||
zephyr_sources_ifdef(CONFIG_GPIO soc_gpio.c)
|
|
@ -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
arch/arm/soc/st_stm32/stm32f2/gpio_registers.h
Normal file
52
arch/arm/soc/st_stm32/stm32f2/gpio_registers.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2018 qianfan Zhao <qianfanguijin@163.com>
|
||||
*
|
||||
* 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
arch/arm/soc/st_stm32/stm32f2/soc_gpio.c
Normal file
144
arch/arm/soc/st_stm32/stm32f2/soc_gpio.c
Normal file
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright (c) 2018 qianfan Zhao <qianfanguijin@163.com>
|
||||
*
|
||||
* 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
arch/arm/soc/st_stm32/stm32f2/soc_registers.h
Normal file
13
arch/arm/soc/st_stm32/stm32f2/soc_registers.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright (c) 2018 qianfan Zhao <qianfanguijin@163.com>
|
||||
*
|
||||
* 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_ */
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue