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 __lrf_h__
34 #define __lrf_h__
35 
36 #include <stdint.h>
37 #include <stddef.h>
38 #include <stdbool.h>
39 #include <ti/drivers/rcl/hal/hal.h>
40 
41 #if defined(DeviceFamily_CC23X0R5) || defined(DeviceFamily_CC23X0R2) || defined(DeviceFamily_CC27XX) || defined(DeviceFamily_CC23X0R22) || defined(DeviceFamily_CC2340R53)
42 #  include <ti/devices/DeviceFamily.h>
43 #  include DeviceFamily_constructPath(inc/hw_types.h)
44 #  include DeviceFamily_constructPath(inc/hw_lrfdpbe.h)
45 #  include <ti/drivers/rcl/LRFCC23X0.h>
46 #endif
47 
48 #ifdef DeviceFamily_CC1308
49 #  define BUFFER_SPLIT_SUPPORT
50 #  include "LRFCC1308.h"
51 #endif
52 
53 /**
54  *  Special value given as a TX power to indicate that the lowest available
55  *  TX power is requested
56  */
57 #define LRF_TxPower_Use_Min       ((LRF_TxPowerTable_Index){.rawValue = -128})
58 /**
59  *  Special value given as a TX power to indicate that the highest available
60  *  TX power is requested
61  */
62 #define LRF_TxPower_Use_Max       ((LRF_TxPowerTable_Index){.rawValue = 125})
63 /**
64  *  Special value given as a TX power to indicate that a given raw TX power
65  *  register setting should be used.
66  */
67 #define LRF_TxPower_Use_Raw       ((LRF_TxPowerTable_Index){.rawValue = 126})
68 /**
69  *  Special value given as a TX power to indicate that a TX power should not
70  *  be programmed; instead, use the register value written through settings or
71  *  register write.
72  */
73 #define LRF_TxPower_None          ((LRF_TxPowerTable_Index){.rawValue = 127})
74 
75 /**
76  *  Buffer available limit when no limit exists
77  *
78  */
79 #define LRF_SETTINGS_BUFFER_UNLIMITED 0x3FFF
80 
81 /**
82  * RSSI value indicating an invalid RSSI
83  *
84  */
85 #define LRF_RSSI_INVALID (127)
86 
87 
88 typedef enum LRF_RadioState_e {
89     RadioState_Down = 0,
90     RadioState_ImagesLoaded,  /* TOPsm images loaded, persists     */
91     RadioState_Configured,    /* REGBANK values loaded, no persist */
92 } LRF_RadioState;
93 
94 /**
95  *  @brief Setup operation result
96  */
97 typedef enum LRF_SetupResult_e {
98     SetupResult_Ok,                    /*!< Setup was successful */
99     SetupResult_Ok_Partial,            /*!< Setup was successful so far, need rest of buffer */
100     SetupResult_ErrorImageLen,         /*!< An image was too long */
101     SetupResult_ErrorConfigLen,        /*!< A register configuration table was too long */
102     SetupResult_ErrorElemLen,          /*!< A register configuration element exceeded the table length */
103     SetupResult_ErrorElemType,         /*!< A register configuration element had invalid type */
104     SetupResult_ErrorElemAddrAlign,    /*!< A register configuration element had unsupported address alignment */
105     SetupResult_ErrorParRange,         /*!< A register parameter element was outside the allowed range */
106     SetupResult_ErrorSwConfig,         /*!< The swConfig field was NULL */
107 } LRF_SetupResult;
108 
109 struct LRF_TOPsmImage_s {
110     uint32_t  imageLen;
111     uint32_t  image[];
112 };
113 
114 typedef union {
115     struct {
116         uint32_t lengthMinus1 : 12;
117         uint32_t type         : 4;
118         uint32_t startAddress : 16;
119     } region;
120     uint32_t value32;
121     uint16_t value16[2];
122     struct {
123         uint16_t value16;
124         uint16_t address;
125     } sparse;
126     struct {
127         uint16_t value16;
128         uint16_t mask16;
129     } masked;
130     struct {
131         uint32_t length              : 14;
132         uint32_t invertedFeatureMask : 1;
133         uint32_t compoundSegment     : 1;
134         uint32_t featureMask         : 16;
135     } segment;
136 } LRF_ConfigWord;
137 
138 struct LRF_RegConfigList_s {
139     uint32_t numEntries;
140     LRF_ConfigWord *entries[];
141 };
142 
143 typedef enum {
144     HW_Region_Clear             = 0,
145     HW_Write_16bit              = 1,
146     HW_Write_32bit              = 2,
147     HW_Write_16bit_sparse       = 3,
148     SW_Region_Clear             = 4,
149     SW_Write_16bit              = 5,
150     SW_Write_32bit              = 6,
151     SW_Write_16bit_sparse       = 7,
152     Par_Region_Clear            = 8,
153     Par_Reference_32bit         = 9,
154     Par_Write_32bit             = 10,
155     HW_Write_16bit_masked       = 11,
156     LRF_RegionOperation_Skip    = 254,
157     LRF_RegionOperation_Invalid = 255,
158 } LRF_RegionOperation;
159 
160 typedef enum {
161     LRF_ApplySettings_NoBase      = 0,
162     LRF_ApplySettings_IncludeBase = 1,
163 } LRF_ApplySettingsBase;
164 
165 typedef struct {
166     /* Settings */
167     uint16_t                phyFeatures;
168     LRF_ApplySettingsBase   includeBase;
169 
170 #ifdef BUFFER_SPLIT_SUPPORT
171     /* State variables */
172     bool                    started;
173     int32_t                 totalLength;
174     uint32_t                segmentLength;
175 
176     /* State variables for region */
177     uintptr_t               address;
178     LRF_RegionOperation     operation;
179     uint32_t                regionLength;
180     uint32_t                regionStart;
181 #endif
182 } LRF_ApplySettingsState;
183 
184 #define LRF_PhyFeatures_Default 0
185 
186 /* The definition below ensures an invalid value runtime and a warning compiletime */
187 #define __ERROR_Address_is_in_an_invalid_range_for_LRF_setup 0x00040000
188 
189 #define _ADDRESS_REGION_BIT(_address)                                   \
190     ((((((uintptr_t)(_address)) >= (LRF_BASE_ADDR)) &&                  \
191        ((uintptr_t)(_address)) < ((LRF_BASE_ADDR) + 0x10000)) ? 0 :     \
192       ((((uintptr_t)(_address)) >= (PBE_RAM_BASE_ADDR)) &&              \
193         (((uintptr_t)(_address)) < ((PBE_RAM_BASE_ADDR) + 0x10000)) ?   \
194        1 :                                                              \
195        (((((uintptr_t)(_address)) >= 0) &&                              \
196         (((uintptr_t)(_address)) < 0x10000)) ?                          \
197        2 :                                                              \
198        (__ERROR_Address_is_in_an_invalid_range_for_LRF_setup)))) << 14)
199 
200 #define LRF_SETTINGS_CLEAR(_startAddress, _numWords)                    \
201     ((((_numWords) - 1) & 0x0FFF) |                                     \
202      _ADDRESS_REGION_BIT(_startAddress) |                               \
203      ((((uintptr_t)(_startAddress)) & 0xFFFF) << 16))
204 
205 #define LRF_SETTINGS_16BIT_BLOCK(_startAddress, _numWords)              \
206     ((((_numWords) - 1) & 0x0FFF) |                                     \
207     _ADDRESS_REGION_BIT(_startAddress) | (1 << 12) |                    \
208      ((((uintptr_t)(_startAddress)) & 0xFFFF) << 16))
209 
210 #define LRF_SETTINGS_16BIT_DUAL_ENTRY(_value0, _value1)                  \
211     (((_value0) & 0xFFFF) | (((_value1) & 0xFFFF) << 16))
212 
213 #define LRF_SETTINGS_32BIT_BLOCK(_startAddress, _numWords)              \
214     ((((_numWords) - 1) & 0x0FFF) |                                     \
215      _ADDRESS_REGION_BIT(_startAddress) | (2 << 12) |                   \
216      ((((uintptr_t)(_startAddress)) & 0xFFFF) << 16))
217 
218 #define LRF_SETTINGS_16BIT_SPARSE_BLOCK(_startAddress, _numWords)       \
219     ((((_numWords) - 1) & 0x0FFF) |                                     \
220      _ADDRESS_REGION_BIT(_startAddress) | (3 << 12))                    \
221 
222 #define LRF_SETTINGS_16BIT_SPARSE_ENTRY(_address, _value)               \
223     (((((uintptr_t)(_address)) & 0xFFFF) << 16) | ((_value) & 0xFFFF))
224 
225 #define LRF_SETTINGS_16BIT_MASKED_BLOCK(_startAddress, _numWords)       \
226     ((((_numWords) - 1) & 0x0FFF) | (11 << 12) |                        \
227      ((((uintptr_t)(_startAddress)) & 0xFFFF) << 16))
228 
229 #define LRF_SETTINGS_16BIT_MASKED_ENTRY(_mask, _value)                  \
230     ((((_mask) & 0xFFFF) << 16) | ((_value) & 0xFFFF))
231 
232 LRF_SetupResult LRF_setupRadio(const LRF_Config *lrfConfig, uint16_t phyFeatures, LRF_RadioState lrfState);
233 
234 LRF_SetupResult LRF_loadImage(const LRF_TOPsmImage *image, uint32_t destinationAddress);
235 
LRF_resetSettingsState(LRF_ApplySettingsState * state)236 static inline void LRF_resetSettingsState(LRF_ApplySettingsState *state)
237 {
238 #ifdef BUFFER_SPLIT_SUPPORT
239     state->totalLength = 0;
240 #else
241     (void)state;
242 #endif
243 }
244 
245 void LRF_initSettingsState(LRF_ApplySettingsState *state,
246                            LRF_ApplySettingsBase   includeBase,
247                            uint16_t                phyFeatures);
248 LRF_SetupResult LRF_applySettings(LRF_ConfigWord         *config,
249                                   LRF_ApplySettingsState *state,
250                                   int32_t                 bufferAvailWords);
251 
252 void LRF_enable(void);
253 void LRF_disable(void);
254 void LRF_powerDown(void);
255 void LRF_sendHardStop(void);
256 void LRF_sendGracefulStop(void);
257 void LRF_hardStop(void);
258 
259 void LRF_waitForTopsmReady(void);
260 uint32_t LRF_prepareRxFifo(void);
261 uint32_t LRF_prepareTxFifo(void);
262 uint32_t LRF_peekRxFifo(int32_t offset);
263 uint32_t LRF_peekTxFifo(int32_t offset);
264 uint8_t *LRF_getTxFifoWrAddr(int32_t offset);
265 void LRF_skipTxFifoWords(uint32_t wordLength);
266 void LRF_discardRxFifoWords(uint32_t wordLength);
267 void LRF_readRxFifoWords(uint32_t *data32, uint32_t wordLength);
268 void LRF_writeTxFifoWords(const uint32_t *data32, uint32_t wordLength);
269 void LRF_setRxFifoEffSz(uint32_t maxSz);
270 void LRF_programFrequency(uint32_t frequency, bool tx);
271 uint32_t LRF_enableSynthRefsys(void);
272 void LRF_disableSynthRefsys(void);
273 void LRF_setClockEnable(uint16_t mask, uint8_t entryNumber);
274 void LRF_clearClockEnable(uint16_t mask, uint8_t entryNumber);
275 int8_t LRF_readRssi(void);
276 void LRF_setRawTxPower(uint32_t value, uint32_t temperatureCoefficient);
277 LRF_TxPowerTable_Entry LRF_getRawTxPower(void);
278 bool LRF_imagesNeedUpdate(const LRF_Config *lrfConfig);
279 
280 /**
281  * @brief Search for settings corresponding to the highest tx power lower than
282  * specified value in the tx power table
283  *
284  *  @param  table pointer to the tx power table to be searched
285  *  @param  powerLevel maximum allowed power level
286  *
287  *  @return Settings corresponding to a power level equal to or lower than requested
288  *  or LRF_TxPowerTable_INVALID_VALUE if no valid setting was found.
289  *
290  */
291 LRF_TxPowerTable_Entry LRF_TxPowerTable_findValue(const LRF_TxPowerTable *table, LRF_TxPowerTable_Index powerLevel);
292 
293 void LRF_rclEnableRadioClocks(void);
294 void LRF_rclDisableRadioClocks(void);
295 
LRF_enableHwInterrupt(uint32_t mask)296 static inline void LRF_enableHwInterrupt(uint32_t mask)
297 {
298     hal_enable_command_radio_interrupt(mask);
299 }
300 
LRF_disableHwInterrupt(uint32_t mask)301 static inline void LRF_disableHwInterrupt(uint32_t mask)
302 {
303     hal_disable_command_radio_interrupt(mask);
304 }
305 
LRF_clearHwInterrupt(uint32_t mask)306 static inline void LRF_clearHwInterrupt(uint32_t mask)
307 {
308     hal_clear_command_radio_interrupt(mask);
309 }
310 
311 extern uint32_t swParamList[];
312 extern const size_t swParamListSz;
313 
314 #endif
315