You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
182 lines
4.8 KiB
182 lines
4.8 KiB
#ifndef _GPIO_H |
|
#define _GPIO_H |
|
|
|
#include "hal_types.h" |
|
#include "exti.h" |
|
|
|
|
|
/** |
|
* @brief GPIO Pin modes. |
|
* |
|
* These only allow for 50MHZ max output speeds; if you want slower, |
|
* use direct register access. |
|
*/ |
|
|
|
/* |
|
we should define modes to be compatible with HAL_GPIO_ defines from HAL.h |
|
#define HAL_GPIO_INPUT 0 |
|
#define HAL_GPIO_OUTPUT 1 |
|
#define HAL_GPIO_ALT 2 |
|
|
|
*/ |
|
|
|
typedef enum gpio_pin_mode { |
|
GPIO_INPUT_FLOATING, /**< Input floating. */ |
|
GPIO_OUTPUT_PP, /**< Output push-pull. */ |
|
GPIO_AF_OUTPUT_PP, /**< Alternate function output push-pull. */ |
|
// more complex modes |
|
GPIO_INPUT_ANALOG, /**< Analog input. */ |
|
GPIO_INPUT_PD, /**< Input pull-down. */ |
|
GPIO_INPUT_PU, /**< Input pull-up. */ |
|
/* GPIO_INPUT_PU treated as a special case, for ODR twiddling */ |
|
GPIO_OUTPUT_OD, /**< Output open-drain. */ |
|
GPIO_OUTPUT_OD_PU, /**< Output open-drain with pullUp */ |
|
GPIO_AF_OUTPUT_OD, /**< Alternate function output open drain. */ |
|
GPIO_AF_OUTPUT_OD_PU, /**< Alternate function output open drain with pullup */ |
|
GPIO_PIN_MODE_LAST |
|
} gpio_pin_mode; |
|
|
|
#define Bit_RESET 0 |
|
#define Bit_SET 1 |
|
|
|
typedef enum |
|
{ |
|
GPIO_speed_2MHz = 0x00, /*!< Low speed */ |
|
GPIO_speed_25MHz = 0x01, /*!< Medium speed */ |
|
GPIO_speed_50MHz = 0x02, /*!< Fast speed */ |
|
GPIO_speed_100MHz = 0x03 /*!< High speed on 30 pF (80 MHz Output max speed on 15 pF) */ |
|
} GPIOSpeed_t; |
|
|
|
|
|
|
|
/** GPIO device type */ |
|
typedef struct gpio_dev { |
|
GPIO_TypeDef *GPIOx; /**< Register map */ |
|
uint32_t clk; /**< RCC clock information */ |
|
afio_exti_port exti_port; /**< AFIO external interrupt port value */ |
|
} gpio_dev; |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
extern const gpio_dev gpioa; |
|
extern const gpio_dev* const _GPIOA; |
|
extern const gpio_dev gpiob; |
|
extern const gpio_dev* const _GPIOB; |
|
extern const gpio_dev gpioc; |
|
extern const gpio_dev* const _GPIOC; |
|
extern const gpio_dev gpiod; |
|
extern const gpio_dev* const _GPIOD; |
|
extern const gpio_dev gpioe; |
|
extern const gpio_dev* const _GPIOE; |
|
extern const gpio_dev gpiof; |
|
extern const gpio_dev* const _GPIOF; |
|
extern const gpio_dev gpiog; |
|
extern const gpio_dev* const _GPIOG; |
|
|
|
/** |
|
* Initialize a GPIO device. |
|
*/ |
|
extern void gpio_init(const gpio_dev* const dev); |
|
|
|
/** |
|
* Initialize and reset all available GPIO devices. |
|
*/ |
|
extern void gpio_init_all(void); |
|
|
|
/** |
|
* Set the mode of a GPIO pin. |
|
*/ |
|
extern void gpio_set_mode(const gpio_dev* const dev, uint8_t pin, gpio_pin_mode mode); |
|
|
|
|
|
/** |
|
* Set the alternate function mode of a GPIO pin. |
|
* |
|
* @param dev GPIO device. |
|
* @param pin Pin on the device whose mode to set, 0--15. |
|
* @param mode alternate function mode to set the pin to. |
|
* @see gpio_pin_mode |
|
*/ |
|
static inline void gpio_set_af_mode(const gpio_dev* const dev, uint8_t pin, uint8_t mode) |
|
{ |
|
/* Check the parameters */ |
|
assert_param(IS_GPIO_ALL_PERIPH(dev->GPIOx)); |
|
assert_param(IS_GPIO_PIN_SOURCE(pin)); |
|
assert_param(IS_GPIO_AF(mode)); |
|
|
|
// GPIO_PinAFConfig(dev->GPIOx, pin, mode); |
|
uint32_t temp = dev->GPIOx->AFR[pin >> 0x03] & ~((uint32_t)0xF << ((uint32_t)((uint32_t)pin & (uint32_t)0x07) * 4)); |
|
dev->GPIOx->AFR[pin >> 0x03] = temp | ((uint32_t)(mode) << ((uint32_t)((uint32_t)pin & (uint32_t)0x07) * 4)); |
|
} |
|
|
|
|
|
static INLINE void gpio_write_bit(const gpio_dev* const dev, uint8_t pin, uint8_t val) |
|
{ |
|
/* Check the parameters */ |
|
assert_param(IS_GPIO_ALL_PERIPH(dev->GPIOx)); |
|
assert_param(IS_GPIO_PIN_SOURCE(pin)); |
|
|
|
uint16_t bv = BIT(pin); |
|
|
|
if (val) { |
|
dev->GPIOx->BSRRL = bv; |
|
} else { |
|
dev->GPIOx->BSRRH = bv; |
|
} |
|
} |
|
|
|
static INLINE uint8_t gpio_read_bit(const gpio_dev* const dev, uint8_t pin) |
|
{ |
|
/* Check the parameters */ |
|
assert_param(IS_GPIO_ALL_PERIPH(dev->GPIOx)); |
|
assert_param(IS_GPIO_PIN_SOURCE(pin)); |
|
|
|
if ((dev->GPIOx->IDR & BIT(pin)) != Bit_RESET){ |
|
return (uint8_t)Bit_SET; |
|
} |
|
|
|
return (uint8_t)Bit_RESET; |
|
|
|
|
|
} |
|
|
|
static inline void gpio_toggle_bit(const gpio_dev* const dev, uint8_t pin) |
|
{ |
|
/* Check the parameters */ |
|
assert_param(IS_GPIO_ALL_PERIPH(dev->GPIOx)); |
|
assert_param(IS_GPIO_PIN_SOURCE(pin)); |
|
dev->GPIOx->ODR ^= BIT(pin); |
|
} |
|
|
|
static inline afio_exti_port gpio_exti_port(const gpio_dev* const dev) |
|
{ |
|
/* Check the parameters */ |
|
assert_param(IS_GPIO_ALL_PERIPH(dev->GPIOx)); |
|
return dev->exti_port; |
|
} |
|
|
|
|
|
static inline void gpio_set_speed(const gpio_dev* const dev, uint8_t pin, GPIOSpeed_t gpio_speed){ |
|
/* Speed mode configuration */ |
|
dev->GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (pin * 2)); |
|
dev->GPIOx->OSPEEDR |= ((uint32_t)(gpio_speed) << (pin * 2)); |
|
} |
|
|
|
|
|
static inline void afio_exti_select(afio_exti_port gpio_port, afio_exti_num pin) |
|
{ |
|
uint32_t tmp = ((uint32_t)0x0F) << (0x04 * (pin & (uint8_t)0x03)); |
|
SYSCFG->EXTICR[pin >> 0x02] &= ~tmp; |
|
SYSCFG->EXTICR[pin >> 0x02] |= (((uint32_t)gpio_port) << (0x04 * (pin & (uint8_t)0x03))); |
|
|
|
} |
|
|
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
|
|
#endif |
|
|
|
|