ADISense1000 Version 2.1 code base

Fork of AdiSense1000_V21 by Sean Wilson

Revision:
28:4eb837cd71df
Parent:
16:e4f2689363bb
diff -r 12d0204be712 -r 4eb837cd71df common/utils.c
--- a/common/utils.c	Mon Mar 26 14:50:05 2018 +0000
+++ b/common/utils.c	Thu May 17 10:34:45 2018 +0100
@@ -26,6 +26,8 @@
             ADI_SENSE_LOG_INFO("\tActive Configuration Errors - ATTENTION REQUIRED");
         if (pStatus->deviceStatus & ADI_SENSE_DEVICE_STATUS_LUT_ERROR)
             ADI_SENSE_LOG_INFO("\tActive Look-Up Table Errors - ATTENTION REQUIRED");
+        if (pStatus->deviceStatus & ADI_SENSE_DEVICE_STATUS_EXT_FLASH_ERROR)
+            ADI_SENSE_LOG_INFO("\tActive External Flash Errors - ATTENTION REQUIRED");
 
         if (pStatus->deviceStatus & ADI_SENSE_DEVICE_STATUS_ERROR)
         {
@@ -49,14 +51,6 @@
                     ADI_SENSE_LOG_INFO("\t\t\tSupply Monitor fault detected");
                 if (pStatus->diagnosticsStatus & ADI_SENSE_DIAGNOSTICS_STATUS_SUPPLY_CAP_ERROR)
                     ADI_SENSE_LOG_INFO("\t\t\tSupply Regulator Capacitor fault detected");
-                if (pStatus->diagnosticsStatus & ADI_SENSE_DIAGNOSTICS_STATUS_AINM_UV_ERROR)
-                    ADI_SENSE_LOG_INFO("\t\t\tNegative Analog Input Under-Voltage fault detected");
-                if (pStatus->diagnosticsStatus & ADI_SENSE_DIAGNOSTICS_STATUS_AINM_OV_ERROR)
-                    ADI_SENSE_LOG_INFO("\t\t\tNegative Analog Input Over-Voltage fault detected");
-                if (pStatus->diagnosticsStatus & ADI_SENSE_DIAGNOSTICS_STATUS_AINP_UV_ERROR)
-                    ADI_SENSE_LOG_INFO("\t\t\tPositive Analog Input Under-Voltage fault detected");
-                if (pStatus->diagnosticsStatus & ADI_SENSE_DIAGNOSTICS_STATUS_AINP_OV_ERROR)
-                    ADI_SENSE_LOG_INFO("\t\t\tPositive Analog Input Over-Voltage fault detected");
                 if (pStatus->diagnosticsStatus & ADI_SENSE_DIAGNOSTICS_STATUS_CONVERSION_ERROR)
                     ADI_SENSE_LOG_INFO("\t\t\tInternal ADC Conversions fault detected");
                 if (pStatus->diagnosticsStatus & ADI_SENSE_DIAGNOSTICS_STATUS_CALIBRATION_ERROR)
@@ -101,10 +95,6 @@
                     ADI_SENSE_LOG_INFO("\t\t\tSensor Not Ready alert detected");
                 if (pStatus->channelAlerts[i] & ADI_SENSE_CHANNEL_ALERT_COMP_NOT_READY)
                     ADI_SENSE_LOG_INFO("\t\t\tCompensation Channel Not Ready alert detected");
-                if (pStatus->channelAlerts[i] & ADI_SENSE_CHANNEL_ALERT_UNDER_VOLTAGE)
-                    ADI_SENSE_LOG_INFO("\t\t\tUnder Voltage alert detected");
-                if (pStatus->channelAlerts[i] & ADI_SENSE_CHANNEL_ALERT_OVER_VOLTAGE)
-                    ADI_SENSE_LOG_INFO("\t\t\tOver Voltage alert detected");
                 if (pStatus->channelAlerts[i] & ADI_SENSE_CHANNEL_ALERT_LUT_UNDER_RANGE)
                     ADI_SENSE_LOG_INFO("\t\t\tUnder Look-Up Table Range alert detected");
                 if (pStatus->channelAlerts[i] & ADI_SENSE_CHANNEL_ALERT_LUT_OVER_RANGE)
@@ -116,17 +106,33 @@
 
 void utils_printSamples(
     ADI_SENSE_DATA_SAMPLE *pSampleBuffer,
-    uint32_t nNumSamples)
+    uint32_t nNumSamples,
+    ADI_SENSE_MEASUREMENT_MODE eMeasurementMode)
 {
+    bool fftMode = (eMeasurementMode == ADI_SENSE_MEASUREMENT_MODE_FFT);
+
     for (uint32_t i = 0; i < nNumSamples; i++)
     {
-        ADI_SENSE_LOG_INFO("Sample # %2d Channel # %2d :: Raw %8d  :: Processed %.7f :: flags: %s %s",
-                           i+1,
-                           pSampleBuffer[i].channelId,
-                           pSampleBuffer[i].rawValue,
-                           pSampleBuffer[i].processedValue,
-                           pSampleBuffer[i].status & ADI_SENSE_DEVICE_STATUS_ERROR ? "ERROR" : "",
-                           pSampleBuffer[i].status & ADI_SENSE_DEVICE_STATUS_ALERT ? "ALERT" : "");
+        if (fftMode)
+        {
+            ADI_SENSE_LOG_INFO("Sample # %2d Channel # %2d :: Bin/Raw %8d  :: Magnitude %e :: flags:%s%s",
+                               i+1,
+                               pSampleBuffer[i].channelId,
+                               pSampleBuffer[i].rawValue,
+                               pSampleBuffer[i].processedValue,
+                               pSampleBuffer[i].status & ADI_SENSE_DEVICE_STATUS_ERROR ? " ERROR" : "",
+                               pSampleBuffer[i].status & ADI_SENSE_DEVICE_STATUS_ALERT ? " ALERT" : "");
+        }
+        else
+        {
+            ADI_SENSE_LOG_INFO("Sample # %2d Channel # %2d :: Raw %8d  :: Processed %f :: flags:%s%s",
+                               i+1,
+                               pSampleBuffer[i].channelId,
+                               pSampleBuffer[i].rawValue,
+                               pSampleBuffer[i].processedValue,
+                               pSampleBuffer[i].status & ADI_SENSE_DEVICE_STATUS_ERROR ? " ERROR" : "",
+                               pSampleBuffer[i].status & ADI_SENSE_DEVICE_STATUS_ALERT ? " ALERT" : "");
+        }
     }
 }
 
@@ -217,31 +223,30 @@
         return res;
 
     /*
-     * Retrieve the number of samples per cycle, per DATAREADY pulse, etc. for this configuration.
+     * Retrieve the number of samples per cycle, per DATAREADY pulse, etc. for
+     * this configuration.
      */
     ADI_SENSE_1000_OPERATING_MODE eOperatingMode;
     ADI_SENSE_1000_DATAREADY_MODE eDataReadyMode;
     uint32_t nSamplesPerDataready;
     uint32_t nSamplesPerCycle;
+    uint8_t nBytesPerSample;
     res = adi_sense_1000_GetDataReadyModeInfo(hDevice,
                                               eMeasurementMode,
                                               &eOperatingMode,
                                               &eDataReadyMode,
                                               &nSamplesPerDataready,
-                                              &nSamplesPerCycle);
+                                              &nSamplesPerCycle,
+                                              &nBytesPerSample);
     if (res != ADI_SENSE_SUCCESS)
         return res;
 
     /*
      * Allocate a buffer to store the samples retrieved on each DATAREADY pulse
-     * However, if the DATAREADY pulse is per-conversion, allocate a bigger buffer
-     * to accumulate a full cycle of samples before printing them
      */
     ADI_SENSE_DATA_SAMPLE *pSampleBuffer;
-    if (eDataReadyMode == ADI_SENSE_1000_DATAREADY_PER_CONVERSION)
-        pSampleBuffer = malloc(sizeof(ADI_SENSE_DATA_SAMPLE) * nSamplesPerCycle);
-    else
-        pSampleBuffer = malloc(sizeof(ADI_SENSE_DATA_SAMPLE) * nSamplesPerDataready);
+    pSampleBuffer = malloc(sizeof(ADI_SENSE_DATA_SAMPLE) *
+                           nSamplesPerDataready);
     if (pSampleBuffer == NULL)
     {
         ADI_SENSE_LOG_ERROR("Failed to allocate sample buffer");
@@ -261,53 +266,58 @@
     /*
      * Loop continuously unless operating mode is single-cycle
      */
-    do {
+    uint32_t nSampleCount = 0;
+    while (true)
+    {
         ADI_SENSE_STATUS status;
-        uint32_t nCurrentSamples;
         uint32_t nReturned;
-        nCurrentSamples = 0;
 
         /*
-         * Accumulate the samples from a cycle and print them
-         * NOTE: requires a sufficient idle time between cycles to allow printing to occur
+         * Wait until the next batch of 1 or more samples is ready, continuously
+         * checking DATAREADY until it is asserted
          */
-        do {
+        while (! (bDataReady || bError))
+            ;
+
+        if (!bError)
+        {
             /*
-             * Wait for the cycle to complete, continuously checking DATAREADY until it is asserted
+             * Get data samples from the measurement cycle, if no error has occurred
              */
-            while (! (bDataReady || bError))
-                ;
-
-            if (! bError)
+            bDataReady = false;
+            res = adi_sense_GetData(hDevice, eMeasurementMode, pSampleBuffer,
+                                    nBytesPerSample, nSamplesPerDataready,
+                                    &nReturned);
+            if (res != ADI_SENSE_SUCCESS)
             {
-                /*
-                 * Retrieve the data samples from the measurement cycle, if no error has occurred
-                 */
-                bDataReady = false;
-                res = adi_sense_GetData(hDevice, eMeasurementMode, &pSampleBuffer[nCurrentSamples], nSamplesPerDataready, &nReturned);
-                nCurrentSamples += nReturned;
-                if (res != ADI_SENSE_SUCCESS)
+                if (res == ADI_SENSE_INCOMPLETE)
                 {
-                    if (res == ADI_SENSE_INCOMPLETE)
-                    {
-                        /* For this case, let's get the device status and print
-                         * any samples we did get */
-                        ADI_SENSE_LOG_WARN("Failed to retrieve all requested data samples");
-                        break;
-                    }
-                    else
-                    {
-                        ADI_SENSE_LOG_WARN("Failed to retrieve data samples from device");
-                        return res;
-                    }
+                    /*
+                     * This is expected in cases where cycleSkipCount may
+                     * be non-zero for some channels, resulting in
+                     * variable-length sequences
+                     */
+                    ADI_SENSE_LOG_DEBUG("Retrieved %u of %u requested data samples",
+                                        nReturned, nSamplesPerDataready);
+                }
+                else
+                {
+                    ADI_SENSE_LOG_WARN("Failed to get data samples from device");
+                    return res;
                 }
             }
-        } while (!bError && (nCurrentSamples < nSamplesPerCycle));
 
-        /*
-         * Display the data samples
-         */
-        utils_printSamples(pSampleBuffer, nCurrentSamples);
+            /*
+             * Display the data samples.
+             *
+             * NOTE: this requires a sufficient idle time between subsequent
+             * DATAREADY pulses to allow printing to occur.  Otherwise,
+             * subsequent samples may be missed if not retrieved promptly when
+             * the next DATAREADY assertion occurs.
+             */
+            utils_printSamples(pSampleBuffer, nReturned, eMeasurementMode);
+            nSampleCount += nReturned;
+        }
 
         /*
          * Check and print device status if errors/alerts have been triggered
@@ -331,7 +341,34 @@
                     break;
             }
         }
-    } while (eOperatingMode != ADI_SENSE_1000_OPERATING_MODE_SINGLECYCLE);
+
+        if (eOperatingMode == ADI_SENSE_1000_OPERATING_MODE_SINGLECYCLE)
+        {
+            /*
+             * In this mode, break out of the loop when the measurement command
+             * has completed.
+             *
+             * One option is to check for the expected number of samples to be
+             * returned for the cycle.  However, cycles may have variable-length
+             * sequences if the cycleSkipCount option is non-zero for any of the
+             * channels.
+             *
+             * So, instead, we check for the command-running status, which
+             * will de-assert in this mode when the measurement command has
+             * completed a single cycle.
+             */
+            bool_t bCommandRunning;
+            res = adi_sense_GetCommandRunningState(hDevice, &bCommandRunning);
+            if (res != ADI_SENSE_SUCCESS)
+            {
+                ADI_SENSE_LOG_ERROR("Failed to get command-running status");
+                return res;
+            }
+
+            if (!bCommandRunning && !bDataReady)
+                break;
+        }
+    }
 
     res = adi_sense_StopMeasurement(hDevice);
     if (res != ADI_SENSE_SUCCESS)
@@ -348,4 +385,3 @@
 
     return ADI_SENSE_SUCCESS;
 }
-