summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src/stm32/stm32_gpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/arch/arm/src/stm32/stm32_gpio.c')
-rwxr-xr-xnuttx/arch/arm/src/stm32/stm32_gpio.c215
1 files changed, 214 insertions, 1 deletions
diff --git a/nuttx/arch/arm/src/stm32/stm32_gpio.c b/nuttx/arch/arm/src/stm32/stm32_gpio.c
index a92fd1d1c..a806baeed 100755
--- a/nuttx/arch/arm/src/stm32/stm32_gpio.c
+++ b/nuttx/arch/arm/src/stm32/stm32_gpio.c
@@ -41,6 +41,7 @@
#include <sys/types.h>
#include <debug.h>
+#include "up_arch.h"
#include "chip.h"
#include "stm32_gpio.h"
#include "stm32_internal.h"
@@ -52,9 +53,37 @@
/****************************************************************************
* Private Types
****************************************************************************/
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const uint32 g_gpiobase[STM32_NGPIO] =
+{
+#if STM32_NGPIO > 0
+ STM32_GPIOA_BASE,
+#endif
+#if STM32_NGPIO > 1
+ STM32_GPIOB_BASE,
+#endif
+#if STM32_NGPIO > 2
+ STM32_GPIOC_BASE,
+#endif
+#if STM32_NGPIO > 3
+ STM32_GPIOD_BASE,
+#endif
+#if STM32_NGPIO > 4
+ STM32_GPIOE_BASE,
+#endif
+#if STM32_NGPIO > 5
+ STM32_GPIOF_BASE,
+#endif
+#if STM32_NGPIO > 6
+ STM32_GPIOG_BASE,
+#endif
+};
/****************************************************************************
- * Private Function Prototypes
+ * Private Functions
****************************************************************************/
/****************************************************************************
@@ -71,6 +100,190 @@
int stm32_configgpio(uint32 cfgset)
{
+ uint32 gpiobase;
+ uint32 cr;
+ uint32 regval;
+ uint32 regaddr;
+ unsigned int gpio;
+ unsigned int pin;
+ unsigned int pos;
+ unsigned int mode;
+ unsigned int cnf;
+ boolean output;
+
+ /* Verify that this hardware supports the select GPIO port */
+
+ gpio = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
+ if (gpio < STM32_NGPIO)
+ {
+ /* Get the port base address */
+
+ gpiobase = g_gpiobase[gpio];
+
+ /* Get the pin number and select the port configuration register for that pin */
+
+ pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;
+ if (pin < 8)
+ {
+ cr = gpiobase + STM32_GPIO_CRL_OFFSET;
+ pos = pin;
+ }
+ else
+ {
+ cr = gpiobase + STM32_GPIO_CRH_OFFSET;
+ pos = pin - 8;
+ }
+
+ /* Input or output? */
+
+ output = ((cfgset & GPIO_OUTPUT_PIN) != 0);
+
+ /* Decode the mode and configuration */
+
+ if (output)
+ {
+ mode = (cfgset & GPIO_MODE_MASK) >> GPIO_MODE_SHIFT;
+ }
+ else
+ {
+ mode = 0;
+ }
+
+ cnf = (cfgset & GPIO_CNF_MASK) >> GPIO_CNF_SHIFT;
+
+ /* Set the port configuration register */
+
+ regval = getreg32(cr);
+ regval &= ~(GPIO_CR_MODE_MASK(pos)|GPIO_CRL_CNF_MASK(pos));
+ regval |= (mode << GPIO_CR_MODE_SHIFT(pos)) | (cnf << GPIO_CRL_CNF_SHIFT(pos));
+ putreg32(regval, cr);
+
+ /* Set or reset the corresponding BRR/BSRR bit */
+
+ if (output)
+ {
+ /* It is an output pin, we need to set/clear the output value */
+
+
+ if ((cfgset & GPIO_OUTPUT_VALUE) != 0)
+ {
+ /* Use the BSRR register to set the output */
+
+ regaddr = gpiobase + STM32_GPIO_BSRR_OFFSET;
+ }
+ else
+ {
+ /* Use the BRR register to clear */
+
+ regaddr = gpiobase + STM32_GPIO_BRR_OFFSET;
+ }
+ }
+ else
+ {
+ if ((cfgset & GPIO_MODE_MASK) == GPIO_CNF_INPULLDWN)
+ {
+ regaddr = gpiobase + STM32_GPIO_BSRR_OFFSET;
+ }
+ else if ((cfgset & GPIO_MODE_MASK) == GPIO_CNF_INPULLUP)
+ {
+ regaddr = gpiobase + STM32_GPIO_BRR_OFFSET;
+ }
+ else
+ {
+ return OK;
+ }
+ }
+
+ regval = getreg32(regaddr);
+ regval |= (1 << pin);
+ putreg32(regval, regaddr);
+ return OK;
+ }
+ return ERROR;
}
+/****************************************************************************
+ * Name: stm32_gpiowrite
+ *
+ * Description:
+ * Write one or zero to the selected GPIO pin
+ *
+ ****************************************************************************/
+
+void stm32_gpiowrite(uint32 pinset, boolean value)
+{
+ uint32 gpiobase;
+ uint32 offset;
+ unsigned int gpio;
+ unsigned int pin;
+
+ gpio = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
+ if (gpio < STM32_NGPIO)
+ {
+ /* Get the port base address */
+
+ gpiobase = g_gpiobase[gpio];
+
+ /* Get the pin number */
+
+ pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;
+
+ /* Set or clear the output on the pin */
+
+ if (value)
+ {
+ offset = STM32_GPIO_BSRR_OFFSET;
+ }
+ else
+ offset = STM32_GPIO_BRR_OFFSET;
+ {
+ }
+ putreg32((1 << pin), gpiobase + offset);
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_gpioread
+ *
+ * Description:
+ * Read one or zero from the selected GPIO pin
+ *
+ ****************************************************************************/
+
+boolean stm32_gpioread(uint32 pinset)
+{
+ uint32 gpiobase;
+ unsigned int gpio;
+ unsigned int pin;
+
+ gpio = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
+ if (gpio < STM32_NGPIO)
+ {
+ /* Get the port base address */
+
+ gpiobase = g_gpiobase[gpio];
+
+ /* Get the pin number and return the input state of that pin */
+
+ pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;
+ return ((getreg32(gpiobase + STM32_GPIO_IDR_OFFSET) & (1 << pin)) != 0);
+ }
+ return 0;
+}
+
+/****************************************************************************
+ * Function: stm32_dumpgpio
+ *
+ * Description:
+ * Dump all GPIO registers associated with the provided base address
+ *
+ ****************************************************************************/
+
+#if 0 /* Not implemented */
+int stm32_dumpgpio(uint32 pinset, const char *msg)
+{
+}
+#endif
+
+