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

Trigger radio signal in multiprotocol.

We are implementing a protocol using the softdevice s140 multiprotocol API. The protocol is always listening, but occasionally transmitting.

To manage this setup, we request timeslots of a configurable interval (for example 30ms), and have set TIMER0 to wake up after a shorter time (for example 25ms) to trigger a signal and request an extend to continue listen, for example from now+30ms.

This works quite fine, and we can manage to always listen, and from time to time be interrupted for BLE traffic.

The question is about TX, or more specifically how to interrupt the RX.f

When the application want to transmit a packet, we don't want the system to wait for the TIMER0 interrupt to be able to handle the transmission from the radio signals, but rather get another signal immediately, that have the possibility to send back actions like extend. But more importantly on the same interrupt level to make it easier to manage concurrency to the memory.

So the question:

Is it possible to from thread level/application trigger a signal in the time slot in the multiprotocol api?

I was thinking if it would be possible to use NVIC_SetPendingIRQ(RADIO_IRQn); but is not sure if that would be supported or have side effects, for example if it would happen outside of a time slot

Parents
  • Hi Max, 


    We actually having an example here for SDK v17.0.2 that does almost what you wanted to do. It run at the same time with BLE and most of the time it will just stay in RX mode. When there is a packet needed to be sent it switch the radio to TX. The proprieatary protocol used here is ESB. I'm not sure why you need to trigger a radio IRQ in this case, when you have packet to send just stop RX and switch the radio to TX to send. 

    Please have a look at the example here.
    The blog post that cover the example can be found here.

    Note that we don't use a timer (30ms in your case) to request timeslot, we instead request timeslot only once, and keep extending it using TIMER0. If it can't be extended we will request the earliest and continue. If the request is blocked, we try again inside the event handler. 

  • Hi,

    Thanks for the reply. Have not seen that example, so thanks.

    For what I can tell however, it looks like it uses time slots/extension periods that are either PTX (transmission) or PRX (reception), and if the slot is PTX or PRX is determined at the start of the slot, so a PRX can't be interrupted in the middle by adding a packet in the TX queue. (Looking at TIMESLOT_BEGIN_IRQHandler)

    To get low latency and more control over when to transmit, that means the extension period needs to be low. To have 1ms of latency, there need to be wakeups every 1ms.

    For our use, using polling with a timer continously reading the tx queue would mean that interrupt have to wake up a couple of times every ms to reduce the latency, which is not really a good practice.

    Using that example as reference, would it be possilble from thread level/application to interrupt a PRX interval half way through to switch to PTX directly, and not have to wait for the next scheduled timer?

  • Hi Max, 


    Actually, you are right that in our implementation we don't interrupt the the PRX period when we have a packet to send. Instead we queue the TX packet in the fifo as in function esb_timeslot_send_str().

    When the timeslot being extended, in our example every 5ms we will check the FIFO and send the packets if there is anything in the FIFO. It's correct that if you would need to wait for the next extending event (NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED) to send the packets, you can reduce the latency by reducing the extension length. But I don't see much problem waking the CPU up every 1ms for example, because the current draw by the RADIO when staying in RX mode is significantly higher than the short period when the CPU has to wake up. (Note that it's not we have to wait for the next timeslot , we only have to wait for the next extending success event)


    If you don't want to wait for the next extended timeslot event to execute the queue, I don't see any problem if you just call  NVIC_SetPendingIRQ(TIMESLOT_BEGIN_IRQn); right when you want to send a packet. Calling that will trigger the handler TIMESLOT_BEGIN_IRQHandler which stops the RX period and put the RADIO to PTX mode immediately. 

  • Hi,

    I agree that it wouldn't be a problem with 1ms sequence. But in our case, we actually trying to mix multiple protocols together, of different timing requirements. So we would probably have to go down to 100us cycles or less to have the latency as we need, which would need in many cases.

    Waking up the TIMESLOT_BEGIN_IRQHandler makes it possible to update the radio state, but it doesn't give access to the radio signalling, to be able to extend or take any other action on the timeslot itself. But except from that, it's exactly what I want do achieve.

    So the question is, is it possible to wake up the softdevice to trigger a timeslot signal, which also gives access to return an action?

  • Hi Max, 
    Please elaborate a little bit more on " but it doesn't give access to the radio signalling, to be able to extend or take any other action on the timeslot itself." ? 


    You have full control of the RADIO as long as you are still staying in the timeslot. You don't need to ask the softdevice to trigger any timeslot signal. 

  • Hi,

    Looking at the SoftDevice Specificataion for s140, there is a section Radio Timeslot Signals (in PDF version v2.1, numbered 9.2.7.3), For example signal NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO and NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0

    infocenter.nordicsemi.com/.../tsl_signals.html

    Those signals area to be received like interrupts on highest priority by the application, and works much like interrupts. But the difference are that they return an action.

    The signal handler is specified with the sd_radio_session_open():

    https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.s140.api.v7.2.0%2Fgroup___n_r_f___s_o_c___f_u_n_c_t_i_o_n_s.html&anchor=ga55a52eb4d0491cb7105de6a13eb2b11b

    The signals referred to is handled by the callback of type nrf_signal_callback_t, and is able to return an action defined by the type nrf_radio_signal_callback_return_parameter_t.

    One scenario would be that if we have a slot requested for 5 more milliseconds, and still are listening, to be able to transmit we might need to do CCA, transmit, and then wait for an acknowledgement. If we don't have time for that, it's not worth starting the transmission. So in our case, the interrupt needs to be able to first try to extend, and if successful, transmit.

    Thus, just triggering another IRQ won't give access to slot extend (or other return actions) to update the slot. So just access the radio would not be enough, since then we might break the requirement that all radio operations must be finished before the slot ends.

  • Hi again Max, 


    So it's more about extending a timeslot dynamically ? If that's the case, it's pretty easy. Currently we trigger a extending request by setting a TIMER0 interrupt. In our case it's NRF_TIMER0->EVENTS_COMPARE[1] event. When this even is triggered the softdevice will signal NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0 and you can return your request to extend there. 

    I haven't tried by I think you can just trigger the TIMER0 interrupt by calling NVIC_SetPendingIRQ(TIMER0_IRQn). If that's not allowed by the softdevice you  can just setup a CC[] register to trigger a EVENT_COMPARE. You have mutliple CC registers to trigger different COMPARE events. You can use a TASK_CAPTURE to get the current timer counter and can trigger an event right away. 

Reply
  • Hi again Max, 


    So it's more about extending a timeslot dynamically ? If that's the case, it's pretty easy. Currently we trigger a extending request by setting a TIMER0 interrupt. In our case it's NRF_TIMER0->EVENTS_COMPARE[1] event. When this even is triggered the softdevice will signal NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0 and you can return your request to extend there. 

    I haven't tried by I think you can just trigger the TIMER0 interrupt by calling NVIC_SetPendingIRQ(TIMER0_IRQn). If that's not allowed by the softdevice you  can just setup a CC[] register to trigger a EVENT_COMPARE. You have mutliple CC registers to trigger different COMPARE events. You can use a TASK_CAPTURE to get the current timer counter and can trigger an event right away. 

Children
No Data
Related