aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmaple/gpio.c28
-rw-r--r--libmaple/gpio.h222
2 files changed, 191 insertions, 59 deletions
diff --git a/libmaple/gpio.c b/libmaple/gpio.c
index c250f68..2c58cc2 100644
--- a/libmaple/gpio.c
+++ b/libmaple/gpio.c
@@ -145,7 +145,7 @@ void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode) {
*/
/**
- * Initialize the AFIO clock, and reset the AFIO registers.
+ * @brief Initialize the AFIO clock, and reset the AFIO registers.
*/
void afio_init(void) {
rcc_clk_enable(RCC_AFIO);
@@ -155,15 +155,12 @@ void afio_init(void) {
#define AFIO_EXTI_SEL_MASK 0xF
/**
- * Select a source input for an external interrupt.
+ * @brief Select a source input for an external interrupt.
*
- * @param exti External interrupt. One of: AFIO_EXTI_0,
- * AFIO_EXTI_1, ..., AFIO_EXTI_15.
+ * @param exti External interrupt.
* @param gpio_port Port which contains pin to use as source input.
- * One of: AFIO_EXTI_PA, AFIO_EXTI_PB, AFIO_EXTI_PC,
- * AFIO_EXTI_PD, and, on high density devices,
- * AFIO_EXTI_PE, AFIO_EXTI_PF, AFIO_EXTI_PG.
- * @see exti_port
+ * @see afio_exti_num
+ * @see afio_exti_port
*/
void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port) {
__io uint32 *exti_cr = &AFIO_BASE->EXTICR1 + exti / 4;
@@ -176,15 +173,14 @@ void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port) {
}
/**
- * @brief Remap an alternate function peripheral to a different pin
- * mapping
- * @param peripheral to remap
+ * @brief Perform an alternate function remap.
+ * @param remapping Remapping to perform.
*/
-void afio_remap(AFIORemapPeripheral p) {
- if (p & AFIO_REMAP_USE_MAPR2) {
- p &= ~AFIO_REMAP_USE_MAPR2;
- AFIO_BASE->MAPR2 |= p;
+void afio_remap(afio_remap_peripheral remapping) {
+ if (remapping & AFIO_REMAP_USE_MAPR2) {
+ remapping &= ~AFIO_REMAP_USE_MAPR2;
+ AFIO_BASE->MAPR2 |= remapping;
} else {
- AFIO_BASE->MAPR |= p;
+ AFIO_BASE->MAPR |= remapping;
}
}
diff --git a/libmaple/gpio.h b/libmaple/gpio.h
index b15124c..9e09289 100644
--- a/libmaple/gpio.h
+++ b/libmaple/gpio.h
@@ -57,8 +57,10 @@ typedef struct gpio_reg_map {
} gpio_reg_map;
/**
- * External interrupt line port selector. Used to determine which
- * GPIO port to map an external interrupt line onto. */
+ * @brief External interrupt line port selector.
+ *
+ * Used to determine which GPIO port to map an external interrupt line
+ * onto. */
/* (See AFIO sections, below) */
typedef enum {
AFIO_EXTI_PA, /**< Use PAx pin. */
@@ -80,19 +82,26 @@ typedef struct gpio_dev {
} gpio_dev;
extern gpio_dev gpioa;
+/** GPIO port A device. */
extern gpio_dev* const GPIOA;
extern gpio_dev gpiob;
+/** GPIO port B device. */
extern gpio_dev* const GPIOB;
extern gpio_dev gpioc;
+/** GPIO port C device. */
extern gpio_dev* const GPIOC;
extern gpio_dev gpiod;
+/** GPIO port D device. */
extern gpio_dev* const GPIOD;
#ifdef STM32_HIGH_DENSITY
extern gpio_dev gpioe;
+/** GPIO port E device. */
extern gpio_dev* const GPIOE;
extern gpio_dev gpiof;
+/** GPIO port F device. */
extern gpio_dev* const GPIOF;
extern gpio_dev gpiog;
+/** GPIO port G device. */
extern gpio_dev* const GPIOG;
#endif
@@ -118,6 +127,8 @@ extern gpio_dev* const GPIOG;
*/
/* Control registers, low and high */
+
+#define GPIO_CR_CNF (0x3 << 2)
#define GPIO_CR_CNF_INPUT_ANALOG (0x0 << 2)
#define GPIO_CR_CNF_INPUT_FLOATING (0x1 << 2)
#define GPIO_CR_CNF_INPUT_PU_PD (0x2 << 2)
@@ -125,6 +136,7 @@ extern gpio_dev* const GPIOG;
#define GPIO_CR_CNF_OUTPUT_OD (0x1 << 2)
#define GPIO_CR_CNF_AF_OUTPUT_PP (0x2 << 2)
#define GPIO_CR_CNF_AF_OUTPUT_OD (0x3 << 2)
+#define GPIO_CR_MODE 0x3
#define GPIO_CR_MODE_INPUT 0x0
#define GPIO_CR_MODE_OUTPUT_10MHZ 0x1
#define GPIO_CR_MODE_OUTPUT_2MHZ 0x2
@@ -237,6 +249,7 @@ typedef struct afio_reg_map {
*/
/* Event control register */
+
#define AFIO_EVCR_EVOE (0x1 << 7)
#define AFIO_EVCR_PORT_PA (0x0 << 4)
#define AFIO_EVCR_PORT_PB (0x1 << 4)
@@ -261,6 +274,7 @@ typedef struct afio_reg_map {
#define AFIO_EVCR_PIN_15 0xF
/* AF remap and debug I/O configuration register */
+
#define AFIO_MAPR_SWJ_CFG (0x7 << 24)
#define AFIO_MAPR_SWJ_CFG_FULL_SWJ (0x0 << 24)
#define AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST (0x1 << 24)
@@ -273,22 +287,121 @@ typedef struct afio_reg_map {
#define AFIO_MAPR_TIM5CH4_IREMAP BIT(16)
#define AFIO_MAPR_PD01_REMAP BIT(15)
#define AFIO_MAPR_CAN_REMAP (0x3 << 13)
+#define AFIO_MAPR_CAN_REMAP_NONE (0x0 << 13)
+#define AFIO_MAPR_CAN_REMAP_PB8_PB9 (0x2 << 13)
+#define AFIO_MAPR_CAN_REMAP_PD0_PD1 (0x3 << 13)
#define AFIO_MAPR_TIM4_REMAP BIT(12)
#define AFIO_MAPR_TIM3_REMAP (0x3 << 10)
+#define AFIO_MAPR_TIM3_REMAP_NONE (0x0 << 10)
+#define AFIO_MAPR_TIM3_REMAP_PARTIAL (0x2 << 10)
+#define AFIO_MAPR_TIM3_REMAP_FULL (0x3 << 10)
#define AFIO_MAPR_TIM2_REMAP (0x3 << 8)
+#define AFIO_MAPR_TIM2_REMAP_NONE (0x0 << 8)
+#define AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3 (0x1 << 8)
+#define AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11 (0x2 << 8)
+#define AFIO_MAPR_TIM2_REMAP_FULL (0x3 << 8)
#define AFIO_MAPR_TIM1_REMAP (0x3 << 6)
+#define AFIO_MAPR_TIM1_REMAP_NONE (0x0 << 6)
+#define AFIO_MAPR_TIM1_REMAP_PARTIAL (0x1 << 6)
+#define AFIO_MAPR_TIM1_REMAP_FULL (0x3 << 6)
#define AFIO_MAPR_USART3_REMAP (0x3 << 4)
+#define AFIO_MAPR_USART3_REMAP_NONE (0x0 << 4)
+#define AFIO_MAPR_USART3_REMAP_PARTIAL (0x1 << 4)
+#define AFIO_MAPR_USART3_REMAP_FULL (0x3 << 4)
#define AFIO_MAPR_USART2_REMAP BIT(3)
#define AFIO_MAPR_USART1_REMAP BIT(2)
#define AFIO_MAPR_I2C1_REMAP BIT(1)
#define AFIO_MAPR_SPI1_REMAP BIT(0)
-/* External interrupt configuration registers */
+/* External interrupt configuration register 1 */
+
+#define AFIO_EXTICR1_EXTI3 (0xF << 12)
+#define AFIO_EXTICR1_EXTI3_PA (0x0 << 12)
+#define AFIO_EXTICR1_EXTI3_PB (0x1 << 12)
+#define AFIO_EXTICR1_EXTI3_PC (0x2 << 12)
+#define AFIO_EXTICR1_EXTI3_PD (0x3 << 12)
+#define AFIO_EXTICR1_EXTI3_PE (0x4 << 12)
+#define AFIO_EXTICR1_EXTI3_PF (0x5 << 12)
+#define AFIO_EXTICR1_EXTI3_PG (0x6 << 12)
+#define AFIO_EXTICR1_EXTI2 (0xF << 8)
+#define AFIO_EXTICR1_EXTI2_PA (0x0 << 8)
+#define AFIO_EXTICR1_EXTI2_PB (0x1 << 8)
+#define AFIO_EXTICR1_EXTI2_PC (0x2 << 8)
+#define AFIO_EXTICR1_EXTI2_PD (0x3 << 8)
+#define AFIO_EXTICR1_EXTI2_PE (0x4 << 8)
+#define AFIO_EXTICR1_EXTI2_PF (0x5 << 8)
+#define AFIO_EXTICR1_EXTI2_PG (0x6 << 8)
+#define AFIO_EXTICR1_EXTI1 (0xF << 4)
+#define AFIO_EXTICR1_EXTI1_PA (0x0 << 4)
+#define AFIO_EXTICR1_EXTI1_PB (0x1 << 4)
+#define AFIO_EXTICR1_EXTI1_PC (0x2 << 4)
+#define AFIO_EXTICR1_EXTI1_PD (0x3 << 4)
+#define AFIO_EXTICR1_EXTI1_PE (0x4 << 4)
+#define AFIO_EXTICR1_EXTI1_PF (0x5 << 4)
+#define AFIO_EXTICR1_EXTI1_PG (0x6 << 4)
+#define AFIO_EXTICR1_EXTI0 0xF
+#define AFIO_EXTICR1_EXTI0_PA 0x0
+#define AFIO_EXTICR1_EXTI0_PB 0x1
+#define AFIO_EXTICR1_EXTI0_PC 0x2
+#define AFIO_EXTICR1_EXTI0_PD 0x3
+#define AFIO_EXTICR1_EXTI0_PE 0x4
+#define AFIO_EXTICR1_EXTI0_PF 0x5
+#define AFIO_EXTICR1_EXTI0_PG 0x6
+
+/* External interrupt configuration register 2 */
+
+#define AFIO_EXTICR2_EXTI7 (0xF << 12)
+#define AFIO_EXTICR2_EXTI7_PA (0x0 << 12)
+#define AFIO_EXTICR2_EXTI7_PB (0x1 << 12)
+#define AFIO_EXTICR2_EXTI7_PC (0x2 << 12)
+#define AFIO_EXTICR2_EXTI7_PD (0x3 << 12)
+#define AFIO_EXTICR2_EXTI7_PE (0x4 << 12)
+#define AFIO_EXTICR2_EXTI7_PF (0x5 << 12)
+#define AFIO_EXTICR2_EXTI7_PG (0x6 << 12)
+#define AFIO_EXTICR2_EXTI6 (0xF << 8)
+#define AFIO_EXTICR2_EXTI6_PA (0x0 << 8)
+#define AFIO_EXTICR2_EXTI6_PB (0x1 << 8)
+#define AFIO_EXTICR2_EXTI6_PC (0x2 << 8)
+#define AFIO_EXTICR2_EXTI6_PD (0x3 << 8)
+#define AFIO_EXTICR2_EXTI6_PE (0x4 << 8)
+#define AFIO_EXTICR2_EXTI6_PF (0x5 << 8)
+#define AFIO_EXTICR2_EXTI6_PG (0x6 << 8)
+#define AFIO_EXTICR2_EXTI5 (0xF << 4)
+#define AFIO_EXTICR2_EXTI5_PA (0x0 << 4)
+#define AFIO_EXTICR2_EXTI5_PB (0x1 << 4)
+#define AFIO_EXTICR2_EXTI5_PC (0x2 << 4)
+#define AFIO_EXTICR2_EXTI5_PD (0x3 << 4)
+#define AFIO_EXTICR2_EXTI5_PE (0x4 << 4)
+#define AFIO_EXTICR2_EXTI5_PF (0x5 << 4)
+#define AFIO_EXTICR2_EXTI5_PG (0x6 << 4)
+#define AFIO_EXTICR2_EXTI4 0xF
+#define AFIO_EXTICR2_EXTI4_PA 0x0
+#define AFIO_EXTICR2_EXTI4_PB 0x1
+#define AFIO_EXTICR2_EXTI4_PC 0x2
+#define AFIO_EXTICR2_EXTI4_PD 0x3
+#define AFIO_EXTICR2_EXTI4_PE 0x4
+#define AFIO_EXTICR2_EXTI4_PF 0x5
+#define AFIO_EXTICR2_EXTI4_PG 0x6
+
+/* AF remap and debug I/O configuration register 2 */
+
+#define AFIO_MAPR2_FSMC_NADV BIT(10)
+#define AFIO_MAPR2_TIM14_REMAP BIT(9)
+#define AFIO_MAPR2_TIM13_REMAP BIT(8)
+#define AFIO_MAPR2_TIM11_REMAP BIT(7)
+#define AFIO_MAPR2_TIM10_REMAP BIT(6)
+#define AFIO_MAPR2_TIM9_REMAP BIT(5)
+
+/*
+ * AFIO convenience routines
+ */
+
+void afio_init(void);
/**
* External interrupt line numbers.
*/
-typedef enum {
+typedef enum afio_exti_num {
AFIO_EXTI_0, /**< External interrupt line 0. */
AFIO_EXTI_1, /**< External interrupt line 1. */
AFIO_EXTI_2, /**< External interrupt line 2. */
@@ -307,50 +420,73 @@ typedef enum {
AFIO_EXTI_15, /**< External interrupt line 15. */
} afio_exti_num;
-/* AF remap and debug I/O configuration register 2 */
-#define AFIO_MAPR2_FSMC_NADV BIT(10)
-#define AFIO_MAPR2_TIM14_REMAP BIT(9)
-#define AFIO_MAPR2_TIM13_REMAP BIT(8)
-#define AFIO_MAPR2_TIM11_REMAP BIT(7)
-#define AFIO_MAPR2_TIM10_REMAP BIT(6)
-#define AFIO_MAPR2_TIM9_REMAP BIT(5)
+void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port);
/* HACK: Use upper bit to denote MAPR2, Bit 31 is reserved and
* not used in either MAPR or MAPR2 */
#define AFIO_REMAP_USE_MAPR2 (1 << 31)
-typedef enum AFIORemapPeripheral {
- AFIO_REMAP_ADC2_ETRGREG = AFIO_MAPR_ADC2_ETRGREG_REMAP,
- AFIO_REMAP_ADC2_ETRGINJ = AFIO_MAPR_ADC2_ETRGINJ_REMAP,
- AFIO_REMAP_ADC1_ETRGREG = AFIO_MAPR_ADC1_ETRGREG_REMAP,
- AFIO_REMAP_ADC1_ETRGINJ = AFIO_MAPR_ADC1_ETRGINJ_REMAP,
- AFIO_REMAP_TIM5CH4_I = AFIO_MAPR_TIM5CH4_IREMAP,
- AFIO_REMAP_PD01 = AFIO_MAPR_PD01_REMAP,
- AFIO_REMAP_CAN = AFIO_MAPR_CAN_REMAP,
- AFIO_REMAP_TIM4 = AFIO_MAPR_TIM4_REMAP,
- AFIO_REMAP_TIM3 = AFIO_MAPR_TIM3_REMAP,
- AFIO_REMAP_TIM2 = AFIO_MAPR_TIM2_REMAP,
- AFIO_REMAP_TIM1 = AFIO_MAPR_TIM1_REMAP,
- AFIO_REMAP_USART3 = AFIO_MAPR_USART3_REMAP,
- AFIO_REMAP_USART2 = AFIO_MAPR_USART2_REMAP,
- AFIO_REMAP_USART1 = AFIO_MAPR_USART1_REMAP,
- AFIO_REMAP_I2C1 = AFIO_MAPR_I2C1_REMAP,
- AFIO_REMAP_SPI1 = AFIO_MAPR_SPI1_REMAP,
- AFIO_REMAP_FSMC_NADV = AFIO_MAPR2_FSMC_NADV | AFIO_REMAP_USE_MAPR2,
- AFIO_REMAP_TIM14 = AFIO_MAPR2_TIM14_REMAP | AFIO_REMAP_USE_MAPR2,
- AFIO_REMAP_TIM13 = AFIO_MAPR2_TIM13_REMAP | AFIO_REMAP_USE_MAPR2,
- AFIO_REMAP_TIM11 = AFIO_MAPR2_TIM11_REMAP | AFIO_REMAP_USE_MAPR2,
- AFIO_REMAP_TIM10 = AFIO_MAPR2_TIM10_REMAP | AFIO_REMAP_USE_MAPR2,
- AFIO_REMAP_TIM9 = AFIO_MAPR2_TIM9_REMAP | AFIO_REMAP_USE_MAPR2
-} AFIORemapPeripheral;
-
-void afio_remap(AFIORemapPeripheral p);
-
-/*
- * AFIO convenience routines
- */
-void afio_init(void);
-void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port);
+/** Available peripheral remaps. */
+typedef enum afio_remap_peripheral {
+ AFIO_REMAP_ADC2_ETRGREG = AFIO_MAPR_ADC2_ETRGREG_REMAP, /**<
+ ADC 2 external trigger regular conversion remapping */
+ AFIO_REMAP_ADC2_ETRGINJ = AFIO_MAPR_ADC2_ETRGINJ_REMAP, /**<
+ ADC 2 external trigger injected conversion remapping */
+ AFIO_REMAP_ADC1_ETRGREG = AFIO_MAPR_ADC1_ETRGREG_REMAP, /**<
+ ADC 1 external trigger regular conversion remapping */
+ AFIO_REMAP_ADC1_ETRGINJ = AFIO_MAPR_ADC1_ETRGINJ_REMAP, /**<
+ ADC 1 external trigger injected conversion remapping */
+ AFIO_REMAP_TIM5CH4_I = AFIO_MAPR_TIM5CH4_IREMAP, /**<
+ Timer 5 channel 4 internal remapping */
+ AFIO_REMAP_PD01 = AFIO_MAPR_PD01_REMAP, /**<
+ Port D0/Port D1 mapping on OSC_IN/OSC_OUT */
+ AFIO_REMAP_CAN_1 = AFIO_MAPR_CAN_REMAP_PB8_PB9, /**<
+ CAN alternate function remapping 1 (RX on PB8, TX on PB9) */
+ AFIO_REMAP_CAN_2 = AFIO_MAPR_CAN_REMAP_PD0_PD1, /**<
+ CAN alternate function remapping 2 (RX on PD0, TX on PD1) */
+ AFIO_REMAP_TIM4 = AFIO_MAPR_TIM4_REMAP, /**<
+ Timer 4 remapping */
+ AFIO_REMAP_TIM3_PARTIAL = AFIO_MAPR_TIM3_REMAP_PARTIAL, /**<
+ Timer 3 partial remapping */
+ AFIO_REMAP_TIM3_FULL = AFIO_MAPR_TIM3_REMAP_FULL, /**<
+ Timer 3 full remapping */
+ AFIO_REMAP_TIM2_PARTIAL_1 = AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3, /**<
+ Timer 2 partial remapping 1 (CH1 and ETR on PA15, CH2 on PB3, CH3
+ on PA2, CH4 on PA3) */
+ AFIO_REMAP_TIM2_PARTIAL_2 = AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11, /**<
+ Timer 2 partial remapping 2 (CH1 and ETR on PA0, CH2 on PA1, CH3
+ on PB10, CH4 on PB11) */
+ AFIO_REMAP_TIM2_FULL = AFIO_MAPR_TIM2_REMAP_FULL, /**<
+ Timer 2 full remapping */
+ AFIO_REMAP_USART2 = AFIO_MAPR_USART2_REMAP, /**<
+ USART 2 remapping */
+ AFIO_REMAP_USART1 = AFIO_MAPR_USART1_REMAP, /**<
+ USART 1 remapping */
+ AFIO_REMAP_I2C1 = AFIO_MAPR_I2C1_REMAP, /**<
+ I2C 1 remapping */
+ AFIO_REMAP_SPI1 = AFIO_MAPR_SPI1_REMAP, /**<
+ SPI 1 remapping */
+ AFIO_REMAP_FSMC_NADV = (AFIO_MAPR2_FSMC_NADV |
+ AFIO_REMAP_USE_MAPR2), /**<
+ NADV signal not connected */
+ AFIO_REMAP_TIM14 = (AFIO_MAPR2_TIM14_REMAP |
+ AFIO_REMAP_USE_MAPR2), /**<
+ Timer 14 remapping */
+ AFIO_REMAP_TIM13 = (AFIO_MAPR2_TIM13_REMAP |
+ AFIO_REMAP_USE_MAPR2), /**<
+ Timer 13 remapping */
+ AFIO_REMAP_TIM11 = (AFIO_MAPR2_TIM11_REMAP |
+ AFIO_REMAP_USE_MAPR2), /**<
+ Timer 11 remapping */
+ AFIO_REMAP_TIM10 = (AFIO_MAPR2_TIM10_REMAP |
+ AFIO_REMAP_USE_MAPR2), /**<
+ Timer 10 remapping */
+ AFIO_REMAP_TIM9 = (AFIO_MAPR2_TIM9_REMAP |
+ AFIO_REMAP_USE_MAPR2) /**<
+ Timer 9 */
+} afio_remap_peripheral;
+
+void afio_remap(afio_remap_peripheral p);
/**
* @brief Debug port configuration