Exemple #1
0
void
vBSP430platformSpinForJumper_ni (void)
{
  /* P1.2 input with pullup */
  P1SEL &= ~BIT2;
  P1DIR &= ~BIT2;
  P1REN |= BIT2;
  P1OUT |= BIT2;
#if BSP430_LED
  vBSP430ledInitialize_ni();
#else /* BSP430_LED */
  P1DIR |= (BIT0 | BIT1);
  P1SEL &= ~(BIT0 | BIT1);
#endif /* BSP430_LED */
  P1OUT |= BIT0;
  while (! (P1IN & BIT2)) {
    BSP430_CORE_WATCHDOG_CLEAR();
    BSP430_CORE_DELAY_CYCLES(BSP430_CLOCK_NOMINAL_MCLK_HZ / 10);
    P1OUT ^= BIT0 | BIT1;
  }
  /* Restore P1.2 */
  P1OUT &= ~(BIT0 | BIT1 | BIT2);
  P1DIR |= BIT2;
  P1REN &= ~BIT2;
}
Exemple #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;

      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;
}
Exemple #3
0
void
vBSP430platformSpinForJumper_ni (void)
{
  const unsigned char led_bits = BIT1 | BIT2 | BIT3 | BIT4 | BIT5;
  /* P7.7 input configured with pullup */
  P7DIR &= ~BIT7;
  P7REN |= BIT7;
  P7OUT |= BIT7;

  /* Flash LEDs alternately while waiting */
#if BSP430_LED
  vBSP430ledInitialize_ni();
#else /* BSP430_LED */
  P1DIR |= led_bits;
  P1SEL &= ~led_bits;
#endif /* BSP430_LED */
  P1OUT &= ~(BIT2 | BIT4);
  P1OUT |= BIT1 | BIT3 | BIT5;
  while (! (P7IN & BIT7)) {
    BSP430_CORE_WATCHDOG_CLEAR();
    BSP430_CORE_DELAY_CYCLES(BSP430_CLOCK_NOMINAL_MCLK_HZ / 10);
    P1OUT ^= led_bits;
  }

  /* Restore P1.0 and LEDs */
  P1OUT &= ~led_bits;
  P7OUT &= ~BIT7;
  P7DIR |= BIT7;
  P7REN &= ~BIT7;
}
Exemple #4
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;
}
Exemple #5
0
/* Emit a NUL-terminated string of text, returning the number of
 * characters emitted. */
static int
emit_text_ni (const char * s,
              hBSP430halSERIAL uart)
{
  int rv = 0;
  if (uart) {
    while (s[rv]) {
      emit_char2_ni(s[rv++], uart);
      BSP430_CORE_WATCHDOG_CLEAR();
    }
  }
  return rv;
}
Exemple #6
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();
}
Exemple #7
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;

      /* 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;
}
Exemple #8
0
void main ()
{
#if (BSP430_CONSOLE - 0)
  const char * help;
  unsigned long smclk_Hz;
  unsigned long aclk_Hz;
#endif /* BSP430_CONSOLE */

  /* First thing you do in main is configure the platform. */
  vBSP430platformInitialize_ni();

  /* If we support a console, dump out a bunch of configuration
   * information. */
#if (BSP430_CONSOLE - 0)
  (void)iBSP430consoleInitialize();
  cputtext("\nclocks " __DATE__ " " __TIME__ "\n");
  cputtext("\nBSP430_PLATFORM_BOOT_CONFIGURE_LFXT1: ");
  cputu(BSP430_PLATFORM_BOOT_CONFIGURE_LFXT1, 10);
  cputtext("\nBSP430_CLOCK_LFXT1_STABILIZATION_DELAY_CYCLES: ");
  cputul(BSP430_CLOCK_LFXT1_STABILIZATION_DELAY_CYCLES, 10);
  cputtext("\nBSP430_PLATFORM_BOOT_LFXT1_DELAY_SEC: ");
  cputu(BSP430_PLATFORM_BOOT_LFXT1_DELAY_SEC, 10);
  cputtext("\nBSP430_PLATFORM_BOOT_CONFIGURE_CLOCKS: ");
  cputu(BSP430_PLATFORM_BOOT_CONFIGURE_CLOCKS, 10);
#if defined(__MSP430_HAS_BC2__)
#if (configBSP430_BC2_TRIM_TO_MCLK - 0)
  cputtext("\nconfigBSP430_BC2_TRIM_TO_MCLK: 1");
#else /* configBSP430_BC2_TRIM_TO_MCLK */
  cputtext("\nconfigBSP430_BC2_TRIM_TO_MCLK: 0");
#endif /* configBSP430_BC2_TRIM_TO_MCLK */
#if (BSP430_BC2_TRIM_TO_MCLK - 0)
  cputtext("\nBSP430_BC2_TRIM_TO_MCLK: 1");
#else /* BSP430_BC2_TRIM_TO_MCLK */
  cputtext("\nBSP430_BC2_TRIM_TO_MCLK: 0");
#endif /* BSP430_BC2_TRIM_TO_MCLK */
#endif /* BC2 */
#if defined(__MSP430_HAS_UCS__) || defined(__MSP430_HAS_UCS_RF__)
#if (configBSP430_UCS_TRIM_DCOCLKDIV - 0)
  cputtext("\nconfigBSP430_UCS_TRIM_DCOCLKDIV: 1");
#else /* configBSP430_UCS_TRIM_DCOCLKDIV */
  cputtext("\nconfigBSP430_UCS_TRIM_DCOCLKDIV: 0");
#endif /* configBSP430_UCS_TRIM_DCOCLKDIV */
#if (BSP430_UCS_TRIM_DCOCLKDIV - 0)
  cputtext("\nBSP430_UCS_TRIM_DCOCLKDIV: 1");
#else /* BSP430_UCS_TRIM_DCOCLKDIV */
  cputtext("\nBSP430_UCS_TRIM_DCOCLKDIV: 0");
#endif /* BSP430_UCS_TRIM_DCOCLKDIV */
#endif /* UCS */

  cputtext("\nBSP430_CLOCK_PUC_MCLK_HZ: ");
  cputul(BSP430_CLOCK_PUC_MCLK_HZ, 10);
  cputtext("\nBSP430_CLOCK_NOMINAL_MCLK_HZ: ");
  cputul(BSP430_CLOCK_NOMINAL_MCLK_HZ, 10);
  cputtext("\nBSP430_CLOCK_LFXT1_IS_FAULTED_NI(): ");
  cputu(BSP430_CLOCK_LFXT1_IS_FAULTED_NI(), 10);
  cputtext("\nBSP430_CLOCK_NOMINAL_VLOCLK_HZ: ");
  cputu(BSP430_CLOCK_NOMINAL_VLOCLK_HZ, 10);
  cputtext("\nBSP430_CLOCK_NOMINAL_XT1CLK_HZ: ");
  cputul(BSP430_CLOCK_NOMINAL_XT1CLK_HZ, 10);
#if defined(BSP430_CLOCK_NOMINAL_XT2CLK_HZ)
  cputtext("\nBSP430_PLATFORM_BOOT_CONFIGURE_XT2: ");
  cputu(BSP430_PLATFORM_BOOT_CONFIGURE_XT2, 10);
  cputtext("\nBSP430_CLOCK_XT2_IS_FAULTED_NI(): ");
  cputu(BSP430_CLOCK_XT2_IS_FAULTED_NI(), 10);
  cputtext("\nBSP430_CLOCK_NOMINAL_XT2CLK_HZ: ");
  cputul(BSP430_CLOCK_NOMINAL_XT2CLK_HZ, 10);
#endif /* BSP430_CLOCK_NOMINAL_XT2CLK_HZ */
  cputtext("\nulBSP430clockMCLK_Hz_ni(): ");
  cputul(ulBSP430clockMCLK_Hz_ni(), 10);
  cputtext("\nBSP430_PLATFORM_BOOT_SMCLK_DIVIDING_SHIFT: ");
  cputi(BSP430_PLATFORM_BOOT_SMCLK_DIVIDING_SHIFT, 10);
  cputtext("\nulBSP430clockSMCLK_Hz_ni(): ");
  smclk_Hz = ulBSP430clockSMCLK_Hz_ni();
  cputul(smclk_Hz, 10);
  cputtext("\nBSP430_PLATFORM_BOOT_ACLK_DIVIDING_SHIFT: ");
  cputi(BSP430_PLATFORM_BOOT_ACLK_DIVIDING_SHIFT, 10);
  cputtext("\nulBSP430clockACLK_Hz_ni(): ");
  aclk_Hz = ulBSP430clockACLK_Hz_ni();
  cputul(aclk_Hz, 10);

#if (BSP430_TIMER_CCACLK - 0)
  if (1000000UL <= aclk_Hz) {
    cputtext("\nUnable to use high-speed ACLK for differential timing of SMCLK");
  } else {
    do {
      const unsigned int SAMPLE_PERIOD_ACLK = 10;
      volatile sBSP430hplTIMER * tp = xBSP430hplLookupTIMER(BSP430_TIMER_CCACLK_PERIPH_HANDLE);
      unsigned int cc_delta;
      unsigned long aclk_rel_smclk_Hz;
      unsigned long smclk_rel_aclk_Hz;

      if (! tp) {
        cputtext("\nUnable to access configured CCACLK timer");
        break;
      }
      /* Capture the SMCLK ticks between adjacent ACLK ticks */
      tp->ctl = TASSEL_2 | MC_2 | TACLR;
      cc_delta = uiBSP430timerCaptureDelta_ni(BSP430_TIMER_CCACLK_PERIPH_HANDLE,
                                              BSP430_TIMER_CCACLK_ACLK_CCIDX,
                                              CM_2,
                                              BSP430_TIMER_CCACLK_ACLK_CCIS,
                                              SAMPLE_PERIOD_ACLK);
      tp->ctl = 0;
      if (-1 == cc_delta) {
        cputtext("\nCCACLK measurement failed");
        break;
      }
      cputchar('\n');
      cputu(SAMPLE_PERIOD_ACLK, 10);
      cputtext(" ticks of ACLK produced ");
      cputu(cc_delta, 10);
      cputtext(" ticks of SMCLK");
      cputtext("\nComparison with measured values:");
      cputtext("\n SMCLK (Hz) (if measured ACLK correct): ");
      smclk_rel_aclk_Hz = (cc_delta * aclk_Hz) / SAMPLE_PERIOD_ACLK;
      cputul(smclk_rel_aclk_Hz, 10);
      cputtext(" (error ");
      cputl(smclk_rel_aclk_Hz - smclk_Hz, 10);
      cputtext(" = ");
      cputl(1000 * labs(smclk_rel_aclk_Hz - smclk_Hz) / smclk_Hz, 10);
      cputtext(" kHz/MHz)");
      cputtext("\n ACLK (Hz) (if measured SMCLK correct): ");
      aclk_rel_smclk_Hz = SAMPLE_PERIOD_ACLK * smclk_Hz / cc_delta;
      cputul(aclk_rel_smclk_Hz, 10);
      cputtext(" (error ");
      cputl(aclk_rel_smclk_Hz - aclk_Hz, 10);
      cputtext(" = ");
      cputl(1000 * labs(aclk_rel_smclk_Hz - aclk_Hz) / aclk_Hz, 10);
      cputtext(" Hz/kHz)");
    } while (0);
  }
#else /* BSP430_TIMER_CCACLK */
  cputtext("\nNo CCACLK timer available for ACLK/SMCLK comparison");
#endif /* BSP430_TIMER_CCACLK */

  cputchar('\n');

#if defined(__MSP430_HAS_BC2__)
  cputtext("\nBC2: DCO ");
  cputu(DCOCTL, 16);
  cputtext(" CTL1  ");
  cputu(BCSCTL1, 16);
  cputtext(" CTL2  ");
  cputu(BCSCTL2, 16);
  cputtext(" CTL3  ");
  cputu(BCSCTL3, 16);

#endif

#if defined(__MSP430_HAS_FLL__) || defined(__MSP430_HAS_FLLPLUS__)
  cprintf("\nFLL: SCF QCTL %02x I0 %02x I1 %02x ; CTL0 %02x CTL1 %02x CTL2 %02x\n",
          SCFQCTL, SCFI0, SCFI1, FLL_CTL0, FLL_CTL1,
#if defined(FLL_CTL2_)
          FLL_CTL2
#else /* FLL_CTL2 */
          ~0
#endif /* FLL_CTL2 */
         );
#endif /* FLL/PLUS */

#if defined(__MSP430_HAS_UCS__) || defined(__MSP430_HAS_UCS_RF__)
  cputtext("\nBSP430_UCS_FLL_SELREF: "
#if SELREF__XT2CLK <= BSP430_UCS_FLL_SELREF
           "XT2CLK"
#elif SELREF__REFOCLK <= BSP430_UCS_FLL_SELREF
           "REFOCLK"
#else /* BSP430_UCS_FLL_SELREF */
           "XT1CLK"
#endif /* BSP430_UCS_FLL_SELREF */
          );
  cprintf("\nUCS RSEL %d DCO %d MOD %d:"
          "\n CTL0 %04x CTL1 %04x CTL2 %04x CTL3 %04x"
          "\n CTL4 %04x CTL5 %04x CTL6 %04x CTL7 %04x",
          0x1F & (UCSCTL1 / DCORSEL0), 0x1F & (UCSCTL0 / DCO0), 0x1F & (UCSCTL0 / MOD0),
          UCSCTL0, UCSCTL1, UCSCTL2, UCSCTL3,
          UCSCTL4, UCSCTL5, UCSCTL6, UCSCTL7);
#endif /* UCS */

#if defined(__MSP430_HAS_CS__) || defined(__MSP430_HAS_CS_A__)
  cprintf("\nCS %s : RSEL %d DCOFSEL %d:"
          "\n CTL0 %04x CTL1 %04x CTL2 %04x CTL3 %04x"
          "\n CTL4 %04x CTL5 %04x CTL6 %04x"
          "\n FRCTL0 %04x",
#if (BSP430_CS_IS_FR57XX - 0)
          "FR57xx"
#endif
#if (BSP430_CS_IS_FR58XX - 0)
          "FR58xx"
#endif
          "", !!(DCORSEL & CSCTL1), 0x07 & (CSCTL1 / DCOFSEL0),
          CSCTL0, CSCTL1, CSCTL2, CSCTL3,
          CSCTL4, CSCTL5, CSCTL6, FRCTL0);
#endif /* CS */

#endif /* BSP430_CONSOLE */

  if (0 == iBSP430platformConfigurePeripheralPins_ni(BSP430_PERIPH_EXPOSED_CLOCKS, 0, 1)) {
#if (BSP430_CONSOLE - 0)
    cputtext("\n\nClock signals exposed:\n ");
    help = NULL;
#ifdef BSP430_PLATFORM_PERIPHERAL_HELP
    help = xBSP430platformPeripheralHelp(BSP430_PERIPH_EXPOSED_CLOCKS, 0);
#endif /* BSP430_PLATFORM_PERIPHERAL_HELP */
    if (NULL == help) {
      help = "Go look at the data sheet and source, because nobody told me where they are";
    }
    cputtext(help);
    cputtext("\nStatus register LPM bits: ");
    cputu(__read_status_register() & BSP430_CORE_LPM_SR_MASK, 16);
    cputtext("\nIFG1 bits: ");
#if defined(__MSP430_HAS_MSP430XV2_CPU__)
    cputu(SFRIFG1, 16);
#else /* CPUX */
    cputu(IFG1, 16);
#endif /* CPUX */
    cputtext(" with OFIFG ");
    cputu(OFIFG, 16);
    cputchar('\n');
#endif /* BSP430_CONSOLE */

    /* Spin here with CPU active.  In LPM0, MCLK is disabled.  Other
     * clocks get disabled at deeper sleep modes; if you fall off the
     * bottom, you might end up in LPM4 with all clocks disabled. */
    while (1) {
      vBSP430ledSet(0, -1);
      BSP430_CORE_WATCHDOG_CLEAR();
      BSP430_CORE_DELAY_CYCLES(BSP430_CLOCK_NOMINAL_MCLK_HZ / 2);
    }
  } else {
#if (BSP430_CONSOLE - 0)
    cputtext("\nFailed to expose clock signals\n");
#endif /* BSP430_CONSOLE */
  }
}
Exemple #9
0
/* This code is derived from the implementation in MSP430Ware
 * driverlib version 1.25 file driverlib/5xx_6xx/pmm.c.  Gratuitous
 * and non-gratuitous coding format, style, and content changes have
 * been made. */
static unsigned int
setVCoreUp (unsigned int level)
{
  unsigned int PMMRIE_backup;
  unsigned int SVSMHCTL_backup;
  unsigned int SVSMLCTL_backup;

  /* The code flow for increasing the Vcore has been altered to work around
   * the erratum FLASH37.
   * Please refer to the Errata sheet to know if a specific device is affected.
   * DO NOT ALTER THIS FUNCTION */

  /* Open PMM registers for write access */
  PMMCTL0_H = 0xA5;

  /* Disable dedicated Interrupts.  Backup all registers */
  PMMRIE_backup = PMMRIE;
  PMMRIE &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE | SVSLPE | SVMHVLRIE | SVMHIE |
              SVSMHDLYIE | SVMLVLRIE | SVMLIE | SVSMLDLYIE);
  SVSMHCTL_backup = SVSMHCTL;
  SVSMLCTL_backup = SVSMLCTL;

  /* Clear flags */
  PMMIFG = 0;

  /* Set SVM highside to new level and check if a VCore increase is possible */
  SVSMHCTL = SVMHE | SVSHE | (SVSMHRRL0 * level);

  /* Wait until SVM highside is settled */
  while ((PMMIFG & SVSMHDLYIFG) == 0) {
    BSP430_CORE_WATCHDOG_CLEAR();
  }

  /* Clear flag */
  PMMIFG &= ~SVSMHDLYIFG;

  /* Check if a VCore increase is possible */
  if ((PMMIFG & SVMHIFG) == SVMHIFG) {
    /* -> Vcc is too low for a Vcore increase, recover the previous
     * settings */
    PMMIFG &= ~SVSMHDLYIFG;
    SVSMHCTL = SVSMHCTL_backup;

    /* Wait until SVM highside is settled */
    while ((PMMIFG & SVSMHDLYIFG) == 0) {
      BSP430_CORE_WATCHDOG_CLEAR();
    }

    /* Clear all Flags */
    PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);

    /* Restore PMM interrupt enable register */
    PMMRIE = PMMRIE_backup;
    /* Lock PMM registers for write access */
    PMMCTL0_H = 0x00;
    /* return: voltage not set */
    return -1;
  }

  /* Set also SVS highside to new level.  Vcc is high enough for a
   * Vcore increase */
  SVSMHCTL |= (SVSHRVL0 * level);

  /* Wait until SVM highside is settled */
  while ((PMMIFG & SVSMHDLYIFG) == 0) {
    BSP430_CORE_WATCHDOG_CLEAR();
  }

  /* Clear flag */
  PMMIFG &= ~SVSMHDLYIFG;

  /* Set VCore to new level */
  PMMCTL0_L = PMMCOREV0 * level;

  /* Set SVM, SVS low side to new level */
  SVSMLCTL = SVMLE | (SVSMLRRL0 * level) | SVSLE | (SVSLRVL0 * level);

  /* Wait until SVM low side is settled */
  while ((PMMIFG & SVSMLDLYIFG) == 0) {
    BSP430_CORE_WATCHDOG_CLEAR();
  }

  /* Clear flag */
  PMMIFG &= ~SVSMLDLYIFG;
  /* SVS, SVM core and high side are now set to protect for the new core level */

  /* Restore Low side settings.  Clear all other bits _except_ level
   * settings */
  SVSMLCTL &= (SVSLRVL0 | SVSLRVL1 | SVSMLRRL0 | SVSMLRRL1 | SVSMLRRL2);

  /* Clear level settings in the backup register,keep all other bits */
  SVSMLCTL_backup &= ~(SVSLRVL0 | SVSLRVL1 | SVSMLRRL0 | SVSMLRRL1 | SVSMLRRL2);

  /* Restore low-side SVS monitor settings */
  SVSMLCTL |= SVSMLCTL_backup;

  /* Restore High side settings */
  /* Clear all other bits except level settings */
  SVSMHCTL &= (SVSHRVL0 | SVSHRVL1 | SVSMHRRL0 | SVSMHRRL1 | SVSMHRRL2);

  /* Clear level settings in the backup register,keep all other bits */
  SVSMHCTL_backup &= ~(SVSHRVL0 | SVSHRVL1 | SVSMHRRL0 | SVSMHRRL1 | SVSMHRRL2);

  /* Restore backup */
  SVSMHCTL |= SVSMHCTL_backup;

  /* Wait until SVM high side and low side are settled */
  while (((PMMIFG & SVSMLDLYIFG) == 0)
         || ((PMMIFG & SVSMHDLYIFG) == 0)) {
    BSP430_CORE_WATCHDOG_CLEAR();
  }

  /* Clear all Flags */
  PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);

  /* Restore PMM interrupt enable register */
  PMMRIE = PMMRIE_backup;

  /* Lock PMM registers for write access */
  PMMCTL0_H = 0x00;

  return 0;
}
Exemple #10
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;
}