| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659 |
- /***************************************************************************//**
- * @file
- * @brief Pulse Counter (PCNT) peripheral API
- * @author Energy Micro AS
- * @version 3.0.0
- *******************************************************************************
- * @section License
- * <b>(C) Copyright 2012 Energy Micro AS, http://www.energymicro.com</b>
- *******************************************************************************
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software.
- * 2. Altered source versions must be plainly marked as such, and must not be
- * misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- *
- * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
- * obligation to support this Software. Energy Micro AS is providing the
- * Software "AS IS", with no express or implied warranties of any kind,
- * including, but not limited to, any implied warranties of merchantability
- * or fitness for any particular purpose or warranties against infringement
- * of any proprietary rights of a third party.
- *
- * Energy Micro AS will not be liable for any consequential, incidental, or
- * special damages, or any other relief, or for any claim by any third party,
- * arising from your use of this Software.
- *
- ******************************************************************************/
- #include "em_pcnt.h"
- #include "em_cmu.h"
- #include "em_assert.h"
- #include "em_bitband.h"
- /***************************************************************************//**
- * @addtogroup EM_Library
- * @{
- ******************************************************************************/
- /***************************************************************************//**
- * @addtogroup PCNT
- * @brief Pulse Counter (PCNT) Peripheral API
- * @{
- ******************************************************************************/
- /*******************************************************************************
- ******************************* DEFINES ***********************************
- ******************************************************************************/
- /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
- /** Validation of PCNT register block pointer reference for assert statements. */
- #if (PCNT_COUNT == 1)
- #define PCNT_REF_VALID(ref) ((ref) == PCNT0)
- #elif (PCNT_COUNT == 2)
- #define PCNT_REF_VALID(ref) (((ref) == PCNT0) || ((ref) == PCNT1))
- #elif (PCNT_COUNT == 3)
- #define PCNT_REF_VALID(ref) (((ref) == PCNT0) || ((ref) == PCNT1) || \
- ((ref) == PCNT2))
- #else
- #error Undefined number of pulse counters (PCNT).
- #endif
- /** @endcond */
- /*******************************************************************************
- ************************** LOCAL FUNCTIONS ********************************
- ******************************************************************************/
- /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
- /***************************************************************************//**
- * @brief
- * Map PCNT structure into instance number.
- *
- * @param[in] pcnt
- * Pointer to PCNT peripheral register block
- *
- * @return
- * Instance number.
- ******************************************************************************/
- __STATIC_INLINE unsigned int PCNT_Map(PCNT_TypeDef *pcnt)
- {
- return(((uint32_t)pcnt - PCNT0_BASE) / 0x400);
- }
- /***************************************************************************//**
- * @brief
- * Wait for ongoing sync of register(s) to low frequency domain to complete.
- *
- * @param[in] pcnt
- * Pointer to PCNT peripheral register block
- *
- * @param[in] mask
- * Bitmask corresponding to SYNCBUSY register defined bits, indicating
- * registers that must complete any ongoing synchronization.
- ******************************************************************************/
- __STATIC_INLINE void PCNT_Sync(PCNT_TypeDef *pcnt, uint32_t mask)
- {
- /* Avoid deadlock if modifying the same register twice when freeze mode is
- * activated. */
- if (pcnt->FREEZE & PCNT_FREEZE_REGFREEZE)
- {
- return;
- }
- /* Wait for any pending previous write operation to have been completed in low
- * frequency domain. */
- while (pcnt->SYNCBUSY & mask)
- ;
- }
- /** @endcond */
- /*******************************************************************************
- ************************** GLOBAL FUNCTIONS *******************************
- ******************************************************************************/
- /***************************************************************************//**
- * @brief
- * Reset PCNT counters and TOP register.
- *
- * @note
- * Notice that special SYNCBUSY handling is not applicable for the RSTEN
- * bit of the control register, so we don't need to wait for it when only
- * modifying RSTEN. (It would mean undefined wait time if clocked by external
- * clock.) The SYNCBUSY bit will however be set, leading to a synchronization
- * in the LF domain, with in reality no changes.
- *
- * @param[in] pcnt
- * Pointer to PCNT peripheral register block.
- ******************************************************************************/
- void PCNT_CounterReset(PCNT_TypeDef *pcnt)
- {
- EFM_ASSERT(PCNT_REF_VALID(pcnt));
- /* Enable reset of CNT and TOP register */
- BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 1);
- /* Disable reset of CNT and TOP register */
- BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 0);
- }
- /***************************************************************************//**
- * @brief
- * Set counter and top values.
- *
- * @details
- * The pulse counter is disabled while changing these values, and reenabled
- * (if originally enabled) when values have been set.
- *
- * @note
- * This function will stall until synchronization to low frequency domain is
- * completed. For that reason, it should normally not be used when using
- * an external clock to clock the PCNT module, since stall time may be
- * undefined in that case. The counter should normally only be set when
- * operating in (or about to enable) #pcntModeOvsSingle mode.
- *
- * @param[in] pcnt
- * Pointer to PCNT peripheral register block.
- *
- * @param[in] count
- * Value to set in counter register.
- *
- * @param[in] top
- * Value to set in top register.
- ******************************************************************************/
- void PCNT_CounterTopSet(PCNT_TypeDef *pcnt, uint32_t count, uint32_t top)
- {
- uint32_t ctrl;
- EFM_ASSERT(PCNT_REF_VALID(pcnt));
- /* Keep current control setting, must be restored */
- ctrl = pcnt->CTRL;
- /* If enabled, disable pulse counter before changing values */
- if ((ctrl & _PCNT_CTRL_MODE_MASK) != PCNT_CTRL_MODE_DISABLE)
- {
- PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
- pcnt->CTRL = (ctrl & ~_PCNT_CTRL_MODE_MASK) | PCNT_CTRL_MODE_DISABLE;
- }
- /* Load into TOPB */
- PCNT_Sync(pcnt, PCNT_SYNCBUSY_TOPB);
- pcnt->TOPB = count;
- /* Load TOPB value into TOP */
- PCNT_Sync(pcnt, PCNT_SYNCBUSY_TOPB | PCNT_SYNCBUSY_CMD);
- /* This bit has no effect on rev. C and onwards parts - for compatibility */
- pcnt->CMD = PCNT_CMD_LTOPBIM;
- PCNT_Sync(pcnt, PCNT_SYNCBUSY_CMD);
- /* Load TOP into CNT */
- pcnt->CMD = PCNT_CMD_LCNTIM;
- /* Restore TOP? ('count' setting has been loaded into pcnt->TOP, better
- * to use 'top' than pcnt->TOP in compare, since latter may in theory not
- * be visible yet.) */
- if (top != count)
- {
- /* Wait for command to sync LCNTIM before setting TOPB */
- PCNT_Sync(pcnt, PCNT_SYNCBUSY_CMD);
- /* Load into TOPB, we don't need to check for TOPB sync complete here,
- * it has been ensured above. */
- pcnt->TOPB = top;
- /* Load TOPB value into TOP */
- PCNT_Sync(pcnt, PCNT_SYNCBUSY_TOPB | PCNT_SYNCBUSY_CMD);
- pcnt->CMD = PCNT_CMD_LTOPBIM;
- }
- /* Reenable if it was enabled */
- if ((ctrl & _PCNT_CTRL_MODE_MASK) != PCNT_CTRL_MODE_DISABLE)
- {
- PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL | PCNT_SYNCBUSY_CMD);
- pcnt->CTRL = ctrl;
- }
- }
- /***************************************************************************//**
- * @brief
- * Set PCNT operational mode.
- *
- * @details
- * Notice that this function does not do any configuration. Setting operational
- * mode is normally only required after initialization is done, and if not
- * done as part of initialization. Or if requiring to disable/reenable pulse
- * counter.
- *
- * @note
- * This function may stall until synchronization to low frequency domain is
- * completed. For that reason, it should normally not be used when using
- * an external clock to clock the PCNT module, since stall time may be
- * undefined in that case.
- *
- * @param[in] pcnt
- * Pointer to PCNT peripheral register block.
- *
- * @param[in] mode
- * Operational mode to use for PCNT.
- ******************************************************************************/
- void PCNT_Enable(PCNT_TypeDef *pcnt, PCNT_Mode_TypeDef mode)
- {
- uint32_t tmp;
- EFM_ASSERT(PCNT_REF_VALID(pcnt));
- /* Set as specified */
- tmp = pcnt->CTRL & ~_PCNT_CTRL_MODE_MASK;
- tmp |= (uint32_t)mode << _PCNT_CTRL_MODE_SHIFT;
- /* LF register about to be modified require sync. busy check */
- PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
- pcnt->CTRL = tmp;
- }
- #if (defined (_EFM32_TINY_FAMILY) || defined (_EFM32_GIANT_FAMILY))
- /***************************************************************************//**
- * @brief
- * Enable/disable the selected PRS input of PCNT.
- *
- * @details
- * Notice that this function does not do any configuration.
- *
- * @param[in] pcnt
- * Pointer to PCNT peripheral register block.
- *
- * @param[in] prsInput
- * PRS input (S0 or S1) of the selected PCNT module.
- *
- * @param[in] enable
- * Set to true to enable, false to disable the selected PRS input.
- ******************************************************************************/
- void PCNT_PRSInputEnable(PCNT_TypeDef *pcnt,
- PCNT_PRSInput_TypeDef prsInput,
- bool enable)
- {
- EFM_ASSERT(PCNT_REF_VALID(pcnt));
- /* Enable/disable the selected PRS input on the selected PCNT module. */
- switch (prsInput)
- {
- /* Enable/disable PRS input S0. */
- case pcntPRSInputS0:
- {
- BITBAND_Peripheral(&(pcnt->INPUT), _PCNT_INPUT_S0PRSEN_SHIFT, (uint32_t)enable);
- }
- break;
- /* Enable/disable PRS input S1. */
- case pcntPRSInputS1:
- {
- BITBAND_Peripheral(&(pcnt->INPUT), _PCNT_INPUT_S1PRSEN_SHIFT, (uint32_t)enable);
- }
- break;
- /* Invalid parameter, asserted. */
- default:
- {
- EFM_ASSERT(0);
- }
- break;
- }
- }
- #endif
- /***************************************************************************//**
- * @brief
- * PCNT register synchronization freeze control.
- *
- * @details
- * Some PCNT registers require synchronization into the low frequency (LF)
- * domain. The freeze feature allows for several such registers to be
- * modified before passing them to the LF domain simultaneously (which
- * takes place when the freeze mode is disabled).
- *
- * @note
- * When enabling freeze mode, this function will wait for all current
- * ongoing PCNT synchronization to LF domain to complete (Normally
- * synchronization will not be in progress.) However for this reason, when
- * using freeze mode, modifications of registers requiring LF synchronization
- * should be done within one freeze enable/disable block to avoid unecessary
- * stalling.
- *
- * @param[in] pcnt
- * Pointer to PCNT peripheral register block.
- *
- * @param[in] enable
- * @li true - enable freeze, modified registers are not propagated to the
- * LF domain
- * @li false - disables freeze, modified registers are propagated to LF
- * domain
- ******************************************************************************/
- void PCNT_FreezeEnable(PCNT_TypeDef *pcnt, bool enable)
- {
- EFM_ASSERT(PCNT_REF_VALID(pcnt));
- if (enable)
- {
- /* Wait for any ongoing LF synchronization to complete. This is just to
- * protect against the rare case when a user:
- * - modifies a register requiring LF sync
- * - then enables freeze before LF sync completed
- * - then modifies the same register again
- * since modifying a register while it is in sync progress should be
- * avoided. */
- while (pcnt->SYNCBUSY)
- ;
- pcnt->FREEZE = PCNT_FREEZE_REGFREEZE;
- }
- else
- {
- pcnt->FREEZE = 0;
- }
- }
- /***************************************************************************//**
- * @brief
- * Init pulse counter.
- *
- * @details
- * This function will configure the pulse counter. The clock selection is
- * configured as follows, depending on operational mode:
- *
- * @li #pcntModeOvsSingle - Use LFACLK.
- * @li #pcntModeExtSingle - Use external PCNTn_S0 pin.
- * @li #pcntModeExtQuad - Use external PCNTn_S0 pin.
- *
- * Notice that the LFACLK must be enabled in all modes, since some basic setup
- * is done with this clock even if external pin clock usage mode is chosen.
- * The pulse counter clock for the selected instance must also be enabled
- * prior to init.
- *
- * Notice that pins used by the PCNT module must be properly configured
- * by the user explicitly through setting the ROUTE register, in order for
- * the PCNT to work as intended.
- *
- * Writing to CNT will not occur in external clock modes (EXTCLKQUAD and
- * EXTCLKSINGLE) because the external clock rate is unknown. The user should
- * handle it manually depending on the application
- *
- * TOPB is written for all modes but in external clock mode it will take
- * 3 external clock cycles to sync to TOP
- *
- *
- * @note
- * Initializing requires synchronization into the low frequency domain. This
- * may cause some delay.
- *
- * @param[in] pcnt
- * Pointer to PCNT peripheral register block.
- *
- * @param[in] init
- * Pointer to initialization structure used to initialize.
- ******************************************************************************/
- void PCNT_Init(PCNT_TypeDef *pcnt, const PCNT_Init_TypeDef *init)
- {
- unsigned int inst;
- uint32_t tmp;
- EFM_ASSERT(PCNT_REF_VALID(pcnt));
- /* Map pointer to instance */
- inst = PCNT_Map(pcnt);
- #if (defined (_EFM32_TINY_FAMILY) || defined (_EFM32_GIANT_FAMILY))
- /* Selecting the PRS channels for the PRS input sources of the PCNT. These are
- * written with a Read-Modify-Write sequence in order to keep the value of the
- * input enable bits which can be modified using PCNT_PRSInputEnable(). */
- tmp = pcnt->INPUT & ~(_PCNT_INPUT_S0PRSSEL_MASK | _PCNT_INPUT_S1PRSSEL_MASK);
- tmp |= ((uint32_t)init->s0PRS << _PCNT_INPUT_S0PRSSEL_SHIFT) |
- ((uint32_t)init->s1PRS << _PCNT_INPUT_S1PRSSEL_SHIFT);
- pcnt->INPUT = tmp;
- #endif
- /* Build CTRL setting, except for mode */
- tmp = 0;
- if (init->negEdge)
- {
- tmp |= PCNT_CTRL_EDGE_NEG;
- }
- if (init->countDown)
- {
- tmp |= PCNT_CTRL_CNTDIR_DOWN;
- }
- if (init->filter)
- {
- tmp |= PCNT_CTRL_FILT;
- }
- #if (defined (_EFM32_TINY_FAMILY) || defined (_EFM32_GIANT_FAMILY))
- if (init->hyst)
- {
- tmp |= PCNT_CTRL_HYST;
- }
- if (init->s1CntDir)
- {
- tmp |= PCNT_CTRL_S1CDIR;
- }
- /* Configure counter events for regular and auxiliary counter. */
- tmp |= init->cntEvent << _PCNT_CTRL_CNTEV_SHIFT;
- tmp |= init->auxCntEvent << _PCNT_CTRL_AUXCNTEV_SHIFT;
- #endif
- /* Reset pulse counter while changing clock source. The reset bit */
- /* is asynchronous, we don't have to check for SYNCBUSY. */
- BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 1);
- /* Select LFACLK to clock in control setting */
- CMU_PCNTClockExternalSet(inst, false);
- /* Handling depends on whether using external clock or not. */
- switch (init->mode)
- {
- case pcntModeExtSingle:
- case pcntModeExtQuad:
- tmp |= init->mode << _PCNT_CTRL_MODE_SHIFT;
- /* In most cases, the SYNCBUSY bit is set due to reset bit set, and waiting
- * for asynchronous reset bit is strictly not necessary.
- * But in theory, other operations on CTRL register may have been done
- * outside this function, so wait. */
- PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
- /* Enable PCNT Clock Domain Reset. The PCNT must be in reset before changing
- * the clock source to an external clock */
- pcnt->CTRL = PCNT_CTRL_RSTEN;
- /* Wait until CTRL write synchronized into LF domain. */
- PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
- /* Change to external clock BEFORE disabling reset */
- CMU_PCNTClockExternalSet(inst, true);
- /* Write to TOPB. If using external clock TOPB will sync to TOP at the same
- * time as the mode. This will insure that if the user chooses to count
- * down, the first "countable" pulse will make CNT go to TOP and not 0xFF
- * (default TOP value). */
- pcnt->TOPB = init->top;
- /* This bit has no effect on rev. C and onwards parts - for compatibility */
- pcnt->CMD = PCNT_CMD_LTOPBIM;
- /* Write the CTRL register with the configurations.
- * This should be written after TOPB in the eventuality of a pulse between
- * these two writes that would cause the CTRL register to be synced one
- * clock cycle earlier than the TOPB. */
- pcnt->CTRL = tmp;
- /* There are no syncs for TOP, CMD or CTRL because the clock rate is unknown
- * and the program could stall
- * These will be synced within 3 clock cycles of the external clock /
- * For the same reason CNT cannot be written here. */
- break;
- /* pcntModeDisable */
- /* pcntModeOvsSingle */
- default:
- /* No need to set disabled mode if already disabled. */
- if ((pcnt->CTRL & _PCNT_CTRL_MODE_MASK) != PCNT_CTRL_MODE_DISABLE)
- {
- /* Set control to disabled mode, leave reset on until ensured disabled.
- * We don't need to wait for CTRL SYNCBUSY completion here, it was
- * triggered by reset bit above, which is asynchronous. */
- pcnt->CTRL = tmp | PCNT_CTRL_MODE_DISABLE | PCNT_CTRL_RSTEN;
- /* Wait until CTRL write synchronized into LF domain before proceeding
- * to disable reset. */
- PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
- }
- /* Disable reset bit, counter should now be in disabled mode. */
- BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 0);
- /* Set counter and top values as specified. */
- PCNT_CounterTopSet(pcnt, init->counter, init->top);
- /* Enter oversampling mode if selected. */
- if (init->mode == pcntModeOvsSingle)
- {
- PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
- pcnt->CTRL = tmp | (init->mode << _PCNT_CTRL_MODE_SHIFT);
- }
- break;
- }
- }
- /***************************************************************************//**
- * @brief
- * Reset PCNT to same state as after a HW reset.
- *
- * @details
- * Notice the LFACLK must be enabled, since some basic reset is done with
- * this clock. The pulse counter clock for the selected instance must also
- * be enabled prior to init.
- *
- * @note
- * The ROUTE register is NOT reset by this function, in order to allow for
- * centralized setup of this feature.
- *
- * @param[in] pcnt
- * Pointer to PCNT peripheral register block.
- ******************************************************************************/
- void PCNT_Reset(PCNT_TypeDef *pcnt)
- {
- unsigned int inst;
- EFM_ASSERT(PCNT_REF_VALID(pcnt));
- /* Map pointer to instance and clock info */
- inst = PCNT_Map(pcnt);
- pcnt->IEN = _PCNT_IEN_RESETVALUE;
- /* Notice that special SYNCBUSY handling is not applicable for the RSTEN
- * bit of the control register, so we don't need to wait for it when only
- * modifying RSTEN. The SYNCBUSY bit will be set, leading to a
- * synchronization in the LF domain, with in reality no changes to LF domain.
- * Enable reset of CNT and TOP register. */
- BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 1);
- /* Select LFACLK as default */
- CMU_PCNTClockExternalSet(inst, false);
- PCNT_TopBufferSet(pcnt, _PCNT_TOPB_RESETVALUE);
- /* Reset CTRL leaving RSTEN set */
- pcnt->CTRL = _PCNT_CTRL_RESETVALUE | PCNT_CTRL_RSTEN;
- /* Disable reset after CTRL reg has been synchronized */
- PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
- BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 0);
- /* Clear pending interrupts */
- pcnt->IFC = _PCNT_IFC_MASK;
- /* Do not reset route register, setting should be done independently */
- }
- /***************************************************************************//**
- * @brief
- * Set top buffer value.
- *
- * @note
- * This function may stall until synchronization to low frequency domain is
- * completed. For that reason, it should normally not be used when using
- * an external clock to clock the PCNT module, since stall time may be
- * undefined in that case.
- *
- * @param[in] pcnt
- * Pointer to PCNT peripheral register block.
- *
- * @param[in] val
- * Value to set in top buffer register.
- ******************************************************************************/
- void PCNT_TopBufferSet(PCNT_TypeDef *pcnt, uint32_t val)
- {
- EFM_ASSERT(PCNT_REF_VALID(pcnt));
- /* LF register about to be modified require sync. busy check */
- PCNT_Sync(pcnt, PCNT_SYNCBUSY_TOPB);
- pcnt->TOPB = val;
- }
- /***************************************************************************//**
- * @brief
- * Set top value.
- *
- * @note
- * This function will stall until synchronization to low frequency domain is
- * completed. For that reason, it should normally not be used when using
- * an external clock to clock the PCNT module, since stall time may be
- * undefined in that case.
- *
- * @param[in] pcnt
- * Pointer to PCNT peripheral register block.
- *
- * @param[in] val
- * Value to set in top register.
- ******************************************************************************/
- void PCNT_TopSet(PCNT_TypeDef *pcnt, uint32_t val)
- {
- EFM_ASSERT(PCNT_REF_VALID(pcnt));
- /* LF register about to be modified require sync. busy check */
- /* Load into TOPB */
- PCNT_Sync(pcnt, PCNT_SYNCBUSY_TOPB);
- pcnt->TOPB = val;
- /* Load TOPB value into TOP */
- PCNT_Sync(pcnt, PCNT_SYNCBUSY_TOPB | PCNT_SYNCBUSY_CMD);
- pcnt->CMD = PCNT_CMD_LTOPBIM;
- }
- /** @} (end addtogroup PCNT) */
- /** @} (end addtogroup EM_Library) */
|