CC26xx Driver Library
[setup.h] Setup

Functions

void SetupTrimDevice (void)
 Performs the necessary trim of the device which is not done in ROM boot code. More...
 

Detailed Description

This module contains functions for device setup which is not done in boot code.

Function Documentation

§ SetupTrimDevice()

void SetupTrimDevice ( void  )

Performs the necessary trim of the device which is not done in ROM boot code.

This function should only execute coming from ROM boot.

The following is handled by this function:

  • Checks if the driverlib variant used by the application is supported by the device. Execution is halted in case of unsupported driverlib variant.
  • Configures VIMS cache mode based on setting in CCFG.
  • Configures functionalities like DCDC and XOSC dependent on startup modes like cold reset, wakeup from shutdown and wakeup from from powerdown.
  • Configures VIMS power domain control.
  • Configures optimal wait time for flash FSM in cases where flash pump wakes up from sleep.
Note
The current implementation does not take soft reset into account. However, it does no damage to execute it again. It only consumes time.
This function is called by the compiler specific device startup codes that are integrated in the SimpleLink SDKs for CC13xx/CC26XX devices.
Returns
None
117 {
118  uint32_t ui32Fcfg1Revision;
119  uint32_t ui32AonSysResetctl;
120 
121  // Get layout revision of the factory configuration area
122  // (Handle undefined revision as revision = 0)
123  ui32Fcfg1Revision = HWREG(FCFG1_BASE + FCFG1_O_FCFG1_REVISION);
124  if ( ui32Fcfg1Revision == 0xFFFFFFFF ) {
125  ui32Fcfg1Revision = 0;
126  }
127 
128  // This driverlib version and setup file is for the CC13x4, CC26x4 chips.
129  // Halt if violated
131 
132  // Select correct CACHE mode and set correct CACHE configuration
133 #if ( CCFG_BASE == CCFG_BASE_DEFAULT )
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( ! ( HWREG( AON_IOC_BASE + AON_IOC_O_IOCLATCH ) & AON_IOC_IOCLATCH_EN ))
149  {
150  // NB. This should be calling a ROM implementation of required trim and
151  // compensation
152  // e.g. 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( ! ( HWREG( AON_PMCTL_BASE + AON_PMCTL_O_SLEEPCTL ) & AON_PMCTL_SLEEPCTL_IO_PAD_SLEEP_DIS ))
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);
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()
181  TrimAfterColdResetWakeupFromShutDown(ui32Fcfg1Revision);
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  // And finally at the end of the flash boot process:
191  // SET BOOT_DET bits in AON_PMCTL to 3 if already found to be 1
192  // Note: The BOOT_DET_x_CLR/SET bits must be manually cleared
193  if ((( HWREG( AON_PMCTL_BASE + AON_PMCTL_O_RESETCTL ) &
194  ( AON_PMCTL_RESETCTL_BOOT_DET_1_M | AON_PMCTL_RESETCTL_BOOT_DET_0_M )) >>
195  AON_PMCTL_RESETCTL_BOOT_DET_0_S ) == 1 )
196  {
197  ui32AonSysResetctl = ( HWREG( AON_PMCTL_BASE + AON_PMCTL_O_RESETCTL ) &
198  ~( AON_PMCTL_RESETCTL_BOOT_DET_1_CLR_M | AON_PMCTL_RESETCTL_BOOT_DET_0_CLR_M |
199  AON_PMCTL_RESETCTL_BOOT_DET_1_SET_M | AON_PMCTL_RESETCTL_BOOT_DET_0_SET_M | AON_PMCTL_RESETCTL_MCU_WARM_RESET_M ));
200  HWREG( AON_PMCTL_BASE + AON_PMCTL_O_RESETCTL ) = ui32AonSysResetctl | AON_PMCTL_RESETCTL_BOOT_DET_1_SET_M;
201  HWREG( AON_PMCTL_BASE + AON_PMCTL_O_RESETCTL ) = ui32AonSysResetctl;
202  }
203 
204  // Reset the RTC
205  AONRTCReset();
206  // Configure the combined event
207  IntPendClear(INT_AON_RTC_COMB);
209  // Start the RTC
210  AONRTCEnable();
211 
212  // Make sure there are no ongoing VIMS mode change when leaving SetupTrimDevice()
213  // (There should typically be no wait time here, but need to be sure)
214  while ( HWREG( VIMS_BASE + VIMS_O_STAT ) & VIMS_STAT_MODE_CHANGING ) {
215  // Do nothing - wait for an eventual ongoing mode change to complete.
216  }
217 
218  // Configure the NONSECWRn registers to allow manipulation of
219  // ADI_3_REFSYS_DCDCCTL5_IPEAK and ADI_3_REFSYS_DCDCCTL5_DITHER from the
220  // non-secure side. This is required by the radio for proper operation.
221  // The ADI_3_REFSYS_O_DCDCCTL5 register byte-offset is divided by two
222  // since the the ADDR field is encoded as a half-word index
223 
224  // Dither disabled, IPEAK = 0
225  HWREG( ADI3_BASE + ADI_O_NONSECWR0) = (( 0x00 << ADI_NONSECWR0_DATA_S) & ADI_NONSECWR0_DATA_M ) |
226  ((( ( ADI_3_REFSYS_O_DCDCCTL5) ) << ADI_NONSECWR0_ADDR_S ) & ADI_NONSECWR0_ADDR_M) |
227  (( 0x0F << ADI_NONSECWR0_WR_MASK_S) & ADI_NONSECWR0_WR_MASK_M);
228 
229  // Dither enabled, IPEAK = 0
230  HWREG( ADI3_BASE + ADI_O_NONSECWR1) = (( 0x08 << ADI_NONSECWR1_DATA_S) & ADI_NONSECWR1_DATA_M ) |
231  ((( ( ADI_3_REFSYS_O_DCDCCTL5) ) << ADI_NONSECWR1_ADDR_S ) & ADI_NONSECWR1_ADDR_M) |
232  (( 0x0F << ADI_NONSECWR1_WR_MASK_S) & ADI_NONSECWR1_WR_MASK_M);
233 
234  // Dither disabled, IPEAK = 3
235  HWREG( ADI3_BASE + ADI_O_NONSECWR2) = (( 0x03 << ADI_NONSECWR2_DATA_S) & ADI_NONSECWR2_DATA_M ) |
236  ((( ( ADI_3_REFSYS_O_DCDCCTL5) ) << ADI_NONSECWR2_ADDR_S ) & ADI_NONSECWR2_ADDR_M) |
237  (( 0x0F << ADI_NONSECWR2_WR_MASK_S) & ADI_NONSECWR2_WR_MASK_M);
238 
239  // Dither disabled, IPEAK = 7
240  HWREG( ADI3_BASE + ADI_O_NONSECWR3) = (( 0x07 << ADI_NONSECWR3_DATA_S) & ADI_NONSECWR3_DATA_M ) |
241  ((( ( ADI_3_REFSYS_O_DCDCCTL5) ) << ADI_NONSECWR3_ADDR_S ) & ADI_NONSECWR3_ADDR_M) |
242  (( 0x0F << ADI_NONSECWR3_WR_MASK_S) & ADI_NONSECWR3_WR_MASK_M);
243 
244  // Configure Sensor Controller access to TDC clock control
245  // Allow read and write ACLK_TDC_SRC_SEL and ACLK_REF_SRC_SEL fields in
246  // DDI_0_OSC_O_CTL0 register.
247  // The ADDR field is encoded as a half-word index. So we need to divide the
248  // regular byte-offset by two.
249  // Use NONSECDDIACC3 because if ADDR is 0 for multiple NONSECDDIACCn,
250  // only the highest NONSECDIACCn takes effect. 0 is the reset value for
251  // ADDR and DDI_0_OSC_O_CTL0 has an ADDR offset of 0. So to access this
252  // Register, we should always aim to use the highest NONSECDDIACCn.
253  HWREG( AUX_SCE_BASE + AUX_SCE_O_NONSECDDIACC3) = AUX_SCE_NONSECDDIACC3_RD_EN |
254  (( ( DDI_0_OSC_O_CTL0 / 2 ) << AUX_SCE_NONSECDDIACC3_ADDR_S ) & AUX_SCE_NONSECDDIACC3_ADDR_M ) |
255  (( DDI_0_OSC_CTL0_ACLK_TDC_SRC_SEL_M | DDI_0_OSC_CTL0_ACLK_REF_SRC_SEL_M ) & AUX_SCE_NONSECDDIACC3_WR_MASK_M );
256 
257  // Configure Sensor Controller access to COMPB 32 kHz clock enable
258  // We want to read and write DDI_0_OSC_ATESTCTL_SCLK_LF_AUX_EN.
259  // This is a 16-bit write, so we need to add to the address offset since
260  // DDI_0_OSC_ATESTCTL_SCLK_LF_AUX_EN is in the upper half of the register.
261  // The ADDR field is encoded as a half-word index. So we need to divide the
262  // regular byte-offset by two.
263  // The mask needs to be shifted down because the original register field
264  // mask is provided as a 32-bit mask.
265  HWREG( AUX_SCE_BASE + AUX_SCE_O_NONSECDDIACC1) = AUX_SCE_NONSECDDIACC1_RD_EN |
266  ((( ( DDI_0_OSC_O_ATESTCTL + 2 ) / 2 ) << AUX_SCE_NONSECDDIACC1_ADDR_S ) & AUX_SCE_NONSECDDIACC1_ADDR_M) |
267  (( DDI_0_OSC_ATESTCTL_SCLK_LF_AUX_EN_M >> 16 ) & AUX_SCE_NONSECDDIACC1_WR_MASK_M);
268 
269  // Enable output of RTC clock for Radio Timer Synchronization
270  HWREG(AON_RTC_BASE + AON_RTC_O_CTL) |= AON_RTC_CTL_RTC_UPD_EN_M;
271 }
#define AON_RTC_CH1
Definition: aon_rtc.h:93
void IntPendClear(uint32_t ui32Interrupt)
Unpends an interrupt.
Definition: interrupt.c:441
void ThisLibraryIsFor_CC13x4_CC26x4_HaltIfViolated(void)
Verifies that current chip is CC13x4 or CC26x4 and never returns if violated.
Definition: chipinfo.c:196
#define AON_RTC_CH2
Definition: aon_rtc.h:94
static void AONRTCCombinedEventConfig(uint32_t ui32Channels)
Configure the source of the combined event.
Definition: aon_rtc.h:335
static void TrimAfterColdResetWakeupFromShutDownWakeupFromPowerDown(void)
Trims to be applied when coming from POWER_DOWN (also called when coming from SHUTDOWN and PIN_RESET)...
Definition: setup.c:282
static void AONRTCReset(void)
Reset the RTC.
Definition: aon_rtc.h:209
#define AON_RTC_CH0
Definition: aon_rtc.h:92
static void TrimAfterColdResetWakeupFromShutDown(uint32_t ui32Fcfg1Revision)
Trims to be applied when coming from SHUTDOWN (also called when coming from PIN_RESET).
Definition: setup.c:298
static void AONRTCEnable(void)
Enable the RTC.
Definition: aon_rtc.h:172
void SetupSetCacheModeAccordingToCcfgSetting(void)
Set correct VIMS_MODE according to CCFG setting (CACHE or GPRAM)
Definition: setup_rom.c:881
static void TrimAfterColdReset(void)
Trims to be applied when coming from PIN_RESET.
Definition: setup.c:398
Here is the call graph for this function: