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

GPIO pullups and direction

If I write a zero to the output register, and enable the pullup on the same pin, can I switch between driven low output and input with pullup simply by settting/clearing the DIR bit? Will the pullup still be in circuit when the output is enabled? I have studied the datasheet and the associated schematic, but this is still not clear to me.

Parents
  • I have tried the both ,

    NRF_GPIO->DIRSET |= (1UL << LED_1);
    NRF_GPIO->PIN_CNF[LED_1] |=  GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos;	
    
    NRF_GPIO->DIRSET &= ~(1UL << LED_1);
    

    NRF_GPIO->DIRSET &= ~(1UL << LED_1);
    NRF_GPIO->PIN_CNF[LED_1] |=  GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos;	
    
    NRF_GPIO->DIRSET |= (1UL << LED_1);
    while(1);
    

    and the pullup wasn't there. So i am concluding that it will be reset to no_pull everytime we change pin direction

  • I think you are using the wrong register. It should be DIR, rather than DIRSET. I just wrote the following snippet of code:

    NRF_GPIO->DIR &= ~(1UL << BUTTON_NORTH);		// Set as ip
    NRF_GPIO->PIN_CNF[BUTTON_NORTH] |= GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos; // Set pullup
    
    SEGGER_RTT_printf(0, "PIN_CNF = %08x\n\r", NRF_GPIO->PIN_CNF[BUTTON_NORTH]);
    NRF_GPIO->DIR |= (1UL << BUTTON_NORTH);		// Set as op
    SEGGER_RTT_printf(0, "PIN_CNF = %08x\n\r", NRF_GPIO->PIN_CNF[BUTTON_NORTH]);
    NRF_GPIO->DIR &= ~(1UL << BUTTON_NORTH);		// Set as ip
    SEGGER_RTT_printf(0, "PIN_CNF = %08x\n\r", NRF_GPIO->PIN_CNF[BUTTON_NORTH]);
    

    and the output on the Segger RTT shows the PIN_CNF rgister to be: 0x0000000e 0x0000000f 0x0000000e

    So I believe the pullup does persist if you use the DIR register to chage direction.

    I will re-write this to use the DIRSET and DIRCLR registers...

    while(1);
    
Reply
  • I think you are using the wrong register. It should be DIR, rather than DIRSET. I just wrote the following snippet of code:

    NRF_GPIO->DIR &= ~(1UL << BUTTON_NORTH);		// Set as ip
    NRF_GPIO->PIN_CNF[BUTTON_NORTH] |= GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos; // Set pullup
    
    SEGGER_RTT_printf(0, "PIN_CNF = %08x\n\r", NRF_GPIO->PIN_CNF[BUTTON_NORTH]);
    NRF_GPIO->DIR |= (1UL << BUTTON_NORTH);		// Set as op
    SEGGER_RTT_printf(0, "PIN_CNF = %08x\n\r", NRF_GPIO->PIN_CNF[BUTTON_NORTH]);
    NRF_GPIO->DIR &= ~(1UL << BUTTON_NORTH);		// Set as ip
    SEGGER_RTT_printf(0, "PIN_CNF = %08x\n\r", NRF_GPIO->PIN_CNF[BUTTON_NORTH]);
    

    and the output on the Segger RTT shows the PIN_CNF rgister to be: 0x0000000e 0x0000000f 0x0000000e

    So I believe the pullup does persist if you use the DIR register to chage direction.

    I will re-write this to use the DIRSET and DIRCLR registers...

    while(1);
    
Children
No Data
Related