mpsl_init: MPSL ASSERT: 112, 2223 - NCS v2.5.2

Hi,

I am trying to port the DTM example to our board, 52833 based but when DTM is initialised I get about 1400ms of CW then:

00> *** Booting nRF Connect SDK v2.5.2 ***
00> [00:00:00.170,837] <err> mpsl_init: MPSL ASSERT: 112, 2223
00> [00:00:00.170,837] <err> os: ***** HARD FAULT *****
00> [00:00:00.170,867] <err> os: Fault escalation (see below)
00> [00:00:00.170,867] <err> os: ARCH_EXCEPT with reason 3
00>
00> [00:00:00.170,898] <err> os: r0/a1: 0x00000003 r1/a2: 0x00000000 r2/a3: 0x00000000
00> [00:00:00.170,898] <err> os: r3/a4: 0x00000000 r12/ip: 0x200039f0 r14/lr: 0x00033f93
00> [00:00:00.170,928] <err> os: xpsr: 0x41000011
00> [00:00:00.170,928] <err> os: Faulting instruction address (r15/pc): 0x00033fa0
00> [00:00:00.170,959] <err> os: >>> ZEPHYR FATAL ERROR 3: Kernel oops on CPU 0
00> [00:00:00.170,989] <err> os: Fault during interrupt handling
00>
00> [00:00:00.171,020] <err> os: Current thread: 0x200039f0 (unknown)
00> [00:00:00.680,297] <err> fatal_error: Resetting system

It's worth noting that the BLE stack is still compiled in, though in this example I'm not calling bt_enable(). That said I'm hoping I might be able to have it start in BLE until a characteristic write happens then stop BLE and switch to DTM.

Anyway hoping someone can shed some light on the ASSERT.

Thanks!

  • Hi,

    The assert is raised because the RADIO interrupt was triggered outside of a timeslot allocated by the MPSL. The solution may be to request a long continuous timeslot after entering DTM mode.

    Best regards,

    Vidar 

  • Thanks very much Vidar.

    I'm guessing something is still configured during Zephyr startup even though I haven't actually started using the radio other than via the DTM code? It's just I don't see anything in the sample about timeslots.

    The solution may be to request a long continuous timeslot

    I'm not sure I understand what that means. I tried adding:

    static mpsl_timeslot_request_t timeslot_request_earliest = {
            .request_type = MPSL_TIMESLOT_REQ_TYPE_EARLIEST,
            .params.earliest.hfclk = MPSL_TIMESLOT_HFCLK_CFG_NO_GUARANTEE,
            .params.earliest.priority = MPSL_TIMESLOT_PRIORITY_NORMAL,
            .params.earliest.length_us = 100000,
            .params.earliest.timeout_us = 100000000
    };
    static mpsl_timeslot_signal_return_param_t signal_callback_return_param = {
        .callback_action=MPSL_TIMESLOT_SIGNAL_ACTION_EXTEND,
        .params.extend.length_us=100000
    };
    static mpsl_timeslot_signal_return_param_t *mpsl_timeslot_callback(
            mpsl_timeslot_session_id_t session_id,
            uint32_t signal_type)
    {
        //LOG_INF("callback %d", signal_type);
        return &signal_callback_return_param;
    }
    
    
    ...
        dtm_init(&dtm_iq_report_callback);
        int err = mpsl_timeslot_session_open(mpsl_timeslot_callback, &session_id);
        if (err) {
                LOG_ERR("Timeslot session open error: %d", err);
        }
        err = mpsl_timeslot_request(session_id, &timeslot_request_earliest);
        if (err) {
                LOG_ERR("Timeslot request error: %d", err);
        }
    ...
    
        dtm_test_transmit(5, 1, DTM_PACKET_VENDOR);


    But depending on the ordering - before or after dtm_test_transmit() - I either get the CPU on continuously (based on power) but no Tx or no difference (Tx for 1.5 sec with the same crash)
    Since you mentioned interrupts I also tried irq_disable(RADIO_IRQn) after both dtm_init() and dtm_test_transmit() but that made no difference either.
    Thanks!
  • Hi Vidar,

     I also tried irq_disable(RADIO_IRQn) after both dtm_init() and dtm_test_transmit() but that made no difference either.

    Actually I made a mistake and put the 2nd irq_disable in the wrong place.

    This DOES work, and if I do this at the top of main() with a k_sleep() after it I get a solid CW and then it'll even continue on to starting BLE, which works for me since I can then use DFU to put the real firmware back after we're done.

    So maybe that'd be enough, but still it'd be better for me if I could use the BLE trigger since I'd like to use the char write to pick the frequency. That still doesn't work - I still get the same MPSL ASSERT. Note that in this case the char write handler is setting a flag that causes the main thread to do:

    bt_disable();
    irq_disable(RADIO_IRQn);
    k_sleep(K_MSEC(500));
    NVIC_ClearPendingIRQ(RADIO_IRQn);
    dtm_init(&dtm_iq_report_callback);
    irq_disable(RADIO_IRQn);

    Any ideas? I thought maybe there's an interrupt pending so that the crash is happening as soon dtm_init() enables the interrupt, but haven't got much evidence to back that up. 

    Thanks!

  • Hi,

    Glad to hear you've made progress on this. We currently do not have any samples demonstrating how to combine DTM and BLE in a single firmware image.

    BillB said:
    So maybe that'd be enough, but still it'd be better for me if I could use the BLE trigger since I'd like to use the char write to pick the frequency. That still doesn't work - I still get the same MPSL ASSERT. Note that in this case the char write handler is setting a flag that causes the main thread to do:

    Please check if the return value from bt_disable() is zero and not a negative error code. As an alternative (a 'hack'), you could use one of the retention registers (GPREGRET – 1 byte each) to store the DTM configuration or mode you want to use, and then call sys_reboot() (equivalent to NVIC_SystemReset) so you can enter DTM on subsuequent boot before enabling the BLE stack.

Related