Skip to content

Commit

Permalink
cpu/stm32*: changes for new GPIO API
Browse files Browse the repository at this point in the history
  • Loading branch information
gschorcht committed Sep 3, 2020
1 parent 9024fba commit bd0b266
Show file tree
Hide file tree
Showing 18 changed files with 409 additions and 360 deletions.
1 change: 1 addition & 0 deletions cpu/stm32/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ config CPU_STM32
select HAS_BOOTLOADER_STM32
select HAS_PERIPH_CPUID
select HAS_PERIPH_GPIO
select HAS_PERIPH_GPIO_EXP
select HAS_PERIPH_GPIO_IRQ
select HAS_PUF_SRAM
select HAS_PERIPH_TIMER_PERIODIC
Expand Down
3 changes: 3 additions & 0 deletions cpu/stm32/Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ ifneq (,$(filter periph_uart_nonblocking,$(USEMODULE)))
USEMODULE += tsrb
endif

# 16 bit GPIO pin mask required
USEMODULE += gpio_mask_16bit

ifneq (,$(filter stm32_eth,$(USEMODULE)))
FEATURES_REQUIRED += periph_eth
USEMODULE += netdev_eth
Expand Down
2 changes: 1 addition & 1 deletion cpu/stm32/Makefile.features
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ include $(RIOTCPU)/stm32/stm32_info.mk
FEATURES_PROVIDED += bootloader_stm32
FEATURES_PROVIDED += cpu_stm32$(CPU_FAM)
FEATURES_PROVIDED += periph_cpuid
FEATURES_PROVIDED += periph_gpio periph_gpio_irq
FEATURES_PROVIDED += periph_gpio periph_gpio_irq periph_gpio_exp
FEATURES_PROVIDED += puf_sram
FEATURES_PROVIDED += periph_timer_periodic
FEATURES_PROVIDED += periph_uart_modecfg
Expand Down
209 changes: 209 additions & 0 deletions cpu/stm32/include/gpio_arch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
/*
* Copyright (C) 2016 Freie Universität Berlin
* 2017 OTA keys S.A.
* 2020 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @ingroup cpu_stm32
* @{
*
* @file
* @brief Shared CPU specific GPIO definitions for the STM32 family
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Vincent Dupont <vincent@otakeys.com>
* @author Gunar Schorcht <gunar@schorcht.net>
*/

#ifndef GPIO_ARCH_H
#define GPIO_ARCH_H

#include "cpu.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Define a magic number that tells us to use hardware chip select
*
* We use a random value here, that does clearly differentiate from any possible
* GPIO pin number.
*/
#define SPI_HWCS_MASK (0x80)

/**
* @brief Override the default SPI hardware chip select access macro
*
* Since the CPU does only support one single hardware chip select line, we can
* detect the usage of non-valid lines by comparing to SPI_HWCS_MASK.
*/
#define SPI_HWCS(x) ((gpio_t){ .port.dev = NULL, .pin = SPI_HWCS_MASK | x })

/**
* @brief Test whether a GPIO pin is defined as SPI hardware chip select
*/
#define SPI_HWCS_IS(x) (x.port.dev == NULL && ((x.pin & SPI_HWCS_MASK) == SPI_HWCS_MASK))

/**
* @brief Base register address for MCU GPIO ports
*
* For all STM32 MCUs except the STM32F1 family, masking the last 14 bits
* corresponds to the base address of GPIO port A `GPIOA_BASE`, where these
* 14 bits are zero. For the STM32F1 family, however, these 14 bits are not
* zero because the base address of GPIO port A starts at
* `APB2PERIPH_BASE + 0x800`. Therefore, for the STM32F1 family, `GPIOA_BASE`
* cannot be used as the base address when testing for an MCU GPIO port.
* Instead `APB2PERIPH_BASE` must be used for STM32F1 family.
*/
#ifdef STM32F1
#define GPIO_CPU_PORT_BASE (APB2PERIPH_BASE)
#else
#define GPIO_CPU_PORT_BASE (GPIOA_BASE)
#endif

/**
* @brief Mask for MCU port register addresses
*/
#define GPIO_CPU_PORT_MASK (0xffffc000UL)

/**
* @brief Convert MCU port number into its register address
*/
#define GPIO_CPU_PORT(port) (GPIOA_BASE + (port << 10))

/**
* @brief Convert a MCU port register address into its port number
*
*/
#ifdef STM32F1
#define GPIO_CPU_PORT_NUM(port) (((port >> 10) & 0x0f) - 2)
#else
#define GPIO_CPU_PORT_NUM(port) ((port >> 10) & 0x0f)
#endif

/**
* @brief Available MUX values for configuring a pin's alternate function
*/
typedef enum {
#ifdef CPU_FAM_STM32F1
GPIO_AF_OUT_PP = 0xb, /**< alternate function output - push-pull */
GPIO_AF_OUT_OD = 0xf, /**< alternate function output - open-drain */
#else
GPIO_AF0 = 0, /**< use alternate function 0 */
GPIO_AF1, /**< use alternate function 1 */
GPIO_AF2, /**< use alternate function 2 */
GPIO_AF3, /**< use alternate function 3 */
GPIO_AF4, /**< use alternate function 4 */
GPIO_AF5, /**< use alternate function 5 */
GPIO_AF6, /**< use alternate function 6 */
GPIO_AF7, /**< use alternate function 7 */
#ifndef CPU_FAM_STM32F0
GPIO_AF8, /**< use alternate function 8 */
GPIO_AF9, /**< use alternate function 9 */
GPIO_AF10, /**< use alternate function 10 */
GPIO_AF11, /**< use alternate function 11 */
GPIO_AF12, /**< use alternate function 12 */
GPIO_AF13, /**< use alternate function 13 */
GPIO_AF14, /**< use alternate function 14 */
GPIO_AF15 /**< use alternate function 15 */
#endif
#endif
} gpio_af_t;

#ifdef CPU_FAM_STM32F1
#ifndef DOXYGEN
/**
* @brief Generate GPIO mode bitfields
*
* We use 4 bit to determine the pin functions:
* - bit 4: ODR value
* - bit 2+3: in/out
* - bit 1: PU enable
* - bit 2: OD enable
*/
#define GPIO_MODE(mode, cnf, odr) (mode | (cnf << 2) | (odr << 4))

/**
* @brief Override GPIO mode options
*
* We use 4 bit to encode CNF and MODE.
* @{
*/
#define HAVE_GPIO_MODE_T
typedef enum {
GPIO_IN = GPIO_MODE(0, 1, 0), /**< input w/o pull R */
GPIO_IN_PD = GPIO_MODE(0, 2, 0), /**< input with pull-down */
GPIO_IN_PU = GPIO_MODE(0, 2, 1), /**< input with pull-up */
GPIO_OUT = GPIO_MODE(3, 0, 0), /**< push-pull output */
GPIO_OD = GPIO_MODE(3, 1, 0), /**< open-drain w/o pull R */
GPIO_OD_PU = (0xff) /**< not supported by HW */
} gpio_mode_t;
/** @} */
#endif /* ndef DOXYGEN */

/**
* @brief Override values for pull register configuration
* @{
*/
#define HAVE_GPIO_PP_T
typedef enum {
GPIO_NOPULL = 4, /**< do not use internal pull resistors */
GPIO_PULLUP = 9, /**< enable internal pull-up resistor */
GPIO_PULLDOWN = 8 /**< enable internal pull-down resistor */
} gpio_pp_t;
/** @} */
#else /* CPU_FAM_STM32F1 */
/**
* @brief Generate GPIO mode bitfields
*
* We use 5 bit to encode the mode:
* - bit 0+1: pin mode (input / output)
* - bit 2+3: pull resistor configuration
* - bit 4: output type (0: push-pull, 1: open-drain)
*/
#define GPIO_MODE(io, pr, ot) ((io << 0) | (pr << 2) | (ot << 4))

#ifndef DOXYGEN
/**
* @brief Override GPIO mode options
* @{
*/
#define HAVE_GPIO_MODE_T
typedef enum {
GPIO_IN = GPIO_MODE(0, 0, 0), /**< input w/o pull R */
GPIO_IN_PD = GPIO_MODE(0, 2, 0), /**< input with pull-down */
GPIO_IN_PU = GPIO_MODE(0, 1, 0), /**< input with pull-up */
GPIO_OUT = GPIO_MODE(1, 0, 0), /**< push-pull output */
GPIO_OD = GPIO_MODE(1, 0, 1), /**< open-drain w/o pull R */
GPIO_OD_PU = GPIO_MODE(1, 1, 1) /**< open-drain with pull-up */
} gpio_mode_t;
/** @} */
#endif /* ndef DOXYGEN */
#endif /* ndef CPU_FAM_STM32F1 */

#ifndef DOXYGEN
/**
* @brief Override flank configuration values
* @{
*/
#define HAVE_GPIO_FLANK_T
typedef enum {
GPIO_RISING = 1, /**< emit interrupt on rising flank */
GPIO_FALLING = 2, /**< emit interrupt on falling flank */
GPIO_BOTH = 3 /**< emit interrupt on both flanks */
} gpio_flank_t;
/** @} */
#endif /* ndef DOXYGEN */

#ifdef __cplusplus
}
#endif

#endif /* GPIO_ARCH_H */
/** @} */
Loading

0 comments on commit bd0b266

Please sign in to comment.