int stm32_gpio_configure(u32_t *base_addr, int pin, int conf, int altf) { volatile struct stm32f3x_gpio *gpio = (struct stm32f3x_gpio *)(base_addr); int mode, cmode; cmode = STM32_MODE(conf); mode = func_to_mode(cmode); /* clear bits */ gpio->moder &= ~(0x3 << (pin * 2)); /* set bits */ gpio->moder |= (mode << (pin * 2)); if (cmode == STM32F3X_PIN_CONFIG_AF) { /* alternate function setup */ int af = STM32_AF(conf); volatile u32_t *afr = &gpio->afrl; int crpin = pin; if (crpin > 7) { afr = &gpio->afrh; crpin -= 8; } /* clear AF bits */ *afr &= ~(0xf << (crpin * 4)); /* set AF */ *afr |= (af << (crpin * 4)); } else if (cmode == STM32F3X_PIN_CONFIG_ANALOG) { gpio->pupdr &= ~(0x3 << (pin * 2)); } else { /* clear typer */ gpio->otyper &= ~(1 << pin); if (cmode == STM32F3X_PIN_CONFIG_DRIVE_OPEN_DRAIN || cmode == STM32F3X_PIN_CONFIG_DRIVE_OPEN_DRAIN_PU || cmode == STM32F3X_PIN_CONFIG_DRIVE_OPEN_DRAIN_PD) { /* configure pin as output open-drain */ gpio->otyper |= 1 << pin; } /* configure pin as floating by clearing pupd flags */ gpio->pupdr &= ~(0x3 << (pin * 2)); if (cmode == STM32F3X_PIN_CONFIG_BIAS_PULL_UP || cmode == STM32F3X_PIN_CONFIG_DRIVE_PUSH_PULL_PU || cmode == STM32F3X_PIN_CONFIG_DRIVE_OPEN_DRAIN_PU) { /* enable pull up */ gpio->pupdr |= (1 << (pin * 2)); } else if (cmode == STM32F3X_PIN_CONFIG_BIAS_PULL_DOWN || cmode == STM32F3X_PIN_CONFIG_DRIVE_PUSH_PULL_PD || cmode == STM32F3X_PIN_CONFIG_DRIVE_OPEN_DRAIN_PD) { /* or pull down */ gpio->pupdr |= (2 << (pin * 2)); } } return 0; }
int stm32_gpio_configure(uint32_t *base_addr, int pin, int pinconf, int afnum) { volatile struct stm32l4x_gpio *gpio = (struct stm32l4x_gpio *)(base_addr); unsigned int mode, otype, pupd; unsigned int pin_shift = pin << 1; unsigned int afr_bank = pin / 8; unsigned int afr_shift = (pin % 8) << 2; uint32_t scratch; mode = func_to_mode(pinconf, afnum); otype = func_to_otype(pinconf); pupd = func_to_pupd(pinconf); scratch = gpio->moder & ~(STM32L4X_MODER_MASK << pin_shift); gpio->moder = scratch | (mode << pin_shift); scratch = gpio->otyper & ~(STM32L4X_OTYPER_MASK << pin); gpio->otyper = scratch | (otype << pin); scratch = gpio->pupdr & ~(STM32L4X_PUPDR_MASK << pin_shift); gpio->pupdr = scratch | (pupd << pin_shift); scratch = gpio->afr[afr_bank] & ~(STM32L4X_AFR_MASK << afr_shift); gpio->afr[afr_bank] = scratch | (afnum << afr_shift); return 0; }