ADCREFM.nc
上传用户:joranyuan
上传日期:2022-06-23
资源大小:3306k
文件大小:8k
源码类别:

网络

开发平台:

Others

  1. // $Id: ADCREFM.nc,v 1.1.1.1 2005/04/22 04:26:45 acwarrie Exp $
  2. /* tab:4
  3.  * "Copyright (c) 2000-2003 The Regents of the University  of California.  
  4.  * All rights reserved.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software and its
  7.  * documentation for any purpose, without fee, and without written agreement is
  8.  * hereby granted, provided that the above copyright notice, the following
  9.  * two paragraphs and the author appear in all copies of this software.
  10.  * 
  11.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  12.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  13.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  14.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  15.  * 
  16.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  17.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  18.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  19.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  20.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
  21.  *
  22.  * Copyright (c) 2002-2003 Intel Corporation
  23.  * All rights reserved.
  24.  *
  25.  * This file is distributed under the terms in the attached INTEL-LICENSE     
  26.  * file. If you do not find these files, copies can be found by writing to
  27.  * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, 
  28.  * 94704.  Attention:  Intel License Inquiry.
  29.  */
  30. /*
  31.  *
  32.  * Authors: Jason Hill, David Gay, Philip Levis, Phil Buonadonna
  33.  * Version: $Id: ADCREFM.nc,v 1.1.1.1 2005/04/22 04:26:45 acwarrie Exp $
  34.  *
  35.  */
  36. /*  OS component abstraction of the analog to digital converter using a 
  37.  *  fixed reference input.  I assumes the presence of a TOS_ADC_BANDGAP_PORT
  38.  *  to provide that referenced reading. This module was designed to 
  39.  *  accomodate platforms that use varying/unstable ADC references. It also
  40.  *  works around limitations where the measured variable cannot be larger than
  41.  *  the actual ADC reference
  42.  *
  43.  *  The conversion result is given by the equation:
  44.  * 
  45.  *    ADC = (Vport * 1024) / Vref
  46.  * 
  47.  *  Where Vport can be between zero and (2^6-1)*Vref (I.E. Vport CAN be larger
  48.  *  than Vref)
  49.  * 
  50.  *  Note: On the ATmega128, Vref (using this module) is 1.23 Volts
  51.  */
  52. /*  ADC_INIT command initializes the device */
  53. /*  ADC_GET_DATA command initiates acquiring a sensor reading. */
  54. /*  It returns immediately.   */
  55. /*  ADC_DATA_READY is signaled, providing data, when it becomes */
  56. /*  available. */
  57. /*  Access to the sensor is performed in the background by a separate */
  58. /* TOS task. */
  59. module ADCREFM 
  60. {
  61.   provides {
  62.     interface ADC[uint8_t port]; // The RAW ADC interface
  63.     interface ADC as CalADC[uint8_t port];
  64.     interface ADCControl;
  65.   }
  66.   uses {
  67.     interface HPLADC;
  68.     interface Timer;
  69.   }
  70. }
  71. implementation
  72. {
  73.   enum {
  74.     IDLE = 0,
  75.     SINGLE_CONVERSION = 1,
  76.     CONTINUOUS_CONVERSION = 2,
  77.   };
  78.   uint16_t ReqPort;
  79.   uint16_t ReqVector;
  80.   uint16_t ContReqMask;
  81.   uint16_t CalReqMask;
  82.   uint32_t RefVal;
  83.   task void CalTask() {
  84.     call ADCControl.manualCalibrate();
  85.     return;
  86.   }
  87.   command result_t ADCControl.init() {
  88.     atomic {
  89.       ReqPort = 0;
  90.       ReqVector = ContReqMask = CalReqMask= 0;
  91.       RefVal = 381; // Reference value assuming 3.3 Volt power source
  92.     }
  93.     dbg(DBG_BOOT, ("ADC initialized.n"));
  94.     
  95.     return call HPLADC.init();
  96.   }
  97.   command result_t ADCControl.setSamplingRate(uint8_t rate) {
  98.     return call HPLADC.setSamplingRate(rate);
  99.   }
  100.   command result_t ADCControl.bindPort(uint8_t port, uint8_t adcPort) {
  101.     return call HPLADC.bindPort(port, adcPort);
  102.   }
  103.   default async event result_t ADC.dataReady[uint8_t port](uint16_t data) {
  104.     return FAIL; // ensures ADC is disabled if no handler
  105.   }
  106.   default async event result_t CalADC.dataReady[uint8_t port](uint16_t data) {
  107.     return FAIL; // ensures ADC is disabled if no handler
  108.   }
  109.   event result_t Timer.fired() {
  110.     post CalTask();
  111.     return SUCCESS;
  112.   }
  113.   async event result_t HPLADC.dataReady(uint16_t data) {
  114.     uint16_t doneValue = data;
  115.     uint8_t donePort;
  116.     uint8_t nextPort = 0xff;
  117.     bool fCalResult = FALSE;
  118.     result_t Result = SUCCESS;
  119.     if (ReqPort == TOS_ADC_BANDGAP_PORT) {
  120.       RefVal = data;
  121.     }
  122.     // BEGIN atomic
  123.     atomic { 
  124.       donePort = ReqPort;
  125.       // Check to see if this port has requested continous conversio
  126.       if (((1<<donePort) & ContReqMask) == 0) { 
  127. ReqVector ^= (1<<donePort); 
  128.       }
  129.       
  130.       // Check for calibrated result
  131.       if ((1<<donePort) & CalReqMask) {
  132. fCalResult = TRUE;
  133. if (((1<<donePort) & ContReqMask) == 0) { 
  134.   CalReqMask ^= (1<<donePort);
  135. }
  136.       }
  137.       if (ReqVector) {
  138. // Always ensure we rotate through the reference port 
  139. //ReqVector |= (1<<TOS_ADC_BANDGAP_PORT); 
  140. do {
  141.   ReqPort++;
  142.           ReqPort = (ReqPort == TOSH_ADC_PORTMAPSIZE) ? 0 : ReqPort;
  143. } while (((1<<ReqPort) & ReqVector) == 0);
  144. nextPort = ReqPort;
  145.       }
  146.     }
  147.     // END atomic
  148.     if (nextPort != 0xff) {
  149.       call HPLADC.samplePort(nextPort);  // This function is interupt-safe  
  150.     }
  151.   
  152.     dbg(DBG_ADC, "adc_tick: port %d with value %i n", donePort, (int)data);
  153.     if (donePort != TOS_ADC_BANDGAP_PORT) {
  154.       if (fCalResult) {
  155. uint32_t tmp = (uint32_t) data;
  156. tmp = tmp << 10;  // data * 1024
  157. tmp = (tmp / RefVal);  // doneValue = data * 1024/ref
  158. doneValue = (uint16_t) tmp;
  159. Result = signal CalADC.dataReady[donePort](doneValue);
  160.       }
  161.       else {
  162. Result = signal ADC.dataReady[donePort](doneValue);
  163.       }
  164.     }
  165.    
  166.     atomic {
  167.       if ((ContReqMask & (1<<donePort)) && (Result == FAIL)) {
  168.       ContReqMask ^= (1<<donePort);
  169.       }
  170.     }
  171.     return SUCCESS;
  172.   }
  173.  
  174.   result_t startGet(uint8_t port) {
  175.     uint16_t PortMask, oldReqVector = 1;
  176.     result_t Result = SUCCESS;
  177.     
  178.     PortMask = (1<<port);
  179.     if ((PortMask & ReqVector) != 0) {
  180.       // Already a pending request on this port
  181.       Result = FAIL;
  182.     }
  183.     else {
  184.       oldReqVector = ReqVector;
  185.       ReqVector |= PortMask;
  186.       if (oldReqVector == 0) {
  187. if((Result = call HPLADC.samplePort(port))){
  188.        ReqPort = port;
  189. }
  190.       }
  191.     }
  192.     
  193.     return Result;
  194.   }
  195.   async command result_t ADC.getData[uint8_t port]() {
  196.     result_t Result;
  197.     if (port > TOSH_ADC_PORTMAPSIZE) {
  198.       return FAIL;
  199.     }
  200.     atomic {
  201.       Result = startGet(port);
  202.     }
  203.     return Result;
  204.   }
  205.   async command result_t CalADC.getData[uint8_t port]() {
  206.     result_t Result = SUCCESS;
  207.     if (port > TOSH_ADC_PORTMAPSIZE) {
  208.       return FAIL;
  209.     }
  210.     atomic {
  211.       CalReqMask |= (1<<port);
  212.       Result = startGet(port);
  213.       if (Result == FAIL) {
  214. CalReqMask ^= (1<<port);
  215.       }
  216.     }
  217.     return Result;
  218.   }
  219.   async command result_t ADC.getContinuousData[uint8_t port]() {
  220.     result_t Result = SUCCESS;
  221.     if (port > TOSH_ADC_PORTMAPSIZE) {
  222.       return FAIL;
  223.     }
  224.     atomic {
  225.       ContReqMask |= (1<<port);
  226.       Result = startGet(port);
  227.       if (Result == FAIL) {
  228. ContReqMask ^= (1<<port);
  229.       }
  230.     }
  231.     return Result;
  232.   }
  233.   async command result_t CalADC.getContinuousData[uint8_t port]() {
  234.     result_t Result = SUCCESS;
  235.     if (port > TOSH_ADC_PORTMAPSIZE) {
  236.       return FAIL;
  237.     }
  238.     atomic {
  239.       ContReqMask |= (1<<port);
  240.       CalReqMask  |= (1<<port);
  241.       Result = startGet(port);
  242.       if (Result == FAIL) {
  243. ContReqMask ^= (1<<port);
  244. CalReqMask ^= (1<<port);
  245.       }
  246.     }
  247.     return Result;
  248.   }
  249.   async command result_t ADCControl.manualCalibrate() {
  250.     result_t Result;
  251.     atomic {
  252.       Result = startGet(TOS_ADC_BANDGAP_PORT);
  253.     }
  254.     return Result;
  255.   }
  256.   async command result_t ADCControl.autoCalibrate(uint16_t interval) {
  257.     result_t Result;
  258.     if (interval == 0) {
  259.       Result = call Timer.stop();
  260.     }
  261.     else {
  262.       Result = call Timer.start(TIMER_REPEAT,interval);
  263.     }
  264.     return Result;
  265.   }
  266. }