Low Duty Cycle (LDC, sometimes just Duty Cycle) by definition means switching something periodically on and off. However, in the context of low power radios, we usually use it for receive mode only: In this case, the radio is switching between a low power, long duration sleep state and short active states, wherein the radio is in receive state looking for valid preamble. In this way the radio is able to save huge amount of power.
Furthermore this operation is automatic, means no MCU intervention is needed for scheduling receive intervals, saving more energy. Typically an interrupt line or events are used to indicate a valid packet's arrival.
Synchronous and asynchronous duty cycling
Duty cycling radio protocols can be sorted into asynchronous or synchronous protocols. Asynchronous means that the receiver don't know when the transmitter would send a packet, while in synchronous mode, as its name implies, there is temporal synchronization between the two connected parts, the messages will be sent at a specified time.
Some widely used protocols use LDC (e.g. Bluetooth low energy) in synchronized networks. By spending energy and time for synchronization, the receiver can receive all the packets while it is in sleep state most of the time.
However, in some cases, the overhead required by the synchronization doesn't worth it, e.g. if you need to receive messages from a transmitter that rarely sends anything. In such cases, you probably want to use asynchronous duty cycling on the receiver, but in such cases the transmitter cannot predict when the receiver is listening. The goal of this KBA is to solve this problem, and explain how asynchronous LDC works.
In this KBA the theoretical configuration of LDC will be presented illustrated with application examples (general use cases), and at last some implementation notes will be showed for both EZRadioPRO and EFR32 devices.
Theory of LDC
The main idea behind the LDC is to move the power consumption of RX to the TX side. Though in LDC mode the both side are strongly dependent to each other focus on the RX side first and assume an optimal transmitter.
RX side considerations - Preamble detection period
To minimize the receiver's side average power consumption, the time spent in active state should be minimized. What's the minimum time to keep the receiver on? When and how could the receiver detect an incoming message? What is this event? There are more options for the receiver to detect an incoming message, but we concentrate only to the preamble detection case.
In preamble detection duty cycle mode the radio periodically wakes up for short duration to look for a preamble. When a valid preamble is detected, the radio remains in receive state until the packet is fully received (or an error detected during reception).
Note that the original goal of the preamble is to achieve bit synchronization of the incoming signal (or to restore the clock signal in other words). Therefore, the preamble should be always at least as long as it needs to be to reliably achieve this task. Most radio's datasheets (Si4460/1/3/4 p. 28.) recommends selecting preamble length and preamble detection threshold (aka. preamble detection period), which is a minimal value to achieve 0% PER.
Define the following receiver time terms:
Tpdp: preamble detection period,
Tron: receiver's active state time (it will be longer, than the preamble detection period due to packet reception),
Tsleep: receiver's sleep state time,
and ignore other timing constraints, like wake-up time, radio state transition time, etc.
From this point assume optimal RX, and focus on the TX side.
TX side consideration - application examples - LDC in asynchronous networks
There is tradeoff between the RX side's and the TX side's power consumption: longer sleep period infer longer transmission time (see the examples section).
There is two widely used scenario to ensure package reception on the receiver side in asynchronous networks, one called as "Duty-cycle" mode, and the other is the "Master-slave" or "Master blast" mode.
Duty-cycle mode
This mode requires a packet with a very long preamble at the transmitter side. For the simplest example assume the active time (Tron) and the sleep period (Tsleep) are given. In this case the transmitter should have at least
Tpream = 2 * Tron + Tsleep
long preamble to make sure all packets will be received, independent of the receiver state when the transmission started. The rest of the packet is transmitted in Trest time.
In the worst case scenario, the transmitter starts transmitting slightly after the receiver wakes up, and does not provide long enough preamble for detection (Tpdp) in this wake-on period, continues the transmission during the receiver is in sleep state (Tsleep), and for the next active period (Tpdp+Trest), where the receiver finally detects and receives the packet. This is shown in the picture below.
Worst case scenario - Duty-cycle mode
Compared to the case when the receiver is always in receive state, Duty-cycle mode saves approximately the duty-cycle proportion of power on the receiver side.
(Unsynchronized) Master-slave mode
The master term refers to the transmitter and the slave term to the receiver(s).
This mode has a very similar idea, but instead of one packet with long preamble it uses transmit burst with short packets back to back, which transmit time, Tburst, should fit to Tpream determined in the Duty-cycle mode (the preamble length is much shorter in this mode but it has to fit to Tpdp time at least, and we will call it Tpream). Usually the rest of the packet (syncword, header, payload, CRC, etc.) is for Trest time in the air.
Worst case scenario - Master-slave mode
The slave must be in active state at least 2 * Tpream + Trest = Tron long, which is higher than in the Duty-cycle mode for ensuring packet reception for every case.
Comparison of applications
The downside of Duty-cycle mode is comes up when the radio wakes on the beginning of the preamble. This implies a long active period due to the waiting for the whole packet. On the other hand, with Master-slave mode the receiver only needs to be active for as long as it receives a single, short packet. The downside of Master-slave mode is that the receiver must be in active state as long as the longest possible packet is, otherwise it could miss the preamble of the packet.
Therefore the selection of application strongly depends on the protocol, or rather we should say that the used protocol should define the LDC application mode.
Possible improvements in Master-slave mode
With Master-slave mode, it is possible to improve the performance and energy consumption. For example, the transmitter could check for an ACK after each transmit. If the transmission was acknowledged, the transmitter can stop. The drawback with this is that this only works with a single receiver, and the active period of the receiver should be extended to include the time the transmitter spends to wait for an ACK.
Another method to improve Master-slave mode is to use a specific "wake-up" message, and not the actual data. This wake-up message only tells the receiver when the actual data will be transmitted and the receiver can wake-up again for that. This worsens the power consumption on both receiver and transmitter side, but the data length doesn't affect the active time on the slave any more.
Note about preamble detection selection
Low detection threshold may led to misdetection and sensitivity loss, but halting the receiver longer in active state increase energy consumption.
Therefore the threshold should be good enough to achieve the required packet error rate. Note that the data rate may also impact on the threshold selection.
Implementation on EZRadioPRO
EZRadioPro devices have a low frequency (32 KHz) clock system, called as WUT (Wake-Up Timer). It can be operated from an external or an internal clock source (see in the API documentation (GLOBAL_CLK_CFG register, CLK_32_SEL bit fields). The radio uses this clock during sleep state for generating wake-up signal (the WUT activity distinguishes between sleep and standby states), thereby WUT supports LDC mode (and Low Battery Detection as well) by hardware.
Registers with GLOBAL_WUT prefix related to this timer. Both the sleep period and the active period (documentation calls it LDC period) should be set with a mantissa (WUT_M and WUT_LDC bitfields) and a common exponent (WUT_R bitfields). The active period may be less than configured LDC period, when a packet arrived before its expiration (as shown in the second picture). We signed LDC period as Tron and sleep period as Tsleep.
Next to the periods the preamble detection threshold should be configured. It determines the number of valid preamble bits the radio must receive to qualify a valid preamble. A shorter Preamble Detection Threshold may be chosen if occasional false detections can be tolerated. This threshold can be set through the PREAMBLE_CONFIG_STD_1 register's RX_THRESHOLD bitfields, and all the other preamble related setting is located in the 0x10 Group of the registers.
After issuing a START_RX command the radio's high frequency crystal should be started up, and the PLL requires some calibration time (see AN585 p.1.). This should be take into consideration to set the periods correctly (this start-up time should be subtracted from the sleep period).
Further documentation:
LDC EZRadioPRO can be found in the AN585, which describes Master-slave mode more in depth.
EFR32 devices have LDC (although this feature called as Duty Cycle mode) implemented as part of Channel Hopping feature. The theory is similar to that, which was described for EZRadioPRO devices, but here is a more simplest implementation, only two relevant APIs should to know:
RAIL_ConfigRxDutyCycle(): configures the mode and timing for the Duty Cycle operation.
RAIL_EnableRxDutyCycle(): enables radio's receiver (RAIL_StartRX() or RAIL_ScheduleRx() API should be called after this).
RAIL_EVENT_RX_DUTY_CYCLE_RX_END: event triggered after a complete active-sleep period, where RAIL_StartRX() or RAIL_ScheduleRx() should be called again.
Note that the APIs do not put the MCU itself into sleep state. However, RAIL_Sleep() will allow deep sleep while the radio is not active. To enable RAIL timers in EM2 sleep, timer synchronization must be also enabled. For more details, see tutorial on timer synchronization and sleep.
Notes:
The RAIL_ConfigRxDutyCycle() and the RAIL_EnableRxDutyCycle() APIs are not supported on the EFR32XG1 family of chips, and in multiprotocol applications.
The RAIL_ConfigRxDutyCycle() and the RAIL_EnableRxDutyCycle() APIs must not be called while the radio is on.
There is a Duty Cycle example in the Flex SDK, but it does not use the APIs above.
There are cases when the communication between devices can happen on multiple channels and the actual channel is not known prior the communication. In these cases, the receiver usually tries to find the transmitter's channel by listening on all possible channels for a short time to catch the transmitter's signal - in most of the cases it searches for valid preamble.
In RAIL it is possible to manually set the required channel, listen and wait for valid preamble then depending on the received signal continues to receive the whole packet or reconfigure the receiver to the next channel and repeat this procedure until receiving a valid packet.
However, manually configuring the receiver to all channels and starting the receiving then checking for valid packet makes the code needlessly difficult and additionally it is inefficient.
RAIL provides a hardware accelerated method to achieve the channel scanning in a very simple and efficient way. This method is called RX channel hopping.
Note: This feature is not supported on the EFR32XG1 family of chips and currently not supported in multiprotocol.
Configuring and enabling RX channel hopping
There are two API function to support channel hopping:
RAIL_ConfigRxChannelHopping()
RAIL_EnableRxChannelHopping()
Configuring channel hopping
As its name suggests RAIL_ConfigRxChannelHopping() is responsible to configure the hardware to the required operation mode. Beside a RAIL handle, it takes one input which is a RAIL_RxChannelHoppingConfig_t structure. It contains a buffer for channel hopping information, number of channels which is in channel hopping sequence and most importantly the entries of channels (RAIL_RxChannelHoppingConfigEntry_t) contains the parameters of the specified channels.
The channel hopping information buffer (must be allocated by the application) and size can be defined as follows:
The individual channel parameters must be defined in the channel hopping entries, each entry contains parameters for one channel. The channel hopping will happened in the order of entry elements, so the channel order can be arbitrary - it is even possible to add a channel multiple times in the sequence however in this case multiple entry is necessary for that channel.
The parameters of a channel must be placed into RAIL_RxChannelHoppingConfigEntry_t structures. Although these parameters can be different for each entries, for simplicity reasons this example uses same parameters for all channels.
The entry structure has a .parameter member and the meaning of this member depends on the .mode setting - in the current case it means microseconds and determines how long the hardware will listen on the current channel before hops to the next one. This value depends on the PHY settings may need to finetune experimentally. For different settings see the RAIL API documentation.
The second parameter enables channel hopping while the third one specify whether hopping should be reset to start from the channel at index zero, or continue from the channel last hopped to.
Note: The radio should not be on when this API is called.
Starting receiving
If the radio is configured as shown above, there is only one step remaining, to start the reception.
It can be done by calling
RAIL_StartRx(railHandle, 0, NULL);
The radio will continuously remain in RX mode and run the hopping sequence until a packet received. If a packet is received the radio returns to idle state.
This behavior can be modified by setting auto state transition (see RAIL API documentation for details about auto state transition feature).
Channel hopping complete event
Sometimes it is advantageous to know when the hopping sequence finished. RAIL provide an event for this purpose: RAIL_EVENT_RX_CHANNEL_HOPPING_COMPLETE if this event is enabled, the RAILCb_Generic() will be fired every time the hopping sequence completed.
Receiving this event does not mean that channel hopping is stopped, it only signals that one round of the sequence is finished and it will be continued with the next round.
The TX side
To successfully receive a packet by the receiver side it is necessary to choose a preamble length on the transmitter side which long enough for the receiver to complete at least one whole sequence. So, if the receiver needs 10ms to complete on sequence of scanning the transmitter's preamble length must be at least 10ms. As the preamble in the Radio Configurator is specified in symbols (bits) it is the customers responsibility to convert the preamble length from time to symbols.
Proprietary Knowledge Base
Low duty cycle mode
Content
Introduction and motivation
Low Duty Cycle (LDC, sometimes just Duty Cycle) by definition means switching something periodically on and off. However, in the context of low power radios, we usually use it for receive mode only: In this case, the radio is switching between a low power, long duration sleep state and short active states, wherein the radio is in receive state looking for valid preamble. In this way the radio is able to save huge amount of power.
Furthermore this operation is automatic, means no MCU intervention is needed for scheduling receive intervals, saving more energy. Typically an interrupt line or events are used to indicate a valid packet's arrival.
Synchronous and asynchronous duty cycling
Duty cycling radio protocols can be sorted into asynchronous or synchronous protocols. Asynchronous means that the receiver don't know when the transmitter would send a packet, while in synchronous mode, as its name implies, there is temporal synchronization between the two connected parts, the messages will be sent at a specified time.
Some widely used protocols use LDC (e.g. Bluetooth low energy) in synchronized networks. By spending energy and time for synchronization, the receiver can receive all the packets while it is in sleep state most of the time.
However, in some cases, the overhead required by the synchronization doesn't worth it, e.g. if you need to receive messages from a transmitter that rarely sends anything. In such cases, you probably want to use asynchronous duty cycling on the receiver, but in such cases the transmitter cannot predict when the receiver is listening. The goal of this KBA is to solve this problem, and explain how asynchronous LDC works.
In this KBA the theoretical configuration of LDC will be presented illustrated with application examples (general use cases), and at last some implementation notes will be showed for both EZRadioPRO and EFR32 devices.
Theory of LDC
The main idea behind the LDC is to move the power consumption of RX to the TX side. Though in LDC mode the both side are strongly dependent to each other focus on the RX side first and assume an optimal transmitter.
RX side considerations - Preamble detection period
To minimize the receiver's side average power consumption, the time spent in active state should be minimized. What's the minimum time to keep the receiver on? When and how could the receiver detect an incoming message? What is this event? There are more options for the receiver to detect an incoming message, but we concentrate only to the preamble detection case.
In preamble detection duty cycle mode the radio periodically wakes up for short duration to look for a preamble. When a valid preamble is detected, the radio remains in receive state until the packet is fully received (or an error detected during reception).
Note that the original goal of the preamble is to achieve bit synchronization of the incoming signal (or to restore the clock signal in other words). Therefore, the preamble should be always at least as long as it needs to be to reliably achieve this task. Most radio's datasheets (Si4460/1/3/4 p. 28.) recommends selecting preamble length and preamble detection threshold (aka. preamble detection period), which is a minimal value to achieve 0% PER.
Define the following receiver time terms:
and ignore other timing constraints, like wake-up time, radio state transition time, etc.
From this point assume optimal RX, and focus on the TX side.
TX side consideration - application examples - LDC in asynchronous networks
There is tradeoff between the RX side's and the TX side's power consumption: longer sleep period infer longer transmission time (see the examples section).
There is two widely used scenario to ensure package reception on the receiver side in asynchronous networks, one called as "Duty-cycle" mode, and the other is the "Master-slave" or "Master blast" mode.
Duty-cycle mode
This mode requires a packet with a very long preamble at the transmitter side. For the simplest example assume the active time (Tron) and the sleep period (Tsleep) are given. In this case the transmitter should have at least
Tpream = 2 * Tron + Tsleep
long preamble to make sure all packets will be received, independent of the receiver state when the transmission started. The rest of the packet is transmitted in Trest time.
In the worst case scenario, the transmitter starts transmitting slightly after the receiver wakes up, and does not provide long enough preamble for detection (Tpdp) in this wake-on period, continues the transmission during the receiver is in sleep state (Tsleep), and for the next active period (Tpdp+Trest), where the receiver finally detects and receives the packet. This is shown in the picture below.
Compared to the case when the receiver is always in receive state, Duty-cycle mode saves approximately the duty-cycle proportion of power on the receiver side.
(Unsynchronized) Master-slave mode
The master term refers to the transmitter and the slave term to the receiver(s).
This mode has a very similar idea, but instead of one packet with long preamble it uses transmit burst with short packets back to back, which transmit time, Tburst, should fit to Tpream determined in the Duty-cycle mode (the preamble length is much shorter in this mode but it has to fit to Tpdp time at least, and we will call it Tpream). Usually the rest of the packet (syncword, header, payload, CRC, etc.) is for Trest time in the air.
The slave must be in active state at least 2 * Tpream + Trest = Tron long, which is higher than in the Duty-cycle mode for ensuring packet reception for every case.
Comparison of applications
The downside of Duty-cycle mode is comes up when the radio wakes on the beginning of the preamble. This implies a long active period due to the waiting for the whole packet. On the other hand, with Master-slave mode the receiver only needs to be active for as long as it receives a single, short packet. The downside of Master-slave mode is that the receiver must be in active state as long as the longest possible packet is, otherwise it could miss the preamble of the packet.
Therefore the selection of application strongly depends on the protocol, or rather we should say that the used protocol should define the LDC application mode.
Possible improvements in Master-slave mode
With Master-slave mode, it is possible to improve the performance and energy consumption. For example, the transmitter could check for an ACK after each transmit. If the transmission was acknowledged, the transmitter can stop. The drawback with this is that this only works with a single receiver, and the active period of the receiver should be extended to include the time the transmitter spends to wait for an ACK.
Another method to improve Master-slave mode is to use a specific "wake-up" message, and not the actual data. This wake-up message only tells the receiver when the actual data will be transmitted and the receiver can wake-up again for that. This worsens the power consumption on both receiver and transmitter side, but the data length doesn't affect the active time on the slave any more.
Note about preamble detection selection
Low detection threshold may led to misdetection and sensitivity loss, but halting the receiver longer in active state increase energy consumption.
Therefore the threshold should be good enough to achieve the required packet error rate. Note that the data rate may also impact on the threshold selection.
Implementation on EZRadioPRO
EZRadioPro devices have a low frequency (32 KHz) clock system, called as WUT (Wake-Up Timer). It can be operated from an external or an internal clock source (see in the API documentation (GLOBAL_CLK_CFG register, CLK_32_SEL bit fields). The radio uses this clock during sleep state for generating wake-up signal (the WUT activity distinguishes between sleep and standby states), thereby WUT supports LDC mode (and Low Battery Detection as well) by hardware.
Registers with GLOBAL_WUT prefix related to this timer. Both the sleep period and the active period (documentation calls it LDC period) should be set with a mantissa (WUT_M and WUT_LDC bitfields) and a common exponent (WUT_R bitfields). The active period may be less than configured LDC period, when a packet arrived before its expiration (as shown in the second picture). We signed LDC period as Tron and sleep period as Tsleep.
Next to the periods the preamble detection threshold should be configured. It determines the number of valid preamble bits the radio must receive to qualify a valid preamble. A shorter Preamble Detection Threshold may be chosen if occasional false detections can be tolerated. This threshold can be set through the PREAMBLE_CONFIG_STD_1 register's RX_THRESHOLD bitfields, and all the other preamble related setting is located in the 0x10 Group of the registers.
After issuing a START_RX command the radio's high frequency crystal should be started up, and the PLL requires some calibration time (see AN585 p.1.). This should be take into consideration to set the periods correctly (this start-up time should be subtracted from the sleep period).
Further documentation:
Implementation on EFR32
EFR32 devices have LDC (although this feature called as Duty Cycle mode) implemented as part of Channel Hopping feature. The theory is similar to that, which was described for EZRadioPRO devices, but here is a more simplest implementation, only two relevant APIs should to know:
RAIL_ConfigRxDutyCycle()
: configures the mode and timing for the Duty Cycle operation.RAIL_EnableRxDutyCycle()
: enables radio's receiver (RAIL_StartRX()
orRAIL_ScheduleRx()
API should be called after this).RAIL_EVENT_RX_DUTY_CYCLE_RX_END
: event triggered after a complete active-sleep period, whereRAIL_StartRX()
orRAIL_ScheduleRx()
should be called again.For a complete documentation visit the API documentation.
Note that the APIs do not put the MCU itself into sleep state. However,
RAIL_Sleep()
will allow deep sleep while the radio is not active. To enable RAIL timers in EM2 sleep, timer synchronization must be also enabled. For more details, see tutorial on timer synchronization and sleep.Notes:
RAIL_ConfigRxDutyCycle()
and theRAIL_EnableRxDutyCycle()
APIs are not supported on the EFR32XG1 family of chips, and in multiprotocol applications.RAIL_ConfigRxDutyCycle()
and theRAIL_EnableRxDutyCycle()
APIs must not be called while the radio is on.RAIL RX channel hopping (channel scanning)
Introduction
There are cases when the communication between devices can happen on multiple channels and the actual channel is not known prior the communication. In these cases, the receiver usually tries to find the transmitter's channel by listening on all possible channels for a short time to catch the transmitter's signal - in most of the cases it searches for valid preamble.
In RAIL it is possible to manually set the required channel, listen and wait for valid preamble then depending on the received signal continues to receive the whole packet or reconfigure the receiver to the next channel and repeat this procedure until receiving a valid packet.
However, manually configuring the receiver to all channels and starting the receiving then checking for valid packet makes the code needlessly difficult and additionally it is inefficient.
RAIL provides a hardware accelerated method to achieve the channel scanning in a very simple and efficient way. This method is called RX channel hopping.
Note: This feature is not supported on the EFR32XG1 family of chips and currently not supported in multiprotocol.
Configuring and enabling RX channel hopping
There are two API function to support channel hopping:
Configuring channel hopping
As its name suggests
RAIL_ConfigRxChannelHopping()
is responsible to configure the hardware to the required operation mode. Beside a RAIL handle, it takes one input which is aRAIL_RxChannelHoppingConfig_t
structure. It contains a buffer for channel hopping information, number of channels which is in channel hopping sequence and most importantly the entries of channels (RAIL_RxChannelHoppingConfigEntry_t
) contains the parameters of the specified channels.The channel hopping information buffer (must be allocated by the application) and size can be defined as follows:
The channel hopping configuration must be prepared as well
The individual channel parameters must be defined in the channel hopping entries, each entry contains parameters for one channel. The channel hopping will happened in the order of entry elements, so the channel order can be arbitrary - it is even possible to add a channel multiple times in the sequence however in this case multiple entry is necessary for that channel.
The parameters of a channel must be placed into
RAIL_RxChannelHoppingConfigEntry_t
structures. Although these parameters can be different for each entries, for simplicity reasons this example uses same parameters for all channels.The entry structure has a
.parameter
member and the meaning of this member depends on the.mode
setting - in the current case it means microseconds and determines how long the hardware will listen on the current channel before hops to the next one. This value depends on the PHY settings may need to finetune experimentally. For different settings see the RAIL API documentation.If the configuration is complete simply call
Enabling channel hopping
To enable RX channel hopping call
The second parameter enables channel hopping while the third one specify whether hopping should be reset to start from the channel at index zero, or continue from the channel last hopped to.
Note: The radio should not be on when this API is called.
Starting receiving
If the radio is configured as shown above, there is only one step remaining, to start the reception.
It can be done by calling
The radio will continuously remain in RX mode and run the hopping sequence until a packet received. If a packet is received the radio returns to idle state.
This behavior can be modified by setting auto state transition (see RAIL API documentation for details about auto state transition feature).
Channel hopping complete event
Sometimes it is advantageous to know when the hopping sequence finished. RAIL provide an event for this purpose:
RAIL_EVENT_RX_CHANNEL_HOPPING_COMPLETE
if this event is enabled, theRAILCb_Generic()
will be fired every time the hopping sequence completed.Receiving this event does not mean that channel hopping is stopped, it only signals that one round of the sequence is finished and it will be continued with the next round.
The TX side
To successfully receive a packet by the receiver side it is necessary to choose a preamble length on the transmitter side which long enough for the receiver to complete at least one whole sequence. So, if the receiver needs 10ms to complete on sequence of scanning the transmitter's preamble length must be at least 10ms. As the preamble in the Radio Configurator is specified in symbols (bits) it is the customers responsibility to convert the preamble length from time to symbols.