mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
cpu/stm32l1: remodel to new GPIO interface
This commit is contained in:
parent
bda86cfcd3
commit
c95612295e
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Freie Universität Berlin
|
||||
* Copyright (C) 2015 Hamburg University of Applied Sciences
|
||||
*
|
||||
* 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
|
||||
@ -14,18 +15,71 @@
|
||||
* @brief CPU specific definitions for internal peripheral handling
|
||||
*
|
||||
* @author Hauke Petersen <hauke.peterse@fu-berlin.de>
|
||||
* @author Katja Kirstein <katja.kirstein@haw-hamburg.de>
|
||||
*/
|
||||
|
||||
#ifndef PERIPH_CPU_H_
|
||||
#define PERIPH_CPU_H_
|
||||
|
||||
#include "cpu.h"
|
||||
#include "periph/dev_enums.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* nothing defined here, yet */
|
||||
/**
|
||||
* @brief Overwrite the default gpio_t type definition
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_GPIO_T
|
||||
typedef uint32_t gpio_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Definition of a fitting UNDEF value
|
||||
*/
|
||||
#define GPIO_UNDEF (0xffffffff)
|
||||
|
||||
/**
|
||||
* @brief Define a CPU specific GPIO pin generator macro
|
||||
*/
|
||||
#define GPIO(x, y) ((GPIOA_BASE + (x << 10)) | y)
|
||||
|
||||
/**
|
||||
* @brief Available ports on the STM32L1 family
|
||||
*/
|
||||
enum {
|
||||
PORT_A = 0, /**< port A */
|
||||
PORT_B = 1, /**< port B */
|
||||
PORT_C = 2, /**< port C */
|
||||
PORT_D = 3, /**< port D */
|
||||
PORT_E = 4, /**< port E */
|
||||
PORT_F = 6, /**< port F */
|
||||
PORT_G = 7, /**< port G */
|
||||
PORT_H = 5, /**< port H */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Available MUX values for configuring a pin's alternate function
|
||||
*/
|
||||
typedef enum {
|
||||
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 */
|
||||
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_af_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
* Copyright (C) 2015 Freie Universität Berlin
|
||||
* Copyright (C) 2015 Hamburg University of Applied Sciences
|
||||
*
|
||||
* 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
|
||||
@ -7,13 +8,14 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup driver_periph
|
||||
* @ingroup cpu_stm32l1
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Low-level GPIO driver implementation
|
||||
*
|
||||
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Katja Kirstein <katja.kirstein@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
@ -24,545 +26,199 @@
|
||||
#include "periph/gpio.h"
|
||||
#include "periph_conf.h"
|
||||
|
||||
#/**
|
||||
* @brief Number of available external interrupt lines
|
||||
*/
|
||||
#define GPIO_ISR_CHAN_NUMOF (16U)
|
||||
|
||||
/**
|
||||
* @brief Datastructure to hold an interrupt context
|
||||
*/
|
||||
typedef struct {
|
||||
gpio_cb_t cb;
|
||||
void *arg;
|
||||
} gpio_state_t;
|
||||
void (*cb)(void *arg); /**< interrupt callback routine */
|
||||
void *arg; /**< optional argument */
|
||||
} exti_ctx_t;
|
||||
|
||||
static gpio_state_t gpio_config[GPIO_NUMOF];
|
||||
/**
|
||||
* @brief Hold one callback function pointer for each interrupt line
|
||||
*/
|
||||
static exti_ctx_t exti_chan[GPIO_ISR_CHAN_NUMOF];
|
||||
|
||||
/* static port mappings */
|
||||
static GPIO_TypeDef *const gpio_port_map[GPIO_NUMOF] = {
|
||||
#if GPIO_0_EN
|
||||
[GPIO_0] = GPIO_0_PORT,
|
||||
#endif
|
||||
#if GPIO_1_EN
|
||||
[GPIO_1] = GPIO_1_PORT,
|
||||
#endif
|
||||
#if GPIO_2_EN
|
||||
[GPIO_2] = GPIO_2_PORT,
|
||||
#endif
|
||||
#if GPIO_3_EN
|
||||
[GPIO_3] = GPIO_3_PORT,
|
||||
#endif
|
||||
#if GPIO_4_EN
|
||||
[GPIO_4] = GPIO_4_PORT,
|
||||
#endif
|
||||
#if GPIO_5_EN
|
||||
[GPIO_5] = GPIO_5_PORT,
|
||||
#endif
|
||||
#if GPIO_6_EN
|
||||
[GPIO_6] = GPIO_6_PORT,
|
||||
#endif
|
||||
#if GPIO_7_EN
|
||||
[GPIO_7] = GPIO_7_PORT,
|
||||
#endif
|
||||
#if GPIO_8_EN
|
||||
[GPIO_8] = GPIO_8_PORT,
|
||||
#endif
|
||||
#if GPIO_9_EN
|
||||
[GPIO_9] = GPIO_9_PORT,
|
||||
#endif
|
||||
#if GPIO_10_EN
|
||||
[GPIO_10] = GPIO_10_PORT,
|
||||
#endif
|
||||
#if GPIO_11_EN
|
||||
[GPIO_11] = GPIO_11_PORT,
|
||||
#endif
|
||||
#if GPIO_12_EN
|
||||
[GPIO_12] = GPIO_12_PORT,
|
||||
#endif
|
||||
#if GPIO_13_EN
|
||||
[GPIO_13] = GPIO_13_PORT,
|
||||
#endif
|
||||
#if GPIO_14_EN
|
||||
[GPIO_14] = GPIO_14_PORT,
|
||||
#endif
|
||||
#if GPIO_15_EN
|
||||
[GPIO_15] = GPIO_15_PORT,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* static pin mappings */
|
||||
static const uint8_t gpio_pin_map[GPIO_NUMOF] = {
|
||||
#if GPIO_0_EN
|
||||
[GPIO_0] = GPIO_0_PIN,
|
||||
#endif
|
||||
#if GPIO_1_EN
|
||||
[GPIO_1] = GPIO_1_PIN,
|
||||
#endif
|
||||
#if GPIO_2_EN
|
||||
[GPIO_2] = GPIO_2_PIN,
|
||||
#endif
|
||||
#if GPIO_3_EN
|
||||
[GPIO_3] = GPIO_3_PIN,
|
||||
#endif
|
||||
#if GPIO_4_EN
|
||||
[GPIO_4] = GPIO_4_PIN,
|
||||
#endif
|
||||
#if GPIO_5_EN
|
||||
[GPIO_5] = GPIO_5_PIN,
|
||||
#endif
|
||||
#if GPIO_6_EN
|
||||
[GPIO_6] = GPIO_6_PIN,
|
||||
#endif
|
||||
#if GPIO_7_EN
|
||||
[GPIO_7] = GPIO_7_PIN,
|
||||
#endif
|
||||
#if GPIO_8_EN
|
||||
[GPIO_8] = GPIO_8_PIN,
|
||||
#endif
|
||||
#if GPIO_9_EN
|
||||
[GPIO_9] = GPIO_9_PIN,
|
||||
#endif
|
||||
#if GPIO_10_EN
|
||||
[GPIO_10] = GPIO_10_PIN,
|
||||
#endif
|
||||
#if GPIO_11_EN
|
||||
[GPIO_11] = GPIO_11_PIN,
|
||||
#endif
|
||||
#if GPIO_12_EN
|
||||
[GPIO_12] = GPIO_12_PIN,
|
||||
#endif
|
||||
#if GPIO_13_EN
|
||||
[GPIO_13] = GPIO_13_PIN,
|
||||
#endif
|
||||
#if GPIO_14_EN
|
||||
[GPIO_14] = GPIO_14_PIN,
|
||||
#endif
|
||||
#if GPIO_15_EN
|
||||
[GPIO_15] = GPIO_15_PIN,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* static irq mappings */
|
||||
static const IRQn_Type gpio_irq_map[GPIO_NUMOF] = {
|
||||
#if GPIO_0_EN
|
||||
[GPIO_0] = GPIO_0_IRQ,
|
||||
#endif
|
||||
#if GPIO_1_EN
|
||||
[GPIO_1] = GPIO_1_IRQ,
|
||||
#endif
|
||||
#if GPIO_2_EN
|
||||
[GPIO_2] = GPIO_2_IRQ,
|
||||
#endif
|
||||
#if GPIO_3_EN
|
||||
[GPIO_3] = GPIO_3_IRQ,
|
||||
#endif
|
||||
#if GPIO_4_EN
|
||||
[GPIO_4] = GPIO_4_IRQ,
|
||||
#endif
|
||||
#if GPIO_5_EN
|
||||
[GPIO_5] = GPIO_5_IRQ,
|
||||
#endif
|
||||
#if GPIO_6_EN
|
||||
[GPIO_6] = GPIO_6_IRQ,
|
||||
#endif
|
||||
#if GPIO_7_EN
|
||||
[GPIO_7] = GPIO_7_IRQ,
|
||||
#endif
|
||||
#if GPIO_8_EN
|
||||
[GPIO_8] = GPIO_8_IRQ,
|
||||
#endif
|
||||
#if GPIO_9_EN
|
||||
[GPIO_9] = GPIO_9_IRQ,
|
||||
#endif
|
||||
#if GPIO_10_EN
|
||||
[GPIO_10] = GPIO_10_IRQ,
|
||||
#endif
|
||||
#if GPIO_11_EN
|
||||
[GPIO_11] = GPIO_11_IRQ,
|
||||
#endif
|
||||
#if GPIO_12_EN
|
||||
[GPIO_12] = GPIO_12_IRQ,
|
||||
#endif
|
||||
#if GPIO_13_EN
|
||||
[GPIO_13] = GPIO_13_IRQ,
|
||||
#endif
|
||||
#if GPIO_14_EN
|
||||
[GPIO_14] = GPIO_14_IRQ,
|
||||
#endif
|
||||
#if GPIO_15_EN
|
||||
[GPIO_15] = GPIO_15_IRQ,
|
||||
#endif
|
||||
};
|
||||
|
||||
int gpio_init(gpio_t dev, gpio_dir_t dir, gpio_pp_t pullup)
|
||||
/**
|
||||
* @brief Extract the port base address from the given pin identifier
|
||||
*/
|
||||
static inline GPIO_TypeDef *_port(gpio_t pin)
|
||||
{
|
||||
GPIO_TypeDef *port;
|
||||
uint8_t pin;
|
||||
|
||||
if (dev >= GPIO_NUMOF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
port = gpio_port_map[dev];
|
||||
pin = gpio_pin_map[dev];
|
||||
|
||||
if (dir == GPIO_DIR_OUT) {
|
||||
port->MODER &= ~(2 << (2 * pin)); /* set pin to output mode */
|
||||
port->MODER |= (1 << (2 * pin));
|
||||
port->OTYPER &= ~(1 << pin); /* set to push-pull configuration */
|
||||
port->OSPEEDR |= (3 << (2 * pin)); /* set to high speed */
|
||||
port->ODR &= ~(1 << pin); /* set pin to low signal */
|
||||
}
|
||||
else {
|
||||
port->MODER &= ~(3 << (2 * pin)); /* configure pin as input */
|
||||
}
|
||||
port->PUPDR &= ~(3 << (2 * pin)); /* configure push-pull resistors */
|
||||
port->PUPDR |= (pullup << (2 * pin));
|
||||
|
||||
return 0; /* all OK */
|
||||
return (GPIO_TypeDef *)(pin & ~(0x0f));
|
||||
}
|
||||
|
||||
int gpio_init_int(gpio_t dev, gpio_pp_t pullup, gpio_flank_t flank, gpio_cb_t cb, void *arg)
|
||||
/**
|
||||
* @brief Extract the port number form the given identifier
|
||||
*
|
||||
* The port number is extracted by looking at bits 10, 11, 12, 13 of the base
|
||||
* register addresses.
|
||||
*/
|
||||
static inline int _port_num(gpio_t pin)
|
||||
{
|
||||
int res;
|
||||
uint8_t pin;
|
||||
return ((pin >> 10) & 0x0f);
|
||||
}
|
||||
|
||||
if (dev >= GPIO_NUMOF) {
|
||||
return -1;
|
||||
/**
|
||||
* @brief Extract the pin number from the last 4 bit of the pin identifier
|
||||
*/
|
||||
static inline int _pin_num(gpio_t pin)
|
||||
{
|
||||
return (pin & 0x0f);
|
||||
}
|
||||
|
||||
int gpio_init(gpio_t pin, gpio_dir_t dir, gpio_pp_t pullup)
|
||||
{
|
||||
GPIO_TypeDef *port = _port(pin);
|
||||
int pin_num = _pin_num(pin);
|
||||
|
||||
/* enable clock */
|
||||
RCC->AHBENR |= (RCC_AHBENR_GPIOAEN << _port_num(pin));
|
||||
/* configure pull register */
|
||||
port->PUPDR &= ~(3 << (2 * pin_num));
|
||||
port->PUPDR |= (pullup << (2 * pin_num));
|
||||
/* set direction */
|
||||
if (dir == GPIO_DIR_OUT) {
|
||||
port->MODER &= ~(3 << (2 * pin_num)); /* set pin to output mode */
|
||||
port->MODER |= (1 << (2 * pin_num));
|
||||
port->OTYPER &= ~(1 << pin_num); /* set to push-pull */
|
||||
port->OSPEEDR |= (3 << (2 * pin_num)); /* set to high speed */
|
||||
port->ODR &= ~(1 << pin_num); /* set pin to low signal */
|
||||
}
|
||||
|
||||
pin = gpio_pin_map[dev];
|
||||
|
||||
/* configure pin as input */
|
||||
res = gpio_init(dev, GPIO_DIR_IN, pullup);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
else {
|
||||
port->MODER &= ~(3 << (2 * pin_num)); /* configure pin as input */
|
||||
}
|
||||
|
||||
/* enable clock of the SYSCFG module for EXTI configuration */
|
||||
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
|
||||
|
||||
/* read pin number, set EXIT channel and enable global interrupt for EXTI channel */
|
||||
switch (dev) {
|
||||
#ifdef GPIO_0_EN
|
||||
case GPIO_0:
|
||||
GPIO_0_EXTI_CFG();
|
||||
break;
|
||||
#endif
|
||||
#ifdef GPIO_1_EN
|
||||
case GPIO_1:
|
||||
GPIO_1_EXTI_CFG();
|
||||
break;
|
||||
#endif
|
||||
#ifdef GPIO_2_EN
|
||||
case GPIO_2:
|
||||
GPIO_2_EXTI_CFG();
|
||||
break;
|
||||
#endif
|
||||
#ifdef GPIO_3_EN
|
||||
case GPIO_3:
|
||||
GPIO_3_EXTI_CFG();
|
||||
break;
|
||||
#endif
|
||||
#ifdef GPIO_4_EN
|
||||
case GPIO_4:
|
||||
GPIO_4_EXTI_CFG();
|
||||
break;
|
||||
#endif
|
||||
#ifdef GPIO_5_EN
|
||||
case GPIO_5:
|
||||
GPIO_5_EXTI_CFG();
|
||||
break;
|
||||
#endif
|
||||
#ifdef GPIO_6_EN
|
||||
case GPIO_6:
|
||||
GPIO_6_EXTI_CFG();
|
||||
break;
|
||||
#endif
|
||||
#ifdef GPIO_7_EN
|
||||
case GPIO_7:
|
||||
GPIO_7_EXTI_CFG();
|
||||
break;
|
||||
#endif
|
||||
#ifdef GPIO_8_EN
|
||||
case GPIO_8:
|
||||
GPIO_8_EXTI_CFG();
|
||||
break;
|
||||
#endif
|
||||
#ifdef GPIO_9_EN
|
||||
case GPIO_9:
|
||||
GPIO_9_EXTI_CFG();
|
||||
break;
|
||||
#endif
|
||||
#ifdef GPIO_10_EN
|
||||
case GPIO_10:
|
||||
GPIO_10_EXTI_CFG();
|
||||
break;
|
||||
#endif
|
||||
#ifdef GPIO_11_EN
|
||||
case GPIO_11:
|
||||
GPIO_11_EXTI_CFG();
|
||||
break;
|
||||
#endif
|
||||
#ifdef GPIO_12_EN
|
||||
case GPIO_12:
|
||||
GPIO_12_EXTI_CFG();
|
||||
break;
|
||||
#endif
|
||||
#ifdef GPIO_13_EN
|
||||
case GPIO_13:
|
||||
GPIO_13_EXTI_CFG();
|
||||
break;
|
||||
#endif
|
||||
#ifdef GPIO_14_EN
|
||||
case GPIO_14:
|
||||
GPIO_14_EXTI_CFG();
|
||||
break;
|
||||
#endif
|
||||
#ifdef GPIO_15_EN
|
||||
case GPIO_15:
|
||||
GPIO_15_EXTI_CFG();
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
NVIC_EnableIRQ(gpio_irq_map[dev]);
|
||||
|
||||
/* set callback */
|
||||
gpio_config[dev].cb = cb;
|
||||
gpio_config[dev].arg = arg;
|
||||
|
||||
/* configure the event that triggers an interrupt */
|
||||
switch (flank) {
|
||||
case GPIO_RISING:
|
||||
EXTI->RTSR |= (1 << pin);
|
||||
EXTI->FTSR &= ~(1 << pin);
|
||||
break;
|
||||
case GPIO_FALLING:
|
||||
EXTI->RTSR &= ~(1 << pin);
|
||||
EXTI->FTSR |= (1 << pin);
|
||||
break;
|
||||
case GPIO_BOTH:
|
||||
EXTI->RTSR |= (1 << pin);
|
||||
EXTI->FTSR |= (1 << pin);
|
||||
break;
|
||||
}
|
||||
|
||||
/* clear any pending requests */
|
||||
EXTI->PR = (1 << pin);
|
||||
/* unmask the pins interrupt channel */
|
||||
EXTI->IMR |= (1 << pin);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gpio_irq_enable(gpio_t dev)
|
||||
int gpio_init_int(gpio_t pin,
|
||||
gpio_pp_t pullup, gpio_flank_t flank,
|
||||
gpio_cb_t cb, void *arg)
|
||||
{
|
||||
uint8_t pin;
|
||||
int pin_num = _pin_num(pin);
|
||||
int port_num = _port_num(pin);
|
||||
|
||||
if (dev >= GPIO_NUMOF) {
|
||||
return;
|
||||
/* configure and save exti configuration struct */
|
||||
exti_chan[pin_num].cb = cb;
|
||||
exti_chan[pin_num].arg = arg;
|
||||
/* enable the SYSCFG clock */
|
||||
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
|
||||
/* initialize pin as input */
|
||||
gpio_init(pin, GPIO_DIR_IN, pullup);
|
||||
/* enable global pin interrupt */
|
||||
if (pin_num < 5) {
|
||||
NVIC_EnableIRQ(EXTI0_IRQn + pin_num);
|
||||
}
|
||||
|
||||
pin = gpio_pin_map[dev];
|
||||
EXTI->IMR |= (1 << pin);
|
||||
else if (pin_num < 10) {
|
||||
NVIC_EnableIRQ(EXTI9_5_IRQn);
|
||||
}
|
||||
else {
|
||||
NVIC_EnableIRQ(EXTI15_10_IRQn);
|
||||
}
|
||||
/* configure the active edge(s) */
|
||||
switch (flank) {
|
||||
case GPIO_RISING:
|
||||
EXTI->RTSR |= (1 << pin_num);
|
||||
EXTI->FTSR &= ~(1 << pin_num);
|
||||
break;
|
||||
case GPIO_FALLING:
|
||||
EXTI->RTSR &= ~(1 << pin_num);
|
||||
EXTI->FTSR |= (1 << pin_num);
|
||||
break;
|
||||
case GPIO_BOTH:
|
||||
EXTI->RTSR |= (1 << pin_num);
|
||||
EXTI->FTSR |= (1 << pin_num);
|
||||
break;
|
||||
}
|
||||
/* enable specific pin as exti sources */
|
||||
SYSCFG->EXTICR[pin_num >> 2] &= ~(0xf << ((pin_num & 0x03) * 4));
|
||||
SYSCFG->EXTICR[pin_num >> 2] |= (port_num << ((pin_num & 0x03) * 4));
|
||||
/* clear any pending requests */
|
||||
EXTI->PR = (1 << pin_num);
|
||||
/* enable interrupt for EXTI line */
|
||||
EXTI->IMR |= (1 << pin_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gpio_irq_disable(gpio_t dev)
|
||||
void gpio_init_af(gpio_t pin, gpio_af_t af)
|
||||
{
|
||||
uint8_t pin;
|
||||
GPIO_TypeDef *port = _port(pin);
|
||||
uint32_t pin_num = _pin_num(pin);
|
||||
|
||||
if (dev >= GPIO_NUMOF) {
|
||||
return;
|
||||
}
|
||||
|
||||
pin = gpio_pin_map[dev];
|
||||
EXTI->IMR &= ~(1 << pin);
|
||||
/* set pin to AF mode */
|
||||
port->MODER &= ~(3 << (2 * pin_num));
|
||||
port->MODER |= (2 << (2 * pin_num));
|
||||
/* set selected function */
|
||||
port->AFR[(pin_num > 7) ? 1 : 0] &= ~(0xf << ((pin_num & 0x07) * 4));
|
||||
port->AFR[(pin_num > 7) ? 1 : 0] |= (af << ((pin_num & 0x07) * 4));
|
||||
}
|
||||
|
||||
int gpio_read(gpio_t dev)
|
||||
void gpio_irq_enable(gpio_t pin)
|
||||
{
|
||||
GPIO_TypeDef *port;
|
||||
uint8_t pin;
|
||||
EXTI->IMR |= (1 << _pin_num(pin));
|
||||
}
|
||||
|
||||
if (dev >= GPIO_NUMOF) {
|
||||
return -1;
|
||||
void gpio_irq_disable(gpio_t pin)
|
||||
{
|
||||
EXTI->IMR &= ~(1 << _pin_num(pin));
|
||||
}
|
||||
|
||||
int gpio_read(gpio_t pin)
|
||||
{
|
||||
GPIO_TypeDef *port = _port(pin);
|
||||
uint32_t pin_num = _pin_num(pin);
|
||||
|
||||
if (port->MODER & (3 << (pin_num * 2))) { /* if configured as output */
|
||||
return port->ODR & (1 << pin_num); /* read output data reg */
|
||||
}
|
||||
|
||||
port = gpio_port_map[dev];
|
||||
pin = gpio_pin_map[dev];
|
||||
|
||||
if (port->MODER & (1 << (pin * 2))) { /* if configured as output */
|
||||
return port->ODR & (1 << pin); /* read output data register */
|
||||
} else {
|
||||
return port->IDR & (1 << pin); /* else read input data register */
|
||||
else {
|
||||
return port->IDR & (1 << pin_num); /* else read input data reg */
|
||||
}
|
||||
}
|
||||
|
||||
void gpio_set(gpio_t dev)
|
||||
void gpio_set(gpio_t pin)
|
||||
{
|
||||
GPIO_TypeDef *port;
|
||||
uint8_t pin;
|
||||
|
||||
if (dev >= GPIO_NUMOF) {
|
||||
return;
|
||||
}
|
||||
|
||||
port = gpio_port_map[dev];
|
||||
pin = gpio_pin_map[dev];
|
||||
|
||||
port->ODR |= (1 << pin);
|
||||
_port(pin)->BSRRL = (1 << _pin_num(pin));
|
||||
}
|
||||
|
||||
void gpio_clear(gpio_t dev)
|
||||
void gpio_clear(gpio_t pin)
|
||||
{
|
||||
GPIO_TypeDef *port;
|
||||
uint8_t pin;
|
||||
|
||||
if (dev >= GPIO_NUMOF) {
|
||||
return;
|
||||
}
|
||||
|
||||
port = gpio_port_map[dev];
|
||||
pin = gpio_pin_map[dev];
|
||||
|
||||
port->ODR &= ~(1 << pin);
|
||||
_port(pin)->BSRRH = (1 << _pin_num(pin));
|
||||
}
|
||||
|
||||
void gpio_toggle(gpio_t dev)
|
||||
void gpio_toggle(gpio_t pin)
|
||||
{
|
||||
if (gpio_read(dev)) {
|
||||
gpio_clear(dev);
|
||||
} else {
|
||||
gpio_set(dev);
|
||||
if (gpio_read(pin)) {
|
||||
gpio_clear(pin);
|
||||
}
|
||||
else {
|
||||
gpio_set(pin);
|
||||
}
|
||||
}
|
||||
|
||||
void gpio_write(gpio_t dev, int value)
|
||||
void gpio_write(gpio_t pin, int value)
|
||||
{
|
||||
if (value) {
|
||||
gpio_set(dev);
|
||||
} else {
|
||||
gpio_clear(dev);
|
||||
gpio_set(pin);
|
||||
}
|
||||
else {
|
||||
gpio_clear(pin);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GPIO_IRQ_0
|
||||
void isr_exti0(void)
|
||||
void isr_exti(void)
|
||||
{
|
||||
if (EXTI->PR & EXTI_PR_PR0) {
|
||||
EXTI->PR |= EXTI_PR_PR0; /* clear status bit by writing a 1 to it */
|
||||
gpio_config[GPIO_IRQ_0].cb(gpio_config[GPIO_IRQ_0].arg);
|
||||
for (int i = 0; i < GPIO_ISR_CHAN_NUMOF; i++) {
|
||||
if (EXTI->PR & (1 << i)) {
|
||||
EXTI->PR |= (1 << i); /* clear by writing a 1 */
|
||||
exti_chan[i].cb(exti_chan[i].arg);
|
||||
}
|
||||
}
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef GPIO_IRQ_1
|
||||
void isr_exti1(void)
|
||||
{
|
||||
if (EXTI->PR & EXTI_PR_PR1) {
|
||||
EXTI->PR |= EXTI_PR_PR1; /* clear status bit by writing a 1 to it */
|
||||
gpio_config[GPIO_IRQ_1].cb(gpio_config[GPIO_IRQ_1].arg);
|
||||
}
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef GPIO_IRQ_2
|
||||
void isr_exti2(void)
|
||||
{
|
||||
if (EXTI->PR & EXTI_PR_PR2) {
|
||||
EXTI->PR |= EXTI_PR_PR2; /* clear status bit by writing a 1 to it */
|
||||
gpio_config[GPIO_IRQ_2].cb(gpio_config[GPIO_IRQ_2].arg);
|
||||
}
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef GPIO_IRQ_3
|
||||
void isr_exti3(void)
|
||||
{
|
||||
if (EXTI->PR & EXTI_PR_PR3) {
|
||||
EXTI->PR |= EXTI_PR_PR3; /* clear status bit by writing a 1 to it */
|
||||
gpio_config[GPIO_IRQ_3].cb(gpio_config[GPIO_IRQ_3].arg);
|
||||
}
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef GPIO_IRQ_4
|
||||
void isr_exti4(void)
|
||||
{
|
||||
if (EXTI->PR & EXTI_PR_PR4) {
|
||||
EXTI->PR |= EXTI_PR_PR4; /* clear status bit by writing a 1 to it */
|
||||
gpio_config[GPIO_IRQ_4].cb(gpio_config[GPIO_IRQ_4].arg);
|
||||
}
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GPIO_IRQ_5) || defined(GPIO_IRQ_6) || defined(GPIO_IRQ_7) || defined(GPIO_IRQ_8) || defined(GPIO_IRQ_9)
|
||||
void isr_exti9_5(void)
|
||||
{
|
||||
if (EXTI->PR & EXTI_PR_PR5) {
|
||||
EXTI->PR |= EXTI_PR_PR5; /* clear status bit by writing a 1 to it */
|
||||
gpio_config[GPIO_IRQ_5].cb(gpio_config[GPIO_IRQ_5].arg);
|
||||
}
|
||||
else if (EXTI->PR & EXTI_PR_PR6) {
|
||||
EXTI->PR |= EXTI_PR_PR6; /* clear status bit by writing a 1 to it */
|
||||
gpio_config[GPIO_IRQ_6].cb(gpio_config[GPIO_IRQ_6].arg);
|
||||
}
|
||||
else if (EXTI->PR & EXTI_PR_PR7) {
|
||||
EXTI->PR |= EXTI_PR_PR7; /* clear status bit by writing a 1 to it */
|
||||
gpio_config[GPIO_IRQ_7].cb(gpio_config[GPIO_IRQ_7].arg);
|
||||
}
|
||||
else if (EXTI->PR & EXTI_PR_PR8) {
|
||||
EXTI->PR |= EXTI_PR_PR8; /* clear status bit by writing a 1 to it */
|
||||
gpio_config[GPIO_IRQ_8].cb(gpio_config[GPIO_IRQ_8].arg);
|
||||
}
|
||||
else if (EXTI->PR & EXTI_PR_PR9) {
|
||||
EXTI->PR |= EXTI_PR_PR9; /* clear status bit by writing a 1 to it */
|
||||
gpio_config[GPIO_IRQ_9].cb(gpio_config[GPIO_IRQ_9].arg);
|
||||
}
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GPIO_IRQ_10) || defined(GPIO_IRQ_11) || defined(GPIO_IRQ_12) || defined(GPIO_IRQ_13) || defined(GPIO_IRQ_14) || defined(GPIO_IRQ_15)
|
||||
void isr_exti15_10(void)
|
||||
{
|
||||
if (EXTI->PR & EXTI_PR_PR10) {
|
||||
EXTI->PR |= EXTI_PR_PR10; /* clear status bit by writing a 1 to it */
|
||||
gpio_config[GPIO_IRQ_10].cb(gpio_config[GPIO_IRQ_10].arg);
|
||||
}
|
||||
else if (EXTI->PR & EXTI_PR_PR11) {
|
||||
EXTI->PR |= EXTI_PR_PR11; /* clear status bit by writing a 1 to it */
|
||||
gpio_config[GPIO_IRQ_11].cb(gpio_config[GPIO_IRQ_11].arg);
|
||||
}
|
||||
else if (EXTI->PR & EXTI_PR_PR12) {
|
||||
EXTI->PR |= EXTI_PR_PR12; /* clear status bit by writing a 1 to it */
|
||||
gpio_config[GPIO_IRQ_12].cb(gpio_config[GPIO_IRQ_12].arg);
|
||||
}
|
||||
else if (EXTI->PR & EXTI_PR_PR13) {
|
||||
EXTI->PR |= EXTI_PR_PR13; /* clear status bit by writing a 1 to it */
|
||||
gpio_config[GPIO_IRQ_13].cb(gpio_config[GPIO_IRQ_13].arg);
|
||||
}
|
||||
else if (EXTI->PR & EXTI_PR_PR14) {
|
||||
EXTI->PR |= EXTI_PR_PR14; /* clear status bit by writing a 1 to it */
|
||||
gpio_config[GPIO_IRQ_14].cb(gpio_config[GPIO_IRQ_14].arg);
|
||||
}
|
||||
else if (EXTI->PR & EXTI_PR_PR15) {
|
||||
EXTI->PR |= EXTI_PR_PR15; /* clear status bit by writing a 1 to it */
|
||||
gpio_config[GPIO_IRQ_15].cb(gpio_config[GPIO_IRQ_15].arg);
|
||||
}
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -492,14 +492,12 @@ void i2c_poweroff(i2c_t dev)
|
||||
#if I2C_0_EN
|
||||
case I2C_0:
|
||||
while (I2C_0_DEV->SR2 & I2C_SR2_BUSY);
|
||||
|
||||
I2C_0_CLKDIS();
|
||||
break;
|
||||
#endif
|
||||
#if I2C_1_EN
|
||||
case I2C_1:
|
||||
while (I2C_0_DEV->SR2 & I2C_SR2_BUSY);
|
||||
|
||||
I2C_0_CLKDIS();
|
||||
break;
|
||||
#endif
|
||||
|
@ -42,11 +42,7 @@ WEAK_DEFAULT void isr_tamper_stamp(void);
|
||||
WEAK_DEFAULT void isr_rtc_wkup(void);
|
||||
WEAK_DEFAULT void isr_flash(void);
|
||||
WEAK_DEFAULT void isr_rcc(void);
|
||||
WEAK_DEFAULT void isr_exti0(void);
|
||||
WEAK_DEFAULT void isr_exti1(void);
|
||||
WEAK_DEFAULT void isr_exti2(void);
|
||||
WEAK_DEFAULT void isr_exti3(void);
|
||||
WEAK_DEFAULT void isr_exti4(void);
|
||||
WEAK_DEFAULT void isr_exti(void);
|
||||
WEAK_DEFAULT void isr_dma1_ch1(void);
|
||||
WEAK_DEFAULT void isr_dma1_ch2(void);
|
||||
WEAK_DEFAULT void isr_dma1_ch3(void);
|
||||
@ -59,7 +55,6 @@ WEAK_DEFAULT void isr_usb_hp(void);
|
||||
WEAK_DEFAULT void isr_usb_lp(void);
|
||||
WEAK_DEFAULT void isr_dac(void);
|
||||
WEAK_DEFAULT void isr_comp(void);
|
||||
WEAK_DEFAULT void isr_exti9_5(void);
|
||||
WEAK_DEFAULT void isr_lcd(void);
|
||||
WEAK_DEFAULT void isr_tim9(void);
|
||||
WEAK_DEFAULT void isr_tim10(void);
|
||||
@ -76,7 +71,6 @@ WEAK_DEFAULT void isr_spi2(void);
|
||||
WEAK_DEFAULT void isr_usart1(void);
|
||||
WEAK_DEFAULT void isr_usart2(void);
|
||||
WEAK_DEFAULT void isr_usart3(void);
|
||||
WEAK_DEFAULT void isr_exti15_10(void);
|
||||
WEAK_DEFAULT void isr_rtc_alarm(void);
|
||||
WEAK_DEFAULT void isr_usb_fs_wkup(void);
|
||||
WEAK_DEFAULT void isr_tim6(void);
|
||||
@ -123,11 +117,11 @@ ISR_VECTORS const void *interrupt_vector[] = {
|
||||
(void*) isr_rtc_wkup,
|
||||
(void*) isr_flash,
|
||||
(void*) isr_rcc,
|
||||
(void*) isr_exti0,
|
||||
(void*) isr_exti1,
|
||||
(void*) isr_exti2,
|
||||
(void*) isr_exti3,
|
||||
(void*) isr_exti4,
|
||||
(void*) isr_exti,
|
||||
(void*) isr_exti,
|
||||
(void*) isr_exti,
|
||||
(void*) isr_exti,
|
||||
(void*) isr_exti,
|
||||
(void*) isr_dma1_ch1,
|
||||
(void*) isr_dma1_ch2,
|
||||
(void*) isr_dma1_ch3,
|
||||
@ -140,7 +134,7 @@ ISR_VECTORS const void *interrupt_vector[] = {
|
||||
(void*) isr_usb_lp,
|
||||
(void*) isr_dac,
|
||||
(void*) isr_comp,
|
||||
(void*) isr_exti9_5,
|
||||
(void*) isr_exti,
|
||||
(void*) isr_lcd,
|
||||
(void*) isr_tim9,
|
||||
(void*) isr_tim10,
|
||||
@ -157,7 +151,7 @@ ISR_VECTORS const void *interrupt_vector[] = {
|
||||
(void*) isr_usart1,
|
||||
(void*) isr_usart2,
|
||||
(void*) isr_usart3,
|
||||
(void*) isr_exti15_10,
|
||||
(void*) isr_exti,
|
||||
(void*) isr_rtc_alarm,
|
||||
(void*) isr_usb_fs_wkup,
|
||||
(void*) isr_tim6,
|
||||
|
Loading…
Reference in New Issue
Block a user