CMD_PROP_CS

The carrier sense command monitors the RF activity on a channel and decides, whether a channel is occupied (Busy) or available (Idle). It can be used to implement a CSMA scheme where a TX command only executes when nothing else occupies the channel. Channel detection is based upon two criteria: RSSI measurement and/or correlation (the presence of preamble).

Execution

The RF channel can be in several states:

Invalid

This is the default state at CS start.

Idle

No signal was found.

Busy

A signal was detected (RSSI above threshold or correlation succeeded (preamble detected).

../../_images/channel_states.png

Figure 79. Channel states and possible transitions.

*

-> INVALID

All possible transitions between these states are illustrated in Figure 79. Carrier sense always starts in INVALID state. Depending on the measured RSSI and/ or the presence of preamble, the channel goes either into IDLE or BUSY state. The operation ends or may continue depending on the configuration. In addition, a timeout may occur which ends the measurement process immediately. After that, a status code is written to the radio operation and an execution result is generated for the evaluation phase.

A detailed sequence description of the carrier sense execution phase is shown in Figure 80. In total, four procedures run in parallel:

watchRssi()

Optional. Constantly measures the signal strength(RSSI) value and updates the channel state.

watchCorr()

Optional. Correlates the RF signal with the expected preamble sequence and updates the channel state.

watchChannelState()

Watches and evaluates the channel state changes caused by watchRssi() or watchCorr().

waitForCsEndTrigger()
Optional. Waits for a timeout/end trigger (.csEndTrigger) and

evaluates the channel state when triggered.

 scale 0.8

 :Execution started;
 :channelState = INVALID;]
 split
     if (.csConf.bEnaRssi) then (1)
         :watchRssi();|
     else (0)
     endif
     end
 split again
     if (.csConf.bEnaCorr) then (1)
         :watchCorr();|
     else (0)
     endif
     end
 split again
     :watchChannelState();|
 split again
     :waitForCsEndTrigger();|
 end split
 :Execution Finished;

 legend right
     Command parameters:
     - .csConf.bEnaRssi
     - .csConf.bEnaCorr
 Endlegend

Figure 80. The execution phase of CMD_CS as a SDL diagram. Four procedures run in parallel.

 scale 0.8

 start
 :idleCount = 0;\nbusyCount = 0;\nrssiState = INVALID;]
 repeat
     :RSSI sample available<
     note right
         See section 'Timing' below.
     end note
     :RSSI = readRssi();]
     if (RSSI < .rssiThr) then (yes)
         :idleCount++;\nbusyCount = 0;]
         if (idleCount >= .numRssiIdle) then (yes)
             :rssiState = IDLE;]
             :updateChannelState(rssiState);|
             :RSSI state changed>
         endif
     else (no)
         :busyCount++;\nidleCount = 0;]
         if (busyCount >= .numRssiBusy) then (yes)
             :rssiState = BUSY;]
             :updateChannelState(rssiState);|
             :RSSI state changed>
         endif
     endif
 repeat while ()

 legend right
     Command parameters:
     - .numRssiBusy
     - .numRssiIdle
     - .rssiThr
 endlegend

Figure 81. The watchRssi() function from Figure 80.. For each change of rssiState, the resulting state is updated ccording to Table 17..

../../_images/cmd_cs_watchCorr.png

Figure 82. The watchCorr() function from Figure 80. as a state chart. For each state change, the correlation state is updated according to Table 17..

-> invalid

Both procedures, watchRssi() and watchCorr() result in an internal channel state that is one of INVALID, IDLE or BUSY. Depending on .bEnaRssi and .bEnaRssi one or both functions are active (not possible to set both to 0). If only one function is active, the resulting channel state is equal to the internal channel state. When both functions are active, the .csConf.operation flag specifies how the results from these functions are combined:

  • 0: The channel is BUSY if either watchRssi() OR watchCorr() indicate BUSY.

  • 1: The channel is BUSY if both watchRssi() AND watchCorr() indicate BUSY.

A complete mapping can be found in Table 17. The resulting channel state is then fed into watchChannelState() (Figure 83.) and waitForCsEndTrigger() (Figure 84.).

Table 17. Truth table that combines the output of watchRssi() and watchCorr() depending on .csConf.operation. The resulting channel state is used as input for watchChannelState() in Figure 83. and waitForCsEndTrigger() in Figure 84..

RSSI OR Correlation csConf.operation = 0

RSSI AND Correlation csConf.operation = 1

Correlation state

RSSI State

INVALID

IDLE

BUSY

INVALID

IDLE

BUSY

INVALID

INVALID

INVALID

BUSY

INVALID

IDLE

INVALID

IDLE

INVALID

IDLE

BUSY

IDLE

IDLE

IDLE

BUSY

BUSY

BUSY

BUSY

INVALID

IDLE

BUSY

 scale 0.8

 start
 :finished = false;]
 repeat
     :channelState changed<
     :channelState = lookup(rssiState, corrState);|
     note right
         See lookup table above
     endnote
     if (channelState) then (IDLE)
         if (.csConf.idleOp) then (1)
             :finished = true;\nresult = FALSE;\n.status = PROP_DONE_IDLE;]
         else (0)
         endif
     elseif (channelState) then (BUSY)
         if (.csConf.busyOp) then (1)
             :finished = true;\nresult = TRUE;\n.status = PROP_DONE_BUSY;]
         else (0)
         endif
     else (INVALID)
     endif
 repeat while (finished?) is (false)
 stop

 legend right
     Command parameters:
     - .csConf.busyOp
     - .csConf.idleOp
 endlegend

Figure 83. The watchChannelState() function from Figure 80..

 scale 0.8

 start
 :csEndTrigger fired<
 if (channelState) then (IDLE)
     :.status = PROP_DONE_IDLE;\nresult = FALSE;]
 elseif (channelState) then (BUSY)
     :.status = PROP_DONE_BUSY;\nresult = TRUE;]
 else (INVALID)
     if (.csConf.timeOutRes) then (1)
         :.status = PROP_DONE_IDLETIMEOUT;\nresult = FALSE;]
     else (0)
         :.status = PROP_DONE_BUSYTIMEOUT;\nresult = TRUE;]
     endif
 endif
 stop

 legend right
     Command parameters:
     - .csConf.timeOutRes
 endlegend

Figure 84. The waitForCsEndTrigger() function from Figure 80. in an SDL diagram.

Timing

The CMD_PROP_CS provides two timing values:

  • .csEndTime is the minimum execution time in RAT ticks, after which channel state evaluation is forced. Optional.

  • .corrPeriod specifies the number of RAT ticks between each correlation evaluation.

How to choose a minimum value for cmd.csEndTime so that at least either .numRssiIdle or .numRssiBusy RSSI samples are measured before a final decision is forced? The following drawing illustrates the CS command execution phase.

../../_images/aafig-98140fe36f89f0c5061f8be503573b94ffe734dc.png

After the obligatory parsing delay of approximatly 50 µs, command execution starts and the end trigger for .csEndTime is armed. After a fixed time Rssi_0, the first RSSI sample is available and the RSSI available signal in Figure 81. is fired for the first time. Successive RSSI samples occur with a period Rssi_n. The execution may either end up due to channel state evaluation in Figure 83. or a timeout of cmd.csEndTime, but has an additional evaluation delay of 5 µs.

Please note, that the RSSI sample period might be affected by the Automatic Gain Correction (AGC) and the AGC is always enabled in RX mode. In case of a very strong signal, the AGC might increase the first sample period Rssi_1 up to 4 times. If the signal strength is changing very fast, the AGC re-adjusts every RSSI sample period. However, in reality it is safe to assume that only the first period Rssi_1 is delayed by the AGC. The value Rssi_0 in contrast, is not affected, but the value might be wrong if the signal strength is above -50 dBm. For CSMA applications, this is expected to be uncritical.

A minimum value for cmd.csEndTime can be estimated with formula (10).

(10)csEndTime_{\text{min}}^{\text{rssi}} =
     \begin{cases}
         Rssi_0 + Rssi_n \cdot cmd.numRssiIdle + \SI{5}{\us} \\
         Rssi_0 + Rssi_n \cdot cmd.numRssiBusy + \SI{5}{\us}
     \end{cases}

Table 18. provides measurement results for Rssi_0 and Rssi_n. Both depend on the configured RX bandwidth (.rxBw), specified either in CMD_PROP_RADIO_SETUP or CMD_PROP_RADIO_DIV_SETUP.

Table 18. Timing watchRssi() and watchCorr()

RX bandwidth

Value for rxBw

First RSSI sample

RSSI sample period

[kHz]

CC13x0

CC26x0

Rssi_0 [µs]

Rssi_n [µs]

45/55/66

32/33/34

n/a

348

136

78/98/118

35/36/37

1/2/3

214

68

155/196/236

38/39/40

4/5/6

149

34

311/392/471

41/42/43

7/8/9

114

17

622/784/942

44/45/46

10/11/12

98

10

1243/1567/1884

47/48/49

13/14/15

89

10