STM32F4xx input pin reads wrong state on first run but not subsequent

cgccstm32stm32f4

I am working on a program which reads the state of a pin at startup to determine an operational mode. When I run the code on first power up, it reads incorrectly, but subsequent resets without power cycle read correct. I can't seem to find an answer for why this might be and I'm a bit at a loss myself. I figure there is some sort of timing issue that is happening and that is why subsequent reads are fine, but I'm not sure how to modify my code to deal with it. The circuit is PI6 connected to either 3.3V or GND, depending on the desired configuration. Here is the relevant code:

#define DEVICE_HOST_MODE_PIN                GPIO_PIN_6
#define DEVICE_HOST_MODE_PORT               GPIOI
#define DEVICE_HOST_MODE_CLK_ENABLE()       __GPIOI_CLK_ENABLE()
#define DEVICE_HOST_MODE_CLK_DISABLE()      __GPIOI_CLK_DISABLE()

int main(void) {

    /* MCU Configuration----------------------------------------------------------*/

    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    HAL_Init();

    /* Configure the system clock */
    SystemClock_Config();

    /* System interrupt init*/
    /* Sets the priority grouping field */
    HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);
    HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

    BSP_InitializeMode();
    /* Remaining application code */
}

void BSP_InitializeMode(void) {
    /*Configure MODE signal line */
    GPIO_InitTypeDef GPIO_InitStruct;
    DEVICE_HOST_MODE_CLK_ENABLE();
    GPIO_InitStruct.Pin = DEVICE_HOST_MODE_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
    GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
    HAL_GPIO_Init(DEVICE_HOST_MODE_PORT, &GPIO_InitStruct);
    GPIO_PinState state = HAL_GPIO_ReadPin(HOST_READY_PORT, DEVICE_HOST_MODE_PIN);
    isDevice = (state == GPIO_PIN_RESET);
}

The SystemClock_Config() method is as generated by STM cube. I am currently compiling with -O0 and -g3 flags.

EDIT 1

Some additional information I have discovered: It seems more specifically that I can't read that a pin is pulled high (3.3V). I tried adding another pin and configuring both as pull-up, then grounding the one I want, and both simply read grounded.

EDIT 2

As requested, the definition of isDevice is posted below. This is in a header file mode.h

#ifndef MODE_H_
#define MODE_H_

#include <stdbool.h>

extern bool isDevice;

#endif /* MODE_H_ */

And the actual implementation is in the same file as the original code, at the top:

bool isDevice = true;

Additionally, I discovered a typo. Fixing it does not seem to have fixed the root problem though. I was reading the wrong GPIO pin number. It has been corrected above. Again, changing this to the correct pin number has not resolved the issue, and it still presents with two pins. I have tried setting them for no pull, pull up and pull down, and in no circumstances does it seem to change the result. They always read as grounded, no matter what signal is applied to them.

Best Answer

So it turns out this was a simple copy paste error on my part which, due to similarly named macros in adjacent functions, my eyes glassed over. I was initializing one port, while reading another. My function above should have read:

void BSP_InitializeMode(void) {
    /*Configure MODE signal line */
    GPIO_InitTypeDef GPIO_InitStruct;
    DEVICE_HOST_MODE_CLK_ENABLE();
    GPIO_InitStruct.Pin = DEVICE_HOST_MODE_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
    GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
    HAL_GPIO_Init(DEVICE_HOST_MODE_PORT, &GPIO_InitStruct);
    GPIO_PinState state = HAL_GPIO_ReadPin(DEVICE_HOST_MODE_PORT, DEVICE_HOST_MODE_PIN);
    isDevice = (state == GPIO_PIN_RESET);
}
Related Topic