Project

General

Profile

Statistics
| Revision:

root / trunk / code / lib / src / libdragonfly / analog.c @ 7

History | View | Annotate | Download (3.73 KB)

1
/*
2
 * analog.c - Contains the function implementations for manipulating the ADC
3
 * on the firefly+ board
4
 * 
5
 * author:  CMU Robotics Club, Colony Project
6
 * code mostly taken from fwr analog file (author: Tom Lauwers)
7
 */
8

    
9
#include <util/delay.h>
10
#include <avr/interrupt.h>
11
#include "analog.h"
12

    
13
// Internal Function Prototypes
14
void set_adc_mux(int which);
15

    
16
/**
17
 * @defgroup analog Analog
18
 * Functions for manipulation the ADC on the dragonfly board.
19
 * All definitions may be found in analog.h.
20
 *
21
 * @{
22
 **/
23

    
24

    
25
/**
26
 * Initializes the ADC.
27
 * Call analog_init before reading from the analog ports.
28
 *
29
 * @see analog8, analog10
30
 **/
31
void analog_init(void)
32
{
33
        // ADC Status Register A
34
        // Bit 7 - ADEN is set (enables analog)
35
        // Bit 6 - Start conversion bit is set (must be done once for free-running mode)
36
        // Bit 5 - Enable Auto Trigger (for free running mode)
37
        // Bit 4 - ADC interrupt flag, 0
38
        // Bit 3 - Enable ADC Interrupt (required to run free-running mode)
39
        // Bits 2-0 - Set to create a clock divisor of 128, to make ADC clock = 8,000,000/128
40
        ADCSRA |= 0xEF;
41

    
42
        // ADC Status Register B
43
        // Bit 7, 5-3 - Must be cleared
44
        // Bit 2:0 - Set mode, currently cleared for free running operation
45
        // Bit 6 - Analog comparator mode - cleared
46
//        ADCSRB = 0x00;
47
        
48
        // ADMUX register
49
        // Bit 7,6 - Set voltage reference to AVcc (0b01)
50
        // Bit 5 - Set ADLAR bit for left adjust to do simple 8-bit reads
51
        // Bit 4 - X
52
        // Bit 3:0 - Sets the current channel, set to ADC7 (the external mux)
53
        ADMUX = 0x67;
54

    
55
        // Set external mux lines to outputs
56
        DDRG |= 0x1C;
57
        set_adc_mux(0x07);
58
}        
59

    
60

    
61
/**
62
 * Reads an eight bit number from an analog port.
63
 * analog_init must be called before using this function.
64
 * 
65
 * @param which the analog port to read from. One of
66
 * the constants AN0 - AN7.
67
 *
68
 * @return the eight bit input to the specified port
69
 *
70
 * @see analog_init, analog10
71
 **/
72
unsigned int analog8(int which)
73
{
74
        if(which < EXT_MUX)
75
                ADMUX = 0x60 + which;
76
        else if(which == EXT_MUX)
77
                return 0;
78
        else
79
        {
80
                ADMUX = 0x60 + EXT_MUX;
81
                set_adc_mux(which - 8);
82
                _delay_ms(1);
83
        }
84
        
85
        _delay_ms(1); // need at least 130 us between conversions
86
        return ADCH;
87
}
88

    
89
/**
90
 * Reads a ten bit number from the specified port.
91
 * analog_init must be called before using this function.
92
 *
93
 * @param which the analog port to read from. Typically
94
 * a constant, one of AN0 - AN7.
95
 *
96
 * @return the ten bit number input to the specified port
97
 * 
98
 * @see analog_init, analog8
99
 **/
100
unsigned int analog10(int which)
101
{
102
        unsigned int adc_h = 0;
103
        unsigned int adc_l = 0;
104

    
105
        if(which < EXT_MUX)
106
                ADMUX = 0x60 + which;
107
        else if(which == EXT_MUX)
108
                return 0;
109
        else
110
        {
111
                ADMUX = 0x60 + EXT_MUX;
112
                set_adc_mux(which - 8);
113
                _delay_ms(1);
114
        }
115

    
116
        _delay_ms(1);
117
        adc_l = ADCL; /* highest 2 bits of ADCL -> least 2 bits of analog val */
118
        adc_h = ADCH; /* ADCH -> 8 highest bits of analog val */
119
        
120
        return (adc_h << 2) | (adc_l >> 6);
121
}
122

    
123
/**
124
 * Returns the current position of the wheel, as an integer
125
 * in the range 0 - 255.
126
 * analog_init must be called before using this function.
127
 *
128
 * @return the orientation of the wheel, as an integer in
129
 * the range 0 - 255.
130
 *
131
 * @see analog_init
132
 **/
133
int wheel(void)
134
{
135
        return analog8(WHEEL_PORT);
136
}
137

    
138
/**@}**/ //end defgroup
139

    
140
SIGNAL (SIG_ADC)
141
{
142
        // This is just here to catch ADC interrupts because ADC is free running.  
143
        // No code needs to be in here.
144
}
145

    
146
void set_adc_mux(int which)
147
{
148
  // FIX THIS IN NEXT REVISION
149
  // ADDR2 ADDR1 ADDR0
150
  // G2.G4.G3 set mux to port 0-7 via binary selection
151
  // math would be much cleaner if it was G4.G3.G2
152
  
153
  // mask so only proper bits are possible.  
154
  PORTG = (PORTG & 0xE3) | ((which & 0x03) << 3) | (which & 0x04);
155
}
156