Vybhav Kadaba
/
EV-PRO-MW1001_Development_updateFW
Bumped Mbed FW version to 01.20.0080
Embed:
(wiki syntax)
Show/hide line numbers
utils.c
Go to the documentation of this file.
00001 /* 00002 Copyright 2019 (c) Analog Devices, Inc. 00003 00004 All rights reserved. 00005 00006 Redistribution and use in source and binary forms, with or without 00007 modification, are permitted provided that the following conditions are met: 00008 - Redistributions of source code must retain the above copyright 00009 notice, this list of conditions and the following disclaimer. 00010 - Redistributions in binary form must reproduce the above copyright 00011 notice, this list of conditions and the following disclaimer in 00012 the documentation and/or other materials provided with the 00013 distribution. 00014 - Neither the name of Analog Devices, Inc. nor the names of its 00015 contributors may be used to endorse or promote products derived 00016 from this software without specific prior written permission. 00017 - The use of this software may or may not infringe the patent rights 00018 of one or more patent holders. This license does not release you 00019 from the requirement that you obtain separate licenses from these 00020 patent holders to use this software. 00021 - Use of the software either in source or binary form, must be run 00022 on or directly connected to an Analog Devices Inc. component. 00023 00024 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR 00025 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, 00026 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00027 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, 00028 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00029 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR 00030 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00031 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00032 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00033 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 */ 00035 00036 /*! 00037 ****************************************************************************** 00038 * @file: utils.c 00039 * @brief: Interface Utilities for ADMW1001 00040 *----------------------------------------------------------------------------- 00041 */ 00042 #include <stdlib.h> 00043 00044 #include "utils.h" 00045 #include "admw_log.h" 00046 00047 void utils_printStatus( 00048 ADMW_STATUS *pStatus) 00049 { 00050 ADMW_LOG_INFO("Status Summary:"); 00051 00052 if (pStatus->deviceStatus == 0) { 00053 ADMW_LOG_INFO("\tNo errors detected"); 00054 } else { 00055 if (pStatus->deviceStatus & ADMW_DEVICE_STATUS_BUSY ) 00056 ADMW_LOG_INFO("\tCommand running"); 00057 if (pStatus->deviceStatus & ADMW_DEVICE_STATUS_DATAREADY ) 00058 ADMW_LOG_INFO("\tData ready"); 00059 if (pStatus->deviceStatus & ADMW_DEVICE_STATUS_ERROR ) 00060 ADMW_LOG_INFO("\tActive Errors - RESET REQUIRED"); 00061 if (pStatus->deviceStatus & ADMW_DEVICE_STATUS_FIFO_ERROR ) 00062 { 00063 ADMW_LOG_INFO("\tActive FIFO Errors - ATTENTION REQUIRED"); 00064 ADMW_LOG_INFO("\tFIFO buffer full"); 00065 ADMW_LOG_INFO("\tExceeding measurements per cycle limit of %d",MAXIMUM_MEASUREMENTS_PER_CYCLE); 00066 } 00067 if (pStatus->deviceStatus & ADMW_DEVICE_STATUS_CONFIG_ERROR ) 00068 ADMW_LOG_INFO("\tActive Configuration Errors - ATTENTION REQUIRED"); 00069 if (pStatus->deviceStatus & ADMW_DEVICE_STATUS_ALERT ) { 00070 ADMW_LOG_INFO("\tActive Alerts - ATTENTION REQUIRED:"); 00071 00072 for (unsigned i = 0; i < ADMW1001_MAX_CHANNELS ; i++) { 00073 if (pStatus->channelAlerts [i] == 0) 00074 continue; 00075 00076 ADMW_LOG_INFO("\t\tChannel #%u:", i); 00077 if (pStatus->channelAlerts [i] & ADMW_ALERT_DETAIL_CH_ADC_NEAR_OVERRANGE ) 00078 ADMW_LOG_INFO("\t\t\ADC near overrange detected"); 00079 if (pStatus->channelAlerts [i] & ADMW_ALERT_DETAIL_CH_SENSOR_UNDERRANGE ) 00080 ADMW_LOG_INFO("\t\t\tSensor underrange detected"); 00081 if (pStatus->channelAlerts [i] & ADMW_ALERT_DETAIL_CH_SENSOR_OVERRANGE ) 00082 ADMW_LOG_INFO("\t\t\tSensor overrange detected"); 00083 if (pStatus->channelAlerts [i] & ADMW_ALERT_DETAIL_CH_CJ_SOFT_FAULT ) 00084 ADMW_LOG_INFO("\t\t\tCJC soft fault alert detected"); 00085 if (pStatus->channelAlerts [i] & ADMW_ALERT_DETAIL_CH_CJ_HARD_FAULT ) 00086 ADMW_LOG_INFO("\t\t\tCJC hard fault alert detected"); 00087 if (pStatus->channelAlerts [i] & ADMW_ALERT_DETAIL_CH_ADC_INPUT_OVERRANGE ) 00088 ADMW_LOG_INFO("\t\t\tADC input overranage alert detected"); 00089 if (pStatus->channelAlerts [i] & ADMW_ALERT_DETAIL_CH_SENSOR_HARDFAULT ) 00090 ADMW_LOG_INFO("\t\t\tChannel sensor hardfault alert detected"); 00091 } 00092 } 00093 00094 if ((pStatus->deviceStatus & ADMW_DEVICE_STATUS_ERROR ) || 00095 (pStatus->deviceStatus & ADMW_DEVICE_STATUS_ALERT )) { 00096 ADMW_LOG_INFO("\t\tLast Debug Code: %u-%u", 00097 (pStatus->debugCode >> 16) & 0xFFFF, 00098 (pStatus->debugCode >> 0) & 0xFFFF); 00099 } 00100 } 00101 } 00102 00103 void utils_printSamples( 00104 ADMW_DATA_SAMPLE *pSampleBuffer, 00105 uint32_t nNumSamples, 00106 ADMW_MEASUREMENT_MODE eMeasurementMode) 00107 { 00108 for (uint32_t i = 0; i < nNumSamples; i++) { 00109 ADMW_LOG_INFO("Sample # %2d Channel_ID # %2d :: Raw_Sample %f :: processedValue %f :: flags: ERROR:%X , ALERT:%X", 00110 i+1, 00111 pSampleBuffer[i].Channel_ID, 00112 pSampleBuffer[i].Raw_Sample, 00113 pSampleBuffer[i].processedValue, 00114 pSampleBuffer[i].Ch_Error, 00115 pSampleBuffer[i].Ch_Alert); 00116 } 00117 } 00118 00119 static void gpioCallbackFn(ADMW_GPIO_PIN ePinId, void * pArg) 00120 { 00121 volatile bool *pbFlag = (volatile bool *)pArg; 00122 *pbFlag = true; 00123 } 00124 00125 ADMW_RESULT utils_registerCallbacks( 00126 ADMW_DEVICE_HANDLE hDevice, 00127 volatile bool *pbDataReady, 00128 volatile bool *pbError, 00129 volatile bool *pbAlert) 00130 { 00131 ADMW_RESULT res; 00132 bool state; 00133 00134 res = admw_RegisterGpioCallback(hDevice, ADMW_GPIO_PIN_DATAREADY , 00135 gpioCallbackFn, (void *)pbDataReady); 00136 if (res != ADMW_SUCCESS ) { 00137 ADMW_LOG_ERROR("Failed to register DATAREADY callback"); 00138 return res; 00139 } 00140 00141 res = admw_GetGpioState(hDevice, ADMW_GPIO_PIN_ALERT_ERROR , &state); 00142 if (res != ADMW_SUCCESS ) { 00143 ADMW_LOG_ERROR("Failed to get current ERROR state"); 00144 return res; 00145 } 00146 if (state) { 00147 ADMW_LOG_ERROR("ERROR signal already asserted"); 00148 return ADMW_FAILURE ; 00149 } 00150 res = admw_RegisterGpioCallback(hDevice, ADMW_GPIO_PIN_ALERT_ERROR , 00151 gpioCallbackFn, (void *)pbError); 00152 if (res != ADMW_SUCCESS ) { 00153 ADMW_LOG_ERROR("Failed to register ERROR callback"); 00154 return res; 00155 } 00156 00157 /*res = admw_GetGpioState(hDevice, ADMW_GPIO_PIN_ALERT, &state); 00158 if (res != ADMW_SUCCESS) 00159 { 00160 ADMW_LOG_ERROR("Failed to get current ALERT state"); 00161 return res; 00162 } 00163 if (state) 00164 { 00165 ADMW_LOG_ERROR("ALERT signal already asserted"); 00166 return ADMW_FAILURE; 00167 }*/ 00168 res = admw_RegisterGpioCallback(hDevice, ADMW_GPIO_PIN_ALERT_ERROR , 00169 gpioCallbackFn, (void *)pbAlert); 00170 if (res != ADMW_SUCCESS ) { 00171 ADMW_LOG_ERROR("Failed to register ALERT callback"); 00172 return res; 00173 } 00174 00175 return ADMW_SUCCESS ; 00176 } 00177 00178 ADMW_RESULT utils_deregisterCallbacks( 00179 ADMW_DEVICE_HANDLE hDevice) 00180 { 00181 ADMW_RESULT res; 00182 00183 res = admw_RegisterGpioCallback(hDevice, ADMW_GPIO_PIN_DATAREADY , 00184 NULL, NULL); 00185 if (res != ADMW_SUCCESS ) { 00186 ADMW_LOG_ERROR("Failed to deregister DATAREADY callback"); 00187 return res; 00188 } 00189 00190 res = admw_RegisterGpioCallback(hDevice, ADMW_GPIO_PIN_ALERT_ERROR , 00191 NULL, NULL); 00192 if (res != ADMW_SUCCESS ) { 00193 ADMW_LOG_ERROR("Failed to deregister ERROR callback"); 00194 return res; 00195 } 00196 00197 res = admw_RegisterGpioCallback(hDevice, ADMW_GPIO_PIN_ALERT_ERROR , 00198 NULL, NULL); 00199 if (res != ADMW_SUCCESS ) { 00200 ADMW_LOG_INFO("Failed to deregister ALERT callback"); 00201 return res; 00202 } 00203 00204 return ADMW_SUCCESS ; 00205 } 00206 00207 ADMW_RESULT utils_runMeasurement( 00208 ADMW_DEVICE_HANDLE hDevice, 00209 ADMW_MEASUREMENT_MODE eMeasurementMode) 00210 { 00211 ADMW_RESULT res; 00212 volatile bool bDataReady = false; 00213 volatile bool bError = false; 00214 volatile bool bAlert = false; 00215 res = utils_registerCallbacks(hDevice, &bDataReady, &bError, &bAlert); 00216 if (res != ADMW_SUCCESS ) 00217 return res; 00218 00219 /* 00220 * Retrieve the number of samples per cycle, per DATAREADY pulse, etc. for 00221 * this configuration. 00222 */ 00223 ADMW1001_OPERATING_MODE eOperatingMode; 00224 ADMW1001_DATAREADY_MODE eDataReadyMode; 00225 uint32_t nSamplesPerDataready; 00226 uint32_t nSamplesPerCycle; 00227 uint8_t nBytesPerSample; 00228 res = admw1001_GetDataReadyModeInfo(hDevice, 00229 eMeasurementMode, 00230 &eOperatingMode, 00231 &eDataReadyMode, 00232 &nSamplesPerDataready, 00233 &nSamplesPerCycle, 00234 &nBytesPerSample); 00235 if (res != ADMW_SUCCESS ) 00236 return res; 00237 00238 /* 00239 * Allocate a buffer to store the samples retrieved on each DATAREADY pulse 00240 */ 00241 ADMW_DATA_SAMPLE *pSampleBuffer; 00242 pSampleBuffer = malloc(sizeof(ADMW_DATA_SAMPLE ) * 00243 nSamplesPerDataready); 00244 if (pSampleBuffer == NULL) { 00245 ADMW_LOG_ERROR("Failed to allocate sample buffer"); 00246 return ADMW_NO_MEM ; 00247 } 00248 00249 /* 00250 * Kick off the measurement cycle(s) here 00251 */ 00252 ADMW_LOG_INFO("Starting measurement"); 00253 res = admw_StartMeasurement(hDevice, eMeasurementMode); 00254 if (res != ADMW_SUCCESS ) { 00255 ADMW_LOG_ERROR("Failed to start measurement"); 00256 return res; 00257 } 00258 00259 /* 00260 * Loop continuously unless operating mode is single-cycle 00261 */ 00262 uint32_t nSampleCount = 0; 00263 uint32_t nReturned; 00264 while (true) { 00265 ADMW_STATUS status; 00266 00267 /* 00268 * Wait until the next batch of 1 or more samples is ready, continuously 00269 * checking DATAREADY until it is asserted 00270 */ 00271 res = admw_GetStatus(hDevice, &status); 00272 if (res != ADMW_SUCCESS ) { 00273 ADMW_LOG_ERROR("Failed to retrieve device status"); 00274 } 00275 if (status.deviceStatus & ADMW_DEVICE_STATUS_FIFO_ERROR ) 00276 { 00277 utils_printStatus(&status); 00278 break; 00279 } 00280 while (! (bDataReady || bError)); 00281 if (!bError) { 00282 /* 00283 * Get data samples from the measurement cycle, if no error has occurred 00284 */ 00285 bDataReady = false; 00286 res = admw_GetData(hDevice, eMeasurementMode, pSampleBuffer, 00287 nBytesPerSample, nSamplesPerDataready, 00288 &nReturned); 00289 if (res != ADMW_SUCCESS ) { 00290 if (res == ADMW_INCOMPLETE ) { 00291 /* 00292 * This is expected in cases where cycleSkipCount may 00293 * be non-zero for some channels, resulting in 00294 * variable-length sequences 00295 */ 00296 00297 ADMW_LOG_DEBUG("Retrieved %u of %u requested data samples", 00298 nReturned, nSamplesPerDataready); 00299 continue; 00300 } else { 00301 ADMW_LOG_WARN("Failed to get data samples from device"); 00302 return res; 00303 } 00304 } 00305 00306 /* 00307 * Display the data samples. 00308 * 00309 * NOTE: this requires a sufficient idle time between subsequent 00310 * DATAREADY pulses to allow printing to occur. Otherwise, 00311 * subsequent samples may be missed if not retrieved promptly when 00312 * the next DATAREADY assertion occurs. 00313 */ 00314 utils_printSamples(pSampleBuffer, nReturned, eMeasurementMode); 00315 nSampleCount += nReturned; 00316 } 00317 00318 /* 00319 * Check and print device status if errors/alerts have been triggered 00320 */ 00321 if (bError || bAlert) { 00322 res = admw_GetStatus(hDevice, &status); 00323 if (res != ADMW_SUCCESS ) { 00324 ADMW_LOG_ERROR("Failed to retrieve device status"); 00325 return res; 00326 } 00327 00328 if (status.deviceStatus & 00329 (ADMW_DEVICE_STATUS_ERROR | ADMW_DEVICE_STATUS_ALERT )) { 00330 utils_printStatus(&status); 00331 00332 /* Break out of the loop if any errors are raised */ 00333 if (bError) 00334 break; 00335 } 00336 } 00337 00338 if (eOperatingMode == ADMW1001_OPERATING_MODE_SINGLECYCLE ) { 00339 /* 00340 * In this mode, break out of the loop when the measurement command 00341 * has completed. 00342 * 00343 * One option is to check for the expected number of samples to be 00344 * returned for the cycle. However, cycles may have variable-length 00345 * sequences if the cycleSkipCount option is non-zero for any of the 00346 * channels. 00347 * 00348 * So, instead, we check for the command-running status, which 00349 * will de-assert in this mode when the measurement command has 00350 * completed a single cycle. 00351 */ 00352 bool bCommandRunning; 00353 res = admw_GetCommandRunningState(hDevice, &bCommandRunning); 00354 if (res != ADMW_SUCCESS ) { 00355 ADMW_LOG_ERROR("Failed to get command-running status"); 00356 return res; 00357 } 00358 00359 if (!bCommandRunning && !bDataReady) 00360 break; 00361 } 00362 } 00363 00364 ADMW_LOG_INFO("Stopping measurement"); 00365 res = admw_StopMeasurement(hDevice); 00366 if (res != ADMW_SUCCESS ) { 00367 ADMW_LOG_ERROR("Failed to send stop measurement"); 00368 return res; 00369 } 00370 00371 free(pSampleBuffer); 00372 00373 res = utils_deregisterCallbacks(hDevice); 00374 if (res != ADMW_SUCCESS ) 00375 return res; 00376 00377 return ADMW_SUCCESS ; 00378 } 00379
Generated on Thu Jul 14 2022 10:33:00 by 1.7.2