Start and end triggers

All radio operations provide a start trigger. It brings the command from PENDING state into ACTIVE state and starts the actual command execution.

Table 2. Available trigger types. The identifiers can be found in <ti/devices/${DEVICE_FAMILY}/driverlib/rf_mailbox.h>. Identifiers marked with a (*) are only available for chained commands.
Number Identifier Trigger fires
0 TRIG_NOW Immediately. Available for start triggers only. This is the default value.
1 TRIG_NEVER Never, except possibly by CMD_TRIGGER if bEnaCmd == 1. Default value for end triggers.
2 TRIG_ABSTIME At an absolute time, specified by startTime.
3 TRIG_REL_SUBMIT At a time relative to the command submission time.
4 TRIG_REL_START At a time relative to the start of the command (when the start trigger fires). Available for end triggers only.
5 TRIG_REL_PREVSTART* At a time relative to the start of the previous command. Applies only to chained commands.
6 TRIG_REL_FIRSTSTART* At a time relative to the start of the first command in a chain.
7 TRIG_REL_PREVEND* At a time relative to the end of the previous command in a chain.
8 TRIG_REL_EVT1* At a time relative to event 1 of the previous command in a chain.
9 TRIG_REL_EVT2* At a time relative to event 2 of the previous command in a chain.
10 TRIG_EXTERNAL On an external trigger input.

The start trigger configuration is defined by the following command members:

struct RF_Op {
    // ...
    ratmr_t startTime;                  // Absolute or relative start time (depending on triggerType)
    struct {
        uint8_t triggerType:4;          // The type of trigger
        uint8_t bEnaCmd:1;              // 1: CMD_TRIGGER can be used as an alternative trigger
                                        // 0: No alternative trigger command
        uint8_t triggerNo:2;            // Specifies the trigger number when using CMD_TRIGGER (bEnaCmd is 1)
                                        // Valid values are 0..3.
        uint8_t pastTrig:1;             // 1: A trigger event in the past is interpreted as "fire now"
                                        // 0: A trigger event in the past results in an error
    } startTrigger;                     // Trigger that starts the radio operation command
    // ...
};

End triggers are only available for operations that run for a longer time and wait for something to happen. CMD_PROP_RX is such a command. The configuration of end triggers is very similar to start triggers:

struct RF_Op {
    // ...
    ratmr_t endTime;                    // Absolute or relative end time (depending on triggerType)
    struct {
        uint8_t triggerType:4;          // The type of trigger
        uint8_t bEnaCmd:1;              // 1: CMD_TRIGGER can be used as an alternative trigger
                                        // 0: No alternative trigger command
        uint8_t triggerNo:2;            // Specifies the trigger number when using CMD_TRIGGER (bEnaCmd is 1)
                                        // Valid values are 0..3.
        uint8_t pastTrig:1;             // 1: A trigger event in the past is interpreted as "fire now"
                                        // 0: A trigger event in the past results in an error
    } endTrigger;                       // Trigger that ends the radio operation command
    // ...
};

Absolute triggers TRIG_ABSTIME

TRIG_ABSTIME fires at an absolute time stamp specified by the startTime parameter. Absolute triggers are needed, for instance, when implementing synchronous protocols where multiple commands must execute relative to one common time base. This avoids glitches that one would observe when using TRIG_NOW and timers on the main CPU.

Usually, RF_getCurrentTime() is used to get the initial time and all other times are set relative to that one. In the following code snippet, a radio operation executes exactly every second:

#define RF_convertMsToRatTicks(milliseconds) \
    ((uint32_t)(milliseconds) * 4 * 1000)

command.startTrigger.triggerType = TRIG_ABSTIME;
command.startTime = RF_getCurrentTime();

for (;;) {
    command.startTime += RF_convertMsToRatTicks(1000);
    RF_runCmd(rfHandle, (RF_Op*)&command, RF_PriorityNormal, NULL, 0);
}

If startTime is not a future time stamp, then the trigger will never fire. In such cases, command.startTrigger.pastTrig must be set to 1.

Please note, that the RF driver powers the RF core down while waiting for an absolute start trigger. This trick is described in the RF driver API documentation.

Relative triggers TRIG_REL_*

Relative triggers specify a time duration with respect to another event, for instance relative to the start of a radio operation. Table 2. lists all available trigger types.

The duration is always specified in RAT ticks. The following code snippet sets a relative end trigger for CMD_PROP_CS. A helper macro simplifies conversion.:

// Convert microseconds into RAT ticks.
#define RF_convertUsToRatTicks(microseconds) \
    ((uint32_t)(microseconds) * 4)

// Convert milliseconds into RAT ticks.
#define RF_convertMsToRatTicks(milliseconds) \
    RF_convertUsToRatTicks((milliseconds) * 1000)

// Set a relative end trigger 4ms after execution start.
RF_cmdPropCs.csEndTrigger.triggerType = TRIG_REL_START;
RF_cmdPropCs.csEndTime = RF_converMsToRatTicks(4);

External triggers TRIG_EXTERNAL

TRIG_EXTERNAL is used to start and stop a radio operation by an external hardware event. The event source is one of the internal RF core signals RFC_GPI0 or RFC_GPI1. These signals can be routed to a physical pin using the IO controller. Possible event types are either a rising edge, a falling edge or both. Both, event source and type are encoded in the startTime parameter of the radio operation.

The following code snippet shows how to start a command by a falling edge on the GPIO pin IOID_25:

// Define a struct for convenience.
typedef struct
{
    uint32_t reserved:2;  // unused
    uint32_t inputMode:2; // 0: rising, 1: falling, 2: both edges
    uint32_t reserved2:4; // unused
    uint32_t source:5;    // 22: RFC_GPI0, 23: RFC_GPI1
} ExternalTrigger;

// Set the trigger configuration
ExternalTrigger triggerConfig =
{
    .inputMode = 1,       // falling edge
    .source = 22          // Use RFC_GPI0
};

command.startTrigger.triggerType = TRIG_EXTERNAL;
command.startTime = *((uint32_t*)&triggerConfig);

// Route a physical pin to the internal RFC_GPI0 signal.
PINCC26XX_setMux(buttonPinHandle, IOID_25, PINCC26XX_MUX_RFC_GPI0);

See the section Routing RF core signals to physical pins for more details on signal rounting.

Alternative triggers via CMD_TRIGGER

Sometimes it is desirable to trigger a radio operation based on a software event. This can be achieved using the immediate command CMD_TRIGGER. Each radio operation trigger provides the fields bEnaCmd and triggerNo to do that. This trigger serves as an alternative trigger source. The original trigger specified by triggerType is not affected. This means, that both, timeout triggers and CMD_TRIGGER can be used at the same time.

The following code snippet shows how to set up a custom end trigger for a infinitely running radio operation:

// Set up the radio operation
radioOp.endTrigger.type = TRIG_NEVER; // Run the command without a timeout
                                      // trigger.
radioOp.endTrigger.bEnaCmd = 1;       // Enable CMD_TRIGGER as an end trigger.
radioOp.endTrigger.triggerNo = 2;     // Chose a value between 0 and 3.

// Set up the immediate trigger command
rfc_CMD_TRIGGER triggerCmd = {
    .commandNo = CMD_TRIGGER,
    .triggerNo = 2;                   // Chose the same value as for the
                                      // radio operation command trigger
                                      // above.
};

// Start the long-running radio operation
RF_CmdHandle radioOpHandle = RF_postCmd(rfHandle, (RF_Op*)&radioOp, RF_PriorityNormal, NULL, 0);

// Do some work ...

// Finish execution of the radio operation by the trigger command
RF_runImmediateCmd(rfHandle, (uint32_t*)&triggerCmd);

Another use case is the combination of alternative triggers with command chaining. Let us assume that an application wants to achieve a fast transition from CMD_PROP_RX to CMD_PROP_TX, but the exact time when this should happen is unknown in advance. In this case, chaining CMD_PROP_RX with CMD_PROP_TX and using CMD_TRIGGER to end the RX command is faster than aborthing the RX command before posting the TX command.