This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

When BLE is Shared with 2.4g wireless via timeslot, the initial failure of esb occurs

Platform:NRF51822,  SDK12.1  S130

Phenomenon:By flipping the led light in the NRF_RADIO_CALLBACK_SIGNAL_TYPE_START event, it is known that the timeslot request is normal. The ESB initializer is executed in the NRF_RADIO_CALLBACK_SIGNAL_TYPE_START event, but when you execute the update_radio_parameters function of the nrf_esb_init() function, the program dies. 

BLE scan broadcast is used in the main program and the scan interval is 5S

I request your help   thank you!

#include <stdint.h>
#include <stdbool.h>
#include "nrf.h"
#include "app_error.h"
#include "nrf_gpio.h"
#include "softdevice_handler.h"
#include "boards.h"
#include "nrf_nvic.h"
#include "nrf_esb.h"
#include "my_esb.h"
#include "nrf_log.h"
#include "app_fifo.h"
#include "main.h"

#define TIMESLOT_BEGIN_IRQn        SWI3_IRQn
#define TIMESLOT_BEGIN_IRQHandler  SWI3_IRQHandler
#define TIMESLOT_BEGIN_IRQPriority 1
#define TIMESLOT_END_IRQn          SWI4_IRQn
#define TIMESLOT_END_IRQHandler    SWI4_IRQHandler
#define TIMESLOT_END_IRQPriority   1


/**Constants for timeslot API
*/
static nrf_radio_request_t m_timeslot_request;
static uint32_t m_slot_length = 10000;
static nrf_radio_signal_callback_return_param_t signal_callback_return_param;

/**@brief Request next timeslot event in earliest configuration
*/
uint32_t request_next_event_earliest(void)       //µÚÒ»´ÎÇëÇó±ØÐëΪearliestÀàÐÍ
{
	
		m_slot_length = 50000UL; //us               ³¤¶È·¶Î§ÏÞÖÆ100us~100ms 
		m_timeslot_request.request_type = NRF_RADIO_REQ_TYPE_EARLIEST;   //±ØÐëΪ´ËÀàÐÍ
		// ÕâÀïÐèÒªÉèÖÃtimeslot Æô¶¯ºó HFCLK ΪÍⲿ¾§Õñ,ÒòΪ RADIO Ôì×÷ÐèÒªÍⲿ¾§Õñ
		m_timeslot_request.params.earliest.hfclk = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
		
		m_timeslot_request.params.earliest.priority = NRF_RADIO_PRIORITY_NORMAL;
		m_timeslot_request.params.earliest.length_us = m_slot_length;
		m_timeslot_request.params.earliest.timeout_us = 1000000;
		return sd_radio_request(&m_timeslot_request);
	
}

/**@brief Configure next timeslot event in earliest configuration
*/
void configure_next_event_earliest(void)
{
		m_slot_length = 50000UL;
		m_timeslot_request.request_type = NRF_RADIO_REQ_TYPE_EARLIEST;
		m_timeslot_request.params.earliest.hfclk = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
		
		m_timeslot_request.params.earliest.priority = NRF_RADIO_PRIORITY_NORMAL;
		m_timeslot_request.params.earliest.length_us = m_slot_length;
		m_timeslot_request.params.earliest.timeout_us = 1000000;
}

void configure_next_event_normal(void)
{
    m_slot_length = 50000UL;
	  m_timeslot_request.request_type = NRF_RADIO_REQ_TYPE_NORMAL;
	  m_timeslot_request.params.normal.hfclk = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
	  m_timeslot_request.params.normal.priority = NRF_RADIO_PRIORITY_NORMAL;
	  m_timeslot_request.params.normal.distance_us = 500000;
	  m_timeslot_request.params.normal.length_us = m_slot_length ;

}





/**@brief Timeslot signal handler  »á»°Ïà¹ØµÄʼþ´¦Àí ¼´µ±timeslotÇëÇó·¢Æðºó»á½ÓÊÕµ½ÏµÍ³ÉÏÅ×ÉÏÀ´µÄһЩÏà¹Øʼþ
*/
void nrf_evt_signal_handler(uint32_t evt_id)
{
		uint32_t err_code;
		switch (evt_id)
		{
				case NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN:              //´ËʼþÉæ¼°µ½ÐźŴ¦Àíº¯Êý
		//		printf("NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN\r\n");       //yu ʹÓÃprintfº¯Êý³öÏÖ²»ºÏ·¨µÄ°ëÖ÷»úģʽ
//				     NRF_LOG_INFO("NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN\r\n");
				break;
				case NRF_EVT_RADIO_SESSION_IDLE:                                //»á»°´¦ÓÚ¿ÕÏУ¬¼´µ±Ç°Ã»ÓÐÇëÇóµÄtimeslotÐèÒª´¦Àí
		//		printf("NRF_EVT_RADIO_SESSION_IDLE\r\n");
				break;
				case NRF_EVT_RADIO_SESSION_CLOSED:                             //sd_radio_session_close()¹Ø±Õ»á»°Ê±»á²úÉú´Ëʼþ
		//		printf("NRF_EVT_RADIO_SESSION_CLOSED\r\n");
				break;
				case NRF_EVT_RADIO_BLOCKED:                                  //timeslotºÍЭÒéÕ»µÄÔËÐвúÉú³åÍ»
		//		printf("NRF_EVT_RADIO_BLOCKED\r\n");
				case NRF_EVT_RADIO_CANCELED:                                 //±¾´ÎÇëÇóÈ¡ÏûÖ®ºó
		//		printf("NRF_EVT_RADIO_CANCELED\r\n");
				err_code = request_next_event_earliest();                   //ÊÕµ½ÒÔÉÏ2¸öʼþºóÖØÐÂÖ´ÐÐÇëÇó²Ù×÷
				APP_ERROR_CHECK(err_code);
		//		printf("evt err:%d\r\n",err_code);
				break;
				default:
				break;
		}
}
extern void RADIO_IRQHandler(void);



/**@brief Timeslot event handler                               timeslotÏà¹ØµÄÐźŴ¦Àíº¯Êý

×¢Ò⣺´Ëº¯ÊýÄÚ²»Äܵ÷ÓÃSVC»úÖÆʵÏÖµÄsd_¿ªÍ·µÄЭÒéÕ»apiº¯Êý

*/

//int CLOCK_VALUE = 3;
nrf_radio_signal_callback_return_param_t * radio_callback(uint8_t signal_type)           //´Ëº¯ÊýÔÚsd_radio_session_open()ÖÐ×¢²á
{
	uint32_t err_code;
		switch(signal_type)
		{
				case NRF_RADIO_CALLBACK_SIGNAL_TYPE_START:                                       //±íʾÇëÇóµÄtimeslot¿ªÊ¼
		//				printf("NRF_RADIO_CALLBACK_SIGNAL_TYPE_START\r\n");
						 signal_callback_return_param.params.request.p_next = NULL;
						 signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;

             NRF_TIMER0->TASKS_STOP          = 1;
             NRF_TIMER0->TASKS_CLEAR         = 1;
             NRF_TIMER0->MODE                = (TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos);	
				     NRF_TIMER0->EVENTS_COMPARE[0]   = 0;
						 NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Msk;
						
						 NRF_TIMER0->CC[0] = m_slot_length - 500;                                    // ¶¨Ê±Æ÷ÔÚtimeslot ½áÊøÇ° 500us µ½ÆÚ
						 NRF_TIMER0->CC[1] 				= (m_slot_length - 2000);
				     NRF_TIMER0->BITMODE             = (TIMER_BITMODE_BITMODE_24Bit << TIMER_BITMODE_BITMODE_Pos);
				     NRF_TIMER0->TASKS_START         = 1;
						 NRF_RADIO->POWER = (RADIO_POWER_POWER_Enabled << RADIO_POWER_POWER_Pos);    // ÕâÀïÉèÖÃһϠRADIO µÄ power,·ñÔòradio ·¢Êý¾ÝÓÐÎÊÌâ
						
						 NVIC_EnableIRQ(TIMER0_IRQn);

					   NVIC_ClearPendingIRQ(TIMESLOT_BEGIN_IRQn);
             NVIC_SetPriority(TIMESLOT_BEGIN_IRQn, 1);
             NVIC_EnableIRQ(TIMESLOT_BEGIN_IRQn);				
				     NVIC_SetPendingIRQ(TIMESLOT_BEGIN_IRQn);
						 
//						 nrf_gpio_pin_toggle(24);

//             esb_init();
//						 esb_test_tx();
				break;
				
				case NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO:
						
						 signal_callback_return_param.params.request.p_next = NULL;
						 signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
				     RADIO_IRQHandler();                                                         // radio µÄÖжϴ¦Àíº¯ÊýÐèÒªÔÚÕâÀïÖ÷¶¯µ÷ÓÃ
						 
				break;
				
				case NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0:
		//				printf("NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0\r\n");
				     if(NRF_TIMER0->EVENTS_COMPARE[0] && (NRF_TIMER0->INTENSET & (TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENCLR_COMPARE0_Pos)))
						 { 
								 NRF_TIMER0->TASKS_STOP                    = 1;
								 NRF_TIMER0->TASKS_CLEAR                   = 1;
								 NRF_TIMER0->EVENTS_COMPARE[0]             = 0;			

								 if(!nrf_esb_is_idle())
								 {  
										 NRF_RADIO->INTENCLR = 0xFFFFFFFF;
										 NRF_RADIO->TASKS_DISABLE = 1;
								 }							 
								 configure_next_event_normal();
//						     ble_stack_start();
//								 err_code= nrf_esb_disable();
//                 APP_ERROR_CHECK(err_code);
								 signal_callback_return_param.params.request.p_next = &m_timeslot_request;   //ÇëÇóÏÂÒ»¸ötimeslot
								 signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END;  //NRF_RADIO_SIGNAL_CALLBACK_ACTION_END
				

				
						 
						//ÕâÀï¿É×öһЩÊÕβ¹¤×÷
//						 NRF_RADIO->POWER = (RADIO_POWER_POWER_Disabled << RADIO_POWER_POWER_Pos);
						 }

				break;
				// ÏÂÃæ2¸öÐźţ¬±¾¹¤³ÌÔÝδÓÃ
				case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED:    //±íʾtimeslotÑÓ³¤ÇëÇó³É¹¦
//					   NVIC_SetPendingIRQ(TIMESLOT_BEGIN_IRQn);
             NRF_TIMER0->TASKS_STOP          = 1;
             NRF_TIMER0->EVENTS_COMPARE[0]   = 0;				
				     NRF_TIMER0->CC[0]               += (5000UL - 25);
				     NRF_TIMER0->TASKS_START         = 1;
				     NVIC_SetPendingIRQ(TIMESLOT_BEGIN_IRQn);
				
				     
				case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED:
					
					   NVIC_SetPendingIRQ(TIMESLOT_END_IRQn);
					   signal_callback_return_param.params.request.p_next = NULL;
					   signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
					
				break;
				default:
				//No implementation needed
				break;
		}
		return (&signal_callback_return_param);
}

uint32_t timeslot_sd_init(void)
{
		uint32_t err_code;
		err_code = sd_radio_session_open(radio_callback);   //  ÇëÇótimeslotÇ°£¬Æô¶¯Ò»¶Î»á»°
		if (err_code != NRF_SUCCESS)
		{
			  return err_code;
		}
		
		err_code = request_next_event_earliest();  //ÇëÇóµÚ1´Îtimeslot
		
		if(err_code != NRF_SUCCESS)
		{
			  (void)sd_radio_session_close();
		    return err_code;		
		}
		
//		nrf_gpio_cfg_output(16);
		return NRF_SUCCESS;
		
}

/**@brief IRQHandler used for execution context management. 
  *        Any available handler can be used as we're not using the associated hardware.
  *        This handler is used to stop and disable UESB
  */
void TIMESLOT_END_IRQHandler(void) 
{
    uint32_t err_code;

		err_code= nrf_esb_flush_tx();
		APP_ERROR_CHECK(err_code);
		err_code= nrf_esb_flush_rx();
		APP_ERROR_CHECK(err_code);
    err_code= nrf_esb_disable();
    APP_ERROR_CHECK(err_code);

}

/**@brief IRQHandler used for execution context management. 
  *        Any available handler can be used as we're not using the associated hardware.
  *        This handler is used to initiate UESB RX/TX
  */
int flag = 0;
void TIMESLOT_BEGIN_IRQHandler(void) 
{
    uint32_t err_code;

   
	  err_code = esb_init();

		flag++;
	  esb_test_tx();


}

  

  • #include <stdbool.h>
    #include <stdint.h>
    #include <string.h>
    #include <stdio.h>
    #include "sdk_common.h"
    #include "nrf.h"
    #include "nrf_esb.h"
    #include "nrf_error.h"
    #include "nrf_esb_error_codes.h"
    #include "nrf_delay.h"
    #include "app_util.h"

    static nrf_esb_payload_t tx_payload = NRF_ESB_CREATE_PAYLOAD(0,0x01,0x02,3,4,5,6);

    static nrf_esb_payload_t rx_payload;
    static uint8_t tx_flag;


    static void nrf_esb_event_handler(nrf_esb_evt_t const * p_event)
    {
    switch (p_event->evt_id)
    {
    case NRF_ESB_EVENT_TX_SUCCESS:
    // printf("TX SUCCESS EVENT\r\n");
    break;

    case NRF_ESB_EVENT_TX_FAILED:
    // printf("TX FAILED EVENT\r\n");
    (void) nrf_esb_flush_tx();
    (void) nrf_esb_start_tx();
    break;

    case NRF_ESB_EVENT_RX_RECEIVED:
    // printf("RX RECEIVED EVENT\r\n");
    while (nrf_esb_read_rx_payload(&rx_payload) == NRF_SUCCESS)
    {
    if (rx_payload.length > 0)
    {
    // printf("RX RECEIVED PAYLOAD\r\n");
    for( uint8_t i = 0; i < rx_payload.length; i++ )
    {
    // printf("%02x ",rx_payload.data[i]);
    }
    // printf("\r\n");
    }
    }
    break;
    }
    }


    uint32_t esb_init( void )
    {
    uint32_t err_code;
    uint8_t base_addr_0[4] = {0xE7, 0xE7, 0xE7, 0xE7};
    uint8_t base_addr_1[4] = {0xC2, 0xC2, 0xC2, 0xC2};
    uint8_t addr_prefix[8] = {0xE7, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8 };


    nrf_esb_config_t nrf_esb_config = NRF_ESB_DEFAULT_CONFIG;

    memcpy(&nrf_esb_config, &nrf_esb_config, sizeof(nrf_esb_config_t));
    nrf_esb_config.retransmit_count = 6;
    nrf_esb_config.selective_auto_ack = false;
    nrf_esb_config.protocol = NRF_ESB_PROTOCOL_ESB_DPL;
    nrf_esb_config.bitrate = NRF_ESB_BITRATE_2MBPS;
    nrf_esb_config.event_handler = nrf_esb_event_handler;
    nrf_esb_config.mode = NRF_ESB_MODE_PTX;

    nrf_esb_config.radio_irq_priority = 0;

    err_code = nrf_esb_init(&nrf_esb_config);
    VERIFY_SUCCESS(err_code);

    err_code = nrf_esb_set_base_address_0(base_addr_0);
    VERIFY_SUCCESS(err_code);

    err_code = nrf_esb_set_base_address_1(base_addr_1);
    VERIFY_SUCCESS(err_code);

    err_code = nrf_esb_set_prefixes(addr_prefix, 8);
    VERIFY_SUCCESS(err_code);

    tx_payload.length = 3;
    tx_payload.pipe = 0;
    tx_payload.data[0] = 0x00;

    return NRF_SUCCESS;

    }

    void esb_test_tx( void ) 
    {
    tx_payload.noack = false;
    if (nrf_esb_write_payload(&tx_payload) == NRF_SUCCESS)
    {
    // printf("PTX send data\r\n");
    }
    tx_flag = 0;
    }

    void set_tx_flag(void)
    {
    tx_flag = 1;
    }
    uint8_t is_need_tx(void)
    {
    return tx_flag;
    }

  • Hi Yuxu, 

    Did you base your code on any our our example ? 

    Did the code work for you before ? Which modification caused the application stopped working ? 

    Could you tell what exactly happen when "the program dies" ? 

Related