Connecting radio event to a GPIOTE using DPPI on the network core running hci_rpmsg sample

I am having trouble setting up a GPIO pin that will toggle when the radio is active on the network core. I have tried adding the code in bluetooth.c from the ppi_trace sample to a copy of the hci_rpmsg sample with no results. At first I thought it was something to do with the GPIO pin, but I was able to toggle the pin using an event from Timer1. 

OS: Zephyr

nRF Connect SDK: v1.8.0

HW: nRF5340DK v2.0.0

Application Core is running an image based on BLE Central sample and the Network Core is running hci_rpmsg with DPPI additions. 

Is there anything I am missing?

Parents
  • Hi,

    I have not looked at the projects, but if you are able to connect a TIMER1 event that is used by hci_rpmsg project to a GPIO pin, then maybe you should check if there are any limitations in how to setup DPPI that you should be aware of. E.g. reading the documentation: 
    https://infocenter.nordicsemi.com/topic/ps_nrf5340/dppi.html 

    I can find the following: "In order to write to CHG[x], the corresponding CHG[x].EN and CHG[x].DIS subscribe registers must be disabled. Writes to CHG[x] are ignored if any of the two subscribe registers are enabled."

    In can be things like that also take effect here. 

    Which RADIO event are you trying to connect? Do you have any code snippet of the changes you have tried?

    Best regards,
    Kenneth

Reply
  • Hi,

    I have not looked at the projects, but if you are able to connect a TIMER1 event that is used by hci_rpmsg project to a GPIO pin, then maybe you should check if there are any limitations in how to setup DPPI that you should be aware of. E.g. reading the documentation: 
    https://infocenter.nordicsemi.com/topic/ps_nrf5340/dppi.html 

    I can find the following: "In order to write to CHG[x], the corresponding CHG[x].EN and CHG[x].DIS subscribe registers must be disabled. Writes to CHG[x] are ignored if any of the two subscribe registers are enabled."

    In can be things like that also take effect here. 

    Which RADIO event are you trying to connect? Do you have any code snippet of the changes you have tried?

    Best regards,
    Kenneth

Children
  • Hi Kenneth,

    I am trying to connect both the NRF_RADIO_EVENT_READY and NRF_RADIO_EVENT_DISABLED events eventually. The following code snippet was my attempt to connect the NRF_RADIO_EVENT_READY event. 

    #define DBG_PIN		31
    static uint8_t m_DbgCh;
    
    static nrfx_err_t DppiInit(void)
    {
    	nrfx_err_t err = NRFX_SUCCESS;
    	nrf_gpio_pin_mcu_select(DBG_PIN, NRF_GPIO_PIN_MCUSEL_PERIPHERAL);
    
    	err = nrfx_gpiote_init(0);
    	if (err != NRFX_SUCCESS)
    	{
    		LOG_ERR("GPIOTE Init failed (err 0x%08x)", err);
    		return err;
    	}
    	nrfx_gpiote_out_config_t const cfg = NRFX_GPIOTE_CONFIG_OUT_TASK_TOGGLE(false);
    	err = nrfx_gpiote_out_init(DBG_PIN, &cfg);
    	if (err != NRFX_SUCCESS)
    	{
    		LOG_ERR("GPIOTE Out init failed (err 0x%08x)", err);
    		return err;
    	}
    	nrfx_gpiote_out_task_enable(DBG_PIN);
    
    	err = nrfx_dppi_channel_alloc(&m_DbgCh);
    	if (err != NRFX_SUCCESS)
    	{
    		LOG_ERR("DPPI Debug Ch allocation failed (err 0x%08x)", err);
    		return err;
    	}
    	nrfx_gppi_channel_endpoints_setup(m_DbgCh,
    		nrf_radio_event_address_get(NRF_RADIO, NRF_RADIO_EVENT_READY),
    		nrfx_gpiote_out_task_addr_get(DBG_PIN));
    
    	err = nrfx_dppi_channel_enable(m_DbgCh);
    	if (err != NRFX_SUCCESS)
    	{
    		LOG_ERR("DPPI Debug Ch allocation failed (err 0x%08x)", err);
    		return err;
    	}
    
    	return err;
    }
    
    void main(void)
    {
    	int err;
    
    	/* incoming events and data from the controller */
    	static K_FIFO_DEFINE(rx_queue);
    
    	LOG_DBG("Start");
    
    	nrfx_err_t ret = DppiInit();
    	if (ret != NRFX_SUCCESS)
    		LOG_ERR("Failed to setup DPPI (err 0x%08x)", ret);
    		
    	/* Enable the raw interface, this will in turn open the HCI driver */
    	bt_enable_raw(&rx_queue);
    
    	/* Spawn the TX thread and start feeding commands and data to the
    	 * controller
    	 */
    	k_thread_create(&tx_thread_data, tx_thread_stack,
    			K_THREAD_STACK_SIZEOF(tx_thread_stack), tx_thread,
    			NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT);
    	k_thread_name_set(&tx_thread_data, "HCI rpmsg TX");
    
    	while (1) {
    		struct net_buf *buf;
    
    		buf = net_buf_get(&rx_queue, K_FOREVER);
    		err = hci_rpmsg_send(buf);
    		if (err) {
    			LOG_ERR("Failed to send (err %d)", err);
    		}
    	}
    }

    "In order to write to CHG[x], the corresponding CHG[x].EN and CHG[x].DIS subscribe registers must be disabled. Writes to CHG[x] are ignored if any of the two subscribe register

    I added some log statements that printed out the contents of the CHG[x].EN, CHG[x].DIS and CHG[x] registers and they are all 0x00000000. I put the log statements after bt_enable_raw(&rx_queue). 

    Do you have any other suggestions?

    Thank you,

    Austin

  • I suspect the reason why this is not working is that on the nRF5340 there is DPPI, and there is only one publish_ready register:
    https://infocenter.nordicsemi.com/topic/ps_nrf5340/radio.html#register.PUBLISH_READY

    What happens in this case is that you are configuring this register to be used with channel m_DbgCh, however later the zephyr controller will overwrite this register to for instance be used with the radio coex functionality. So for this to work as you want, you likely will need to find where in the zephyr controller the NRF_RADIO_EVENT_READY is used, and re-use the same CHIDX set in the PUBLISH_READY for the GPIOTE channel you want toggle.

    Kenneth

Related