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);
}
  • app_button does not use timer for polling in that sense. It uses a timer for a debounce delay after the button has been pushed, see here. The error you are getting is because GPIOTE_IRQHandler is defined in nrf_drv_gpiote.c and in main.c. I would suggest that you use the nrf_drv_gpiote library. Be aware that with the SoftDevice, the delay may be longer than 1 ms while in a connection, see here for more info.

  • Thank you for the suggestion, Ole Bauck.

    I looked into the gpiote example in SDK 9.0.0. The example only used gpiote task to drive the LED while gpiote event is not included. I tried to add a gpiote event but it did not work.

    Is there any gpiote example that uses gpiote event (e.g. evoked by a button switching the pin fro high to low)?

  • Never mind. I managed to get the gpiote event working though it did not respond to a LED task through ppi. That's for another question.

  • What do you mean when you say "stopped working"? Do the chip reset (this is the default behaviour if err_code is not NRF_SUCCESS in APP_ERROR_CHECK(...))?

  • When the main function called gpiote_init, the DK board did not reach scanning. All 4 LEDs were on.

    Without gpiote_init, the DK board scanned and could detect the dongle board which was running the periperhal code. Only LED 1 was on.

    How do I check that err_code does not return NRF_SUCCESS ?

    I also discovered that if m_cb.state = NRF_DRV_STATE_INITIALIZED; is commented out in nrf_drv_gpiote_init, the code works.

    I don't understand why though.

Related