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