Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / colonet / utilities / robot_wireless_relay / analog.c @ 13

History | View | Annotate | Download (2.78 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
void analog_init(void)
14
{
15
        /*
16
   * ADC Status Register A
17
   * Bit 7 - ADEN is set (enables analog)
18
   * Bit 6 - Start conversion bit is set (must be done once for free-running 
19
   * mode)
20
   * Bit 5 - Enable Auto Trigger (for free running mode)
21
   * Bit 3 - Enable ADC Interrupt (required to run free-running mode)
22
   * Bits 2-0 - Set to create a clock divisor of 128, to make ADC clock = 
23
   * 16,000,000/128
24
   */
25
        ADCSRA |= 0xEF;
26

    
27
        /*
28
   * ADMUX register
29
   * Bit 7,6 - Set voltage reference to AVcc (0b01)
30
   * Bit 5 - Set ADLAR bit for left adjust to do simple 8-bit reads
31
   * Bit 4 - X
32
   * Bit 3:0 - Sets the current channel
33
   */
34
        ADMUX = 0x67;
35
        
36
#ifdef FFPP
37
        DDRA |= 0x70;
38
        set_adc_mux(0x07);
39
#endif
40
}        
41

    
42
#ifdef FFPP
43
void set_adc_mux(int which)
44
{
45
  // A4..A6 set mux to port 0-7 via binary selection
46
  
47
  // mask so only proper bits are possible.
48
  which &= 0x07;
49
  PORTA &= 0x8F;
50
  PORTA |= which << 4;
51
}
52

    
53
void enable_analog(int analog_setting)        //why do we need this?
54
{
55
        // Digital input disable - don't disable any of them
56
        // Set any of the lower six bits to a 1 to disable that bit
57
        DDRF = 0x00; //ALL_ANALOG;
58
}
59
#endif
60

    
61
unsigned int analog8(int which)
62
{
63
#ifdef FFPP
64
        if(which < EXT_MUX){
65
      ADMUX = 0x60 + which;
66
  }else if(which == EXT_MUX){                //Why dont we combine this and the above?
67
    return 0;
68
  }else{
69
    ADMUX = 0x60 + EXT_MUX;
70
    set_adc_mux(which - 8);
71
    _delay_ms(10);
72
  }
73
#else
74
        ADMUX = 0x60 + which;
75
#endif
76

    
77
        _delay_ms(1); 
78
  // need at least 130 us between conversions (for fwr robot, how much for 
79
  //new avr?)
80
        return ADCH;
81
}
82

    
83
unsigned int analog10(int which)
84
{
85
        unsigned int adc_h = 0;
86
        unsigned int adc_l = 0;
87

    
88
#ifdef FFPP
89

    
90
        if(which < EXT_MUX){
91
    ADMUX = 0x60 + which;
92
  }else if(which == EXT_MUX){                //Why dont we combine this and the above?
93
    return 0;
94
  }else{
95
    ADMUX = 0x60 + EXT_MUX;
96
    set_adc_mux(which - 8);
97
    _delay_ms(10);
98
  }
99

    
100
#else
101
        ADMUX = 0x60 + which;
102
#endif
103
        _delay_ms(1);
104
        adc_l = ADCL; /* highest 2 bits of ADCL -> least 2 bits of analog val */
105
        adc_h = ADCH; /* ADCH -> 8 highest bits of analog val */
106
        
107
        return (adc_h << 2) | (adc_l >> 6);
108
}
109

    
110
int wheel(void)
111
{
112
        return analog8(WHEEL_PORT);
113
}
114

    
115
int battery(void)
116
{
117
  /* 5 volts is the max, 255 is the max 8bit number , *2 for the divider */
118
        return analog8(BATT_PORT) * 500 >>7;
119
}
120

    
121
SIGNAL (SIG_ADC)
122
{
123
        // This is just here to catch ADC interrupts because ADC is free running.  
124
        // No code needs to be in here.
125
}