int iBSP430clockConfigureLFXT1_ni (int enablep, int loop_limit) { int loop_delta; int rc = 0; BSP430_CLOCK_CLEAR_FAULTS_NI(); if (enablep && (0 != loop_limit)) { rc = iBSP430platformConfigurePeripheralPins_ni(BSP430_PERIPH_LFXT1, 0, 1); if (0 == rc) { loop_delta = (0 < loop_limit) ? 1 : 0; FLL_CTL0 = (FLL_CTL0 & ~(OSCCAP0 | OSCCAP1 | XTS_FLL)) | BSP430_CLOCK_LFXT1_XCAP; do { BSP430_CLOCK_CLEAR_FAULTS_NI(); loop_limit -= loop_delta; BSP430_CORE_WATCHDOG_CLEAR(); BSP430_CORE_DELAY_CYCLES(BSP430_CLOCK_LFXT1_STABILIZATION_DELAY_CYCLES); } while (BSP430_FLLPLUS_LFXT1_IS_FAULTED_NI() && (0 != loop_limit)); rc = ! BSP430_FLLPLUS_LFXT1_IS_FAULTED_NI(); } } BSP430_CLOCK_OSC_CLEAR_FAULT_NI(); if (! rc) { (void)iBSP430platformConfigurePeripheralPins_ni(BSP430_PERIPH_LFXT1, 0, 0); FLL_CTL0 &= ~(OSCCAP0 | OSCCAP1); } return rc; }
int iBSP430clockConfigureLFXT1_ni (int enablep, int loop_limit) { int loop_delta; int rc = 0; BSP430_CLOCK_CLEAR_FAULTS_NI(); if (enablep && (0 != loop_limit)) { rc = iBSP430platformConfigurePeripheralPins_ni(BSP430_PERIPH_LFXT1, 0, 1); if (0 == rc) { loop_delta = (0 < loop_limit) ? 1 : 0; /* See whether the crystal is populated and functional. Do * this with the DCO reset to the power-up configuration, * where clock should be nominal 1 MHz. * * @TODO: Preserve XT2 configuration */ BCSCTL3 = BSP430_CLOCK_LFXT1_XCAP; do { loop_limit -= loop_delta; BSP430_CORE_WATCHDOG_CLEAR(); BSP430_CORE_DELAY_CYCLES(BSP430_CLOCK_LFXT1_STABILIZATION_DELAY_CYCLES); } while ((BSP430_BC2_LFXT1_IS_FAULTED_NI()) && (0 != loop_limit)); rc = ! BSP430_BC2_LFXT1_IS_FAULTED_NI(); } } BSP430_CLOCK_OSC_CLEAR_FAULT_NI(); if (! rc) { (void)iBSP430platformConfigurePeripheralPins_ni(BSP430_PERIPH_LFXT1, 0, 0); /* Explicitly fall back to VLOCLK and disable capacitors */ BCSCTL3 = LFXT1S_2; } return rc; }
unsigned long ulBSP430clockConfigureMCLK_ni (unsigned long mclk_Hz) { unsigned int flld = 0; unsigned int fn_x = 0; int dcoplus = 0; unsigned int dcoclk_xt1 = (mclk_Hz + BSP430_CLOCK_NOMINAL_XT1CLK_HZ / 2) / BSP430_CLOCK_NOMINAL_XT1CLK_HZ; /* Convert a value in MHz to the same value in ticks of LXFT1 */ #define MHZ_TO_XT1(_n) (((_n)*1000000UL) / BSP430_CLOCK_NOMINAL_XT1CLK_HZ) /* Gross selection of DCO range. We select the range if the target * frequency is above the midpoint of the previous range. */ if (MHZ_TO_XT1(26/2) < dcoclk_xt1) { fn_x = FN_8; } else if (MHZ_TO_XT1(17/2) < dcoclk_xt1) { fn_x = FN_4; } else if (MHZ_TO_XT1(12/2) < dcoclk_xt1) { fn_x = FN_3; } else if (MHZ_TO_XT1(6/2) < dcoclk_xt1) { fn_x = FN_2; } #undef MHZ_TO_XT1 /* Need a divider if multiplier is too large. */ while (FLL_N_MASK < (dcoclk_xt1 - 1)) { dcoplus = 1; ++flld; dcoclk_xt1 /= 2; } (void)iBSP430clockConfigureLFXT1_ni(1, -1); if (dcoplus) { FLL_CTL0 |= DCOPLUS; } SCFQCTL = dcoclk_xt1 - 1; SCFI0 = (flld * FLLD0) | fn_x; /* Clear all the oscillator faults and spin until DCO stabilized. */ do { BSP430_CLOCK_CLEAR_FAULTS_NI(); BSP430_CORE_WATCHDOG_CLEAR(); /* Conservatively assume a 32 MHz clock */ BSP430_CORE_DELAY_CYCLES(32 * BSP430_CLOCK_FAULT_RECHECK_DELAY_US); } while (BSP430_FLLPLUS_DCO_IS_FAULTED_NI()); return ulBSP430clockMCLK_Hz_ni(); }
int iBSP430clockConfigureLFXT1_ni (int enablep, int loop_limit) { int loop_delta; int rc = 0; BSP430_CLOCK_CLEAR_FAULTS_NI(); if (enablep && (0 != loop_limit)) { rc = iBSP430platformConfigurePeripheralPins_ni(BSP430_PERIPH_LFXT1, 0, 1); if (0 == rc) { loop_delta = (0 < loop_limit) ? 1 : 0; /* Low frequency XT1 needed. Spin at high drive to stability, then * drop back. */ CSCTL6 = XT1DRIVE_3 | (CSCTL6 & ~(XTS | XT1BYPASS | XT1AGCOFF | XT1AUTOOFF)); do { BSP430_CLOCK_CLEAR_FAULTS_NI(); loop_limit -= loop_delta; BSP430_CORE_WATCHDOG_CLEAR(); BSP430_CORE_DELAY_CYCLES(BSP430_CLOCK_LFXT1_STABILIZATION_DELAY_CYCLES); } while ((BSP430_CS4_LFXT1_IS_FAULTED_NI()) && (0 != loop_limit)); rc = ! BSP430_CS4_LFXT1_IS_FAULTED_NI(); } } BSP430_CLOCK_OSC_CLEAR_FAULT_NI(); CSCTL6 &= ~XT1DRIVE_3; if (! rc) { (void)iBSP430platformConfigurePeripheralPins_ni(BSP430_PERIPH_LFXT1, 0, 0); /* Disable as an indication that XIN is not enabled. Also remove * capacitance setting. */ CSCTL6 = XT1BYPASS | (CSCTL6 & ~(XT1DRIVE0 | XT1DRIVE1)); } return rc; }
unsigned long ulBSP430clockConfigureMCLK_ni (unsigned long mclk_Hz) { unsigned char dcoctl; unsigned char bcsctl1; unsigned long error_Hz; int use_trim_to_mclk = 1; long freq_Hz; if (0 == mclk_Hz) { mclk_Hz = BSP430_CLOCK_PUC_MCLK_HZ; use_trim_to_mclk = 0; } /* Power-up defaults */ dcoctl = 0x60; bcsctl1 = 0x87; freq_Hz = BSP430_CLOCK_PUC_MCLK_HZ; /* Calculate absolute error from _freq_Hz to target */ #define ERROR_HZ(_freq_Hz) ((mclk_Hz < _freq_Hz) ? (_freq_Hz - mclk_Hz) : (mclk_Hz - _freq_Hz)) error_Hz = ERROR_HZ(freq_Hz); (void)error_Hz; /* Test a candidate to see if it's better than what we've got now */ #define TRY_FREQ(_tag, _cand_Hz) do { \ unsigned long cand_error_Hz = ERROR_HZ(_cand_Hz); \ if (cand_error_Hz < error_Hz) { \ dcoctl = CALDCO_##_tag; \ bcsctl1 = CALBC1_##_tag; \ freq_Hz = _cand_Hz; \ error_Hz = cand_error_Hz; \ } \ } while (0) /* Candidate availability is MCU-specific and can be determined by * checking for a corresponding preprocessor definition */ #if defined(CALDCO_1MHZ_) TRY_FREQ(1MHZ, 1000000UL); #endif /* CALDCO_1MHZ */ #if defined(CALDCO_8MHZ_) TRY_FREQ(8MHZ, 8000000UL); #endif /* CALDCO_8MHZ */ #if defined(CALDCO_12MHZ_) TRY_FREQ(12MHZ, 12000000UL); #endif /* CALDCO_12MHZ */ #if defined(CALDCO_16MHZ_) TRY_FREQ(16MHZ, 16000000UL); #endif /* CALDCO_16MHZ */ #undef TRY_FREQ #undef ERROR_HZ /* Clearing DCO bits first supports workaround for erratum BCL12 */ DCOCTL = 0; BCSCTL1 = bcsctl1; DCOCTL = dcoctl; /* SELM = DCOCLK; DIVM = /1 */ BCSCTL2 &= ~(SELM_MASK | DIVM_MASK); configuredMCLK_Hz = freq_Hz; if (use_trim_to_mclk) { #if BSP430_BC2_TRIM_TO_MCLK - 0 (void)iBSP430bc2TrimToMCLK_ni(mclk_Hz); #endif /* BSP430_BC2_TRIM_TO_MCLK */ } /* Spin until DCO faults cleared */ do { BSP430_CLOCK_CLEAR_FAULTS_NI(); BSP430_CORE_WATCHDOG_CLEAR(); /* Conservatively assume a 32 MHz clock */ BSP430_CORE_DELAY_CYCLES(32 * BSP430_CLOCK_FAULT_RECHECK_DELAY_US); } while (BSP430_CLOCK_OSC_IS_FAULTED_NI()); return configuredMCLK_Hz; }