
<font color="#a020f0">#include </font><font color="#ff00ff">&quot;c:\cvavr\inc\mega128.h&quot;</font>
<font color="#a020f0">#include </font><font color="#ff00ff">&quot;portdef.h&quot;</font>
<font color="#a020f0">#include </font><font color="#ff00ff">&quot;adc.h&quot;</font>

<font color="#2e8b57"><b>extern</b></font> <font color="#2e8b57"><b>void</b></font> serprintstr(<font color="#2e8b57"><b>char</b></font> *);
<font color="#2e8b57"><b>extern</b></font> <font color="#2e8b57"><b>int</b></font> systime_ms;

<font color="#0000ff">/*</font><font color="#0000ff"> adc_state is used to store the channel that we are currently reading, </font>
<font color="#0000ff"> * and whether we are still waiting for it or if it's already read.</font>
<font color="#0000ff"> */</font>
ADCState adc_state;

<font color="#2e8b57"><b>int</b></font> ADCdata[<font color="#ff00ff">8</font>];         <font color="#0000ff">// The actual data we got from the adc</font>
<font color="#2e8b57"><b>int</b></font> ADCoffsets[<font color="#ff00ff">8</font>];  <font color="#0000ff">// The offset of the accel/gyro</font>
<font color="#2e8b57"><b>int</b></font> ADCscalingn[<font color="#ff00ff">8</font>]; <font color="#0000ff">// The scaling numerator (multiply by this)</font>
<font color="#2e8b57"><b>int</b></font> ADCscalingd[<font color="#ff00ff">8</font>]; <font color="#0000ff">// The scaling denominator (divide by this)</font>

<font color="#2e8b57"><b>void</b></font> ADCinit(<font color="#2e8b57"><b>void</b></font>) {
        EICRB=<font color="#ff00ff">0x80</font>; <font color="#0000ff">// trigger INT7 on falling edge (/INT line of ADC)</font>
        EIMSK=<font color="#ff00ff">0x80</font>;
        DDRE=<font color="#ff00ff">0x70</font>;  <font color="#0000ff">// Bits 4,5,6 are outputs   </font>
        adc_state.chan=<font color="#ff00ff">0</font>;
        adc_state.waiting=<font color="#ff00ff">0</font>;
        ADCCtrlRD = <font color="#ff00ff">1</font>;
        ADCCtrlWR = <font color="#ff00ff">1</font>;

        <font color="#0000ff">// 2-4 are gyros, 5-7 are accelerometers</font>
        ADCoffsets[<font color="#ff00ff">2</font>]=<font color="#ff00ff">2096</font>;
        ADCoffsets[<font color="#ff00ff">3</font>]=<font color="#ff00ff">1398</font>;
        ADCoffsets[<font color="#ff00ff">4</font>]=<font color="#ff00ff">1988</font>;
        ADCoffsets[<font color="#ff00ff">5</font>]=<font color="#ff00ff">1160</font>;
        ADCoffsets[<font color="#ff00ff">6</font>]=<font color="#ff00ff">1195</font>;
        ADCoffsets[<font color="#ff00ff">7</font>]=<font color="#ff00ff">1133</font>;

        ADCscalingn[<font color="#ff00ff">2</font>]=<font color="#ff00ff">1</font>;
        ADCscalingn[<font color="#ff00ff">3</font>]=<font color="#ff00ff">1</font>;
        ADCscalingn[<font color="#ff00ff">4</font>]=<font color="#ff00ff">1</font>;
        ADCscalingn[<font color="#ff00ff">5</font>]=<font color="#ff00ff">2</font>;
        ADCscalingn[<font color="#ff00ff">6</font>]=<font color="#ff00ff">2</font>;
        ADCscalingn[<font color="#ff00ff">7</font>]=<font color="#ff00ff">2</font>;

        ADCscalingd[<font color="#ff00ff">2</font>]=<font color="#ff00ff">1</font>;
        ADCscalingd[<font color="#ff00ff">3</font>]=<font color="#ff00ff">1</font>;
        ADCscalingd[<font color="#ff00ff">4</font>]=<font color="#ff00ff">1</font>;
        ADCscalingd[<font color="#ff00ff">5</font>]=<font color="#ff00ff">1</font>;
        ADCscalingd[<font color="#ff00ff">6</font>]=<font color="#ff00ff">1</font>;
        ADCscalingd[<font color="#ff00ff">7</font>]=<font color="#ff00ff">1</font>;
}

<font color="#0000ff">/*</font><font color="#0000ff"> Set up a conversion for the next channel. */</font>
<font color="#2e8b57"><b>void</b></font> ADCCnvSetup(<font color="#2e8b57"><b>void</b></font>) {
        DisableInterrupts;
        DDRA = <font color="#ff00ff">0xFF</font>;
        ADCCtrlWR = <font color="#ff00ff">0</font>;
        <font color="#0000ff">// Normal operation, internal clock mode, internally controlled acquisition,</font>
        <font color="#0000ff">// 0 to 5V input range                     </font>
        PORTA = (0b01000000 + adc_state.chan);
        ADCCtrlWR = <font color="#ff00ff">1</font>;
        adc_state.waiting=<font color="#ff00ff">1</font>;
        EnableInterrupts;
}

<font color="#0000ff">/*</font><font color="#0000ff"> When we get an interrupt from the ADC, read in the data */</font>
interrupt [EXT_INT7] <font color="#2e8b57"><b>void</b></font> adc_ready(<font color="#2e8b57"><b>void</b></font>) {
        <font color="#0000ff">// If we are waiting for a conversion</font>
        <font color="#804040"><b>if</b></font>(adc_state.waiting) {
            adc_state.waiting=<font color="#ff00ff">0</font>;
                DDRA = <font color="#ff00ff">0x00</font>;
                ADCCtrlRD = <font color="#ff00ff">0</font>;
                ADCCtrlHBEN = <font color="#ff00ff">0</font>;
                ADCdata[adc_state.chan]=<font color="#ff00ff">0x0000</font>;
                <font color="#0000ff">// Read in the low byte</font>
                ADCdata[adc_state.chan]=PINA;
                ADCCtrlHBEN = <font color="#ff00ff">1</font>;
                <font color="#0000ff">// Read in the high byte</font>
                ADCdata[adc_state.chan]+=((<font color="#2e8b57"><b>int</b></font>)(PINA &amp; <font color="#ff00ff">0x0F</font>)) &lt;&lt;<font color="#ff00ff">8</font>;
                ADCCtrlRD = <font color="#ff00ff">1</font>;
                <font color="#0000ff">// Scale the data </font>
                ADCdata[adc_state.chan]=ADCdata[adc_state.chan]-ADCoffsets[adc_state.chan];
                ADCdata[adc_state.chan]=ADCscalingn[adc_state.chan]*ADCdata[adc_state.chan];
                ADCdata[adc_state.chan]=ADCdata[adc_state.chan]/ADCscalingd[adc_state.chan];
                adc_state.chan++;
        }
        ADCCnvSetup();
}
