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_LRFCC2340_h__include
34 #define ti_drivers_LRFCC2340_h__include
35 
36 #include <stdint.h>
37 #include <stddef.h>
38 #include <stdbool.h>
39 #include <ti/devices/DeviceFamily.h>
40 #include DeviceFamily_constructPath(inc/hw_memmap.h)
41 #include DeviceFamily_constructPath(inc/hw_lrfdpbe.h)
42 #include DeviceFamily_constructPath(inc/hw_lrfddbell.h)
43 #include DeviceFamily_constructPath(inc/pbe_generic_regdef_regs.h)
44 
45 #include <ti/drivers/rcl/RCL_Types.h>
46 
47 /** @brief Type for tx power configuration.
48  *
49  * Register value to be written to registers, prior to temperature compensation
50  */
51 #ifdef DeviceFamily_CC27XX
52 /* TODO: See RCL-556 */
53 #define LRFDPBE32_BASE          0x40081400 // LRFDPBE32
54 #define LRFDMDM32_BASE          0x40082400 // LRFDMDM32
55 #define LRFDRFE32_BASE          0x40083400 // LRFDRFE32
56 typedef union
57 {
58     struct {
59         uint16_t ibBoost: 2;
60         uint16_t ib: 6;
61         uint16_t gain: 3;
62         uint16_t mode: 2;
63         uint16_t reserved: 2;
64         uint16_t noIfampRfLdoBypass: 1;
65     };
66     uint16_t rawValue;
67 } LRF_TxPowerTable_Value;
68 #else
69 typedef union
70 {
71     struct {
72         uint16_t reserved: 5;
73         uint16_t ib: 6;
74         uint16_t gain: 3;
75         uint16_t mode: 1;
76         uint16_t noIfampRfLdoBypass: 1;
77     };
78     uint16_t rawValue;
79 } LRF_TxPowerTable_Value;
80 #endif
81 #define LRF_TxPowerTable_INVALID_VALUE ((LRF_TxPowerTable_Value){.rawValue = 0xFFFF})              /*!< Value indicating that no valid tx power could be found in the table. */
82 
83 typedef uint8_t LRF_TxPowerTable_TempCoeff;
84 
85 typedef enum LRF_TxPowerResult_e {
86     TxPowerResult_Ok,                  /*!< TX power value was OK */
87     TxPowerResult_Error,               /*!< TX power value had an error */
88 } LRF_TxPowerResult;
89 
90 
91 #define LRF_EventNone                  ((LRF_Events){ .value = (0U << 0U)})   /*!< No events */
92 #define LRF_EventOpDone                ((LRF_Events){ .value = (1U << 0U)})   /*!< The PBE operation has finished */
93 #define LRF_EventPingRsp               ((LRF_Events){ .value = (1U << 1U)})   /*!< When receiving a CMD_PING, PBE responds with a PINGRSP. */
94 #define LRF_EventRxCtrl                ((LRF_Events){ .value = (1U << 2U)})   /*!< Frame filtering passed, or LL control packet received correctly */
95 #define LRF_EventRxCtrlAck             ((LRF_Events){ .value = (1U << 3U)})   /*!< LL control packet received with CRC OK, not to be ignored, then acknowledgement sent */
96 #define LRF_EventRxNok                 ((LRF_Events){ .value = (1U << 4U)})   /*!< Packet received with CRC error */
97 #define LRF_EventRxIgnored             ((LRF_Events){ .value = (1U << 5U)})   /*!< Packet received, but may be ignored by MCU */
98 #define LRF_EventRxEmpty               ((LRF_Events){ .value = (1U << 6U)})   /*!< Empty packet received, or Rx ACK treatment finished */
99 #define LRF_EventRxBufFull             ((LRF_Events){ .value = (1U << 7U)})   /*!< Packet received which did not fit in the RX FIFO and was not to be discarded.  */
100 #define LRF_EventRxOk                  ((LRF_Events){ .value = (1U << 8U)})   /*!< Packet received with CRC OK and not to be ignored by the MCU */
101 #define LRF_EventTxCtrl                ((LRF_Events){ .value = (1U << 9U)})   /*!< Transmitted LL control packet */
102 #define LRF_EventTxCtrlAckAck          ((LRF_Events){ .value = (1U << 10U)})  /*!< Acknowledgement received on a transmitted LL control packet, and acknowledgement transmitted for that packet */
103 #define LRF_EventTxRetrans             ((LRF_Events){ .value = (1U << 11U)})  /*!< Packet retransmitted with same SN */
104 #define LRF_EventTxAck                 ((LRF_Events){ .value = (1U << 12U)})  /*!< Acknowledgement transmitted, or acknowledgement received on a transmitted packet. */
105 #define LRF_EventTxDone                ((LRF_Events){ .value = (1U << 13U)})  /*!< Packet transmitted */
106 #define LRF_EventTxCtrlAck             ((LRF_Events){ .value = (1U << 14U)})  /*!< Acknowledgement received on a transmitted LL control packet */
107 #define LRF_EventOpError               ((LRF_Events){ .value = (1U << 15U)})  /*!< Something went awfully wrong, the reason is indicated in RAM-based register BLE_ENDCAUSE. */
108 #define LRF_EventRxfifo                ((LRF_Events){ .value = (1U << 16U)})  /*!< Event from fifo, triggered when crossing threshold. Normal use for rxfifo is to generate IRQ when crossing threshold upwards (filling fifo). But downwards is also possible to configure, could be use case for using both fifos for TX or both for RX */
109 #define LRF_EventTxfifo                ((LRF_Events){ .value = (1U << 17U)})  /*!< Event from fifo, triggered when crossing threshold. Normal use for txfifo is to generate IRQ when crossing threshold downwards (emptying fifo). But upwards is also possible to configure, could be use case for using both fifos for TX or both for RX */
110 #define LRF_EventLossOfLock            ((LRF_Events){ .value = (1U << 18U)})  /*!< LOSS_OF_LOCK event */
111 #define LRF_EventLock                  ((LRF_Events){ .value = (1U << 19U)})  /*!< LOCK event */
112 #define LRF_EventRfesoft0              ((LRF_Events){ .value = (1U << 20U)})  /*!< RFESOFT0 event */
113 #define LRF_EventRfesoft1              ((LRF_Events){ .value = (1U << 21U)})  /*!< RFESOFT1 event */
114 #define LRF_EventRfedone               ((LRF_Events){ .value = (1U << 22U)})  /*!< RFEDONE event */
115 #define LRF_EventMdmsoft0              ((LRF_Events){ .value = (1U << 23U)})  /*!< MDMSOFT event */
116 #define LRF_EventMdmsoft1              ((LRF_Events){ .value = (1U << 24U)})  /*!< MDMSOFT1 event */
117 #define LRF_EventMdmsoft2              ((LRF_Events){ .value = (1U << 25U)})  /*!< MDMSOFT event */
118 #define LRF_EventMdmout                ((LRF_Events){ .value = (1U << 26U)})  /*!< MDMOUT event */
119 #define LRF_EventMdmin                 ((LRF_Events){ .value = (1U << 27U)})  /*!< MDMIN event */
120 #define LRF_EventMdmdone               ((LRF_Events){ .value = (1U << 28U)})  /*!< MDMDONE event */
121 #define LRF_EventSystim0               ((LRF_Events){ .value = (1U << 29U)})  /*!< SYSTIM0 event */
122 #define LRF_EventSystim1               ((LRF_Events){ .value = (1U << 30U)})  /*!< SYSTIM1 event */
123 #define LRF_EventSystim2               ((LRF_Events){ .value = (1U << 31U)})  /*!< SYSTIM2 event */
124 
125 
126 union LRF_Events_u {
127     struct {
128         uint32_t opDone              : 1; /*!< The PBE operation has finished */
129         uint32_t pingRsp             : 1; /*!< When receiving a CMD_PING, PBE responds with a PINGRSP. */
130         uint32_t rxCtrl              : 1; /*!< LL control packet received correctly */
131         uint32_t rxCtrlAck           : 1; /*!< LL control packet received with CRC OK, not to be ignored, then acknowledgement sent */
132         uint32_t rxNok               : 1; /*!< Packet received with CRC error */
133 
134         uint32_t rxIgnored           : 1; /*!< Packet received, but may be ignored by MCU */
135         uint32_t rxEmpty             : 1; /*!< Empty packet received */
136         uint32_t rxBufFull           : 1; /*!< Packet received which did not fit in the RX FIFO and was not to be discarded.  */
137         uint32_t rxOk                : 1; /*!< Packet received with CRC OK and not to be ignored by the MCU */
138         uint32_t txCtrl              : 1; /*!< Transmitted LL control packet */
139         uint32_t txCtrlAckAck        : 1; /*!< Acknowledgement received on a transmitted LL control packet, and acknowledgement transmitted for that packet */
140         uint32_t txRetrans           : 1; /*!< Packet retransmitted with same SN */
141         uint32_t txAck               : 1; /*!< Acknowledgement received on a transmitted packet. */
142         uint32_t txDone              : 1; /*!< Packet transmitted */
143         uint32_t txCtrlAck           : 1; /*!< Acknowledgement received on a transmitted LL control packet */
144         uint32_t opError             : 1; /*!< Something went awfully wrong, the reason is indicated in RAM-based register BLE_ENDCAUSE. */
145         uint32_t rxfifo              : 1; /*!< Event from fifo, triggered when crossing threshold. Normal use for rxfifo is to generate IRQ when crossing threshold upwards (filling fifo). But downwards is also possible to configure, could be use case for using both fifos for TX or both for RX */
146         uint32_t txfifo              : 1; /*!< Event from fifo, triggered when crossing threshold. Normal use for txfifo is to generate IRQ when crossing threshold downwards (emptying fifo). But upwards is also possible to configure, could be use case for using both fifos for TX or both for RX */
147         uint32_t lossOfLock          : 1; /*!< LOSS_OF_LOCK event */
148         uint32_t lock                : 1; /*!< LOCK event */
149         uint32_t rfesoft0            : 1; /*!< RFESOFT0 event */
150         uint32_t rfesoft1            : 1; /*!< RFESOFT1 event */
151         uint32_t rfedone             : 1; /*!< RFEDONE event */
152         uint32_t mdmsoft0            : 1; /*!< MDMSOFT event */
153         uint32_t mdmsoft1            : 1; /*!< MDMSOFT1 event */
154         uint32_t mdmsoft2            : 1; /*!< MDMSOFT event */
155         uint32_t mdmout              : 1; /*!< MDMOUT event */
156         uint32_t mdmin               : 1; /*!< MDMIN event */
157         uint32_t mdmdone             : 1; /*!< MDMDONE event */
158         uint32_t systim0             : 1; /*!< SYSTIM0 event */
159         uint32_t systim1             : 1; /*!< SYSTIM1 event */
160         uint32_t systim2             : 1; /*!< SYSTIM2 event */
161     };
162     uint32_t value;
163 };
164 
165 typedef struct LRF_RegConfig_s {
166     uint32_t configLen;
167     uint32_t regConfig[];
168 } LRF_RegConfig;
169 
170 /**
171  * @brief Index of the tx power table.
172  */
173 typedef union
174 {
175     struct {
176         uint8_t fraction : 1; /*!< If set to 1, raises the requested power level by 0.5 dB */
177         int8_t dBm : 7; /*!< Unit of level used to indicate that a power level is expressed in decibels (dB) with reference to one milliwatt (mW). */
178     };
179     int8_t rawValue; /*!< rawValue is twice the dBm number, allowing 0.5 dB steps */
180 } LRF_TxPowerTable_Index;
181 
182 /**
183  * @brief Single entry of the tx power table. Maps power in dBm to specific
184  * register settings.
185  */
186 typedef struct {
187     LRF_TxPowerTable_Index power;            /*!< Power level */
188     LRF_TxPowerTable_TempCoeff tempCoeff;    /*!< Temperature coefficient */
189     LRF_TxPowerTable_Value value;            /*!< Settings to be compensated and written into register */
190 } LRF_TxPowerTable_Entry;
191 
192 /** Value indicating that no valid tx power could be found in the table. */
193 #define LRF_TxPowerEntry_INVALID_VALUE \
194 ((LRF_TxPowerTable_Entry) {\
195     .power = LRF_TxPower_None,\
196     .tempCoeff = 0,\
197     .value = LRF_TxPowerTable_INVALID_VALUE,\
198 })
199 
200 /**
201  * @brief Tx power table, containing all characterized dBm to register settings mappings
202  *
203  *  The table must be sorted from lowest to highest power level
204  */
205 typedef struct {
206     uint32_t numEntries;
207     LRF_TxPowerTable_Entry powerTable[];
208 } LRF_TxPowerTable;
209 
210 typedef struct LRF_TxShape_s {
211     struct {
212         uint32_t      scale    :17;
213         uint32_t      numCoeff :15;
214     };
215     uint8_t       coeff[];
216 } LRF_TxShape;
217 
218 #define LRF_TRIM_NUM_VARIANTS 2
219 #define LRF_TRIM_NORMAL_BW    0
220 #define LRF_TRIM_HIGH_BW      1                 /* Revision >= 4 only */
221 
222 #define LRF_TRIM_MIN_VERSION_FULL_FEATURES  4    /* Only AppTrims revision 4 and above has all features */
223 
224 /* RCL-335: Some CC23X0R5 devices (State D) have an error in the programmed RSSI offset */
225 #define LRF_TRIM_VERSION_RSSIOFFSET_ISSUE_CC23X0R5 4     /* AppTrims revision with issue in rssiOffset field */
226 #define LRF_TRIM_LIMIT_RSSIOFFSET_ISSUE_CC23X0R5  (-4)   /* If rssiOffset is less or equal to this, apply correction */
227 #define LRF_TRIM_CORRECTION_RSSIOFFSET_ISSUE_CC23X0R5 5  /* Correction to apply to devices with wrong RSSI offset */
228 
229 #define LRF_TRIM_VERSION_STATE_C_TRIM_WORKAROUND_CC27XX 7U                /* AppTrims revision of CC27XX devices in state C and beyond */
230 /* RCL-591: RTRIM is hardcoded to 10 for CC27XX state B devices */
231 #define LRF_TRIM_RTRIM_VALUE_STATE_B_RTRIM_WORKAROUND_CC27XX 10U          /* RTRIM value used on CC27XX state B devices */
232 /* RCL-616: DCOLDO0:FIRSTTRIM is hardcoded to 8 and DCOLDO0:SECONDTRIM is increased by 10 for CC27XX state B devices */
233 #define LRF_TRIM_DCOLDO0_FIRSTTRIM_VALUE_STATE_B_DCOLDO_WORKAROUND_CC27XX 8U    /* DCOLDO0:FIRSTTRIM value used on CC27XX state B devices */
234 #define LRF_TRIM_DCOLDO0_SECONDTRIM_INC_STATE_B_DCOLDO_WORKAROUND_CC27XX 10U    /* DCOLDO0:SECONDTRIM needs to be increased by 10 on CC27XX state B devices */
235 #define LRF_TRIM_DCOLDO0_SECONDTRIM_CODED_BITS_MASK_STATE_B_DCOLDO_WORKAROUND_CC27XX ((1U << 3U) | (1U << 5U))    /* Bits mask for bit 3 and 5 of DCOLDO0:SECONDTRIM */
236 #define LRF_TRIM_DCOLDO0_SECONDTRIM_MAX_STATE_B_DCOLDO_WORKAROUND_CC27XX 63U    /* DCOLDO0:SECONDTRIM maximum value allowed within the range of 6-bit representation */
237 
238 /* CC27XX devices with revision numbers below 5 only have one PA trim value (instead of four) in CFG and need a workaround */
239 #define LRF_TRIM_VERSION_CORRECT_AMOUNT_OF_PA_TRIMS_CC27XX 5
240 
241 /* Definitions for trim */
242 typedef struct {
243     uint32_t word[2];
244 } LRF_DoubleWord;
245 
246 typedef union {
247     struct {
248         // Trim value for LRFDRFE:PA0.TRIM
249         union {
250             struct {    // length: 2B
251                 uint16_t trim           : 5;
252                 uint16_t zero           : 11;
253             } pa0;
254 #ifdef DeviceFamily_CC27XX
255             // Trim values for PA (mode0, mode1)
256             struct {    // length: 2B
257                 uint16_t trim0           : 5;
258                 uint16_t zero0           : 3;
259                 uint16_t trim1           : 5;
260                 uint16_t zero1           : 3;
261             } pa2trim01;
262 #endif
263         };
264         // Trim value for LRFDRFE:ATSTREFH.IREFTRIM
265         struct {    // length: 2B
266             uint16_t zero0          : 10;
267             uint16_t irefTrim       : 5;
268             uint16_t zero1          : 1;
269         } atstRefH;
270     } fields;
271     struct {
272 #ifdef DeviceFamily_CC27XX
273         uint16_t pa2trim01;
274 #else
275         uint16_t pa0;
276 #endif
277         uint16_t atstRefH;
278     };
279     uint32_t data;
280 } LRF_Trim0;
281 
282 typedef union {
283     struct {
284         // Trim value for LRFDRFE:LNA.TRIM
285         struct {    // length: 2B
286             uint16_t zero0          : 4;
287             uint16_t trim           : 4;
288             uint16_t zero1          : 8;
289         } lna;
290         // Trim value for LRFDRFE:IFAMPRFLDO.TRIM
291         struct {    // length: 2B
292             uint16_t zero           : 9;
293             uint16_t trim           : 7;
294         } ifampRfLdo;
295         // Trim value for LRFDRFE:DIVLDO.VOUTTRIM
296         struct {    // length: 2B
297             uint16_t zero0          : 8;
298             uint16_t voutTrim       : 7;
299             uint16_t zero1          : 1;
300         } divLdo;
301         // Trim value for LRFDRFE:TDCLDO.VOUTTRIM
302         struct {    // length: 2B
303             uint16_t zero0          : 8;
304             uint16_t voutTrim       : 7;
305             uint16_t zero1          : 1;
306         } tdcLdo;
307     } fields;
308     struct {
309         uint16_t lna;
310         uint16_t ifampRfLdo;
311         uint16_t divLdo;
312         uint16_t tdcLdo;
313     };
314     LRF_DoubleWord data;
315 } LRF_Trim1;
316 
317 typedef union {
318     struct {
319         // Trim values for LRFDRFE:DCOLDO0
320         struct {    // length: 2B
321             uint16_t zero0          : 4;
322             uint16_t firstTrim      : 4;
323             uint16_t secondTrim     : 6;
324             uint16_t zero1          : 2;
325         } dcoLdo0;
326         // Trim value for LRFDRFE:IFADCALDO.TRIMOUT
327         struct {    // length: 2B
328             uint16_t zero0          : 8;
329             uint16_t trimout        : 6;
330             uint16_t zero1          : 2;
331         } ifadcAldo;
332         // Trim value for LRFDRFE:IFADCDLDO.TRIMOUT
333         struct {    // length: 2B
334             uint16_t zero0          : 8;
335             uint16_t trimout        : 6;
336             uint16_t zero1          : 2;
337         } ifadcDldo;
338         // Trim value for LRFDRFE:DCO.TAILRESTRIM
339         struct {    // length: 2B
340             uint16_t zero0          : 3;
341             uint16_t tailresTrim    : 4;
342             uint16_t zero1          : 9;
343         } dco;
344     } fields;
345     struct {
346         uint16_t dcoLdo0;
347         uint16_t ifadcAldo;
348         uint16_t ifadcDldo;
349         uint16_t dco;
350     };
351     LRF_DoubleWord data;
352 } LRF_Trim2;
353 
354 typedef union {
355     struct {
356         // Trim value for LRFDRFE:IFADCQUANT.QUANTTHR
357         struct {    // length: 2B
358             uint16_t quantThr       : 3;
359             uint16_t zero           : 13;
360         } ifadcQuant;
361         // Trim values for LRFDRFE:IFADC0
362         struct {    // length: 2B
363             uint16_t zero0          : 2;
364             uint16_t aafcap         : 2;
365             uint16_t int2Adj        : 4;
366             uint16_t zero1          : 2;
367             uint16_t ditheren       : 2;    /* Revision >= 4 only */
368             uint16_t dithertrim     : 3;
369             uint16_t zero2          : 1;
370         } ifadc0;
371         // Trim value for LRFDRFE:IFADC1.TRIM
372         struct {    // length: 2B
373             uint16_t zero0          : 9;
374             uint16_t trim           : 6;
375             uint16_t nrz            : 1;
376         } ifadc1;
377         // Trim values for LRFDRFE:IFADCLF
378         struct {    // length: 2B
379             uint16_t int3           : 4;
380             uint16_t ff1            : 4;
381             uint16_t ff2            : 4;
382             uint16_t ff3            : 4;
383         } ifadclf;
384     } fields;
385     struct {
386         uint16_t ifadcQuant;
387         uint16_t ifadc0;
388         uint16_t ifadc1;
389         uint16_t ifadclf;
390     };
391     LRF_DoubleWord data;
392 } LRF_Trim_Variant;
393 
394 typedef struct
395 {
396     uint16_t rtrimMinOffset : 2;
397     uint16_t rtrimMaxOffset : 2;
398     uint16_t divLdoMinOffset: 2;
399     uint16_t divLdoMaxOffset: 2;
400     uint16_t tdcLdoMinOffset: 2;
401     uint16_t tdcLdoMaxOffset: 2;
402     uint16_t tThrl          : 2;
403     uint16_t tThrh          : 2;
404 } LRF_Trim_tempLdoRtrim;
405 
406 typedef struct {
407     int32_t rssiTcomp      : 4;
408     int32_t magnTcomp      : 4;
409     int32_t magnOffset     : 4;
410     int32_t rfu            : 4;
411     int32_t agcThrTcomp    : 4;
412     int32_t agcThrOffset   : 4;
413     int32_t lowGainOffset  : 4;
414     int32_t highGainOffset : 4;
415 } LRF_Trim_tempRssiAgc;
416 
417 typedef union {
418     struct {
419         struct {    // length: 4B
420             LRF_Trim_tempLdoRtrim tempLdoRtrim;
421             uint8_t hfxtPdError;
422             uint8_t res;
423          } lrfdrfeExtTrim1;                  /* Revision >= 4 only */
424         // Trim values for synth divider 0
425         LRF_Trim_tempRssiAgc lrfdrfeExtTrim0;
426     } fields;
427     struct {
428         uint32_t lrfdrfeExtTrim1;
429         uint32_t lrfdrfeExtTrim0;
430     };
431     uint32_t data;
432 } LRF_Trim3;
433 
434 typedef union {
435     struct {
436         struct {    // length: 2B
437                     // RSSI measured for front end 0 in production test.
438                     // Value is read by RF Core FW during RF Core initialization
439             uint16_t offset         : 8;
440             uint16_t trimCompleteN  : 1;
441             uint16_t zero           : 7;
442         } fend0Rssi;
443         // Trim values for synth divider 0
444         struct {    // length: 2B
445                     // Trim value for IQ mismatch compensation.
446                     // Value is read by RF Core FW during RF Core initialization
447             uint16_t iqmc           : 16;
448         } syntDiv0;
449 #ifdef DeviceFamily_CC27XX
450         // Trim values for PA (mode2, mode3)
451         struct {    // length: 2B
452             uint16_t trim2           : 5;
453             uint16_t zero0           : 3;
454             uint16_t trim3           : 5;
455             uint16_t zero1           : 3;
456         } pa2trim23;
457 #else
458         uint16_t res1;
459 #endif
460         struct {
461             uint8_t zero            : 4;
462             uint8_t aafcap          : 4;
463         } ifamprfldo[LRF_TRIM_NUM_VARIANTS];     /* Revision >= 4 only */
464     } fields;
465     struct {
466         int8_t   rssiOffset;
467         uint8_t  trimCompleteN;
468         uint16_t demIQMC0;
469 #ifdef DeviceFamily_CC27XX
470         uint16_t pa2trim23;
471 #else
472         uint16_t res1;
473 #endif
474         uint8_t  ifamprfldo[LRF_TRIM_NUM_VARIANTS];
475     };
476     uint32_t data;
477 } LRF_Trim4;
478 
479 /* This definition is used instead of the definition from hw_fcfg.h to accommodate implementation
480    and cut parameters not relevant to LRF */
481 typedef struct {
482     uint8_t             revision;           /* Revision of appTrims */
483     uint8_t             nToolsClientOffset;
484     uint8_t             reserved[2];
485     LRF_Trim0           trim0;
486     LRF_Trim1           trim1;
487     LRF_Trim2           trim2;
488     LRF_Trim_Variant    trimVariant[LRF_TRIM_NUM_VARIANTS];
489     LRF_Trim3           trim3;
490     LRF_Trim4           trim4;
491 } LRF_TrimDef;
492 
493 /**
494  *  @brief Software defined PHY parameters
495  */
496 typedef struct LRF_SwConfig_s {
497     int32_t           rxIntFrequency;         /*!< Receiver intermediate frequency [Hz] */
498     int32_t           rxFrequencyOffset;      /*!< Receiver frequency offset [Hz] */
499     int32_t           txFrequencyOffset;      /*!< Transmitter frequency offset [Hz] */
500     uint32_t          modFrequencyDeviation;  /*!< Transmitter frequency deviation [Hz] */
501     const LRF_TxShape *txShape;               /*!< Transmitter shape definition */
502     uint8_t           bwIndex;                /*!< Index to use for bandwitdh dependent settings (0: normal 1: high) */
503     uint8_t           bwIndexDither;          /*!< Index to use for bandwitdh dependent ADC dithering settings (0: low 1: normal/high) */
504 } LRF_SwConfig;
505 
506 /**
507  *  @brief Software defined PHY parameter list
508  */
509 typedef struct LRF_SwParam_s {
510     const LRF_SwConfig      *swConfig;          /*!< Software defined parameters. */
511     const LRF_TxPowerTable  *txPowerTable;      /*!< TX power table */
512     const LRF_TrimDef       *trimDef;           /*!< Trim definitions. NULL: Do not apply trim. */
513 } LRF_SwParam;
514 
515 /**
516  *  @brief Radio configuration structure
517  */
518 typedef struct LRF_Config_s {
519     const LRF_TOPsmImage    *pbeImage;       /*!< Image for the PBE */
520     const LRF_TOPsmImage    *mceImage;       /*!< Image for the MCE */
521     const LRF_TOPsmImage    *rfeImage;       /*!< Image for the RFE */
522     const LRF_RegConfigList *regConfigList;  /*!< List of pointers to register definitions */
523 } LRF_Config;
524 
525 #define LRF_BASE_ADDR           0x40080000U
526 #define PBE_RAM_BASE_ADDR       0x40090000U
527 #define BUF_RAM_BASE_ADDR       0x40092000U
528 #define RXF_UNWRAPPED_BASE_ADDR 0x40093000U
529 #define TXF_UNWRAPPED_BASE_ADDR 0x40093800U
530 #define MCE_RAM_BASE_ADDR       0x40094000U
531 #define RFE_RAM_BASE_ADDR       0x40096000U
532 #define S2R_RAM_BASE_ADDR       0x40098000U
533 #define TOPSM_RAM_SZ            0x00001000U /* 4 KB */
534 #define MAX_REG_CONFIG_LEN      1024U        /* 1024 entries, using 4 KB */
535 
536 #define LRF_TXPOWER_REFERENCE_TEMPERATURE 25    /*!< Reference temperature for TX power, degrees C */
537 #define LRF_TXPOWER_TEMPERATURE_SCALING  0x100 /*!< Scaling factor for TX power temperature coefficients */
538 
539 extern const LRF_TxShape LRF_shapeBaseGfsk05;
540 extern const LRF_TxShape LRF_shapeBaseGfsk067;
541 extern const LRF_TxShape LRF_shapeBaseGfsk20;
542 
LRF_sendHardStop(void)543 static inline void LRF_sendHardStop(void)
544 {
545     /* Send stop to PBE */
546     /* This API is the same across PBE banks */
547     HWREG_WRITE_LRF(LRFDPBE_BASE + LRFDPBE_O_API) = PBE_GENERIC_REGDEF_API_OP_STOP;
548 }
549 
LRF_sendGracefulStop(void)550 static inline void LRF_sendGracefulStop(void)
551 {
552     /* Send stop to PBE */
553     /* This API is the same across PBE banks */
554     HWREG_WRITE_LRF(LRFDPBE_BASE + LRFDPBE_O_API) = PBE_GENERIC_REGDEF_API_OP_EOPSTOP;
555 }
556 
LRF_hardStop(void)557 static inline void LRF_hardStop(void)
558 {
559     /* LRF does not need to do anything special after hard stop is sent */
560 }
561 
LRF_getTxFifoWritable(void)562 static inline uint32_t LRF_getTxFifoWritable(void)
563 {
564     return HWREG_READ_LRF(LRFDPBE_BASE + LRFDPBE_O_TXFWRITABLE);
565 }
566 
567 /**
568  * @brief Programs current TX power setting in radio with temperature compensation
569  */
570 void LRF_programTemperatureCompensatedTxPower(void);
571 
572 /**
573  * @brief Finds settings corresponding to the highest tx power lower than
574  * the specified value in the tx power table and programs it in the radio
575  *
576  *  @param  powerLevel maximum allowed power level in dBm, or special value
577  *      (%LRF_TxPower_Use_Min, %LRF_TxPower_Use_Max, %LRF_TxPower_Use_Raw, or %LRF_TxPower_None)
578  *
579  *  @return TxPowerResult_Ok on success; TxPowerResult_Error if no valid settings were found
580  *
581  */
582 LRF_TxPowerResult LRF_programTxPower(LRF_TxPowerTable_Index powerLevel);
583 
584 /**
585  * @brief Request specific clock enable bits for use by the RCL
586  *
587  *  @param  mask Bit mask of clock enable bits to be set; bit positions as in LRFDDBELL_CLKCTL
588  *
589  */
LRF_setRclClockEnable(uint16_t mask)590 static inline void LRF_setRclClockEnable(uint16_t mask)
591 {
592     hal_set_rcl_clock_enable(mask);
593 }
594 
595 /**
596  * @brief Remove request of specific clock enable bits for use by the RCL
597  *
598  *  @param  mask Bit mask of clock enable bits to be cleared; bit positions as in LRFDDBELL_CLKCTL
599  *
600  */
LRF_clearRclClockEnable(uint16_t mask)601 static inline void LRF_clearRclClockEnable(uint16_t mask)
602 {
603     hal_clear_rcl_clock_enable(mask);
604 }
605 
606 /* Temporarily added definitions until https://jira.itg.ti.com/browse/TIDRIVERS-6489 is implemented */
607 #ifndef NO_DRIVERS
608 #include <ti/drivers/Power.h>
609 
610 #ifdef DeviceFamily_CC27XX
611 #define LRF_POWER_PERIPH_VALUE(x) (PowerCC27XX_PERIPH_GROUP_LRFD | (x))
612 #else
613 #define LRF_POWER_PERIPH_VALUE(x) (PowerCC23X0_PERIPH_GROUP_LRFD | (x))
614 #endif
615 
616 #ifdef PowerLPF3_PERIPH_LRFD_BUFRAM
617 #error "Remove local definition in LRFCC23X0.h and rely on Power driver's definition"
618 #else
619 #define PowerLPF3_PERIPH_LRFD_BUFRAM LRF_POWER_PERIPH_VALUE(LRFDDBELL_CLKCTL_BUFRAM_S)
620 #endif
621 
622 #ifdef PowerLPF3_PERIPH_LRFD_MDM
623 #error "Remove local definition in LRFCC23X0.h and rely on Power driver's definition"
624 #else
625 #define PowerLPF3_PERIPH_LRFD_MDM    LRF_POWER_PERIPH_VALUE(LRFDDBELL_CLKCTL_MDM_S)
626 #endif
627 
628 #ifdef PowerLPF3_PERIPH_LRFD_TRC
629 #error "Remove local definition in LRFCC23X0.h and rely on Power driver's definition"
630 #else
631 #define PowerLPF3_PERIPH_LRFD_TRC    LRF_POWER_PERIPH_VALUE(LRFDDBELL_CLKCTL_TRC_S)
632 #endif
633 /* End of temporarily added definitions */
634 
635 #endif
636 
637 #endif
638