Sean Wilson / Mbed OS AdiSense1000_V21

Fork of AdiSense1000 by PoC_Team

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers utils.c Source File

utils.c

00001 #include <stdlib.h>
00002 
00003 #include "utils.h"
00004 #include "inc/adi_sense_log.h"
00005 
00006 void utils_printStatus(
00007     ADI_SENSE_STATUS  *pStatus)
00008 {
00009     ADI_SENSE_LOG_INFO("Status Summary:");
00010 
00011     if (pStatus->deviceStatus  == 0)
00012     {
00013         ADI_SENSE_LOG_INFO("\tNo errors detected");
00014     }
00015     else
00016     {
00017         if (pStatus->deviceStatus  & ADI_SENSE_DEVICE_STATUS_BUSY )
00018             ADI_SENSE_LOG_INFO("\tCommand running");
00019         if (pStatus->deviceStatus  & ADI_SENSE_DEVICE_STATUS_DATAREADY )
00020             ADI_SENSE_LOG_INFO("\tData ready");
00021         if (pStatus->deviceStatus  & ADI_SENSE_DEVICE_STATUS_ERROR )
00022             ADI_SENSE_LOG_INFO("\tActive Errors - RESET REQUIRED");
00023         if (pStatus->deviceStatus  & ADI_SENSE_DEVICE_STATUS_FIFO_ERROR )
00024             ADI_SENSE_LOG_INFO("\tActive FIFO Errors - ATTENTION REQUIRED");
00025         if (pStatus->deviceStatus  & ADI_SENSE_DEVICE_STATUS_CONFIG_ERROR )
00026             ADI_SENSE_LOG_INFO("\tActive Configuration Errors - ATTENTION REQUIRED");
00027         if (pStatus->deviceStatus  & ADI_SENSE_DEVICE_STATUS_LUT_ERROR )
00028             ADI_SENSE_LOG_INFO("\tActive Look-Up Table Errors - ATTENTION REQUIRED");
00029         if (pStatus->deviceStatus  & ADI_SENSE_DEVICE_STATUS_EXT_FLASH_ERROR )
00030             ADI_SENSE_LOG_INFO("\tActive External Flash Errors - ATTENTION REQUIRED");
00031 
00032         if (pStatus->deviceStatus  & ADI_SENSE_DEVICE_STATUS_ERROR )
00033         {
00034             ADI_SENSE_LOG_INFO("\tActive Errors - ATTENTION REQUIRED");
00035             ADI_SENSE_LOG_INFO("\t\tLast Error Code: %u (0x%X)",
00036                                pStatus->errorCode , pStatus->errorCode );
00037 
00038             if (pStatus->diagnosticsStatus  == 0)
00039             {
00040                 ADI_SENSE_LOG_INFO("\t\tNo diagnostics faults detected");
00041             }
00042             else
00043             {
00044                 ADI_SENSE_LOG_INFO("\t\tActive diagnostics faults:");
00045 
00046                 if (pStatus->diagnosticsStatus  & ADI_SENSE_DIAGNOSTICS_STATUS_CHECKSUM_ERROR )
00047                     ADI_SENSE_LOG_INFO("\t\t\tInternal Checksum fault detected");
00048                 if (pStatus->diagnosticsStatus  & ADI_SENSE_DIAGNOSTICS_STATUS_COMMS_ERROR )
00049                     ADI_SENSE_LOG_INFO("\t\t\tInternal Communications fault detected");
00050                 if (pStatus->diagnosticsStatus  & ADI_SENSE_DIAGNOSTICS_STATUS_SUPPLY_MONITOR_ERROR )
00051                     ADI_SENSE_LOG_INFO("\t\t\tSupply Monitor fault detected");
00052                 if (pStatus->diagnosticsStatus  & ADI_SENSE_DIAGNOSTICS_STATUS_SUPPLY_CAP_ERROR )
00053                     ADI_SENSE_LOG_INFO("\t\t\tSupply Regulator Capacitor fault detected");
00054                 if (pStatus->diagnosticsStatus  & ADI_SENSE_DIAGNOSTICS_STATUS_CONVERSION_ERROR )
00055                     ADI_SENSE_LOG_INFO("\t\t\tInternal ADC Conversions fault detected");
00056                 if (pStatus->diagnosticsStatus  & ADI_SENSE_DIAGNOSTICS_STATUS_CALIBRATION_ERROR )
00057                     ADI_SENSE_LOG_INFO("\t\t\tInternal Device Calibrations fault detected");
00058             }
00059         }
00060 
00061         if (pStatus->deviceStatus  & ADI_SENSE_DEVICE_STATUS_ALERT )
00062         {
00063             ADI_SENSE_LOG_INFO("\tActive Alerts - ATTENTION REQUIRED:");
00064             ADI_SENSE_LOG_INFO("\t\tLast Alert Code: %u (0x%X)",
00065                                pStatus->alertCode , pStatus->alertCode );
00066 
00067             for (unsigned i = 0; i < ADI_SENSE_1000_MAX_CHANNELS ; i++)
00068             {
00069                 if (pStatus->channelAlerts [i] == 0)
00070                     continue;
00071 
00072                 ADI_SENSE_LOG_INFO("\t\tChannel #%u:", i);
00073                 ADI_SENSE_LOG_INFO("\t\t\tLast Alert Code: %u (0x%X)",
00074                                    pStatus->channelAlertCodes [i],
00075                                    pStatus->channelAlertCodes [i]);
00076                 if (pStatus->channelAlerts [i] & ADI_SENSE_CHANNEL_ALERT_TIMEOUT )
00077                     ADI_SENSE_LOG_INFO("\t\t\tTimeout alert detected");
00078                 if (pStatus->channelAlerts [i] & ADI_SENSE_CHANNEL_ALERT_UNDER_RANGE )
00079                     ADI_SENSE_LOG_INFO("\t\t\tUnder Range alert detected");
00080                 if (pStatus->channelAlerts [i] & ADI_SENSE_CHANNEL_ALERT_OVER_RANGE )
00081                     ADI_SENSE_LOG_INFO("\t\t\tOver Range alert detected");
00082                 if (pStatus->channelAlerts [i] & ADI_SENSE_CHANNEL_ALERT_LOW_LIMIT )
00083                     ADI_SENSE_LOG_INFO("\t\t\tLow limit alert detected");
00084                 if (pStatus->channelAlerts [i] & ADI_SENSE_CHANNEL_ALERT_HIGH_LIMIT )
00085                     ADI_SENSE_LOG_INFO("\t\t\tHigh Limit alert detected");
00086                 if (pStatus->channelAlerts [i] & ADI_SENSE_CHANNEL_ALERT_SENSOR_OPEN )
00087                     ADI_SENSE_LOG_INFO("\t\t\tSensor Fault alert detected");
00088                 if (pStatus->channelAlerts [i] & ADI_SENSE_CHANNEL_ALERT_REF_DETECT )
00089                     ADI_SENSE_LOG_INFO("\t\t\tReference Detection alert detected");
00090                 if (pStatus->channelAlerts [i] & ADI_SENSE_CHANNEL_ALERT_CONFIG_ERR )
00091                     ADI_SENSE_LOG_INFO("\t\t\tConfiguration Error alert detected");
00092                 if (pStatus->channelAlerts [i] & ADI_SENSE_CHANNEL_ALERT_LUT_ERR )
00093                     ADI_SENSE_LOG_INFO("\t\t\tLook-Up Table Error alert detected");
00094                 if (pStatus->channelAlerts [i] & ADI_SENSE_CHANNEL_ALERT_SENSOR_NOT_READY )
00095                     ADI_SENSE_LOG_INFO("\t\t\tSensor Not Ready alert detected");
00096                 if (pStatus->channelAlerts [i] & ADI_SENSE_CHANNEL_ALERT_COMP_NOT_READY )
00097                     ADI_SENSE_LOG_INFO("\t\t\tCompensation Channel Not Ready alert detected");
00098                 if (pStatus->channelAlerts [i] & ADI_SENSE_CHANNEL_ALERT_LUT_UNDER_RANGE )
00099                     ADI_SENSE_LOG_INFO("\t\t\tUnder Look-Up Table Range alert detected");
00100                 if (pStatus->channelAlerts [i] & ADI_SENSE_CHANNEL_ALERT_LUT_OVER_RANGE )
00101                     ADI_SENSE_LOG_INFO("\t\t\tOver Look-Up Table Range alert detected");
00102             }
00103         }
00104     }
00105 }
00106 
00107 void utils_printSamples(
00108     ADI_SENSE_DATA_SAMPLE  *pSampleBuffer,
00109     uint32_t nNumSamples,
00110     ADI_SENSE_MEASUREMENT_MODE  eMeasurementMode)
00111 {
00112     bool fftMode = (eMeasurementMode == ADI_SENSE_MEASUREMENT_MODE_FFT );
00113 
00114     for (uint32_t i = 0; i < nNumSamples; i++)
00115     {
00116         if (fftMode)
00117         {
00118             ADI_SENSE_LOG_INFO("Sample # %2d Channel # %2d :: Bin/Raw %8d  :: Magnitude %e :: flags:%s%s",
00119                                i+1,
00120                                pSampleBuffer[i].channelId,
00121                                pSampleBuffer[i].rawValue,
00122                                pSampleBuffer[i].processedValue,
00123                                pSampleBuffer[i].status & ADI_SENSE_DEVICE_STATUS_ERROR  ? " ERROR" : "",
00124                                pSampleBuffer[i].status & ADI_SENSE_DEVICE_STATUS_ALERT  ? " ALERT" : "");
00125         }
00126         else
00127         {
00128             ADI_SENSE_LOG_INFO("Sample # %2d Channel # %2d :: Raw %8d  :: Processed %f :: flags:%s%s",
00129                                i+1,
00130                                pSampleBuffer[i].channelId,
00131                                pSampleBuffer[i].rawValue,
00132                                pSampleBuffer[i].processedValue,
00133                                pSampleBuffer[i].status & ADI_SENSE_DEVICE_STATUS_ERROR  ? " ERROR" : "",
00134                                pSampleBuffer[i].status & ADI_SENSE_DEVICE_STATUS_ALERT  ? " ALERT" : "");
00135         }
00136     }
00137 }
00138 
00139 static void gpioCallbackFn(ADI_SENSE_GPIO_PIN  ePinId, void * pArg)
00140 {
00141     volatile bool_t *pbFlag = (volatile bool_t *)pArg;
00142     *pbFlag = true;
00143 }
00144 
00145 ADI_SENSE_RESULT  utils_registerCallbacks(
00146     ADI_SENSE_DEVICE_HANDLE  hDevice,
00147     volatile bool_t *pbDataReady,
00148     volatile bool_t *pbError,
00149     volatile bool_t *pbAlert)
00150 {
00151     ADI_SENSE_RESULT  res;
00152 
00153     res = adi_sense_RegisterGpioCallback(hDevice, ADI_SENSE_GPIO_PIN_DATAREADY ,
00154                                          gpioCallbackFn, (void *)pbDataReady);
00155     if (res != ADI_SENSE_SUCCESS )
00156     {
00157         ADI_SENSE_LOG_ERROR("Failed to register DATAREADY callback");
00158         return res;
00159     }
00160 
00161     res = adi_sense_RegisterGpioCallback(hDevice, ADI_SENSE_GPIO_PIN_ERROR ,
00162                                          gpioCallbackFn, (void *)pbError);
00163     if (res != ADI_SENSE_SUCCESS )
00164     {
00165         ADI_SENSE_LOG_ERROR("Failed to register ERROR callback");
00166         return res;
00167     }
00168 
00169     res = adi_sense_RegisterGpioCallback(hDevice, ADI_SENSE_GPIO_PIN_ALERT ,
00170                                          gpioCallbackFn, (void *)pbAlert);
00171     if (res != ADI_SENSE_SUCCESS )
00172     {
00173         ADI_SENSE_LOG_ERROR("Failed to register ALERT callback");
00174         return res;
00175     }
00176 
00177     return ADI_SENSE_SUCCESS ;
00178 }
00179 
00180 ADI_SENSE_RESULT  utils_deregisterCallbacks(
00181     ADI_SENSE_DEVICE_HANDLE  hDevice)
00182 {
00183     ADI_SENSE_RESULT  res;
00184 
00185     res = adi_sense_RegisterGpioCallback(hDevice, ADI_SENSE_GPIO_PIN_DATAREADY ,
00186                                          NULL, NULL);
00187     if (res != ADI_SENSE_SUCCESS )
00188     {
00189         ADI_SENSE_LOG_ERROR("Failed to deregister DATAREADY callback");
00190         return res;
00191     }
00192 
00193     res = adi_sense_RegisterGpioCallback(hDevice, ADI_SENSE_GPIO_PIN_ERROR ,
00194                                          NULL, NULL);
00195     if (res != ADI_SENSE_SUCCESS )
00196     {
00197         ADI_SENSE_LOG_ERROR("Failed to deregister ERROR callback");
00198         return res;
00199     }
00200 
00201     res = adi_sense_RegisterGpioCallback(hDevice, ADI_SENSE_GPIO_PIN_ALERT ,
00202                                          NULL, NULL);
00203     if (res != ADI_SENSE_SUCCESS )
00204     {
00205         ADI_SENSE_LOG_INFO("Failed to deregister ALERT callback");
00206         return res;
00207     }
00208 
00209     return ADI_SENSE_SUCCESS ;
00210 }
00211 
00212 ADI_SENSE_RESULT  utils_runMeasurement(
00213     ADI_SENSE_DEVICE_HANDLE  hDevice,
00214     ADI_SENSE_MEASUREMENT_MODE  eMeasurementMode)
00215 {
00216     ADI_SENSE_RESULT  res;
00217 
00218     volatile bool_t bDataReady = false;
00219     volatile bool_t bError = false;
00220     volatile bool_t bAlert = false;
00221     res = utils_registerCallbacks(hDevice, &bDataReady, &bError, &bAlert);
00222     if (res != ADI_SENSE_SUCCESS )
00223         return res;
00224 
00225     /*
00226      * Retrieve the number of samples per cycle, per DATAREADY pulse, etc. for
00227      * this configuration.
00228      */
00229     ADI_SENSE_1000_OPERATING_MODE  eOperatingMode;
00230     ADI_SENSE_1000_DATAREADY_MODE  eDataReadyMode;
00231     uint32_t nSamplesPerDataready;
00232     uint32_t nSamplesPerCycle;
00233     uint8_t nBytesPerSample;
00234     res = adi_sense_1000_GetDataReadyModeInfo(hDevice,
00235                                               eMeasurementMode,
00236                                               &eOperatingMode,
00237                                               &eDataReadyMode,
00238                                               &nSamplesPerDataready,
00239                                               &nSamplesPerCycle,
00240                                               &nBytesPerSample);
00241     if (res != ADI_SENSE_SUCCESS )
00242         return res;
00243 
00244     /*
00245      * Allocate a buffer to store the samples retrieved on each DATAREADY pulse
00246      */
00247     ADI_SENSE_DATA_SAMPLE  *pSampleBuffer;
00248     pSampleBuffer = malloc(sizeof(ADI_SENSE_DATA_SAMPLE ) *
00249                            nSamplesPerDataready);
00250     if (pSampleBuffer == NULL)
00251     {
00252         ADI_SENSE_LOG_ERROR("Failed to allocate sample buffer");
00253         return ADI_SENSE_NO_MEM ;
00254     }
00255 
00256     /*
00257      * Kick off the measurement cycle(s) here
00258      */
00259     res = adi_sense_StartMeasurement(hDevice, eMeasurementMode);
00260     if (res != ADI_SENSE_SUCCESS )
00261     {
00262         ADI_SENSE_LOG_ERROR("Failed to start measurement");
00263         return res;
00264     }
00265 
00266     /*
00267      * Loop continuously unless operating mode is single-cycle
00268      */
00269     uint32_t nSampleCount = 0;
00270     while (true)
00271     {
00272         ADI_SENSE_STATUS  status;
00273         uint32_t nReturned;
00274 
00275         /*
00276          * Wait until the next batch of 1 or more samples is ready, continuously
00277          * checking DATAREADY until it is asserted
00278          */
00279         while (! (bDataReady || bError))
00280             ;
00281 
00282         if (!bError)
00283         {
00284             /*
00285              * Get data samples from the measurement cycle, if no error has occurred
00286              */
00287             bDataReady = false;
00288             res = adi_sense_GetData(hDevice, eMeasurementMode, pSampleBuffer,
00289                                     nBytesPerSample, nSamplesPerDataready,
00290                                     &nReturned);
00291             if (res != ADI_SENSE_SUCCESS )
00292             {
00293                 if (res == ADI_SENSE_INCOMPLETE )
00294                 {
00295                     /*
00296                      * This is expected in cases where cycleSkipCount may
00297                      * be non-zero for some channels, resulting in
00298                      * variable-length sequences
00299                      */
00300                     ADI_SENSE_LOG_DEBUG("Retrieved %u of %u requested data samples",
00301                                         nReturned, nSamplesPerDataready);
00302                 }
00303                 else
00304                 {
00305                     ADI_SENSE_LOG_WARN("Failed to get data samples from device");
00306                     return res;
00307                 }
00308             }
00309 
00310             /*
00311              * Display the data samples.
00312              *
00313              * NOTE: this requires a sufficient idle time between subsequent
00314              * DATAREADY pulses to allow printing to occur.  Otherwise,
00315              * subsequent samples may be missed if not retrieved promptly when
00316              * the next DATAREADY assertion occurs.
00317              */
00318             utils_printSamples(pSampleBuffer, nReturned, eMeasurementMode);
00319             nSampleCount += nReturned;
00320         }
00321 
00322         /*
00323          * Check and print device status if errors/alerts have been triggered
00324          */
00325         if (bError || bAlert)
00326         {
00327             res = adi_sense_GetStatus(hDevice, &status);
00328             if (res != ADI_SENSE_SUCCESS )
00329             {
00330                 ADI_SENSE_LOG_ERROR("Failed to retrieve device status");
00331                 return res;
00332             }
00333 
00334             if (status.deviceStatus  &
00335                 (ADI_SENSE_DEVICE_STATUS_ERROR  | ADI_SENSE_DEVICE_STATUS_ALERT ))
00336             {
00337                 utils_printStatus(&status);
00338 
00339                 /* Break out of the loop if any errors are raised */
00340                 if (bError)
00341                     break;
00342             }
00343         }
00344 
00345         if (eOperatingMode == ADI_SENSE_1000_OPERATING_MODE_SINGLECYCLE )
00346         {
00347             /*
00348              * In this mode, break out of the loop when the measurement command
00349              * has completed.
00350              *
00351              * One option is to check for the expected number of samples to be
00352              * returned for the cycle.  However, cycles may have variable-length
00353              * sequences if the cycleSkipCount option is non-zero for any of the
00354              * channels.
00355              *
00356              * So, instead, we check for the command-running status, which
00357              * will de-assert in this mode when the measurement command has
00358              * completed a single cycle.
00359              */
00360             bool_t bCommandRunning;
00361             res = adi_sense_GetCommandRunningState(hDevice, &bCommandRunning);
00362             if (res != ADI_SENSE_SUCCESS )
00363             {
00364                 ADI_SENSE_LOG_ERROR("Failed to get command-running status");
00365                 return res;
00366             }
00367 
00368             if (!bCommandRunning && !bDataReady)
00369                 break;
00370         }
00371     }
00372 
00373     res = adi_sense_StopMeasurement(hDevice);
00374     if (res != ADI_SENSE_SUCCESS )
00375     {
00376         ADI_SENSE_LOG_ERROR("Failed to send stop measurement");
00377         return res;
00378     }
00379 
00380     free(pSampleBuffer);
00381 
00382     res = utils_deregisterCallbacks(hDevice);
00383     if (res != ADI_SENSE_SUCCESS )
00384         return res;
00385 
00386     return ADI_SENSE_SUCCESS ;
00387 }