Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
common/utils.c
- Committer:
- Vkadaba
- Date:
- 2019-06-15
- Revision:
- 6:9d393a9677f4
- Parent:
- 5:0728bde67bdb
- Child:
- 10:14954555be2a
File content as of revision 6:9d393a9677f4:
#include <stdlib.h>
#include "utils.h"
#include "admw_log.h"
void utils_printStatus(
ADMW_STATUS *pStatus)
{
ADMW_LOG_INFO("Status Summary:");
if (pStatus->deviceStatus == 0)
{
ADMW_LOG_INFO("\tNo errors detected");
}
else
{
if (pStatus->deviceStatus & ADMW_DEVICE_STATUS_BUSY)
ADMW_LOG_INFO("\tCommand running");
if (pStatus->deviceStatus & ADMW_DEVICE_STATUS_DATAREADY)
ADMW_LOG_INFO("\tData ready");
if (pStatus->deviceStatus & ADMW_DEVICE_STATUS_ERROR)
ADMW_LOG_INFO("\tActive Errors - RESET REQUIRED");
if (pStatus->deviceStatus & ADMW_DEVICE_STATUS_FIFO_ERROR)
ADMW_LOG_INFO("\tActive FIFO Errors - ATTENTION REQUIRED");
if (pStatus->deviceStatus & ADMW_DEVICE_STATUS_CONFIG_ERROR)
ADMW_LOG_INFO("\tActive Configuration Errors - ATTENTION REQUIRED");
if (pStatus->deviceStatus & ADMW_DEVICE_STATUS_LUT_ERROR)
ADMW_LOG_INFO("\tActive Look-Up Table Errors - ATTENTION REQUIRED");
if (pStatus->deviceStatus & ADMW_DEVICE_STATUS_ERROR)
{
ADMW_LOG_INFO("\tActive Errors - ATTENTION REQUIRED");
ADMW_LOG_INFO("\t\tLast Error Code: %u (0x%X)",
pStatus->errorCode, pStatus->errorCode);
if (pStatus->diagnosticsStatus == 0)
{
ADMW_LOG_INFO("\t\tNo diagnostics faults detected");
}
else
{
ADMW_LOG_INFO("\t\tActive diagnostics faults:");
if (pStatus->diagnosticsStatus & ADMW_DIAGNOSTICS_STATUS_CHECKSUM_ERROR)
ADMW_LOG_INFO("\t\t\tInternal Checksum fault detected");
if (pStatus->diagnosticsStatus & ADMW_DIAGNOSTICS_STATUS_CONVERSION_ERROR)
ADMW_LOG_INFO("\t\t\tInternal ADC Conversions fault detected");
if (pStatus->diagnosticsStatus & ADMW_DIAGNOSTICS_STATUS_CALIBRATION_ERROR)
ADMW_LOG_INFO("\t\t\tInternal Device Calibrations fault detected");
}
}
if (pStatus->deviceStatus & ADMW_DEVICE_STATUS_ALERT)
{
ADMW_LOG_INFO("\tActive Alerts - ATTENTION REQUIRED:");
ADMW_LOG_INFO("\t\tLast Alert Code: %u (0x%X)",
pStatus->alertCode, pStatus->alertCode);
for (unsigned i = 0; i < ADMW1001_MAX_CHANNELS; i++)
{
if (pStatus->channelAlerts[i] == 0)
continue;
ADMW_LOG_INFO("\t\tChannel #%u:", i);
ADMW_LOG_INFO("\t\t\tLast Alert Code: %u (0x%X)",
pStatus->channelAlertCodes[i],
pStatus->channelAlertCodes[i]);
if (pStatus->channelAlerts[i] & ADMW_CHANNEL_ALERT_TIMEOUT)
ADMW_LOG_INFO("\t\t\tTimeout alert detected");
if (pStatus->channelAlerts[i] & ADMW_CHANNEL_ALERT_UNDER_RANGE)
ADMW_LOG_INFO("\t\t\tUnder Range alert detected");
if (pStatus->channelAlerts[i] & ADMW_CHANNEL_ALERT_OVER_RANGE)
ADMW_LOG_INFO("\t\t\tOver Range alert detected");
if (pStatus->channelAlerts[i] & ADMW_CHANNEL_ALERT_LOW_LIMIT)
ADMW_LOG_INFO("\t\t\tLow limit alert detected");
if (pStatus->channelAlerts[i] & ADMW_CHANNEL_ALERT_HIGH_LIMIT)
ADMW_LOG_INFO("\t\t\tHigh Limit alert detected");
if (pStatus->channelAlerts[i] & ADMW_CHANNEL_ALERT_SENSOR_OPEN)
ADMW_LOG_INFO("\t\t\tSensor Fault alert detected");
if (pStatus->channelAlerts[i] & ADMW_CHANNEL_ALERT_REF_DETECT)
ADMW_LOG_INFO("\t\t\tReference Detection alert detected");
if (pStatus->channelAlerts[i] & ADMW_CHANNEL_ALERT_CONFIG_ERR)
ADMW_LOG_INFO("\t\t\tConfiguration Error alert detected");
if (pStatus->channelAlerts[i] & ADMW_CHANNEL_ALERT_LUT_ERR)
ADMW_LOG_INFO("\t\t\tLook-Up Table Error alert detected");
if (pStatus->channelAlerts[i] & ADMW_CHANNEL_ALERT_SENSOR_NOT_READY)
ADMW_LOG_INFO("\t\t\tSensor Not Ready alert detected");
if (pStatus->channelAlerts[i] & ADMW_CHANNEL_ALERT_COMP_NOT_READY)
ADMW_LOG_INFO("\t\t\tCompensation Channel Not Ready alert detected");
if (pStatus->channelAlerts[i] & ADMW_CHANNEL_ALERT_LUT_UNDER_RANGE)
ADMW_LOG_INFO("\t\t\tUnder Look-Up Table Range alert detected");
if (pStatus->channelAlerts[i] & ADMW_CHANNEL_ALERT_LUT_OVER_RANGE)
ADMW_LOG_INFO("\t\t\tOver Look-Up Table Range alert detected");
}
}
if ((pStatus->deviceStatus & ADMW_DEVICE_STATUS_ERROR) ||
(pStatus->deviceStatus & ADMW_DEVICE_STATUS_ALERT))
{
ADMW_LOG_INFO("\t\tLast Debug Code: %u-%u",
(pStatus->debugCode >> 16) & 0xFFFF,
(pStatus->debugCode >> 0) & 0xFFFF);
}
}
}
void utils_printSamples(
ADMW_DATA_SAMPLE *pSampleBuffer,
uint32_t nNumSamples,
ADMW_MEASUREMENT_MODE eMeasurementMode)
{
}
static void gpioCallbackFn(ADMW_GPIO_PIN ePinId, void * pArg)
{
volatile bool *pbFlag = (volatile bool *)pArg;
*pbFlag = true;
}
ADMW_RESULT utils_registerCallbacks(
ADMW_DEVICE_HANDLE hDevice,
volatile bool *pbDataReady,
volatile bool *pbError,
volatile bool *pbAlert)
{
ADMW_RESULT res;
bool state;
res = admw_RegisterGpioCallback(hDevice, ADMW_GPIO_PIN_DATAREADY,
gpioCallbackFn, (void *)pbDataReady);
if (res != ADMW_SUCCESS)
{
ADMW_LOG_ERROR("Failed to register DATAREADY callback");
return res;
}
res = admw_GetGpioState(hDevice, ADMW_GPIO_PIN_ALERT_ERROR, &state);
if (res != ADMW_SUCCESS)
{
ADMW_LOG_ERROR("Failed to get current ERROR state");
return res;
}
if (state)
{
ADMW_LOG_ERROR("ERROR signal already asserted");
return ADMW_FAILURE;
}
res = admw_RegisterGpioCallback(hDevice, ADMW_GPIO_PIN_ALERT_ERROR,
gpioCallbackFn, (void *)pbError);
if (res != ADMW_SUCCESS)
{
ADMW_LOG_ERROR("Failed to register ERROR callback");
return res;
}
/*res = admw_GetGpioState(hDevice, ADMW_GPIO_PIN_ALERT, &state);
if (res != ADMW_SUCCESS)
{
ADMW_LOG_ERROR("Failed to get current ALERT state");
return res;
}
if (state)
{
ADMW_LOG_ERROR("ALERT signal already asserted");
return ADMW_FAILURE;
}*/
res = admw_RegisterGpioCallback(hDevice, ADMW_GPIO_PIN_ALERT_ERROR,
gpioCallbackFn, (void *)pbAlert);
if (res != ADMW_SUCCESS)
{
ADMW_LOG_ERROR("Failed to register ALERT callback");
return res;
}
return ADMW_SUCCESS;
}
ADMW_RESULT utils_deregisterCallbacks(
ADMW_DEVICE_HANDLE hDevice)
{
ADMW_RESULT res;
res = admw_RegisterGpioCallback(hDevice, ADMW_GPIO_PIN_DATAREADY,
NULL, NULL);
if (res != ADMW_SUCCESS)
{
ADMW_LOG_ERROR("Failed to deregister DATAREADY callback");
return res;
}
res = admw_RegisterGpioCallback(hDevice, ADMW_GPIO_PIN_ALERT_ERROR,
NULL, NULL);
if (res != ADMW_SUCCESS)
{
ADMW_LOG_ERROR("Failed to deregister ERROR callback");
return res;
}
res = admw_RegisterGpioCallback(hDevice, ADMW_GPIO_PIN_ALERT_ERROR,
NULL, NULL);
if (res != ADMW_SUCCESS)
{
ADMW_LOG_INFO("Failed to deregister ALERT callback");
return res;
}
return ADMW_SUCCESS;
}
ADMW_RESULT utils_runMeasurement(
ADMW_DEVICE_HANDLE hDevice,
ADMW_MEASUREMENT_MODE eMeasurementMode)
{
ADMW_RESULT res;
volatile bool bDataReady = false;
volatile bool bError = false;
volatile bool bAlert = false;
res = utils_registerCallbacks(hDevice, &bDataReady, &bError, &bAlert);
if (res != ADMW_SUCCESS)
return res;
/*
* Retrieve the number of samples per cycle, per DATAREADY pulse, etc. for
* this configuration.
*/
ADMW1001_OPERATING_MODE eOperatingMode;
ADMW1001_DATAREADY_MODE eDataReadyMode;
uint32_t nSamplesPerDataready;
uint32_t nSamplesPerCycle;
uint8_t nBytesPerSample;
res = admw1001_GetDataReadyModeInfo(hDevice,
eMeasurementMode,
&eOperatingMode,
&eDataReadyMode,
&nSamplesPerDataready,
&nSamplesPerCycle,
&nBytesPerSample);
if (res != ADMW_SUCCESS)
return res;
/*
* Allocate a buffer to store the samples retrieved on each DATAREADY pulse
*/
ADMW_DATA_SAMPLE *pSampleBuffer;
pSampleBuffer = malloc(sizeof(ADMW_DATA_SAMPLE) *
nSamplesPerDataready);
if (pSampleBuffer == NULL)
{
ADMW_LOG_ERROR("Failed to allocate sample buffer");
return ADMW_NO_MEM;
}
/*
* Kick off the measurement cycle(s) here
*/
ADMW_LOG_INFO("Starting measurement");
res = admw_StartMeasurement(hDevice, eMeasurementMode);
if (res != ADMW_SUCCESS)
{
ADMW_LOG_ERROR("Failed to start measurement");
return res;
}
/*
* Loop continuously unless operating mode is single-cycle
*/
uint32_t nSampleCount = 0;
uint32_t nReturned;
while (true)
{
ADMW_STATUS status;
/*
* Wait until the next batch of 1 or more samples is ready, continuously
* checking DATAREADY until it is asserted
*/
while (! (bDataReady || bError))
;
if (!bError)
{
/*
* Get data samples from the measurement cycle, if no error has occurred
*/
bDataReady = false;
res = admw_GetData(hDevice, eMeasurementMode, pSampleBuffer,
nBytesPerSample, nSamplesPerDataready,
&nReturned);
if (res != ADMW_SUCCESS)
{
if (res == ADMW_INCOMPLETE)
{
/*
* This is expected in cases where cycleSkipCount may
* be non-zero for some channels, resulting in
* variable-length sequences
*/
ADMW_LOG_DEBUG("Retrieved %u of %u requested data samples",
nReturned, nSamplesPerDataready);
}
else
{
ADMW_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 = admw_GetStatus(hDevice, &status);
if (res != ADMW_SUCCESS)
{
ADMW_LOG_ERROR("Failed to retrieve device status");
return res;
}
if (status.deviceStatus &
(ADMW_DEVICE_STATUS_ERROR | ADMW_DEVICE_STATUS_ALERT))
{
utils_printStatus(&status);
/* Break out of the loop if any errors are raised */
if (bError)
break;
}
}
if (eOperatingMode == ADMW1001_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 bCommandRunning;
res = admw_GetCommandRunningState(hDevice, &bCommandRunning);
if (res != ADMW_SUCCESS)
{
ADMW_LOG_ERROR("Failed to get command-running status");
return res;
}
if (!bCommandRunning && !bDataReady)
break;
}
}
ADMW_LOG_INFO("Stopping measurement");
res = admw_StopMeasurement(hDevice);
if (res != ADMW_SUCCESS)
{
ADMW_LOG_ERROR("Failed to send stop measurement");
return res;
}
free(pSampleBuffer);
res = utils_deregisterCallbacks(hDevice);
if (res != ADMW_SUCCESS)
return res;
return ADMW_SUCCESS;
}