Introduction
In Bluetooth® Low Energy (BLE), periodic advertising (without responses) refers to a feature in which an advertiser can broadcast data at regular intervals without expecting or allowing a response from receiving devices. This advertising method relies on the use of extended advertising PDUs, and is particularly useful for applications requiring consistent data transmission over time, such as broadcasting sensor data, location beacons, or public information in a power-efficient manner. By not waiting for acknowledgments or replies, periodic advertising minimizes power consumption and reduces the complexity of maintaining a connection.
Periodic Advertising with Responses (PAwR) was introduced in Bluetooth Core Specification 5.4 to enable bi-directional communication between an advertiser and multiple scanners within a structured time frame. Unlike standard periodic advertising, PAwR allows devices to send responses within pre-defined response slots, enabling efficient communication while maintaining low power consumption.
A key feature of PAwR is that AUX_CONNECT_REQ PDUs are allowed, meaning that advertisers can act as initiators and trigger a transition from periodic advertising to an active connection with a particular scanner when needed. This enables both connectionless and connection-oriented communication models.
| PDU Type | PDU Name | Physical Channel | LE 1M | LE 2M | LE Coded | Currently Supported | Used in | Direction |
| 0b0101 | AUX_CONNECT_REQ | Secondary | * | * | * | * | PAwR | Sent |
| 0b0111 | ADV_EXT_IND | Primary | * | | * | * | PA | Sent |
| 0b0111 | AUX_ADV_IND | Secondary | * | * | * | * | PA | Sent |
| 0b0111 | AUX_SYNC_IND | Periodic | * | * | * | * | PA | Sent |
| 0b0111 | AUX_CHAIN_IND | Secondary and Periodic | * | * | * | * | PA | Sent |
| 0b0111 | AUX_SYNC_SUBEVENT_IND | Periodic | * | * | * | * | PAwR | Sent |
| 0b0111 | AUX_SYNC_SUBEVENT_RSP | Periodic | * | * | * | * | PAwR | Received |
| 0b1000 | AUX_CONNECT_RSP | Secondary | * | * | * | * | PAwR | Received |
Usage
The periodic advertising command handler supports both periodic advertising without responses and periodic advertising with responses. It sends the indication PDUs marked with a direction of sent in the table above. When configured for periodic advertising with responses, the handler can also receive response PDUs, such as AUX_SYNC_SUBEVENT_RSP and AUX_CONNECT_RSP.
Periodic Advertising Establishment
Periodic advertising establishment is the procedure where an advertiser informs potential scanners about ongoing periodic advertising. During this procedure, the advertiser sends an ADV_EXT_IND PDU that points to an AUX_ADV_IND PDU. This AUX_ADV_IND contains the SyncInfo, which a scanner uses to synchronize with the periodic advertising events.
To signal the use of periodic advertising with responses, the advertiser includes an ACAD field in the AUX_ADV_IND PDU. This field contains an AD Structure with Periodic Advertising Response Timing Information, which allows a scanner to identify the advertising as PAwR.
To perform periodic advertising establishment, follow these basic steps:
- Initialize the RCL (See RCL_init) and provide a handle (See RCL_open).
- Initialize and configure a RCL_CMD_BLE5_ADV_t command for periodic advertising establishment.
- Provide the necessary Tx buffer(s) such that they have been initialized and configured to contain the necessary syncInfo needed for the periodic advertising.
- Submit the command with RCL_Command_submit, and either use RCL_Command_pend or a callback to wait for the command's conclusion and proceed with any additional tasks such as post-processing or the submitting of new commands.
Periodic Advertising without Responses
When configured for periodic advertising without responses, the periodic advertiser command handler sends AUX_SYNC_IND and AUX_CHAIN_IND PDUs. The AUX_CHAIN_IND PDUs can contain an AuxPtr to chain additional packets.
Example of periodic advertising events from the same advertising set
If the execution of the RCL_CMD_BLE5_ADV_t command is successful, it can be assumed that the periodic advertising establishment is done, and the user can proceed with the periodic advertising.
- Initialize and configure a RCL_CMD_BLE5_PER_ADV_t command.
- Use the start time of the RCL_CMD_BLE5_ADV_t command, RCL_BLE5_getAuxAdvStartTimeDelta, and the SyncInfo needed to set up the start time of the RCL_CMD_BLE5_PER_ADV_t command.
- Provide the necessary Tx buffer(s) such that they have been initialized and configured to contain the desired advertising data.
- Submit the command RCL_Command_submit, and either use RCL_Command_pend or a callback to wait for the command's conclusion and proceed with any additional tasks such as post-processing or the submitting of new commands.
- Rely on the start time of the previous RCL_CMD_BLE5_PER_ADV_t command to schedule new periodic advertising commands.
The following code snippet shows how to establish a periodic advertising as an advertiser:
void runPeriodicAdvertiser(void)
{
RCL_Buffer_TxBuffer *advExtTxBuffer = (RCL_Buffer_TxBuffer *)txBuffer;
RCL_Buffer_TxBuffer *auxAdvTxBuffer = (RCL_Buffer_TxBuffer *)txBuffer2;
RCL_Buffer_TxBuffer *auxSyncTxBuffer = (RCL_Buffer_TxBuffer *)txBuffer3;
RCL_Buffer_TxBuffer *auxChainTxBuffer = (RCL_Buffer_TxBuffer *)txBuffer4;
AuxPtr advExtAuxPtr;
AuxPtr auxSyncAuxPtr;
SyncInfo auxAdvSyncInfo;
advCmd.chanMap = CH_MAP;
advCmd.common.phyFeatures = PHY_FEATURES;
advCmd.ctx = &advCtx;
advCmd.stats = &advStats;
advCmd.common.runtime.callback = advCallback;
advCmd.common.runtime.lrfCallbackMask.value = 0;
advStats = (RCL_StatsAdvScanInit) { 0 };
advStats.config.accumulate = true;
advCmd.common.timing.absStartTime = startTimeAdvCmd;
advExtAuxPtr.auxOffset = 0;
advExtAuxPtr.offsetUnits = 1;
advExtAuxPtr.auxPhy = 1;
advExtAuxPtr.ca = 0;
advExtAuxPtr.chIndex = 25;
auxAdvSyncInfo.accessAddress = PER_ADV_ACCESS_ADDRESS;
auxAdvSyncInfo.crcInit = PER_ADV_CRC_INIT;
auxAdvSyncInfo.interval = 500;
auxAdvSyncInfo.offsetInfo.adjust = 0;
auxAdvSyncInfo.offsetInfo.base = 2400;
auxAdvSyncInfo.offsetInfo.units = 0;
auxAdvSyncInfo.chMap.chMap0To7 = 0xFF;
auxAdvSyncInfo.chMap.chMap8To15 = 0xFF;
auxAdvSyncInfo.chMap.chMap16To23 = 0xFF;
auxAdvSyncInfo.chMap.chMap24To31 = 0xFF;
auxAdvSyncInfo.chMap.chMap32To36 = 0x1F;
auxAdvSyncInfo.sleepClockAccuracy = 4;
auxAdvSyncInfo.periodicEventCounter = 0x78;
auxSyncAuxPtr.auxOffset = 0;
auxSyncAuxPtr.offsetUnits = 1;
auxSyncAuxPtr.ca = 0;
auxSyncAuxPtr.chIndex = 16;
auxSyncAuxPtr.auxPhy = 1;
setAdvExtBuffer(advExtTxBuffer, &advExtAuxPtr);
setAuxAdvSyncBuffer(auxAdvTxBuffer, &auxAdvSyncInfo, AUX_ADV_DATA_LEN);
perAdvCmd.ctx = &perAdvCtx;
perAdvCmd.stats = &perAdvStats;
perAdvCmd.common.runtime.callback = advCallback;
perAdvCmd.common.runtime.lrfCallbackMask.value = 0;
perAdvStats = (RCL_StatsAdvScanInit) { 0 };
perAdvStats.config.accumulate = true;
setAuxSyncBuffer(auxSyncTxBuffer, &auxSyncAuxPtr, AUX_ADV_DATA_LEN);
setAuxChainBuffer(auxChainTxBuffer, NULL, AUX_CHAIN_DATA_LEN);
PHY_FEATURES,
CH_MAP,
ADV_EXT_IND_PAYLOAD_LEN);
uint32_t startTimePerAdvCmd = startTimeAuxAdvInd +
perAdvCmd.common.timing.absStartTime = startTimePerAdvCmd;
perAdvCmd.ctx->accessAddress = PER_ADV_ACCESS_ADDRESS;
perAdvCmd.ctx->crcInit = PER_ADV_CRC_INIT;
perAdvCmd.common.phyFeatures = advExtAuxPtr.auxPhy;
}
As mentioned before, periodic advertising establishment requires that an AUX_ADV_IND PDU be sent with the necessary SyncInfo. This information is used by potential scanners to properly follow the periodic advertising events. In the previous code snippet, the Tx buffer corresponding to the AUX_ADV_IND is built with a helper function that populates the Tx buffer with appropriate values for each field in the Common Extended Advertising Payload Format.
typedef struct
{
uint16_t base: 13;
uint16_t units: 1;
uint16_t adjust: 1;
uint16_t reserved: 1;
} packetOffsetInfo;
typedef struct
{
uint8_t chMap0To7;
uint8_t chMap8To15;
uint8_t chMap16To23;
uint8_t chMap24To31;
uint8_t chMap32To36: 5;
uint8_t reserved: 3;
} channelMap;
typedef struct
{
packetOffsetInfo offsetInfo;
uint16_t interval;
channelMap chMap;
uint8_t sleepClockAccuracy;
uint32_t accessAddress;
uint32_t crcInit;
uint16_t periodicEventCounter;
} SyncInfo;
static void setAuxAdvSyncBuffer(RCL_Buffer_TxBuffer *buffer, SyncInfo *auxAdvSyncInfo, uint8_t advDataLen)
{
uint8_t payloadLength = 1 + AUX_ADV_SYNC_HDR_LEN + advDataLen;
uint8_t *txData;
txData[0] = BLE_HDR_AUX_ADV_IND;
txData[1] = payloadLength;
txData[3] = BLE5_EXT_HDR_FLAG_ADVA_BM | BLE5_EXT_HDR_FLAG_ADI_BM | BLE5_EXT_HDR_FLAG_SYNC_INFO_BM;
txData[4] = 0xAA;
txData[5] = 0xBB;
txData[6] = 0xCC;
txData[7] = 0xDD;
txData[8] = 0xEE;
txData[9] = 0x01;
txData[10] = 0;
txData[11] = 0;
txData[12] = auxAdvSyncInfo->offsetInfo.base & 0xFF;
txData[13] = ((auxAdvSyncInfo->offsetInfo.base >> 8) & 0x1F) |
((auxAdvSyncInfo->offsetInfo.units & 0x01) << 5) |
((auxAdvSyncInfo->offsetInfo.adjust & 0x01) << 6);
txData[14] = (auxAdvSyncInfo->interval & 0xFF);
txData[15] = (auxAdvSyncInfo->interval >> 8);
txData[16] = (auxAdvSyncInfo->chMap.chMap0To7);
txData[17] = (auxAdvSyncInfo->chMap.chMap8To15);
txData[18] = (auxAdvSyncInfo->chMap.chMap16To23);
txData[19] = (auxAdvSyncInfo->chMap.chMap24To31);
txData[20] = (auxAdvSyncInfo->chMap.chMap32To36 & 0x1F) |
((auxAdvSyncInfo->sleepClockAccuracy & 0x07) << 5);
txData[21] = (auxAdvSyncInfo->accessAddress & 0xFF);
txData[22] = (auxAdvSyncInfo->accessAddress >> 8) & 0xFF;
txData[23] = (auxAdvSyncInfo->accessAddress >> 16) & 0xFF;
txData[24] = (auxAdvSyncInfo->accessAddress >> 24) & 0xFF;
txData[25] = (auxAdvSyncInfo->crcInit & 0xFF);
txData[26] = (auxAdvSyncInfo->crcInit >> 8) & 0xFF;
txData[27] = (auxAdvSyncInfo->crcInit >> 16) & 0xFF;
txData[28] = (auxAdvSyncInfo->periodicEventCounter & 0xFF);
txData[29] = (auxAdvSyncInfo->periodicEventCounter >> 8);
if (advDataLen > 0)
{
for(uint32_t i = 0; i < advDataLen; i++)
{
txData[30 + i] = i & 0xFF;
}
}
}
Notice how the previously defined SyncInfo is used to populate the Tx buffer with the help of a C struct.
Using the periodic advertising command handler requires at least one Tx buffer in the buffer list corresponding to the AUX_SYNC_IND PDU. If needed, the user can rely on the callback to the command to provide additional Tx buffers corresponding to AUX_CHAIN_IND PDUs.
Considering that the syncPacketWindowOffset indicates the transmission time of an AUX_SYNC_IND, and that the reference point is the start time of the AUX_ADV_IND, the RCL provides the RCL_BLE5_getAuxAdvStartTimeDelta API to ease the calculation of the start time of the periodic advertising command.
This API can also be used once periodic advertising is ongoing, but the advertiser needs to inform new scanner devices about the ongoing periodic advertising.
Periodic Advertising with Responses
When configured for periodic advertising with responses, the periodic advertiser command handler sends AUX_SYNC_SUBEVENT_IND and AUX_CONNECT_REQ PDUs.
After transmitting an AUX_SYNC_SUBEVENT_IND PDU, a PAwR advertiser may receive AUX_SYNC_SUBEVENT_RSP PDUs from peer scanners that have subscribed to response slots. The timing between the indication transmission and the reception of responses is determined by several factors, including the PDU payload length, the Periodic Advertising Response Slot Delay, and the Periodic Advertising Response Slot Spacing.
In some cases, such as when a scanner subscribes to the first response slot, the interval between the end of the indication transmission and the start of the first response slot can be very short. This is particularly true when using longer payloads or certain PHYs, where the transmission time of the indication PDU approaches the response slot delay. As a result, the available margin for the receiver to become ready before the response slot begins may be limited.
The table below demonstrates how different combinations of PDU payload length and response slot delay impact the available time margin between the end of the AUX_SYNC_SUBEVENT_IND transmission and the start of the first response slot. These examples assume a PAwR scanner subscribes to the first response slot:
| Case | PHY | AUX_SYNC_SUBEVENT_IND Payload (bytes) | Response Slot Delay | Transmission Time (µs) | Available Margin (µs) |
| 1 | LE 1M | 125 | 1.25 ms | ~1080 | ~170 |
| 2 | LE 1M | 255 | 2.5 ms | ~2120 | ~380 |
| 3 | LE 2M | 140 | 1.25 ms | ~604 | ~646 |
| 4 | LE 2M | 255 | 2.5 ms | ~1064 | ~1436 |
| 5 | LE Coded S2 | 49 | 1.25 ms | ~1246 | ~4 |
| 6 | LE Coded S2 | 255 | 5.0 ms | ~4542 | ~458 |
| 7 | LE Coded S8 | 4 | 1.25 ms | ~976 | ~274 |
| 8 | LE Coded S8 | 16 | 1.25 ms | ~1744 | N/A |
Timing example table notes:
- An available margin of 4 µs is insufficient, as it violates the minimum T_IFS requirement of 150 µs.
- A 4-byte payload for AUX_SYNC_SUBEVENT_IND is generally impractical, as it leaves little room for meaningful data for a PAwR scanner.
N/A indicates that the available margin is negative, meaning the timing requirements cannot be met under those specific conditions.
Besides, the Bluetooth specification mandates an Inter-Frame Space (T_IFS) of 150 µs, which is the required interval between consecutive transmissions and receptions on the same channel. For PAwR, it is specified that the duration of the AUX_SYNC_SUBEVENT_IND PDU must be less than the Periodic Advertising Response Slot Delay minus T_IFS (150 µs).
These timing constraints present significant challenges for achieving both reliable reception and power efficiency:
- If the interval between the indication and the response slot is long, opening the receiver window too early results in unnecessary power consumption.
- Conversely, if the available margin is tight, the receiver must be activated no later than the first response slot to ensure timely reception.
Furthermore, periodic advertising with responses allows for connection creation, requiring the advertiser to support both sending AUX_CONNECT_REQ PDUs and receiving AUX_CONNECT_RSP PDUs. Unlike PAwR synchronization—where the focus is on sending indications and receiving responses—connection creation demands different radio configurations and operational sequences.
To address these diverse timing and operational requirements, the PAwR advertiser handler provides three distinct operating modes. Modes 0 and 1 are optimized for PAwR synchronization, while Mode 2 is specifically designed for creating connections. The following sections describe each mode in detail.
PAwR Advertiser Mode 0
Example of Periodic Advertising with Responses: PAwR Advertiser Mode 0 and Generic Rx
Mode 0 is designed for scenarios where the available time margin between the end of the AUX_SYNC_SUBEVENT_IND transmission and the start of the first response slot is tight. For example, as illustrated in case 1 of the timing examples table, only about 170 µs is available for the receiver to become ready before the first response slot begins. In such cases, using a separate RCL_CMD_BLE5_GENERIC_RX_t radio command may not be practical due to its startup latency.
To address this, Mode 0 enables the PAwR advertiser to automatically switch to receive mode immediately after transmitting an AUX_SYNC_SUBEVENT_IND PDU. The receiver is scheduled to open just before the first response slot, with its timing precisely calculated by subtracting the radio's Rx startup overhead from the Periodic Advertising Response Slot Delay. This approach ensures that the receiver is active only when necessary, minimizing power consumption while still meeting strict timing requirements.
Mode 0 also allows the user to specify the expected number of AUX_SYNC_SUBEVENT_RSP PDUs to be received, which is useful for the scenario where response slots are closely spaced. The operation will conclude when either the specified number of responses has been received or a timeout occurs.
For response slots that are spaced farther apart in time, it is not efficient to keep the receiver active continuously, as this would lead to unnecessary power consumption. Instead, as shown in the figure above, Mode 0 is typically used to handle the first few, closely spaced response slots (for example, the first three). For subsequent response slots that occur later, one or more RCL_CMD_BLE5_GENERIC_RX_t commands can be scheduled to open the receiver window only when needed, further optimizing timing and power efficiency.
According to the Bluetooth Core Specification, AUX_SYNC_SUBEVENT_RSP PDUs use the access address (AA) defined in the Periodic Advertising Timing Information. This AA must differ from the one set in the SyncInfo, which is used for AUX_SYNC_IND PDUs. When configuring the PAwR advertiser in Mode 0, a second access address should be provided using the rspAA field of the RCL_CTX_PER_ADVERTISER_t context structure, and the accessAddress field of the RCL_CTX_GENERIC_RX_t context structure if RCL_CMD_BLE5_GENERIC_RX_t commands are used.
After successful execution of the RCL_CMD_BLE5_ADV_t command, periodic advertising establishment is complete and PAwR advertising can proceed. The following steps outline the process to perform PAwR advertising in Mode 0:
- Initialize and configure a RCL_CMD_BLE5_PER_ADV_t command.
- Use the start time of the RCL_CMD_BLE5_ADV_t command, RCL_BLE5_getAuxAdvStartTimeDelta, and the SyncInfo to set up the start time of the RCL_CMD_BLE5_PER_ADV_t command.
- Provide the necessary Tx buffer(s) that have been initialized and configured to contain the AUX_SYNC_SUBEVENT_IND PDU.
- Provide the necessary Multibuffer(s) that have been initialized and configured to receive the AUX_SYNC_SUBEVENT_RSP PDU.
- Submit the command with RCL_Command_submit, and either use RCL_Command_pend or a callback to wait for the command's conclusion and proceed with any additional tasks such as post-processing or submitting new commands.
- Initialize and configure one or more RCL_CMD_BLE5_GENERIC_RX_t commands, depending on the response slot subscription.
- Provide the necessary Multibuffer(s) that have been initialized and configured to receive the AUX_SYNC_SUBEVENT_RSP PDUs.
- For each RCL_CMD_BLE5_GENERIC_RX_t command, use the start time of the RCL_CMD_BLE5_PER_ADV_t command, along with the Periodic Advertising Response Slot Delay, Periodic Advertising Response Slot Spacing, and the response slot subscription to set up the appropriate start time.
- Use the start time of the previous RCL_CMD_BLE5_PER_ADV_t command, along with the Periodic Advertising Subevent Interval and the periodic advertising interval, to schedule the next PAwR advertising command.
The following code snippet shows how to configure the PAwR advertiser in Mode 0 and run periodic advertising with responses as an advertiser:
void runPAwRAdvertiserMode0(void)
{
advCmd.chanMap = CH_MAP;
advCmd.common.phyFeatures = PHY_FEATURES;
advCmd.ctx = &advCtx;
advCmd.stats = &advStats;
advCmd.common.runtime.callback = advCallback;
advCmd.common.runtime.lrfCallbackMask.value = 0;
advStats = (RCL_StatsAdvScanInit) { 0 };
advStats.config.accumulate = true;
AuxPtr advExtAuxPtr = { 0U };
advExtAuxPtr.auxOffset = 0;
advExtAuxPtr.offsetUnits = 1;
advExtAuxPtr.auxPhy = 1;
advExtAuxPtr.ca = 0;
advExtAuxPtr.chIndex = 25;
SyncInfo auxAdvSyncInfo = { 0U };
auxAdvSyncInfo.accessAddress = PER_ADV_ACCESS_ADDRESS;
auxAdvSyncInfo.crcInit = PER_ADV_CRC_INIT;
auxAdvSyncInfo.interval = 500;
auxAdvSyncInfo.offsetInfo.adjust = 0;
auxAdvSyncInfo.offsetInfo.base = 2400;
auxAdvSyncInfo.offsetInfo.units = 0;
auxAdvSyncInfo.chMap.chMap0To7 = 0xFF;
auxAdvSyncInfo.chMap.chMap8To15 = 0xFF;
auxAdvSyncInfo.chMap.chMap16To23 = 0xFF;
auxAdvSyncInfo.chMap.chMap24To31 = 0xFF;
auxAdvSyncInfo.chMap.chMap32To36 = 0x1F;
auxAdvSyncInfo.sleepClockAccuracy = 4;
auxAdvSyncInfo.periodicEventCounter = 0x78;
RCL_Buffer_TxBuffer *advExtTxBuffer = (RCL_Buffer_TxBuffer *)txBuffer;
RCL_Buffer_TxBuffer *auxAdvTxBuffer = (RCL_Buffer_TxBuffer *)txBuffer2;
setAdvExtBuffer(advExtTxBuffer, &advExtAuxPtr);
SubEventInfo auxAdvSubEventInfo = { 0U };
auxAdvSubEventInfo.rspAA = PAWR_RESPONSE_ACCESS_ADDRESS;
auxAdvSubEventInfo.numSubevents = 3;
auxAdvSubEventInfo.subeventInterval = 30;
auxAdvSubEventInfo.responseSlotDelay = 5;
auxAdvSubEventInfo.responseSlotSpacing = 20;
uint8_t acadBuffer[sizeof(ADStructure) + sizeof(SubEventInfo)] = { 0U };
ADStructure *acadField = (ADStructure *)acadBuffer;
acadField->length = sizeof(SubEventInfo) + 1;
acadField->adType = AD_TYPE_PAWR_TIMING_INFORMATION;
for (uint8_t i = 0; i < sizeof(SubEventInfo); i++)
{
acadField->adData[i] = ((uint8_t *)&auxAdvSubEventInfo)[i];
}
setAuxAdvPawrBuffer(auxAdvTxBuffer, &auxAdvSyncInfo, acadField, AUX_ADV_DATA_LEN);
perAdvCtx.accessAddress = PER_ADV_ACCESS_ADDRESS;
perAdvCtx.crcInit = PER_ADV_CRC_INIT;
perAdvCtx.rspAA = auxAdvSubEventInfo.rspAA;
perAdvCmd.channel = BLE_EXAMPLE_PAWR_CHANNEL;
perAdvCmd.expSubeventRspNum = 3;
perAdvCmd.responseSlotDelay = auxAdvSubEventInfo.responseSlotDelay;
perAdvCmd.ctx = &perAdvCtx;
perAdvCmd.stats = &perAdvStats;
perAdvCmd.common.phyFeatures = advExtAuxPtr.auxPhy;
perAdvCmd.common.allowDelay = false;
perAdvCmd.common.runtime.callback = pawrAdvCallback;
perAdvCmd.common.timing.relGracefulStopTime =
RCL_SCHEDULER_SYSTIM_US(auxAdvSubEventInfo.responseSlotDelay * PAwR_SUBEVENT_RESPONSE_SLOT_DELAY_US +
(2 * auxAdvSubEventInfo.responseSlotSpacing * PAwR_SUBEVENT_RESPONSE_SLOT_SPACING_US));
RCL_Buffer_TxBuffer *auxSyncSubEventTxBuffer = (RCL_Buffer_TxBuffer *)txBuffer3;
setAuxSyncSubEventBuffer(auxSyncSubEventTxBuffer, acadField, AUX_SYNC_SUBEVENT_IND_ADV_DATA_LEN);
RCL_MultiBuffer *multiBuffer = (RCL_MultiBuffer *)rxBuffer;
advCmd.common.timing.absStartTime = startTimeAdvCmd;
PHY_FEATURES,
CH_MAP,
ADV_EXT_IND_PAYLOAD_LEN);
perAdvCmd.common.timing.absStartTime = startTimePawrAdvCmd;
}
To operate in Mode 0, configure the periodic advertiser radio command with perAdvType set to RCL_CMD_BLE_PER_ADV_TYPE_PAWR and pawrMode set to RCL_CMD_BLE_PAWR_MODE_ZERO.
As previously described, the advertiser's Tx buffer for the AUX_ADV_IND must include both the required SyncInfo and the ACAD field containing the Periodic Advertising Response Timing Information. These elements enable scanners to synchronize with periodic advertising events and interpret the response slot configuration. The helper function referenced in the earlier code snippet illustrates how to construct this Tx buffer.
typedef struct
{
uint16_t base: 13;
uint16_t units: 1;
uint16_t adjust: 1;
uint16_t reserved: 1;
} packetOffsetInfo;
typedef struct
{
uint8_t chMap0To7;
uint8_t chMap8To15;
uint8_t chMap16To23;
uint8_t chMap24To31;
uint8_t chMap32To36: 5;
uint8_t reserved: 3;
} channelMap;
typedef struct
{
packetOffsetInfo offsetInfo;
uint16_t interval;
channelMap chMap;
uint8_t sleepClockAccuracy;
uint32_t accessAddress;
uint32_t crcInit;
uint16_t periodicEventCounter;
} SyncInfo;
typedef struct
{
uint8_t length;
uint8_t adType;
uint8_t adData[];
} ADStructure;
{
uint32_t rspAA;
uint8_t numSubevents;
uint8_t subeventInterval;
uint8_t responseSlotDelay;
uint8_t responseSlotSpacing;
} SubEventInfo;
static void setAuxAdvPawrBuffer(RCL_Buffer_TxBuffer *buffer, SyncInfo *auxAdvSyncInfo, ADStructure *acad, uint8_t advDataLen)
{
uint8_t payloadLength = 1 + AUX_ADV_PAWR_HDR_LEN + advDataLen;
uint8_t *txData;
txData[0] = BLE_HDR_AUX_ADV_IND;
txData[1] = payloadLength;
txData[3] = BLE5_EXT_HDR_FLAG_ADVA_BM | BLE5_EXT_HDR_FLAG_ADI_BM | BLE5_EXT_HDR_FLAG_SYNC_INFO_BM;
txData[4] = 0xAA;
txData[5] = 0xBB;
txData[6] = 0xCC;
txData[7] = 0xDD;
txData[8] = 0xEE;
txData[9] = 0x01;
txData[10] = 0;
txData[11] = 0;
txData[12] = auxAdvSyncInfo->offsetInfo.base & 0xFF;
txData[13] = ((auxAdvSyncInfo->offsetInfo.base >> 8) & 0x1F) |
((auxAdvSyncInfo->offsetInfo.units & 0x01) << 5) |
((auxAdvSyncInfo->offsetInfo.adjust & 0x01) << 6);
txData[14] = (auxAdvSyncInfo->interval & 0xFF);
txData[15] = (auxAdvSyncInfo->interval >> 8);
txData[16] = (auxAdvSyncInfo->chMap.chMap0To7);
txData[17] = (auxAdvSyncInfo->chMap.chMap8To15);
txData[18] = (auxAdvSyncInfo->chMap.chMap16To23);
txData[19] = (auxAdvSyncInfo->chMap.chMap24To31);
txData[20] = (auxAdvSyncInfo->chMap.chMap32To36 & 0x1F) |
((auxAdvSyncInfo->sleepClockAccuracy & 0x07) << 5);
txData[21] = (auxAdvSyncInfo->accessAddress & 0xFF);
txData[22] = (auxAdvSyncInfo->accessAddress >> 8) & 0xFF;
txData[23] = (auxAdvSyncInfo->accessAddress >> 16) & 0xFF;
txData[24] = (auxAdvSyncInfo->accessAddress >> 24) & 0xFF;
txData[25] = (auxAdvSyncInfo->crcInit & 0xFF);
txData[26] = (auxAdvSyncInfo->crcInit >> 8) & 0xFF;
txData[27] = (auxAdvSyncInfo->crcInit >> 16) & 0xFF;
txData[28] = (auxAdvSyncInfo->periodicEventCounter & 0xFF);
txData[29] = (auxAdvSyncInfo->periodicEventCounter >> 8);
if (acad != NULL && acad->length > 0)
{
txData[30] = acad->length;
txData[31] = acad->adType;
for (uint8_t i = 0; i < (acad->length - 1); i++)
{
txData[32 + i] = acad->adData[i];
}
}
if (advDataLen > 0)
{
uint8_t advDataStartIndex = 30 + ((acad != NULL && acad->length > 0) ? (acad->length + 1) : 0);
for(uint32_t i = 0; i < advDataLen; i++)
{
txData[advDataStartIndex + i] = i & 0xFF;
}
}
}
PAwR Advertiser Mode 1
Example of Periodic Advertising with Responses: PAwR Advertiser Mode 1 and Generic Rx
Mode 1 is intended for scenarios where there is a more generous timing margin between the end of the AUX_SYNC_SUBEVENT_IND transmission and the start of the first response slot. For example, as shown in cases 3 and 4 of the timing examples table, a relatively large time window is available. Although the PAwR advertiser is often mains-powered, it is still advantageous to minimize power consumption by limiting the duration the receiver is active.
In Mode 1, after transmitting the AUX_SYNC_SUBEVENT_IND PDU, the PAwR advertiser operation concludes. One or more RCL_CMD_BLE5_GENERIC_RX_t commands can then be scheduled to open the receiver window just before the response slots to which peer PAwR scanners have subscribed. This approach allows the receiver to be active only when necessary, further optimizing power efficiency.
The RCL_CMD_BLE5_GENERIC_RX_t command supports receiving a specified number of AUX_SYNC_SUBEVENT_RSP PDUs, similar to Mode 0. To receive these PDUs, a different access address must be configured in the accessAddress field of the RCL_CTX_GENERIC_RX_t context structure.
After successful execution of the RCL_CMD_BLE5_ADV_t command, periodic advertising establishment is complete and PAwR advertising can proceed. The following steps outline the process to perform PAwR advertising in Mode 1:
- Initialize and configure a RCL_CMD_BLE5_PER_ADV_t command.
- Use the start time of the RCL_CMD_BLE5_ADV_t command, RCL_BLE5_getAuxAdvStartTimeDelta, and the SyncInfo to set up the start time of the RCL_CMD_BLE5_PER_ADV_t command.
- Provide the necessary Tx buffer(s) that have been initialized and configured to contain the AUX_SYNC_SUBEVENT_IND PDU.
- Submit the command with RCL_Command_submit, and either use RCL_Command_pend or a callback to wait for the command's conclusion and proceed with any additional tasks such as post-processing or submitting new commands.
- Initialize and configure one or more RCL_CMD_BLE5_GENERIC_RX_t commands, depending on the response slot subscription.
- Provide the necessary Multibuffer(s) that have been initialized and configured to receive the AUX_SYNC_SUBEVENT_RSP PDUs.
- For each RCL_CMD_BLE5_GENERIC_RX_t command, use the start time of the RCL_CMD_BLE5_PER_ADV_t command, along with the Periodic Advertising Response Slot Delay, Periodic Advertising Response Slot Spacing, and the response slot subscription to set up the appropriate start time.
- Use the start time of the previous RCL_CMD_BLE5_PER_ADV_t command, along with the Periodic Advertising Subevent Interval and the periodic advertising interval, to schedule the next PAwR advertising command.
The following code snippet shows how to configure the PAwR advertiser in Mode 1 and run periodic advertising with responses as an advertiser:
void runPAwRAdvertiserMode1(void)
{
advCmd.chanMap = CH_MAP;
advCmd.common.phyFeatures = PHY_FEATURES;
advCmd.ctx = &advCtx;
advCmd.stats = &advStats;
advCmd.common.runtime.callback = advCallback;
advCmd.common.runtime.lrfCallbackMask.value = 0;
advStats = (RCL_StatsAdvScanInit) { 0 };
advStats.config.accumulate = true;
AuxPtr advExtAuxPtr = { 0U };
advExtAuxPtr.auxOffset = 0;
advExtAuxPtr.offsetUnits = 1;
advExtAuxPtr.auxPhy = 1;
advExtAuxPtr.ca = 0;
advExtAuxPtr.chIndex = 25;
SyncInfo auxAdvSyncInfo = { 0U };
auxAdvSyncInfo.accessAddress = PER_ADV_ACCESS_ADDRESS;
auxAdvSyncInfo.crcInit = PER_ADV_CRC_INIT;
auxAdvSyncInfo.interval = 500;
auxAdvSyncInfo.offsetInfo.adjust = 0;
auxAdvSyncInfo.offsetInfo.base = 2400;
auxAdvSyncInfo.offsetInfo.units = 0;
auxAdvSyncInfo.chMap.chMap0To7 = 0xFF;
auxAdvSyncInfo.chMap.chMap8To15 = 0xFF;
auxAdvSyncInfo.chMap.chMap16To23 = 0xFF;
auxAdvSyncInfo.chMap.chMap24To31 = 0xFF;
auxAdvSyncInfo.chMap.chMap32To36 = 0x1F;
auxAdvSyncInfo.sleepClockAccuracy = 4;
auxAdvSyncInfo.periodicEventCounter = 0x78;
RCL_Buffer_TxBuffer *advExtTxBuffer = (RCL_Buffer_TxBuffer *)txBuffer;
RCL_Buffer_TxBuffer *auxAdvTxBuffer = (RCL_Buffer_TxBuffer *)txBuffer2;
setAdvExtBuffer(advExtTxBuffer, &advExtAuxPtr);
SubEventInfo auxAdvSubEventInfo = { 0U };
auxAdvSubEventInfo.rspAA = PAWR_RESPONSE_ACCESS_ADDRESS;
auxAdvSubEventInfo.numSubevents = 3;
auxAdvSubEventInfo.subeventInterval = 30;
auxAdvSubEventInfo.responseSlotDelay = 5;
auxAdvSubEventInfo.responseSlotSpacing = 20;
uint8_t acadBuffer[sizeof(ADStructure) + sizeof(SubEventInfo)] = { 0U };
ADStructure *acadField = (ADStructure *)acadBuffer;
acadField->length = sizeof(SubEventInfo) + 1;
acadField->adType = AD_TYPE_PAWR_TIMING_INFORMATION;
for (uint8_t i = 0; i < sizeof(SubEventInfo); i++)
{
acadField->adData[i] = ((uint8_t *)&auxAdvSubEventInfo)[i];
}
setAuxAdvPawrBuffer(auxAdvTxBuffer, &auxAdvSyncInfo, acadField, AUX_ADV_DATA_LEN);
perAdvCtx.accessAddress = PER_ADV_ACCESS_ADDRESS;
perAdvCtx.crcInit = PER_ADV_CRC_INIT;
perAdvCmd.channel = BLE_EXAMPLE_PAWR_CHANNEL;
perAdvCmd.ctx = &perAdvCtx;
perAdvCmd.stats = &perAdvStats;
perAdvCmd.common.phyFeatures = advExtAuxPtr.auxPhy;
perAdvCmd.common.allowDelay = false;
perAdvCmd.common.runtime.callback = pawrAdvCallback;
RCL_Buffer_TxBuffer *auxSyncSubEventTxBuffer = (RCL_Buffer_TxBuffer *)txBuffer3;
setAuxSyncSubEventBuffer(auxSyncSubEventTxBuffer, acadField, AUX_SYNC_SUBEVENT_IND_ADV_DATA_LEN);
genRxCtx.config.repeated = 1;
genRxCtx.config.disableSync = 0;
genRxCtx.config.discardRxPackets = 0;
genRxCtx.accessAddress = auxAdvSubEventInfo.rspAA;
genRxCtx.crcInit = PER_ADV_CRC_INIT;
genRxCtx.maxPktLen = PAWR_AUX_SYNC_PKT_MAX_PAYLOAD;
genRxCtx.maxPkts = 3;
genRxStats.config.accumulate = true;
genRxCmd.channel = BLE_EXAMPLE_PAWR_CHANNEL;
genRxCmd.ctx = &genRxCtx;
genRxCmd.stats = &genRxStats;
genRxCmd.common.phyFeatures = advExtAuxPtr.auxPhy;
genRxCmd.common.allowDelay = false;
genRxCmd.common.runtime.callback = scanCallback;
genRxCmd.common.runtime.lrfCallbackMask.value = 0;
RCL_MultiBuffer *multiBuffer = (RCL_MultiBuffer *)rxBuffer;
genRxCmd.common.timing.relGracefulStopTime =
RCL_SCHEDULER_SYSTIM_US(2 * auxAdvSubEventInfo.responseSlotSpacing * PAwR_SUBEVENT_RESPONSE_SLOT_SPACING_US);
advCmd.common.timing.absStartTime = startTimeAdvCmd;
PHY_FEATURES,
CH_MAP,
ADV_EXT_IND_PAYLOAD_LEN);
perAdvCmd.common.timing.absStartTime = startTimePawrAdvCmd;
uint32_t subEventRspSlotTime = (auxAdvSubEventInfo.responseSlotDelay * PAwR_SUBEVENT_RESPONSE_SLOT_DELAY_US) +
(0 * auxAdvSubEventInfo.responseSlotSpacing * PAwR_SUBEVENT_RESPONSE_SLOT_SPACING_US);
genRxCmd.common.timing.absStartTime = startTimeGenRxCmd;
}
To operate in Mode 1, configure the periodic advertiser radio command with perAdvType set to RCL_CMD_BLE_PER_ADV_TYPE_PAWR and pawrMode set to RCL_CMD_BLE_PAWR_MODE_ONE.
PAwR Mode 2
Mode 2 is intended for creating connections with peer PAwR scanners. In this mode, the PAwR advertiser transmits an AUX_CONNECT_REQ PDU to initiate a connection and then automatically switches to receive mode to listen for the corresponding AUX_CONNECT_RSP. In this scenario, the advertiser assumes the role of initiator, while the scanner acts as the responder. As a result, the InitA field in the AUX_CONNECT_REQ contains the advertiser's address, and the AdvA field contains the scanner's address. Similarly, in the AUX_CONNECT_RSP, the AdvA field holds the scanner's address, and the TargetA field contains the advertiser's address.
After successful execution of the RCL_CMD_BLE5_ADV_t command, periodic advertising establishment is complete and PAwR advertising can proceed. The following steps outline the process to initiate a connection using PAwR advertising in Mode 2:
- Initialize and configure a RCL_CMD_BLE5_PER_ADV_t command.
- Use the start time of the RCL_CMD_BLE5_ADV_t command, RCL_BLE5_getAuxAdvStartTimeDelta, and the SyncInfo to set up the start time of the RCL_CMD_BLE5_PER_ADV_t command.
- Provide the necessary Tx buffer(s) that have been initialized and configured to contain the AUX_CONNECT_REQ PDU.
- Provide the necessary Multibuffer(s) that have been initialized and configured to receive the AUX_CONNECT_RSP PDU.
- Submit the command with RCL_Command_submit, and either use RCL_Command_pend or a callback to wait for the command's conclusion and proceed with any additional tasks such as post-processing or submitting new commands.
- Upon the RCL_CMD_BLE5_PER_ADV_t command ending with connected status, use the timestamp of the received AUX_CONNECT_RSP PDU, along with the connection event timing parameters to schedule the RCL_CMD_BLE5_CONNECTION_t command for running connection events.
The following code snippet shows how to configure the PAwR advertiser in Mode 2 and initiate a connection as an advertiser:
void runPAwRAdvertiserMode2(void)
{
advCmd.chanMap = CH_MAP;
advCmd.common.phyFeatures = PHY_FEATURES;
advCmd.ctx = &advCtx;
advCmd.stats = &advStats;
advCmd.common.runtime.callback = advCallback;
advCmd.common.runtime.lrfCallbackMask.value = 0;
advStats = (RCL_StatsAdvScanInit) { 0 };
advStats.config.accumulate = true;
AuxPtr advExtAuxPtr = { 0U };
advExtAuxPtr.auxOffset = 0;
advExtAuxPtr.offsetUnits = 1;
advExtAuxPtr.auxPhy = 1;
advExtAuxPtr.ca = 0;
advExtAuxPtr.chIndex = 25;
SyncInfo auxAdvSyncInfo = { 0U };
auxAdvSyncInfo.accessAddress = PER_ADV_ACCESS_ADDRESS;
auxAdvSyncInfo.crcInit = PER_ADV_CRC_INIT;
auxAdvSyncInfo.interval = 500;
auxAdvSyncInfo.offsetInfo.adjust = 0;
auxAdvSyncInfo.offsetInfo.base = 2400;
auxAdvSyncInfo.offsetInfo.units = 0;
auxAdvSyncInfo.chMap.chMap0To7 = 0xFF;
auxAdvSyncInfo.chMap.chMap8To15 = 0xFF;
auxAdvSyncInfo.chMap.chMap16To23 = 0xFF;
auxAdvSyncInfo.chMap.chMap24To31 = 0xFF;
auxAdvSyncInfo.chMap.chMap32To36 = 0x1F;
auxAdvSyncInfo.sleepClockAccuracy = 4;
auxAdvSyncInfo.periodicEventCounter = 0x78;
RCL_Buffer_TxBuffer *advExtTxBuffer = (RCL_Buffer_TxBuffer *)txBuffer;
RCL_Buffer_TxBuffer *auxAdvTxBuffer = (RCL_Buffer_TxBuffer *)txBuffer2;
setAdvExtBuffer(advExtTxBuffer, &advExtAuxPtr);
SubEventInfo auxAdvSubEventInfo = { 0U };
auxAdvSubEventInfo.rspAA = PAWR_RESPONSE_ACCESS_ADDRESS;
auxAdvSubEventInfo.numSubevents = 3;
auxAdvSubEventInfo.subeventInterval = 30;
auxAdvSubEventInfo.responseSlotDelay = 5;
auxAdvSubEventInfo.responseSlotSpacing = 20;
uint8_t acadBuffer[sizeof(ADStructure) + sizeof(SubEventInfo)] = { 0U };
ADStructure *acadField = (ADStructure *)acadBuffer;
acadField->length = sizeof(SubEventInfo) + 1;
acadField->adType = AD_TYPE_PAWR_TIMING_INFORMATION;
for (uint8_t i = 0; i < sizeof(SubEventInfo); i++)
{
acadField->adData[i] = ((uint8_t *)&auxAdvSubEventInfo)[i];
}
setAuxAdvPawrBuffer(auxAdvTxBuffer, &auxAdvSyncInfo, acadField, AUX_ADV_DATA_LEN);
DeviceAddr advA = (DeviceAddr) { .addrType = 0, .addrByte = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06} };
DeviceAddr initA = (DeviceAddr) { .addrType = 0, .addrByte = {0x06, 0x05, 0x04, 0x03, 0x02, 0x01} };
perAdvCtx.accessAddress = PER_ADV_ACCESS_ADDRESS;
perAdvCtx.crcInit = PER_ADV_CRC_INIT;
perAdvCtx.ownA[0] = initA.halfword[0];
perAdvCtx.ownA[1] = initA.halfword[1];
perAdvCtx.ownA[2] = initA.halfword[2];
perAdvCtx.addrType.own = initA.addrType;
perAdvCtx.peerA[0] = advA.halfword[0];
perAdvCtx.peerA[1] = advA.halfword[1];
perAdvCtx.peerA[2] = advA.halfword[2];
perAdvCtx.addrType.peer = advA.addrType;
perAdvCmd.channel = BLE_EXAMPLE_PAWR_CHANNEL;
perAdvCmd.ctx = &perAdvCtx;
perAdvCmd.stats = &perAdvStats;
perAdvCmd.common.phyFeatures = advExtAuxPtr.auxPhy;
perAdvCmd.common.allowDelay = false;
perAdvCmd.common.runtime.callback = pawrAdvCallback;
RCL_Buffer_TxBuffer *auxConnReqTxBuffer = (RCL_Buffer_TxBuffer *)txBuffer3;
setAuxConnReqBuffer(auxConnReqTxBuffer, &advA, &initA);
RCL_MultiBuffer *multiBuffer = (RCL_MultiBuffer *)rxBuffer;
advCmd.common.timing.absStartTime = startTimeAdvCmd;
PHY_FEATURES,
CH_MAP,
ADV_EXT_IND_PAYLOAD_LEN);
perAdvCmd.common.timing.absStartTime = startTimePawrAdvCmd;
{
List_List finishedBuffers;
List_clearList(&finishedBuffers);
uint32_t firstConnEventStartTime = calCentralConnEventStartTime(auxConnRspReceivedTime, perAdvCmd.common.phyFeatures, PAWR_CONNECTION_WINOFFSET);
(void) firstConnEventStartTime;
}
}
To operate in Mode 2, configure the periodic advertiser radio command with perAdvType set to RCL_CMD_BLE_PER_ADV_TYPE_PAWR and pawrMode set to RCL_CMD_BLE_PAWR_MODE_TWO.
The previous code snippet demonstrates how to calculate the start time for the first connection event (i.e., the RCL_CMD_BLE5_CONNECTION_t command) using the timestamp of the received AUX_CONNECT_RSP PDU. The calCentralConnEventStartTime function performs this calculation by considering the reception timestamp, PHY settings, and the connection window offset.
static uint32_t getExtTransmitWindowDelay(uint16_t phyFeatures)
{
switch (phyFeatures)
{
case RCL_PHY_FEATURE_SUB_PHY_CODED_BLE | RCL_PHY_FEATURE_CODED_TX_RATE_S8_BLE:
case RCL_PHY_FEATURE_SUB_PHY_CODED_BLE | RCL_PHY_FEATURE_CODED_TX_RATE_S2_BLE:
case RCL_PHY_FEATURE_SUB_PHY_1_MBPS_BLE:
case RCL_PHY_FEATURE_SUB_PHY_2_MBPS_BLE:
default:
}
}
static uint32_t calCentralConnEventStartTime(uint32_t auxConnRspTimestamp, uint16_t phyFeatures, uint16_t winOffset)
{
uint32_t connEventStartTime = auxConnRspTimestamp;
connEventStartTime += getExtTransmitWindowDelay(phyFeatures);
return connEventStartTime;
}
Architecture
The life cycle of the periodic advertiser command handler is influenced by the type of the periodic advertising event, whether it is periodic advertising without responses or periodic advertising with responses.
For periodic advertising without responses, the life cycle of the periodic advertiser command handler depends on the number of packets that are part of the periodic advertising event. The command handler requires at least one Tx buffer in the buffer list at command start. This buffer will be inspected to determine if an AuxPtr has been provided, and based on this, the operation will either conclude after transmitting the packet or schedule a new operation corresponding to the auxiliary packet.
For periodic advertising with responses, the life cycle of the periodic advertiser command handler depends on the selected PAwR mode:
- In Mode 1, the command handler completes its operation after transmitting the AUX_SYNC_SUBEVENT_IND PDU.
- In Mode 2, the command handler concludes after transmitting the AUX_CONNECT_REQ PDU and successfully receiving the corresponding AUX_CONNECT_RSP PDU.
- In Mode 0, the command handler transmits the AUX_SYNC_SUBEVENT_IND PDU and then automatically switches to receive mode, listening for the configured number of AUX_SYNC_SUBEVENT_RSP PDUs before ending the operation.
It's worth mentioning that only non-connectable/non-scannable PDUs can be sent with the periodic advertising command, and other PDUs will be rejected and the command will end indicating a Tx buffer corruption.
Periodic Advertising without Responses
Periodic Advertising with Responses - Mode 0
| RCL Event (In) | Description |
| RCL_EventSetup | Setup has been performed |
| RCL_EventTimerStart | Timer-based start signalled |
| RCL_EventGracefulStop | Graceful stop has been observed |
| RCL_EventHardStop | Hard stop has been observed |
| RCL_EventRxBufferUpdate | Rx buffer has been updated |
| RCL Event (Out) | Description |
| RCL_EventLastCmdDone | The RCL is finished with the command |
| RCL_EventCmdStarted | Command handler has accepted and started executing |
| RCL_EventTxBufferFinished | An Tx buffer is finished |
| RCL_EventRxBufferFinished | An Rx buffer is finished |
| RCL_EventRxEntryAvail | An Rx entry is available |
| LRF Event | Description |
| LRF_EventOpDone | The PBE operation has finished |
| LRF_EventOpError | Something went wrong. Cause located in the PBE ENDCAUSE register |
| Normal completion if the expected number of responses has been received, due to LRF_sendHardStop |
| LRF_EventRxOk | Packet received with CRC OK and not to be ignored by the MCU |
| LRF_EventRxNok | Packet received with CRC error |
| LRF_EventRxIgnored | Packet received, but may be ignored by MCU |
| LRF_EventRxBufFull | Packet received which did not fit in the Rx FIFO and was not to be discarded |
Periodic Advertising with Responses - Mode 1
Periodic Advertising with Responses - Mode 2
| RCL Event (In) | Description |
| RCL_EventSetup | Setup has been performed |
| RCL_EventTimerStart | Timer-based start signalled |
| RCL_EventGracefulStop | Graceful stop has been observed |
| RCL_EventHardStop | Hard stop has been observed |
| RCL_EventRxBufferUpdate | Rx buffer has been updated |
| RCL Event (Out) | Description |
| RCL_EventLastCmdDone | The RCL is finished with the command |
| RCL_EventCmdStarted | Command handler has accepted and started executing |
| RCL_EventTxBufferFinished | An Tx buffer is finished |
| RCL_EventRxBufferFinished | An Rx buffer is finished |
| RCL_EventRxEntryAvail | An Rx entry is available |
| LRF Event | Description |
| LRF_EventOpDone | The PBE operation has finished |
| LRF_EventOpError | Something went wrong. Cause located in the PBE ENDCAUSE register |
| LRF_EventRxOk | Packet received with CRC OK and not to be ignored by the MCU |
| LRF_EventRxNok | Packet received with CRC error |
| LRF_EventRxIgnored | Packet received, but may be ignored by MCU |
| LRF_EventRxBufFull | Packet received which did not fit in the Rx FIFO and was not to be discarded |