ADISense1000 Version 2.1 code base

Fork of AdiSense1000_V21 by Sean Wilson

Branch:
v2.0
Revision:
27:567abf893938
Parent:
16:e4f2689363bb
Child:
29:57edca10d78c
--- a/common/utils.c	Mon Mar 26 14:50:05 2018 +0000
+++ b/common/utils.c	Mon Mar 26 20:28:05 2018 +0100
@@ -116,17 +116,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 +233,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 +276,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 {
-            /*
-             * Wait for the cycle to complete, continuously checking DATAREADY until it is asserted
-             */
-            while (! (bDataReady || bError))
-                ;
+        while (! (bDataReady || bError))
+            ;
+
+        if (bError)
+            break;
 
-            if (! bError)
+        /*
+         * Get data samples from the measurement cycle, if no error has occurred
+         */
+        bDataReady = false;
+        res = adi_sense_GetData(hDevice, eMeasurementMode, pSampleBuffer,
+                                nBytesPerSample, nSamplesPerDataready,
+                                &nReturned);
+        if (res != ADI_SENSE_SUCCESS)
+        {
+            if (res == ADI_SENSE_INCOMPLETE)
             {
                 /*
-                 * Retrieve the data samples from the measurement cycle, if no error has occurred
+                 * This is expected in cases where cycleSkipCount may
+                 * be non-zero for some channels, resulting in
+                 * variable-length sequences
                  */
-                bDataReady = false;
-                res = adi_sense_GetData(hDevice, eMeasurementMode, &pSampleBuffer[nCurrentSamples], nSamplesPerDataready, &nReturned);
-                nCurrentSamples += nReturned;
-                if (res != ADI_SENSE_SUCCESS)
-                {
-                    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;
-                    }
-                }
+                ADI_SENSE_LOG_DEBUG("Retrieved %u of %u requested data samples",
+                                    nReturned, nSamplesPerDataready);
             }
-        } while (!bError && (nCurrentSamples < nSamplesPerCycle));
+            else
+            {
+                ADI_SENSE_LOG_WARN("Failed to get data samples from device");
+                return res;
+            }
+        }
 
         /*
-         * Display the data samples
+         * 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, nCurrentSamples);
+        utils_printSamples(pSampleBuffer, nReturned, eMeasurementMode);
+        nSampleCount += nReturned;
 
         /*
          * Check and print device status if errors/alerts have been triggered
@@ -331,7 +351,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 +395,3 @@
 
     return ADI_SENSE_SUCCESS;
 }
-