This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Pin P0.00 as a button input not working as GPIO but P0.01 does. Already switched all LFCLKSRC to RC.

Board: NRF52840

SDK: 16

Soft Device: s113

So our board is custom and does not contain a crystal. We are treating P0.00 and P0.01 as GPIOs for button inputs. P0.01 works fine but P0.00 does not work and no events are produced despite both being programmed the exact same way.  

I understand that those pins are reserved as crystal pins and according to other posts in this forum you should switch all LFCLKSRC to RC when you want to use them as GPIO. This has been done and does not fix the issue. In addition there are no NULL values in the pin configuration. The EE tested the voltage and found that it is oscillating between hi and low when the button is not pressed. Below is how the pins are configured with BSP_BUTTON_0 being the button not working correctly: 

static const app_button_cfg_t app_buttons[BUTTONS_NUMBER] =
{
    #ifdef BSP_BUTTON_0
    {BSP_BUTTON_0, APP_BUTTON_ACTIVE_LOW, NRF_GPIO_PIN_NOPULL, bsp_button_event_handler},
    #endif // BUTTON_0

    #ifdef BSP_BUTTON_1
    {BSP_BUTTON_1, APP_BUTTON_ACTIVE_LOW, NRF_GPIO_PIN_NOPULL, bsp_button_event_handler},
    #endif // BUTTON_1

    #ifdef BSP_BUTTON_2
    {BSP_BUTTON_2, APP_BUTTON_ACTIVE_LOW, NRF_GPIO_PIN_PULLUP, bsp_button_event_handler},
    #endif // BUTTON_2

    #ifdef BSP_BUTTON_3
    {BSP_BUTTON_3, APP_BUTTON_ACTIVE_LOW, NRF_GPIO_PIN_NOPULL, bsp_button_event_handler},
    #endif // BUTTON_3

    #ifdef BSP_BUTTON_4
    {BSP_BUTTON_4, APP_BUTTON_ACTIVE_LOW, NRF_GPIO_PIN_NOPULL, bsp_button_event_handler},
    #endif // BUTTON_4

    #ifdef BSP_BUTTON_5
    {BSP_BUTTON_5, APP_BUTTON_ACTIVE_LOW, NRF_GPIO_PIN_NOPULL, bsp_button_event_handler},
    #endif // BUTTON_5

    #ifdef BSP_BUTTON_6
    {BSP_BUTTON_6, APP_BUTTON_ACTIVE_LOW, NRF_GPIO_PIN_NOPULL, bsp_button_event_handler},
    #endif // BUTTON_6

    #ifdef BSP_BUTTON_7
    {BSP_BUTTON_7, APP_BUTTON_ACTIVE_LOW, NRF_GPIO_PIN_NOPULL, bsp_button_event_handler},
    #endif // BUTTON_7

    #ifdef BSP_BUTTON_8
    {BSP_BUTTON_8, APP_BUTTON_ACTIVE_LOW, NRF_GPIO_PIN_NOPULL, bsp_button_event_handler},
    #endif // BUTTON_8

    #ifdef BSP_BUTTON_9
    {BSP_BUTTON_9, APP_BUTTON_ACTIVE_LOW, NRF_GPIO_PIN_NOPULL, bsp_button_event_handler},
    #endif // BUTTON_9
};

Given this information, any information that could solve this issue with the button not working?    

  • Hi

    What did you change in order to set the LFCLKSRC to use the RC oscillator exactly? The recommendation is to make these changes to the following function in your sdk_config.h file:

    // <h> Clock - SoftDevice clock configuration
    
    //==========================================================
    // <o> NRF_SDH_CLOCK_LF_SRC  - SoftDevice clock source.
     
    // <0=> NRF_CLOCK_LF_SRC_RC 
    // <1=> NRF_CLOCK_LF_SRC_XTAL 
    // <2=> NRF_CLOCK_LF_SRC_SYNTH 
    
    #ifndef NRF_SDH_CLOCK_LF_SRC
    #define NRF_SDH_CLOCK_LF_SRC 0
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_RC_CTIV - SoftDevice calibration timer interval. 
    #ifndef NRF_SDH_CLOCK_LF_RC_CTIV
    #define NRF_SDH_CLOCK_LF_RC_CTIV 16
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_RC_TEMP_CTIV - SoftDevice calibration timer interval under constant temperature. 
    // <i> How often (in number of calibration intervals) the RC oscillator shall be calibrated
    // <i>  if the temperature has not changed.
    
    #ifndef NRF_SDH_CLOCK_LF_RC_TEMP_CTIV
    #define NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 2
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_ACCURACY  - External clock accuracy used in the LL to compute timing.
     
    // <0=> NRF_CLOCK_LF_ACCURACY_250_PPM 
    // <1=> NRF_CLOCK_LF_ACCURACY_500_PPM 
    // <2=> NRF_CLOCK_LF_ACCURACY_150_PPM 
    // <3=> NRF_CLOCK_LF_ACCURACY_100_PPM 
    // <4=> NRF_CLOCK_LF_ACCURACY_75_PPM 
    // <5=> NRF_CLOCK_LF_ACCURACY_50_PPM 
    // <6=> NRF_CLOCK_LF_ACCURACY_30_PPM 
    // <7=> NRF_CLOCK_LF_ACCURACY_20_PPM 
    // <8=> NRF_CLOCK_LF_ACCURACY_10_PPM 
    // <9=> NRF_CLOCK_LF_ACCURACY_5_PPM 
    // <10=> NRF_CLOCK_LF_ACCURACY_2_PPM 
    // <11=> NRF_CLOCK_LF_ACCURACY_1_PPM 
    
    #ifndef NRF_SDH_CLOCK_LF_ACCURACY
    #define NRF_SDH_CLOCK_LF_ACCURACY 1
    #endif

    P0.00 and P0.01 should behave identically when the RC oscillator is enabled, so the only two things I can think of that would cause something like this is either the LFCLKSRC not being configured correctly to use the RC oscillator, or that there's a HW issue where the P0.00 pin is soldered incorrectly. Can you check your custom board to make sure that it's not a disconnect or short somewhere on the P0.00 line.

    Best regards,

    Simon

  • Hey Simon, 

    Yeah I changed the SDK options for XTAL in three places: 

    // <e> NRFX_CLOCK_ENABLED - nrfx_clock - CLOCK peripheral driver
    //==========================================================
    #ifndef NRFX_CLOCK_ENABLED
    #define NRFX_CLOCK_ENABLED 1
    #endif
    // <o> NRFX_CLOCK_CONFIG_LF_SRC  - LF Clock Source
     
    // <0=> RC 
    // <1=> XTAL 
    // <2=> Synth 
    // <131073=> External Low Swing 
    // <196609=> External Full Swing 
    
    #ifndef NRFX_CLOCK_CONFIG_LF_SRC
    #define NRFX_CLOCK_CONFIG_LF_SRC 0
    #endif

    // <e> NRF_CLOCK_ENABLED - nrf_drv_clock - CLOCK peripheral driver - legacy layer
    //==========================================================
    #ifndef NRF_CLOCK_ENABLED
    #define NRF_CLOCK_ENABLED 1
    #endif
    // <o> CLOCK_CONFIG_LF_SRC  - LF Clock Source
     
    // <0=> RC 
    // <1=> XTAL 
    // <2=> Synth 
    // <131073=> External Low Swing 
    // <196609=> External Full Swing 
    
    #ifndef CLOCK_CONFIG_LF_SRC
    #define CLOCK_CONFIG_LF_SRC 0
    #endif

    // </h> 
    //==========================================================
    
    // <h> Clock - SoftDevice clock configuration
    
    //==========================================================
    // <o> NRF_SDH_CLOCK_LF_SRC  - SoftDevice clock source.
     
    // <0=> NRF_CLOCK_LF_SRC_RC 
    // <1=> NRF_CLOCK_LF_SRC_XTAL 
    // <2=> NRF_CLOCK_LF_SRC_SYNTH 
    
    #ifndef NRF_SDH_CLOCK_LF_SRC
    #define NRF_SDH_CLOCK_LF_SRC 0
    #endif

    Are there any specific settings elsewhere that need to be set when switching to RC? 

  • Hi

    This should be sufficient to use the RC oscillator. You should set the accuracy and calibration values to what I mentioned in my last reply to ensure that it doesn't drift too much, but this indicates that P0.00 is not connected properly. Can you check your custom board to make sure that it's not a disconnect or short somewhere on the P0.00 line.

    Best regards,

    Simon

  • I checked the settings and they do match what you put in your original reply so we can filter that out.

    There is no disconnect or short anywhere. The EE has confirmed and said that it is like this in more than one stick. 

    Here is the log output for Button 0 with code SEGGER_RTT_printf(0, "Button 0 Status: %d\n", NRF_GPIO->PIN_CNF[BUTTON_0]);:

    uint32_t bsp_init(uint32_t type, bsp_event_callback_t callback)
    {
        SEGGER_RTT_WriteString(0, "bsp_init() bsp class\n");
        SEGGER_RTT_printf(0, "Button 0 Status: %d\n", NRF_GPIO->PIN_CNF[RTH_BUTTON]);
        uint32_t err_code = NRF_SUCCESS;
    
    #if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
        m_indication_type     = type;
    #endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
    
    #if (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE)
        m_registered_callback = callback;
    
        // BSP will support buttons and generate events
        if (type & BSP_INIT_BUTTONS)
        {
            uint32_t num;
            SEGGER_RTT_printf(0, "Button 0 Status: %d\n", NRF_GPIO->PIN_CNF[RTH_BUTTON]);
    
            for (num = 0; ((num < BUTTONS_NUMBER) && (err_code == NRF_SUCCESS)); num++)
            {
                err_code = bsp_event_to_button_action_assign(num, BSP_BUTTON_ACTION_PUSH, BSP_EVENT_DEFAULT);
            }
    
            /*added in to handle button releases*/
            for (num = 0; ((num < BUTTONS_NUMBER) && (err_code == NRF_SUCCESS)); num++)
            {
                err_code = bsp_event_to_button_action_assign(num, BSP_BUTTON_ACTION_RELEASE, BSP_EVENT_RELEASE);
            }
    
            if (err_code == NRF_SUCCESS)
            {
                err_code = app_button_init((app_button_cfg_t *)app_buttons,
                                           BUTTONS_NUMBER,
                                           APP_TIMER_TICKS(5));
               SEGGER_RTT_WriteString(0, "app_button_init()\n");
            }
            SEGGER_RTT_printf(0, "Button 0 Status: %d\n", NRF_GPIO->PIN_CNF[RTH_BUTTON]);
    
            if (err_code == NRF_SUCCESS)
            {
                err_code = app_button_enable();
                SEGGER_RTT_WriteString(0, "app_button_enable()\n");
            }
            SEGGER_RTT_printf(0, "Button 0 Status: %d\n", NRF_GPIO->PIN_CNF[RTH_BUTTON]);
    
            if (err_code == NRF_SUCCESS)
            {
                err_code = app_timer_create(&m_bsp_button_tmr,
                                            APP_TIMER_MODE_SINGLE_SHOT,
                                            button_timer_handler);
            }
            SEGGER_RTT_WriteString(0, "app_timer_create() button\n");
        }
    #elif (BUTTONS_NUMBER > 0) && (defined BSP_SIMPLE)
        bsp_board_init(type);
    #endif // (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE)
    
    #if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
        if (type & BSP_INIT_LEDS)
        {
          //handle LEDs only. Buttons are already handled.
          bsp_board_init(BSP_INIT_LEDS);
    
          // timers module must be already initialized!
          if (err_code == NRF_SUCCESS)
          {
              err_code =
                  app_timer_create(&m_bsp_leds_tmr, APP_TIMER_MODE_SINGLE_SHOT, leds_timer_handler);
          }
    
          if (err_code == NRF_SUCCESS)
          {
              err_code =
                  app_timer_create(&m_bsp_alert_tmr, APP_TIMER_MODE_REPEATED, alert_timer_handler);
          }
        }
    #endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
    
        return err_code;
    }

    The log outputs:

    bsp_init() bsp class
    Button 0 Status: 2
    Button 0 Status: 2
    app_button_init()
    Button 0 Status: 0
    app_button_enable()
    Button 0 Status: 196608

    Then the log in the main loop:

    Button 0 Status: 3

    What do the numbers represent? Does this help with diagnosing the issue? 

  • Hi

    The PIN_CNF register is the config register for every GPIO, so the numbers represent whether they're set as input, output, disconnected, high drive, and so on (mentioned in the nRF52840 PS.

    The last value you log is 3, which means it's a disconnected output. (the default should be 2 which is a disconnected input). To use it as a button you need a pull (up or down) on a connected input.

    Best regards,

    Simon

Related