This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
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

Using GPIOTE with S130 in the BLE UART example

I've been using the ble_app_uart example with S130 on a nRF51 DK board. I wanted to add an interrupt with some GPIO pins. So I added GPIOTE interrupt handler but the compiler returned an error:

linking... ._build\nrf51422_xxac_s120.axf: Error: L6200E: Symbol GPIOTE_IRQHandler multiply defined (by nrf_drv_gpiote.o and main.o). Not enough information to list image symbols. Not enough information to list the image map. Finished: 2 information, 0 warning and 1 error messages. "._build\nrf51422_xxac_s120.axf" - 1 Error(s), 0 Warning(s).

I only added two function: stimulus_init and the interrupt handler.

void stimulus_init(void) 
{
  nrf_gpio_cfg_sense_input(16, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_LOW);
  NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Msk;
  NVIC_EnableIRQ(GPIOTE_IRQn);
}
void GPIOTE_IRQHandler(void)
{
  if(NRF_GPIOTE->EVENTS_PORT)
  {
    NRF_GPIOTE->EVENTS_PORT = 0;
  }
}

I am aware of the function "app_button_init" to initialise GPIO pins. But it seems that it uses timer for polling. I need to use interrupt in order to minimise delay which needs to be within 1 ms.


Update: 02/12/2015

After I could get the gpiote event working on its own (without any softdevice), I added the code below to main.c and called it in the main function. The idea is that when button 1 (AUDIO_STIM_PIN) is pressed, "A" is sent over BLE UART.

But then the entire code stopped working. Even after commenting everything after nrf_drv_gpiote_init(), the code stopped working.

Any suggestions on what went wrong?

void stimulus_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) 
{
	uint8_t data_array[1] = "A";
	uint16_t len = 1;
	ret_code_t err_code = ble_uart_c_write_string(&m_ble_uart_c, data_array, len);
  if (err_code != NRF_ERROR_INVALID_STATE)
  {
    APP_ERROR_CHECK(err_code);
  }
}

void gpiote_init(void)
{
	uint32_t gpiote_event_addr;
	ret_code_t err_code;
	
	err_code = nrf_drv_gpiote_init();
  APP_ERROR_CHECK(err_code);
	
  nrf_drv_gpiote_in_config_t event_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);

  err_code = nrf_drv_gpiote_in_init(AUDIO_STIM_PIN, &event_config, stimulus_handler);
  APP_ERROR_CHECK(err_code);
  
	gpiote_event_addr = nrf_drv_gpiote_in_event_addr_get(AUDIO_STIM_PIN);
  
	nrf_drv_gpiote_in_event_enable(AUDIO_STIM_PIN, true);
}
Parents
  • Update answer:

    The gpiote driver is already initialized so nrf_drv_gpiote_init() will return error and either stop the code or reset the chip depending if DEBUG is defined (see the code in app_error_handler(...)). Change to this code:

    if(!nrf_drv_gpiote_is_init())
    {
        err_code = nrf_drv_gpiote_init();
        APP_ERROR_CHECK(err_code);
    }
    

    Update 09.12.2015: The GPIOTE handler is running at APP_PRIORITY_HIGH, which means that sd_ble_gattc_write(...) is called at this level. It is not allowed to do SoftDevice calls at APP_PRIORITY_HIGH, and if attempted to do so, the application will run into hardfault. SoftDevice calls have to be made in main context or at APP_PRIORITY_LOW.

  • Thanks for that. I just discovered this too after stepping through in Debug.

    I also decided to use another pin (P0.15) and placed another button switch there so that it will call my event handler instead of gpiote_event_handler. I also had to use the high accuracy option (nrf_drv_gpiote_in_config_t event_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);). After these two changes and adding the init check (nrf_drv_gpiote_is_init) that you pointed out, the code worked as original.

    Interestingly, when I pressed the new button, the BLE link was disconnected. The red LED on the dongle changed from on (connected state) to blinking (disconnected). I expected stimulus_handler to be executed which sent the string "A" to the dongle. If the reset button the DK board is pressed, the BLE link was connected again. But pressing the button disconnected the ink again.

Reply
  • Thanks for that. I just discovered this too after stepping through in Debug.

    I also decided to use another pin (P0.15) and placed another button switch there so that it will call my event handler instead of gpiote_event_handler. I also had to use the high accuracy option (nrf_drv_gpiote_in_config_t event_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);). After these two changes and adding the init check (nrf_drv_gpiote_is_init) that you pointed out, the code worked as original.

    Interestingly, when I pressed the new button, the BLE link was disconnected. The red LED on the dongle changed from on (connected state) to blinking (disconnected). I expected stimulus_handler to be executed which sent the string "A" to the dongle. If the reset button the DK board is pressed, the BLE link was connected again. But pressing the button disconnected the ink again.

Children
No Data
Related