1 /******************************************************************************
2 * Filename: setup.c
3 * Revised: 2020-12-11 09:58:05 +0100 (Fri, 11 Dec 2020)
4 * Revision: 59848
5 *
6 * Description: Setup file for CC13xx/CC26xx devices.
7 *
8 * Copyright (c) 2015 - 2020, 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 // Hardware headers
40 #include "../inc/hw_types.h"
41 #include "../inc/hw_memmap.h"
42 #include "../inc/hw_adi.h"
43 #include "../inc/hw_adi_2_refsys.h"
44 #include "../inc/hw_adi_3_refsys.h"
45 #include "../inc/hw_adi_4_aux.h"
46 // Temporarily adding these defines as they are missing in hw_adi_4_aux.h
47 #define ADI_4_AUX_O_LPMBIAS 0x0000000E
48 #define ADI_4_AUX_LPMBIAS_LPM_TRIM_IOUT_M 0x0000003F
49 #define ADI_4_AUX_LPMBIAS_LPM_TRIM_IOUT_S 0
50 #define ADI_4_AUX_COMP_LPM_BIAS_WIDTH_TRIM_M 0x00000038
51 #define ADI_4_AUX_COMP_LPM_BIAS_WIDTH_TRIM_S 3
52 #include "../inc/hw_aon_ioc.h"
53 #include "../inc/hw_aon_pmctl.h"
54 #include "../inc/hw_aon_rtc.h"
55 #include "../inc/hw_ddi_0_osc.h"
56 #include "../inc/hw_ddi.h"
57 #include "../inc/hw_ccfg.h"
58 #include "../inc/hw_fcfg1.h"
59 #include "../inc/hw_flash.h"
60 #include "../inc/hw_prcm.h"
61 #include "../inc/hw_vims.h"
62 // Driverlib headers
63 #include "aux_sysif.h"
64 #include "chipinfo.h"
65 #include "setup.h"
66 #include "setup_rom.h"
67
68 //*****************************************************************************
69 //
70 // Handle support for DriverLib in ROM:
71 // This section will undo prototype renaming made in the header file
72 //
73 //*****************************************************************************
74 #if !defined(DOXYGEN)
75 #undef SetupTrimDevice
76 #define SetupTrimDevice NOROM_SetupTrimDevice
77 #endif
78
79
80
81 //*****************************************************************************
82 //
83 // Defined CPU delay macro with microseconds as input
84 // Quick check shows: (To be further investigated)
85 // At 48 MHz RCOSC and VIMS.CONTROL.PREFETCH = 0, there is 5 cycles
86 // At 48 MHz RCOSC and VIMS.CONTROL.PREFETCH = 1, there is 4 cycles
87 // At 24 MHz RCOSC and VIMS.CONTROL.PREFETCH = 0, there is 3 cycles
88 //
89 //*****************************************************************************
90 #define CPU_DELAY_MICRO_SECONDS( x ) \
91 CPUdelay(((uint32_t)((( x ) * 48.0 ) / 5.0 )) - 1 )
92
93
94 //*****************************************************************************
95 //
96 // Function declarations
97 //
98 //*****************************************************************************
99 static void TrimAfterColdReset( void );
100 static void TrimAfterColdResetWakeupFromShutDown( uint32_t ui32Fcfg1Revision );
101 static void TrimAfterColdResetWakeupFromShutDownWakeupFromPowerDown( void );
102
103 //*****************************************************************************
104 //
105 // Perform the necessary trim of the device which is not done in boot code
106 //
107 // This function should only execute coming from ROM boot. The current
108 // implementation does not take soft reset into account. However, it does no
109 // damage to execute it again. It only consumes time.
110 //
111 //*****************************************************************************
112 void
SetupTrimDevice(void)113 SetupTrimDevice(void)
114 {
115 uint32_t ui32Fcfg1Revision;
116 uint32_t ui32AonSysResetctl;
117
118 // Get layout revision of the factory configuration area
119 // (Handle undefined revision as revision = 0)
120 ui32Fcfg1Revision = HWREG(FCFG1_BASE + FCFG1_O_FCFG1_REVISION);
121 if ( ui32Fcfg1Revision == 0xFFFFFFFF ) {
122 ui32Fcfg1Revision = 0;
123 }
124
125 // This driverlib version and setup file is for the CC13x2, CC26x2 PG2.0 or later chips.
126 // Halt if violated
127 ThisLibraryIsFor_CC13x2_CC26x2_HwRev20AndLater_HaltIfViolated();
128
129 // Enable standby in flash bank
130 HWREGBITW( FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
131
132 // Select correct CACHE mode and set correct CACHE configuration
133 #if ( CCFG_BASE == CCFG_BASE_DEFAULT )
134 SetupSetCacheModeAccordingToCcfgSetting();
135 #else
136 NOROM_SetupSetCacheModeAccordingToCcfgSetting();
137 #endif
138
139 // 1. Check for powerdown
140 // 2. Check for shutdown
141 // 3. Assume cold reset if none of the above.
142 //
143 // It is always assumed that the application will freeze the latches in
144 // AON_IOC when going to powerdown in order to retain the values on the IOs.
145 //
146 // NB. If this bit is not cleared before proceeding to powerdown, the IOs
147 // will all default to the reset configuration when restarting.
148 if( ! ( HWREGBITW( AON_IOC_BASE + AON_IOC_O_IOCLATCH, AON_IOC_IOCLATCH_EN_BITN )))
149 {
150 // NB. This should be calling a ROM implementation of required trim and
151 // compensation
152 // e.g. TrimAfterColdResetWakeupFromShutDownWakeupFromPowerDown()
153 TrimAfterColdResetWakeupFromShutDownWakeupFromPowerDown();
154 }
155 // Check for shutdown
156 //
157 // When device is going to shutdown the hardware will automatically clear
158 // the SLEEPDIS bit in the SLEEP register in the AON_PMCTL module.
159 // It is left for the application to assert this bit when waking back up,
160 // but not before the desired IO configuration has been re-established.
161 else if( ! ( HWREGBITW( AON_PMCTL_BASE + AON_PMCTL_O_SLEEPCTL, AON_PMCTL_SLEEPCTL_IO_PAD_SLEEP_DIS_BITN )))
162 {
163 // NB. This should be calling a ROM implementation of required trim and
164 // compensation
165 // e.g. TrimAfterColdResetWakeupFromShutDown() -->
166 // TrimAfterColdResetWakeupFromShutDownWakeupFromPowerDown();
167 TrimAfterColdResetWakeupFromShutDown(ui32Fcfg1Revision);
168 TrimAfterColdResetWakeupFromShutDownWakeupFromPowerDown();
169 }
170 else
171 {
172 // Consider adding a check for soft reset to allow debugging to skip
173 // this section!!!
174 //
175 // NB. This should be calling a ROM implementation of required trim and
176 // compensation
177 // e.g. TrimAfterColdReset() -->
178 // TrimAfterColdResetWakeupFromShutDown() -->
179 // TrimAfterColdResetWakeupFromShutDownWakeupFromPowerDown()
180 TrimAfterColdReset();
181 TrimAfterColdResetWakeupFromShutDown(ui32Fcfg1Revision);
182 TrimAfterColdResetWakeupFromShutDownWakeupFromPowerDown();
183
184 }
185
186 // Set VIMS power domain control.
187 // PDCTL1VIMS = 0 ==> VIMS power domain is only powered when CPU power domain is powered
188 HWREG( PRCM_BASE + PRCM_O_PDCTL1VIMS ) = 0;
189
190 // Configure optimal wait time for flash FSM in cases where flash pump
191 // wakes up from sleep
192 HWREG(FLASH_BASE + FLASH_O_FPAC1) = (HWREG(FLASH_BASE + FLASH_O_FPAC1) &
193 ~FLASH_FPAC1_PSLEEPTDIS_M) |
194 (0x139<<FLASH_FPAC1_PSLEEPTDIS_S);
195
196 // And finally at the end of the flash boot process:
197 // SET BOOT_DET bits in AON_PMCTL to 3 if already found to be 1
198 // Note: The BOOT_DET_x_CLR/SET bits must be manually cleared
199 if ((( HWREG( AON_PMCTL_BASE + AON_PMCTL_O_RESETCTL ) &
200 ( AON_PMCTL_RESETCTL_BOOT_DET_1_M | AON_PMCTL_RESETCTL_BOOT_DET_0_M )) >>
201 AON_PMCTL_RESETCTL_BOOT_DET_0_S ) == 1 )
202 {
203 ui32AonSysResetctl = ( HWREG( AON_PMCTL_BASE + AON_PMCTL_O_RESETCTL ) &
204 ~( AON_PMCTL_RESETCTL_BOOT_DET_1_CLR_M | AON_PMCTL_RESETCTL_BOOT_DET_0_CLR_M |
205 AON_PMCTL_RESETCTL_BOOT_DET_1_SET_M | AON_PMCTL_RESETCTL_BOOT_DET_0_SET_M | AON_PMCTL_RESETCTL_MCU_WARM_RESET_M ));
206 HWREG( AON_PMCTL_BASE + AON_PMCTL_O_RESETCTL ) = ui32AonSysResetctl | AON_PMCTL_RESETCTL_BOOT_DET_1_SET_M;
207 HWREG( AON_PMCTL_BASE + AON_PMCTL_O_RESETCTL ) = ui32AonSysResetctl;
208 }
209
210 // Make sure there are no ongoing VIMS mode change when leaving SetupTrimDevice()
211 // (There should typically be no wait time here, but need to be sure)
212 while ( HWREGBITW( VIMS_BASE + VIMS_O_STAT, VIMS_STAT_MODE_CHANGING_BITN )) {
213 // Do nothing - wait for an eventual ongoing mode change to complete.
214 }
215 }
216
217 //*****************************************************************************
218 //
219 //! \brief Trims to be applied when coming from POWER_DOWN (also called when
220 //! coming from SHUTDOWN and PIN_RESET).
221 //!
222 //! \return None
223 //
224 //*****************************************************************************
225 static void
TrimAfterColdResetWakeupFromShutDownWakeupFromPowerDown(void)226 TrimAfterColdResetWakeupFromShutDownWakeupFromPowerDown( void )
227 {
228 // Currently no specific trim for Powerdown
229 }
230
231 //*****************************************************************************
232 //
233 //! \brief Trims to be applied when coming from SHUTDOWN (also called when
234 //! coming from PIN_RESET).
235 //!
236 //! \param ui32Fcfg1Revision
237 //!
238 //! \return None
239 //
240 //*****************************************************************************
241 static void
TrimAfterColdResetWakeupFromShutDown(uint32_t ui32Fcfg1Revision)242 TrimAfterColdResetWakeupFromShutDown(uint32_t ui32Fcfg1Revision)
243 {
244 uint32_t ccfg_ModeConfReg ;
245
246 // Check in CCFG for alternative DCDC setting
247 if (( HWREG( CCFG_BASE + CCFG_O_SIZE_AND_DIS_FLAGS ) & CCFG_SIZE_AND_DIS_FLAGS_DIS_ALT_DCDC_SETTING ) == 0 ) {
248 // ADI_3_REFSYS:DCDCCTL5[3] (=DITHER_EN) = CCFG_MODE_CONF_1[19] (=ALT_DCDC_DITHER_EN)
249 // ADI_3_REFSYS:DCDCCTL5[2:0](=IPEAK ) = CCFG_MODE_CONF_1[18:16](=ALT_DCDC_IPEAK )
250 // Using a single 4-bit masked write since layout is equal for both source and destination
251 HWREGB( ADI3_BASE + ADI_O_MASK4B + ( ADI_3_REFSYS_O_DCDCCTL5 * 2 )) = ( 0xF0 |
252 ( HWREG( CCFG_BASE + CCFG_O_MODE_CONF_1 ) >> CCFG_MODE_CONF_1_ALT_DCDC_IPEAK_S ));
253
254 }
255
256 // TBD - Temporarily removed for CC13x2 / CC26x2
257
258 // Force DCDC to use RCOSC before starting up XOSC.
259 // Clock loss detector does not use XOSC until SCLK_HF actually switches
260 // and thus DCDC is not protected from clock loss on XOSC in that time frame.
261 // The force must be released when the switch to XOSC has happened. This is done
262 // in OSCHfSourceSwitch().
263 HWREG(AUX_DDI0_OSC_BASE + DDI_O_MASK16B + (DDI_0_OSC_O_CTL0 << 1) + 4) = DDI_0_OSC_CTL0_CLK_DCDC_SRC_SEL_M | (DDI_0_OSC_CTL0_CLK_DCDC_SRC_SEL_M >> 16);
264 // Dummy read to ensure that the write has propagated
265 HWREGH(AUX_DDI0_OSC_BASE + DDI_0_OSC_O_CTL0);
266
267 // read the MODE_CONF register in CCFG
268 ccfg_ModeConfReg = HWREG( CCFG_BASE + CCFG_O_MODE_CONF );
269
270 // First part of trim done after cold reset and wakeup from shutdown:
271 // -Adjust the VDDR_TRIM_SLEEP value.
272 // -Configure DCDC.
273 SetupAfterColdResetWakeupFromShutDownCfg1( ccfg_ModeConfReg );
274
275 // Addition to the CC1352 boost mode for HWREV >= 2.0
276 // The combination VDDR_EXT_LOAD=0 and VDDS_BOD_LEVEL=1 is defined to select boost mode
277 if ((( ccfg_ModeConfReg & CCFG_MODE_CONF_VDDR_EXT_LOAD ) == 0 ) &&
278 (( ccfg_ModeConfReg & CCFG_MODE_CONF_VDDS_BOD_LEVEL ) != 0 ) )
279 {
280 HWREGB( ADI3_BASE + ADI_3_REFSYS_O_DCDCCTL3 ) = ADI_3_REFSYS_DCDCCTL3_VDDR_BOOST_COMP_BOOST ;
281 }
282
283 // Second part of trim done after cold reset and wakeup from shutdown:
284 // -Configure XOSC.
285 #if ( CCFG_BASE == CCFG_BASE_DEFAULT )
286 SetupAfterColdResetWakeupFromShutDownCfg2( ui32Fcfg1Revision, ccfg_ModeConfReg );
287 #else
288 NOROM_SetupAfterColdResetWakeupFromShutDownCfg2( ui32Fcfg1Revision, ccfg_ModeConfReg );
289 #endif
290
291 {
292 uint32_t trimReg ;
293 uint32_t ui32TrimValue ;
294
295 //--- Propagate the LPM_BIAS trim ---
296 trimReg = HWREG( FCFG1_BASE + FCFG1_O_DAC_BIAS_CNF );
297 ui32TrimValue = (( trimReg & FCFG1_DAC_BIAS_CNF_LPM_TRIM_IOUT_M ) >>
298 FCFG1_DAC_BIAS_CNF_LPM_TRIM_IOUT_S ) ;
299 HWREGB( AUX_ADI4_BASE + ADI_4_AUX_O_LPMBIAS ) = (( ui32TrimValue << ADI_4_AUX_LPMBIAS_LPM_TRIM_IOUT_S ) &
300 ADI_4_AUX_LPMBIAS_LPM_TRIM_IOUT_M ) ;
301 // Set LPM_BIAS_BACKUP_EN according to FCFG1 configuration
302 if ( trimReg & FCFG1_DAC_BIAS_CNF_LPM_BIAS_BACKUP_EN ) {
303 HWREGB( ADI3_BASE + ADI_O_SET + ADI_3_REFSYS_O_AUX_DEBUG ) = ADI_3_REFSYS_AUX_DEBUG_LPM_BIAS_BACKUP_EN;
304 } else {
305 HWREGB( ADI3_BASE + ADI_O_CLR + ADI_3_REFSYS_O_AUX_DEBUG ) = ADI_3_REFSYS_AUX_DEBUG_LPM_BIAS_BACKUP_EN;
306 }
307 // Set LPM_BIAS_WIDTH_TRIM according to FCFG1 configuration
308 {
309 uint32_t widthTrim = (( trimReg & FCFG1_DAC_BIAS_CNF_LPM_BIAS_WIDTH_TRIM_M ) >> FCFG1_DAC_BIAS_CNF_LPM_BIAS_WIDTH_TRIM_S );
310 HWREGH( AUX_ADI4_BASE + ADI_O_MASK8B + ( ADI_4_AUX_O_COMP * 2 )) = // Set LPM_BIAS_WIDTH_TRIM = 3
311 (( ADI_4_AUX_COMP_LPM_BIAS_WIDTH_TRIM_M << 8 ) | // Set mask (bits to be written) in [15:8]
312 ( widthTrim << ADI_4_AUX_COMP_LPM_BIAS_WIDTH_TRIM_S ) ); // Set value (in correct bit pos) in [7:0]
313 }
314 }
315
316 // Third part of trim done after cold reset and wakeup from shutdown:
317 // -Configure HPOSC.
318 // -Setup the LF clock.
319 #if ( CCFG_BASE == CCFG_BASE_DEFAULT )
320 SetupAfterColdResetWakeupFromShutDownCfg3( ccfg_ModeConfReg );
321 #else
322 NOROM_SetupAfterColdResetWakeupFromShutDownCfg3( ccfg_ModeConfReg );
323 #endif
324
325 // Set AUX into power down active mode
326 AUXSYSIFOpModeChange( AUX_SYSIF_OPMODE_TARGET_PDA );
327
328 // Disable EFUSE clock
329 HWREGBITW( FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_EFUSECLK_BITN ) = 1;
330 }
331
332
333 //*****************************************************************************
334 //
335 //! \brief Trims to be applied when coming from PIN_RESET.
336 //!
337 //! \return None
338 //
339 //*****************************************************************************
340 static void
TrimAfterColdReset(void)341 TrimAfterColdReset( void )
342 {
343 // Currently no specific trim for Cold Reset
344 }
345