OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [CORTEX_LM3S811_IAR/] [LuminaryCode/] [adc.c] - Blame information for rev 581

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 581 jeremybenn
//*****************************************************************************
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
//*****************************************************************************

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.