MPSL_TIMESLOT_SIGNAL_RADIO doesn't hit

I'm using nRF Connect SDK v2.0.2 (in VSCode, w/ the plugin) on nRF52840-DKs.

Following the MPSL Timeslot sample, in the code shown below, I created a non-preemptible thread that periodically requests a single timeslot. 

In the mpsl_timeslot_callback(), the MPSL_TIMESLOT_SIGNAL_START and MPSL_TIMESLOT_SIGNAL_TIMER0 events occur as expected, but the MPSL_TIMESLOT_SIGNAL_RADIO case never happens. Why not? How can I make that happen?

#define TIMESLOT_REQUEST_PERIOD_ms  (250)

// ...

/* Timeslot requests */
static mpsl_timeslot_request_t timeslot_request_earliest =
{
	.request_type             = MPSL_TIMESLOT_REQ_TYPE_EARLIEST,
	.params.earliest.hfclk    = MPSL_TIMESLOT_HFCLK_CFG_NO_GUARANTEE, //TODO: OK?
	.params.earliest.priority = MPSL_TIMESLOT_PRIORITY_HIGH,
	.params.earliest.length_us  = TIMESLOT_LENGTH_US,
	.params.earliest.timeout_us = TIMESLOT_TIMEOUT_US,
};

static mpsl_timeslot_signal_return_param_t signal_callback_return_param;


// ...


static mpsl_timeslot_signal_return_param_t *mpsl_timeslot_callback(
	mpsl_timeslot_session_id_t session_id,
	uint32_t signal_type)
{
	(void) session_id; /* unused parameter */

	mpsl_timeslot_signal_return_param_t *p_ret_val = NULL;

	switch (signal_type)
	{
		case MPSL_TIMESLOT_SIGNAL_RADIO:
		{
			//NB: this doesn't hit...
			break;
		}

		case MPSL_TIMESLOT_SIGNAL_START:
		{
			// this hits

			/* No return action */
			signal_callback_return_param.callback_action =
				MPSL_TIMESLOT_SIGNAL_ACTION_NONE;
			p_ret_val = &signal_callback_return_param;

			/* Setup timer to trigger an interrupt (and thus the TIMER0
			* signal) before timeslot end.
			*/
			nrf_timer_cc_set(NRF_TIMER0, NRF_TIMER_CC_CHANNEL0,
				TIMER_EXPIRY_US);
			nrf_timer_int_enable(NRF_TIMER0, NRF_TIMER_INT_COMPARE0_MASK);
			break;
		}

		case MPSL_TIMESLOT_SIGNAL_TIMER0:
		{
			// this hits

			/* Clear event */
			nrf_timer_int_disable(NRF_TIMER0, NRF_TIMER_INT_COMPARE0_MASK);
			nrf_timer_event_clear(NRF_TIMER0, NRF_TIMER_EVENT_COMPARE0);

			/* Timeslot will be ended */
			signal_callback_return_param.callback_action =
				MPSL_TIMESLOT_SIGNAL_ACTION_NONE;
				//MPSL_TIMESLOT_SIGNAL_ACTION_END;

			p_ret_val = &signal_callback_return_param;
			break;
		}

		case MPSL_TIMESLOT_SIGNAL_SESSION_IDLE:
			break;
		case MPSL_TIMESLOT_SIGNAL_SESSION_CLOSED:
			break;

		// case MPSL_TIMESLOT_SIGNAL_BLOCKED:
		// case SIGNAL_CODE_BLOCKED_CANCELLED:
		default:
		{
			printk("ERR: unexpected signal: %u\n", signal_type);
			k_oops();
			break;
		}
	}

	return p_ret_val;
}


/* To ensure thread safe operation, call all MPSL APIs from a non-preemptible
 * thread.
 */
static void mpsl_nonpreemptible_thread(void)
{
	// Open timeslot session, and make periodic timeslot request
	//  (every TIMESLOT_REQUEST_PERIOD_ms)

	int err;

	/* Initialize to invalid session id */
	mpsl_timeslot_session_id_t session_id = 0xFFu;

	err = mpsl_timeslot_session_open(mpsl_timeslot_callback, &session_id);

	if (err) {
		printk("ERR: Timeslot session open error: %d\n", err);
		k_oops();
	}
	else
	{
		while (1)
		{
			osDelay(TIMESLOT_REQUEST_PERIOD_ms);

			err = mpsl_timeslot_request(session_id, &timeslot_request_earliest);

			if (err)
			{
				printk("ERR: Timeslot request error: %d\n", err);
				k_oops();
			}
		}
	}
}


K_THREAD_DEFINE(mpsl_nonpreemptible_thread_id, STACKSIZE,
		mpsl_nonpreemptible_thread, NULL, NULL, NULL,
		K_PRIO_COOP(MPSL_THREAD_PRIO), 0, 0);


void main(void)
{
    // do some BLE stuff...
}

Things I tried, which made no difference:

1. I've tried adding

	nrf_radio_int_enable(NRF_RADIO,
		(NRF_RADIO_INT_CCABUSY_MASK |
		 NRF_RADIO_INT_CCAIDLE_MASK));

in main(), (and I used nrf_radio_int_enable_check() to ensure it set the bits).

2. I also tried using mpsl_radio_notification_cfg_set() such as shown below.

// Following comments from
//  https://github.com/inductivekickback/ncs_ble_esb_demo
// which I used as a sample. Unsure if it still applies.
/**
 * An interrupt vector to use with the Radio Notification feature as well as lowering the
 * priority of the MPSL callback (Zero Latency IRQ workaround). As of NCS v1.6 this doesn't
 * handle MPSL_TIMESLOT_SIGNAL_TIMER0 signals correctly unless it uses priority MPSL_LOW_PRIO
 * or higher.
 */
#define RADIO_IRQN          QDEC_IRQn
#define RADIO_IRQ_NODELABEL qdec
//#define RADIO_IRQN          RADIO_IRQn
//#define RADIO_IRQ_NODELABEL radio
#define RADIO_IRQ_PRIO      4

static void radio_notify_cb(const void *context);

static void setup_radio_notification(void)
{
	IRQ_CONNECT(DT_IRQN(DT_NODELABEL(RADIO_IRQ_NODELABEL)), RADIO_IRQ_PRIO,
		radio_notify_cb, NULL, 0);
	irq_enable(DT_IRQN(DT_NODELABEL(RADIO_IRQ_NODELABEL)));

	int32_t err = mpsl_radio_notification_cfg_set(MPSL_RADIO_NOTIFICATION_TYPE_INT_ON_ACTIVE,
		MPSL_RADIO_NOTIFICATION_DISTANCE_200US,
		RADIO_IRQN);

	if (err)
	{
		printk("ERR: mpsl_radio_notification_cfg_set() returned %i\n", err);
	}
}

static void radio_notify_cb(const void *context)
{
	// this doesn't hit either
}

Parents Reply Children
No Data
Related