CC13xx Driver Library
osc.c
Go to the documentation of this file.
1 /******************************************************************************
2 * Filename: osc.c
3 * Revised: 2015-06-19 19:26:38 +0200 (Fri, 19 Jun 2015)
4 * Revision: 44012
5 *
6 * Description: Driver for setting up the system Oscillators
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 <inc/hw_types.h>
40 #include <inc/hw_ccfg.h>
41 #include <driverlib/aon_batmon.h>
42 #include <driverlib/aon_rtc.h>
43 #include <driverlib/osc.h>
44 
45 //*****************************************************************************
46 //
47 // Handle support for DriverLib in ROM:
48 // This section will undo prototype renaming made in the header file
49 //
50 //*****************************************************************************
51 #if !defined(DOXYGEN)
52  #undef OSCClockSourceSet
53  #define OSCClockSourceSet NOROM_OSCClockSourceSet
54  #undef OSCClockSourceGet
55  #define OSCClockSourceGet NOROM_OSCClockSourceGet
56  #undef OSCInterfaceEnable
57  #define OSCInterfaceEnable NOROM_OSCInterfaceEnable
58 #endif
59 
60 //*****************************************************************************
61 //
62 // OSCHF switch time calculator defines and globals
63 //
64 //*****************************************************************************
65 
66 #define RTC_CV_TO_MS(x) (( 1000 * ( x )) >> 16 )
67 #define RTC_CV_TO_US(x) (( 1000000 * ( x )) >> 16 )
68 
69 typedef struct {
71  uint32_t timeXoscOff_CV ;
72  uint32_t timeXoscOn_CV ;
73  uint32_t timeXoscStable_CV ;
74  int32_t tempXoscOff ;
76 
78 
79 //*****************************************************************************
80 //
82 //
83 //*****************************************************************************
84 void
85 OSCClockSourceSet(uint32_t ui32SrcClk, uint32_t ui32Osc)
86 {
87  //
88  // Check the arguments.
89  //
90  ASSERT((ui32SrcClk & OSC_SRC_CLK_LF) ||
91  (ui32SrcClk & OSC_SRC_CLK_MF) ||
92  (ui32SrcClk & OSC_SRC_CLK_HF));
93  ASSERT((ui32Osc == OSC_RCOSC_HF) ||
94  (ui32Osc == OSC_RCOSC_LF) ||
95  (ui32Osc == OSC_XOSC_HF) ||
96  (ui32Osc == OSC_XOSC_LF));
97 
98  //
99  // Request the high frequency source clock (using 24 MHz XTAL)
100  //
101  if(ui32SrcClk & OSC_SRC_CLK_HF)
102  {
103  //
104  // Enable the HF XTAL as HF clock source
105  //
109  ui32Osc);
110  }
111 
112  //
113  // Configure the medium frequency source clock
114  //
115  if(ui32SrcClk & OSC_SRC_CLK_MF)
116  {
120  ui32Osc);
121  }
122 
123  //
124  // Configure the low frequency source clock.
125  //
126  if(ui32SrcClk & OSC_SRC_CLK_LF)
127  {
128  //
129  // Change the clock source.
130  //
134  ui32Osc);
135  }
136 }
137 
138 //*****************************************************************************
139 //
141 //
142 //*****************************************************************************
143 uint32_t
144 OSCClockSourceGet(uint32_t ui32SrcClk)
145 {
146  uint32_t ui32ClockSource;
147 
148  //
149  // Check the arguments.
150  //
151  ASSERT((ui32SrcClk & OSC_SRC_CLK_LF) ||
152  (ui32SrcClk & OSC_SRC_CLK_HF));
153 
154  //
155  // Return the source for the selected clock.
156  //
157  if(ui32SrcClk == OSC_SRC_CLK_LF)
158  {
162  }
163  else
164  {
168  }
169  return (ui32ClockSource);
170 }
171 
172 //*****************************************************************************
173 //
175 //
176 //*****************************************************************************
177 void
179 {
180  //
181  // Force power on AUX to ensure CPU has access
182  //
185  { }
186 
187  //
188  // Enable the AUX domain OSC clock and wait for it to be ready
189  //
192  { }
193 }
194 
195 
196 //*****************************************************************************
197 //
198 // Returns maximum startup time (in microseconds) of XOSC_HF
199 //
200 //*****************************************************************************
201 uint32_t
202 OSCHF_GetStartupTime( uint32_t timeUntilWakeupInMs )
203 {
204  uint32_t deltaTimeSinceXoscOnInMs ;
205  int32_t deltaTempSinceXoscOn ;
206  uint32_t newStartupTimeInUs ;
207 
208  deltaTimeSinceXoscOnInMs = RTC_CV_TO_MS( AONRTCCurrentCompareValueGet() - oscHfGlobals.timeXoscOn_CV );
209  deltaTempSinceXoscOn = AONBatMonTemperatureGetDegC() - oscHfGlobals.tempXoscOff;
210 
211  if ( deltaTempSinceXoscOn < 0 ) {
212  deltaTempSinceXoscOn = -deltaTempSinceXoscOn;
213  }
214 
215  if ( (( timeUntilWakeupInMs + deltaTimeSinceXoscOnInMs ) > 3000 ) ||
216  ( deltaTempSinceXoscOn > 5 ) ||
217  ( oscHfGlobals.timeXoscStable_CV < oscHfGlobals.timeXoscOn_CV ) ||
218  ( oscHfGlobals.previousStartupTimeInUs == 0 ) )
219  {
220  newStartupTimeInUs = 2000;
222  newStartupTimeInUs = (( HWREG( CCFG_BASE + CCFG_O_MODE_CONF_1 ) &
225  // Note: CCFG startup time is "in units of 100us" adding 25% margin results in *125
226  }
227  } else {
228  newStartupTimeInUs = RTC_CV_TO_US( oscHfGlobals.timeXoscStable_CV - oscHfGlobals.timeXoscOn_CV );
229  newStartupTimeInUs += ( newStartupTimeInUs >> 2 ); // Add 25 percent margin
230  if ( newStartupTimeInUs < oscHfGlobals.previousStartupTimeInUs ) {
231  newStartupTimeInUs = oscHfGlobals.previousStartupTimeInUs;
232  }
233  }
234 
235  if ( newStartupTimeInUs < 200 ) {
236  newStartupTimeInUs = 200;
237  }
238  if ( newStartupTimeInUs > 4000 ) {
239  newStartupTimeInUs = 4000;
240  }
241  return ( newStartupTimeInUs );
242 }
243 
244 
245 //*****************************************************************************
246 //
247 // Turns on XOSC_HF (but without switching to XOSC_HF)
248 //
249 //*****************************************************************************
250 void
252 {
255 }
256 
257 
258 //*****************************************************************************
259 //
260 // Switch to XOSC_HF if XOSC_HF is ready.
261 //
262 //*****************************************************************************
263 bool
265 {
266  uint32_t startupTimeInUs;
267  uint32_t prevLimmit25InUs;
268 
270  // Already on XOSC - nothing to do
271  return ( 1 );
272  }
273  if ( OSCHfSourceReady()) {
275 
276  //
277  // Store startup time, but limit to 25 percent reduction each time.
278  //
280  startupTimeInUs = RTC_CV_TO_US( oscHfGlobals.timeXoscStable_CV - oscHfGlobals.timeXoscOn_CV );
281  prevLimmit25InUs = oscHfGlobals.previousStartupTimeInUs;
282  prevLimmit25InUs -= ( prevLimmit25InUs >> 2 ); // 25 percent margin
283  oscHfGlobals.previousStartupTimeInUs = startupTimeInUs;
284  if ( prevLimmit25InUs > startupTimeInUs ) {
285  oscHfGlobals.previousStartupTimeInUs = prevLimmit25InUs;
286  }
287  return ( 1 );
288  }
289  return ( 0 );
290 }
291 
292 
293 //*****************************************************************************
294 //
295 // Switch to RCOSC_HF and turn off XOSC_HF
296 //
297 //*****************************************************************************
298 void
300 {
301  //
302  // Set SCLK_HF and SCLK_MF to RCOSC_HF without checking
303  // Doing this anyway to keep HF and MF in sync
304  //
306 
307  //
308  // Do the switching if not already running on RCOSC_HF
309  //
312  }
313 
315  oscHfGlobals.tempXoscOff = AONBatMonTemperatureGetDegC();
316 }
static void AONWUCAuxWakeupEvent(uint32_t ui32Mode)
Control the wake up procedure of the AUX domain.
Definition: aon_wuc.h:476
static uint32_t AONWUCPowerStatusGet(void)
Get the power status of the device.
Definition: aon_wuc.h:556
static void OSCHfSourceSwitch(void)
Switch the high frequency clock.
Definition: osc.h:314
void AUXWUCClockEnable(uint32_t ui32Clocks)
Enable clocks for peripherals in the AUX domain.
Definition: aux_wuc.c:64
#define OSC_SRC_CLK_MF
Definition: osc.h:107
#define AUX_WUC_OSCCTRL_CLOCK
Definition: aux_wuc.h:109
uint32_t timeXoscOff_CV
Definition: osc.c:71
uint32_t AUXWUCClockStatus(uint32_t ui32Clocks)
Get the status of a clock.
Definition: aux_wuc.c:162
uint32_t timeXoscStable_CV
Definition: osc.c:73
int32_t AONBatMonTemperatureGetDegC(void)
Get the current temperature measurement as a signed value in Deg Celsius.
Definition: aon_batmon.c:54
uint32_t OSCClockSourceGet(uint32_t ui32SrcClk)
Get the source clock settings.
Definition: osc.c:144
#define AUX_WUC_CLOCK_READY
Definition: aux_wuc.h:119
void DDI16BitfieldWrite(uint32_t ui32Base, uint32_t ui32Reg, uint32_t ui32Mask, uint32_t ui32Shift, uint16_t ui32Data)
Write a bitfield via the DDI using 16-bit maskable write.
Definition: ddi.c:108
void OSCInterfaceEnable(void)
Enable System CPU access to the OSC_DIG module.
Definition: osc.c:178
uint32_t OSCHF_GetStartupTime(uint32_t timeUntilWakeupInMs)
Returns maximum startup time (in microseconds) of XOSC_HF.
Definition: osc.c:202
#define AONWUC_AUX_POWER_ON
Definition: aon_wuc.h:172
#define OSC_SRC_CLK_HF
Definition: osc.h:106
bool OSCHF_AttemptToSwitchToXosc(void)
Switch to XOSC_HF if XOSC_HF is ready.
Definition: osc.c:264
#define OSC_RCOSC_HF
Definition: osc.h:110
static bool OSCHfSourceReady(void)
Check if the HF clock source is ready to be switched.
Definition: osc.h:284
#define OSC_XOSC_HF
Definition: osc.h:111
#define AONWUC_AUX_WAKEUP
Definition: aon_wuc.h:152
#define OSC_SRC_CLK_LF
Definition: osc.h:108
uint32_t previousStartupTimeInUs
Definition: osc.c:70
uint16_t DDI16BitfieldRead(uint32_t ui32Base, uint32_t ui32Reg, uint32_t ui32Mask, uint32_t ui32Shift)
Read a bitfield via the DDI using 16-bit read.
Definition: ddi.c:198
static OscHfGlobals_t oscHfGlobals
Definition: osc.c:77
#define ASSERT(expr)
Definition: debug.h:74
#define OSC_RCOSC_LF
Definition: osc.h:112
int32_t tempXoscOff
Definition: osc.c:74
void OSCHF_SwitchToRcOscTurnOffXosc(void)
Switch to RCOSC_HF and turn off XOSC_HF.
Definition: osc.c:299
uint32_t timeXoscOn_CV
Definition: osc.c:72
#define RTC_CV_TO_US(x)
Definition: osc.c:67
uint32_t AONRTCCurrentCompareValueGet(void)
Get the current value of the RTC counter in a format that matches RTC compare values.
Definition: aon_rtc.c:62
void OSCClockSourceSet(uint32_t ui32SrcClk, uint32_t ui32Osc)
Configure the oscillator input to the a source clock.
Definition: osc.c:85
void OSCHF_TurnOnXosc(void)
Turns on XOSC_HF (but without switching to XOSC_HF).
Definition: osc.c:251
#define OSC_XOSC_LF
Definition: osc.h:113
#define RTC_CV_TO_MS(x)
Definition: osc.c:66