Rohan Gurav
/
Sean_AdiSense1000_V21
ADISense1000 Version 2.1 code base
Fork of AdiSense1000_V21 by
common/utils.c
- Committer:
- Dan O'Donovan
- Date:
- 2018-03-26
- Branch:
- v2.0
- Revision:
- 27:567abf893938
- Parent:
- 16:e4f2689363bb
- Child:
- 29:57edca10d78c
File content as of revision 27:567abf893938:
#include <stdlib.h> #include "utils.h" #include "inc/adi_sense_log.h" void utils_printStatus( ADI_SENSE_STATUS *pStatus) { ADI_SENSE_LOG_INFO("Status Summary:"); if (pStatus->deviceStatus == 0) { ADI_SENSE_LOG_INFO("\tNo errors detected"); } else { if (pStatus->deviceStatus & ADI_SENSE_DEVICE_STATUS_BUSY) ADI_SENSE_LOG_INFO("\tCommand running"); if (pStatus->deviceStatus & ADI_SENSE_DEVICE_STATUS_DATAREADY) ADI_SENSE_LOG_INFO("\tData ready"); if (pStatus->deviceStatus & ADI_SENSE_DEVICE_STATUS_ERROR) ADI_SENSE_LOG_INFO("\tActive Errors - RESET REQUIRED"); if (pStatus->deviceStatus & ADI_SENSE_DEVICE_STATUS_FIFO_ERROR) ADI_SENSE_LOG_INFO("\tActive FIFO Errors - ATTENTION REQUIRED"); if (pStatus->deviceStatus & ADI_SENSE_DEVICE_STATUS_CONFIG_ERROR) 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_ERROR) { ADI_SENSE_LOG_INFO("\tActive Errors - ATTENTION REQUIRED"); ADI_SENSE_LOG_INFO("\t\tLast Error Code: %u (0x%X)", pStatus->errorCode, pStatus->errorCode); if (pStatus->diagnosticsStatus == 0) { ADI_SENSE_LOG_INFO("\t\tNo diagnostics faults detected"); } else { ADI_SENSE_LOG_INFO("\t\tActive diagnostics faults:"); if (pStatus->diagnosticsStatus & ADI_SENSE_DIAGNOSTICS_STATUS_CHECKSUM_ERROR) ADI_SENSE_LOG_INFO("\t\t\tInternal Checksum fault detected"); if (pStatus->diagnosticsStatus & ADI_SENSE_DIAGNOSTICS_STATUS_COMMS_ERROR) ADI_SENSE_LOG_INFO("\t\t\tInternal Communications fault detected"); if (pStatus->diagnosticsStatus & ADI_SENSE_DIAGNOSTICS_STATUS_SUPPLY_MONITOR_ERROR) 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) ADI_SENSE_LOG_INFO("\t\t\tInternal Device Calibrations fault detected"); } } if (pStatus->deviceStatus & ADI_SENSE_DEVICE_STATUS_ALERT) { ADI_SENSE_LOG_INFO("\tActive Alerts - ATTENTION REQUIRED:"); ADI_SENSE_LOG_INFO("\t\tLast Alert Code: %u (0x%X)", pStatus->alertCode, pStatus->alertCode); for (unsigned i = 0; i < ADI_SENSE_1000_MAX_CHANNELS; i++) { if (pStatus->channelAlerts[i] == 0) continue; ADI_SENSE_LOG_INFO("\t\tChannel #%u:", i); ADI_SENSE_LOG_INFO("\t\t\tLast Alert Code: %u (0x%X)", pStatus->channelAlertCodes[i], pStatus->channelAlertCodes[i]); if (pStatus->channelAlerts[i] & ADI_SENSE_CHANNEL_ALERT_TIMEOUT) ADI_SENSE_LOG_INFO("\t\t\tTimeout alert detected"); if (pStatus->channelAlerts[i] & ADI_SENSE_CHANNEL_ALERT_UNDER_RANGE) ADI_SENSE_LOG_INFO("\t\t\tUnder Range alert detected"); if (pStatus->channelAlerts[i] & ADI_SENSE_CHANNEL_ALERT_OVER_RANGE) ADI_SENSE_LOG_INFO("\t\t\tOver Range alert detected"); if (pStatus->channelAlerts[i] & ADI_SENSE_CHANNEL_ALERT_LOW_LIMIT) ADI_SENSE_LOG_INFO("\t\t\tLow limit alert detected"); if (pStatus->channelAlerts[i] & ADI_SENSE_CHANNEL_ALERT_HIGH_LIMIT) ADI_SENSE_LOG_INFO("\t\t\tHigh Limit alert detected"); if (pStatus->channelAlerts[i] & ADI_SENSE_CHANNEL_ALERT_SENSOR_OPEN) ADI_SENSE_LOG_INFO("\t\t\tSensor Fault alert detected"); if (pStatus->channelAlerts[i] & ADI_SENSE_CHANNEL_ALERT_REF_DETECT) ADI_SENSE_LOG_INFO("\t\t\tReference Detection alert detected"); if (pStatus->channelAlerts[i] & ADI_SENSE_CHANNEL_ALERT_CONFIG_ERR) ADI_SENSE_LOG_INFO("\t\t\tConfiguration Error alert detected"); if (pStatus->channelAlerts[i] & ADI_SENSE_CHANNEL_ALERT_LUT_ERR) ADI_SENSE_LOG_INFO("\t\t\tLook-Up Table Error alert detected"); if (pStatus->channelAlerts[i] & ADI_SENSE_CHANNEL_ALERT_SENSOR_NOT_READY) 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) ADI_SENSE_LOG_INFO("\t\t\tOver Look-Up Table Range alert detected"); } } } } void utils_printSamples( ADI_SENSE_DATA_SAMPLE *pSampleBuffer, uint32_t nNumSamples, ADI_SENSE_MEASUREMENT_MODE eMeasurementMode) { bool fftMode = (eMeasurementMode == ADI_SENSE_MEASUREMENT_MODE_FFT); for (uint32_t i = 0; i < nNumSamples; i++) { 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" : ""); } } } static void gpioCallbackFn(ADI_SENSE_GPIO_PIN ePinId, void * pArg) { volatile bool_t *pbFlag = (volatile bool_t *)pArg; *pbFlag = true; } ADI_SENSE_RESULT utils_registerCallbacks( ADI_SENSE_DEVICE_HANDLE hDevice, volatile bool_t *pbDataReady, volatile bool_t *pbError, volatile bool_t *pbAlert) { ADI_SENSE_RESULT res; res = adi_sense_RegisterGpioCallback(hDevice, ADI_SENSE_GPIO_PIN_DATAREADY, gpioCallbackFn, (void *)pbDataReady); if (res != ADI_SENSE_SUCCESS) { ADI_SENSE_LOG_ERROR("Failed to register DATAREADY callback"); return res; } res = adi_sense_RegisterGpioCallback(hDevice, ADI_SENSE_GPIO_PIN_ERROR, gpioCallbackFn, (void *)pbError); if (res != ADI_SENSE_SUCCESS) { ADI_SENSE_LOG_ERROR("Failed to register ERROR callback"); return res; } res = adi_sense_RegisterGpioCallback(hDevice, ADI_SENSE_GPIO_PIN_ALERT, gpioCallbackFn, (void *)pbAlert); if (res != ADI_SENSE_SUCCESS) { ADI_SENSE_LOG_ERROR("Failed to register ALERT callback"); return res; } return ADI_SENSE_SUCCESS; } ADI_SENSE_RESULT utils_deregisterCallbacks( ADI_SENSE_DEVICE_HANDLE hDevice) { ADI_SENSE_RESULT res; res = adi_sense_RegisterGpioCallback(hDevice, ADI_SENSE_GPIO_PIN_DATAREADY, NULL, NULL); if (res != ADI_SENSE_SUCCESS) { ADI_SENSE_LOG_ERROR("Failed to deregister DATAREADY callback"); return res; } res = adi_sense_RegisterGpioCallback(hDevice, ADI_SENSE_GPIO_PIN_ERROR, NULL, NULL); if (res != ADI_SENSE_SUCCESS) { ADI_SENSE_LOG_ERROR("Failed to deregister ERROR callback"); return res; } res = adi_sense_RegisterGpioCallback(hDevice, ADI_SENSE_GPIO_PIN_ALERT, NULL, NULL); if (res != ADI_SENSE_SUCCESS) { ADI_SENSE_LOG_INFO("Failed to deregister ALERT callback"); return res; } return ADI_SENSE_SUCCESS; } ADI_SENSE_RESULT utils_runMeasurement( ADI_SENSE_DEVICE_HANDLE hDevice, ADI_SENSE_MEASUREMENT_MODE eMeasurementMode) { ADI_SENSE_RESULT res; volatile bool_t bDataReady = false; volatile bool_t bError = false; volatile bool_t bAlert = false; res = utils_registerCallbacks(hDevice, &bDataReady, &bError, &bAlert); if (res != ADI_SENSE_SUCCESS) return res; /* * 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, &nBytesPerSample); if (res != ADI_SENSE_SUCCESS) return res; /* * Allocate a buffer to store the samples retrieved on each DATAREADY pulse */ ADI_SENSE_DATA_SAMPLE *pSampleBuffer; pSampleBuffer = malloc(sizeof(ADI_SENSE_DATA_SAMPLE) * nSamplesPerDataready); if (pSampleBuffer == NULL) { ADI_SENSE_LOG_ERROR("Failed to allocate sample buffer"); return ADI_SENSE_NO_MEM; } /* * Kick off the measurement cycle(s) here */ res = adi_sense_StartMeasurement(hDevice, eMeasurementMode); if (res != ADI_SENSE_SUCCESS) { ADI_SENSE_LOG_ERROR("Failed to start measurement"); return res; } /* * Loop continuously unless operating mode is single-cycle */ uint32_t nSampleCount = 0; while (true) { ADI_SENSE_STATUS status; uint32_t nReturned; /* * Wait until the next batch of 1 or more samples is ready, continuously * checking DATAREADY until it is asserted */ while (! (bDataReady || bError)) ; if (bError) break; /* * 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) { /* * 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; } } /* * 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 */ if (bError || bAlert) { res = adi_sense_GetStatus(hDevice, &status); if (res != ADI_SENSE_SUCCESS) { ADI_SENSE_LOG_ERROR("Failed to retrieve device status"); return res; } if (status.deviceStatus & (ADI_SENSE_DEVICE_STATUS_ERROR | ADI_SENSE_DEVICE_STATUS_ALERT)) { utils_printStatus(&status); /* Break out of the loop if any errors are raised */ if (bError) break; } } 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) { ADI_SENSE_LOG_ERROR("Failed to send stop measurement"); return res; } free(pSampleBuffer); res = utils_deregisterCallbacks(hDevice); if (res != ADI_SENSE_SUCCESS) return res; return ADI_SENSE_SUCCESS; }