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