CC13xx Driver Library
rfc.c
Go to the documentation of this file.
1 /******************************************************************************
2 * Filename: rfc.c
3 * Revised: 2016-04-07 15:04:05 +0200 (Thu, 07 Apr 2016)
4 * Revision: 46052
5 *
6 * Description: Driver for the RF Core.
7 *
8 * Copyright (c) 2015, 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 <driverlib/rfc.h>
40 
41 #define RFC_RESERVED0 0x40044108
42 #define RFC_RESERVED1 0x40044114
43 #define RFC_RESERVED2 0x4004410C
44 #define RFC_RESERVED3 0x40044100
45 
46 // Position of divider value
47 #define CONFIG_MISC_ADC_DIVIDER 27
48 #define CONFIG_MISC_ADC_DIVIDER_BM 0xF8000000U
49 
50 // RTrim positions
51 #define FCFG1_O_CONFIG_MISC_ADC_PO_TAIL_RES_TRIM_M 0x003C0000
52 #define FCFG1_O_CONFIG_MISC_ADC_PO_TAIL_RES_TRIM_S 18
53 #define FCFG1_O_CONFIG_MISC_ADC_DIV6_PO_TAIL_RES_TRIM_M 0x003C0000
54 #define FCFG1_O_CONFIG_MISC_ADC_DIV6_PO_TAIL_RES_TRIM_S 18
55 #define FCFG1_O_CONFIG_MISC_ADC_DIV10_PO_TAIL_RES_TRIM_M 0x003C0000
56 #define FCFG1_O_CONFIG_MISC_ADC_DIV10_PO_TAIL_RES_TRIM_S 18
57 #define FCFG1_O_CONFIG_MISC_ADC_DIV12_PO_TAIL_RES_TRIM_M 0x003C0000
58 #define FCFG1_O_CONFIG_MISC_ADC_DIV12_PO_TAIL_RES_TRIM_S 18
59 #define FCFG1_O_CONFIG_MISC_ADC_DIV15_PO_TAIL_RES_TRIM_M 0x003C0000
60 #define FCFG1_O_CONFIG_MISC_ADC_DIV15_PO_TAIL_RES_TRIM_S 18
61 #define FCFG1_O_CONFIG_MISC_ADC_DIV30_PO_TAIL_RES_TRIM_M 0x003C0000
62 #define FCFG1_O_CONFIG_MISC_ADC_DIV30_PO_TAIL_RES_TRIM_S 18
63 
64 //*****************************************************************************
65 //
66 // Get and clear CPE interrupt flags
67 //
68 //*****************************************************************************
69 uint32_t
71 {
72  uint32_t ui32Ifg = HWREG(RFC_DBELL_BASE+RFC_DBELL_O_RFCPEIFG);
73 
74  do {
75  HWREG(RFC_DBELL_BASE+RFC_DBELL_O_RFCPEIFG) = ~ui32Ifg;
76  } while (HWREG(RFC_DBELL_BASE+RFC_DBELL_O_RFCPEIFG) & ui32Ifg);
77 
78  return (ui32Ifg);
79 }
80 
81 
82 //*****************************************************************************
83 //
84 // Send command to doorbell and wait for ack
85 //
86 //*****************************************************************************
87 uint32_t
88 RFCDoorbellSendTo(uint32_t pOp)
89 {
90  while(HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDR) != 0);
91 
93 
94  HWREG(RFC_DBELL_BASE+RFC_DBELL_O_CMDR) = pOp;
95 
96  while(!HWREG(RFC_DBELL_BASE + RFC_DBELL_O_RFACKIFG));
98 
99  return(HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDSTA));
100 }
101 
102 
103 //*****************************************************************************
104 //
105 // Turn off synth, NOTE: Radio will no longer respond to commands!
106 //
107 //*****************************************************************************
108 void
110 {
111  // Disable CPE clock, enable FSCA clock. NOTE: Radio will no longer respond to commands!
112  HWREG(RFC_PWR_NONBUF_BASE + RFC_PWR_O_PWMCLKEN) = (HWREG(RFC_PWR_NONBUF_BASE + RFC_PWR_O_PWMCLKEN) & ~RFC_PWR_PWMCLKEN_CPE_M) | RFC_PWR_PWMCLKEN_FSCA_M;
113 
114  (*((volatile unsigned long *)(RFC_RESERVED0))) = 3;
115  (*((volatile unsigned long *)(RFC_RESERVED1))) = 0x1030;
116  (*((volatile unsigned long *)(RFC_RESERVED2))) = 1;
117  (*((volatile unsigned long *)(RFC_RESERVED1))) = 0x50;
118  (*((volatile unsigned long *)(RFC_RESERVED2))) = 1;
119  (*((volatile unsigned long *)(RFC_RESERVED1))) = 0x650;
120  (*((volatile unsigned long *)(RFC_RESERVED2))) = 1;
121  (*((volatile unsigned long *)(RFC_RESERVED3))) = 1;
122 }
123 
124 
125 //*****************************************************************************
126 //
127 // Read RF Trim from flash using the CM3
128 //
129 //*****************************************************************************
130 void RFCRfTrimRead(rfc_radioOp_t *pOpSetup, rfTrim_t* pRfTrim)
131 {
132  int divider;
133  // Check which setup command is used
134  switch (pOpSetup->commandNo)
135  {
136  case CMD_RADIO_SETUP:
137  divider = ((rfc_CMD_RADIO_SETUP_t *)pOpSetup)->loDivider;
138  break;
140  divider = ((rfc_CMD_PROP_RADIO_DIV_SETUP_t *)pOpSetup)->loDivider;
141  break;
142  default:
143  divider = 0; // Use 2.4 GHz
144  break;
145  }
146 
147  // Read trim from FCFG1
148  pRfTrim->configIfAdc = HWREG(FCFG1_BASE + FCFG1_O_CONFIG_IF_ADC);
149  switch (divider)
150  {
151  case 5:
156  break;
157 
158  case 6:
163  break;
164 
165  case 10:
170  break;
171 
172  case 12:
177  break;
178 
179  case 15:
184  break;
185 
186  case 30:
191  break;
192 
193  default:
195  pRfTrim->configSynth = HWREG(FCFG1_BASE + FCFG1_O_CONFIG_SYNTH);
196  // Make sure configMiscAdc is not 0 by setting an unused bit to 1
199  break;
200  }
201 }
202 
203 
204 //*****************************************************************************
205 //
206 // Check Override RTrim vs FCFG RTrim
207 //
208 //*****************************************************************************
209 void RFCRTrim(rfc_radioOp_t *pOpSetup)
210 {
211  int32_t divider;
212  uint32_t fcfg1_rtrim;
213  uint32_t *pOverride;
214  int32_t override_index;
215  uint32_t override_value;
216  uint32_t override_rtrim = 0;
217 
218  // Check which setup command is used
219  switch (pOpSetup->commandNo)
220  {
221  case CMD_RADIO_SETUP:
222  divider = ((rfc_CMD_RADIO_SETUP_t *)pOpSetup)->loDivider;
223  pOverride = ((rfc_CMD_RADIO_SETUP_t *)pOpSetup)->pRegOverride;
224  break;
226  divider = 2;
227  pOverride = ((rfc_CMD_PROP_RADIO_SETUP_t *)pOpSetup)->pRegOverride;
228  break;
230  divider = ((rfc_CMD_PROP_RADIO_DIV_SETUP_t *)pOpSetup)->loDivider;
231  pOverride = ((rfc_CMD_PROP_RADIO_DIV_SETUP_t *)pOpSetup)->pRegOverride;
232  break;
233  default:
234  return;
235  }
236 
237  if (pOverride == 0)
238  {
239  // Did not find override, return
240  return;
241  }
242 
243 
244  // Search top 5 overrides for RTRIM
245  for(override_index = 0; override_index < 5; override_index++)
246  {
247  override_value = pOverride[override_index];
248  if((override_value & 0xFFFF) == 0x4038)
249  {
250  override_rtrim = (override_value & 0xF0000) >> 16;
251  break;
252  }
253  }
254 
255  if (override_rtrim == 0)
256  {
257  // Did not find override, return
258  return;
259  }
260 
261  // Read trim from FCFG1
262  switch (divider)
263  {
264  case 2:
265  fcfg1_rtrim = (HWREG(FCFG1_BASE + FCFG1_O_CONFIG_MISC_ADC)
267  break;
268  case 5:
269  // Legacy
270  fcfg1_rtrim = (HWREG(FCFG1_BASE + FCFG1_O_MISC_OTP_DATA)
272  break;
273  case 6:
274  fcfg1_rtrim = (HWREG(FCFG1_BASE + FCFG1_O_CONFIG_MISC_ADC_DIV6)
276  break;
277  case 10:
278  fcfg1_rtrim = (HWREG(FCFG1_BASE + FCFG1_O_CONFIG_MISC_ADC_DIV10)
280  break;
281  case 12:
282  fcfg1_rtrim = (HWREG(FCFG1_BASE + FCFG1_O_CONFIG_MISC_ADC_DIV12)
284  break;
285  case 15:
286  fcfg1_rtrim = (HWREG(FCFG1_BASE + FCFG1_O_CONFIG_MISC_ADC_DIV15)
288  break;
289  case 30:
290  fcfg1_rtrim = (HWREG(FCFG1_BASE + FCFG1_O_CONFIG_MISC_ADC_DIV30)
292  break;
293  default:
294  fcfg1_rtrim = (HWREG(FCFG1_BASE + FCFG1_O_CONFIG_MISC_ADC)
296  break;
297  }
298 
299  // Check for early samples
300  if(fcfg1_rtrim == 0xF)
301  {
302  // set default
303  switch (divider)
304  {
305  case 5:
306  case 10:
307  case 15:
308  case 30:
309  pOverride[override_index] = (override_value & 0xFFF0FFFF) | (0x7 << 16);
310  break;
311  case 2:
312  case 6:
313  case 12:
314  default:
315  pOverride[override_index] = (override_value & 0xFFF0FFFF) | (0x4 << 16);
316  break;
317  }
318  }
319  else
320  {
321  // Test Override vs FCFG1 limit.
322  if(override_rtrim >= fcfg1_rtrim)
323  {
324  // Do nothing
325  ;
326  }
327  else
328  {
329  // Set override to FCFG1 limit value
330  pOverride[override_index] = (override_value & 0xFFF0FFFF) | (fcfg1_rtrim << 16);
331  }
332  }
333 }
334 
335 
336 //*****************************************************************************
337 //
338 // Write preloaded RF trim values to CM0
339 //
340 //*****************************************************************************
341 void RFCRfTrimSet(rfTrim_t* pRfTrim)
342 {
343  memcpy((void*)&HWREG(0x21000018), (void*)pRfTrim, sizeof(rfTrim_t));
344 }
345 
346 
347 //*****************************************************************************
348 //
349 // Handle support for DriverLib in ROM:
350 // This section will undo prototype renaming made in the header file
351 //
352 //*****************************************************************************
353 #if !defined(DOXYGEN)
354  #undef RFCCpeIntGetAndClear
355  #define RFCCpeIntGetAndClear NOROM_RFCCpeIntGetAndClear
356  #undef RFCDoorbellSendTo
357  #define RFCDoorbellSendTo NOROM_RFCDoorbellSendTo
358  #undef RFCSynthPowerDown
359  #define RFCSynthPowerDown NOROM_RFCSynthPowerDown
360  #undef RFCRfTrimRead
361  #define RFCRfTrimRead NOROM_RFCRfTrimRead
362  #undef RFCRfTrimSet
363  #define RFCRfTrimSet NOROM_RFCRfTrimSet
364  #undef RFCRTrim
365  #define RFCRTrim NOROM_RFCRTrim
366 #endif
367 
368 // See rfc.h for implementation
#define RFC_RESERVED0
Definition: rfc.c:41
uint32_t configSynth
Definition: rfc.h:73
#define FCFG1_O_CONFIG_MISC_ADC_DIV15_PO_TAIL_RES_TRIM_S
Definition: rfc.c:60
#define FCFG1_O_CONFIG_MISC_ADC_DIV10_PO_TAIL_RES_TRIM_M
Definition: rfc.c:55
#define CMD_PROP_RADIO_SETUP
Definition: rf_prop_cmd.h:442
#define FCFG1_O_CONFIG_MISC_ADC_DIV12_PO_TAIL_RES_TRIM_M
Definition: rfc.c:57
struct __RFC_STRUCT rfc_CMD_PROP_RADIO_DIV_SETUP_s rfc_CMD_PROP_RADIO_DIV_SETUP_t
Definition: rf_prop_cmd.h:67
struct __RFC_STRUCT rfc_CMD_RADIO_SETUP_s rfc_CMD_RADIO_SETUP_t
Definition: rf_common_cmd.h:62
#define CMD_PROP_RADIO_DIV_SETUP
Definition: rf_prop_cmd.h:530
struct __RFC_STRUCT rfc_radioOp_s rfc_radioOp_t
Definition: rf_common_cmd.h:60
#define CONFIG_MISC_ADC_DIVIDER_BM
Definition: rfc.c:48
#define FCFG1_O_CONFIG_MISC_ADC_DIV10_PO_TAIL_RES_TRIM_S
Definition: rfc.c:56
void RFCRfTrimSet(rfTrim_t *pRfTrim)
Write preloaded RF trim values to CM0.
Definition: rfc.c:341
static void RFCAckIntClear(void)
Clear interrupt flags.
Definition: rfc.h:314
#define FCFG1_O_CONFIG_MISC_ADC_PO_TAIL_RES_TRIM_M
Definition: rfc.c:51
Definition: rfc.h:70
uint32_t RFCCpeIntGetAndClear(void)
Get and clear CPE interrupt flags.
Definition: rfc.c:70
#define CONFIG_MISC_ADC_DIVIDER
Definition: rfc.c:47
#define RFC_RESERVED3
Definition: rfc.c:44
struct __RFC_STRUCT rfc_CMD_PROP_RADIO_SETUP_s rfc_CMD_PROP_RADIO_SETUP_t
Definition: rf_prop_cmd.h:66
uint32_t configMiscAdc
Definition: rfc.h:74
#define RFC_RESERVED2
Definition: rfc.c:43
void RFCRTrim(rfc_radioOp_t *pOpSetup)
Check Override RTrim vs FCFG RTrim.
Definition: rfc.c:209
uint32_t configRfFrontend
Definition: rfc.h:72
#define CMD_RADIO_SETUP
#define FCFG1_O_CONFIG_MISC_ADC_DIV12_PO_TAIL_RES_TRIM_S
Definition: rfc.c:58
uint32_t configIfAdc
Definition: rfc.h:71
#define FCFG1_O_CONFIG_MISC_ADC_DIV30_PO_TAIL_RES_TRIM_M
Definition: rfc.c:61
uint32_t RFCDoorbellSendTo(uint32_t pOp)
Send command to doorbell and wait for ack.
Definition: rfc.c:88
#define FCFG1_O_CONFIG_MISC_ADC_PO_TAIL_RES_TRIM_S
Definition: rfc.c:52
#define FCFG1_O_CONFIG_MISC_ADC_DIV30_PO_TAIL_RES_TRIM_S
Definition: rfc.c:62
void RFCRfTrimRead(rfc_radioOp_t *pOpSetup, rfTrim_t *pRfTrim)
Read RF trim from flash using CM3.
Definition: rfc.c:130
#define FCFG1_O_CONFIG_MISC_ADC_DIV6_PO_TAIL_RES_TRIM_M
Definition: rfc.c:53
void RFCSynthPowerDown()
Turn off synth, NOTE: Radio will no longer respond to commands!
Definition: rfc.c:109
#define FCFG1_O_CONFIG_MISC_ADC_DIV6_PO_TAIL_RES_TRIM_S
Definition: rfc.c:54
#define FCFG1_O_CONFIG_MISC_ADC_DIV15_PO_TAIL_RES_TRIM_M
Definition: rfc.c:59
#define RFC_RESERVED1
Definition: rfc.c:42