Contiki 2.5
adc.h
Go to the documentation of this file.
1 /** @file /hal/micro/adc.h
2  * @brief Header for A/D converter.
3  *
4  * <!--(C) COPYRIGHT 2010 STMicroelectronics. All rights reserved. -->
5  */
6 /** @addtogroup adc
7  * Sample A/D converter driver.
8  *
9  * See adc.h for source code.
10  *
11  * @note Stm32w108xx ADC driver support is preliminary and essentailly untested -
12  * please do not attempt to use this ADC driver on this platform.
13  *
14  * @note Except for the Stm32w108xx, the StZNet stack does use these functions.
15  *
16  * To use the ADC system, include this file and ensure that
17  * ::halInternalInitAdc() is called whenever the microcontroller is
18  * started.
19  *
20  * A "user" is a separate thread of execution and usage. That is,
21  * internal St code is one user and clients are a different user.
22  * But a client that is calling the ADC in two different functions
23  * constitutes only one user, as long as the ADC access is not
24  * interleaved.
25  *
26  * @note This code does not allow access to the continuous reading mode of
27  * the ADC, which some clients may require.
28  *
29  * Many functions in this file return an ::StStatus value. See
30  * error-def.h for definitions of all ::StStatus return values.
31  *
32  *@{
33  */
34 #ifndef __ADC_H__
35 #define __ADC_H__
36 
37 #ifdef CORTEXM3_STM32W108
38 
39 // A type for the ADC User enumeration.
40 typedef int8u ADCUser;
41 enum
42 {
43  /** LQI User ID. */
44  ADC_USER_LQI = 0,
45  /** Application User ID */
46  ADC_USER_APP = 1,
47  /** Application User ID */
48  ADC_USER_APP2 = 2
49 };
50 
51 /** @brief Be sure to update ::NUM_ADC_USERS if additional users are added
52  * to the ::ADCUser list.
53  */
54 #define NUM_ADC_USERS 3 // make sure to update if the above is adjusted
55 
56 
57 // A type for the reference enumeration.
58 typedef int8u ADCReferenceType;
59 enum
60 {
61  /** AREF pin reference. */
62  ADC_REF_AREF = 0x00,
63  /** AVCC pin reference. */
64  ADC_REF_AVCC = 0x40,
65  /** Internal reference. */
66  ADC_REF_INT = 0xC0
67 };
68 
69 // A type for the rate enumeration.
70 typedef int8u ADCRateType;
71 enum
72 {
73  /** Rate 32 us, 5 effective bits in ADC_DATA[15:11] */
74  ADC_CONVERSION_TIME_US_32 = 0x0,
75  /** Rate 64 us, 6 effective bits in ADC_DATA[15:10] */
76  ADC_CONVERSION_TIME_US_64 = 0x1,
77  /** Rate 128 us, 7 effective bits in ADC_DATA[15:9] */
78  ADC_CONVERSION_TIME_US_128 = 0x2,
79  /** Rate 256 us, 8 effective bits in ADC_DATA[15:8] */
80  ADC_CONVERSION_TIME_US_256 = 0x3,
81  /** Rate 512 us, 9 effective bits in ADC_DATA[15:7] */
82  ADC_CONVERSION_TIME_US_512 = 0x4,
83  /** Rate 1024 us, 10 effective bits in ADC_DATA[15:6] */
84  ADC_CONVERSION_TIME_US_1024 = 0x5,
85  /** Rate 2048 us, 11 effective bits in ADC_DATA[15:5] */
86  ADC_CONVERSION_TIME_US_2048 = 0x6,
87  /** Rate 4096 us, 12 effective bits in ADC_DATA[15:4] */
88  ADC_CONVERSION_TIME_US_4096 = 0x7,
89 };
90 
91 
92 #if defined (CORTEXM3)
93  /** Channel 0 : ADC0 on PB5 */
94 #define ADC_MUX_ADC0 0x0
95  /** Channel 1 : ADC1 on PB6 */
96 #define ADC_MUX_ADC1 0x1
97  /** Channel 2 : ADC2 on PB7 */
98 #define ADC_MUX_ADC2 0x2
99  /** Channel 3 : ADC3 on PC1 */
100 #define ADC_MUX_ADC3 0x3
101  /** Channel 4 : ADC4 on PA4 */
102 #define ADC_MUX_ADC4 0x4
103  /** Channel 5 : ADC5 on PA5 */
104 #define ADC_MUX_ADC5 0x5
105  /** Channel 8 : VSS (0V) - not for high voltage range */
106 #define ADC_MUX_GND 0x8
107  /** Channel 9 : VREF/2 (0.6V) */
108 #define ADC_MUX_VREF2 0x9
109  /** Channel A : VREF (1.2V)*/
110 #define ADC_MUX_VREF 0xA
111  /** Channel B : Regulator/2 (0.9V) - not for high voltage range */
112 #define ADC_MUX_VREG2 0xB
113 
114 // ADC_SOURCE_<pos>_<neg> selects <pos> as the positive input and <neg> as
115 // the negative input.
116 enum
117 {
118  ADC_SOURCE_ADC0_VREF2 = ((ADC_MUX_ADC0 <<ADC_MUXN_BITS) + ADC_MUX_VREF2),
119  ADC_SOURCE_ADC0_GND = ((ADC_MUX_ADC0 <<ADC_MUXN_BITS) + ADC_MUX_GND),
120 
121  ADC_SOURCE_ADC1_VREF2 = ((ADC_MUX_ADC1 <<ADC_MUXN_BITS) + ADC_MUX_VREF2),
122  ADC_SOURCE_ADC1_GND = ((ADC_MUX_ADC1 <<ADC_MUXN_BITS) + ADC_MUX_GND),
123 
124  ADC_SOURCE_ADC2_VREF2 = ((ADC_MUX_ADC2 <<ADC_MUXN_BITS) + ADC_MUX_VREF2),
125  ADC_SOURCE_ADC2_GND = ((ADC_MUX_ADC2 <<ADC_MUXN_BITS) + ADC_MUX_GND),
126 
127  ADC_SOURCE_ADC3_VREF2 = ((ADC_MUX_ADC3 <<ADC_MUXN_BITS) + ADC_MUX_VREF2),
128  ADC_SOURCE_ADC3_GND = ((ADC_MUX_ADC3 <<ADC_MUXN_BITS) + ADC_MUX_GND),
129 
130  ADC_SOURCE_ADC4_VREF2 = ((ADC_MUX_ADC4 <<ADC_MUXN_BITS) + ADC_MUX_VREF2),
131  ADC_SOURCE_ADC4_GND = ((ADC_MUX_ADC4 <<ADC_MUXN_BITS) + ADC_MUX_GND),
132 
133  ADC_SOURCE_ADC5_VREF2 = ((ADC_MUX_ADC5 <<ADC_MUXN_BITS) + ADC_MUX_VREF2),
134  ADC_SOURCE_ADC5_GND = ((ADC_MUX_ADC5 <<ADC_MUXN_BITS) + ADC_MUX_GND),
135 
136  ADC_SOURCE_ADC1_ADC0 = ((ADC_MUX_ADC1 <<ADC_MUXN_BITS) + ADC_MUX_ADC0),
137  ADC_SOURCE_ADC0_ADC1 = ((ADC_MUX_ADC1 <<ADC_MUXN_BITS) + ADC_MUX_ADC0),
138 
139  ADC_SOURCE_ADC3_ADC2 = ((ADC_MUX_ADC3 <<ADC_MUXN_BITS) + ADC_MUX_ADC2),
140  ADC_SOURCE_ADC2_ADC3 = ((ADC_MUX_ADC3 <<ADC_MUXN_BITS) + ADC_MUX_ADC2),
141 
142  ADC_SOURCE_ADC5_ADC4 = ((ADC_MUX_ADC5 <<ADC_MUXN_BITS) + ADC_MUX_ADC4),
143 
144  ADC_SOURCE_GND_VREF2 = ((ADC_MUX_GND <<ADC_MUXN_BITS) + ADC_MUX_VREF2),
145  ADC_SOURCE_VGND = ((ADC_MUX_GND <<ADC_MUXN_BITS) + ADC_MUX_GND),
146 
147  ADC_SOURCE_VREF_VREF2 = ((ADC_MUX_VREF <<ADC_MUXN_BITS) + ADC_MUX_VREF2),
148  ADC_SOURCE_VREF = ((ADC_MUX_VREF <<ADC_MUXN_BITS) + ADC_MUX_GND),
149 /* Modified the original ADC driver for enabling the ADC extended range mode required for
150  supporting the STLM20 temperature sensor.
151  NOTE:
152  The ADC extended range is inaccurate due to the high voltage mode bug of the general purpose ADC
153  (see STM32W108 errata). As consequence, it is not reccomended to use this ADC driver for getting
154  the temperature values
155 */
156 #ifdef ENABLE_ADC_EXTENDED_RANGE_BROKEN
157  ADC_SOURCE_VREF2_VREF2 = ((ADC_MUX_VREF2 <<ADC_MUXN_BITS) + ADC_MUX_VREF2),
158  ADC_SOURCE_VREF2 = ((ADC_MUX_VREF2 <<ADC_MUXN_BITS) + ADC_MUX_GND),
159 #endif /* ENABLE_ADC_EXTENDED_RANGE_BROKEN */
160 
161  ADC_SOURCE_VREG2_VREF2 = ((ADC_MUX_VREG2 <<ADC_MUXN_BITS) + ADC_MUX_VREF2),
162  ADC_SOURCE_VDD_GND = ((ADC_MUX_VREG2 <<ADC_MUXN_BITS) + ADC_MUX_GND)
163 };
164 
165 /** @brief Macro that returns the ADCChannelType, from a given couple of sources
166  * (positive and negative). To be used with halStartAdcConversion().
167  */
168 #define ADC_SOURCE(P,N) (( P << ADC_MUXN_BITS ) + N)
169 
170 #endif // defined (CORTEXM3)
171 
172 
173 /** @brief A type for the channel enumeration
174  * (such as ::ADC_SOURCE_ADC0_GND)
175  */
176 typedef int8u ADCChannelType;
177 
178 /** @brief Returns the ADC channel from a given GPIO. Its value can can be used
179  * inside the ADC_SOURCE(P,N) macro to retrieve the input pair for
180  * halStartAdcConversion().
181  *
182  * @param io The GPIO pin (it can be specified with the convenience macros
183  * PORTA_PIN(), PORTB_PIN(), PORTC_PIN() )
184  *
185  * @return The ADC_MUX value connected to the given GPIO.
186  */
187 int8u halGetADCChannelFromGPIO(int32u io);
188 
189 
190 /** @brief Initializes and powers-up the ADC.
191  */
192 void halInternalInitAdc(void);
193 
194 /** @brief Starts an ADC conversion for the user specified by \c id.
195  *
196  * @appusage The application must set \c reference to the voltage
197  * reference desired (see the ADC references enum),
198  * set \c channel to the channel number
199  * required (see the ADC channel enum), and set \c rate to reflect the
200  * number of bits of accuracy desired (see the ADC rates enum)
201  *
202  * @param id An ADC user.
203  *
204  * @param reference Voltage reference to use, chosen from enum
205  *
206  * @param channel Microprocessor channel number.
207  *
208  * @param rate rate number (see the ADC rate enum).
209  *
210  * @return One of the following:
211  * - ADC_CONVERSION_DEFERRED if the conversion is still waiting
212  * to start.
213  * - ADC_CONVERSION_BUSY if the conversion is currently taking
214  * place.
215  * - ST_ERR_FATAL if a passed parameter is invalid.
216  */
217 StStatus halStartAdcConversion(ADCUser id,
218  ADCReferenceType reference,
219  ADCChannelType channel,
220  ADCRateType rate);
221 
222 /** @brief Returns the status of a pending conversion
223  * previously started by ::halStartAdcConversion(). If the conversion
224  * is complete, writes the raw register value of the conversion (the unaltered
225  * value taken directly from the ADC's data register) into \c value.
226  *
227  * @param id An ADC user.
228  *
229  * @param value Pointer to an int16u to be loaded with the new value.
230  *
231  * @return One of the following:
232  * - ::ST_ADC_CONVERSION_DONE if the conversion is complete.
233  * - ::ST_ADC_CONVERSION_DEFERRED if the conversion is still waiting
234  * to start.
235  * - ::ST_ADC_CONVERSION_BUSY if the conversion is currently taking
236  * place.
237  * - ::ST_ADC_NO_CONVERSION_PENDING if \c id does not have a pending
238  * conversion.
239  */
240 StStatus halRequestAdcData(ADCUser id, int16u *value);
241 
242 
243 /** @brief Waits for the user's request to complete and then,
244  * if a conversion was done, writes the raw register value of the conversion
245  * (the unaltered value taken directly from the ADC's data register) into
246  * \c value and returns ::ADC_CONVERSION_DONE, or immediately
247  * returns ::ADC_NO_CONVERSION_PENDING.
248  *
249  * @param id An ADC user.
250  *
251  * @param value Pointer to an int16u to be loaded with the new value.
252  *
253  * @return One of the following:
254  * - ::ST_ADC_CONVERSION_DONE if the conversion is complete.
255  * - ::ST_ADC_NO_CONVERSION_PENDING if \c id does not have a pending
256  * conversion.
257  */
258 StStatus halReadAdcBlocking(ADCUser id, int16u *value);
259 
260 
261 /** @brief Calibrates or recalibrates the ADC system.
262  *
263  * @appusage Use this function to (re)calibrate as needed. This function is
264  * intended for the microcontroller, which requires proper calibration to calculate
265  * a human readible value (a value in volts). If the app does not call this
266  * function, the first time (and only the first time) the function
267  * ::halConvertValueToVolts() is called, this function is invoked. To
268  * maintain accurate volt calculations, the application should call this
269  * whenever it expects the temperature of the micro to change.
270  *
271  * @param id An ADC user.
272  *
273  * @return One of the following:
274  * - ::ST_ADC_CONVERSION_DONE if the calibration is complete.
275  * - ::ST_ERR_FATAL if the calibration failed.
276  */
277 StStatus halAdcCalibrate(ADCUser id);
278 
279 
280 /** @brief Convert the raw register value (the unaltered value taken
281  * directly from the ADC's data register) into a signed fixed point value with
282  * units 10^-4 Volts. The returned value will be in the range -12000 to
283  * +12000 (-1.2000 volts to +1.2000 volts).
284  *
285  * @appusage Use this function to get a human useful value.
286  *
287  * @param value An int16u to be converted.
288  *
289  * @return Volts as signed fixed point with units 10^-4 Volts.
290  */
291 int16s halConvertValueToVolts(int16u value);
292 
293 
294 /** @brief Calibrates Vref to be 1.2V +/-10mV.
295  *
296  * @appusage This function must be called from halInternalInitAdc() before
297  * making ADC readings. This function is not intended to be called from any
298  * function other than halInternalInitAdc(). This function ensures that the
299  * master cell voltage and current bias values are calibrated before
300  * calibrating Vref.
301  */
302 void stCalibrateVref(void);
303 
304 #ifdef CORTEXM3
305 void halAdcSetClock(boolean fast);
306 void halAdcSetRange(boolean high);
307 boolean halAdcGetClock(void);
308 boolean halAdcGetRange(void);
309 #endif
310 
311 #endif /* CORTEXM3_STM32W108 */
312 
313 #ifdef CORTEXM3_STM32F103
314 #include "micro/cortexm3/stm32f103ret/adc.h"
315 #endif /* CORTEXM3_STM32F103 */
316 
317 #endif // __ADC_H__
318 
319 /** @} // END addtogroup
320  */
321 
322