MHVLib  20111011
An efficiency oriented runtime library for AVR microcontrollers
A:/eclipse/mhvlib/MHV_ADC.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2011, Make, Hack, Void Inc
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *  * Redistributions of source code must retain the above copyright
00008  *    notice, this list of conditions and the following disclaimer.
00009  *  * Redistributions in binary form must reproduce the above copyright
00010  *    notice, this list of conditions and the following disclaimer in the
00011  *    documentation and/or other materials provided with the distribution.
00012  *  * Neither the name of the Make, Hack, Void nor the
00013  *    names of its contributors may be used to endorse or promote products
00014  *    derived from this software without specific prior written permission.
00015  *
00016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00017  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00018  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019  * DISCLAIMED. IN NO EVENT SHALL MAKE, HACK, VOID BE LIABLE FOR ANY
00020  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00021  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00022  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00023  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00024  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00025  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  */
00027 #include <MHV_ADC.h>
00028 
00035 MHV_ADC::MHV_ADC(MHV_EVENT_ADC *adcs, uint8_t adcCount) {
00036         _adcs = adcs;
00037         _adcCount = adcCount;
00038 
00039         _adcChannel = -1;
00040 
00041         mhv_memClear(_adcs, sizeof(*_adcs), adcCount);
00042 }
00043 
00047 void MHV_ADC::adc() {
00048         _adcValue = ADC;
00049         _adcChannel = MHV_AD_CHANNEL;
00050 
00051         MHV_AD_DISABLE_INTERRUPT;
00052 }
00053 
00059 void MHV_ADC::registerListener(uint8_t channel, MHV_ADCListener *listener) {
00060         for (uint8_t i = 0; i < _adcCount; i++) {
00061                 if (_adcs[i].channel == -1) {
00062                         _adcs[i].channel = channel;
00063                         _adcs[i].listener = listener;
00064                         break;
00065                 }
00066         }
00067 }
00068 
00073 void MHV_ADC::deregisterListener(uint8_t channel) {
00074         for (uint8_t i = 0; i < _adcCount; i++) {
00075                 if (_adcs[i].channel == channel) {
00076                         _adcs[i].channel = -1;
00077                         break;
00078                 }
00079         }
00080 }
00081 
00087 uint16_t MHV_ADC::busyRead(uint8_t channel, uint8_t reference) {
00088         ADMUX = reference | (channel & 0x0F);
00089 
00090 #ifdef MUX5
00091         ADCSRB = (ADCSRB & ~_BV(MUX5)) | ((channel & _BV(5) >> (5-MUX5)));
00092 #endif
00093 
00094 // Start the conversion
00095         ADCSRA |= _BV(ADSC);
00096 
00097         while (ADCSRA & _BV(ADSC)) {};
00098 
00099         return ADC;
00100 }
00101 
00107 void MHV_ADC::asyncRead(uint8_t channel, uint8_t reference) {
00108         ADMUX = reference | (channel & 0x0F);
00109 
00110 #ifdef MUX5
00111         ADCSRB = (ADCSRB & ~_BV(MUX5)) | ((channel & _BV(5) >> (5-MUX5)));
00112 #endif
00113 
00114 // Start the conversion
00115         ADCSRA |= _BV(ADSC);
00116 
00117         MHV_AD_ENABLE_INTERRUPT;
00118 }
00119 
00124 void MHV_ADC::setPrescaler(MHV_AD_PRESCALER prescaler) {
00125         ADCSRA = (ADCSRA & 0xf8) | (prescaler & 0x7);
00126 }
00127 
00128 
00132 void MHV_ADC::handleEvents() {
00133         uint8_t i;
00134 
00135         if (_adcChannel != -1) {
00136                 for (i = 0; i < _adcCount; i++) {
00137                         if (_adcs[i].channel == _adcChannel) {
00138                                 _adcChannel = -1;
00139                                 _adcs[i].listener->adc(_adcs[i].channel, _adcValue);
00140                                 break;
00141                         }
00142                 }
00143         }
00144 }