| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 | #include "gpio.h"gpio_pindef_t gpio_pins[] = {	GPIO_TABLE(EXPAND_AS_DEFS)};void gpio_hw_config_pin(GPIO_TypeDef *port, uint8_t pin, uint16_t conf) {	uint8_t shift;	shift = pin * 2;	port->MODER &= ~(GPIO_MODER_MASK << shift);	port->MODER |= (uint32_t)((conf >> GPIO_MODE_CFG_SHIFT) & GPIO_MODER_MASK) << shift;	port->OTYPER &= ~(GPIO_TYPER_MASK << pin);	port->OTYPER |= (uint32_t)((conf >> GPIO_TYPE_CFG_SHIFT) & GPIO_TYPER_MASK) << pin;	port->OSPEEDR &= ~(GPIO_SPEEDR_MASK << shift);	port->OSPEEDR |= (uint32_t)((conf >> GPIO_SPEED_CFG_SHIFT) & GPIO_SPEEDR_MASK) << shift;	port->PUPDR &= ~(GPIO_PUPDR_MASK << shift);	port->PUPDR |= (uint32_t)((conf >> GPIO_PUPD_CFG_SHIFT) & GPIO_PUPDR_MASK) << shift;}void gpio_connect_af(gpio_t id, uint8_t af_n) {	gpio_pindef_t *pin = &gpio_pins[id];	uint8_t shift;	if (pin->pin < 8) {		shift = pin->pin * 4;		pin->port->AFR[0] &= ~((uint32_t)GPIO_AFR_MASK << shift);		pin->port->AFR[0] |= af_n << shift;	}	else {		shift = (pin->pin - 8) * 4;		pin->port->AFR[1] &= ~((uint32_t)GPIO_AFR_MASK << shift);		pin->port->AFR[1] |= af_n << shift;	}}/* * TODO add analog flag and setup ADC pins in a proper way */static void gpio_set_config(gpio_t id) {	gpio_pindef_t *pin = &gpio_pins[id];	if (pin->flags & GPIO_AF) {		uint8_t af_n = (uint8_t)(pin->flags >> _GPIO_AF_SHIFT);		gpio_connect_af(id, af_n);		gpio_hw_config_pin(pin->port, pin->pin, GPIO_MODE_AF_CFG | 				GPIO_SPEED_HIGH_CFG);	}	else if (pin->flags & GPIO_IN)		gpio_hw_config_pin(pin->port, pin->pin, GPIO_MODE_IN_CFG | 				GPIO_SPEED_HIGH_CFG);	else if (pin->flags & GPIO_IN_PU) {		gpio_hw_config_pin(pin->port, pin->pin, GPIO_MODE_IN_CFG | GPIO_PU_CFG |				GPIO_SPEED_HIGH_CFG);		gpio_set(id, pin->flags & GPIO_SET);	}	else if (pin->flags & GPIO_OUT) {		gpio_hw_config_pin(pin->port, pin->pin, GPIO_MODE_OUT_CFG |				((pin->flags & GPIO_OD) ? 				 GPIO_TYPE_OD_CFG : GPIO_TYPE_PP_CFG) |				GPIO_SPEED_HIGH_CFG);		gpio_set(id, pin->flags & GPIO_SET);	}}void gpio_init(void) {	uint32_t i;	GPIO_DeInit(GPIOA);	GPIO_DeInit(GPIOB);	GPIO_DeInit(GPIOC);	GPIO_DeInit(GPIOD);	GPIO_DeInit(GPIOE);	// configure clocks	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN |			RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN |			RCC_AHB1ENR_GPIOEEN;	// configure gpios	for (i = 0; i < GPIO_TOTAL_COUNT; i++) {		if (gpio_pins[i].flags & GPIO_NOINIT)			continue;		else {			gpio_set_config(i);		}	}}void gpio_set(gpio_t pin, bool value) {	if (gpio_pins[pin].flags & GPIO_INV)		value = !value;	if (value)		gpio_pins[pin].port->BSRRL = 1 << gpio_pins[pin].pin;	else		gpio_pins[pin].port->BSRRH = 1 << gpio_pins[pin].pin;}void gpio_invert_output(gpio_t pin) {	gpio_pins[pin].port->ODR ^= 1 << gpio_pins[pin].pin;}bool gpio_get(gpio_t pin) {	bool value;	if (gpio_pins[pin].flags & GPIO_NOINIT) {		return false;	}	else {		value = (gpio_pins[pin].port->IDR & (1 << gpio_pins[pin].pin)) >> gpio_pins[pin].pin;		return (gpio_pins[pin].flags & GPIO_INV) ? !value : value;	}}bool gpio_is_output(gpio_t pin) {	return (gpio_pins[pin].flags & GPIO_OUT) ? true : false;}void gpio_set_direction(gpio_t pin, bool out) {	if (out) {		gpio_pins[pin].flags &= ~(GPIO_IN | GPIO_IN_PU);		gpio_pins[pin].flags |= GPIO_OUT;	}	else {		gpio_pins[pin].flags &= ~(GPIO_OUT | GPIO_OD);		gpio_pins[pin].flags |= GPIO_IN;	}	gpio_set_config(pin);}void gpio_test() {}typedef struct {	gpio_pindef_t *gpio;	void (*handler)(void);} exti_handler_t;
 |