This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Read GPIO immediately after configured

Tested with PCA10040 1.2.4 bare board
Chosen p0.11 as it seems to connect nothing (floating)

I would expect the code below always prints "<info> Main: [11] 1 1 1 1 1", no matter how many times nrf_gpio_cfg_default() is called.
I did see the expected result when nrf_gpio_cfg_default() is not called at all.
But by adding number of nrf_gpio_cfg_default() calls the result varies:
    0 call(s) => <info> Main: [11] 1 1 1 1 1
    1 call(s) => <info> Main: [11] 0 1 1 1 1
    2 call(s) => <info> Main: [11] 0 1 1 1 1
    3 call(s) => <info> Main: [11] 1 1 1 1 1
    4 call(s) => <info> Main: [11] 0 0 1 1 1

...

#define GPIO_PIN_TO_TEST                (11)
static void test_read_gpio(void)
{
    uint32_t read_result[5];

    /*
     * Pre-configure actions
     * Not expected that this does affect read result
     * and even number of nrf_gpio_cfg_default() calls matters
     */
//    nrf_gpio_cfg_default(GPIO_PIN_TO_TEST);
//    nrf_gpio_cfg_default(GPIO_PIN_TO_TEST);
//    nrf_gpio_cfg_default(GPIO_PIN_TO_TEST);
//    nrf_gpio_cfg_default(GPIO_PIN_TO_TEST);
//    nrf_gpio_cfg_default(GPIO_PIN_TO_TEST);
//    nrf_gpio_cfg_default(GPIO_PIN_TO_TEST);
//    nrf_gpio_cfg_default(GPIO_PIN_TO_TEST);
//    nrf_gpio_cfg_default(GPIO_PIN_TO_TEST);
//    nrf_gpio_cfg_default(GPIO_PIN_TO_TEST);
    nrf_gpio_cfg_input(GPIO_PIN_TO_TEST, NRF_GPIO_PIN_PULLUP);

    /*
     * Read GPIO multiple times
     */
    read_result[0] = nrf_gpio_pin_read(GPIO_PIN_TO_TEST);
    read_result[1] = nrf_gpio_pin_read(GPIO_PIN_TO_TEST);
    read_result[2] = nrf_gpio_pin_read(GPIO_PIN_TO_TEST);
    read_result[3] = nrf_gpio_pin_read(GPIO_PIN_TO_TEST);
    read_result[4] = nrf_gpio_pin_read(GPIO_PIN_TO_TEST);
    NRF_LOG_INFO("[%d] %d %d %d %d %d", GPIO_PIN_TO_TEST, read_result[0], read_result[1], read_result[2], read_result[3], read_result[4]);
    NRF_LOG_FLUSH();

    /*
     * return to deault
     */
    nrf_gpio_cfg_default(GPIO_PIN_TO_TEST);
}

/**@brief Function for application main entry.
 */
int main(void)
{
    ret_code_t err_code;

    log_init();
    NRF_LOG_INFO("[%s] self_inspection", __func__);
    NRF_LOG_FLUSH();

    test_read_gpio();
    return 0;
}

Exact results repeated constantly on the same PCA10040 and even another custom board where p0.11 is pulled to ground externally by 200k resistor.

 pointed out the fact that GPIO runs off the 16 MHz peripheral clock, while CPU runs off 64 MHz in this post
Is this the real cause of the above phenomenon?
Or is it caused by some (SOC internal / PCB) RC rising / falling characteristics?

And what is the best solution? (naive delay does the job, not I doubt its efficiency)
(Say, if the real cause is 16/64 MHz timing, maybe Data / Instruction Synchronization Barrier is the answer?)

Parents Reply Children
  • I get this, which is expected:

    <info> app: [0000000B] 1 1 1 1 1

    I ran some sanity tests, all pass:

    STATIC_ASSERT( 0 == (GPIO_PIN_CNF_DIR_Pos),   "Error - GPIO_PIN_CNF_DIR_Pos");
    STATIC_ASSERT( 1 == (GPIO_PIN_CNF_INPUT_Pos), "Error - GPIO_PIN_CNF_INPUT_Pos");
    STATIC_ASSERT( 2 == (GPIO_PIN_CNF_PULL_Pos),  "Error - GPIO_PIN_CNF_PULL_Pos");
    STATIC_ASSERT( 8 == (GPIO_PIN_CNF_DRIVE_Pos), "Error - GPIO_PIN_CNF_DRIVE_Pos");
    STATIC_ASSERT(16 == (GPIO_PIN_CNF_SENSE_Pos), "Error - GPIO_PIN_CNF_SENSE_Pos");
    
    STATIC_ASSERT(0x000003 ==
                       ((NRF_GPIO_PIN_DIR_OUTPUT       << GPIO_PIN_CNF_DIR_Pos)   |
                        (NRF_GPIO_PIN_INPUT_DISCONNECT << GPIO_PIN_CNF_INPUT_Pos) |
                        (NRF_GPIO_PIN_NOPULL           << GPIO_PIN_CNF_PULL_Pos)  |
                        (NRF_GPIO_PIN_S0S1             << GPIO_PIN_CNF_DRIVE_Pos) |
                        (NRF_GPIO_PIN_NOSENSE          << GPIO_PIN_CNF_SENSE_Pos)), "PIN_CFG Error");
    STATIC_ASSERT(0x00000 ==
                       ((NRF_GPIO_PIN_DIR_INPUT        << GPIO_PIN_CNF_DIR_Pos)   |
                        (NRF_GPIO_PIN_INPUT_CONNECT    << GPIO_PIN_CNF_INPUT_Pos) |
                        (NRF_GPIO_PIN_NOPULL           << GPIO_PIN_CNF_PULL_Pos)  |
                        (NRF_GPIO_PIN_S0S1             << GPIO_PIN_CNF_DRIVE_Pos) |
                        (NRF_GPIO_PIN_NOSENSE          << GPIO_PIN_CNF_SENSE_Pos)), "PIN_CFG Error");
    STATIC_ASSERT(0x00002 ==
                       ((NRF_GPIO_PIN_DIR_INPUT        << GPIO_PIN_CNF_DIR_Pos)   |
                        (NRF_GPIO_PIN_INPUT_DISCONNECT << GPIO_PIN_CNF_INPUT_Pos) |
                        (NRF_GPIO_PIN_NOPULL           << GPIO_PIN_CNF_PULL_Pos)  |
                        (NRF_GPIO_PIN_S0S1             << GPIO_PIN_CNF_DRIVE_Pos) |
                        (NRF_GPIO_PIN_NOSENSE          << GPIO_PIN_CNF_SENSE_Pos)), "PIN_CFG Error");

    I take it there is nothing plugged into pin 11, such as an expansion board? If that were the case, you would see a slower rise/fall time on the pin which would affect your results

  • There's only PCA10040, nothing else.

    It's so weird that the same project behaves differently... 

    Could you try this binary, and could you please share your binary?

    blinky_pca10040.hex

Related