1 /*
2  * Copyright (c) 2021-2024, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #ifndef ti_drivers_RCL_commands_ieee_h__include
34 #define ti_drivers_RCL_commands_ieee_h__include
35 
36 #include <ti/drivers/rcl/RCL_Command.h>
37 #include <ti/drivers/rcl/RCL_Buffer.h>
38 
39 #include <ti/drivers/utils/List.h>
40 
41 typedef struct RCL_CMD_IEEE_RX_TX_t            RCL_CmdIeeeRxTx;
42 typedef struct RCL_CMD_IEEE_TX_TEST_t          RCL_CmdIeeeTxTest;
43 typedef struct RCL_STATS_IEEE_t                RCL_StatsIeee;
44 typedef struct RCL_CmdIeee_RxAction_t          RCL_CmdIeee_RxAction;
45 typedef struct RCL_CmdIeee_TxAction_t          RCL_CmdIeee_TxAction;
46 
47 /* Command IDs for generic commands */
48 #define RCL_CMDID_IEEE_RX_TX            0x2001U
49 #define RCL_CMDID_IEEE_TX_TEST          0x2002U
50 
51 /** Macro for finding RF frequency from channel */
52 #define RCL_CMD_IEEE_CHANNEL_FREQUENCY(channel) ((((channel) - 11UL) * 5000000UL) + 2405000000UL)
53 
54 /**
55  *  @brief Appended packet status field from RX buffer
56  *
57  */
58 typedef union {
59     struct {
60         uint8_t crcError    :1;     /*!< True if packet had CRC error */
61         uint8_t ignored     :1;     /*!< True if packet was ignored */
62         uint8_t reserved    :6;
63     };
64     uint8_t value;
65 } RCL_CmdIeee_RxPktStatus;
66 
67  /**
68  *  @brief IEEE 802.15.4 Receive and transmit command
69  *
70  *  Command to receive or transmit a packet
71  */
72 struct RCL_CMD_IEEE_RX_TX_t {
73     RCL_Command             common;
74     uint32_t                rfFrequency; /*!< RF frequency in Hz to program */
75     RCL_Command_TxPower     txPower;     /*!< Transmit power */
76     RCL_CmdIeee_RxAction    *rxAction;   /*!< Configuration of receive part of command. NULL: Transmit only */
77     RCL_CmdIeee_TxAction    *txAction;   /*!< Configuration of transmit part of command. NULL: No transmission configured */
78     RCL_StatsIeee           *stats;      /*!< Statistics */
79 
80 };
81 #define RCL_CmdIeeeRxTx_Default()                           \
82 {                                                           \
83     .common = RCL_Command_Default(RCL_CMDID_IEEE_RX_TX,     \
84                                   RCL_Handler_Ieee_RxTx),   \
85     .rfFrequency = 2440000000U,                             \
86     .txPower = {.dBm = 0, .fraction = 0},                   \
87     .rxAction = NULL,                                       \
88     .txAction = NULL,                                       \
89     .stats = NULL,                                          \
90 }
91 #define RCL_CmdIeeeRxTx_DefaultRuntime() (RCL_CmdIeeeRxTx) RCL_CmdIeeeRxTx_Default()
92 
93 typedef enum
94 {
95     RCL_CmdIeee_AutoAck_Off,                    /*!< No auto-ACK */
96     RCL_CmdIeee_AutoAck_ImmAckNoAutoPend,       /*!< Send automatic Imm-Ack with frame pending from setting */
97     RCL_CmdIeee_AutoAck_ImmAckAutoPendAll,      /*!< Send automatic Imm-Ack with frame pending from source matching table */
98     RCL_CmdIeee_AutoAck_ImmAckAutoPendDataReq,  /*!< Send automatic Imm-Ack with frame pending from source matching table for data requests */
99     RCL_CmdIeee_AutoAck_ProvidedFrame,          /*!< Send ACK frame provided externally (not supported in this version) */
100 } RCL_CmdIeee_AutoAckMode;
101 
102 typedef union
103 {
104     struct {
105         uint16_t panId;                      /*!< Pan ID of the entry */
106         uint16_t shortAddr;                  /*!< Short address of the entry */
107     };
108     uint32_t combined;
109 } RCL_CmdIeee_PanIdAddr;
110 
111 /** Maximum number of entries in %RCL_CmdIeee_SourceMatchingTableShort (assuming no extended entry) */
112 #define RCL_CMD_IEEE_SOURCE_MATCH_TABLE_SHORT_MAX_LEN 64
113 
114 /** Maximum number of entries in %RCL_CmdIeee_SourceMatchingTableShort if an extended table is present*/
115 #define RCL_CMD_IEEE_SOURCE_MATCH_TABLE_SHORT_WITH_EXT_MAX_LEN 32
116 
117 #define RCL_CMD_IEEE_SOURCE_MATCH_TABLE_SHORT_NUM_WORDS \
118 (((RCL_CMD_IEEE_SOURCE_MATCH_TABLE_SHORT_MAX_LEN) + ((8 * sizeof(uint16_t)) - 1)) / (8 * sizeof(uint16_t)))
119 
120 typedef struct
121 {
122     uint32_t numEntries;                                                    /*!< Number of entries in the list */
123     uint16_t entryEnable[RCL_CMD_IEEE_SOURCE_MATCH_TABLE_SHORT_NUM_WORDS];  /*!< Bits indicating which entires are enabled for matching (1 means enabled) */
124     uint16_t framePending[RCL_CMD_IEEE_SOURCE_MATCH_TABLE_SHORT_NUM_WORDS]; /*!< Frame pending bits for the entries */
125     RCL_CmdIeee_PanIdAddr shortEntry[];                                     /*!< PAN ID and short address for the entry */
126 } RCL_CmdIeee_SourceMatchingTableShort;
127 
128 /** Maximum number of entries in %RCL_CmdIeee_SourceMatchingTableExt */
129 #define RCL_CMD_IEEE_SOURCE_MATCH_TABLE_EXT_MAX_LEN 16
130 
131 #define RCL_CMD_IEEE_SOURCE_MATCH_TABLE_EXT_NUM_WORDS \
132 (((RCL_CMD_IEEE_SOURCE_MATCH_TABLE_EXT_MAX_LEN) + ((8 * sizeof(uint16_t)) - 1)) / (8 * sizeof(uint16_t)))
133 
134 typedef struct
135 {
136     uint32_t numEntries;                                                    /*!< Number of entries in the list */
137     uint16_t entryEnable[RCL_CMD_IEEE_SOURCE_MATCH_TABLE_EXT_NUM_WORDS];    /*!< Bits indicating which entires are enabled for matching (1 means enabled) */
138     uint16_t framePending[RCL_CMD_IEEE_SOURCE_MATCH_TABLE_EXT_NUM_WORDS];   /*!< Frame pending bits for the entries */
139     uint64_t extEntry[];                                                    /*!< Extended address for the entry */
140 } RCL_CmdIeee_SourceMatchingTableExt;
141 
142 typedef struct RCL_CmdIeee_PanConfig_t
143 {
144     uint64_t localExtAddr;                      /*!< Extended address of device */
145     uint16_t localPanId;                        /*!< PAN ID of device */
146     uint16_t localShortAddr;                    /*!< Short address of device */
147     RCL_CmdIeee_AutoAckMode autoAckMode : 3;    /*!< Auto-ACK mode */
148     uint8_t defaultPend : 1;                    /*!< Default value of frame pending bit */
149     uint8_t panCoord : 1;                       /*!< 0: Device is not pan coordinator. 1: Device is PAN coordinator */
150     uint8_t maxFrameVersion : 2;                /*!< Maximum frame version to accept */
151     RCL_CmdIeee_SourceMatchingTableShort *sourceMatchingTableShort; /*!< Source matching table for short addresses */
152     RCL_CmdIeee_SourceMatchingTableExt *sourceMatchingTableExt;     /*!< Source matching table for extended addresses (not supported in this version)*/
153 } RCL_CmdIeee_PanConfig;
154 
155 #define RCL_CmdIeee_PanConfig_Default()                     \
156 {                                                           \
157     .localExtAddr = 0,                                      \
158     .localPanId = 0,                                        \
159     .localShortAddr = 0,                                    \
160     .autoAckMode = RCL_CmdIeee_AutoAck_Off,                 \
161     .defaultPend = 0,                                       \
162     .panCoord = 0,                                          \
163     .maxFrameVersion = 1,                                   \
164     .sourceMatchingTableShort = NULL,                       \
165     .sourceMatchingTableExt = NULL,                         \
166 }
167 #define RCL_CmdIeee_PanConfig_DefaultRuntime() (RCL_CmdIeee_PanConfig) RCL_CmdIeee_PanConfig_Default()
168 
169 /* Do include after typedefs, as the types are needed in ti/drivers/rcl/handlers/ieee.h */
170 #include <ti/drivers/rcl/handlers/ieee.h>
171 
172 /** Maximum number of simultaneously supported PANs */
173 #define RCL_CMD_IEEE_MAX_NUM_PAN    1   /* Maximum number of PANs; will be updated to 2 when dual PAN support is added */
174 
175 struct RCL_CmdIeee_RxAction_t
176 {
177     List_List rxBuffers;                /*!< Linked list of buffers for storing received packets */
178     uint8_t numPan;                     /*!< Number of PANs to support. 0: Frame filtering disabled (promiscuous mode). 1: Single PAN. 2: Dual PAN (not supported in this version). */
179     bool frameFiltStop;                 /*!< 0: Receive frame to the end on frame filtering mismatch. 1: Go back to sync search on frame filtering mismatch. Not supported in this version. */
180     bool disableSync;                   /*!< 0: Receive packets normally. 1: Do not sync to received SFD (not supported in this version). */
181     bool alwaysStoreAck;                /*!< 0: Store ACKs received after transmission only. 1: Store all received ACKs. */
182     RCL_CmdIeee_PanConfig panConfig[RCL_CMD_IEEE_MAX_NUM_PAN];  /*!< PAN configuration for the supplied PANs */
183 };
184 
185 #define RCL_CmdIeee_RxAction_Default()                      \
186 {                                                           \
187     .rxBuffers = { 0 },                                     \
188     .numPan = 0,                                            \
189     .frameFiltStop = false,                                 \
190     .disableSync = false,                                   \
191     .alwaysStoreAck = false,                                \
192     .panConfig = {RCL_CmdIeee_PanConfig_Default()}          \
193 }
194 #define RCL_CmdIeee_RxAction_DefaultRuntime() (RCL_CmdIeee_RxAction) RCL_CmdIeee_RxAction_Default()
195 
196 typedef enum
197 {
198     RCL_CmdIeee_NoCca = 0,                   /*!< No CCA; transmit unconditionally */
199     RCL_CmdIeee_CcaMode1Energy = 1,          /*!< Report busy channel on energy above threshold */
200     RCL_CmdIeee_CcaMode2Signal = 2,          /*!< Report busy channel on DSSS signal observed */
201     RCL_CmdIeee_CcaMode3EnergyOrSignal = 3,  /*!< Report busy channel on energy above threshold OR DSSS signal observed */
202     RCL_CmdIeee_CcaMode4Aloha = 4,           /*!< Always report idle channel when not receiving a packet */
203     RCL_CmdIeee_CcaMode3EnergyAndSignal = 7, /*!< Report busy channel on energy above threshold AND DSSS signal observed */
204 } RCL_CmdIeee_CcaMode;
205 
206 struct RCL_CmdIeee_TxAction_t
207 {
208     RCL_CommandStatus txStatus;         /*!< Returned status of TX operation */
209     int8_t rssiLimit;                   /*!< RSSI limit (dBm) for energy based CCA */
210     RCL_ScheduleType ccaScheduling : 1; /*!< Schedule type for the CCA part */
211     uint16_t allowDelay : 1;            /*!< 0: Give error if CCA time is in the past. 1: Start immediately if CCA time is in the past */
212     RCL_CmdIeee_CcaMode ccaMode : 3;    /*!< CCA mode */
213     uint16_t ccaCorrThresh : 3;         /*!< Correlation threshold for signal based CCA (0-7; correlation tops in 128 us window) */
214     uint16_t ccaContentionWindow : 2;   /*!< Initial contention window value for CCA */
215     uint16_t expectImmAck : 1;          /*!< 0: Immediate ACK not expected. 1: Immediate ACK expected */
216     uint16_t expectEnhAck : 1;          /*!< 0: Enhanced ACK not expected. 1: Enhanced ACK expected. Not supported in this version. */
217     uint16_t allowTxDelay : 1;          /*!< 0: Give error if TX time is in the past. 1: Send TX packet immediately if TX time is in the past */
218     uint16_t endCmdWhenDone : 1;        /*!< 0: Keep command and RX action alive after TX action is done. 1: End command after TX action is done */
219     uint32_t absCcaStartTime;           /*!< Absolute start time of the CCA part */
220     uint16_t relativeTxStartTime;       /*!< Start time of TX packet relative to the CCA start time */
221     uint16_t ackTimeout;                /*!< Timeout for getting sync on ACK relative to end of transmitted packet */
222     RCL_Buffer_DataEntry *txEntry;      /*!< Entry holding frame to be transmitted */
223     uint32_t txTimeStamp;               /*!< Returned time stamp of transmitted packet. Not supported in this version. */
224 };
225 #define RCL_CmdIeee_TxAction_Default()                      \
226 {                                                           \
227     .txStatus = RCL_CommandStatus_Idle,                     \
228     .rssiLimit = -70,                                       \
229     .ccaScheduling = RCL_Schedule_Now,                      \
230     .allowDelay = 1,                                        \
231     .ccaMode = RCL_CmdIeee_NoCca,                           \
232     .ccaCorrThresh = 3,                                     \
233     .ccaContentionWindow = 1,                               \
234     .expectImmAck = 0,                                      \
235     .expectEnhAck = 0,                                      \
236     .allowTxDelay = 1,                                      \
237     .endCmdWhenDone = 0,                                    \
238     .absCcaStartTime = 0,                                   \
239     .relativeTxStartTime = 0,                               \
240     .ackTimeout = RCL_SCHEDULER_SYSTIM_US(300),             \
241     .txEntry = NULL,                                        \
242     .txTimeStamp = 0,                                       \
243 }
244 #define RCL_CmdIeee_TxAction_DefaultRuntime() (RCL_CmdIeee_TxAction) RCL_CmdIeee_TxAction_Default()
245 
246 
247 /**
248  *  @brief IEEE 802.15.4 transmitter test command
249  *
250  *  Command to transmit continuously, either a modulated signal or continuous wave
251  */
252 struct RCL_CMD_IEEE_TX_TEST_t {
253     RCL_Command     common;
254     uint32_t        rfFrequency;    /*!< RF frequency in Hz to program */
255     RCL_Command_TxPower txPower;    /*!< Transmit power */
256     uint16_t     txWord;            /*!< Repeated word to transmit */
257     struct {
258         uint8_t  whitenMode: 2;     /*!< 0. No whitening. 1: PRBS-9. 2: PRBS-15. 3: PRBS-32 */
259         uint8_t  sendCw: 1;         /*!< 0: Send modulated signal. 1: Send CW */
260         uint8_t  reserved: 5;       /*!< Reserved, set to 0 */
261     } config;
262 };
263 #define RCL_CmdIeeeTxTest_Default()                             \
264 {                                                               \
265     .common = RCL_Command_Default(RCL_CMDID_IEEE_TX_TEST,    \
266                                   RCL_Handler_Ieee_TxTest),  \
267     .rfFrequency = 2440000000U,                                 \
268     .txPower = {.dBm = 0, .fraction = 0},                       \
269     .txWord = 0,                                                \
270     .config = {                                                 \
271         .whitenMode = 2,                                        \
272         .sendCw = 0,                                            \
273         .reserved = 0,                                          \
274     },                                                          \
275 }
276 #define RCL_CmdIeeeTxTest_DefaultRuntime() (RCL_CmdIeeeTxTest) RCL_CmdIeeeTxTest_Default()
277 
278 #define RCL_CMD_IEEE_WH_MODE_OFF         0 /*!< config.whitenMode: No whitening */
279 #define RCL_CMD_IEEE_WH_MODE_PRBS9       1 /*!< config.whitenMode: PRBS-9 */
280 #define RCL_CMD_IEEE_WH_MODE_PRBS15      2 /*!< config.whitenMode: PRBS-15 */
281 #define RCL_CMD_IEEE_WH_MODE_PRBS32      3 /*!< config.whitenMode: PRBS-32 */
282 
283 struct RCL_STATS_IEEE_t {
284     struct
285     {
286         uint8_t accumulate : 1;      /*!< 0: Reset counters to 0 at start of command. 1: Add to incoming value of counters. */
287         uint8_t activeUpdate : 1;    /*!< 0: Update only at end of command. 1: Update after receiving or transmitting packets. */
288         uint8_t reserved : 6;        /*!< Reserved, set to 0 */
289     } config;                        /*!< Configuration provided to RCL */
290     uint8_t   timestampValid;        /*!< Returns 1 if %lastTimestamp is updated; 0 otherwise */
291     int8_t    lastRssi;              /*!< RSSI of last received packet */
292     int8_t    maxRssi;               /*!< Highest RSSI observed during the operation (only updated after packets and at the end of operation). Not supported in this version. */
293     uint32_t  lastTimestamp;         /*!< Timestamp of last successfully received packet */
294     uint16_t  nRxNok;                /*!< Number of packets received with CRC error */
295     uint16_t  nRxFifoFull;           /*!< Number of packets received that did not fit in RX FIFO */
296     uint16_t  nRxOk;                 /*!< Number of correctly received packets */
297     uint16_t  nRxIgnored;            /*!< Number of ignored packets received */
298     uint16_t  nTxAck;                /*!< Number of auto-ACKs transmitted */
299     uint16_t  nTx;                   /*!< Number of frames transmitted */
300 };
301 
302 #define RCL_StatsIeee_Default()  \
303 {                                   \
304     .config = { 0 },                \
305     .timestampValid = 0,            \
306     .lastRssi = LRF_RSSI_INVALID,   \
307     .maxRssi = LRF_RSSI_INVALID,    \
308 }
309 #define RCL_StatsIeee_DefaultRuntime() (RCL_StatsIeee) RCL_StatsIeee_Default()
310 
311 
312 
313 #endif
314