int stm32_set_pupd(uint32_t cfgset, uint32_t pull_type) { uintptr_t base; uint32_t regval; uint32_t setting; unsigned int port; unsigned int pin; irqstate_t flags; port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; if (port >= STM32_NGPIO_PORTS) { return -EINVAL; } /* Get the port base address */ base = g_gpiobase[port]; /* Get the pin number and select the port configuration register for that * pin */ pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; switch (pull_type) { case GPIO_PULLUP: setting = GPIO_PUPDR_PULLUP; break; case GPIO_PULLDOWN: setting = GPIO_PUPDR_PULLDOWN; break; case GPIO_FLOAT: default: setting = GPIO_PUPDR_NONE; break; } flags = irqsave(); regval = getreg32(base + STM32_GPIO_PUPDR_OFFSET); regval &= ~GPIO_PUPDR_MASK(pin); regval |= (setting << GPIO_PUPDR_SHIFT(pin)); putreg32(regval, base + STM32_GPIO_PUPDR_OFFSET); irqrestore(flags); return OK; }
uint32_t stm32_get_pupd(uint32_t cfgset) { uintptr_t base; uint32_t regval; unsigned int port; unsigned int pin; port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; if (port >= STM32_NGPIO_PORTS) { return 0; /* error is indistinguishable from GPIO_FLOAT, oh well */ } /* Get the port base address */ base = g_gpiobase[port]; /* Get the pin number and select the port configuration register for that * pin */ pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; regval = getreg32(base + STM32_GPIO_PUPDR_OFFSET); regval &= GPIO_PUPDR_MASK(pin); regval >>= GPIO_PUPDR_SHIFT(pin); switch (regval) { case GPIO_PUPDR_PULLUP: return GPIO_PULLUP; case GPIO_PUPDR_PULLDOWN: return GPIO_PULLDOWN; default: return GPIO_FLOAT; } }
int stm32_configgpio(uint32_t cfgset) { uintptr_t base; uint32_t regval; uint32_t setting; unsigned int regoffset; unsigned int port; unsigned int pin; unsigned int pos; unsigned int pinmode; //irqstate_t flags; /* Verify that this hardware supports the select GPIO port */ port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; if (port >= STM32_NGPIO_PORTS) { return -EINVAL; } /* Get the port base address */ base = g_gpiobase[port]; /* Get the pin number and select the port configuration register for that * pin */ pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; /* Set up the mode register (and remember whether the pin mode) */ switch (cfgset & GPIO_MODE_MASK) { default: case GPIO_INPUT: /* Input mode */ pinmode = GPIO_MODER_INPUT; break; case GPIO_OUTPUT: /* General purpose output mode */ pinmode = GPIO_MODER_OUTPUT; break; case GPIO_ALT: /* Alternate function mode */ pinmode = GPIO_MODER_ALT; break; case GPIO_ANALOG: /* Analog mode */ pinmode = GPIO_MODER_ANALOG; break; } /* Interrupts must be disabled from here on out so that we have mutually * exclusive access to all of the GPIO configuration registers. */ //flags = irqsave(); CoSchedLock(); /* Now apply the configuration to the mode register */ regval = getreg32(base + STM32_GPIO_MODER_OFFSET); regval &= ~GPIO_MODER_MASK(pin); regval |= ((uint32_t)pinmode << GPIO_MODER_SHIFT(pin)); putreg32(regval, base + STM32_GPIO_MODER_OFFSET); /* Set up the pull-up/pull-down configuration (all but analog pins) */ setting = GPIO_PUPDR_NONE; if (pinmode != GPIO_MODER_ANALOG) { switch (cfgset & GPIO_PUPD_MASK) { default: case GPIO_FLOAT: /* No pull-up, pull-down */ break; case GPIO_PULLUP: /* Pull-up */ setting = GPIO_PUPDR_PULLUP; break; case GPIO_PULLDOWN: /* Pull-down */ setting = GPIO_PUPDR_PULLDOWN; break; } } regval = getreg32(base + STM32_GPIO_PUPDR_OFFSET); regval &= ~GPIO_PUPDR_MASK(pin); regval |= (setting << GPIO_PUPDR_SHIFT(pin)); putreg32(regval, base + STM32_GPIO_PUPDR_OFFSET); /* Set the alternate function (Only alternate function pins) */ if (pinmode == GPIO_MODER_ALT) { setting = (cfgset & GPIO_AF_MASK) >> GPIO_AF_SHIFT; }