Second Read of Pin with GPIO_PinRead Crashes after PORT_SetPinConfig()

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Second Read of Pin with GPIO_PinRead Crashes after PORT_SetPinConfig()

1,100 Views
james5
Contributor I

Hello,

I'm developing some code for my eventual target using the FRDM-KL03Z board as a starting platform.  I'm trying to write some code that will do a quick power-on self-test and make sure that each GPIO pin is not shorted to power or GND (eventually I'll add or any other IO pin).

I started with one of the example projects (RTC) and modified from there.  The code seems to work well in general and I can control I/O as expected.  But now I'm messing with the GPIO pin directions and configs and there seems to be a problem.

Below is the code of my main.c.  You can see the initialization routines that are called.  What I'm trying to do is take over the GPIO, set them as inputs, turn pull-ups and pull-downs ON and OFF, read the pin state to make sure it is what it should be.  When this is all done I plan to call BOARD_InitPins() again to get the I/O set back to the way I need it for my application.

I've had test code that set the pull-up/-down on and off (with a for loop delay between) and I can see the pin toggling with an oscilloscope, even if I do it many times consecutively.  So that seems to work fine.

But the second time I call GPIO_PinRead() it seems to crash.  I can't figure out why.  I saw another post saying something about the clock not being active for an unused port, but that doesn't seem to be the case here as the first call works fine.  The crash only seems to happen if I use GPIO_PinRead().  If I don't actually read the pin state then the code runs fine.

Any ideas?

    rtc_config_t rtcConfig;
    static int count=0;
    tpm_config_t tpm_config;
    lptmr_config_t lptmr_config;

    uint32_t x;

    /* Board pin, clock, debug console init */
    BOARD_InitPins();
    BOARD_BootClockRUN();
    BOARD_InitDebugConsole();

    LED_GREEN_OFF();
    LED_RED_OFF();
    LED_BLUE_OFF();

    // test LED Green pin for shorts
    gpio_pin_config_t input_pin_config =
    {
        kGPIO_DigitalInput,
        0,
    };

    GPIO_PinInit(BOARD_INITPINS_LED_GREEN_GPIO, BOARD_INITPINS_LED_GREEN_PIN, &input_pin_config);

    port_pin_config_t port_config = {/* Internal pull-up resistor is enabled */
                                                  kPORT_PullUp,
                                                 /* Slow slew rate is configured */
                                                 kPORT_SlowSlewRate,
                                                 /* Passive filter is disabled */
                                                 kPORT_PassiveFilterDisable,
                                                 /* Low drive strength is configured */
                                                 kPORT_LowDriveStrength,
                                                 /* Pin is configured as GPIO */
                                                 kPORT_MuxAsGpio};
    /* configure pin as GPIO with pull-up */
    PORT_SetPinConfig(BOARD_INITPINS_LED_GREEN_PORT, BOARD_INITPINS_LED_GREEN_PIN, &port_config);

    // read pin to ensure that it is indeed HIGH, if not, there is an external short on the board
    if( !(GPIO_PinRead(BOARD_INITPINS_LED_GREEN_GPIO, BOARD_INITPINS_LED_GREEN_PIN)) )
    {
        LED_BLUE_ON();
        while(1);
    }

    port_pin_config_t pull_down_config = {/* Internal pull-down resistor is enabled */
                                                  kPORT_PullDown,
                                                 /* Slow slew rate is configured */
                                                 kPORT_SlowSlewRate,
                                                 /* Passive filter is disabled */
                                                 kPORT_PassiveFilterDisable,
                                                 /* Low drive strength is configured */
                                                 kPORT_LowDriveStrength,
                                                 /* Pin is configured as GPIO */
                                                 kPORT_MuxAsGpio};

//    port_config.pullSelect = kPORT_PullDown;
    /* configure pin as GPIO with pull-down */
    PORT_SetPinConfig(BOARD_INITPINS_LED_GREEN_PORT, BOARD_INITPINS_LED_GREEN_PIN, &pull_down_config);

    for(count=0;count<100;count++);

    // read pin to ensure that it is indeed HIGH, if not, there is an external short on the board
    if( (GPIO_PinRead(BOARD_INITPINS_LED_GREEN_GPIO, BOARD_INITPINS_LED_GREEN_PIN)) )
    {
        LED_BLUE_ON();
        while(1);
    }

0 Kudos
Reply
3 Replies

971 Views
james5
Contributor I

Yes, there is a specific reason as I alluded to in my original posting.  I'm trying to write a self-test routine.  By setting to an input and enabling internal pull-up I can ensure that there is no short to ground on the board by reading HIGH.  Enabling the pull-down and reading LOW tells me there isn't a short to VCC on the board.  By reading all the other I/O with their pull-ups set I can tell that there isn't a short to another I/O pin.

In the end what I found was that I needed to have the following loop between the setting of the pull-up and the reading of the same pin, otherwise the program crashed in the debugger:

for( x=0; x<2; x++ );

If x = 0 or 1 then the crash happens.  I increased it to 10 to allow for some slowness to to capacitance on signal line in a real circuit.  This test doesn't have to be _fast_.

James

0 Kudos
Reply

971 Views
converse
Senior Contributor V

Note that your delay loop will ONLY work when building for debug. When you build for release, the compiler will optimise the code and remove the delay loop (as it does not do anything). As a minimum, you will need to declare your loop variable as volatile

0 Kudos
Reply

971 Views
Sebastian_Del_Rio
NXP Employee
NXP Employee

Hello James, I hope you're doing well,

 

Unfortunately, I was not able to replicate the problem you're experiencing. I loaded your code and it seems to be working correctly on my machine.

 

Can you please tell me the values for the "BOARD_INITPINS_LED_GREEN_GPIO" and "BOARD_INITPINS_LED_GREEN_PIN" masks?

 

I used in the evaluation kit

 

#define BOARD_INITPINS_LED_GREEN_GPIO GPIOB
#define BOARD_INITPINS_LED_GREEN_PIN 11

 

Also, is there a specific reason why you're configuring said pin as an input?

 

 

 

Best regards,

Sebastian

0 Kudos
Reply