Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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();
}
Esempio n. 4
0
File: cs4.c Progetto: pabigot/bsp430
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;
}
Esempio n. 5
0
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;
}