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