54l15 gppi question

hi support team,

customer want to use 54L15 radio event 

NRF_RADIO_EVENT_READY to set up gpio high ,and 
NRF_RADIO_EVENT_DISABLED to clear gpio to low.
i tried below code, but not working, i don't know why, i have tried two days ,but don't know the reason:
nrfx_err_t err;
    uint8_t gpiote_channel;
    uint8_t  ppi_set;
    uint8_t  ppi_clr;

    nrfx_gpiote_t const gpiote_inst = NRFX_GPIOTE_INSTANCE(20);
    err = nrfx_gpiote_init(&gpiote_inst,NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY);
        if (err != NRFX_SUCCESS) {
    printk("nrfx_gpiote_init error: %d\r\n", err);
    // return;
	}

    
    err = nrfx_gpiote_channel_alloc(&gpiote_inst,&gpiote_channel);
    if (err != NRFX_SUCCESS) {
    printk("nrfx_gpiote_channel_alloc error: %08x", err);
    return;
	}

    
    static const nrfx_gpiote_output_config_t output_config = {
        .drive         = NRF_GPIO_PIN_S0S1,
        .input_connect = NRF_GPIO_PIN_INPUT_DISCONNECT,
        .pull          = NRF_GPIO_PIN_PULLUP,
    };

    const nrfx_gpiote_task_config_t task_config = {
        .task_ch  = gpiote_channel,
        .polarity = NRF_GPIOTE_POLARITY_TOGGLE,  
        .init_val = NRF_GPIOTE_INITIAL_VALUE_LOW,
    };

    err = nrfx_gpiote_output_configure(&gpiote_inst,
										RADIO_GPIO_PIN,
                                       &output_config,
                                       &task_config);
	if (err != NRFX_SUCCESS) {
    	printk("nrfx_gpiote_output_configure , err:%d",err);
	}
    

    
    err = nrfx_gppi_channel_alloc(&ppi_set);
    if (err != NRFX_SUCCESS) {
    printk("nrfx_gppi_channel_alloc error: %08x", err);
    return;
	}
    err = nrfx_gppi_channel_alloc(&ppi_clr);
    if (err != NRFX_SUCCESS) {
    printk("nrfx_gppi_channel_alloc error: %08x", err);
    return;
	}

	nrfx_gppi_channel_endpoints_setup(ppi_set,
	nrf_radio_event_address_get(NRF_RADIO, NRF_RADIO_EVENT_READY),
	nrfx_gpiote_set_task_address_get(&gpiote_inst,RADIO_GPIO_PIN));

	nrfx_gppi_channel_endpoints_setup(ppi_clr,
	nrf_radio_event_address_get(NRF_RADIO, NRF_RADIO_EVENT_DISABLED),
	nrfx_gpiote_clr_task_address_get(&gpiote_inst,RADIO_GPIO_PIN));

    nrfx_gppi_channels_enable(BIT(ppi_set));
	nrfx_gppi_channels_enable(BIT(ppi_clr));
	nrfx_gpiote_out_task_enable(&gpiote_inst,RADIO_GPIO_PIN);
please help, it is a little urgent.
Thanks,
William.
Parents Reply Children
  • Thank you Hung Bui,

    I made some modifications based on this code, and now it works now, i want to use radio ready event and radio disabled event to set and clear gpio1.11(54L15).

    I haven't  tried myself but as far as I know MPSL provides pin debugging option that it toggles GPIOs based on  NRF_RADIO_EVENT_READY, NRF_RADIO_EVENT_DISABLED, NRF_RADIO_EVENT_ADDRESS, NRF_RADIO_EVENT_END.
    Could you take a look: https://github.com/nrfconnect/sdk-nrf/blob/v3.1.1/subsys/mpsl/pin_debug/mpsl_pin_debug_nrf54.c

    here is power profile with digital channel to sniffer the radio and gpio1.11, as below:

    here is the code:

    /*
     * Copyright (c) 2024 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    #include <zephyr/init.h>
    #include <zephyr/kernel.h>
    #include <zephyr/logging/log.h>
    #include <mpsl_dppi_protocol_api.h>
    #include <nrfx_gpiote.h>
    #include <helpers/nrfx_gppi.h>
    #include <nrfx_dppi.h>
    #include <hal/nrf_radio.h>
    #include <zephyr/device.h>
    #include <zephyr/drivers/gpio.h>
    
    #define CONFIG_MPSL_PIN_DEBUG_RADIO_READY_AND_DISABLED_PIN  NRF_GPIO_PIN_MAP(1, 11)   // P1.11
    const nrfx_gpiote_t gpiote = NRFX_GPIOTE_INSTANCE(20);
    const nrfx_dppi_t dppi_radio_domain = NRFX_DPPI_INSTANCE(10);
    const nrfx_dppi_t dppi_gpio_domain = NRFX_DPPI_INSTANCE(20);
    LOG_MODULE_REGISTER(radio_pin_debug, 4);
    
    /** @brief Fixed channel for NRF_RADIO->PUBLISH_READY. */
    #define MPSL_DPPI_RADIO_PUBLISH_READY_CHANNEL_IDX    4U
    
    /** @brief Fixed channel for NRF_RADIO->PUBLISH_ADDRESS. */
    #define MPSL_DPPI_RADIO_PUBLISH_ADDRESS_CHANNEL_IDX  5U
    
    /** @brief Fixed channel for NRF_RADIO->PUBLISH_END. */
    #define MPSL_DPPI_RADIO_PUBLISH_END_CHANNEL_IDX      6U
    
    /** @brief Fixed channel for NRF_RADIO->PUBLISH_DISABLED. */
    #define MPSL_DPPI_RADIO_PUBLISH_DISABLED_CH_IDX      7U
    
    static int m_ppi_config(void)
    {
    	uint8_t gppi_chan_radio_ready;
    	uint8_t gppi_chan_radio_disabled;
    
    
    	uint8_t dppi_chan_gpio_ready;
    	uint8_t dppi_chan_gpio_disabled;
    	
    
    	if (nrfx_gppi_channel_alloc(&gppi_chan_radio_ready) !=
    	    NRFX_SUCCESS) {
    		LOG_ERR("Failed allocating gppi_chan_radio_ready");
    		return -ENOMEM;
    	}
    
    	if (nrfx_gppi_channel_alloc(&gppi_chan_radio_disabled) !=
    	    NRFX_SUCCESS) {
    		LOG_ERR("Failed allocating gppi_chan_radio_disabled");
    		return -ENOMEM;
    	}
    
    
    	if (nrfx_dppi_channel_alloc(&dppi_gpio_domain, &dppi_chan_gpio_ready) !=
    	    NRFX_SUCCESS) {
    		LOG_ERR("Failed allocating dppi_chan_gpio_ready");
    		return -ENOMEM;
    	}
    
    	if (nrfx_dppi_channel_alloc(&dppi_gpio_domain, &dppi_chan_gpio_disabled) !=
    	    NRFX_SUCCESS) {
    		LOG_ERR("Failed allocating dppi_chan_gpio_disabled");
    		return -ENOMEM;
    	}
    
    
    	if (nrfx_gppi_edge_connection_setup(gppi_chan_radio_ready,
    					    &dppi_radio_domain,
    					    MPSL_DPPI_RADIO_PUBLISH_READY_CHANNEL_IDX,
    					    &dppi_gpio_domain,
    					    dppi_chan_gpio_ready) != NRFX_SUCCESS) {
    		LOG_ERR("Failed edge setup chan ready");
    		return -ENOMEM;
    	}
    
    	if (nrfx_gppi_edge_connection_setup(gppi_chan_radio_disabled,
    					    &dppi_radio_domain,
    					    MPSL_DPPI_RADIO_PUBLISH_DISABLED_CH_IDX,
    					    &dppi_gpio_domain,
    					    dppi_chan_gpio_disabled) != NRFX_SUCCESS) {
    		LOG_ERR("Failed edge setup chan disabled");
    		return -ENOMEM;
    	}
    
    
    	nrf_gpiote_subscribe_set(
    		gpiote.p_reg,
    		nrfx_gpiote_set_task_address_get(
    			&gpiote, CONFIG_MPSL_PIN_DEBUG_RADIO_READY_AND_DISABLED_PIN),
    		dppi_chan_gpio_ready);
    
    	nrf_gpiote_subscribe_set(
    		gpiote.p_reg,
    		nrfx_gpiote_clr_task_address_get(
    			&gpiote, CONFIG_MPSL_PIN_DEBUG_RADIO_READY_AND_DISABLED_PIN),
    		dppi_chan_gpio_disabled);
    
    
    	nrfx_gppi_channels_enable(NRFX_BIT(gppi_chan_radio_ready) |
    				  NRFX_BIT(gppi_chan_radio_disabled));
    				
    
    	if (nrfx_dppi_channel_enable(&dppi_gpio_domain, dppi_chan_gpio_ready) != NRFX_SUCCESS) {
    		LOG_ERR("Failed chan enable gpio_ready");
    		return -ENOMEM;
    	}
    
    	if (nrfx_dppi_channel_enable(&dppi_gpio_domain, dppi_chan_gpio_disabled) != NRFX_SUCCESS) {
    		LOG_ERR("Failed chan enable gpio_disabled");
    		return -ENOMEM;
    	}
    
    	return 0;
    }
    
    int radio_pin_debug_init(void)
    {
    	uint8_t radio_ready_radio_disabled_gpiote_channel;
    
    	const nrfx_gpiote_output_config_t gpiote_output_cfg = NRFX_GPIOTE_DEFAULT_OUTPUT_CONFIG;
    
    	if (nrfx_gpiote_channel_alloc(&gpiote, &radio_ready_radio_disabled_gpiote_channel) !=
    	    NRFX_SUCCESS) {
    		LOG_ERR("Failed allocating GPIOTE chan");
    		return -ENOMEM;
    	}
    
    
    	const nrfx_gpiote_task_config_t task_cfg_ready_disabled = {
    		.task_ch = radio_ready_radio_disabled_gpiote_channel,
    		.polarity = NRF_GPIOTE_POLARITY_TOGGLE,
    		.init_val = NRF_GPIOTE_INITIAL_VALUE_LOW,
    	};
    
    	if (nrfx_gpiote_output_configure(&gpiote,
    					 CONFIG_MPSL_PIN_DEBUG_RADIO_READY_AND_DISABLED_PIN,
    					 &gpiote_output_cfg,
    					 &task_cfg_ready_disabled)
    	    != NRFX_SUCCESS) {
    		LOG_ERR("Failed configuring GPIOTE chan");
    		return -ENOMEM;
    	}
    
    	if (m_ppi_config() != 0) {
    		return -ENOMEM;
    	}
    
    	nrfx_gpiote_out_task_enable(&gpiote, CONFIG_MPSL_PIN_DEBUG_RADIO_READY_AND_DISABLED_PIN);
    	return 0;
    }
    
    

    one question is, how could i know if the radio event is published already, i could not see radio event publish in this code.

    by the way please help to check if there is any problem in this code.

    the reason for this is because one of my project with 54L15+external wifi, some problems on the the antenna control,so after discussing with customer, we need to use BLE to control the 2,4g shared antenna, when 54L15 radio is working ,control the antenna to BLE, when radio is not working, antenna control switches to external wifi.

    i have another devzone ticket based on the same question:devzone.nordicsemi.com/.../54l15-pta-coex-with-external-wifi

    Regards,

    William.

  • Hi William, 
    Please clarify now you have NRF_RADIO_EVENT_READY  and NRF_RADIO_EVENT_DISABLED they can both toggle a GPIO when the events occur, correct ? 

    William.wei said:
    i could not see radio event publish in this code.

    Are you talking about having the radio interrupt handler in the code ? I don't think it's possible. The interrupt handler is inside softdevice controller stack. My understanding is that the interrupt handler is in MPSL initially and then will be forwarded to softdevice controller if it's BLE event. 

    Please let me know what exactly you need to do after you have the pin toggled. 

    What's the difference from this compare to the coexist library we already have with MPSL (CONFIG_MPSL_CX)? 
    https://docs.nordicsemi.com/bundle/ncs-3.1.1/page/nrf/app_dev/device_guides/wifi_coex.html

  • hi team,

    my purpose is using radio event to control the shared antenna. currently, this is only solution for customer right now.

    1. Yes, you are correct, need both event to toggle a pin, use this pin to control shared antenna.

    so basically, it is same as this:https://github.com/nrfconnect/sdk-nrf/blob/v3.1.1/subsys/mpsl/pin_debug/mpsl_pin_debug_nrf54.c

    but, only one pin for EVENT_READY and EVENT_DISABLED.

    Please clarify now you have NRF_RADIO_EVENT_READY  and NRF_RADIO_EVENT_DISABLED they can both toggle a GPIO when the events occur, correct ? 

    2. i don't need a interrupt handler, nothing to do, just toggle a pin, so using gppi and dppi, 

    Are you talking about having the radio interrupt handler in the code ? I don't think it's possible

    3.there is a problem when using coex pins, because external wifi could not grant the antenna correctly.

    when external wifi works with tx function, grant is noraml, but when external wifi works with rx function, grant is abnormal. so iam looking for a solution for it.

    Please clarify now you have NRF_RADIO_EVENT_READY  and NRF_RADIO_EVENT_DISABLED they can both toggle a GPIO when the events occur, correct ? 

    Regards,

    William.

  • Hi William, 

    I'm sorry that it taking long time to solve the issue. But you need to tell us more clear on what works and what not works and what you need. 
    You mentioned yesterday that "I made some modifications based on this code, and now it works now, "
    So could you declare what works and what doesn't work now ? From what you showed in the trace seems that the pin is toggled correctly when the radio enters RX and then after that TX ? 

Related