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