1 /******************************************************************************
2 * Filename: rfc.c
3 * Revised: 2018-08-08 11:04:37 +0200 (Wed, 08 Aug 2018)
4 * Revision: 52334
5 *
6 * Description: Driver for the RF Core.
7 *
8 * Copyright (c) 2015 - 2017, Texas Instruments Incorporated
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
13 *
14 * 1) Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 *
17 * 2) Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 *
21 * 3) Neither the name of the ORGANIZATION nor the names of its contributors may
22 * be used to endorse or promote products derived from this software without
23 * specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 ******************************************************************************/
38
39 #include "rfc.h"
40 #include "rf_mailbox.h"
41 #include <string.h>
42
43 //*****************************************************************************
44 //
45 // Handle support for DriverLib in ROM:
46 // This section will undo prototype renaming made in the header file
47 //
48 //*****************************************************************************
49 #if !defined(DOXYGEN)
50 #undef RFCCpeIntGetAndClear
51 #define RFCCpeIntGetAndClear NOROM_RFCCpeIntGetAndClear
52 #undef RFCDoorbellSendTo
53 #define RFCDoorbellSendTo NOROM_RFCDoorbellSendTo
54 #undef RFCSynthPowerDown
55 #define RFCSynthPowerDown NOROM_RFCSynthPowerDown
56 #undef RFCCpePatchReset
57 #define RFCCpePatchReset NOROM_RFCCpePatchReset
58 #undef RFCOverrideSearch
59 #define RFCOverrideSearch NOROM_RFCOverrideSearch
60 #undef RFCOverrideUpdate
61 #define RFCOverrideUpdate NOROM_RFCOverrideUpdate
62 #undef RFCHwIntGetAndClear
63 #define RFCHwIntGetAndClear NOROM_RFCHwIntGetAndClear
64 #undef RFCAnaDivTxOverride
65 #define RFCAnaDivTxOverride NOROM_RFCAnaDivTxOverride
66 #endif
67
68
69 //*****************************************************************************
70 //
71 // Get and clear CPE interrupt flags which match the provided bitmask
72 //
73 //*****************************************************************************
74 uint32_t
RFCCpeIntGetAndClear(uint32_t ui32Mask)75 RFCCpeIntGetAndClear(uint32_t ui32Mask)
76 {
77 // Read the CPE interrupt flags which match the provided bitmask
78 uint32_t ui32Ifg = HWREG(RFC_DBELL_BASE + RFC_DBELL_O_RFCPEIFG) & ui32Mask;
79
80 // Clear the interrupt flags
81 RFCCpeIntClear(ui32Ifg);
82
83 // Return with the interrupt flags
84 return (ui32Ifg);
85 }
86
87
88 //*****************************************************************************
89 //
90 // Send a radio operation to the doorbell and wait for an acknowledgement
91 //
92 //*****************************************************************************
93 uint32_t
RFCDoorbellSendTo(uint32_t pOp)94 RFCDoorbellSendTo(uint32_t pOp)
95 {
96 // Wait until the doorbell becomes available
97 while(HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDR) != 0);
98 RFCAckIntClear();
99
100 // Submit the command to the CM0 through the doorbell
101 HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDR) = pOp;
102
103 // Wait until the CM0 starts to parse the command
104 while(!HWREG(RFC_DBELL_BASE + RFC_DBELL_O_RFACKIFG));
105 RFCAckIntClear();
106
107 // Return with the content of status register
108 return(HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDSTA));
109 }
110
111
112 //*****************************************************************************
113 //
114 // Turn off the RF synthesizer. The radio will no longer respond to commands!
115 //
116 //*****************************************************************************
117 void
RFCSynthPowerDown(void)118 RFCSynthPowerDown(void)
119 {
120 // Definition of reserved words
121 const uint32_t RFC_RESERVED0 = 0x40046054;
122 const uint32_t RFC_RESERVED1 = 0x40046060;
123 const uint32_t RFC_RESERVED2 = 0x40046058;
124 const uint32_t RFC_RESERVED3 = 0x40044100;
125
126 // Disable CPE clock, enable FSCA clock.
127 HWREG(RFC_PWR_NONBUF_BASE + RFC_PWR_O_PWMCLKEN) = (HWREG(RFC_PWR_NONBUF_BASE + RFC_PWR_O_PWMCLKEN)
128 & ~RFC_PWR_PWMCLKEN_CPE_M) | RFC_PWR_PWMCLKEN_FSCA_M | RFC_PWR_PWMCLKEN_RFE_M;
129
130 HWREG(RFC_RESERVED0) = 3;
131 HWREG(RFC_RESERVED1) = 0x1030;
132 HWREG(RFC_RESERVED2) = 1;
133 HWREG(RFC_RESERVED1) = 0x50;
134 HWREG(RFC_RESERVED2) = 1;
135 HWREG(RFC_RESERVED1) = 0x650;
136 HWREG(RFC_RESERVED2) = 1;
137 HWREG(RFC_RESERVED1) = 0x10C0;
138 HWREG(RFC_RESERVED2) = 1;
139 HWREG(RFC_RESERVED3) = 1;
140 }
141
142
143 //*****************************************************************************
144 //
145 // Reset previously patched CPE RAM to a state where it can be patched again
146 //
147 //*****************************************************************************
148 void
RFCCpePatchReset(void)149 RFCCpePatchReset(void)
150 {
151 // Function is not complete
152 }
153
154
155 //*****************************************************************************
156 //
157 // Function to search an override list for the provided pattern within the search depth.
158 //
159 //*****************************************************************************
160 uint8_t
RFCOverrideSearch(const uint32_t * pOverride,const uint32_t pattern,const uint32_t mask,const uint8_t searchDepth)161 RFCOverrideSearch(const uint32_t *pOverride, const uint32_t pattern, const uint32_t mask, const uint8_t searchDepth)
162 {
163 // Search from start of the override list, to look for first override entry that matches search pattern
164 uint8_t override_index;
165 for(override_index = 0; (override_index < searchDepth) && (pOverride[override_index] != END_OVERRIDE); override_index++)
166 {
167 // Compare the value to the given pattern
168 if((pOverride[override_index] & mask) == pattern)
169 {
170 // Return with the index of override in case of match
171 return override_index;
172 }
173 }
174
175 // Return with an invalid index
176 return 0xFF;
177 }
178
179 //*****************************************************************************
180 //
181 // Function to calculate the proper override run-time for the High Gain PA.
182 //
183 //*****************************************************************************
184 uint32_t
RFCAnaDivTxOverride(uint8_t loDivider,uint8_t frontEndMode)185 RFCAnaDivTxOverride(uint8_t loDivider, uint8_t frontEndMode)
186 {
187 uint16_t fsOnly;
188 uint16_t txSetting;
189
190 switch (loDivider)
191 {
192 case 0: fsOnly = 0x0502;
193 break;
194 case 2:
195 fsOnly = 0x0102;
196 break;
197 case 4:
198 case 6:
199 case 12:
200 fsOnly = 0xF101;
201 break;
202 case 5:
203 case 10:
204 case 15:
205 case 30:
206 fsOnly = 0x1101;
207 break;
208 default:
209 // Error, should not occur!
210 fsOnly = 0;
211 break;
212 }
213
214 if (frontEndMode == 255)
215 {
216 // Special value meaning 20 dBm PA
217 txSetting = (fsOnly | 0x00C0) & ~0x0400;
218 }
219 else if (frontEndMode == 0)
220 {
221 // Differential
222 txSetting = fsOnly | 0x0030;
223 }
224 else if (frontEndMode & 1)
225 {
226 // Single ended on RFP
227 txSetting = fsOnly | 0x0010;
228 }
229 else
230 {
231 // Single ended on RFN
232 txSetting = fsOnly | 0x0020;
233 }
234
235 return ((((uint32_t) txSetting) << 16) | RFC_FE_OVERRIDE_ADDRESS);
236 }
237
238 //*****************************************************************************
239 //
240 // Update the override list based on values stored in FCFG1
241 //
242 //*****************************************************************************
243 uint8_t
RFCOverrideUpdate(rfc_radioOp_t * pOpSetup,uint32_t * pParams)244 RFCOverrideUpdate(rfc_radioOp_t *pOpSetup, uint32_t *pParams)
245 {
246 // Function is left blank for compatibility reasons.
247 return 0;
248 }
249
250
251 //*****************************************************************************
252 //
253 // Get and clear HW interrupt flags
254 //
255 //*****************************************************************************
256 uint32_t
RFCHwIntGetAndClear(uint32_t ui32Mask)257 RFCHwIntGetAndClear(uint32_t ui32Mask)
258 {
259 // Read the CPE interrupt flags which match the provided bitmask
260 uint32_t ui32Ifg = HWREG(RFC_DBELL_BASE + RFC_DBELL_O_RFHWIFG) & ui32Mask;
261
262 // Clear the interupt flags
263 RFCHwIntClear(ui32Ifg);
264
265 // Return with the interrupt flags
266 return (ui32Ifg);
267 }
268
269
270 //*****************************************************************************
271 //
272 // Handle support for DriverLib in ROM:
273 // This section will undo prototype renaming made in the header file
274 //
275 //*****************************************************************************
276 #if !defined(DOXYGEN)
277 #undef RFCCpeIntGetAndClear
278 #define RFCCpeIntGetAndClear NOROM_RFCCpeIntGetAndClear
279 #undef RFCDoorbellSendTo
280 #define RFCDoorbellSendTo NOROM_RFCDoorbellSendTo
281 #undef RFCSynthPowerDown
282 #define RFCSynthPowerDown NOROM_RFCSynthPowerDown
283 #undef RFCCpePatchReset
284 #define RFCCpePatchReset NOROM_RFCCpePatchReset
285 #undef RFCOverrideSearch
286 #define RFCOverrideSearch NOROM_RFCOverrideSearch
287 #undef RFCOverrideUpdate
288 #define RFCOverrideUpdate NOROM_RFCOverrideUpdate
289 #undef RFCHwIntGetAndClear
290 #define RFCHwIntGetAndClear NOROM_RFCHwIntGetAndClear
291 #undef RFCAnaDivTxOverride
292 #define RFCAnaDivTxOverride NOROM_RFCAnaDivTxOverride
293 #endif
294
295 // See rfc.h for implementation
296