gpio: add support for configuring pins as analog inputs

Bug: 27384840
Change-Id: Ie3677f312bf00f606014ef9d1b03119f4fcc3340
diff --git a/firmware/inc/gpio.h b/firmware/inc/gpio.h
index 3ac76cb..7eb24b7 100644
--- a/firmware/inc/gpio.h
+++ b/firmware/inc/gpio.h
@@ -71,6 +71,7 @@
 void gpioConfigInput(const struct Gpio* __restrict gpio, int32_t gpioSpeed, enum GpioPullMode pull);
 void gpioConfigOutput(const struct Gpio* __restrict gpio, int32_t gpioSpeed, enum GpioPullMode pull, enum GpioOpenDrainMode odrMode, bool value);
 void gpioConfigAlt(const struct Gpio* __restrict gpio, int32_t gpioSpeed, enum GpioPullMode pull, enum GpioOpenDrainMode odrMode, uint32_t altFunc);
+void gpioConfigAnalog(const struct Gpio* __restrict gpio);
 
 /* Sets and gets a value for a specific GPIO pin */
 void gpioSet(const struct Gpio* __restrict gpio, bool value);
diff --git a/firmware/src/platform/stm32f4xx/gpio.c b/firmware/src/platform/stm32f4xx/gpio.c
index 1c4b590..ff17c79 100644
--- a/firmware/src/platform/stm32f4xx/gpio.c
+++ b/firmware/src/platform/stm32f4xx/gpio.c
@@ -181,6 +181,25 @@
         gpioConfigAltWithNum((uint32_t)gpioHandle - GPIO_HANDLE_OFFSET, gpioSpeed, pull, output, altFunc);
 }
 
+static void gpioConfigAnalogWithNum(uint32_t gpioNum)
+{
+    struct StmGpio *block = (struct StmGpio*)mGpioBases[gpioNum >> GPIO_PORT_SHIFT];
+    const uint32_t pinNo = gpioNum & GPIO_PIN_MASK;
+    const uint32_t shift_2b = pinNo * 2;
+    const uint32_t mask_2b = (3UL << shift_2b);
+
+    gpioConfigWithNum(gpioNum, GPIO_SPEED_LOW, GPIO_PULL_NONE, GPIO_OUT_OPEN_DRAIN);
+
+    /* I/O configuration */
+    block->MODER = (block->MODER & ~mask_2b) | (((uint32_t)GPIO_MODE_ANALOG) << shift_2b);
+}
+
+void gpioConfigAnalog(const struct Gpio* __restrict gpioHandle)
+{
+    if (gpioHandle)
+        gpioConfigAnalogWithNum((uint32_t)gpioHandle - GPIO_HANDLE_OFFSET);
+}
+
 static void gpioSetWithNum(uint32_t gpioNum, bool value)
 {
     struct StmGpio *block = (struct StmGpio*)mGpioBases[gpioNum >> GPIO_PORT_SHIFT];