diff options
-rw-r--r-- | core/wiring_digital.c | 1 | ||||
-rw-r--r-- | libmaple/gpio.c | 31 | ||||
-rw-r--r-- | libmaple/gpio.h | 61 |
3 files changed, 56 insertions, 37 deletions
diff --git a/core/wiring_digital.c b/core/wiring_digital.c index c1b7201..52cc652 100644 --- a/core/wiring_digital.c +++ b/core/wiring_digital.c @@ -112,6 +112,7 @@ void pinMode(uint8 pin, WiringPinMode mode) { break; case INPUT_ANALOG: outputMode = GPIO_MODE_INPUT_ANALOG; + break; case INPUT_PULLUP: outputMode = GPIO_MODE_INPUT_PU; break; diff --git a/libmaple/gpio.c b/libmaple/gpio.c index be9db6e..9759df8 100644 --- a/libmaple/gpio.c +++ b/libmaple/gpio.c @@ -40,19 +40,28 @@ void gpio_init(void) { rcc_enable_clk_afio(); } -void gpio_set_mode(GPIO_Port* port, uint8 gpio_pin, uint8 mode) { - uint32 tmp; - uint32 shift = POS(gpio_pin % 8); - GPIOReg CR; +void gpio_set_mode(GPIO_Port* port, uint8 gpio_pin, GPIOPinMode mode) { + uint32 tmp; + uint32 shift = POS(gpio_pin % 8); + GPIOReg CR; + uint32 pullup = 0; - ASSERT(port); - ASSERT(gpio_pin < 16); + ASSERT(port); + ASSERT(gpio_pin < 16); - CR = (gpio_pin < 8) ? &(port->CRL) : &(port->CRH); + if (mode == GPIO_MODE_INPUT_PU) { + pullup = 1; + mode = CNF_INPUT_PD; + } - tmp = *CR; - tmp &= POS_MASK(shift); - tmp |= mode << shift; + CR = (gpio_pin < 8) ? &(port->CRL) : &(port->CRH); - *CR = tmp; + tmp = *CR; + tmp &= POS_MASK(shift); + tmp |= mode << shift; + + *CR = tmp; + + if (pullup) + port->ODR = BIT(gpio_pin); } diff --git a/libmaple/gpio.h b/libmaple/gpio.h index a44047e..74320e6 100644 --- a/libmaple/gpio.h +++ b/libmaple/gpio.h @@ -49,28 +49,37 @@ #define GPIOC_BASE (GPIO_Port*)0x40011000 #define GPIOD_BASE (GPIO_Port*)0x40011400 -/* Pin modes are set by [CNFx[1:0] : MODEx[1:0]] */ -#define GPIO_SPEED_50MHZ (0x3) // Max output speed 50 MHz -#define GPIO_MODE_OUTPUT_PP ((0x00 << 2) | GPIO_SPEED_50MHZ) -#define GPIO_MODE_OUTPUT_OD ((0x01 << 2) | GPIO_SPEED_50MHZ) - -#define GPIO_MODE_AF_OUTPUT_PP ((0x02 << 2) | GPIO_SPEED_50MHZ) -#define GPIO_MODE_AF_OUTPUT_OD ((0x03 << 2) | GPIO_SPEED_50MHZ) - -/* Note: mode bits must be set to zero for input mode */ -#define GPIO_MODE_INPUT_ANALOG (0x00 << 2) -#define GPIO_MODE_INPUT_FLOATING (0x01 << 2) -#define GPIO_MODE_INPUT_PD (0x02 << 2) -#define GPIO_MODE_INPUT_PU (0x02 << 2) +#define GPIO_SPEED_50MHZ (0x3) + +#define MODE_OUTPUT_PP ((0x00 << 2) | GPIO_SPEED_50MHZ) +#define MODE_OUTPUT_OD ((0x01 << 2) | GPIO_SPEED_50MHZ) +#define MODE_AF_OUTPUT_PP ((0x02 << 2) | GPIO_SPEED_50MHZ) +#define MODE_AF_OUTPUT_OD ((0x03 << 2) | GPIO_SPEED_50MHZ) + +#define CNF_INPUT_ANALOG (0x00 << 2) +#define CNF_INPUT_FLOATING (0x01 << 2) +#define CNF_INPUT_PD (0x02 << 2) +#define CNF_INPUT_PU (0x02 << 2) + +typedef enum GPIOPinMode { + GPIO_MODE_OUTPUT_PP = MODE_OUTPUT_PP, + GPIO_MODE_OUTPUT_OD = MODE_OUTPUT_OD, + GPIO_MODE_AF_OUTPUT_PP = MODE_AF_OUTPUT_PP, + GPIO_MODE_AF_OUTPUT_OD = MODE_AF_OUTPUT_OD, + GPIO_MODE_INPUT_ANALOG = CNF_INPUT_ANALOG, + GPIO_MODE_INPUT_FLOATING = CNF_INPUT_FLOATING, + GPIO_MODE_INPUT_PD = CNF_INPUT_PD, + GPIO_MODE_INPUT_PU, +} GPIOPinMode; typedef struct { - volatile uint32 CRL; // Port configuration register low - volatile uint32 CRH; // Port configuration register high - volatile uint32 IDR; // Port input data register - volatile uint32 ODR; // Port output data register - volatile uint32 BSRR; // Port bit set/reset register - volatile uint32 BRR; // Port bit reset register - volatile uint32 LCKR; // Port configuration lock register + volatile uint32 CRL; // Port configuration register low + volatile uint32 CRH; // Port configuration register high + volatile uint32 IDR; // Port input data register + volatile uint32 ODR; // Port output data register + volatile uint32 BSRR; // Port bit set/reset register + volatile uint32 BRR; // Port bit reset register + volatile uint32 LCKR; // Port configuration lock register } GPIO_Port; typedef volatile uint32* GPIOReg; @@ -83,14 +92,14 @@ extern "C"{ #endif void gpio_init(void); -void gpio_set_mode(GPIO_Port* port, uint8 gpio_pin, uint8 mode); +void gpio_set_mode(GPIO_Port* port, uint8 gpio_pin, GPIOPinMode mode); static inline void gpio_write_bit(GPIO_Port *port, uint8 gpio_pin, uint8 val) { - if (val){ - port->BSRR = BIT(gpio_pin); - } else { - port->BRR = BIT(gpio_pin); - } + if (val){ + port->BSRR = BIT(gpio_pin); + } else { + port->BRR = BIT(gpio_pin); + } } static inline uint32 gpio_read_bit(GPIO_Port *port, uint8 gpio_pin) { |