]> begriffs open source - cmsis-freertos/blob - Demo/CORTEX_LM3S811_IAR/LuminaryCode/adc.c
Update cmsis_os2.c
[cmsis-freertos] / Demo / CORTEX_LM3S811_IAR / LuminaryCode / adc.c
1 //*****************************************************************************
2 //
3 // adc.c - Driver for the ADC.
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 adc_api
31 //! @{
32 //
33 //*****************************************************************************
34
35 #include "../hw_adc.h"
36 #include "../hw_ints.h"
37 #include "../hw_memmap.h"
38 #include "../hw_types.h"
39 #include "adc.h"
40 #include "debug.h"
41 #include "interrupt.h"
42
43 //*****************************************************************************
44 //
45 // The currently configured software oversampling factor for each of the ADC
46 // sequencers.
47 //
48 //*****************************************************************************
49 #if defined(GROUP_pucoverssamplefactor) || defined(BUILD_ALL)
50 unsigned char g_pucOversampleFactor[3];
51 #else
52 extern unsigned char g_pucOversampleFactor[3];
53 #endif
54
55 //*****************************************************************************
56 //
57 //! Registers an interrupt handler for an ADC interrupt.
58 //!
59 //! \param ulBase is the base address of the ADC module.
60 //! \param ulSequenceNum is the sample sequence number.
61 //! \param pfnHandler is a pointer to the function to be called when the
62 //! ADC sample sequence interrupt occurs.
63 //!
64 //! This function sets the handler to be called when a sample sequence
65 //! interrupt occurs.  This will enable the global interrupt in the interrupt
66 //! controller; the sequence interrupt must be enabled with ADCIntEnable().  It
67 //! is the interrupt handler's responsibility to clear the interrupt source via
68 //! ADCIntClear().
69 //!
70 //! \sa IntRegister() for important information about registering interrupt
71 //! handlers.
72 //!
73 //! \return None.
74 //
75 //*****************************************************************************
76 #if defined(GROUP_intregister) || defined(BUILD_ALL) || defined(DOXYGEN)
77 void
78 ADCIntRegister(unsigned long ulBase, unsigned long ulSequenceNum,
79                void (*pfnHandler)(void))
80 {
81     unsigned long ulInt;
82
83     //
84     // Check the arguments.
85     //
86     ASSERT(ulBase == ADC_BASE);
87     ASSERT(ulSequenceNum < 4);
88
89     //
90     // Determine the interrupt to register based on the sequence number.
91     //
92     ulInt = INT_ADC0 + ulSequenceNum;
93
94     //
95     // Register the interrupt handler.
96     //
97     IntRegister(ulInt, pfnHandler);
98
99     //
100     // Enable the timer interrupt.
101     //
102     IntEnable(ulInt);
103 }
104 #endif
105
106 //*****************************************************************************
107 //
108 //! Unregisters the interrupt handler for an ADC interrupt.
109 //!
110 //! \param ulBase is the base address of the ADC module.
111 //! \param ulSequenceNum is the sample sequence number.
112 //!
113 //! This function unregisters the interrupt handler.  This will disable the
114 //! global interrupt in the interrupt controller; the sequence interrupt must
115 //! be disabled via ADCIntDisable().
116 //!
117 //! \sa IntRegister() for important information about registering interrupt
118 //! handlers.
119 //!
120 //! \return None.
121 //
122 //*****************************************************************************
123 #if defined(GROUP_intunregister) || defined(BUILD_ALL) || defined(DOXYGEN)
124 void
125 ADCIntUnregister(unsigned long ulBase, unsigned long ulSequenceNum)
126 {
127     unsigned long ulInt;
128
129     //
130     // Check the arguments.
131     //
132     ASSERT(ulBase == ADC_BASE);
133     ASSERT(ulSequenceNum < 4);
134
135     //
136     // Determine the interrupt to unregister based on the sequence number.
137     //
138     ulInt = INT_ADC0 + ulSequenceNum;
139
140     //
141     // Disable the interrupt.
142     //
143     IntDisable(ulInt);
144
145     //
146     // Unregister the interrupt handler.
147     //
148     IntUnregister(ulInt);
149 }
150 #endif
151
152 //*****************************************************************************
153 //
154 //! Disables a sample sequence interrupt.
155 //!
156 //! \param ulBase is the base address of the ADC module.
157 //! \param ulSequenceNum is the sample sequence number.
158 //!
159 //! This function disables the requested sample sequence interrupt.
160 //!
161 //! \return None.
162 //
163 //*****************************************************************************
164 #if defined(GROUP_intdisable) || defined(BUILD_ALL) || defined(DOXYGEN)
165 void
166 ADCIntDisable(unsigned long ulBase, unsigned long ulSequenceNum)
167 {
168     //
169     // Check the arguments.
170     //
171     ASSERT(ulBase == ADC_BASE);
172     ASSERT(ulSequenceNum < 4);
173
174     //
175     // Disable this sample sequence interrupt.
176     //
177     HWREG(ulBase + ADC_O_IM) &= ~(1 << ulSequenceNum);
178 }
179 #endif
180
181 //*****************************************************************************
182 //
183 //! Enables a sample sequence interrupt.
184 //!
185 //! \param ulBase is the base address of the ADC module.
186 //! \param ulSequenceNum is the sample sequence number.
187 //!
188 //! This function enables the requested sample sequence interrupt.  Any
189 //! outstanding interrupts are cleared before enabling the sample sequence
190 //! interrupt.
191 //!
192 //! \return None.
193 //
194 //*****************************************************************************
195 #if defined(GROUP_intenable) || defined(BUILD_ALL) || defined(DOXYGEN)
196 void
197 ADCIntEnable(unsigned long ulBase, unsigned long ulSequenceNum)
198 {
199     //
200     // Check the arguments.
201     //
202     ASSERT(ulBase == ADC_BASE);
203     ASSERT(ulSequenceNum < 4);
204
205     //
206     // Clear any outstanding interrupts on this sample sequence.
207     //
208     HWREG(ulBase + ADC_O_ISC) = 1 << ulSequenceNum;
209
210     //
211     // Enable this sample sequence interrupt.
212     //
213     HWREG(ulBase + ADC_O_IM) |= 1 << ulSequenceNum;
214 }
215 #endif
216
217 //*****************************************************************************
218 //
219 //! Gets the current interrupt status.
220 //!
221 //! \param ulBase is the base address of the ADC module.
222 //! \param ulSequenceNum is the sample sequence number.
223 //! \param bMasked is false if the raw interrupt status is required and true if
224 //! the masked interrupt status is required.
225 //!
226 //! This returns the interrupt status for the specified sample sequence.
227 //! Either the raw interrupt status or the status of interrupts that are
228 //! allowed to reflect to the processor can be returned.
229 //!
230 //! \return The current raw or masked interrupt status.
231 //
232 //*****************************************************************************
233 #if defined(GROUP_intstatus) || defined(BUILD_ALL) || defined(DOXYGEN)
234 unsigned long
235 ADCIntStatus(unsigned long ulBase, unsigned long ulSequenceNum,
236              tBoolean bMasked)
237 {
238     //
239     // Check the arguments.
240     //
241     ASSERT(ulBase == ADC_BASE);
242     ASSERT(ulSequenceNum < 4);
243
244     //
245     // Return either the interrupt status or the raw interrupt status as
246     // requested.
247     //
248     if(bMasked)
249     {
250         return(HWREG(ulBase + ADC_O_ISC) & (1 << ulSequenceNum));
251     }
252     else
253     {
254         return(HWREG(ulBase + ADC_O_RIS) & (1 << ulSequenceNum));
255     }
256 }
257 #endif
258
259 //*****************************************************************************
260 //
261 //! Clears sample sequence interrupt source.
262 //!
263 //! \param ulBase is the base address of the ADC module.
264 //! \param ulSequenceNum is the sample sequence number.
265 //!
266 //! The specified sample sequence interrupt is cleared, so that it no longer
267 //! asserts.  This must be done in the interrupt handler to keep it from being
268 //! called again immediately upon exit.
269 //!
270 //! \return None.
271 //
272 //*****************************************************************************
273 #if defined(GROUP_intclear) || defined(BUILD_ALL) || defined(DOXYGEN)
274 void
275 ADCIntClear(unsigned long ulBase, unsigned long ulSequenceNum)
276 {
277     //
278     // Check the arugments.
279     //
280     ASSERT(ulBase == ADC_BASE);
281     ASSERT(ulSequenceNum < 4);
282
283     //
284     // Clear the interrupt.
285     //
286     HWREG(ulBase + ADC_O_ISC) = 1 << ulSequenceNum;
287 }
288 #endif
289
290 //*****************************************************************************
291 //
292 //! Enables a sample sequence.
293 //!
294 //! \param ulBase is the base address of the ADC module.
295 //! \param ulSequenceNum is the sample sequence number.
296 //!
297 //! Allows the specified sample sequence to be captured when its trigger is
298 //! detected.  A sample sequence must be configured before it is enabled.
299 //!
300 //! \return None.
301 //
302 //*****************************************************************************
303 #if defined(GROUP_sequenceenable) || defined(BUILD_ALL) || defined(DOXYGEN)
304 void
305 ADCSequenceEnable(unsigned long ulBase, unsigned long ulSequenceNum)
306 {
307     //
308     // Check the arugments.
309     //
310     ASSERT(ulBase == ADC_BASE);
311     ASSERT(ulSequenceNum < 4);
312
313     //
314     // Enable the specified sequence.
315     //
316     HWREG(ulBase + ADC_O_ACTSS) |= 1 << ulSequenceNum;
317 }
318 #endif
319
320 //*****************************************************************************
321 //
322 //! Disables a sample sequence.
323 //!
324 //! \param ulBase is the base address of the ADC module.
325 //! \param ulSequenceNum is the sample sequence number.
326 //!
327 //! Prevents the specified sample sequence from being captured when its trigger
328 //! is detected.  A sample sequence should be disabled before it is configured.
329 //!
330 //! \return None.
331 //
332 //*****************************************************************************
333 #if defined(GROUP_sequencedisable) || defined(BUILD_ALL) || defined(DOXYGEN)
334 void
335 ADCSequenceDisable(unsigned long ulBase, unsigned long ulSequenceNum)
336 {
337     //
338     // Check the arugments.
339     //
340     ASSERT(ulBase == ADC_BASE);
341     ASSERT(ulSequenceNum < 4);
342
343     //
344     // Disable the specified sequences.
345     //
346     HWREG(ulBase + ADC_O_ACTSS) &= ~(1 << ulSequenceNum);
347 }
348 #endif
349
350 //*****************************************************************************
351 //
352 //! Configures the trigger source and priority of a sample sequence.
353 //!
354 //! \param ulBase is the base address of the ADC module.
355 //! \param ulSequenceNum is the sample sequence number.
356 //! \param ulTrigger is the trigger source that initiates the sample sequence;
357 //! must be one of the \b ADC_TRIGGER_* values.
358 //! \param ulPriority is the relative priority of the sample sequence with
359 //! respect to the other sample sequences.
360 //!
361 //! This function configures the initiation criteria for a sample sequence.
362 //! Valid sample sequences range from zero to three; sequence zero will capture
363 //! up to eight samples, sequences one and two will capture up to four samples,
364 //! and sequence three will capture a single sample.  The trigger condition and
365 //! priority (with respect to other sample sequence execution) is set.
366 //!
367 //! The parameter \b ulTrigger can take on the following values:
368 //!
369 //! - \b ADC_TRIGGER_PROCESSOR - A trigger generated by the processor, via the
370 //!                              ADCProcessorTrigger() function.
371 //! - \b ADC_TRIGGER_COMP0 - A trigger generated by the first analog
372 //!                          comparator; configured with ComparatorConfigure().
373 //! - \b ADC_TRIGGER_COMP1 - A trigger generated by the second analog
374 //!                          comparator; configured with ComparatorConfigure().
375 //! - \b ADC_TRIGGER_COMP2 - A trigger generated by the third analog
376 //!                          comparator; configured with ComparatorConfigure().
377 //! - \b ADC_TRIGGER_EXTERNAL - A trigger generated by an input from the Port
378 //!                             B4 pin.
379 //! - \b ADC_TRIGGER_TIMER - A trigger generated by a timer; configured with
380 //!                          TimerControlTrigger().
381 //! - \b ADC_TRIGGER_PWM0 - A trigger generated by the first PWM generator;
382 //!                         configured with PWMGenIntTrigEnable().
383 //! - \b ADC_TRIGGER_PWM1 - A trigger generated by the second PWM generator;
384 //!                         configured with PWMGenIntTrigEnable().
385 //! - \b ADC_TRIGGER_PWM2 - A trigger generated by the third PWM generator;
386 //!                         configured with PWMGenIntTrigEnable().
387 //! - \b ADC_TRIGGER_ALWAYS - A trigger that is always asserted, causing the
388 //!                           sample sequence to capture repeatedly (so long as
389 //!                           there is not a higher priority source active).
390 //!
391 //! Note that not all trigger sources are available on all Stellaris family
392 //! members; consult the data sheet for the device in question to determine the
393 //! availability of triggers.
394 //!
395 //! The parameter \b ulPriority is a value between 0 and 3, where 0 represents
396 //! the highest priority and 3 the lowest.  Note that when programming the
397 //! priority among a set of sample sequences, each must have unique priority;
398 //! it is up to the caller to guarantee the uniqueness of the priorities.
399 //!
400 //! \return None.
401 //
402 //*****************************************************************************
403 #if defined(GROUP_sequenceconfigure) || defined(BUILD_ALL) || defined(DOXYGEN)
404 void
405 ADCSequenceConfigure(unsigned long ulBase, unsigned long ulSequenceNum,
406                      unsigned long ulTrigger, unsigned long ulPriority)
407 {
408     //
409     // Check the arugments.
410     //
411     ASSERT(ulBase == ADC_BASE);
412     ASSERT(ulSequenceNum < 4);
413     ASSERT((ulTrigger == ADC_TRIGGER_PROCESSOR) ||
414            (ulTrigger == ADC_TRIGGER_COMP0) ||
415            (ulTrigger == ADC_TRIGGER_COMP1) ||
416            (ulTrigger == ADC_TRIGGER_COMP2) ||
417            (ulTrigger == ADC_TRIGGER_EXTERNAL) ||
418            (ulTrigger == ADC_TRIGGER_TIMER) ||
419            (ulTrigger == ADC_TRIGGER_PWM0) ||
420            (ulTrigger == ADC_TRIGGER_PWM1) ||
421            (ulTrigger == ADC_TRIGGER_PWM2) ||
422            (ulTrigger == ADC_TRIGGER_ALWAYS));
423     ASSERT(ulPriority < 4);
424
425     //
426     // Compute the shift for the bits that control this sample sequence.
427     //
428     ulSequenceNum *= 4;
429
430     //
431     // Set the trigger event for this sample sequence.
432     //
433     HWREG(ulBase + ADC_O_EMUX) = ((HWREG(ulBase + ADC_O_EMUX) &
434                                    ~(0xf << ulSequenceNum)) |
435                                   ((ulTrigger & 0xf) << ulSequenceNum));
436
437     //
438     // Set the priority for this sample sequence.
439     //
440     HWREG(ulBase + ADC_O_SSPRI) = ((HWREG(ulBase + ADC_O_SSPRI) &
441                                     ~(0xf << ulSequenceNum)) |
442                                    ((ulPriority & 0x3) << ulSequenceNum));
443 }
444 #endif
445
446 //*****************************************************************************
447 //
448 //! Configure a step of the sample sequencer.
449 //!
450 //! \param ulBase is the base address of the ADC module.
451 //! \param ulSequenceNum is the sample sequence number.
452 //! \param ulStep is the step to be configured.
453 //! \param ulConfig is the configuration of this step; must be a logical OR of
454 //! \b ADC_CTL_TS, \b ADC_CTL_IE, \b ADC_CTL_END, \b ADC_CTL_D, and one of the
455 //! input channel selects (\b ADC_CTL_CH0 through \b ADC_CTL_CH7).
456 //!
457 //! This function will set the configuration of the ADC for one step of a
458 //! sample sequence.  The ADC can be configured for single-ended or
459 //! differential operation (the \b ADC_CTL_D bit selects differential
460 //! operation when set), the channel to be sampled can be chosen (the
461 //! \b ADC_CTL_CH0 through \b ADC_CTL_CH7 values), and the internal temperature
462 //! sensor can be selected (the \b ADC_CTL_TS bit).  Additionally, this step
463 //! can be defined as the last in the sequence (the \b ADC_CTL_END bit) and it
464 //! can be configured to cause an interrupt when the step is complete (the
465 //! \b ADC_CTL_IE bit).  The configuration is used by the ADC at the
466 //! appropriate time when the trigger for this sequence occurs.
467 //!
468 //! The \b ulStep parameter determines the order in which the samples are
469 //! captured by the ADC when the trigger occurs.  It can range from zero to
470 //! seven for the first sample sequence, from zero to three for the second and
471 //! third sample sequence, and can only be zero for the fourth sample sequence.
472 //!
473 //! Differential mode only works with adjacent channel pairs (e.g. 0 and 1).
474 //! The channel select must be the number of the channel pair to sample (e.g.
475 //! \b ADC_CTL_CH0 for 0 and 1, or \b ADC_CTL_CH1 for 2 and 3) or undefined
476 //! results will be returned by the ADC.  Additionally, if differential mode is
477 //! selected when the temperature sensor is being sampled, undefined results
478 //! will be returned by the ADC.
479 //!
480 //! It is the responsibility of the caller to ensure that a valid configuration
481 //! is specified; this function does not check the validity of the specified
482 //! configuration.
483 //!
484 //! \return None.
485 //
486 //*****************************************************************************
487 #if defined(GROUP_sequencestepconfigure) || defined(BUILD_ALL) || \
488     defined(DOXYGEN)
489 void
490 ADCSequenceStepConfigure(unsigned long ulBase, unsigned long ulSequenceNum,
491                          unsigned long ulStep, unsigned long ulConfig)
492 {
493     //
494     // Check the arugments.
495     //
496     ASSERT(ulBase == ADC_BASE);
497     ASSERT(ulSequenceNum < 4);
498     ASSERT(((ulSequenceNum == 0) && (ulStep < 8)) ||
499            ((ulSequenceNum == 1) && (ulStep < 4)) ||
500            ((ulSequenceNum == 2) && (ulStep < 4)) ||
501            ((ulSequenceNum == 3) && (ulStep < 1)));
502
503     //
504     // Get the offset of the sequence to be configured.
505     //
506     ulBase += ADC_O_SEQ + (ADC_O_SEQ_STEP * ulSequenceNum);
507
508     //
509     // Compute the shift for the bits that control this step.
510     //
511     ulStep *= 4;
512
513     //
514     // Set the analog mux value for this step.
515     //
516     HWREG(ulBase + ADC_O_X_SSMUX) = ((HWREG(ulBase + ADC_O_X_SSMUX) &
517                                       ~(0x0000000f << ulStep)) |
518                                      ((ulConfig & 0x0f) << ulStep));
519
520     //
521     // Set the control value for this step.
522     //
523     HWREG(ulBase + ADC_O_X_SSCTL) = ((HWREG(ulBase + ADC_O_X_SSCTL) &
524                                       ~(0x0000000f << ulStep)) |
525                                      (((ulConfig & 0xf0) >> 4) << ulStep));
526 }
527 #endif
528
529 //*****************************************************************************
530 //
531 //! Determines if a sample sequence overflow occurred.
532 //!
533 //! \param ulBase is the base address of the ADC module.
534 //! \param ulSequenceNum is the sample sequence number.
535 //!
536 //! This determines if a sample sequence overflow has occurred.  This will
537 //! happen if the captured samples are not read from the FIFO before the next
538 //! trigger occurs.
539 //!
540 //! \return Returns zero if there was not an overflow, and non-zero if there
541 //! was.
542 //
543 //*****************************************************************************
544 #if defined(GROUP_sequenceoverflow) || defined(BUILD_ALL) || defined(DOXYGEN)
545 long
546 ADCSequenceOverflow(unsigned long ulBase, unsigned long ulSequenceNum)
547 {
548     //
549     // Check the arguments.
550     //
551     ASSERT(ulBase == ADC_BASE);
552     ASSERT(ulSequenceNum < 4);
553
554     //
555     // Determine if there was an overflow on this sequence.
556     //
557     return(HWREG(ulBase + ADC_O_OSTAT) & (1 << ulSequenceNum));
558 }
559 #endif
560
561 //*****************************************************************************
562 //
563 //! Determines if a sample sequence underflow occurred.
564 //!
565 //! \param ulBase is the base address of the ADC module.
566 //! \param ulSequenceNum is the sample sequence number.
567 //!
568 //! This determines if a sample sequence underflow has occurred.  This will
569 //! happen if too many samples are read from the FIFO.
570 //!
571 //! \return Returns zero if there was not an underflow, and non-zero if there
572 //! was.
573 //
574 //*****************************************************************************
575 #if defined(GROUP_sequenceunderflow) || defined(BUILD_ALL) || defined(DOXYGEN)
576 long
577 ADCSequenceUnderflow(unsigned long ulBase, unsigned long ulSequenceNum)
578 {
579     //
580     // Check the arguments.
581     //
582     ASSERT(ulBase == ADC_BASE);
583     ASSERT(ulSequenceNum < 4);
584
585     //
586     // Determine if there was an underflow on this sequence.
587     //
588     return(HWREG(ulBase + ADC_O_USTAT) & (1 << ulSequenceNum));
589 }
590 #endif
591
592 //*****************************************************************************
593 //
594 //! Gets the captured data for a sample sequence.
595 //!
596 //! \param ulBase is the base address of the ADC module.
597 //! \param ulSequenceNum is the sample sequence number.
598 //! \param pulBuffer is the address where the data is stored.
599 //!
600 //! This function copies data from the specified sample sequence output FIFO to
601 //! a memory resident buffer.  The number of samples available in the hardware
602 //! FIFO are copied into the buffer, which is assumed to be large enough to
603 //! hold that many samples.  This will only return the samples that are
604 //! presently available, which may not be the entire sample sequence if it is
605 //! in the process of being executed.
606 //!
607 //! \return Returns the number of samples copied to the buffer.
608 //
609 //*****************************************************************************
610 #if defined(GROUP_sequencedataget) || defined(BUILD_ALL) || defined(DOXYGEN)
611 long
612 ADCSequenceDataGet(unsigned long ulBase, unsigned long ulSequenceNum,
613                    unsigned long *pulBuffer)
614 {
615     unsigned long ulCount;
616
617     //
618     // Check the arguments.
619     //
620     ASSERT(ulBase == ADC_BASE);
621     ASSERT(ulSequenceNum < 4);
622
623     //
624     // Get the offset of the sequence to be read.
625     //
626     ulBase += ADC_O_SEQ + (ADC_O_SEQ_STEP * ulSequenceNum);
627
628     //
629     // Read samples from the FIFO until it is empty.
630     //
631     ulCount = 0;
632     while(!(HWREG(ulBase + ADC_O_X_SSFSTAT) & ADC_SSFSTAT_EMPTY) &&
633           (ulCount < 8))
634     {
635         //
636         // Read the FIFO and copy it to the destination.
637         //
638         *pulBuffer++ = HWREG(ulBase + ADC_O_X_SSFIFO);
639
640         //
641         // Increment the count of samples read.
642         //
643         ulCount++;
644     }
645
646     //
647     // Return the number of samples read.
648     //
649     return(ulCount);
650 }
651 #endif
652
653 //*****************************************************************************
654 //
655 //! Causes a processor trigger for a sample sequence.
656 //!
657 //! \param ulBase is the base address of the ADC module.
658 //! \param ulSequenceNum is the sample sequence number.
659 //!
660 //! This function triggers a processor-initiated sample sequence if the sample
661 //! sequence trigger is configured to ADC_TRIGGER_PROCESSOR.
662 //!
663 //! \return None.
664 //
665 //*****************************************************************************
666 #if defined(GROUP_processortrigger) || defined(BUILD_ALL) || defined(DOXYGEN)
667 void
668 ADCProcessorTrigger(unsigned long ulBase, unsigned long ulSequenceNum)
669 {
670     //
671     // Check the arguments.
672     //
673     ASSERT(ulBase == ADC_BASE);
674     ASSERT(ulSequenceNum < 4);
675
676     //
677     // Generate a processor trigger for this sample sequence.
678     //
679     HWREG(ulBase + ADC_O_PSSI) = 1 << ulSequenceNum;
680 }
681 #endif
682
683 //*****************************************************************************
684 //
685 //! Configures the software oversampling factor of the ADC.
686 //!
687 //! \param ulBase is the base address of the ADC module.
688 //! \param ulSequenceNum is the sample sequence number.
689 //! \param ulFactor is the number of samples to be averaged.
690 //!
691 //! This function configures the software oversampling for the ADC, which can
692 //! be used to provide better resolution on the sampled data.  Oversampling is
693 //! accomplished by averaging multiple samples from the same analog input.
694 //! Three different oversampling rates are supported; 2x, 4x, and 8x.
695 //!
696 //! Oversampling is only supported on the sample sequencers that are more than
697 //! one sample in depth (i.e. the fourth sample sequencer is not supported).
698 //! Oversampling by 2x (for example) divides the depth of the sample sequencer
699 //! by two; so 2x oversampling on the first sample sequencer can only provide
700 //! four samples per trigger.  This also means that 8x oversampling is only
701 //! available on the first sample sequencer.
702 //!
703 //! \return None.
704 //
705 //*****************************************************************************
706 #if defined(GROUP_softwareoversampleconfigure) || defined(BUILD_ALL) || \
707     defined(DOXYGEN)
708 void
709 ADCSoftwareOversampleConfigure(unsigned long ulBase,
710                                unsigned long ulSequenceNum,
711                                unsigned long ulFactor)
712 {
713     unsigned long ulValue;
714
715     //
716     // Check the arguments.
717     //
718     ASSERT(ulBase == ADC_BASE);
719     ASSERT(ulSequenceNum < 3);
720     ASSERT(((ulFactor == 2) || (ulFactor == 4) || (ulFactor == 8)) &&
721            ((ulSequenceNum == 0) || (ulFactor != 8)));
722
723     //
724     // Convert the oversampling factor to a shift factor.
725     //
726     for(ulValue = 0, ulFactor >>= 1; ulFactor; ulValue++, ulFactor >>= 1)
727     {
728     }
729
730     //
731     // Save the sfiht factor.
732     //
733     g_pucOversampleFactor[ulSequenceNum] = ulValue;
734 }
735 #endif
736
737 //*****************************************************************************
738 //
739 //! Configures a step of the software oversampled sequencer.
740 //!
741 //! \param ulBase is the base address of the ADC module.
742 //! \param ulSequenceNum is the sample sequence number.
743 //! \param ulStep is the step to be configured.
744 //! \param ulConfig is the configuration of this step.
745 //!
746 //! This function configures a step of the sample sequencer when using the
747 //! software oversampling feature.  The number of steps available depends on
748 //! the oversampling factor set by ADCSoftwareOversampleConfigure().  The value
749 //! of \e ulConfig is the same as defined for ADCSequenceStepConfigure().
750 //!
751 //! \return None.
752 //
753 //*****************************************************************************
754 #if defined(GROUP_softwareoversamplestepconfigure) || defined(BUILD_ALL) || \
755     defined(DOXYGEN)
756 void
757 ADCSoftwareOversampleStepConfigure(unsigned long ulBase,
758                                    unsigned long ulSequenceNum,
759                                    unsigned long ulStep,
760                                    unsigned long ulConfig)
761 {
762     //
763     // Check the arguments.
764     //
765     ASSERT(ulBase == ADC_BASE);
766     ASSERT(ulSequenceNum < 3);
767     ASSERT(((ulSequenceNum == 0) &&
768             (ulStep < (8 >> g_pucOversampleFactor[ulSequenceNum]))) ||
769            (ulStep < (4 >> g_pucOversampleFactor[ulSequenceNum])));
770
771     //
772     // Get the offset of the sequence to be configured.
773     //
774     ulBase += ADC_O_SEQ + (ADC_O_SEQ_STEP * ulSequenceNum);
775
776     //
777     // Compute the shift for the bits that control this step.
778     //
779     ulStep *= 4 << g_pucOversampleFactor[ulSequenceNum];
780
781     //
782     // Loop through the hardware steps that make up this step of the software
783     // oversampled sequence.
784     //
785     for(ulSequenceNum = 1 << g_pucOversampleFactor[ulSequenceNum];
786         ulSequenceNum; ulSequenceNum--)
787     {
788         //
789         // Set the analog mux value for this step.
790         //
791         HWREG(ulBase + ADC_O_X_SSMUX) = ((HWREG(ulBase + ADC_O_X_SSMUX) &
792                                           ~(0x0000000f << ulStep)) |
793                                          ((ulConfig & 0x0f) << ulStep));
794
795         //
796         // Set the control value for this step.
797         //
798         HWREG(ulBase + ADC_O_X_SSCTL) = ((HWREG(ulBase + ADC_O_X_SSCTL) &
799                                           ~(0x0000000f << ulStep)) |
800                                          (((ulConfig & 0xf0) >> 4) << ulStep));
801         if(ulSequenceNum != 1)
802         {
803             HWREG(ulBase + ADC_O_X_SSCTL) &= ~((ADC_SSCTL_IE0 |
804                                                 ADC_SSCTL_END0) << ulStep);
805         }
806
807         //
808         // Go to the next hardware step.
809         //
810         ulStep += 4;
811     }
812 }
813 #endif
814
815 //*****************************************************************************
816 //
817 //! Gets the captured data for a sample sequence using software oversampling.
818 //!
819 //! \param ulBase is the base address of the ADC module.
820 //! \param ulSequenceNum is the sample sequence number.
821 //! \param pulBuffer is the address where the data is stored.
822 //! \param ulCount is the number of samples to be read.
823 //!
824 //! This function copies data from the specified sample sequence output FIFO to
825 //! a memory resident buffer with software oversampling applied.  The requested
826 //! number of samples are copied into the data buffer; if there are not enough
827 //! samples in the hardware FIFO to satisfy this many oversampled data items
828 //! then incorrect results will be returned.  It is the caller's responsibility
829 //! to read only the samples that are available and wait until enough data is
830 //! available, for example as a result of receiving an interrupt.
831 //!
832 //! \return None.
833 //
834 //*****************************************************************************
835 #if defined(GROUP_softwareoversampledataget) || defined(BUILD_ALL) || \
836     defined(DOXYGEN)
837 void
838 ADCSoftwareOversampleDataGet(unsigned long ulBase, unsigned long ulSequenceNum,
839                              unsigned long *pulBuffer, unsigned long ulCount)
840 {
841     unsigned long ulIdx, ulAccum;
842
843     //
844     // Check the arguments.
845     //
846     ASSERT(ulBase == ADC_BASE);
847     ASSERT(ulSequenceNum < 3);
848     ASSERT(((ulSequenceNum == 0) &&
849             (ulCount < (8 >> g_pucOversampleFactor[ulSequenceNum]))) ||
850            (ulCount < (4 >> g_pucOversampleFactor[ulSequenceNum])));
851
852     //
853     // Get the offset of the sequence to be read.
854     //
855     ulBase += ADC_O_SEQ + (ADC_O_SEQ_STEP * ulSequenceNum);
856
857     //
858     // Read the samples from the FIFO until it is empty.
859     //
860     while(ulCount--)
861     {
862         //
863         // Compute the sum of the samples.
864         //
865         ulAccum = 0;
866         for(ulIdx = 1 << g_pucOversampleFactor[ulSequenceNum]; ulIdx; ulIdx--)
867         {
868             //
869             // Read the FIFO and add it to the accumulator.
870             //
871             ulAccum += HWREG(ulBase + ADC_O_X_SSFIFO);
872         }
873
874         //
875         // Write the averaged sample to the output buffer.
876         //
877         *pulBuffer++ = ulAccum >> g_pucOversampleFactor[ulSequenceNum];
878     }
879 }
880 #endif
881
882 //*****************************************************************************
883 //
884 //! Configures the hardware oversampling factor of the ADC.
885 //!
886 //! \param ulBase is the base address of the ADC module.
887 //! \param ulFactor is the number of samples to be averaged.
888 //!
889 //! This function configures the hardware oversampling for the ADC, which can
890 //! be used to provide better resolution on the sampled data.  Oversampling is
891 //! accomplished by averaging multiple samples from the same analog input.  Six
892 //! different oversampling rates are supported; 2x, 4x, 8x, 16x, 32x, and 64x.
893 //! Specifying an oversampling factor of zero will disable the hardware
894 //! oversampler.
895 //!
896 //! Hardware oversampling applies uniformly to all sample sequencers.  It does
897 //! not reduce the depth of the sample sequencers like the software
898 //! oversampling APIs; each sample written into the sample sequence FIFO is a
899 //! fully oversampled analog input reading.
900 //!
901 //! Enabling hardware averaging increases the precision of the ADC at the cost
902 //! of throughput.  For example, enabling 4x oversampling reduces the
903 //! throughput of a 250 KSps ADC to 62.5 KSps.
904 //!
905 //! \note Hardware oversampling is available beginning with Rev C0 of the
906 //! Stellaris microcontroller.
907 //!
908 //! \return None.
909 //
910 //*****************************************************************************
911 #if defined(GROUP_hardwareoversampleconfigure) || defined(BUILD_ALL) || \
912     defined(DOXYGEN)
913 void
914 ADCHardwareOversampleConfigure(unsigned long ulBase,
915                                unsigned long ulFactor)
916 {
917     unsigned long ulValue;
918
919     //
920     // Check the arguments.
921     //
922     ASSERT(ulBase == ADC_BASE);
923     ASSERT(((ulFactor == 0) || (ulFactor == 2) || (ulFactor == 4) ||
924            (ulFactor == 8) || (ulFactor == 16) || (ulFactor == 32) ||
925            (ulFactor == 64)));
926
927     //
928     // Convert the oversampling factor to a shift factor.
929     //
930     for(ulValue = 0, ulFactor >>= 1; ulFactor; ulValue++, ulFactor >>= 1)
931     {
932     }
933
934     //
935     // Write the shift factor to the ADC to configure the hardware oversampler.
936     //
937     HWREG(ulBase + ADC_O_SAC) = ulValue;
938 }
939 #endif
940
941 //*****************************************************************************
942 //
943 // Close the Doxygen group.
944 //! @}
945 //
946 //*****************************************************************************