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

Problem using GPIO- and BSP-module simultaneously

Hello,

last week I was trying to integrate a wake-on-motion-functionality for my hardware using some interrupt-handling. While that problem is solved, I came across some kind of interdependency between initializing the GPIO- and the BSP-module simultaneaously.

Here is the code of the 2 functions which I am using:

a) gpio_config()

{
    ret_code_t err_code;

    err_code = nrf_drv_gpiote_init();
    check_error_code(__func__, err_code, 1);

    nrf_drv_gpiote_in_config_t pin_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);

    err_code = nrf_drv_gpiote_in_init(MOTION_IRQ_PIN, &pin_config, motion_irq_evt_handler);
    check_error_code(__func__, err_code, 2);

    nrf_drv_gpiote_in_event_enable(MOTION_IRQ_PIN, true);

    printf("%s(): GPIOs initialized\r\n", __func__);
}

b) bsp_config(bool *p_erase_bonds)

{
    bsp_event_t startup_event;
    uint32_t err_code = NRF_SUCCESS;

    err_code = bsp_init(BSP_INIT_LED | BSP_INIT_BUTTONS,
                        APP_TIMER_TICKS(100, APP_TIMER_PRESCALER),
						bsp_evt_handler);
	if (err_code != NRF_ERROR_INVALID_STATE)
	{
		check_error_code(__func__, err_code, 1);
	}// if (err_code != NRF_ERROR_INVALID_STATE)

    err_code = bsp_btn_ble_init(NULL, &startup_event);
	if (err_code != NRF_ERROR_INVALID_STATE)
	{
		check_error_code(__func__, err_code, 2);
	}// if (err_code != NRF_ERROR_INVALID_STATE)

    *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA);

    printf("%s(): BSP initialized\r\n", __func__);
}

c) Calling-procedure in main()

{
    bool erase_bonds = true;
    uint32_t err_code = NRF_SUCCESS;

    system_startup();

    // Initialize hmi
    gpio_config();
    bsp_config(&erase_bonds);

    // Initialize peer-manager
    pm_config(erase_bonds);

    // Initialize bt-support
    ble_stack_init();
    gap_params_init();
    services_init();

    ...
}

When I first started using this particular procedure with SDK v12.0.0, I was experiencing the a problem with error-code NRF_ERROR_INVALID_STATE (0x0008) inside bsp_config(). So I decided to just uncomment the functionality within bsp_config(), but then I was running into some dependency-issues regarding the ble-advertising. Then I went for a simple workaround by just excluding this error-code from being handled by APP_ERROR_CHECK(), which basically just "disguises" the error and doesnt actually solve it.

After upgrading my SDK to v12.2.0 - without adjusting anything of the code-parts a)-c) - the entire functionality within bsp_config() seems to be causing a problem, so that I actually have to uncomment all of its occurences to keep my system operational.

Now to my questions:

a) Is there any specific order in what way the initialization of the GPIO- and the BSP-module should be handled?

b) Does the upgrade from SDK v12.0.0 to v12.2.0 require any adjustment of the bsp_config()-code or the initialization-order inside main()?

I was already cross-checking with some of the SDK-examples, but the code inside bsp_config() is pretty much the same everywhere and also the call inside main(), which always happens before initializing the peer-manager or the ble-stack!

This is where I am lost...

  • I used this definement here #define MOTION_IRQ_PIN 16 - but like I said the wake-on-motion-functionality isnt my problem! Even if I uncomment everything related to gpio_config() then I still got the same errors (which I cant see) for bsp_config()...

  • Hello Ray Breslin

    I copied your code and did a couple of tests. First a comment on the error you received from bsp_config(). I believe the NRF_ERROR_INVALID_STATE arises due to a conflict in GPIOTE channel assignments. You said in your comment that you use pin P0.16 for the wake up functionality. In your gpio_config function you assign a GPIOTE channel to this pin.

    The bsp_config() function initializes the leds and buttons of the development kit. So when bsp_config() is called it too tries to assign a GPIOTE channel to pin 16, which is wired to button 4 on the development kit. The function performs a check, and notices the pin is already in use. It then generates the NRF_ERROR_INVALID_STATE error.

    If I remove the gpio_config function in my test, everything functions as normal. If you still get errors when you comment away your gpio_config function, then there might be a problem in parts of your code, which you have not posted here. Now on to your questions

    a) when initializing the bsp module, it configures pins P0.13 to P0.20 for leds and buttons. If you configure any of these pins before that, chances are they're gonna be overridden. As mentioned above, the bsp module uses GPIOTE for the pins, so keep that in mind when initializing your GPIOTE. In your case I think the best way would be to first initialize the bsp module, and then change the configurations for pin 16, and any other pin you use, to suit your needs. That way the bsp module is allowed to initialize as it should, before you change the functionality of the buttons or leds.

    b) To my knowledge, it should not be necessary to make any adjustments to the bsp module or the order of initializations when changing from SDK 12.0.0 to SDK 12.2.0

    Best regards

    Jørn Frøysa

  • Thank you for your replay Jorn and for doing the tests with my code!

    While I do understand the behaviour for a) (which does make sense), I still cant get bsp_config() to run properly even if its standalone in b).

    Here are some additional code-snippets from before and after the bsp_config()-call!

    1. Contents of system-startup() [before]

      static void timer_clk_init(void) { nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG; // Time(in milliseconds) between consecutive compare events uint32_t time_ms = 1; uint32_t time_ticks; uint32_t err_code = NRF_SUCCESS;

       APP_TIMER_INIT(...);
      
       err_code = nrf_drv_timer_init(...);
      
       time_ticks = nrf_drv_timer_ms_to_ticks(...);
       nrf_drv_timer_extended_compare(...);
      
       nrf_drv_timer_enable(&TIMER_CLK);
      

      }

      static void uart_init(void) { uint8_t uart_mode = NRF_LOG_ENABLED; uint32_t err_code = NRF_SUCCESS;

       if (uart_mode == 1)
       {
           err_code = NRF_LOG_INIT(NULL);
           check_error_code(__func__, err_code, 1);
       }
       else
       {
           ...
      
           APP_UART_FIFO_INIT(&comm_params,
                              UART_RX_BUF_SIZE,
                              UART_TX_BUF_SIZE,
                              uart_evt_handler,
                              APP_IRQ_PRIORITY_LOW,
                              err_code);
           check_error_code(__func__, err_code, 1);
       }// if (uart_mode == 1)
      

      }

    2. Contents of pm_config() [after]

      static void pm_config(bool erase_bonds) { ble_gap_sec_params_t sec_param; ret_code_t err_code;

       printf("%s(): Peer Manager initializing...\r\n", __func__);
      
       err_code = pm_init();
       check_error_code(__func__, err_code, 1);
      
       if (erase_bonds)
       {
           pm_peers_delete();
       }// if (erase_bonds)
      
       memset(&sec_param, 0, sizeof(ble_gap_sec_params_t));
      
       // Security parameters to be used for all security procedures
       ...
      
       err_code = pm_sec_params_set(&sec_param);
       check_error_code(__func__, err_code, 2);
      
       err_code = pm_register(pm_evt_handler);
       check_error_code(__func__, err_code, 3);
      
       printf("%s(): Peer Manager initialized\r\n", __func__);
      

      }

  • Could you comment out the gpio_config function, or change the pin to one not used by the bsp_init function, to remove the GPIOTE conflict, and then run debug? It would be helpful to know exactly which error you are getting, and what part of the bsp_init function is triggering it.

Related