drivers: gpio: stm32: STM32F7 GPIO support
This patch adds GPIO support for STM32F7 family microcontrollers. Signed-off-by: Yurii Hamann <yurii@hamann.site>
This commit is contained in:
parent
cfb25c74a0
commit
a229500d23
8 changed files with 240 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,20 @@ gsource "arch/arm/soc/st_stm32/stm32f7/Kconfig.defconfig.stm32f7*"
|
|||
config SOC_SERIES
|
||||
default "stm32f7"
|
||||
|
||||
if GPIO_STM32
|
||||
|
||||
config GPIO_STM32_PORTD
|
||||
default y
|
||||
|
||||
config GPIO_STM32_PORTE
|
||||
default y
|
||||
|
||||
config GPIO_STM32_PORTH
|
||||
default y
|
||||
|
||||
config GPIO_STM32_PORTI
|
||||
default y
|
||||
|
||||
endif # GPIO_STM32
|
||||
|
||||
endif # SOC_SERIES_STM32F7X
|
||||
|
|
|
@ -11,6 +11,16 @@ config SOC
|
|||
string
|
||||
default "stm32f746xx"
|
||||
|
||||
if GPIO_STM32
|
||||
|
||||
config GPIO_STM32_PORTJ
|
||||
default y
|
||||
|
||||
config GPIO_STM32_PORTK
|
||||
default y
|
||||
|
||||
endif # GPIO_STM32
|
||||
|
||||
config NUM_IRQS
|
||||
int
|
||||
default 98
|
||||
|
|
53
arch/arm/soc/st_stm32/stm32f7/gpio_registers.h
Normal file
53
arch/arm/soc/st_stm32/stm32f7/gpio_registers.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Yurii Hamann
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _STM32F7X_GPIO_REGISTERS_H_
|
||||
#define _STM32F7X_GPIO_REGISTERS_H_
|
||||
|
||||
/**
|
||||
* @brief Driver for GPIO of STM32F7X family processor.
|
||||
*
|
||||
* Based on reference manual:
|
||||
* RM0385 Reference manual STM32F75xxx and STM32F74xxx
|
||||
* advanced ARM(r)-based 32-bit MCUs
|
||||
*
|
||||
* Chapter 6: General-purpose I/Os (GPIOs)
|
||||
*/
|
||||
|
||||
/* 6.4 GPIO registers - each GPIO port controls 16 pins */
|
||||
struct stm32f7x_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];
|
||||
u32_t brr;
|
||||
};
|
||||
|
||||
union syscfg_exticr {
|
||||
u32_t val;
|
||||
struct {
|
||||
u16_t rsvd__16_31;
|
||||
u16_t exti;
|
||||
} bit;
|
||||
};
|
||||
|
||||
/* 7.2 SYSCFG registers */
|
||||
struct stm32f7x_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 /* _STM32F7X_GPIO_REGISTERS_H_ */
|
|
@ -17,6 +17,10 @@
|
|||
#ifndef _STM32F7_SOC_H_
|
||||
#define _STM32F7_SOC_H_
|
||||
|
||||
#define GPIO_REG_SIZE 0x400
|
||||
/* base address for where GPIO registers start */
|
||||
#define GPIO_PORTS_BASE (GPIOA_BASE)
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
|
||||
#include <device.h>
|
||||
|
|
142
arch/arm/soc/st_stm32/stm32f7/soc_gpio.c
Normal file
142
arch/arm/soc/st_stm32/stm32f7/soc_gpio.c
Normal file
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Yurii Hamann
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* Based on reference manual:
|
||||
* RM0385 Reference manual STM32F75xxx and STM32F74xxx
|
||||
* advanced ARM ® -based 32-bit MCUs
|
||||
*
|
||||
* Chapter 6: General-purpose I/Os (GPIOs)
|
||||
*/
|
||||
|
||||
#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 stm32f7x_gpio *gpio =
|
||||
(struct stm32f7x_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 stm32f7x_gpio *gpio = (struct stm32f7x_gpio *)base;
|
||||
|
||||
if (value) {
|
||||
/* atomic set */
|
||||
gpio->bsrr = (1 << (pin & 0x0f));
|
||||
} else {
|
||||
/* atomic reset */
|
||||
gpio->bsrr = (1 << ((pin & 0x0f) + 0x10));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stm32_gpio_get(u32_t *base, int pin)
|
||||
{
|
||||
struct stm32f7x_gpio *gpio = (struct stm32f7x_gpio *)base;
|
||||
|
||||
return (gpio->idr >> pin) & 0x1;
|
||||
}
|
||||
|
||||
int stm32_gpio_enable_int(int port, int pin)
|
||||
{
|
||||
volatile struct stm32f7x_syscfg *syscfg =
|
||||
(struct stm32f7x_syscfg *)SYSCFG_BASE;
|
||||
volatile union syscfg_exticr *exticr;
|
||||
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
|
||||
};
|
||||
int shift = 0;
|
||||
|
||||
/* Enable SYSCFG clock */
|
||||
clock_control_on(clk, (clock_control_subsys_t *) &pclken);
|
||||
|
||||
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;
|
||||
}
|
|
@ -9,5 +9,6 @@
|
|||
|
||||
/* include register mapping headers */
|
||||
#include "flash_registers.h"
|
||||
#include "gpio_registers.h"
|
||||
|
||||
#endif /* _STM32F7_SOC_REGISTERS_H_ */
|
||||
|
|
|
@ -56,6 +56,19 @@
|
|||
#define STM32_PERIPH_GPIOI LL_AHB1_GRP1_PERIPH_GPIOI
|
||||
#define STM32_PERIPH_GPIOJ LL_AHB1_GRP1_PERIPH_GPIOJ
|
||||
#define STM32_PERIPH_GPIOK LL_AHB1_GRP1_PERIPH_GPIOK
|
||||
#elif CONFIG_SOC_SERIES_STM32F7X
|
||||
#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
|
||||
#define STM32_PERIPH_GPIOJ LL_AHB1_GRP1_PERIPH_GPIOJ
|
||||
#define STM32_PERIPH_GPIOK LL_AHB1_GRP1_PERIPH_GPIOK
|
||||
#elif CONFIG_SOC_SERIES_STM32L0X
|
||||
#define STM32_CLOCK_BUS_GPIO STM32_CLOCK_BUS_IOP
|
||||
#define STM32_PERIPH_GPIOA LL_IOP_GRP1_PERIPH_GPIOA
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue