soc: arm: st_stm32: Cleanup gpio function code.

All series STM32 have mostly the same GPIO architecture
and can share the same code for GPIO manipulation.
Functions of the external interrupt line control are also the same.
This patch extracts common code from them and put them into the 'common'
folder.

Functions of control GPIO of these series scattered in
soc/arm/st_stm32/stm32xx/ folders contain these functions:
stm32_gpio_flags_to_conf(), stm32_gpio_configure(), stm32_gpio_set(),
stm32_gpio_get, stm32_gpio_enable_int().
This patch merges them into the gpio_stm32.c file.

Signed-off-by: Song Qiang <songqiang1304521@gmail.com>
This commit is contained in:
Song Qiang 2019-01-08 18:10:34 +08:00 committed by Kumar Gala
commit 9612f9d840
36 changed files with 376 additions and 1478 deletions

View file

@ -19,9 +19,17 @@
#include "gpio_stm32.h"
#include "gpio_utils.h"
/* F1 series STM32 use AFIO register to configure interrupt generation
* and pinmux.
*/
#ifdef CONFIG_SOC_SERIES_STM32F1X
#include "afio_registers.h"
#else
#include "syscfg_registers.h"
#endif
/**
* @brief Common GPIO driver for STM32 MCUs. Each SoC must implement a
* SoC specific integration glue
* @brief Common GPIO driver for STM32 MCUs.
*/
/**
@ -37,6 +45,202 @@ static void gpio_stm32_isr(int line, void *arg)
}
}
/**
* @brief Common gpio flags to custom flags
*/
const int gpio_stm32_flags_to_conf(int flags, int *pincfg)
{
int direction = flags & GPIO_DIR_MASK;
int pud = flags & GPIO_PUD_MASK;
if (pincfg == NULL) {
return -EINVAL;
}
if (direction == GPIO_DIR_OUT) {
*pincfg = STM32_PINCFG_MODE_OUTPUT;
} else {
/* pull-{up,down} maybe? */
*pincfg = STM32_PINCFG_MODE_INPUT;
if (pud == GPIO_PUD_PULL_UP) {
*pincfg |= STM32_PINCFG_PULL_UP;
} else if (pud == GPIO_PUD_PULL_DOWN) {
*pincfg |= STM32_PINCFG_PULL_DOWN;
} else {
/* floating */
*pincfg |= STM32_PINCFG_FLOATING;
}
}
return 0;
}
/**
* @brief Configure the hardware.
*/
int gpio_stm32_configure(u32_t *base_addr, int pin, int conf, int altf)
{
volatile struct stm32_gpio *gpio =
(struct stm32_gpio *)(base_addr);
#ifdef CONFIG_SOC_SERIES_STM32F1X
int cnf, mode, mode_io;
int crpin = pin;
/* pins are configured in CRL (0-7) and CRH (8-15)
* registers
*/
volatile u32_t *reg = &gpio->crl;
ARG_UNUSED(altf);
if (crpin > 7) {
reg = &gpio->crh;
crpin -= 8;
}
/* each port is configured by 2 registers:
* CNFy[1:0]: Port x configuration bits
* MODEy[1:0]: Port x mode bits
*
* memory layout is repeated for every port:
* | CNF | MODE |
* | [0:1] | [0:1] |
*/
mode_io = (conf >> STM32_MODE_INOUT_SHIFT) & STM32_MODE_INOUT_MASK;
if (mode_io == STM32_MODE_INPUT) {
int in_pudpd = conf & (STM32_PUPD_MASK << STM32_PUPD_SHIFT);
/* Pin configured in input mode */
/* Mode: 00 */
mode = mode_io;
/* Configuration values: */
/* 00: Analog mode */
/* 01: Floating input */
/* 10: Pull-up/Pull-Down */
cnf = (conf >> STM32_CNF_IN_SHIFT) & STM32_CNF_IN_MASK;
if (in_pudpd == STM32_PUPD_PULL_UP) {
/* enable pull up */
gpio->odr |= 1 << pin;
} else if (in_pudpd == STM32_PUPD_PULL_DOWN) {
/* or pull down */
gpio->odr &= ~(1 << pin);
}
} else {
/* Pin configured in output mode */
int mode_speed = ((conf >> STM32_MODE_OSPEED_SHIFT) &
STM32_MODE_OSPEED_MASK);
/* Mode output possible values */
/* 01: Max speed 10MHz (default value) */
/* 10: Max speed 2MHz */
/* 11: Max speed 50MHz */
mode = mode_speed + mode_io;
/* Configuration possible values */
/* x0: Push-pull */
/* x1: Open-drain */
/* 0x: General Purpose Output */
/* 1x: Alternate Function Output */
cnf = ((conf >> STM32_CNF_OUT_0_SHIFT) & STM32_CNF_OUT_0_MASK) |
(((conf >> STM32_CNF_OUT_1_SHIFT) & STM32_CNF_OUT_1_MASK)
<< 1);
}
/* clear bits */
*reg &= ~(0xf << (crpin * 4));
/* set bits */
*reg |= (cnf << (crpin * 4 + 2) | mode << (crpin * 4));
#else
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);
#endif
return 0;
}
/**
* @brief Enable EXTI of the specific line
*/
const int gpio_stm32_enable_int(int port, int pin)
{
#ifdef CONFIG_SOC_SERIES_STM32F1X
volatile struct stm32_afio *syscfg =
(struct stm32_afio *)AFIO_BASE;
#else
volatile struct stm32_syscfg *syscfg =
(struct stm32_syscfg *)SYSCFG_BASE;
#endif
volatile union syscfg_exticr *exticr;
#if defined(CONFIG_SOC_SERIES_STM32F2X) || \
defined(CONFIG_SOC_SERIES_STM32F3X) || \
defined(CONFIG_SOC_SERIES_STM32F4X) || \
defined(CONFIG_SOC_SERIES_STM32F7X) || \
defined(CONFIG_SOC_SERIES_STM32L4X)
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
};
/* Enable SYSCFG clock */
clock_control_on(clk, (clock_control_subsys_t *) &pclken);
#endif
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;
}
#ifdef CONFIG_SOC_SERIES_STM32L0X
/*
* Ports F and G are not present on some STM32L0 parts, so
* for these parts port H external interrupt should be enabled
* by writing value 0x5 instead of 0x7.
*/
if (port == STM32_PORTH) {
port = LL_SYSCFG_EXTI_PORTH;
}
#endif
shift = 4 * (pin % 4);
exticr->val &= ~(0xf << shift);
exticr->val |= port << shift;
return 0;
}
/**
* @brief Configure pin or port
*/
@ -54,12 +258,12 @@ static int gpio_stm32_config(struct device *dev, int access_op,
/* figure out if we can map the requested GPIO
* configuration
*/
map_res = stm32_gpio_flags_to_conf(flags, &pincfg);
map_res = gpio_stm32_flags_to_conf(flags, &pincfg);
if (map_res) {
return map_res;
}
if (stm32_gpio_configure(cfg->base, pin, pincfg, 0)) {
if (gpio_stm32_configure(cfg->base, pin, pincfg, 0)) {
return -EIO;
}
@ -70,7 +274,7 @@ static int gpio_stm32_config(struct device *dev, int access_op,
return -EBUSY;
}
stm32_gpio_enable_int(cfg->port, pin);
gpio_stm32_enable_int(cfg->port, pin);
if (flags & GPIO_INT_EDGE) {
int edge = 0;
@ -100,12 +304,20 @@ static int gpio_stm32_write(struct device *dev, int access_op,
u32_t pin, u32_t value)
{
const struct gpio_stm32_config *cfg = dev->config->config_info;
struct stm32_gpio *gpio = (struct stm32_gpio *)cfg->base;
int pval = 1 << (pin & 0xf);
if (access_op != GPIO_ACCESS_BY_PIN) {
return -ENOTSUP;
}
return stm32_gpio_set(cfg->base, pin, value);
if (value != 0) {
gpio->odr |= pval;
} else {
gpio->odr &= ~pval;
}
return 0;
}
/**
@ -115,12 +327,13 @@ static int gpio_stm32_read(struct device *dev, int access_op,
u32_t pin, u32_t *value)
{
const struct gpio_stm32_config *cfg = dev->config->config_info;
struct stm32_gpio *gpio = (struct stm32_gpio *)cfg->base;
if (access_op != GPIO_ACCESS_BY_PIN) {
return -ENOTSUP;
}
*value = stm32_gpio_get(cfg->base, pin);
*value = (gpio->idr >> pin) & 0x1;
return 0;
}

View file

@ -104,6 +104,20 @@
#define STM32_PERIPH_GPIOI LL_AHB2_GRP1_PERIPH_GPIOI
#endif /* CONFIG_SOC_SERIES_.. */
#ifdef CONFIG_SOC_SERIES_STM32F1X
#define STM32_PINCFG_MODE_OUTPUT STM32_MODE_OUTPUT | STM32_CNF_GP_OUTPUT | STM32_CNF_PUSH_PULL
#define STM32_PINCFG_MODE_INPUT STM32_MODE_INPUT
#define STM32_PINCFG_PULL_UP STM32_CNF_IN_PUPD | STM32_PUPD_PULL_UP
#define STM32_PINCFG_PULL_DOWN STM32_CNF_IN_PUPD | STM32_PUPD_PULL_DOWN
#define STM32_PINCFG_FLOATING STM32_CNF_IN_FLOAT | STM32_PUPD_NO_PULL
#else
#define STM32_PINCFG_MODE_OUTPUT STM32_MODER_OUTPUT_MODE
#define STM32_PINCFG_MODE_INPUT STM32_MODER_INPUT_MODE
#define STM32_PINCFG_PULL_UP STM32_PUPDR_PULL_UP
#define STM32_PINCFG_PULL_DOWN STM32_PUPDR_PULL_DOWN
#define STM32_PINCFG_FLOATING STM32_PUPDR_NO_PULL
#endif /* CONFIG_SOC_SERIES_STM32F1X */
/**
* @brief configuration of GPIO device
*/
@ -126,14 +140,39 @@ struct gpio_stm32_data {
};
/**
* @brief helper for mapping of GPIO flags to SoC specific config
*
* @param flags GPIO encoded flags
* @param out conf SoC specific pin config
*
* @return 0 if flags were mapped to SoC pin config
* @brief layout of stm32 gpio registers
*/
int stm32_gpio_flags_to_conf(int flags, int *conf);
struct stm32_gpio {
#ifdef CONFIG_SOC_SERIES_STM32F1X
u32_t crl;
u32_t crh;
u32_t idr;
u32_t odr;
u32_t bsrr;
u32_t brr;
u32_t lckr;
#else
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];
#if defined(CONFIG_SOC_SERIES_STM32F0X) || \
defined(CONFIG_SOC_SERIES_STM32F3X) || \
defined(CONFIG_SOC_SERIES_STM32F7X) || \
defined(CONFIG_SOC_SERIES_STM32L0X) || \
defined(CONFIG_SOC_SERIES_STM32L4X)
u32_t brr;
#endif
#ifdef CONFIG_SOC_SERIES_STM32L4X
u32_t ascr;
#endif
#endif /* CONFIG_SOC_SERIES_STM32F1X */
};
/**
* @brief helper for configuration of GPIO pin
@ -143,32 +182,6 @@ int stm32_gpio_flags_to_conf(int flags, int *conf);
* @param func GPIO mode
* @param altf Alternate function
*/
int stm32_gpio_configure(u32_t *base_addr, int pin, int func, int altf);
/**
* @brief helper for setting of GPIO pin output
*
* @param base_addr GPIO port base address
* @param pin IO pin
* @param value 1, 0
*/
int stm32_gpio_set(u32_t *base, int pin, int value);
/**
* @brief helper for reading of GPIO pin value
*
* @param base_addr GPIO port base address
* @param pin IO pin
* @return pin value
*/
int stm32_gpio_get(u32_t *base, int pin);
/**
* @brief enable interrupt source for GPIO pin
* @param port
* @param pin
*/
int stm32_gpio_enable_int(int port, int pin);
int gpio_stm32_configure(u32_t *base_addr, int pin, int conf, int altf);
#endif /* ZEPHYR_DRIVERS_GPIO_GPIO_STM32_H_ */

View file

@ -105,7 +105,7 @@ static int stm32_pin_configure(int pin, int func, int altf)
/* not much here, on STM32F10x the alternate function is
* controller by setting up GPIO pins in specific mode.
*/
return stm32_gpio_configure((u32_t *)port_base,
return gpio_stm32_configure((u32_t *)port_base,
STM32_PIN(pin), func, altf);
}

View file

@ -0,0 +1,18 @@
/*
* Copyright (c) 2018 Song Qiang <songqiang1304521@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __SOC_SYSCFG_COMMON_H
#define __SOC_SYSCFG_COMMON_H
union syscfg_exticr {
u32_t val;
struct {
u16_t exti;
u16_t rsvd__16_31;
} bit;
};
#endif /* __STM32_SYSCFG_COMMON_H */

View file

@ -1,3 +1,2 @@
zephyr_include_directories(${ZEPHYR_BASE}/drivers)
zephyr_sources(soc.c)
zephyr_sources_ifdef(CONFIG_GPIO soc_gpio.c)

View file

@ -1,133 +0,0 @@
/*
* Copyright (c) 2017 RnDity Sp. z o.o.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @brief
*
* Based on reference manual:
* STM32F030x4/x6/x8/xC,
* STM32F070x6/xB advanced ARM ® -based MCUs
*
* Chapter 8: 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 == NULL) {
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 stm32f0x_gpio *gpio =
(struct stm32f0x_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 stm32f0x_gpio *gpio = (struct stm32f0x_gpio *)base;
int pval = 1 << (pin & 0xf);
if (value != 0) {
gpio->odr |= pval;
} else {
gpio->odr &= ~pval;
}
return 0;
}
int stm32_gpio_get(u32_t *base, int pin)
{
struct stm32f0x_gpio *gpio = (struct stm32f0x_gpio *)base;
return (gpio->idr >> pin) & 0x1;
}
int stm32_gpio_enable_int(int port, int pin)
{
volatile struct stm32f0x_syscfg *syscfg =
(struct stm32f0x_syscfg *)SYSCFG_BASE;
volatile union syscfg__exticr *exticr;
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;
}

View file

@ -9,6 +9,6 @@
/* include register mapping headers */
#include "flash_registers.h"
#include "gpio_registers.h"
#include "syscfg_registers.h"
#endif /* _STM32F0X_SOC_REGISTERS_H_ */

View file

@ -4,8 +4,8 @@
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _STM32F0X_GPIO_REGISTERS_H_
#define _STM32F0X_GPIO_REGISTERS_H_
#ifndef _STM32_SYSCFG_REGISTERS_H_
#define _STM32_SYSCFG_REGISTERS_H_
/**
* @brief
@ -14,22 +14,10 @@
* STM32F030x4/x6/x8/xC,
* STM32F070x6/xB advanced ARM ® -based MCUs
*
* Chapter 8: General-purpose I/Os (GPIO)
* Chapter 9: System configuration controller (SYSCFG)
*/
struct stm32f0x_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;
};
#include "../common/soc_syscfg_common.h"
union syscfg_cfgr1 {
u32_t val;
@ -56,22 +44,14 @@ union syscfg_cfgr1 {
} bit;
};
union syscfg__exticr {
u32_t val;
struct {
u16_t exti;
u16_t rsvd__16_31;
} bit;
};
struct stm32f0x_syscfg {
struct stm32_syscfg {
union syscfg_cfgr1 cfgr1;
u32_t rsvd;
union syscfg__exticr exticr1;
union syscfg__exticr exticr2;
union syscfg__exticr exticr3;
union syscfg__exticr exticr4;
union syscfg_exticr exticr1;
union syscfg_exticr exticr2;
union syscfg_exticr exticr3;
union syscfg_exticr exticr4;
u32_t cfgr2;
};
#endif /* _STM32F0X_GPIO_REGISTERS_H_ */
#endif /* _STM32_SYSCFG_REGISTERS_H_ */

View file

@ -2,4 +2,3 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers)
zephyr_sources(
soc.c
)
zephyr_sources_ifdef(CONFIG_GPIO soc_gpio.c)

View file

@ -4,8 +4,8 @@
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _STM32F10X_GPIO_REGISTERS_H_
#define _STM32F10X_GPIO_REGISTERS_H_
#ifndef _STM32_AFIO_REGISTERS_H_
#define _STM32_AFIO_REGISTERS_H_
/**
* @brief
@ -18,16 +18,7 @@
* (GPIOs and AFIOs)
*/
/* 9.2 GPIO registers - each GPIO port controls 16 pins */
struct stm32f10x_gpio {
u32_t crl;
u32_t crh;
u32_t idr;
u32_t odr;
u32_t bsrr;
u32_t brr;
u32_t lckr;
};
#include "../common/soc_syscfg_common.h"
/* 9.4.1 AFIO_EVCR */
union __afio_evcr {
@ -67,15 +58,6 @@ union __afio_mapr {
} bit;
};
/* 9.4.{3,4,5,6} AFIO_EXTICRx */
union __afio_exticr {
u32_t val;
struct {
u16_t rsvd__16_31;
u16_t exti;
} bit;
};
/* 9.4.7 AFIO_MAPR2 */
union __afio_mapr2 {
u32_t val;
@ -92,14 +74,14 @@ union __afio_mapr2 {
};
/* 9.4 AFIO registers */
struct stm32f10x_afio {
struct stm32_afio {
union __afio_evcr evcr;
union __afio_mapr mapr;
union __afio_exticr exticr1;
union __afio_exticr exticr2;
union __afio_exticr exticr3;
union __afio_exticr exticr4;
union syscfg_exticr exticr1;
union syscfg_exticr exticr2;
union syscfg_exticr exticr3;
union syscfg_exticr exticr4;
union __afio_mapr2 mapr2;
};
#endif /* _STM32F10X_GPIO_REGISTERS_H_ */
#endif /* _STM32_AFIO_REGISTERS_H_ */

View file

@ -1,184 +0,0 @@
/*
* Copyright (c) 2016 Open-RnD Sp. z o.o.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @brief
*
* Based on reference manual:
* STM32F101xx, STM32F102xx, STM32F103xx, STM32F105xx and STM32F107xx
* advanced ARM ® -based 32-bit MCUs
*
* Chapter 9: General-purpose and alternate-function I/Os
* (GPIOs and AFIOs)
*/
#include <errno.h>
#include <device.h>
#include "soc.h"
#include "soc_registers.h"
#include <gpio.h>
#include <gpio/gpio_stm32.h>
#include <pinmux/stm32/pinmux_stm32.h>
int stm32_gpio_flags_to_conf(int flags, int *pincfg)
{
int direction = flags & GPIO_DIR_MASK;
if (pincfg == NULL) {
return -EINVAL;
}
if (direction == GPIO_DIR_OUT) {
/* Pin is configured as an output */
*pincfg = (STM32_MODE_OUTPUT | STM32_CNF_GP_OUTPUT |
STM32_CNF_PUSH_PULL);
} else {
/* Pin is configured as an input */
int pud = flags & GPIO_PUD_MASK;
/* pull-{up,down} maybe? */
if (pud == GPIO_PUD_PULL_UP) {
*pincfg = (STM32_MODE_INPUT | STM32_CNF_IN_PUPD |
STM32_PUPD_PULL_UP);
} else if (pud == GPIO_PUD_PULL_DOWN) {
*pincfg = (STM32_MODE_INPUT | STM32_CNF_IN_PUPD |
STM32_PUPD_PULL_DOWN);
} else {
/* floating */
*pincfg = (STM32_MODE_INPUT | STM32_CNF_IN_FLOAT |
STM32_PUPD_NO_PULL);
}
}
return 0;
}
int stm32_gpio_configure(u32_t *base_addr, int pin, int conf, int altf)
{
volatile struct stm32f10x_gpio *gpio =
(struct stm32f10x_gpio *)(base_addr);
int cnf, mode, mode_io;
int crpin = pin;
/* pins are configured in CRL (0-7) and CRH (8-15)
* registers
*/
volatile u32_t *reg = &gpio->crl;
ARG_UNUSED(altf);
if (crpin > 7) {
reg = &gpio->crh;
crpin -= 8;
}
/* each port is configured by 2 registers:
* CNFy[1:0]: Port x configuration bits
* MODEy[1:0]: Port x mode bits
*
* memory layout is repeated for every port:
* | CNF | MODE |
* | [0:1] | [0:1] |
*/
mode_io = (conf >> STM32_MODE_INOUT_SHIFT) & STM32_MODE_INOUT_MASK;
if (mode_io == STM32_MODE_INPUT) {
int in_pudpd = conf & (STM32_PUPD_MASK << STM32_PUPD_SHIFT);
/* Pin configured in input mode */
/* Mode: 00 */
mode = mode_io;
/* Configuration values: */
/* 00: Analog mode */
/* 01: Floating input */
/* 10: Pull-up/Pull-Down */
cnf = (conf >> STM32_CNF_IN_SHIFT) & STM32_CNF_IN_MASK;
if (in_pudpd == STM32_PUPD_PULL_UP) {
/* enable pull up */
gpio->odr |= 1 << pin;
} else if (in_pudpd == STM32_PUPD_PULL_DOWN) {
/* or pull down */
gpio->odr &= ~(1 << pin);
}
} else {
/* Pin configured in output mode */
int mode_speed = ((conf >> STM32_MODE_OSPEED_SHIFT) & \
STM32_MODE_OSPEED_MASK);
/* Mode output possible values */
/* 01: Max speed 10MHz (default value) */
/* 10: Max speed 2MHz */
/* 11: Max speed 50MHz */
mode = mode_speed + mode_io;
/* Configuration possible values */
/* x0: Push-pull */
/* x1: Open-drain */
/* 0x: General Purpose Output */
/* 1x: Alternate Function Output */
cnf = ((conf >> STM32_CNF_OUT_0_SHIFT) & STM32_CNF_OUT_0_MASK) |
(((conf >> STM32_CNF_OUT_1_SHIFT) & STM32_CNF_OUT_1_MASK)
<< 1);
}
/* clear bits */
*reg &= ~(0xf << (crpin * 4));
/* set bits */
*reg |= (cnf << (crpin * 4 + 2) | mode << (crpin * 4));
return 0;
}
int stm32_gpio_set(u32_t *base, int pin, int value)
{
struct stm32f10x_gpio *gpio = (struct stm32f10x_gpio *)base;
int pval = 1 << (pin & 0xf);
if (value != 0) {
gpio->odr |= pval;
} else {
gpio->odr &= ~pval;
}
return 0;
}
int stm32_gpio_get(u32_t *base, int pin)
{
struct stm32f10x_gpio *gpio = (struct stm32f10x_gpio *)base;
return (gpio->idr >> pin) & 0x1;
}
int stm32_gpio_enable_int(int port, int pin)
{
volatile struct stm32f10x_afio *afio =
(struct stm32f10x_afio *)AFIO_BASE;
volatile union __afio_exticr *exticr;
int shift = 0;
if (pin <= 3) {
exticr = &afio->exticr1;
} else if (pin <= 7) {
exticr = &afio->exticr2;
} else if (pin <= 11) {
exticr = &afio->exticr3;
} else if (pin <= 15) {
exticr = &afio->exticr4;
} else {
return -EINVAL;
}
shift = 4 * (pin % 4);
exticr->val &= ~(0xf << shift);
exticr->val |= port << shift;
return 0;
}

View file

@ -8,7 +8,7 @@
#define _STM32F10X_SOC_REGISTERS_H_
/* include register mapping headers */
#include "gpio_registers.h"
#include "afio_registers.h"
#include "flash_registers.h"
#endif /* _STM32F10X_SOC_REGISTERS_H_ */

View file

@ -2,4 +2,3 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers)
zephyr_sources(
soc.c
)
zephyr_sources_ifdef(CONFIG_GPIO soc_gpio.c)

View file

@ -1,144 +0,0 @@
/*
* 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 == NULL) {
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 != 0) {
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;
}

View file

@ -8,6 +8,6 @@
#define _STM32F2X_SOC_REGISTERS_H_
/* include register mapping headers */
#include "gpio_registers.h"
#include "syscfg_registers.h"
#endif /* _STM32F2X_SOC_REGISTERS_H_ */

View file

@ -4,42 +4,22 @@
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _STM32F2X_GPIO_REGISTERS_H_
#define _STM32F2X_GPIO_REGISTERS_H_
#ifndef _STM32_SYSCFG_REGISTERS_H_
#define _STM32_SYSCFG_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;
};
#include "../common/soc_syscfg_common.h"
/* 7.2 SYSCFG registers */
struct stm32f2x_syscfg {
struct stm32_syscfg {
u32_t memrmp;
u32_t pmc;
union syscfg_exticr exticr1;
@ -49,4 +29,4 @@ struct stm32f2x_syscfg {
u32_t cmpcr;
};
#endif /* _STM32F2X_GPIO_REGISTERS_H_ */
#endif /* _STM32_SYSCFG_REGISTERS_H_ */

View file

@ -2,4 +2,3 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers)
zephyr_sources(
soc.c
)
zephyr_sources_ifdef(CONFIG_GPIO soc_gpio.c)

View file

@ -1,146 +0,0 @@
/*
* Copyright (c) 2016 RnDity Sp. z o.o.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @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>
int stm32_gpio_flags_to_conf(int flags, int *pincfg)
{
int direction = flags & GPIO_DIR_MASK;
int pud = flags & GPIO_PUD_MASK;
if (pincfg == NULL) {
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 stm32f3x_gpio *gpio =
(struct stm32f3x_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 stm32f3x_gpio *gpio = (struct stm32f3x_gpio *)base;
int pval = 1 << (pin & 0xf);
if (value != 0) {
gpio->odr |= pval;
} else {
gpio->odr &= ~pval;
}
return 0;
}
int stm32_gpio_get(u32_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);
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;
}

View file

@ -9,6 +9,6 @@
/* include register mapping headers */
#include "flash_registers.h"
#include "gpio_registers.h"
#include "syscfg_registers.h"
#endif /* _STM32F3X_SOC_REGISTERS_H_ */

View file

@ -4,8 +4,8 @@
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _STM32F3X_GPIO_REGISTERS_H_
#define _STM32F3X_GPIO_REGISTERS_H_
#ifndef _STM32_SYSCFG_REGISTERS_H_
#define _STM32_SYSCFG_REGISTERS_H_
/**
* @brief
@ -13,22 +13,9 @@
* Based on reference manual:
* STM32F303xB/C/D/E, STM32F303x6/8, STM32F328x8, STM32F358xC,
* STM32F398xE advanced ARM(r)-based MCUs
*
* Chapter 11: General-purpose I/Os
*/
struct stm32f3x_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;
};
#include "../common/soc_syscfg_common.h"
union syscfg_cfgr1 {
u32_t val;
@ -66,21 +53,13 @@ union syscfg_rcr {
} bit;
};
union syscfg__exticr {
u32_t val;
struct {
u16_t exti;
u16_t rsvd__16_31;
} bit;
};
struct stm32f3x_syscfg {
struct stm32_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;
union syscfg_exticr exticr1;
union syscfg_exticr exticr2;
union syscfg_exticr exticr3;
union syscfg_exticr exticr4;
u32_t cfgr2;
u32_t rsvd_0x1C;
u32_t rsvd_0x20;
@ -98,4 +77,4 @@ struct stm32f3x_syscfg {
u32_t cfgr3;
};
#endif /* _STM32F3X_GPIO_REGISTERS_H_ */
#endif /* _STM32_GPIO_REGISTERS_H_ */

View file

@ -2,4 +2,3 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers)
zephyr_sources(
soc.c
)
zephyr_sources_ifdef(CONFIG_GPIO soc_gpio.c)

View file

@ -1,142 +0,0 @@
/*
* Copyright (c) Linaro Limited.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @brief
*
* Based on reference manual:
* RM0368 Reference manual STM32F401xB/C and STM32F401xD/E
* advanced ARM ® -based 32-bit MCUs
*
* Chapter 8: 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 == NULL) {
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 stm32f4x_gpio *gpio =
(struct stm32f4x_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->mode & ~(STM32_MODER_MASK << pin_shift);
gpio->mode = scratch | (mode << pin_shift);
scratch = gpio->ospeed & ~(STM32_OSPEEDR_MASK << pin_shift);
gpio->ospeed = scratch | (ospeed << pin_shift);
scratch = gpio->otype & ~(STM32_OTYPER_MASK << pin);
gpio->otype = 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 stm32f4x_gpio *gpio = (struct stm32f4x_gpio *)base;
if (value != 0) {
/* atomic set */
gpio->bsr = (1 << (pin & 0x0f));
} else {
/* atomic reset */
gpio->bsr = (1 << ((pin & 0x0f) + 0x10));
}
return 0;
}
int stm32_gpio_get(u32_t *base, int pin)
{
struct stm32f4x_gpio *gpio = (struct stm32f4x_gpio *)base;
return (gpio->idr >> pin) & 0x1;
}
int stm32_gpio_enable_int(int port, int pin)
{
volatile struct stm32f4x_syscfg *syscfg =
(struct stm32f4x_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;
}

View file

@ -9,6 +9,6 @@
/* include register mapping headers */
#include "flash_registers.h"
#include "gpio_registers.h"
#include "syscfg_registers.h"
#endif /* _STM32F4_SOC_REGISTERS_H_ */

View file

@ -4,8 +4,8 @@
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _STM32F4X_GPIO_REGISTERS_H_
#define _STM32F4X_GPIO_REGISTERS_H_
#ifndef _STM32_SYSCFG_REGISTERS_H_
#define _STM32_SYSCFG_REGISTERS_H_
/**
* @brief Driver for GPIO of STM32F4X family processor.
@ -13,33 +13,12 @@
* Based on reference manual:
* RM0368 Reference manual STM32F401xB/C and STM32F401xD/E
* advanced ARM(r)-based 32-bit MCUs
*
* Chapter 8: General-purpose I/Os (GPIOs)
*/
/* 8.4 GPIO registers - each GPIO port controls 16 pins */
struct stm32f4x_gpio {
u32_t mode;
u32_t otype;
u32_t ospeed;
u32_t pupdr;
u32_t idr;
u32_t odr;
u32_t bsr;
u32_t lck;
u32_t afr[2];
};
union syscfg_exticr {
u32_t val;
struct {
u16_t rsvd__16_31;
u16_t exti;
} bit;
};
#include "../common/soc_syscfg_common.h"
/* 7.2 SYSCFG registers */
struct stm32f4x_syscfg {
struct stm32_syscfg {
u32_t memrmp;
u32_t pmc;
union syscfg_exticr exticr1;
@ -49,4 +28,4 @@ struct stm32f4x_syscfg {
u32_t cmpcr;
};
#endif /* _STM32F4X_GPIO_REGISTERS_H_ */
#endif /* _STM32_SYSCFG_REGISTERS_H_ */

View file

@ -2,4 +2,3 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers)
zephyr_sources(
soc.c
)
zephyr_sources_ifdef(CONFIG_GPIO soc_gpio.c)

View file

@ -1,53 +0,0 @@
/*
* 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_ */

View file

@ -1,142 +0,0 @@
/*
* 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 == NULL) {
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 != 0) {
/* 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;
}

View file

@ -9,6 +9,6 @@
/* include register mapping headers */
#include "flash_registers.h"
#include "gpio_registers.h"
#include "syscfg_registers.h"
#endif /* _STM32F7_SOC_REGISTERS_H_ */

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2018 Yurii Hamann
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _STM32_SYSCFG_REGISTERS_H_
#define _STM32_SYSCFG_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
*/
#include "../common/soc_syscfg_common.h"
/* 7.2 SYSCFG registers */
struct stm32_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 /* _STM32_SYSCFG_REGISTERS_H_ */

View file

@ -2,4 +2,3 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers)
zephyr_sources(
soc.c
)
zephyr_sources_ifdef(CONFIG_GPIO soc_gpio.c)

View file

@ -1,142 +0,0 @@
/*
* Copyright (c) 2018 Endre Karlson <endre.karlson@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @brief
*
* Based on reference manual:
* STM32F030x4/x6/x8/xC,
* STM32F070x6/xB advanced ARM ® -based MCUs
*
* Chapter 9: 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 == NULL) {
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 stm32l0x_gpio *gpio =
(struct stm32l0x_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 stm32l0x_gpio *gpio = (struct stm32l0x_gpio *)base;
int pval = 1 << (pin & 0xf);
if (value != 0) {
gpio->odr |= pval;
} else {
gpio->odr &= ~pval;
}
return 0;
}
int stm32_gpio_get(u32_t *base, int pin)
{
struct stm32l0x_gpio *gpio = (struct stm32l0x_gpio *)base;
return (gpio->idr >> pin) & 0x1;
}
int stm32_gpio_enable_int(int port, int pin)
{
volatile struct stm32l0x_syscfg *syscfg =
(struct stm32l0x_syscfg *)SYSCFG_BASE;
volatile union syscfg_exticr *exticr;
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;
}
/*
* Ports F and G are not present on some STM32L0 parts, so
* for these parts port H external interrupt should be enabled
* by writing value 0x5 instead of 0x7.
*/
if (port == STM32_PORTH) {
port = LL_SYSCFG_EXTI_PORTH;
}
shift = 4 * (pin % 4);
exticr->val &= ~(0xf << shift);
exticr->val |= port << shift;
return 0;
}

View file

@ -8,6 +8,7 @@
#define _STM32L0X_SOC_REGISTERS_H_
/* include register mapping headers */
#include "gpio_registers.h"
#include "syscfg_registers.h"
#endif /* _STM32L0X_SOC_REGISTERS_H_ */

View file

@ -4,42 +4,21 @@
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _STM32L0X_GPIO_REGISTERS_H_
#define _STM32L0X_GPIO_REGISTERS_H_
#ifndef _STM32_SYSCFG_REGISTERS_H_
#define _STM32_SYSCFG_REGISTERS_H_
/**
* @brief
*
* Based on reference manual:
* STM32L0X advanced ARM ® -based 32-bit MCUs
*
* Chapter 9: General-purpose I/Os (GPIO)
* Chapter 10: System configuration controller (SYSCFG)
*/
struct stm32l0x_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;
};
#include "../common/soc_syscfg_common.h"
union syscfg_exticr {
u32_t val;
struct {
u16_t exti;
u16_t rsvd__16_31;
} bit;
};
struct stm32l0x_syscfg {
struct stm32_syscfg {
u32_t cfgr1;
u32_t cfgr2;
union syscfg_exticr exticr1;
@ -51,4 +30,4 @@ struct stm32l0x_syscfg {
u32_t cfgr3;
};
#endif /* _STM32L0X_GPIO_REGISTERS_H_ */
#endif /* _STM32_SYSCFG_REGISTERS_H_ */

View file

@ -2,4 +2,3 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers)
zephyr_sources(
soc.c
)
zephyr_sources_ifdef(CONFIG_GPIO soc_gpio.c)

View file

@ -1,163 +0,0 @@
/*
* Copyright (c) 2016 Open-RnD Sp. z o.o.
* Copyright (c) 2016 BayLibre, SAS
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @brief
*
* Based on reference manual:
* STM32L4x1, STM32L4x2, STM32L431xx STM32L443xx STM32L433xx, STM32L4x5,
* STM32l4x6 advanced ARM ® -based 32-bit MCUs
*
* 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>
enum {
STM32L4X_PIN3 = 3,
STM32L4X_PIN7 = 7,
STM32L4X_PIN11 = 11,
STM32L4X_PIN15 = 15,
};
#define STM32L4X_IDR_PIN_MASK 0x1
#define STM32L4X_AFR_MASK 0xf
/* GPIO registers - each GPIO port controls 16 pins */
struct stm32l4x_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;
u32_t ascr; /* Only present on STM32L4x1, STM32L4x5, STM32L4x6 */
};
int stm32_gpio_flags_to_conf(int flags, int *pincfg)
{
int direction = flags & GPIO_DIR_MASK;
int pud = flags & GPIO_PUD_MASK;
if (pincfg == NULL) {
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 pinconf, int afnum)
{
volatile struct stm32l4x_gpio *gpio =
(struct stm32l4x_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 = (pinconf >> STM32_MODER_SHIFT) & STM32_MODER_MASK;
otype = (pinconf >> STM32_OTYPER_SHIFT) & STM32_OTYPER_MASK;
ospeed = (pinconf >> STM32_OSPEEDR_SHIFT) & STM32_OSPEEDR_MASK;
pupd = (pinconf >> 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 | (afnum << afr_shift);
return 0;
}
int stm32_gpio_set(u32_t *base, int pin, int value)
{
struct stm32l4x_gpio *gpio = (struct stm32l4x_gpio *)base;
int pval = 1 << (pin & 0xf);
if (value != 0) {
gpio->odr |= pval;
} else {
gpio->odr &= ~pval;
}
return 0;
}
int stm32_gpio_get(u32_t *base, int pin)
{
struct stm32l4x_gpio *gpio = (struct stm32l4x_gpio *)base;
return (gpio->idr >> pin) & STM32L4X_IDR_PIN_MASK;
}
int stm32_gpio_enable_int(int port, int pin)
{
struct stm32l4x_syscfg *syscfg = (struct stm32l4x_syscfg *)SYSCFG_BASE;
struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME);
u32_t *reg;
/* Enable SYSCFG clock */
struct stm32_pclken pclken = {
.bus = STM32_CLOCK_BUS_APB2,
.enr = LL_APB2_GRP1_PERIPH_SYSCFG
};
clock_control_on(clk, (clock_control_subsys_t *) &pclken);
if (pin <= STM32L4X_PIN3) {
reg = &syscfg->exticr1;
} else if (pin <= STM32L4X_PIN7) {
reg = &syscfg->exticr2;
} else if (pin <= STM32L4X_PIN11) {
reg = &syscfg->exticr3;
} else if (pin <= STM32L4X_PIN15) {
reg = &syscfg->exticr4;
} else {
return -EINVAL;
}
*reg &= ~(STM32L4X_SYSCFG_EXTICR_PIN_MASK << ((pin % 4) * 4));
*reg |= port << ((pin % 4) * 4);
return 0; /* Nothing to do here for STM32L4s */
}

View file

@ -4,23 +4,23 @@
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _STM32L4X_SYSCFG_REGISTERS_H_
#define _STM32L4X_SYSCFG_REGISTERS_H_
#ifndef _STM32_SYSCFG_REGISTERS_H_
#define _STM32_SYSCFG_REGISTERS_H_
#define STM32L4X_SYSCFG_EXTICR_PIN_MASK 7
#include "../common/soc_syscfg_common.h"
/* SYSCFG registers */
struct stm32l4x_syscfg {
struct stm32_syscfg {
u32_t memrmp;
u32_t cfgr1;
u32_t exticr1;
u32_t exticr2;
u32_t exticr3;
u32_t exticr4;
union syscfg_exticr exticr1;
union syscfg_exticr exticr2;
union syscfg_exticr exticr3;
union syscfg_exticr exticr4;
u32_t scsr;
u32_t cfgr2;
u32_t swpr;
u32_t skr;
};
#endif /* _STM32L4X_SYSCFG_REGISTERS_H_ */
#endif /* _STM32_SYSCFG_REGISTERS_H_ */