#ifndef GPIO_H_ #define GPIO_H_ #include #include struct gpio { volatile uint32_t MODER; // Port mode register volatile uint32_t OTYPER; // Port output type register volatile uint32_t OSPEEDR; // Port output speed register volatile uint32_t PUPDR; // Port pull-up/pull-down register volatile uint32_t IDR; // Port input data register volatile uint32_t ODR; // Port output data register volatile uint32_t BSRR; // Port bit set/reset register volatile uint32_t LCKR; // Port configuration lock register volatile uint32_t AFRL; // Alternative function low register volatile uint32_t AFRH; // Alternative function high register }; // AFRH, AFRL registers #define GPIO_AF_MCO_1 (0b0000) // Alternative function 0 (AF0) #define GPIO_AF_USART2_RX (0b0111) // Alternative function 7 (AF7) #define GPIO_AF_USART2_TX (0b0111) // Alternative function 7 (AF7) #define GPIO_BASE_ADDR (0x40020000U) #define GPIO_PORT_OFFSET (0x400U) #define GPIO(port) ((struct gpio*)(uintptr_t)(GPIO_BASE_ADDR + (GPIO_PORT_OFFSET * port))) // Create a 8bit number from a port #define PORT(port) (((port) - 'A') << 8) // Create a 16bit number from a port and pin #define PIN(port, num) (PORT(port) | num) // get the lower byte from a PIN #define PINNUM(pin) (pin & 0b1111) // get the upper byte from a PIN #define PINPORT(pin) (pin >> 8) typedef enum { GPIO_MODE_INPUT, GPIO_MODE_OUTPUT, GPIO_MODE_AF, GPIO_MODE_ANALOG } GPIO_MODE; void gpio_set_mode(uint16_t pin, GPIO_MODE mode); void gpio_set_af(uint16_t pin, uint8_t af); void gpio_write(uint16_t pin, bool val); #endif