Exemple #1
0
/***************************************************************************//**
 * @brief
 *   Set LETIMER repeat counter register value.
 *
 * @note
 *   The setting of a repeat counter register requires synchronization into the
 *   low frequency domain. If the same register is modified before a previous
 *   update has completed, this function will stall until the previous
 *   synchronization has completed.
 *
 * @param[in] letimer
 *   Pointer to LETIMER peripheral register block
 *
 * @param[in] rep
 *   Repeat counter register to set, either 0 or 1
 *
 * @param[in] value
 *   Initialization value (<= 0x0000ffff)
 ******************************************************************************/
void LETIMER_RepeatSet(LETIMER_TypeDef *letimer,
                       unsigned int rep,
                       uint32_t value)
{
  volatile uint32_t *repReg;
  uint32_t          syncbusy;

  EFM_ASSERT(LETIMER_REF_VALID(letimer) &&
             LETIMER_REP_REG_VALID(rep) &&
             ((value & ~(_LETIMER_REP0_REP0_MASK >> _LETIMER_REP0_REP0_SHIFT)) == 0));

  /* Initialize selected compare value */
  switch (rep)
  {
  case 0:
    repReg   = &(letimer->REP0);
    syncbusy = LETIMER_SYNCBUSY_REP0;
    break;

  case 1:
    repReg   = &(letimer->REP1);
    syncbusy = LETIMER_SYNCBUSY_REP1;
    break;

  default:
    /* Unknown compare register selected, abort */
    return;
  }

  /* LF register about to be modified require sync. busy check */
  LETIMER_Sync(letimer, syncbusy);

  *repReg = value;
}
Exemple #2
0
/***************************************************************************//**
 * @brief
 *   Set LETIMER compare register value.
 *
 * @note
 *   The setting of a compare register requires synchronization into the
 *   low frequency domain. If the same register is modified before a previous
 *   update has completed, this function will stall until the previous
 *   synchronization has completed. This only applies to the Gecko Family, see
 *   comment in the LETIMER_Sync() internal function call.
 *
 * @param[in] letimer
 *   Pointer to LETIMER peripheral register block
 *
 * @param[in] comp
 *   Compare register to set, either 0 or 1
 *
 * @param[in] value
 *   Initialization value (<= 0x0000ffff)
 ******************************************************************************/
void LETIMER_CompareSet(LETIMER_TypeDef *letimer,
                        unsigned int comp,
                        uint32_t value)
{
  volatile uint32_t *compReg;

  EFM_ASSERT(LETIMER_REF_VALID(letimer) &&
             LETIMER_COMP_REG_VALID(comp) &&
             ((value & ~(_LETIMER_COMP0_COMP0_MASK >> _LETIMER_COMP0_COMP0_SHIFT)) == 0));

  /* Initialize selected compare value */
  switch (comp)
  {
  case 0:
    compReg  = &(letimer->COMP0);
    break;

  case 1:
    compReg  = &(letimer->COMP1);
    break;

  default:
    /* Unknown compare register selected, abort */
    return;
  }

#if defined(_EFM32_GECKO_FAMILY)
  /* LF register about to be modified require sync. busy check */
  LETIMER_Sync(letimer, comp ? LETIMER_SYNCBUSY_COMP1 : LETIMER_SYNCBUSY_COMP0);
#endif

  *compReg = value;
}
Exemple #3
0
/***************************************************************************//**
 * @brief
 *   Start/stop LETIMER.
 *
 * @note
 *   The enabling/disabling of the LETIMER modifies the LETIMER CMD register
 *   which requires synchronization into the low frequency domain. If this
 *   register is modified before a previous update to the same register has
 *   completed, this function will stall until the previous synchronization has
 *   completed.
 *
 * @param[in] letimer
 *   Pointer to LETIMER peripheral register block.
 *
 * @param[in] enable
 *   true to enable counting, false to disable.
 ******************************************************************************/
void LETIMER_Enable(LETIMER_TypeDef *letimer, bool enable)
{
  EFM_ASSERT(LETIMER_REF_VALID(letimer));

  /* LF register about to be modified require sync. busy check */
  LETIMER_Sync(letimer, LETIMER_SYNCBUSY_CMD);

  if (enable)
  {
    letimer->CMD = LETIMER_CMD_START;
  }
  else
  {
    letimer->CMD = LETIMER_CMD_STOP;
  }
}
Exemple #4
0
/***************************************************************************//**
 * @brief
 *   Initialize LETIMER.
 *
 * @details
 *   Note that the compare/repeat values must be set separately with
 *   LETIMER_CompareSet() and LETIMER_RepeatSet(). That should probably be done
 *   prior to the use of this function if configuring the LETIMER to start when
 *   initialization is completed.
 *
 * @note
 *   The initialization of the LETIMER modifies the LETIMER CTRL/CMD registers
 *   which require synchronization into the low frequency domain. If any of those
 *   registers are modified before a previous update to the same register has
 *   completed, this function will stall until the previous synchronization has
 *   completed. This only applies to the Gecko Family, see comment in the
 *   LETIMER_Sync() internal function call.
 *
 * @param[in] letimer
 *   Pointer to LETIMER peripheral register block.
 *
 * @param[in] init
 *   Pointer to LETIMER initialization structure.
 ******************************************************************************/
void LETIMER_Init(LETIMER_TypeDef *letimer, const LETIMER_Init_TypeDef *init)
{
  uint32_t tmp = 0;

  EFM_ASSERT(LETIMER_REF_VALID(letimer));

  /* Stop timer if specified to be disabled and running */
  if (!(init->enable) && (letimer->STATUS & LETIMER_STATUS_RUNNING))
  {
#if defined(_EFM32_GECKO_FAMILY)
    /* LF register about to be modified require sync. busy check */
    LETIMER_Sync(letimer, LETIMER_SYNCBUSY_CMD);
#endif
    letimer->CMD = LETIMER_CMD_STOP;
  }

  /* Configure DEBUGRUN flag, sets whether or not counter should be
   * updated when debugger is active */
  if (init->debugRun)
  {
    tmp |= LETIMER_CTRL_DEBUGRUN;
  }

  if (init->rtcComp0Enable)
  {
    tmp |= LETIMER_CTRL_RTCC0TEN;
  }

  if (init->rtcComp1Enable)
  {
    tmp |= LETIMER_CTRL_RTCC1TEN;
  }

  if (init->comp0Top)
  {
    tmp |= LETIMER_CTRL_COMP0TOP;
  }

  if (init->bufTop)
  {
    tmp |= LETIMER_CTRL_BUFTOP;
  }

  if (init->out0Pol)
  {
    tmp |= LETIMER_CTRL_OPOL0;
  }

  if (init->out1Pol)
  {
    tmp |= LETIMER_CTRL_OPOL1;
  }

  tmp |= init->ufoa0 << _LETIMER_CTRL_UFOA0_SHIFT;
  tmp |= init->ufoa1 << _LETIMER_CTRL_UFOA1_SHIFT;
  tmp |= init->repMode << _LETIMER_CTRL_REPMODE_SHIFT;

#if defined(_EFM32_GECKO_FAMILY)
  /* LF register about to be modified require sync. busy check */
  LETIMER_Sync(letimer, LETIMER_SYNCBUSY_CTRL);
#endif
  letimer->CTRL = tmp;

  /* Start timer if specified to be enabled and not already running */
  if (init->enable && !(letimer->STATUS & LETIMER_STATUS_RUNNING))
  {
#if defined(_EFM32_GECKO_FAMILY)
    /* LF register about to be modified require sync. busy check */
    LETIMER_Sync(letimer, LETIMER_SYNCBUSY_CMD);
#endif
    letimer->CMD = LETIMER_CMD_START;
  }
}