• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * FreeRTOS Common IO V0.1.3
3  * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of
6  * this software and associated documentation files (the "Software"), to deal in
7  * the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * http://aws.amazon.com/freertos
23  * http://www.FreeRTOS.org
24  */
25 
26 /**
27  * @file iot_adc.h
28  * @brief File for the HAL APIs of ADC called by application layer.
29  */
30 #ifndef _IOT_ADC_H_
31 #define _IOT_ADC_H_
32 
33 /**
34  * @brief Error code returned by ADC driver
35  */
36 #define IOT_ADC_SUCCESS                   ( 0 )     /*!< ADC operation completed successfully. */
37 #define IOT_ADC_FAILED                    ( 1 )     /*!< ADC operation failed. */
38 #define IOT_ADC_INVALID_VALUE             ( 2 )     /*!< At least one parameter is invalid. */
39 #define IOT_ADC_NOT_OPEN                  ( 3 )     /*!< ADC operation not possible unless ADC instance is opened. */
40 #define IOT_ADC_FUNCTION_NOT_SUPPORTED    ( 4 )     /*!< ADC operation not supported. */
41 #define IOT_ADC_CH_BUSY                   ( 5 )     /*!< ADC channel is busy at current time. */
42 
43 /**
44  * @brief The handle for a ADC peripheral, defined in the source file.
45  * This is an anonymous struct that is vendor/driver specific.
46  */
47 struct IotAdcDescriptor;
48 
49 /**
50  * @brief IotAdcHandle_t is the handle type returned by calling iot_adc_open().
51  *        This is initialized in open and returned to caller.  The caller must pass
52  *        this pointer to the rest of the ADC APIs.
53  */
54 typedef struct IotAdcDescriptor * IotAdcHandle_t;
55 
56 /**
57  * @brief ADC notification callback type
58  *
59  * @param[in] pvUserContext User Context passed when setting the callback.
60  *            This is not used or modified by the driver.  The context is
61  *            provided by the caller when setting the callback, and is
62  *            passed back to the caller in the callback.
63  * @param[out] pusConvertedData pointer to converted ADC sample data.
64  */
65 typedef void ( * IotAdcCallback_t )( uint16_t * pusConvertedData,
66                                      void * pvUserContext );
67 
68 /**
69  * @brief Initializes ADC controller with default configuration.
70  * init ADC controller, enable ADC clock, reset HW FIFO, set default
71  * configuration parameters, etc. Also allocate all required resources
72  * for ADC operation such as software data buffer etc.
73  *
74  * @warning Must be called prior to any other ADC api's so that a valid handle is obtained.
75  * @warning Once opened, the same ADC instance must be closed before calling open again.
76  *
77  * @param[in] lAdc The instance of ADC controller to initialize.
78  *
79  * @return
80  * - handle to the ADC controller on success
81  * - NULL, if
82  *    - invalid instance number
83  *    - open same instance more than once before closing it.
84  */
85 IotAdcHandle_t iot_adc_open( int32_t lAdc );
86 
87 /**
88  * @brief Close ADC controller.
89  * All pending operation will be cancelled, put ADC module in reset state or low
90  * power state if possible. Release all resources claimed during open call
91  *
92  * @param[in] pxAdc handle to ADC controller returned from iot_adc_open() call.
93  *
94  * @return
95  * - IOT_ADC_SUCCESS, on success;
96  * - IOT_I2C_INVALID_VALUE, if pxAdc is NULL
97  * - IOT_ADC_NOT_OPEN, if is not in open state (already closed).
98  */
99 int32_t iot_adc_close( IotAdcHandle_t const pxAdc );
100 
101 /**
102  * @brief Sets channel callback on availability of channel scan data.
103  * On availability of ADC scan data, the application is notified with a
104  * function callback. The callback function and user context for callback
105  * are set using iot_adc_set_callback.
106  *
107  * @note This callback is per AdcChannel for each handle.
108  * @note If input handle or AdcChannel is invalid, or if callback function is NULL,
109  *       this function silently takes no action.
110  *
111  * @param[in] pxAdc The ADC handle returned in the open() call.
112  * @param[in] ucAdcChannel The ADC channel for which the callback is set
113  * @param[in] xAdcCallback The callback function to be called on availability of ADC channel data.
114  * @param[in] pvUserContext The user context to be passed when callback is called.
115  *
116  * <b>Example Callback Function</b>
117  * For asychronous ADC calls, a callback function is used to signal when the async
118  * task is complete.  This example uses a Semaphore to signal the completion.
119  * @code{c}
120  * static void prvAdcChCallback( uint16_t * pusConvertedData,
121  *                               void * pvUserContext )
122  * {
123  *     BaseType_t xHigherPriorityTaskWoken;
124  *     xSemaphoreGiveFromISR( xIotAdcSemaphore, &xHigherPriorityTaskWoken );
125  * }
126  * @endcode
127  */
128 void iot_adc_set_callback( IotAdcHandle_t const pxAdc,
129                            uint8_t ucAdcChannel,
130                            IotAdcCallback_t xAdcCallback,
131                            void * pvUserContext );
132 
133 /**
134  * @brief Start data acquisition for ADC channel until iot_adc_stop API is called.
135  *        Data will be passed back to client using callback function.
136  *        By default each callback will pass back one data sample, however if client has
137  *        used ioctl to pass in data buffer, only when buffer is full will callback
138  *        be triggered.
139  *
140  * @warning iot_adc_set_callback() must be called prior to this in order to get notification
141  *          when ADC scan is complete and data is available.
142  *
143  * @note iot_adc_set_callback() must be called prior to iot_adc_start().
144  *
145  * @param[in] pxAdc. The ADC handle returned in the open() call
146  * @param[in] ucAdcChannel. The ADC channel to start data acquisition
147  *
148  * @return
149  * - IOT_ADC_SUCCESS on success
150  * - IOT_ADC_INVALID_VALUE, on NULL handle or invalid AdcChannel
151  * - IOT_ADC_NOT_OPEN if ADC has not been opened yet.
152  * - IOT_ADC_CH_BUSY if ADC operation has started but is not complete
153  * - IOT_ADC_FAILED if not callback function has been set.
154  * <b>Example Asynchronous read</b>
155  * @code{c}
156  * // ADC Instance to open
157  * int32_t lAdcInstance = 0;
158  *
159  * // Return value of ADC functions
160  * int32_t lRetVal;
161  *
162  * // ADC Channel to read
163  * int32_t lAdcChannel = 0;
164  *
165  * // User/Driver context; if necessary
166  * void xUserContext = NULL;
167  *
168  * // Open the ADC instance and get a handle.
169  * xAdcHandle = iot_adc_open( lAdcInstance );
170  * // assert(lRetVal == IOT_ADC_SUCCESS);
171  *
172  * // set the callback function
173  * iot_adc_set_callback( xAdcHandle, lAdcChannel, prvAdcChCallback, &xUserCntx );
174  *
175  * // start channel data scan on channel
176  * lRetVal = iot_adc_start( xAdcHandle, lAdcChannel );
177  *  // assert( IOT_ADC_SUCCESS == lRetVal );
178  *
179  *  // wait for the ADC operation to complete
180  *  lRetVal = xSemaphoreTake( xIotAdcSemaphore, lIotAdcChWaitTime );
181  *  // assert ( pdTRUE == lRetVal );
182  *
183  *  // stop channel data scan
184  *  lRetVal = iot_adc_stop( xAdcHandle, lAdcChannel );
185  *  assert( IOT_ADC_SUCCESS == lRetVal );
186  *
187  *  // close ADC module
188  *  lRetVal = iot_adc_close( xAdcHandle );
189  *  // assert( IOT_ADC_SUCCESS == lRetVal );
190  * @endcode
191  */
192 int32_t iot_adc_start( IotAdcHandle_t const pxAdc,
193                        uint8_t ucAdcChannel );
194 
195 /**
196  * @brief Stop data acquisition for ADC channel
197  *
198  * @param[in] pxAdc. The ADC handle returned in the open() call
199  * @param[in] ucAdcChannel. The ADC channel to stop data acquisition
200  *
201  * @return
202  * - IOT_ADC_SCUCCESS on success
203  * - IOT_ADC_INVALID_VALUE, on NULL handle or invalid AdcChannel
204  * - IOT_ADC_NOT_OPEN if ADC has been closed without re-opening.
205  */
206 int32_t iot_adc_stop( IotAdcHandle_t const pxAdc,
207                       uint8_t ucAdcChannel );
208 
209 /**
210  * @brief read one ADC data sample. This API will return one ADC sample.
211  *
212  * @param[in] pxAdc. The ADC handle returned in the open() call.
213  * @param[in] ucAdcChannel. The ADC channel to read data from.
214  * @param[out] pusAdcSample. ADC channel read sample value.
215  *
216  * @return
217  * - IOT_ADC_SCUCCESS on success.
218  * - IOT_ADC_INVALID_VALUE, on NULL handle or invalid AdcChannel.
219  * - IOT_ADC_CH_BUSY if ADC operation not complete.
220  * - IOT_ADC_NOT_OPEN if ADC has been closed without re-opening.
221  * <b>Example Synchronous read</b>
222  * @code{c}
223  * // ADC Instance to open
224  * int32_t lAdcInstance = 0;
225  *
226  * // ADC Channel to read
227  * int32_t lAdcChannel = 0;
228  *
229  * // Declare and ADC handle
230  * IotAdcHandle_t xAdcHandle;
231  *
232  * // Return value of ADC functions
233  * int32_t lRetVal;
234  *
235  * // ADC value read
236  * uint16_t usSample;
237  *
238  * // Open the ADC instance and get a handle.
239  * xAdcHandle = iot_adc_open( lAdcInstance );
240  * // assert(lRetVal == IOT_ADC_SUCCESS);
241  *
242  * // Read sample from ADC channel
243  * lRetVal = iot_adc_read_sample( xAdcHandle, lAdcChannel, &usSample);
244  * // assert(lRetVal == IOT_ADC_SUCCESS);
245  *
246  * // Close the ADC instance and get a handle.
247  * lRetVal = iot_adc_close( xAdcHandle );
248  * // assert(lRetVal == IOT_ADC_SUCCESS);
249  * @endcode
250  *
251  */
252 int32_t iot_adc_read_sample( IotAdcHandle_t const pxAdc,
253                              uint8_t ucAdcChannel,
254                              uint16_t * pusAdcSample );
255 
256 /**
257  * @brief data structures for ioctl request
258  */
259 
260 /**
261  * @brief data structure for ioctl SetAdcConfig and GetAdcConfig
262  */
263 typedef struct IotAdcConfig_s
264 {
265     uint32_t ulAdcSampleTime; /*!< Sample time in ADC clock cycles, apply to all channels.
266                                *!< Shortest sample time maximize conversion speed for lower impedance input
267                                *!< Extending sample time improve sample accuracy for higher impedance input.
268                                *!< Sample time is reported as the closest possible value, rounded up, the hardware can support. */
269     uint8_t ucAdcResolution;  /*!< ADC channel resolution, reported as the closest possible value, rounded up.
270                                *!< value = resolution bits; 12 = 12bit, 13 = 13bit, etc */
271 } IotAdcConfig_t;
272 
273 typedef enum
274 {
275     eChStateIdle, /*!< ADC channel is idle. */
276     eChStateBusy, /*!< ADC channel is busy. */
277 } IotAdcChState_t;
278 
279 /**
280  * @brief data structure for ioctl GetChStatus
281  */
282 typedef struct IotAdcChStatus_s
283 {
284     uint8_t ucAdcChannel;        /*!< ADC Channel number */
285     IotAdcChState_t xAdcChState; /*!< ADC Channel State */
286 } IotAdcChStatus_t;
287 
288 /**
289  * @brief data structure for ioctl SetChBuffer
290  *        setting channel data buffer is optional using this ioctl
291  *        if client doesn't pass in data buffer for driver to use, callback is triggered
292  *        for every ADC sample to pass data back to client as driver doesn't have buffer
293  *        to accumulate data. As soon as callback returns, xConverted_Data becomes invalid.
294  *        On the other hand however if client does pass a buffer for driver to use,
295  *        callback is triggered only after driver has filled buffer with xBufLen samples,
296  *        client buffer is passed back in callback as XConverted_Data whose life span is
297  *        controlled by the client even after callback returns.
298  */
299 typedef struct IotAdcChBuffer_s
300 {
301     uint8_t ucAdcChannel; /*!< Adc Channel number */
302     void * pvBuffer;      /*!< Buffer to store adc results in */
303     uint8_t ucBufLen;     /*!< Max buffer length to write into pvBuffer */
304 } IotAdcChBuffer_t;
305 
306 /**
307  * @brief Some ADC host controller supports grouping multiple ADC channels into a chain.
308  *        When the chain is triggered to sample ADC data, all ADC channels in the group
309  *        are sampled in sequence so that client doesn't need to trigger each channel
310  *        individually. Converted ADC samples from such chain group can be passed back
311  *        to the client with a single callback.
312  *        This data structure is used for ioctl to define ADC chain setting.
313  */
314 typedef struct IoTAdcChain_s
315 {
316     uint8_t ucAdcChannel; /*!< logical ADC channel number as input to ioctl. It is recommended
317                            *!< that client uses the first ADC channel number in the group as its
318                            *!< logical number which client can use later to trigger group sampling */
319     void * pvBuffer;      /*!< data buffer used by driver to save converted sample data.
320                            *!< The buffer is allocated by client and passed to driver to use. */
321     uint8_t ucBufLen;     /*!< Data buffer length, shall be large enough to hold group sample data. */
322     uint16_t usChainMask; /*!< Define which ADC channels are in the chain group.
323                            *!< e.g. 'x' bit set to 1 means ADC channel x is included in the group.
324                            *!< Client shall manage potential ADC channel use conflict. */
325 } IotAdcChain_t;
326 
327 /**
328  * @brief adc ioctl request types.
329  */
330 typedef enum IotAdcIoctlRequest_s
331 {
332     eSetAdcConfig, /*!< Set the ADC Configuration.  Takes IotAdcConfig_t parameter. */
333     eGetAdcConfig, /*!< Get the ADC Configuration.  Returns results in IotAdcConfig_t parameter. */
334     eGetChStatus,  /*!< Get the Channel Status.  Returns results in IotAdcChStatus_t parameter. */
335     eSetChBuffer,  /*!< Set the buffer for ADC values to be stored in.  Takes IotAdcChBuffer_t parameter. */
336     eSetAdcChain,  /*!< ADC Chain for multiple ADC channels.  Takes IotAdcChain_t parameter. */
337 } IotAdcIoctlRequest_t;
338 
339 /**
340  * @brief Used for various ADC control functions.
341  *
342  * @param[in] pxAdc The ADC handle returned in the open() call.
343  * @param[in] xRequest ioctl request defined by IotAdcIoctlRequest_s enums.
344  * @param[in/out] pvBuffer data buffer for ioctl request.
345  * @param[in] pvBuffer size.
346  *
347  * @return
348  * - IOT_ADC_SCUCCESS on success
349  * - IOT_ADC_INVALID_VALUE, on NULL handle or invalid request or NULL or invalid buffer pointer
350  * - IOT_ADC_CH_BUSY if ADC operation not complete.
351  * - IOT_ADC_NOT_OPEN if ADC has been closed without re-opening.
352  * - IOT_ADC_FAILED if invalid ADC chain is requested.
353  * - IOT_ADC_FUNCTION_NOT_SUPPORTED only valid for eSetAdcChain, if feature is not supported.
354  */
355 int32_t iot_adc_ioctl( IotAdcHandle_t const pxAdc,
356                        IotAdcIoctlRequest_t xRequest,
357                        void * const pvBuffer );
358 
359 #endif /* _IOT_ADC_H_ */
360