/***************************************************************************//** * @brief * Get LETIMER repeat register value. * * @param[in] letimer * Pointer to LETIMER peripheral register block * * @param[in] rep * Repeat register to get, either 0 or 1 * * @return * Repeat register value, 0 if invalid register selected. ******************************************************************************/ uint32_t LETIMER_RepeatGet(LETIMER_TypeDef *letimer, unsigned int rep) { uint32_t ret; EFM_ASSERT(LETIMER_REF_VALID(letimer) && LETIMER_REP_REG_VALID(rep)); /* Initialize selected compare value */ switch (rep) { case 0: ret = letimer->REP0; break; case 1: ret = letimer->REP1; break; default: /* Unknown compare register selected */ ret = 0; break; } return(ret); }
/***************************************************************************//** * @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; } }
/***************************************************************************//** * @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. This only applies to the Gecko Family. See comments in the * LETIMER_Sync() internal function call. * * @param[in] letimer * A pointer to the 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)); #if defined(_EFM32_GECKO_FAMILY) /* LF register about to be modified requires sync; busy check. */ regSync(letimer, LETIMER_SYNCBUSY_CMD); #elif defined (LETIMER_SYNCBUSY_START) && defined (LETIMER_SYNCBUSY_STOP) uint32_t syncBusyMask = LETIMER_SYNCBUSY_STOP | LETIMER_SYNCBUSY_START; while (letimer->SYNCBUSY & syncBusyMask) { } #endif if (enable) { letimer->CMD = LETIMER_CMD_START; } else { letimer->CMD = LETIMER_CMD_STOP; } }
/***************************************************************************//** * @brief * Get the LETIMER compare register value. * * @param[in] letimer * A pointer to the LETIMER peripheral register block. * * @param[in] comp * A compare register to get, either 0 or 1. * * @return * A compare register value, 0 if invalid register selected. ******************************************************************************/ uint32_t LETIMER_CompareGet(LETIMER_TypeDef *letimer, unsigned int comp) { uint32_t ret; EFM_ASSERT(LETIMER_REF_VALID(letimer) && LETIMER_COMP_REG_VALID(comp)); /* Initialize the selected compare value. */ switch (comp) { case 0: ret = letimer->COMP0; break; case 1: ret = letimer->COMP1; break; default: /* An unknown compare register selected. */ ret = 0; break; } return(ret); }
/***************************************************************************//** * @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; } }
/***************************************************************************//** * @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 using this function if configuring the LETIMER to start when * initialization is complete. * * @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 comments in the * LETIMER_Sync() internal function call. * * @param[in] letimer * A pointer to the LETIMER peripheral register block. * * @param[in] init * A pointer to the LETIMER initialization structure. ******************************************************************************/ void LETIMER_Init(LETIMER_TypeDef *letimer, const LETIMER_Init_TypeDef *init) { uint32_t tmp = 0; EFM_ASSERT(LETIMER_REF_VALID(letimer)); #if defined (LETIMER_EN_EN) letimer->EN_SET = LETIMER_EN_EN; #endif /* Stop the 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 requires sync; busy check. */ regSync(letimer, LETIMER_SYNCBUSY_CMD); #elif defined(LETIMER_SYNCBUSY_STOP) while (letimer->SYNCBUSY & LETIMER_SYNCBUSY_STOP) { } #endif letimer->CMD = LETIMER_CMD_STOP; } /* Configure the DEBUGRUN flag, which sets whether or not the counter should be * updated when the debugger is active. */ if (init->debugRun) { tmp |= LETIMER_CTRL_DEBUGRUN; } #if defined(LETIMER_CTRL_RTCC0TEN) if (init->rtcComp0Enable) { tmp |= LETIMER_CTRL_RTCC0TEN; } if (init->rtcComp1Enable) { tmp |= LETIMER_CTRL_RTCC1TEN; } #endif if ((init->comp0Top) || (init->topValue != 0U)) { #if defined (LETIMER_CTRL_COMP0TOP) tmp |= LETIMER_CTRL_COMP0TOP; letimer->COMP0 = init->topValue; #elif defined (LETIMER_CTRL_CNTTOPEN) tmp |= LETIMER_CTRL_CNTTOPEN; letimer->TOP = init->topValue; #endif } 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 requires sync; busy check. */ regSync(letimer, LETIMER_SYNCBUSY_CTRL); #endif letimer->CTRL = tmp; /* Start the 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 requires sync; busy check. */ regSync(letimer, LETIMER_SYNCBUSY_CMD); #elif defined(LETIMER_SYNCBUSY_START) while (letimer->SYNCBUSY & LETIMER_SYNCBUSY_START) { } #endif letimer->CMD = LETIMER_CMD_START; } }