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