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