qei.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. //*****************************************************************************
  2. //
  3. // qei.c - Driver for the Quadrature Encoder with Index.
  4. //
  5. // Copyright (c) 2005-2011 Texas Instruments Incorporated. All rights reserved.
  6. // Software License Agreement
  7. //
  8. // Texas Instruments (TI) is supplying this software for use solely and
  9. // exclusively on TI's microcontroller products. The software is owned by
  10. // TI and/or its suppliers, and is protected under applicable copyright
  11. // laws. You may not combine this software with "viral" open-source
  12. // software in order to form a larger program.
  13. //
  14. // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
  15. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
  16. // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  17. // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
  18. // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
  19. // DAMAGES, FOR ANY REASON WHATSOEVER.
  20. //
  21. // This is part of revision 8264 of the Stellaris Peripheral Driver Library.
  22. //
  23. //*****************************************************************************
  24. //*****************************************************************************
  25. //
  26. //! \addtogroup qei_api
  27. //! @{
  28. //
  29. //*****************************************************************************
  30. #include "inc/hw_ints.h"
  31. #include "inc/hw_memmap.h"
  32. #include "inc/hw_qei.h"
  33. #include "inc/hw_types.h"
  34. #include "driverlib/debug.h"
  35. #include "driverlib/interrupt.h"
  36. #include "driverlib/qei.h"
  37. //*****************************************************************************
  38. //
  39. //! Enables the quadrature encoder.
  40. //!
  41. //! \param ulBase is the base address of the quadrature encoder module.
  42. //!
  43. //! This function enables operation of the quadrature encoder module. The
  44. //! module must be configured before it is enabled.
  45. //!
  46. //! \sa QEIConfigure()
  47. //!
  48. //! \return None.
  49. //
  50. //*****************************************************************************
  51. void
  52. QEIEnable(unsigned long ulBase)
  53. {
  54. //
  55. // Check the arguments.
  56. //
  57. ASSERT((ulBase == QEI0_BASE) || (ulBase == QEI1_BASE));
  58. //
  59. // Enable the QEI module.
  60. //
  61. HWREG(ulBase + QEI_O_CTL) |= QEI_CTL_ENABLE;
  62. }
  63. //*****************************************************************************
  64. //
  65. //! Disables the quadrature encoder.
  66. //!
  67. //! \param ulBase is the base address of the quadrature encoder module.
  68. //!
  69. //! This function disables operation of the quadrature encoder module.
  70. //!
  71. //! \return None.
  72. //
  73. //*****************************************************************************
  74. void
  75. QEIDisable(unsigned long ulBase)
  76. {
  77. //
  78. // Check the arguments.
  79. //
  80. ASSERT((ulBase == QEI0_BASE) || (ulBase == QEI1_BASE));
  81. //
  82. // Disable the QEI module.
  83. //
  84. HWREG(ulBase + QEI_O_CTL) &= ~(QEI_CTL_ENABLE);
  85. }
  86. //*****************************************************************************
  87. //
  88. //! Configures the quadrature encoder.
  89. //!
  90. //! \param ulBase is the base address of the quadrature encoder module.
  91. //! \param ulConfig is the configuration for the quadrature encoder. See below
  92. //! for a description of this parameter.
  93. //! \param ulMaxPosition specifies the maximum position value.
  94. //!
  95. //! This function configures the operation of the quadrature encoder. The
  96. //! \e ulConfig parameter provides the configuration of the encoder and is the
  97. //! logical OR of several values:
  98. //!
  99. //! - \b QEI_CONFIG_CAPTURE_A or \b QEI_CONFIG_CAPTURE_A_B specify if edges
  100. //! on channel A or on both channels A and B should be counted by the
  101. //! position integrator and velocity accumulator.
  102. //! - \b QEI_CONFIG_NO_RESET or \b QEI_CONFIG_RESET_IDX specify if the
  103. //! position integrator should be reset when the index pulse is detected.
  104. //! - \b QEI_CONFIG_QUADRATURE or \b QEI_CONFIG_CLOCK_DIR specify if
  105. //! quadrature signals are being provided on ChA and ChB, or if a direction
  106. //! signal and a clock are being provided instead.
  107. //! - \b QEI_CONFIG_NO_SWAP or \b QEI_CONFIG_SWAP to specify if the signals
  108. //! provided on ChA and ChB should be swapped before being processed.
  109. //!
  110. //! \e ulMaxPosition is the maximum value of the position integrator and is
  111. //! the value used to reset the position capture when in index reset mode and
  112. //! moving in the reverse (negative) direction.
  113. //!
  114. //! \return None.
  115. //
  116. //*****************************************************************************
  117. void
  118. QEIConfigure(unsigned long ulBase, unsigned long ulConfig,
  119. unsigned long ulMaxPosition)
  120. {
  121. //
  122. // Check the arguments.
  123. //
  124. ASSERT((ulBase == QEI0_BASE) || (ulBase == QEI1_BASE));
  125. //
  126. // Write the new configuration to the hardware.
  127. //
  128. HWREG(ulBase + QEI_O_CTL) = ((HWREG(ulBase + QEI_O_CTL) &
  129. ~(QEI_CTL_CAPMODE | QEI_CTL_RESMODE |
  130. QEI_CTL_SIGMODE | QEI_CTL_SWAP)) |
  131. ulConfig);
  132. //
  133. // Set the maximum position.
  134. //
  135. HWREG(ulBase + QEI_O_MAXPOS) = ulMaxPosition;
  136. }
  137. //*****************************************************************************
  138. //
  139. //! Gets the current encoder position.
  140. //!
  141. //! \param ulBase is the base address of the quadrature encoder module.
  142. //!
  143. //! This function returns the current position of the encoder. Depending upon
  144. //! the configuration of the encoder, and the incident of an index pulse, this
  145. //! value may or may not contain the expected data (that is, if in reset on
  146. //! index mode, if an index pulse has not been encountered, the position
  147. //! counter is not yet aligned with the index pulse).
  148. //!
  149. //! \return The current position of the encoder.
  150. //
  151. //*****************************************************************************
  152. unsigned long
  153. QEIPositionGet(unsigned long ulBase)
  154. {
  155. //
  156. // Check the arguments.
  157. //
  158. ASSERT((ulBase == QEI0_BASE) || (ulBase == QEI1_BASE));
  159. //
  160. // Return the current position counter.
  161. //
  162. return(HWREG(ulBase + QEI_O_POS));
  163. }
  164. //*****************************************************************************
  165. //
  166. //! Sets the current encoder position.
  167. //!
  168. //! \param ulBase is the base address of the quadrature encoder module.
  169. //! \param ulPosition is the new position for the encoder.
  170. //!
  171. //! This function sets the current position of the encoder; the encoder
  172. //! position is then measured relative to this value.
  173. //!
  174. //! \return None.
  175. //
  176. //*****************************************************************************
  177. void
  178. QEIPositionSet(unsigned long ulBase, unsigned long ulPosition)
  179. {
  180. //
  181. // Check the arguments.
  182. //
  183. ASSERT((ulBase == QEI0_BASE) || (ulBase == QEI1_BASE));
  184. //
  185. // Set the position counter.
  186. //
  187. HWREG(ulBase + QEI_O_POS) = ulPosition;
  188. }
  189. //*****************************************************************************
  190. //
  191. //! Gets the current direction of rotation.
  192. //!
  193. //! \param ulBase is the base address of the quadrature encoder module.
  194. //!
  195. //! This function returns the current direction of rotation. In this case,
  196. //! current means the most recently detected direction of the encoder; it may
  197. //! not be presently moving but this is the direction it last moved before it
  198. //! stopped.
  199. //!
  200. //! \return Returns 1 if moving in the forward direction or -1 if moving in the
  201. //! reverse direction.
  202. //
  203. //*****************************************************************************
  204. long
  205. QEIDirectionGet(unsigned long ulBase)
  206. {
  207. //
  208. // Check the arguments.
  209. //
  210. ASSERT((ulBase == QEI0_BASE) || (ulBase == QEI1_BASE));
  211. //
  212. // Return the direction of rotation.
  213. //
  214. return((HWREG(ulBase + QEI_O_STAT) & QEI_STAT_DIRECTION) ? -1 : 1);
  215. }
  216. //*****************************************************************************
  217. //
  218. //! Gets the encoder error indicator.
  219. //!
  220. //! \param ulBase is the base address of the quadrature encoder module.
  221. //!
  222. //! This function returns the error indicator for the quadrature encoder. It
  223. //! is an error for both of the signals of the quadrature input to change at
  224. //! the same time.
  225. //!
  226. //! \return Returns \b true if an error has occurred and \b false otherwise.
  227. //
  228. //*****************************************************************************
  229. tBoolean
  230. QEIErrorGet(unsigned long ulBase)
  231. {
  232. //
  233. // Check the arguments.
  234. //
  235. ASSERT((ulBase == QEI0_BASE) || (ulBase == QEI1_BASE));
  236. //
  237. // Return the error indicator.
  238. //
  239. return((HWREG(ulBase + QEI_O_STAT) & QEI_STAT_ERROR) ? true : false);
  240. }
  241. //*****************************************************************************
  242. //
  243. //! Enables the velocity capture.
  244. //!
  245. //! \param ulBase is the base address of the quadrature encoder module.
  246. //!
  247. //! This function enables operation of the velocity capture in the quadrature
  248. //! encoder module. The module must be configured before velocity capture is
  249. //! enabled.
  250. //!
  251. //! \sa QEIVelocityConfigure() and QEIEnable()
  252. //!
  253. //! \return None.
  254. //
  255. //*****************************************************************************
  256. void
  257. QEIVelocityEnable(unsigned long ulBase)
  258. {
  259. //
  260. // Check the arguments.
  261. //
  262. ASSERT((ulBase == QEI0_BASE) || (ulBase == QEI1_BASE));
  263. //
  264. // Enable the velocity capture.
  265. //
  266. HWREG(ulBase + QEI_O_CTL) |= QEI_CTL_VELEN;
  267. }
  268. //*****************************************************************************
  269. //
  270. //! Disables the velocity capture.
  271. //!
  272. //! \param ulBase is the base address of the quadrature encoder module.
  273. //!
  274. //! This function disables operation of the velocity capture in the quadrature
  275. //! encoder module.
  276. //!
  277. //! \return None.
  278. //
  279. //*****************************************************************************
  280. void
  281. QEIVelocityDisable(unsigned long ulBase)
  282. {
  283. //
  284. // Check the arguments.
  285. //
  286. ASSERT((ulBase == QEI0_BASE) || (ulBase == QEI1_BASE));
  287. //
  288. // Disable the velocity capture.
  289. //
  290. HWREG(ulBase + QEI_O_CTL) &= ~(QEI_CTL_VELEN);
  291. }
  292. //*****************************************************************************
  293. //
  294. //! Configures the velocity capture.
  295. //!
  296. //! \param ulBase is the base address of the quadrature encoder module.
  297. //! \param ulPreDiv specifies the predivider applied to the input quadrature
  298. //! signal before it is counted; can be one of \b QEI_VELDIV_1,
  299. //! \b QEI_VELDIV_2, \b QEI_VELDIV_4, \b QEI_VELDIV_8, \b QEI_VELDIV_16,
  300. //! \b QEI_VELDIV_32, \b QEI_VELDIV_64, or \b QEI_VELDIV_128.
  301. //! \param ulPeriod specifies the number of clock ticks over which to measure
  302. //! the velocity; must be non-zero.
  303. //!
  304. //! This function configures the operation of the velocity capture portion of
  305. //! the quadrature encoder. The position increment signal is predivided as
  306. //! specified by \e ulPreDiv before being accumulated by the velocity capture.
  307. //! The divided signal is accumulated over \e ulPeriod system clock before
  308. //! being saved and resetting the accumulator.
  309. //!
  310. //! \return None.
  311. //
  312. //*****************************************************************************
  313. void
  314. QEIVelocityConfigure(unsigned long ulBase, unsigned long ulPreDiv,
  315. unsigned long ulPeriod)
  316. {
  317. //
  318. // Check the arguments.
  319. //
  320. ASSERT((ulBase == QEI0_BASE) || (ulBase == QEI1_BASE));
  321. ASSERT(!(ulPreDiv & ~(QEI_CTL_VELDIV_M)));
  322. ASSERT(ulPeriod != 0);
  323. //
  324. // Set the velocity predivider.
  325. //
  326. HWREG(ulBase + QEI_O_CTL) = ((HWREG(ulBase + QEI_O_CTL) &
  327. ~(QEI_CTL_VELDIV_M)) | ulPreDiv);
  328. //
  329. // Set the timer period.
  330. //
  331. HWREG(ulBase + QEI_O_LOAD) = ulPeriod - 1;
  332. }
  333. //*****************************************************************************
  334. //
  335. //! Gets the current encoder speed.
  336. //!
  337. //! \param ulBase is the base address of the quadrature encoder module.
  338. //!
  339. //! This function returns the current speed of the encoder. The value returned
  340. //! is the number of pulses detected in the specified time period; this number
  341. //! can be multiplied by the number of time periods per second and divided by
  342. //! the number of pulses per revolution to obtain the number of revolutions per
  343. //! second.
  344. //!
  345. //! \return Returns the number of pulses captured in the given time period.
  346. //
  347. //*****************************************************************************
  348. unsigned long
  349. QEIVelocityGet(unsigned long ulBase)
  350. {
  351. //
  352. // Check the arguments.
  353. //
  354. ASSERT((ulBase == QEI0_BASE) || (ulBase == QEI1_BASE));
  355. //
  356. // Return the speed capture value.
  357. //
  358. return(HWREG(ulBase + QEI_O_SPEED));
  359. }
  360. //*****************************************************************************
  361. //
  362. //! Registers an interrupt handler for the quadrature encoder interrupt.
  363. //!
  364. //! \param ulBase is the base address of the quadrature encoder module.
  365. //! \param pfnHandler is a pointer to the function to be called when the
  366. //! quadrature encoder interrupt occurs.
  367. //!
  368. //! This function registers the handler to be called when a quadrature encoder
  369. //! interrupt occurs. This function enables the global interrupt in the
  370. //! interrupt controller; specific quadrature encoder interrupts must be
  371. //! enabled via QEIIntEnable(). It is the interrupt handler's responsibility to
  372. //! clear the interrupt source via QEIIntClear().
  373. //!
  374. //! \sa IntRegister() for important information about registering interrupt
  375. //! handlers.
  376. //!
  377. //! \return None.
  378. //
  379. //*****************************************************************************
  380. void
  381. QEIIntRegister(unsigned long ulBase, void (*pfnHandler)(void))
  382. {
  383. unsigned long ulInt;
  384. //
  385. // Check the arguments.
  386. //
  387. ASSERT((ulBase == QEI0_BASE) || (ulBase == QEI1_BASE));
  388. //
  389. // Determine the interrupt number based on the QEI module.
  390. //
  391. ulInt = (ulBase == QEI0_BASE) ? INT_QEI0 : INT_QEI1;
  392. //
  393. // Register the interrupt handler, returning an error if an error occurs.
  394. //
  395. IntRegister(ulInt, pfnHandler);
  396. //
  397. // Enable the quadrature encoder interrupt.
  398. //
  399. IntEnable(ulInt);
  400. }
  401. //*****************************************************************************
  402. //
  403. //! Unregisters an interrupt handler for the quadrature encoder interrupt.
  404. //!
  405. //! \param ulBase is the base address of the quadrature encoder module.
  406. //!
  407. //! This function unregisters the handler to be called when a quadrature
  408. //! encoder interrupt occurs. This function also masks off the interrupt in
  409. //! the interrupt controller so that the interrupt handler no longer is called.
  410. //!
  411. //! \sa IntRegister() for important information about registering interrupt
  412. //! handlers.
  413. //!
  414. //! \return None.
  415. //
  416. //*****************************************************************************
  417. void
  418. QEIIntUnregister(unsigned long ulBase)
  419. {
  420. unsigned long ulInt;
  421. //
  422. // Check the arguments.
  423. //
  424. ASSERT((ulBase == QEI0_BASE) || (ulBase == QEI1_BASE));
  425. //
  426. // Determine the interrupt number based on the QEI module.
  427. //
  428. ulInt = (ulBase == QEI0_BASE) ? INT_QEI0 : INT_QEI1;
  429. //
  430. // Disable the interrupt.
  431. //
  432. IntDisable(ulInt);
  433. //
  434. // Unregister the interrupt handler.
  435. //
  436. IntUnregister(ulInt);
  437. }
  438. //*****************************************************************************
  439. //
  440. //! Enables individual quadrature encoder interrupt sources.
  441. //!
  442. //! \param ulBase is the base address of the quadrature encoder module.
  443. //! \param ulIntFlags is a bit mask of the interrupt sources to be enabled.
  444. //! Can be any of the \b QEI_INTERROR, \b QEI_INTDIR, \b QEI_INTTIMER, or
  445. //! \b QEI_INTINDEX values.
  446. //!
  447. //! This function enables the indicated quadrature encoder interrupt sources.
  448. //! Only the sources that are enabled can be reflected to the processor
  449. //! interrupt; disabled sources have no effect on the processor.
  450. //!
  451. //! \return None.
  452. //
  453. //*****************************************************************************
  454. void
  455. QEIIntEnable(unsigned long ulBase, unsigned long ulIntFlags)
  456. {
  457. //
  458. // Check the arguments.
  459. //
  460. ASSERT((ulBase == QEI0_BASE) || (ulBase == QEI1_BASE));
  461. //
  462. // Enable the specified interrupts.
  463. //
  464. HWREG(ulBase + QEI_O_INTEN) |= ulIntFlags;
  465. }
  466. //*****************************************************************************
  467. //
  468. //! Disables individual quadrature encoder interrupt sources.
  469. //!
  470. //! \param ulBase is the base address of the quadrature encoder module.
  471. //! \param ulIntFlags is a bit mask of the interrupt sources to be disabled.
  472. //! This parameter can be any of the \b QEI_INTERROR, \b QEI_INTDIR,
  473. //! \b QEI_INTTIMER, or \b QEI_INTINDEX values.
  474. //!
  475. //! This function disables the indicated quadrature encoder interrupt sources.
  476. //! Only the sources that are enabled can be reflected to the processor
  477. //! interrupt; disabled sources have no effect on the processor.
  478. //!
  479. //! \return None.
  480. //
  481. //*****************************************************************************
  482. void
  483. QEIIntDisable(unsigned long ulBase, unsigned long ulIntFlags)
  484. {
  485. //
  486. // Check the arguments.
  487. //
  488. ASSERT((ulBase == QEI0_BASE) || (ulBase == QEI1_BASE));
  489. //
  490. // Disable the specified interrupts.
  491. //
  492. HWREG(ulBase + QEI_O_INTEN) &= ~(ulIntFlags);
  493. }
  494. //*****************************************************************************
  495. //
  496. //! Gets the current interrupt status.
  497. //!
  498. //! \param ulBase is the base address of the quadrature encoder module.
  499. //! \param bMasked is false if the raw interrupt status is required and true if
  500. //! the masked interrupt status is required.
  501. //!
  502. //! This function returns the interrupt status for the quadrature encoder
  503. //! module. Either the raw interrupt status or the status of interrupts that
  504. //! are allowed to reflect to the processor can be returned.
  505. //!
  506. //! \return Returns the current interrupt status, enumerated as a bit field of
  507. //! \b QEI_INTERROR, \b QEI_INTDIR, \b QEI_INTTIMER, and \b QEI_INTINDEX.
  508. //
  509. //*****************************************************************************
  510. unsigned long
  511. QEIIntStatus(unsigned long ulBase, tBoolean bMasked)
  512. {
  513. //
  514. // Check the arguments.
  515. //
  516. ASSERT((ulBase == QEI0_BASE) || (ulBase == QEI1_BASE));
  517. //
  518. // Return either the interrupt status or the raw interrupt status as
  519. // requested.
  520. //
  521. if(bMasked)
  522. {
  523. return(HWREG(ulBase + QEI_O_ISC));
  524. }
  525. else
  526. {
  527. return(HWREG(ulBase + QEI_O_RIS));
  528. }
  529. }
  530. //*****************************************************************************
  531. //
  532. //! Clears quadrature encoder interrupt sources.
  533. //!
  534. //! \param ulBase is the base address of the quadrature encoder module.
  535. //! \param ulIntFlags is a bit mask of the interrupt sources to be cleared.
  536. //! This parameter can be any of the \b QEI_INTERROR, \b QEI_INTDIR,
  537. //! \b QEI_INTTIMER, or \b QEI_INTINDEX values.
  538. //!
  539. //! The specified quadrature encoder interrupt sources are cleared, so that
  540. //! they no longer assert. This function must be called in the interrupt
  541. //! handler to keep the interrupt from being triggered again immediately upon
  542. //! exit.
  543. //!
  544. //! \note Because there is a write buffer in the Cortex-M processor, it may
  545. //! take several clock cycles before the interrupt source is actually cleared.
  546. //! Therefore, it is recommended that the interrupt source be cleared early in
  547. //! the interrupt handler (as opposed to the very last action) to avoid
  548. //! returning from the interrupt handler before the interrupt source is
  549. //! actually cleared. Failure to do so may result in the interrupt handler
  550. //! being immediately reentered (because the interrupt controller still sees
  551. //! the interrupt source asserted).
  552. //!
  553. //! \return None.
  554. //
  555. //*****************************************************************************
  556. void
  557. QEIIntClear(unsigned long ulBase, unsigned long ulIntFlags)
  558. {
  559. //
  560. // Check the arguments.
  561. //
  562. ASSERT((ulBase == QEI0_BASE) || (ulBase == QEI1_BASE));
  563. //
  564. // Clear the requested interrupt sources.
  565. //
  566. HWREG(ulBase + QEI_O_ISC) = ulIntFlags;
  567. }
  568. //*****************************************************************************
  569. //
  570. // Close the Doxygen group.
  571. //! @}
  572. //
  573. //*****************************************************************************