Contiki 2.6

adc.h

Go to the documentation of this file.
00001 /** @file /hal/micro/adc.h
00002  * @brief Header for A/D converter.
00003  *
00004  * <!--(C) COPYRIGHT 2010 STMicroelectronics. All rights reserved.        -->
00005  */
00006 /** @addtogroup adc
00007  * Sample A/D converter driver.
00008  *
00009  * See adc.h for source code.
00010  *
00011  * @note Stm32w108xx ADC driver support is preliminary and essentailly untested -
00012  * please do not attempt to use this ADC driver on this platform.
00013  *
00014  * @note Except for the Stm32w108xx, the StZNet stack does use these functions.
00015  *
00016  * To use the ADC system, include this file and ensure that
00017  * ::halInternalInitAdc() is called whenever the microcontroller is
00018  * started.  
00019  *
00020  * A "user" is a separate thread of execution and usage.  That is,
00021  * internal St code is one user and clients are a different user.
00022  * But a client that is calling the ADC in two different functions
00023  * constitutes only one user, as long as the ADC access is not
00024  * interleaved.
00025  *
00026  * @note This code does not allow access to the continuous reading mode of
00027  * the ADC, which some clients may require.
00028  *
00029  * Many functions in this file return an ::StStatus value.  See
00030  * error-def.h for definitions of all ::StStatus return values.
00031  *
00032  *@{
00033  */
00034 #ifndef __ADC_H__
00035 #define __ADC_H__
00036 
00037 #ifdef CORTEXM3_STM32W108
00038 
00039 // A type for the ADC User enumeration.
00040 typedef int8u ADCUser;
00041 enum
00042 {
00043   /** LQI User ID. */
00044   ADC_USER_LQI = 0,
00045   /** Application User ID */
00046   ADC_USER_APP = 1,
00047   /** Application User ID */
00048   ADC_USER_APP2 = 2
00049 };
00050 
00051 /** @brief Be sure to update ::NUM_ADC_USERS if additional users are added
00052  * to the ::ADCUser list.
00053  */
00054 #define NUM_ADC_USERS 3 // make sure to update if the above is adjusted
00055 
00056 
00057 // A type for the reference enumeration.
00058 typedef int8u ADCReferenceType;
00059 enum
00060 {
00061   /** AREF pin reference. */
00062   ADC_REF_AREF = 0x00,
00063   /** AVCC pin reference. */
00064   ADC_REF_AVCC = 0x40,
00065   /** Internal reference. */
00066   ADC_REF_INT  = 0xC0
00067 };
00068 
00069 // A type for the rate enumeration.
00070 typedef int8u ADCRateType;
00071 enum
00072 {
00073   /** Rate 32 us, 5 effective bits in ADC_DATA[15:11] */
00074   ADC_CONVERSION_TIME_US_32   = 0x0,
00075   /** Rate 64 us, 6 effective bits in ADC_DATA[15:10] */
00076   ADC_CONVERSION_TIME_US_64   = 0x1,
00077   /** Rate 128 us, 7 effective bits in ADC_DATA[15:9] */
00078   ADC_CONVERSION_TIME_US_128  = 0x2,
00079   /** Rate 256 us, 8 effective bits in ADC_DATA[15:8] */
00080   ADC_CONVERSION_TIME_US_256  = 0x3,
00081   /** Rate 512 us, 9 effective bits in ADC_DATA[15:7] */
00082   ADC_CONVERSION_TIME_US_512  = 0x4,
00083   /** Rate 1024 us, 10 effective bits in ADC_DATA[15:6] */
00084   ADC_CONVERSION_TIME_US_1024 = 0x5,
00085   /** Rate 2048 us, 11 effective bits in ADC_DATA[15:5] */
00086   ADC_CONVERSION_TIME_US_2048 = 0x6,
00087   /** Rate 4096 us, 12 effective bits in ADC_DATA[15:4] */
00088   ADC_CONVERSION_TIME_US_4096 = 0x7,
00089 };
00090 
00091 
00092 #if defined (CORTEXM3)
00093   /** Channel 0 : ADC0 on PB5 */
00094 #define ADC_MUX_ADC0    0x0
00095   /** Channel 1 : ADC1 on PB6 */
00096 #define ADC_MUX_ADC1    0x1
00097   /** Channel 2 : ADC2 on PB7 */
00098 #define ADC_MUX_ADC2    0x2
00099   /** Channel 3 : ADC3 on PC1 */
00100 #define ADC_MUX_ADC3    0x3
00101   /** Channel 4 : ADC4 on PA4 */
00102 #define ADC_MUX_ADC4    0x4
00103   /** Channel 5 : ADC5 on PA5 */
00104 #define ADC_MUX_ADC5    0x5
00105   /** Channel 8 : VSS (0V) - not for high voltage range */
00106 #define ADC_MUX_GND     0x8
00107   /** Channel 9 : VREF/2 (0.6V) */
00108 #define ADC_MUX_VREF2   0x9
00109   /** Channel A : VREF (1.2V)*/
00110 #define ADC_MUX_VREF    0xA
00111   /** Channel B : Regulator/2 (0.9V) - not for high voltage range */
00112 #define ADC_MUX_VREG2   0xB
00113 
00114 // ADC_SOURCE_<pos>_<neg> selects <pos> as the positive input and <neg> as  
00115 // the negative input.
00116 enum
00117 {
00118   ADC_SOURCE_ADC0_VREF2  = ((ADC_MUX_ADC0  <<ADC_MUXN_BITS) + ADC_MUX_VREF2),
00119   ADC_SOURCE_ADC0_GND    = ((ADC_MUX_ADC0  <<ADC_MUXN_BITS) + ADC_MUX_GND),
00120 
00121   ADC_SOURCE_ADC1_VREF2  = ((ADC_MUX_ADC1  <<ADC_MUXN_BITS) + ADC_MUX_VREF2),
00122   ADC_SOURCE_ADC1_GND    = ((ADC_MUX_ADC1  <<ADC_MUXN_BITS) + ADC_MUX_GND),
00123 
00124   ADC_SOURCE_ADC2_VREF2  = ((ADC_MUX_ADC2  <<ADC_MUXN_BITS) + ADC_MUX_VREF2),
00125   ADC_SOURCE_ADC2_GND    = ((ADC_MUX_ADC2  <<ADC_MUXN_BITS) + ADC_MUX_GND),
00126 
00127   ADC_SOURCE_ADC3_VREF2  = ((ADC_MUX_ADC3  <<ADC_MUXN_BITS) + ADC_MUX_VREF2),
00128   ADC_SOURCE_ADC3_GND    = ((ADC_MUX_ADC3  <<ADC_MUXN_BITS) + ADC_MUX_GND),
00129 
00130   ADC_SOURCE_ADC4_VREF2  = ((ADC_MUX_ADC4  <<ADC_MUXN_BITS) + ADC_MUX_VREF2),
00131   ADC_SOURCE_ADC4_GND    = ((ADC_MUX_ADC4  <<ADC_MUXN_BITS) + ADC_MUX_GND),
00132 
00133   ADC_SOURCE_ADC5_VREF2  = ((ADC_MUX_ADC5  <<ADC_MUXN_BITS) + ADC_MUX_VREF2),
00134   ADC_SOURCE_ADC5_GND    = ((ADC_MUX_ADC5  <<ADC_MUXN_BITS) + ADC_MUX_GND),  
00135 
00136   ADC_SOURCE_ADC1_ADC0   = ((ADC_MUX_ADC1  <<ADC_MUXN_BITS) + ADC_MUX_ADC0),
00137   ADC_SOURCE_ADC0_ADC1   = ((ADC_MUX_ADC1  <<ADC_MUXN_BITS) + ADC_MUX_ADC0),
00138 
00139   ADC_SOURCE_ADC3_ADC2   = ((ADC_MUX_ADC3  <<ADC_MUXN_BITS) + ADC_MUX_ADC2),
00140   ADC_SOURCE_ADC2_ADC3   = ((ADC_MUX_ADC3  <<ADC_MUXN_BITS) + ADC_MUX_ADC2),
00141 
00142   ADC_SOURCE_ADC5_ADC4   = ((ADC_MUX_ADC5  <<ADC_MUXN_BITS) + ADC_MUX_ADC4),
00143 
00144   ADC_SOURCE_GND_VREF2   = ((ADC_MUX_GND   <<ADC_MUXN_BITS) + ADC_MUX_VREF2),
00145   ADC_SOURCE_VGND        = ((ADC_MUX_GND   <<ADC_MUXN_BITS) + ADC_MUX_GND),
00146 
00147   ADC_SOURCE_VREF_VREF2  = ((ADC_MUX_VREF  <<ADC_MUXN_BITS) + ADC_MUX_VREF2),
00148   ADC_SOURCE_VREF        = ((ADC_MUX_VREF  <<ADC_MUXN_BITS) + ADC_MUX_GND),
00149 /* Modified the original ADC driver for enabling the ADC extended range mode required for 
00150    supporting the STLM20 temperature sensor.
00151    NOTE: 
00152    The ADC extended range is inaccurate due to the high voltage mode bug of the general purpose ADC 
00153    (see STM32W108 errata). As consequence, it is not reccomended to use this ADC driver for getting
00154    the temperature values 
00155 */
00156 #ifdef ENABLE_ADC_EXTENDED_RANGE_BROKEN
00157   ADC_SOURCE_VREF2_VREF2  = ((ADC_MUX_VREF2  <<ADC_MUXN_BITS) + ADC_MUX_VREF2),
00158   ADC_SOURCE_VREF2        = ((ADC_MUX_VREF2  <<ADC_MUXN_BITS) + ADC_MUX_GND),
00159 #endif /* ENABLE_ADC_EXTENDED_RANGE_BROKEN */
00160 
00161   ADC_SOURCE_VREG2_VREF2 = ((ADC_MUX_VREG2 <<ADC_MUXN_BITS) + ADC_MUX_VREF2),
00162   ADC_SOURCE_VDD_GND     = ((ADC_MUX_VREG2 <<ADC_MUXN_BITS) + ADC_MUX_GND)
00163 };
00164 
00165 /** @brief Macro that returns the ADCChannelType, from a given couple of sources
00166  * (positive and negative). To be used with halStartAdcConversion().
00167  */
00168 #define ADC_SOURCE(P,N)   (( P << ADC_MUXN_BITS ) + N)
00169 
00170 #endif // defined (CORTEXM3)
00171 
00172 
00173 /** @brief A type for the channel enumeration 
00174  * (such as ::ADC_SOURCE_ADC0_GND)
00175  */
00176 typedef int8u ADCChannelType;
00177 
00178 /** @brief Returns the ADC channel from a given GPIO. Its value can can be used
00179  * inside the ADC_SOURCE(P,N) macro to retrieve the input pair for
00180  * halStartAdcConversion().
00181  *
00182  * @param io  The GPIO pin (it can be specified with the convenience macros
00183  *            PORTA_PIN(), PORTB_PIN(), PORTC_PIN() )
00184  * 
00185  * @return The ADC_MUX value connected to the given GPIO.
00186  */
00187 int8u halGetADCChannelFromGPIO(int32u io);
00188 
00189 
00190 /** @brief Initializes and powers-up the ADC. 
00191  */
00192 void halInternalInitAdc(void);
00193 
00194 /** @brief Starts an ADC conversion for the user specified by \c id.
00195  *
00196  * @appusage The application must set \c reference to the voltage
00197  * reference desired (see the ADC references enum), 
00198  * set \c channel to the channel number
00199  * required (see the ADC channel enum), and set \c rate to reflect the
00200  * number of bits of accuracy desired (see the ADC rates enum)
00201  *
00202  * @param id        An ADC user.
00203  * 
00204  * @param reference Voltage reference to use, chosen from enum
00205  * 
00206  * @param channel   Microprocessor channel number.  
00207  * 
00208  * @param rate      rate number (see the ADC rate enum).
00209  * 
00210  * @return One of the following: 
00211  * - ADC_CONVERSION_DEFERRED   if the conversion is still waiting 
00212  * to start.
00213  * - ADC_CONVERSION_BUSY       if the conversion is currently taking 
00214  * place.
00215  * - ST_ERR_FATAL                 if a passed parameter is invalid.
00216  */
00217 StStatus halStartAdcConversion(ADCUser id,
00218                                   ADCReferenceType reference,
00219                                   ADCChannelType channel,
00220                                   ADCRateType rate);
00221 
00222 /** @brief Returns the status of a pending conversion
00223  * previously started by ::halStartAdcConversion().  If the conversion
00224  * is complete, writes the raw register value of the conversion (the unaltered
00225  * value taken directly from the ADC's data register) into \c value.
00226  *
00227  * @param id     An ADC user.
00228  *
00229  * @param value  Pointer to an int16u to be loaded with the new value. 
00230  * 
00231  * @return One of the following: 
00232  * - ::ST_ADC_CONVERSION_DONE       if the conversion is complete.
00233  * - ::ST_ADC_CONVERSION_DEFERRED   if the conversion is still waiting 
00234  * to start.
00235  * - ::ST_ADC_CONVERSION_BUSY       if the conversion is currently taking 
00236  * place.
00237  * - ::ST_ADC_NO_CONVERSION_PENDING if \c id does not have a pending 
00238  * conversion.
00239  */
00240 StStatus halRequestAdcData(ADCUser id, int16u *value);
00241 
00242 
00243 /** @brief Waits for the user's request to complete and then,
00244  * if a conversion was done, writes the raw register value of the conversion
00245  * (the unaltered value taken directly from the ADC's data register) into
00246  * \c value and returns ::ADC_CONVERSION_DONE, or immediately
00247  * returns ::ADC_NO_CONVERSION_PENDING.
00248  *
00249  * @param id     An ADC user.
00250  *
00251  * @param value  Pointer to an int16u to be loaded with the new value. 
00252  * 
00253  * @return One of the following: 
00254  * - ::ST_ADC_CONVERSION_DONE        if the conversion is complete.
00255  * - ::ST_ADC_NO_CONVERSION_PENDING  if \c id does not have a pending 
00256  * conversion.
00257  */
00258 StStatus halReadAdcBlocking(ADCUser id, int16u *value);
00259 
00260 
00261 /** @brief Calibrates or recalibrates the ADC system. 
00262  *
00263  * @appusage Use this function to (re)calibrate as needed. This function is
00264  * intended for the microcontroller, which requires proper calibration to calculate
00265  * a human readible value (a value in volts).  If the app does not call this
00266  * function, the first time (and only the first time) the function 
00267  * ::halConvertValueToVolts() is called, this function is invoked.  To
00268  * maintain accurate volt calculations, the application should call this
00269  * whenever it expects the temperature of the micro to change.
00270  *
00271  * @param id  An ADC user.
00272  *
00273  * @return One of the following: 
00274  * - ::ST_ADC_CONVERSION_DONE        if the calibration is complete.
00275  * - ::ST_ERR_FATAL                  if the calibration failed.
00276  */
00277 StStatus halAdcCalibrate(ADCUser id);
00278 
00279 
00280 /** @brief Convert the raw register value (the unaltered value taken
00281  * directly from the ADC's data register) into a signed fixed point value with
00282  * units 10^-4 Volts.  The returned value will be in the range -12000 to
00283  * +12000 (-1.2000 volts to +1.2000 volts).
00284  *
00285  * @appusage Use this function to get a human useful value.
00286  *
00287  * @param value  An int16u to be converted.
00288  * 
00289  * @return Volts as signed fixed point with units 10^-4 Volts. 
00290  */
00291 int16s halConvertValueToVolts(int16u value);
00292 
00293 
00294 /** @brief Calibrates Vref to be 1.2V +/-10mV.
00295  *
00296  *  @appusage This function must be called from halInternalInitAdc() before
00297  *  making ADC readings.  This function is not intended to be called from any
00298  *  function other than halInternalInitAdc().  This function ensures that the
00299  *  master cell voltage and current bias values are calibrated before
00300  *  calibrating Vref.
00301  */
00302 void stCalibrateVref(void);
00303 
00304 #ifdef CORTEXM3
00305 void halAdcSetClock(boolean fast);
00306 void halAdcSetRange(boolean high);
00307 boolean halAdcGetClock(void);
00308 boolean halAdcGetRange(void);
00309 #endif
00310 
00311 #endif /* CORTEXM3_STM32W108 */
00312 
00313 #ifdef CORTEXM3_STM32F103
00314 #include "micro/cortexm3/stm32f103ret/adc.h"
00315 #endif /* CORTEXM3_STM32F103 */
00316 
00317 #endif // __ADC_H__
00318 
00319 /** @} // END addtogroup
00320  */
00321 
00322