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();
}