Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

Switching from BLE mode to nRF/generic 2.4GHz mode not working properly?

I am using nRF5 SDK v15.0.0 and an nRF52840 with the S140 SoftDevice (6.0.0). I have an application that works using a custom protocol with the nRF radio. Recently I added BLE functionality and switching to it works flawlessly, but when I attempt to disable the SoftDevice and switch back to the original wireless protocol, the radio doesn't work anymore. Specifically, the RADIO_IRQHandler is never called. Below I included most of the functions I use. Basically I start by enabling the radio, confirming it receives data, then I enable and disable BLE mode (which should re-enable the radio without the BLE stack).

void nrf_mode_init(void)
{
    NRF_RADIO->FREQUENCY = 0;
    NRF_RADIO->TXPOWER = (RADIO_TXPOWER_TXPOWER_Pos8dBm << RADIO_TXPOWER_TXPOWER_Pos);
    // I have a custom function here, setting PCNF0, PCNF1, CRCCNF, CRCINIT, CRCPOLY, MODE, INTENSET, and SHORTS
}

void nrf_mode_reset(void)
{
    NVIC_DisableIRQ(RADIO_IRQn);
    NRF_RADIO->EVENTS_DISABLED = 0U;
	NRF_RADIO->TASKS_DISABLE = 1;
    NRF_RADIO->EVENTS_END = 0U;
	NRF_RADIO->TXPOWER = (RADIO_TXPOWER_TXPOWER_Pos8dBm << RADIO_TXPOWER_TXPOWER_Pos);
}

void nrf_mode_enable_rx(void)
{
	NRF_RADIO->PACKETPTR = (uint32_t) &rx_packet;
	NVIC_ClearPendingIRQ(RADIO_IRQn);
	NVIC_EnableIRQ(RADIO_IRQn);
	NRF_RADIO->TASKS_RXEN = 1;
}

void ble_mode_init(void)
{
    nrf_mode_reset();
    ble_stack_init();
    gap_params_init();
    gatt_init();
    services_init();
    advertising_init();
    conn_params_init();
    advertising_start();
}

void ble_mode_disable(void)
{
    uint32_t err_code = nrf_sdh_disable_request();
    while(nrf_sdh_is_enabled()); // placeholder, confirmed SD is disabled in primary code before enabling nrf mode
    nrf_mode_init();
    nrf_mode_reset();
    nrf_mode_enable_rx();
}

Is there anything else I should be doing to fully disable the SoftDevice and to allow the RF mode to work properly?

Parents Reply Children
  • I can see that now, but I can't see anywhere you are starting the HFCLK?

    Kenneth

  • One more thing, in addition to starting the HFCLK, let the first step after disabling the softdevice be to power cycle the radio peripheral using the POWER register:
    https://infocenter.nordicsemi.com/topic/ps_nrf52840/radio.html#register.POWER

    Kenneth

  • Thank you for your response Kenneth. I managed to fix the problem, which was a combination of internal library initializations that needed to be called again, and notably this clock init function:

    static void clock_initialization()
    {
    	/* Start 16 MHz crystal oscillator */
    	NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    	NRF_CLOCK->TASKS_HFCLKSTART = 1;
    
    	/* Wait for the external oscillator to start up */
    	while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
    	{
    		// Do nothing.
    	}
    
    	// Old CLOCK_LFCLKSRC_SRC_Xtal -> Start long ? Rev C ?
    	/* Start low frequency crystal oscillator for app_timer(used by bsp)*/
    	NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos);
    	NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
    	NRF_CLOCK->TASKS_LFCLKSTART = 1;
    
    	while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
    	{
    		// Do nothing.
    	}
    }
    

    I assume this solved the problem by restarting the HFCLK as you mentioned, and because of your response I was able to track this function down. I'm sorry for continually asking questions related to the deprecated nRF5 SDK, but I seriously appreciate all the help these forums and the Nordic dev team have provided, and we plan to switch to NCS + Zephyr for future products.

Related