[Tinyos-2-commits] CVS: tinyos-2.x/tos/chips/msp430/adc12 Msp430Adc12MultiChannel.nc, NONE, 1.1.2.1 Msp430Adc12Overflow.nc, NONE, 1.1.2.1 HplAdc12.nc, 1.1.2.6, 1.1.2.7 HplAdc12P.nc, 1.1.2.4, 1.1.2.5 Msp430Adc12ClientC.nc, 1.1.2.7, 1.1.2.8 Msp430Adc12.h, 1.1.2.8, 1.1.2.9 Msp430Adc12ImplP.nc, 1.1.2.2, 1.1.2.3 Msp430Adc12P.nc, 1.1.2.11, 1.1.2.12 Msp430Adc12SingleChannel.nc, 1.1.2.8, 1.1.2.9 Msp430RefVoltGeneratorP.nc, 1.1.2.4, 1.1.2.5 README.txt, 1.1.2.2, 1.1.2.3

Jan-Hinrich Hauer janhauer at users.sourceforge.net
Mon Nov 20 06:47:15 PST 2006


Update of /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv15454/tos/chips/msp430/adc12

Modified Files:
      Tag: tinyos-2_0_devel-BRANCH
	HplAdc12.nc HplAdc12P.nc Msp430Adc12ClientC.nc Msp430Adc12.h 
	Msp430Adc12ImplP.nc Msp430Adc12P.nc 
	Msp430Adc12SingleChannel.nc Msp430RefVoltGeneratorP.nc 
	README.txt 
Added Files:
      Tag: tinyos-2_0_devel-BRANCH
	Msp430Adc12MultiChannel.nc Msp430Adc12Overflow.nc 
Log Message:
Added a new interface (Msp430Adc12MultiChannel) and some code that can be used to sample up to 16 different ADC channels with a single command.

--- NEW FILE: Msp430Adc12MultiChannel.nc ---
/* 
 * Copyright (c) 2006, Technische Universitaet Berlin
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 * - Neither the name of the Technische Universitaet Berlin nor the names
 *   of its contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * - Revision -------------------------------------------------------------
 * $Revision: 1.1.2.1 $
 * $Date: 2006/11/20 14:47:10 $
 * @author: Jan Hauer <hauer at tkn.tu-berlin.de>
 * ========================================================================
 */

/** 
 * This interface provides access to the ADC12 on the level of HAL. It can be
 * used to sample up to 16 (different) ADC channels. It separates between
 * configuration and data collection: every time a client has been granted
 * access to the ADC subsystem (via the Resource interface), it first has to
 * configure the ADC.  Afterwards the client may call getData() more than once
 * without reconfiguring the ADC in between (if the client has not released the
 * ADC via the Resource interface), i.e.<p>
 * 
 *    configure() -> ( getData() -> dataReady() )*
 *
 * @author Jan Hauer 
 */

#include "Msp430Adc12.h" 
interface Msp430Adc12MultiChannel 
{   

  /** 
   * Configures the ADC to perform conversion(s) on multiple channels.  Any
   * previous configuration will be overwritten.  If SUCCESS is returned
   * calling <code>getData()</code> will start the conversion immediately and a
   * <code>dataReady()</code> event will be signalled with the conversion
   * result when the conversion has finished.
   *
   * @param config Main ADC12 configuration and configuration of the first
   * channel 
   *
   * @param memctl List of additional channels and respective reference
   * voltages
   *
   * @param numMemctl Number of entries in the list
   * 
   * @param buffer Buffer to store the conversion results, it must have
   * numSamples entries. Results will be stored in the order the channels where
   * specified.
   *
   * @param numSamples Total number of samples. Note: numSamples %
   * (numMemctl+1) must be zero. For example, to sample every channel twice use
   * numSamples = (numMemctl+1) * 2
   *
   * @param jiffies Sampling period per sequence in terms of clock ticks of
   * "sampcon_ssel" and input divider "sampcon_id". A sequence of (numMemctl+1)
   * is always sampled as fast as possible and <code>jiffies</code> specifies
   * the time between those sequences. For example, if numSamples =
   * (numMemctl+1) * 5, then dataReady() will be signalled after (approx.)
   * 5*jiffies clock ticks after the call to getData() and each set of
   * numMemctl+1 channels was sampled at (almost) the same time.
   *
   * @return SUCCESS means that the ADC was configured successfully and
   * <code>getData()</code> can be called to start the conversion.
   */

  async command error_t configure(const msp430adc12_channel_config_t *config,
      adc12memctl_t *memctl, uint8_t numMemctl, uint16_t *buffer, 
      uint16_t numSamples, uint16_t jiffies);

  /** 
   * Starts sampling the adc channels using the configuration as specified by
   * the last call to <code>configure()</code>.
   *
   * @return SUCCESS means that the conversion was started successfully and an
   * event dataReady() will be signalled. Otherwise no event will be signalled.
   */ 
  async command error_t getData();
  
  /** 
   * Conversion results are ready. Results are stored in the buffer in the
   * order the channels where specified in the <code>configure()</code>
   * command, i.e. every (numMemctl+1)-th entry maps to the same channel. 
   * 
   * @param buffer Conversion results (lower 12 bit are valid, respectively).
   * @param numSamples Number of results stored in <code>buffer</code> 
   */    
  async event void dataReady(uint16_t *buffer, uint16_t numSamples); 

}


--- NEW FILE: Msp430Adc12Overflow.nc ---
/* 
 * Copyright (c) 2006, Technische Universitaet Berlin
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 * - Neither the name of the Technische Universitaet Berlin nor the names
 *   of its contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * - Revision -------------------------------------------------------------
 * $Revision: 1.1.2.1 $
 * $Date: 2006/11/20 14:47:10 $
 * @author: Jan Hauer <hauer at tkn.tu-berlin.de>
 * ========================================================================
 */

/** 
 * Signals an ADC12MEMx overflow or conversion time overflow condition to the
 * client.
 *
 * @author Jan Hauer 
 */

#include "Msp430Adc12.h" 
interface Msp430Adc12Overflow 
{   
  /** 
   * An ADC12MEMx overflow condition has occured.
   */ 
  async event void memOverflow();

  /** 
   * A conversion time overflow condition has occured.
   */ 
  async event void conversionTimeOverflow();
}


Index: HplAdc12.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12/HplAdc12.nc,v
retrieving revision 1.1.2.6
retrieving revision 1.1.2.7
diff -C2 -d -r1.1.2.6 -r1.1.2.7
*** HplAdc12.nc	7 Nov 2006 23:15:03 -0000	1.1.2.6
--- HplAdc12.nc	20 Nov 2006 14:47:10 -0000	1.1.2.7
***************
*** 107,120 ****
  
    /** 
-    * Signals an ADC12MEMx overflow.
-    */ 
-   async event void memOverflow();
- 
-   /** 
-    * Signals a Conversion time overflow.
-    */ 
-   async event void conversionTimeOverflow();
- 
-   /** 
     * Signals a conversion result. 
     * @param iv ADC12 interrupt vector value 0x6, 0x8, ... , 0x24
--- 107,110 ----
***************
*** 138,141 ****
--- 128,136 ----
    async command void startConversion();
  
+   /**
+    * Enables conversion (sets the ENC bit).
+    */
+   async command void enableConversion();
+ 
  }
  

Index: HplAdc12P.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12/HplAdc12P.nc,v
retrieving revision 1.1.2.4
retrieving revision 1.1.2.5
diff -C2 -d -r1.1.2.4 -r1.1.2.5
*** HplAdc12P.nc	7 Nov 2006 23:15:03 -0000	1.1.2.4
--- HplAdc12P.nc	20 Nov 2006 14:47:10 -0000	1.1.2.5
***************
*** 114,127 ****
    }
    
    async command bool HplAdc12.isBusy(){ return ADC12CTL1 & ADC12BUSY; }
  
    TOSH_SIGNAL(ADC_VECTOR) {
!     uint16_t iv = ADC12IV;
!     switch(iv)
!     {
!       case  2: signal HplAdc12.memOverflow(); return;
!       case  4: signal HplAdc12.conversionTimeOverflow(); return;
!     }
!     signal HplAdc12.conversionDone(iv);
    }
  }
--- 114,125 ----
    }
    
+   async command void HplAdc12.enableConversion(){ 
+     ADC12CTL0 |= ENC; 
+   }
+     
    async command bool HplAdc12.isBusy(){ return ADC12CTL1 & ADC12BUSY; }
  
    TOSH_SIGNAL(ADC_VECTOR) {
!     signal HplAdc12.conversionDone(ADC12IV);
    }
  }

Index: Msp430Adc12ClientC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12/Msp430Adc12ClientC.nc,v
retrieving revision 1.1.2.7
retrieving revision 1.1.2.8
diff -C2 -d -r1.1.2.7 -r1.1.2.8
*** Msp430Adc12ClientC.nc	7 Nov 2006 23:15:03 -0000	1.1.2.7
--- Msp430Adc12ClientC.nc	20 Nov 2006 14:47:10 -0000	1.1.2.8
***************
*** 48,51 ****
--- 48,53 ----
      interface Resource;
      interface Msp430Adc12SingleChannel;
+     interface Msp430Adc12MultiChannel;
+     interface Msp430Adc12Overflow;
    }
  } implementation {
***************
*** 57,59 ****
--- 59,63 ----
    Resource = Msp430Adc12P.Resource[ID];
    Msp430Adc12SingleChannel = Msp430Adc12P.SingleChannel[ID];
+   Msp430Adc12MultiChannel = Msp430Adc12P.MultiChannel[ID];
+   Msp430Adc12Overflow = Msp430Adc12P.Overflow[ID];
  }

Index: Msp430Adc12.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12/Msp430Adc12.h,v
retrieving revision 1.1.2.8
retrieving revision 1.1.2.9
diff -C2 -d -r1.1.2.8 -r1.1.2.9
*** Msp430Adc12.h	7 Nov 2006 23:15:03 -0000	1.1.2.8
--- Msp430Adc12.h	20 Nov 2006 14:47:10 -0000	1.1.2.9
***************
*** 41,128 ****
  #define REF_VOLT_AUTO_CONFIGURE
  #define CHECK_ARGS
- 
- /*
-  * The msp430adc12_channel_config_t includes all relevant flags to configure
-  * the ADC12 for single channel conversions. They are contained in the following
-  * MSP430 registers: ADC12CTL0, ADC12CTL1, ADC12MCTLx and TACTL of TimerA (if
-  * applicable) and named according to section "17.3 ADC12 Registers" of the
-  * "MSP430x1xx Family User's Guide".
-  * 
-  *                   **********************************
-  *                    
-  * .inch: ADC12 input channel (ADC12MCTLx register). An (external) input
-  * channel maps to one of msp430's A0-A7 pins (see device specific data sheet).
-  *
-  * .sref: reference voltage (ADC12MCTLx register). If REFERENCE_VREFplus_AVss
-  * or REFERENCE_VREFplus_VREFnegterm is chosen AND the client wires to the
-  * Msp430Adc12ClientAutoRVGC or Msp430Adc12ClientAutoDMA_RVGC component then
-  * the reference voltage generator has automatically been enabled to the
-  * voltage level defined by the "ref2_5v" flag (see below) when the
-  * Resource.granted() event is signalled to the client. Otherwise this flag is
-  * ignored.
-  * 
-  * .ref2_5v: Reference generator voltage level (ADC12CTL0 register). See "sref"
-  * flag.
-  * 
-  * .adc12ssel: ADC12 clock source select for the sample-hold-time (ADC12CTL1
-  * register). In combination the "adc12ssel", "adc12div" and "sht" define the
-  * sample-hold-time: "adc12ssel" defines the clock source, "adc12div" defines
-  * the ADC12 clock divider and "sht" define the time expressed in jiffies.
-  * (the sample-hold-time depends on the resistence of the attached sensor, and
-  * is calculated using to the formula in section 17.2.4 of the user guide)
-  *
-  * .adc12div: ADC12 clock divider (ADC12CTL1 register). See "adc12ssel".
-  *
-  * .sht: Sample-and-hold time (ADC12CTL1 register). See "adc12ssel".
-  * 
-  * .sampcon_ssel: Clock source for the sampling period (TASSEL for TimerA).
-  * When an ADC client specifies a non-zero "jiffies" parameter (passed in the
-  * relevant Msp430Adc12SingleChannel interface commands), the ADC
-  * implementation will automatically configure TimerA to be sourced from
-  * "sampcon_ssel" with an input divider of "sampcon_id". During the sampling
-  * process TimerA will then be used to trigger a conversion every "jiffies"
-  * clock ticks.
-  * 
-  * .sampcon_id: Input divider for "sampcon_ssel"  (IDx in TACTL register,
-  * TimerA). See "sampcon_ssel".
-  *
-  * 
-  *                   **********************************
-  *                    
-  * EXAMPLE: Assuming that SMCLK runs at 1 MHz the following code snippet
-  * performs 2000 ADC conversions on channel A2 with a sampling period of 4000 Hz.
-  * The sampling period is defined by the combination of SAMPCON_SOURCE_SMCLK,
-  * SAMPCON_CLOCK_DIV_1 and a "jiffies" parameter of (1000000 / 4000) = 250. 
-  
-    #define NUM_SAMPLES 2000
-    uint16_t buffer[NUM_SAMPLES];
-    
-    msp430adc12_channel_config_t config = {
-     INPUT_CHANNEL_A2, REFERENCE_VREFplus_AVss, REFVOLT_LEVEL_NONE,
-     SHT_SOURCE_SMCLK, SHT_CLOCK_DIV_1, SAMPLE_HOLD_64_CYCLES,
-     SAMPCON_SOURCE_SMCLK, SAMPCON_CLOCK_DIV_1 
-    };
-   
-   event void Boot.booted()
-   {
-     call Resource.request();
-   }
-   
-   event void Resource.granted()
-   {
-     error_t result;
-     result = call SingleChannel.configureMultiple(&config, buffer, BUFFER_SIZE, 250);
-     if (result == SUCCESS)
-       call SingleChannel.getData();
-   }
- 
-   async event uint16_t* SingleChannel.multipleDataReady(uint16_t *buf, uint16_t length)
-   {
-     // buffer contains conversion results
-   }
-  */
- 
   
  typedef struct { 
    unsigned int inch: 4;            // input channel 
    unsigned int sref: 3;            // reference voltage 
--- 41,47 ----
  #define REF_VOLT_AUTO_CONFIGURE
  #define CHECK_ARGS
   
  typedef struct { 
+   // see README.txt for a more detailed explanation
    unsigned int inch: 4;            // input channel 
    unsigned int sref: 3;            // reference voltage 
***************
*** 136,139 ****
--- 55,67 ----
  } msp430adc12_channel_config_t;
  
+ typedef struct 
+ {
+   // see README.txt for a more detailed explanation
+   volatile unsigned
+   inch: 4,                                     // input channel
+   sref: 3,                                     // reference voltage
+   eos: 1;                                      // end of sequence flag
+ } __attribute__ ((packed)) adc12memctl_t;
+ 
  enum inch_enum
  {  
***************
*** 233,246 ****
  #define ADCC_READ_STREAM_SERVICE "AdcC.ReadStream.Client"
  
- typedef struct 
- {
-   volatile unsigned
-   inch: 4,                                     // input channel
-   sref: 3,                                     // reference voltage
-   eos: 1;                                      // end of sequence flag
- } __attribute__ ((packed)) adc12memctl_t;
- 
  /* Test for GCC bug (bitfield access) - only version 3.2.3 is known to be stable */
! // check: is this relevant anymore ?
  #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__)
  #if GCC_VERSION == 332
--- 161,166 ----
  #define ADCC_READ_STREAM_SERVICE "AdcC.ReadStream.Client"
  
  /* Test for GCC bug (bitfield access) - only version 3.2.3 is known to be stable */
! // TODO: check whether this is still relevant...
  #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__)
  #if GCC_VERSION == 332

Index: Msp430Adc12ImplP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12/Msp430Adc12ImplP.nc,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -C2 -d -r1.1.2.2 -r1.1.2.3
*** Msp430Adc12ImplP.nc	7 Nov 2006 23:15:03 -0000	1.1.2.2
--- Msp430Adc12ImplP.nc	20 Nov 2006 14:47:10 -0000	1.1.2.3
***************
*** 40,43 ****
--- 40,45 ----
      interface Init;
      interface Msp430Adc12SingleChannel as SingleChannel[uint8_t id];
+     interface Msp430Adc12MultiChannel as MultiChannel[uint8_t id];
+     interface Msp430Adc12Overflow as Overflow[uint8_t id];
      interface AsyncStdControl as DMAExtension[uint8_t id];
  	}
***************
*** 67,81 ****
      MULTIPLE_DATA = 4,
      MULTIPLE_DATA_REPEAT = 8,
!     CONVERSION_MODE_MASK = 0x0F,
  
!     ADC_BUSY = 16,                /* request pending */
!     USE_TIMERA = 32,              /* TimerA used for SAMPCON signal */
    };
  
    uint8_t state;                  /* see enum above */
    
!   uint16_t *resultBuffer;  /* conversion results */
    uint16_t resultBufferLength;    /* length of buffer */
    uint16_t resultBufferIndex;     /* offset into buffer */
    uint8_t clientID;               /* ID of client that called getData() */
  
--- 69,86 ----
      MULTIPLE_DATA = 4,
      MULTIPLE_DATA_REPEAT = 8,
!     MULTI_CHANNEL = 16,
!     CONVERSION_MODE_MASK = 0x1F,
  
!     ADC_BUSY = 32,                /* request pending */
!     USE_TIMERA = 64,              /* TimerA used for SAMPCON signal */
!     ADC_OVERFLOW = 128,
    };
  
    uint8_t state;                  /* see enum above */
    
!   uint16_t *resultBuffer;         /* conversion results */
    uint16_t resultBufferLength;    /* length of buffer */
    uint16_t resultBufferIndex;     /* offset into buffer */
+   uint8_t numChannels;            /* number of channels (multi-channel conversion) */
    uint8_t clientID;               /* ID of client that called getData() */
  
***************
*** 379,388 ****
    }
  
    void stopConversion()
    {
!     adc12memctl_t memctl = call HplAdc12.getMCtl(0);
      if (state & USE_TIMERA)
        call TimerA.setMode(MSP430TIMER_STOP_MODE);
!     resetAdcPin( memctl.inch );
      call HplAdc12.stopConversion();
      call HplAdc12.resetIFGs(); 
--- 384,483 ----
    }
  
+   async command error_t MultiChannel.configure[uint8_t id](
+       const msp430adc12_channel_config_t *config,
+       adc12memctl_t *memctl, uint8_t numMemctl, uint16_t *buf, 
+       uint16_t numSamples, uint16_t jiffies)
+   {
+     error_t result = ERESERVE;
+ #ifdef CHECK_ARGS
+     if (!config || !memctl || !numMemctl || numMemctl > 15 || !numSamples || 
+         !buf || jiffies == 1 || jiffies == 2 || numSamples % (numMemctl+1) != 0)
+       return EINVAL;
+ #endif
+     atomic {
+       if (state & ADC_BUSY)
+         return EBUSY;
+       if (call ADCArbiterInfo.userId() == id){
+         adc12ctl1_t ctl1 = {
+           adc12busy: 0,
+           // use seq. of channels (rep.seq. channel does not work with TimerA + MSC ?)
+           conseq: (jiffies == 0) ? 3 : 1, 
+           adc12ssel: config->adc12ssel,
+           adc12div: config->adc12div,
+           issh: 0,
+           shp: 1,
+           shs: (jiffies == 0) ? 0 : 1,
+           cstartadd: 0
+         };
+         adc12memctl_t firstMemctl = {
+           inch: config->inch,
+           sref: config->sref,
+           eos: 0
+         };     
+         uint16_t i, mask = 1;
+         adc12ctl0_t ctl0 = call HplAdc12.getCtl0();
+         ctl0.msc = 1;
+         ctl0.sht0 = config->sht;
+         ctl0.sht1 = config->sht;
+ 
+         state = MULTI_CHANNEL;
+         resultBuffer = buf;
+         resultBufferLength = numSamples;
+         resultBufferIndex = 0;
+         numChannels = numMemctl+1;
+         call HplAdc12.setCtl0(ctl0);
+         call HplAdc12.setCtl1(ctl1);
+         call HplAdc12.setMCtl(0, firstMemctl);
+         for (i=0; i<(numMemctl-1) && i < 14; i++){
+           memctl[i].eos = 0;
+           call HplAdc12.setMCtl(i+1, memctl[i]);
+         }
+         memctl[i].eos = 1;
+         call HplAdc12.setMCtl(i+1, memctl[i]);
+         call HplAdc12.setIEFlags(mask << (i+1));        
+         
+         if (jiffies){
+           state |= USE_TIMERA;
+           prepareTimerA(jiffies, config->sampcon_ssel, config->sampcon_id);
+         }
+         result = SUCCESS;
+       }      
+     }
+     return result;
+   }
+ 
+   async command error_t MultiChannel.getData[uint8_t id]()
+   {
+     uint8_t i;
+     atomic {
+       if (call ADCArbiterInfo.userId() == id){
+         if (!resultBuffer)
+           return EINVAL;
+         if (state & ADC_BUSY)
+           return EBUSY;
+         state |= ADC_BUSY;
+         clientID = id;
+         for (i=0; i<numChannels; i++)
+           configureAdcPin((call HplAdc12.getMCtl(i)).inch);
+         call HplAdc12.startConversion();
+         if (state & USE_TIMERA)
+           startTimerA(); 
+         return SUCCESS;
+       }
+     }
+     return FAIL;
+   }
+   
    void stopConversion()
    {
!     uint8_t i;
      if (state & USE_TIMERA)
        call TimerA.setMode(MSP430TIMER_STOP_MODE);
!     resetAdcPin( (call HplAdc12.getMCtl(0)).inch );
!     if (state & MULTI_CHANNEL){
!       ADC12IV = 0; // clear any pending overflow
!       for (i=1; i<numChannels; i++)
!         resetAdcPin( (call HplAdc12.getMCtl(i)).inch );
!     }
      call HplAdc12.stopConversion();
      call HplAdc12.resetIFGs(); 
***************
*** 419,422 ****
--- 514,524 ----
    async event void HplAdc12.conversionDone(uint16_t iv)
    {
+     if (iv <= 4){ // check for overflow
+       if (iv == 2)
+         signal Overflow.memOverflow[clientID]();
+       else
+         signal Overflow.conversionTimeOverflow[clientID]();
+     }
+ #ifndef MSP430ADC12_ONLY_DMA
      switch (state & CONVERSION_MODE_MASK) 
      { 
***************
*** 434,437 ****
--- 536,554 ----
            break;
          }
+       case MULTI_CHANNEL:
+         {
+           uint16_t i = 0;
+           do {
+             *resultBuffer++ = call HplAdc12.getMem(i);
+           } while (++i < numChannels);
+           resultBufferIndex += numChannels;
+           if (resultBufferLength == resultBufferIndex){
+             stopConversion();
+             resultBuffer -= resultBufferLength;
+             resultBufferIndex = 0;
+             signal MultiChannel.dataReady[clientID](resultBuffer, resultBufferLength);
+           } else call HplAdc12.enableConversion();
+         }
+         break;
        case MULTIPLE_DATA:
          {
***************
*** 475,478 ****
--- 592,596 ----
          }
        } // switch
+ #endif
    }
  
***************
*** 487,493 ****
      return 0;
    }
    
!   async event void HplAdc12.memOverflow(){}
!   async event void HplAdc12.conversionTimeOverflow(){}
  
  }
--- 605,613 ----
      return 0;
    }
+    
+   default async event void MultiChannel.dataReady[uint8_t id](uint16_t *buffer, uint16_t numSamples) {};
    
!   default async event void Overflow.memOverflow[uint8_t id](){}
!   default async event void Overflow.conversionTimeOverflow[uint8_t id](){}
  
  }

Index: Msp430Adc12P.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12/Msp430Adc12P.nc,v
retrieving revision 1.1.2.11
retrieving revision 1.1.2.12
diff -C2 -d -r1.1.2.11 -r1.1.2.12
*** Msp430Adc12P.nc	7 Nov 2006 23:15:03 -0000	1.1.2.11
--- Msp430Adc12P.nc	20 Nov 2006 14:47:10 -0000	1.1.2.12
***************
*** 40,43 ****
--- 40,45 ----
      interface Resource[uint8_t id]; 
      interface Msp430Adc12SingleChannel as SingleChannel[uint8_t id]; 
+     interface Msp430Adc12MultiChannel as MultiChannel[uint8_t id]; 
+     interface Msp430Adc12Overflow as Overflow[uint8_t id]; 
      interface AsyncStdControl as DMAExtension[uint8_t id];
    }
***************
*** 48,51 ****
--- 50,55 ----
    Resource = Arbiter;
    SingleChannel = Msp430Adc12ImplP.SingleChannel;
+   MultiChannel= Msp430Adc12ImplP.MultiChannel;
+   Overflow = Msp430Adc12ImplP.Overflow;
    DMAExtension = Msp430Adc12ImplP.DMAExtension;
    

Index: Msp430Adc12SingleChannel.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12/Msp430Adc12SingleChannel.nc,v
retrieving revision 1.1.2.8
retrieving revision 1.1.2.9
diff -C2 -d -r1.1.2.8 -r1.1.2.9
*** Msp430Adc12SingleChannel.nc	7 Nov 2006 23:15:03 -0000	1.1.2.8
--- Msp430Adc12SingleChannel.nc	20 Nov 2006 14:47:10 -0000	1.1.2.9
***************
*** 37,44 ****
   * 
   * This interface provides access to the ADC12 on the level of HAL. It can be
!  * used to sample an adc channel once or repeatedly (one event is signalled per
!  * conversion result) or perform multiple conversions for a channel once or
!  * repeatedly (one event is signalled per multiple conversion results). It
!  * cannot be used to sample different adc channels with a single command.
   * Sampling a channel requires calling a sequence of two commands, configureX()
   * and getData(), where X is either 'Single', 'SingleRepeat', 'Multiple' or
--- 37,45 ----
   * 
   * This interface provides access to the ADC12 on the level of HAL. It can be
!  * used to sample a single adc channel once or repeatedly (one event is
!  * signalled per conversion result) or perform multiple conversions for a
!  * single channel once or repeatedly (one event is signalled per multiple
!  * conversion results). It cannot be used to sample different adc channels with
!  * a single command (use the Msp430Adc12MultiChannel interface instead).
   * Sampling a channel requires calling a sequence of two commands, configureX()
   * and getData(), where X is either 'Single', 'SingleRepeat', 'Multiple' or
***************
*** 47,64 ****
   * configuration, i.e. there are four possible sequences:
   * 
!  *    configureSingle()          -> [ getData() -> singleDataReady() ]*
!  * or configureSingleRepeat()    -> [ getData() -> singleDataReady() ]*
!  * or configureMultiple()        -> [ getData() -> multipleDataReady() ]*
!  * or configureMultipleRepeat()  -> getData() -> multipleDataReady()
   *
!  * where configureX() and getData() are commands called by the client and
   * singleDataReady() and multipleDataReady() are events signalled back to the
!  * client by the adc subsystem. Note that a configuration is valid until
!  * the client reconfigures or releases the ADC (using the Resource 
!  * interface), except for configureMultipleRepeat(), which is only valid 
!  * for a single call to getData(). This means that after a successful 
!  * configuration with, for example, configureSingle() the client may call 
!  * getData() more than once without reconfiguring the ADC in between 
!  * (if the client has not released the ADC via the Resource interface).
   *
   * @author Jan Hauer 
--- 48,65 ----
   * configuration, i.e. there are four possible sequences:
   * 
!  * <p> configureSingle()          -> ( getData() -> singleDataReady() )*
!  * <p> configureSingleRepeat()    -> ( getData() -> singleDataReady() )*
!  * <p> configureMultiple()        -> ( getData() -> multipleDataReady() )*
!  * <p> configureMultipleRepeat()  -> getData() -> multipleDataReady()
   *
!  * <p> where configureX() and getData() are commands called by the client and
   * singleDataReady() and multipleDataReady() are events signalled back to the
!  * client by the adc subsystem. Note that a configuration is valid until the
!  * client reconfigures or releases the ADC (using the Resource interface),
!  * except for configureMultipleRepeat(), which is only valid for a single call
!  * to getData(). This means that after a successful configuration with, for
!  * example, configureSingle() the client may call getData() more than once
!  * without reconfiguring the ADC in between (if the client has not released the
!  * ADC via the Resource interface).
   *
   * @author Jan Hauer 
***************
*** 194,200 ****
     * <code>configureSingleRepeat()</code> command then the return value tells
     * whether another conversion should be performed (<code>SUCCESS()</code>) or
!    * not (<code>FAIL</code>). If <code>SUCCESS()</code> is returned then the
!    * sampling period will be as specified in the
!    * <code>configureSingleRepeat()</code> command.
     * 
     * @param data Conversion result (lower 12 bit).  
--- 195,199 ----
     * <code>configureSingleRepeat()</code> command then the return value tells
     * whether another conversion should be performed (<code>SUCCESS()</code>) or
!    * not (<code>FAIL</code>).
     * 
     * @param data Conversion result (lower 12 bit).  
***************
*** 223,227 ****
     * A null pointer stops a repeated conversion mode. Any non-zero value is
     * interpreted as the next buffer, which must have at least
!    * <code>numSamples</code> entries. The return value us ignored if the ADC
     * was configured with <code>configureMultiple()</code>.
     */    
--- 222,226 ----
     * A null pointer stops a repeated conversion mode. Any non-zero value is
     * interpreted as the next buffer, which must have at least
!    * <code>numSamples</code> entries. The return value is ignored if the ADC
     * was configured with <code>configureMultiple()</code>.
     */    

Index: Msp430RefVoltGeneratorP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12/Msp430RefVoltGeneratorP.nc,v
retrieving revision 1.1.2.4
retrieving revision 1.1.2.5
diff -C2 -d -r1.1.2.4 -r1.1.2.5
*** Msp430RefVoltGeneratorP.nc	7 Nov 2006 23:15:04 -0000	1.1.2.4
--- Msp430RefVoltGeneratorP.nc	20 Nov 2006 14:47:10 -0000	1.1.2.5
***************
*** 272,277 ****
    }
  
-   async event void HplAdc12.memOverflow(){}
-   async event void HplAdc12.conversionTimeOverflow(){}
    async event void HplAdc12.conversionDone(uint16_t iv){}
  
--- 272,275 ----

Index: README.txt
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12/README.txt,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -C2 -d -r1.1.2.2 -r1.1.2.3
*** README.txt	7 Nov 2006 23:15:04 -0000	1.1.2.2
--- README.txt	20 Nov 2006 14:47:10 -0000	1.1.2.3
***************
*** 1,5 ****
! The implementation of the 12-bit ADC stack on the MSP430 is in compliance with
! TEP 101 (tinyos-2.x/doc/txt/tep101.txt) and provides virtualized access to the
! ADC12 by seven different components: AdcReadClientC, AdcReadNowClientC,
  AdcReadStreamClientC, Msp430Adc12ClientC, Msp430Adc12ClientAutoDMAC,
  Msp430Adc12ClientAutoRVGC and Msp430Adc12ClientAutoDMA_RVGC. A client
--- 1,5 ----
! The implementation of the 12-bit ADC stack on the MSP430 is in compliance
! with TEP 101 (tinyos-2.x/doc/txt/tep101.txt) and provides virtualized access
! to the ADC12 by seven different components: AdcReadClientC, AdcReadNowClientC,
  AdcReadStreamClientC, Msp430Adc12ClientC, Msp430Adc12ClientAutoDMAC,
  Msp430Adc12ClientAutoRVGC and Msp430Adc12ClientAutoDMA_RVGC. A client
***************
*** 9,12 ****
--- 9,16 ----
  
  
+ 1. HIL
+ ====================================================================
+ 
+ 
  A platform-independent application (an application like 'Oscilloscope' that is
  supposed to run on, for example, the 'telosb' and 'micaz' platform at the same
***************
*** 25,28 ****
--- 29,35 ----
  
  
+ 2. HAL
+ ====================================================================
+ 
  An application that is written for an MSP430-based platform like 'eyesIFX' or
  'telosb' can access the ADC12 in a more efficient way to, for example, do
***************
*** 53,56 ****
--- 60,67 ----
    * Msp430Adc12ClientAutoDMA_RVGC: DMA and automatic reference voltage
  
+ 
+ PINs
+ --------------------------------------------------------------------
+ 
  During a conversion the respective ADC port pin (ports 6.0 - 6.7) must be
  configured such that the peripheral module function is selected and the port
***************
*** 62,65 ****
--- 73,157 ----
  "P6PIN_AUTO_CONFIGURE" macro in Msp430Adc12.h.
  
+ 
+ Configuration for single channel conversions
+ --------------------------------------------------------------------
+ 
+ The msp430adc12_channel_config_t struct holds all information needed to
+ configure the ADC12 for single channel conversions. The flags come from the
+ following MSP430 registers: ADC12CTL0, ADC12CTL1, ADC12MCTLx and TACTL and are
+ named according to the "MSP430x1xx Family User's Guide". Their meaning is as
+ follows:
+ 
+   .inch: ADC12 input channel (ADC12MCTLx register). An (external) input
+   channel maps to one of msp430's A0-A7 pins (see device specific data sheet).
+ 
+   .sref: reference voltage (ADC12MCTLx register). If REFERENCE_VREFplus_AVss
+   or REFERENCE_VREFplus_VREFnegterm is chosen AND the client wires to the
+   Msp430Adc12ClientAutoRVGC or Msp430Adc12ClientAutoDMA_RVGC component then
+   the reference voltage generator has automatically been enabled to the
+   voltage level defined by the "ref2_5v" flag (see below) when the
+   Resource.granted() event is signalled to the client. Otherwise this flag is
+   ignored.
+   
+   .ref2_5v: Reference generator voltage level (ADC12CTL0 register). See
+   "sref".
+   
+   .adc12ssel: ADC12 clock source select for the sample-hold-time (ADC12CTL1
+   register). In combination the "adc12ssel", "adc12div" and "sht" define the
+   sample-hold-time: "adc12ssel" defines the clock source, "adc12div" defines
+   the ADC12 clock divider and "sht" define the time expressed in jiffies.
+   (the sample-hold-time depends on the resistence of the attached sensor, and
+   is calculated using to the formula in section 17.2.4 of the user guide)
+   
+   .adc12div: ADC12 clock divider (ADC12CTL1 register). See "adc12ssel".
+   
+   .sht: Sample-and-hold time (ADC12CTL1 register). See "adc12ssel".
+   
+   .sampcon_ssel: Clock source for the sampling period (TASSEL for TimerA).
+   When an ADC client specifies a non-zero "jiffies" parameter (using the
+   Msp430Adc12SingleChannel.configureX commands), the ADC
+   implementation will automatically configure TimerA to be sourced from
+   "sampcon_ssel" with an input divider of "sampcon_id". During the sampling
+   process TimerA will be used to trigger a single
+   (Msp430Adc12SingleChannel interface) or a sequence of (Msp430Adc12MultiChannel 
+   interface) conversions every "jiffies" clock ticks.
+   
+   .sampcon_id: Input divider for "sampcon_ssel"  (IDx in TACTL register,
+   TimerA). See "sampcon_ssel".
+ 
+ 
+ Example: Assuming that SMCLK runs at 1 MHz the following code snippet
+ performs 2000 ADC conversions on channel A2 with a sampling period of 4000 Hz.
+ The sampling period is defined by the combination of SAMPCON_SOURCE_SMCLK,
+ SAMPCON_CLOCK_DIV_1 and a "jiffies" parameter of (1000000 / 4000) = 250. 
+ 
+  
+    #define NUM_SAMPLES 2000
+    uint16_t buffer[NUM_SAMPLES];
+    
+    const msp430adc12_channel_config_t config = {
+     INPUT_CHANNEL_A2, REFERENCE_VREFplus_AVss, REFVOLT_LEVEL_NONE,
+     SHT_SOURCE_SMCLK, SHT_CLOCK_DIV_1, SAMPLE_HOLD_64_CYCLES,
+     SAMPCON_SOURCE_SMCLK, SAMPCON_CLOCK_DIV_1 
+    };
+   
+   event void Boot.booted()
+   {
+     call Resource.request();
+   }
+   
+   event void Resource.granted()
+   {
+     error_t result;
+     result = call SingleChannel.configureMultiple(&config, buffer, BUFFER_SIZE, 250);
+     if (result == SUCCESS)
+       call SingleChannel.getData();
+   }
+ 
+   async event uint16_t* SingleChannel.multipleDataReady(uint16_t *buf, uint16_t length)
+   {
+     // buffer contains conversion results
+   }
+ 
  -----
  



More information about the Tinyos-2-commits mailing list