Mike Katz

Quirk to watch for in SDK 2.5.0 for LPC804 in fsl_gpio.c GPIO_PortInit()

Discussion created by Mike Katz on Jun 7, 2019
Latest reply on Jun 10, 2019 by jeremyzhou

In version 2.1.1 the GPIO_PortInit code is:

 

void GPIO_PortInit(GPIO_Type *base, uint32_t port)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
    assert(port < ARRAY_SIZE(s_gpioClockName));

    /* Upgate the GPIO clock */
    CLOCK_EnableClock(s_gpioClockName[port]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}

In 2.1.2 it has changed to:

 

void GPIO_PortInit(GPIO_Type *base, uint32_t port)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
    assert(port < ARRAY_SIZE(s_gpioClockName));

    /* Upgate the GPIO clock */
    CLOCK_EnableClock(s_gpioClockName[port]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if !(defined(FSL_FEATURE_GPIO_HAS_NO_RESET) && FSL_FEATURE_GPIO_HAS_NO_RESET)
    /* Reset the GPIO module */
    RESET_PeripheralReset(s_gpioResets[port]);
#endif
}

 

The code from line 9 through line 12 is new.  In version 2.1.1 GPIO_PortInit() could be called more than once for a given port without affecting the configuration of that port.  However, version 2.1.2, if your processor supports port reset, resets the ports configuration.  So if this is called a 2nd time, any configuration done prior to 2nd call will reset the prior configuration.

 

For example:

    gpio_pin_config_t gpio_config =
    {
        kGPIO_DigitalOutput, 0,
    };

    //
    //  initialize output GPIOs
    //
    GPIO_PortInit(BOARD_INITPINS_HeartBeat_LED_GPIO, BOARD_INITPINS_HeartBeat_LED_PORT);
    GPIO_PinInit(BOARD_INITPINS_HeartBeat_LED_GPIO, BOARD_INITPINS_HeartBeat_LED_PORT, BOARD_INITPINS_HeartBeat_LED_PIN, &gpio_config);
    GPIO_PinInit(BOARD_INITPINS_DebugLed1_GPIO, BOARD_INITPINS_DebugLed1_PORT, BOARD_INITPINS_DebugLed1_PIN, &gpio_config);
    GPIO_PinInit(BOARD_INITPINS_ChargerDisable_GPIO, BOARD_INITPINS_ChargerDisable_PORT, BOARD_INITPINS_ChargerDisable_PIN, &gpio_config);

    //
    //  Initialize the input GPIOs
    //
    gpio_config.pinDirection = kGPIO_DigitalInput;
    GPIO_PortInit(BOARD_INITPINS_HeartBeat_LED_GPIO, BOARD_INITPINS_HeartBeat_LED_PORT);
    GPIO_PinInit(BOARD_INITPINS_Charging_GPIO, BOARD_INITPINS_Charging_PORT, BOARD_INITPINS_Charging_PIN, &gpio_config);
    GPIO_PinInit(BOARD_INITPINS_LeftRightSelect_GPIO, BOARD_INITPINS_LeftRightSelect_PORT, BOARD_INITPINS_LeftRightSelect_PIN, &gpio_config);

The call to GPIO_PortInit() on line 18 may, depending on your processor capabilities, reset the pin initialization done on lines 10 -> 12.

 

If your code only calls GPIO_PortInit() once then you are ok:

 

    gpio_pin_config_t gpio_config =
    {
        kGPIO_DigitalOutput, 0,
    };

    //
    //  initialize output GPIOs
    //
    GPIO_PortInit(BOARD_INITPINS_HeartBeat_LED_GPIO, BOARD_INITPINS_HeartBeat_LED_PORT);
    GPIO_PinInit(BOARD_INITPINS_HeartBeat_LED_GPIO, BOARD_INITPINS_HeartBeat_LED_PORT, BOARD_INITPINS_HeartBeat_LED_PIN, &gpio_config);
    GPIO_PinInit(BOARD_INITPINS_DebugLed1_GPIO, BOARD_INITPINS_DebugLed1_PORT, BOARD_INITPINS_DebugLed1_PIN, &gpio_config);
    GPIO_PinInit(BOARD_INITPINS_ChargerDisable_GPIO, BOARD_INITPINS_ChargerDisable_PORT, BOARD_INITPINS_ChargerDisable_PIN, &gpio_config);

    //
    //  Initialize the input GPIOs
    //
    gpio_config.pinDirection = kGPIO_DigitalInput;
    GPIO_PinInit(BOARD_INITPINS_Charging_GPIO, BOARD_INITPINS_Charging_PORT, BOARD_INITPINS_Charging_PIN, &gpio_config);
    GPIO_PinInit(BOARD_INITPINS_LeftRightSelect_GPIO, BOARD_INITPINS_LeftRightSelect_PORT, BOARD_INITPINS_LeftRightSelect_PIN, &gpio_config);

 

Just another slight code change in an SDK that can break an existing application.

Outcomes