25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

594 lines
19 KiB

  1. /*
  2. * Copyright (c) 2015, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2019 NXP
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include "fsl_enc.h"
  9. /*******************************************************************************
  10. * Definitions
  11. ******************************************************************************/
  12. /* Component ID definition, used by tools. */
  13. #ifndef FSL_COMPONENT_ID
  14. #define FSL_COMPONENT_ID "platform.drivers.enc"
  15. #endif
  16. #define ENC_CTRL_W1C_FLAGS (ENC_CTRL_HIRQ_MASK | ENC_CTRL_XIRQ_MASK | ENC_CTRL_DIRQ_MASK | ENC_CTRL_CMPIRQ_MASK)
  17. #define ENC_CTRL2_W1C_FLAGS (ENC_CTRL2_SABIRQ_MASK | ENC_CTRL2_ROIRQ_MASK | ENC_CTRL2_RUIRQ_MASK)
  18. /*******************************************************************************
  19. * Prototypes
  20. ******************************************************************************/
  21. /*!
  22. * @brief Get instance number for ENC module.
  23. *
  24. * @param base ENC peripheral base address
  25. */
  26. static uint32_t ENC_GetInstance(ENC_Type *base);
  27. /*******************************************************************************
  28. * Variables
  29. ******************************************************************************/
  30. /*! @brief Pointers to ENC bases for each instance. */
  31. static ENC_Type *const s_encBases[] = ENC_BASE_PTRS;
  32. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  33. /*! @brief Pointers to ENC clocks for each instance. */
  34. static const clock_ip_name_t s_encClocks[] = ENC_CLOCKS;
  35. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  36. /*******************************************************************************
  37. * Code
  38. ******************************************************************************/
  39. static uint32_t ENC_GetInstance(ENC_Type *base)
  40. {
  41. uint32_t instance;
  42. /* Find the instance index from base address mappings. */
  43. for (instance = 0; instance < ARRAY_SIZE(s_encBases); instance++)
  44. {
  45. if (s_encBases[instance] == base)
  46. {
  47. break;
  48. }
  49. }
  50. assert(instance < ARRAY_SIZE(s_encBases));
  51. return instance;
  52. }
  53. /*!
  54. * brief Initialization for the ENC module.
  55. *
  56. * This function is to make the initialization for the ENC module. It should be called firstly before any operation to
  57. * the ENC with the operations like:
  58. * - Enable the clock for ENC module.
  59. * - Configure the ENC's working attributes.
  60. *
  61. * param base ENC peripheral base address.
  62. * param config Pointer to configuration structure. See to "enc_config_t".
  63. */
  64. void ENC_Init(ENC_Type *base, const enc_config_t *config)
  65. {
  66. assert(NULL != config);
  67. uint16_t tmp16;
  68. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  69. /* Enable the clock. */
  70. CLOCK_EnableClock(s_encClocks[ENC_GetInstance(base)]);
  71. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  72. /* ENC_CTRL. */
  73. tmp16 = base->CTRL & (uint16_t)(~(ENC_CTRL_W1C_FLAGS | ENC_CTRL_HIP_MASK | ENC_CTRL_HNE_MASK | ENC_CTRL_REV_MASK |
  74. ENC_CTRL_PH1_MASK | ENC_CTRL_XIP_MASK | ENC_CTRL_XNE_MASK | ENC_CTRL_WDE_MASK));
  75. /* For HOME trigger. */
  76. if (kENC_HOMETriggerDisabled != config->HOMETriggerMode)
  77. {
  78. tmp16 |= ENC_CTRL_HIP_MASK;
  79. if (kENC_HOMETriggerOnFallingEdge == config->HOMETriggerMode)
  80. {
  81. tmp16 |= ENC_CTRL_HNE_MASK;
  82. }
  83. }
  84. /* For encoder work mode. */
  85. if (config->enableReverseDirection)
  86. {
  87. tmp16 |= ENC_CTRL_REV_MASK;
  88. }
  89. if (kENC_DecoderWorkAsSignalPhaseCountMode == config->decoderWorkMode)
  90. {
  91. tmp16 |= ENC_CTRL_PH1_MASK;
  92. }
  93. /* For INDEX trigger. */
  94. if (kENC_INDEXTriggerDisabled != config->INDEXTriggerMode)
  95. {
  96. tmp16 |= ENC_CTRL_XIP_MASK;
  97. if (kENC_INDEXTriggerOnFallingEdge == config->INDEXTriggerMode)
  98. {
  99. tmp16 |= ENC_CTRL_XNE_MASK;
  100. }
  101. }
  102. /* Watchdog. */
  103. if (config->enableWatchdog)
  104. {
  105. tmp16 |= ENC_CTRL_WDE_MASK;
  106. base->WTR = config->watchdogTimeoutValue; /* WDOG can be only available when the feature is enabled. */
  107. }
  108. base->CTRL = tmp16;
  109. /* ENC_FILT. */
  110. base->FILT = ENC_FILT_FILT_CNT(config->filterCount) | ENC_FILT_FILT_PER(config->filterSamplePeriod);
  111. /* ENC_CTRL2. */
  112. tmp16 = base->CTRL2 & (uint16_t)(~(ENC_CTRL2_W1C_FLAGS | ENC_CTRL2_OUTCTL_MASK | ENC_CTRL2_REVMOD_MASK |
  113. ENC_CTRL2_MOD_MASK | ENC_CTRL2_UPDPOS_MASK | ENC_CTRL2_UPDHLD_MASK));
  114. if (kENC_POSMATCHOnReadingAnyPositionCounter == config->positionMatchMode)
  115. {
  116. tmp16 |= ENC_CTRL2_OUTCTL_MASK;
  117. }
  118. if (kENC_RevolutionCountOnRollOverModulus == config->revolutionCountCondition)
  119. {
  120. tmp16 |= ENC_CTRL2_REVMOD_MASK;
  121. }
  122. if (config->enableModuloCountMode)
  123. {
  124. tmp16 |= ENC_CTRL2_MOD_MASK;
  125. /* Set modulus value. */
  126. base->UMOD = (uint16_t)(config->positionModulusValue >> 16U); /* Upper 16 bits. */
  127. base->LMOD = (uint16_t)(config->positionModulusValue); /* Lower 16 bits. */
  128. }
  129. if (config->enableTRIGGERClearPositionCounter)
  130. {
  131. tmp16 |= ENC_CTRL2_UPDPOS_MASK;
  132. }
  133. if (config->enableTRIGGERClearHoldPositionCounter)
  134. {
  135. tmp16 |= ENC_CTRL2_UPDHLD_MASK;
  136. }
  137. base->CTRL2 = tmp16;
  138. /* ENC_UCOMP & ENC_LCOMP. */
  139. base->UCOMP = (uint16_t)(config->positionCompareValue >> 16U); /* Upper 16 bits. */
  140. base->LCOMP = (uint16_t)(config->positionCompareValue); /* Lower 16 bits. */
  141. /* ENC_UINIT & ENC_LINIT. */
  142. base->UINIT = (uint16_t)(config->positionInitialValue >> 16U); /* Upper 16 bits. */
  143. base->LINIT = (uint16_t)(config->positionInitialValue); /* Lower 16 bits. */
  144. }
  145. /*!
  146. * brief De-initialization for the ENC module.
  147. *
  148. * This function is to make the de-initialization for the ENC module. It could be called when ENC is no longer used with
  149. * the operations like:
  150. * - Disable the clock for ENC module.
  151. *
  152. * param base ENC peripheral base address.
  153. */
  154. void ENC_Deinit(ENC_Type *base)
  155. {
  156. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  157. /* Disable the clock. */
  158. CLOCK_DisableClock(s_encClocks[ENC_GetInstance(base)]);
  159. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  160. }
  161. /*!
  162. * brief Get an available pre-defined settings for ENC's configuration.
  163. *
  164. * This function initializes the ENC configuration structure with an available settings, the default value are:
  165. * code
  166. * config->enableReverseDirection = false;
  167. * config->decoderWorkMode = kENC_DecoderWorkAsNormalMode;
  168. * config->HOMETriggerMode = kENC_HOMETriggerDisabled;
  169. * config->INDEXTriggerMode = kENC_INDEXTriggerDisabled;
  170. * config->enableTRIGGERClearPositionCounter = false;
  171. * config->enableTRIGGERClearHoldPositionCounter = false;
  172. * config->enableWatchdog = false;
  173. * config->watchdogTimeoutValue = 0U;
  174. * config->filterCount = 0U;
  175. * config->filterSamplePeriod = 0U;
  176. * config->positionMatchMode = kENC_POSMATCHOnPositionCounterEqualToComapreValue;
  177. * config->positionCompareValue = 0xFFFFFFFFU;
  178. * config->revolutionCountCondition = kENC_RevolutionCountOnINDEXPulse;
  179. * config->enableModuloCountMode = false;
  180. * config->positionModulusValue = 0U;
  181. * config->positionInitialValue = 0U;
  182. * endcode
  183. * param config Pointer to a variable of configuration structure. See to "enc_config_t".
  184. */
  185. void ENC_GetDefaultConfig(enc_config_t *config)
  186. {
  187. assert(NULL != config);
  188. /* Initializes the configure structure to zero. */
  189. (void)memset(config, 0, sizeof(*config));
  190. config->enableReverseDirection = false;
  191. config->decoderWorkMode = kENC_DecoderWorkAsNormalMode;
  192. config->HOMETriggerMode = kENC_HOMETriggerDisabled;
  193. config->INDEXTriggerMode = kENC_INDEXTriggerDisabled;
  194. config->enableTRIGGERClearPositionCounter = false;
  195. config->enableTRIGGERClearHoldPositionCounter = false;
  196. config->enableWatchdog = false;
  197. config->watchdogTimeoutValue = 0U;
  198. config->filterCount = 0U;
  199. config->filterSamplePeriod = 0U;
  200. config->positionMatchMode = kENC_POSMATCHOnPositionCounterEqualToComapreValue;
  201. config->positionCompareValue = 0xFFFFFFFFU;
  202. config->revolutionCountCondition = kENC_RevolutionCountOnINDEXPulse;
  203. config->enableModuloCountMode = false;
  204. config->positionModulusValue = 0U;
  205. config->positionInitialValue = 0U;
  206. }
  207. /*!
  208. * brief Load the initial position value to position counter.
  209. *
  210. * This function is to transfer the initial position value (UINIT and LINIT) contents to position counter (UPOS and
  211. * LPOS), so that to provide the consistent operation the position counter registers.
  212. *
  213. * param base ENC peripheral base address.
  214. */
  215. void ENC_DoSoftwareLoadInitialPositionValue(ENC_Type *base)
  216. {
  217. uint16_t tmp16 = base->CTRL & (uint16_t)(~ENC_CTRL_W1C_FLAGS);
  218. tmp16 |= ENC_CTRL_SWIP_MASK; /* Write 1 to trigger the command for loading initial position value. */
  219. base->CTRL = tmp16;
  220. }
  221. /*!
  222. * brief Enable and configure the self test function.
  223. *
  224. * This function is to enable and configuration the self test function. It controls and sets the frequency of a
  225. * quadrature signal generator. It provides a quadrature test signal to the inputs of the quadrature decoder module.
  226. * It is a factory test feature; however, it may be useful to customers' software development and testing.
  227. *
  228. * param base ENC peripheral base address.
  229. * param config Pointer to configuration structure. See to "enc_self_test_config_t". Pass "NULL" to disable.
  230. */
  231. void ENC_SetSelfTestConfig(ENC_Type *base, const enc_self_test_config_t *config)
  232. {
  233. uint16_t tmp16 = 0U;
  234. if (NULL == config) /* Pass "NULL" to disable the feature. */
  235. {
  236. tmp16 = 0U;
  237. }
  238. else
  239. {
  240. tmp16 = ENC_TST_TEN_MASK | ENC_TST_TCE_MASK | ENC_TST_TEST_PERIOD(config->signalPeriod) |
  241. ENC_TST_TEST_COUNT(config->signalCount);
  242. if (kENC_SelfTestDirectionNegative == config->signalDirection)
  243. {
  244. tmp16 |= ENC_TST_QDN_MASK;
  245. }
  246. }
  247. base->TST = tmp16;
  248. }
  249. /*!
  250. * brief Enable watchdog for ENC module.
  251. *
  252. * param base ENC peripheral base address
  253. * param enable Enables or disables the watchdog
  254. */
  255. void ENC_EnableWatchdog(ENC_Type *base, bool enable)
  256. {
  257. uint16_t tmp16 = base->CTRL & (uint16_t)(~(ENC_CTRL_W1C_FLAGS | ENC_CTRL_WDE_MASK));
  258. if (enable)
  259. {
  260. tmp16 |= ENC_CTRL_WDE_MASK;
  261. }
  262. base->CTRL = tmp16;
  263. }
  264. /*!
  265. * brief Get the status flags.
  266. *
  267. * param base ENC peripheral base address.
  268. *
  269. * return Mask value of status flags. For available mask, see to "_enc_status_flags".
  270. */
  271. uint32_t ENC_GetStatusFlags(ENC_Type *base)
  272. {
  273. uint32_t ret32 = 0U;
  274. /* ENC_CTRL. */
  275. if (0U != (ENC_CTRL_HIRQ_MASK & base->CTRL))
  276. {
  277. ret32 |= (uint32_t)kENC_HOMETransitionFlag;
  278. }
  279. if (0U != (ENC_CTRL_XIRQ_MASK & base->CTRL))
  280. {
  281. ret32 |= (uint32_t)kENC_INDEXPulseFlag;
  282. }
  283. if (0U != (ENC_CTRL_DIRQ_MASK & base->CTRL))
  284. {
  285. ret32 |= (uint32_t)kENC_WatchdogTimeoutFlag;
  286. }
  287. if (0U != (ENC_CTRL_CMPIRQ_MASK & base->CTRL))
  288. {
  289. ret32 |= (uint32_t)kENC_PositionCompareFlag;
  290. }
  291. /* ENC_CTRL2. */
  292. if (0U != (ENC_CTRL2_SABIRQ_MASK & base->CTRL2))
  293. {
  294. ret32 |= (uint32_t)kENC_SimultBothPhaseChangeFlag;
  295. }
  296. if (0U != (ENC_CTRL2_ROIRQ_MASK & base->CTRL2))
  297. {
  298. ret32 |= (uint32_t)kENC_PositionRollOverFlag;
  299. }
  300. if (0U != (ENC_CTRL2_RUIRQ_MASK & base->CTRL2))
  301. {
  302. ret32 |= (uint32_t)kENC_PositionRollUnderFlag;
  303. }
  304. if (0U != (ENC_CTRL2_DIR_MASK & base->CTRL2))
  305. {
  306. ret32 |= (uint32_t)kENC_LastCountDirectionFlag;
  307. }
  308. return ret32;
  309. }
  310. /*!
  311. * brief Clear the status flags.
  312. *
  313. * param base ENC peripheral base address.
  314. * param mask Mask value of status flags to be cleared. For available mask, see to "_enc_status_flags".
  315. */
  316. void ENC_ClearStatusFlags(ENC_Type *base, uint32_t mask)
  317. {
  318. uint32_t tmp16 = 0U;
  319. /* ENC_CTRL. */
  320. if (0U != ((uint32_t)kENC_HOMETransitionFlag & mask))
  321. {
  322. tmp16 |= ENC_CTRL_HIRQ_MASK;
  323. }
  324. if (0U != ((uint32_t)kENC_INDEXPulseFlag & mask))
  325. {
  326. tmp16 |= ENC_CTRL_XIRQ_MASK;
  327. }
  328. if (0U != ((uint32_t)kENC_WatchdogTimeoutFlag & mask))
  329. {
  330. tmp16 |= ENC_CTRL_DIRQ_MASK;
  331. }
  332. if (0U != ((uint32_t)kENC_PositionCompareFlag & mask))
  333. {
  334. tmp16 |= ENC_CTRL_CMPIRQ_MASK;
  335. }
  336. if (0U != tmp16)
  337. {
  338. base->CTRL = (uint16_t)(((uint32_t)base->CTRL & (~ENC_CTRL_W1C_FLAGS)) | tmp16);
  339. }
  340. /* ENC_CTRL2. */
  341. tmp16 = 0U;
  342. if (0U != ((uint32_t)kENC_SimultBothPhaseChangeFlag & mask))
  343. {
  344. tmp16 |= ENC_CTRL2_SABIRQ_MASK;
  345. }
  346. if (0U != ((uint32_t)kENC_PositionRollOverFlag & mask))
  347. {
  348. tmp16 |= ENC_CTRL2_ROIRQ_MASK;
  349. }
  350. if (0U != ((uint32_t)kENC_PositionRollUnderFlag & mask))
  351. {
  352. tmp16 |= ENC_CTRL2_RUIRQ_MASK;
  353. }
  354. if (0U != tmp16)
  355. {
  356. base->CTRL2 = (uint16_t)(((uint32_t)base->CTRL2 & (~ENC_CTRL2_W1C_FLAGS)) | tmp16);
  357. }
  358. }
  359. /*!
  360. * brief Enable the interrupts.
  361. *
  362. * param base ENC peripheral base address.
  363. * param mask Mask value of interrupts to be enabled. For available mask, see to "_enc_interrupt_enable".
  364. */
  365. void ENC_EnableInterrupts(ENC_Type *base, uint32_t mask)
  366. {
  367. uint32_t tmp16 = 0U;
  368. /* ENC_CTRL. */
  369. if (0U != ((uint32_t)kENC_HOMETransitionInterruptEnable & mask))
  370. {
  371. tmp16 |= ENC_CTRL_HIE_MASK;
  372. }
  373. if (0U != ((uint32_t)kENC_INDEXPulseInterruptEnable & mask))
  374. {
  375. tmp16 |= ENC_CTRL_XIE_MASK;
  376. }
  377. if (0U != ((uint32_t)kENC_WatchdogTimeoutInterruptEnable & mask))
  378. {
  379. tmp16 |= ENC_CTRL_DIE_MASK;
  380. }
  381. if (0U != ((uint32_t)kENC_PositionCompareInerruptEnable & mask))
  382. {
  383. tmp16 |= ENC_CTRL_CMPIE_MASK;
  384. }
  385. if (tmp16 != 0U)
  386. {
  387. base->CTRL = (uint16_t)(((uint32_t)base->CTRL & (~ENC_CTRL_W1C_FLAGS)) | tmp16);
  388. }
  389. /* ENC_CTRL2. */
  390. tmp16 = 0U;
  391. if (0U != ((uint32_t)kENC_SimultBothPhaseChangeInterruptEnable & mask))
  392. {
  393. tmp16 |= ENC_CTRL2_SABIE_MASK;
  394. }
  395. if (0U != ((uint32_t)kENC_PositionRollOverInterruptEnable & mask))
  396. {
  397. tmp16 |= ENC_CTRL2_ROIE_MASK;
  398. }
  399. if (0U != ((uint32_t)kENC_PositionRollUnderInterruptEnable & mask))
  400. {
  401. tmp16 |= ENC_CTRL2_RUIE_MASK;
  402. }
  403. if (tmp16 != 0U)
  404. {
  405. base->CTRL2 = (uint16_t)(((uint32_t)base->CTRL2 & (~ENC_CTRL2_W1C_FLAGS)) | tmp16);
  406. }
  407. }
  408. /*!
  409. * brief Disable the interrupts.
  410. *
  411. * param base ENC peripheral base address.
  412. * param mask Mask value of interrupts to be disabled. For available mask, see to "_enc_interrupt_enable".
  413. */
  414. void ENC_DisableInterrupts(ENC_Type *base, uint32_t mask)
  415. {
  416. uint16_t tmp16 = 0U;
  417. /* ENC_CTRL. */
  418. if (0U != ((uint32_t)kENC_HOMETransitionInterruptEnable & mask))
  419. {
  420. tmp16 |= ENC_CTRL_HIE_MASK;
  421. }
  422. if (0U != ((uint32_t)kENC_INDEXPulseInterruptEnable & mask))
  423. {
  424. tmp16 |= ENC_CTRL_XIE_MASK;
  425. }
  426. if (0U != ((uint32_t)kENC_WatchdogTimeoutInterruptEnable & mask))
  427. {
  428. tmp16 |= ENC_CTRL_DIE_MASK;
  429. }
  430. if (0U != ((uint32_t)kENC_PositionCompareInerruptEnable & mask))
  431. {
  432. tmp16 |= ENC_CTRL_CMPIE_MASK;
  433. }
  434. if (0U != tmp16)
  435. {
  436. base->CTRL = (uint16_t)(base->CTRL & (uint16_t)(~ENC_CTRL_W1C_FLAGS)) & (uint16_t)(~tmp16);
  437. }
  438. /* ENC_CTRL2. */
  439. tmp16 = 0U;
  440. if (0U != ((uint32_t)kENC_SimultBothPhaseChangeInterruptEnable & mask))
  441. {
  442. tmp16 |= ENC_CTRL2_SABIE_MASK;
  443. }
  444. if (0U != ((uint32_t)kENC_PositionRollOverInterruptEnable & mask))
  445. {
  446. tmp16 |= ENC_CTRL2_ROIE_MASK;
  447. }
  448. if (0U != ((uint32_t)kENC_PositionRollUnderInterruptEnable & mask))
  449. {
  450. tmp16 |= ENC_CTRL2_RUIE_MASK;
  451. }
  452. if (tmp16 != 0U)
  453. {
  454. base->CTRL2 = (uint16_t)(base->CTRL2 & (uint16_t)(~ENC_CTRL2_W1C_FLAGS)) & (uint16_t)(~tmp16);
  455. }
  456. }
  457. /*!
  458. * brief Get the enabled interrupts' flags.
  459. *
  460. * param base ENC peripheral base address.
  461. *
  462. * return Mask value of enabled interrupts.
  463. */
  464. uint32_t ENC_GetEnabledInterrupts(ENC_Type *base)
  465. {
  466. uint32_t ret32 = 0U;
  467. /* ENC_CTRL. */
  468. if (0U != (ENC_CTRL_HIE_MASK & base->CTRL))
  469. {
  470. ret32 |= (uint32_t)kENC_HOMETransitionInterruptEnable;
  471. }
  472. if (0U != (ENC_CTRL_XIE_MASK & base->CTRL))
  473. {
  474. ret32 |= (uint32_t)kENC_INDEXPulseInterruptEnable;
  475. }
  476. if (0U != (ENC_CTRL_DIE_MASK & base->CTRL))
  477. {
  478. ret32 |= (uint32_t)kENC_WatchdogTimeoutInterruptEnable;
  479. }
  480. if (0U != (ENC_CTRL_CMPIE_MASK & base->CTRL))
  481. {
  482. ret32 |= (uint32_t)kENC_PositionCompareInerruptEnable;
  483. }
  484. /* ENC_CTRL2. */
  485. if (0U != (ENC_CTRL2_SABIE_MASK & base->CTRL2))
  486. {
  487. ret32 |= (uint32_t)kENC_SimultBothPhaseChangeInterruptEnable;
  488. }
  489. if (0U != (ENC_CTRL2_ROIE_MASK & base->CTRL2))
  490. {
  491. ret32 |= (uint32_t)kENC_PositionRollOverInterruptEnable;
  492. }
  493. if (0U != (ENC_CTRL2_RUIE_MASK & base->CTRL2))
  494. {
  495. ret32 |= (uint32_t)kENC_PositionRollUnderInterruptEnable;
  496. }
  497. return ret32;
  498. }
  499. /*!
  500. * brief Set initial position value for ENC module.
  501. *
  502. * param base ENC peripheral base address
  503. * param value Positive initial value
  504. */
  505. void ENC_SetInitialPositionValue(ENC_Type *base, uint32_t value)
  506. {
  507. base->UINIT = (uint16_t)(value >> 16U); /* Set upper 16 bits. */
  508. base->LINIT = (uint16_t)(value); /* Set lower 16 bits. */
  509. }
  510. /*!
  511. * brief Get the current position counter's value.
  512. *
  513. * param base ENC peripheral base address.
  514. *
  515. * return Current position counter's value.
  516. */
  517. uint32_t ENC_GetPositionValue(ENC_Type *base)
  518. {
  519. uint32_t ret32;
  520. ret32 = base->UPOS; /* Get upper 16 bits and make a snapshot. */
  521. ret32 <<= 16U;
  522. ret32 |= base->LPOSH; /* Get lower 16 bits from hold register. */
  523. return ret32;
  524. }
  525. /*!
  526. * brief Get the hold position counter's value.
  527. *
  528. * When any of the counter registers is read, the contents of each counter register is written to the corresponding hold
  529. * register. Taking a snapshot of the counters' values provides a consistent view of a system position and a velocity to
  530. * be attained.
  531. *
  532. * param base ENC peripheral base address.
  533. *
  534. * return Hold position counter's value.
  535. */
  536. uint32_t ENC_GetHoldPositionValue(ENC_Type *base)
  537. {
  538. uint32_t ret32;
  539. ret32 = base->UPOSH; /* Get upper 16 bits and make a snapshot. */
  540. ret32 <<= 16U;
  541. ret32 |= base->LPOSH; /* Get lower 16 bits from hold register. */
  542. return ret32;
  543. }