(Working) Code to interface 3 LoadCells to ADISense1000 and display values using the Labview code.

Fork of 4Bridge_ADISense1000_Example_copy by CAC_smartcushion

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers adi_sense_1000.c Source File

adi_sense_1000.c

Go to the documentation of this file.
00001 /*!
00002  ******************************************************************************
00003  * @file:  adi_sense_1000.c
00004  * @brief: ADI Sense API implementation for ADI Sense 1000
00005  *-----------------------------------------------------------------------------
00006  */
00007 
00008 /******************************************************************************
00009 Copyright 2017 (c) Analog Devices, Inc.
00010 
00011 All rights reserved.
00012 
00013 Redistribution and use in source and binary forms, with or without
00014 modification, are permitted provided that the following conditions are met:
00015   - Redistributions of source code must retain the above copyright
00016     notice, this list of conditions and the following disclaimer.
00017   - Redistributions in binary form must reproduce the above copyright
00018     notice, this list of conditions and the following disclaimer in
00019     the documentation and/or other materials provided with the
00020     distribution.
00021   - Neither the name of Analog Devices, Inc. nor the names of its
00022     contributors may be used to endorse or promote products derived
00023     from this software without specific prior written permission.
00024   - The use of this software may or may not infringe the patent rights
00025     of one or more patent holders. This license does not release you
00026     from the requirement that you obtain separate licenses from these
00027     patent holders to use this software.
00028   - Use of the software either in source or binary form, must be run
00029     on or directly connected to an Analog Devices Inc. component.
00030 
00031 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
00032 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
00033 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00034 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
00035 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00036 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
00037 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00038 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00039 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00040 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00041  *
00042  *****************************************************************************/
00043 #include <float.h>
00044 #include <math.h>
00045 #include <string.h>
00046 
00047 #include "inc/adi_sense_platform.h"
00048 #include "inc/adi_sense_api.h"
00049 #include "inc/adi_sense_1000/adi_sense_1000_api.h"
00050 
00051 #include "adi_sense_1000/ADISENSE1000_REGISTERS_typedefs.h"
00052 #include "adi_sense_1000/ADISENSE1000_REGISTERS.h"
00053 #include "adi_sense_1000/adi_sense_1000_lut_data.h"
00054 #include "adi_sense_1000/adi_sense_1000_calibration.h"
00055 
00056 #include "crc16.h"
00057 
00058 /*
00059  * The host is expected to transfer a 16-bit command, followed by data bytes, in 2
00060  * separate transfers delineated by the CS signal and a short delay in between.
00061  *
00062  * The 16-bit command contains a right-justified 11-bit register address (offset),
00063  * and the remaining upper 5 bits are reserved as command bits assigned as follows:
00064  * [15:11] 10000b = write command, 01000b = read command, anything else is invalid
00065  * [10:0]  register address (0-2047)
00066  */
00067 
00068 /* Register address space is limited to 2048 bytes (11 bit address) */
00069 #define REG_COMMAND_MASK 0xF800
00070 #define REG_ADDRESS_MASK 0x07FF
00071 
00072 /*
00073  * The following commands are currently supported, anything else is treated
00074  * as an error
00075  */
00076 #define REG_WRITE_COMMAND 0x8000
00077 #define REG_READ_COMMAND  0x4000
00078 
00079 /*
00080  * The following bytes are sent back to the host when a command is recieved,
00081  * to be used by the host to verify that we were ready to receive the command.
00082  */
00083 #define REG_COMMAND_RESP_0 0xF0
00084 #define REG_COMMAND_RESP_1 0xE1
00085 
00086 /*
00087  * The following minimum delay must be inserted after each SPI transfer to allow
00088  * time for it to be processed by the device
00089  */
00090 #define POST_SPI_TRANSFER_DELAY_USEC (20)
00091 
00092 /*
00093  * The following macros are used to encapsulate the register access code
00094  * to improve readability in the functions further below in this file
00095  */
00096 #define STRINGIFY(name) #name
00097 
00098 /* Expand the full name of the reset value macro for the specified register */
00099 #define REG_RESET_VAL(_name) REG_ADISENSE_##_name##_RESET
00100 
00101 /* Checks if a value is outside the bounds of the specified register field */
00102 #define CHECK_REG_FIELD_VAL(_field, _val)                               \
00103     do {                                                                \
00104         uint32_t _mask  = BITM_ADISENSE_##_field;                       \
00105         uint32_t _shift = BITP_ADISENSE_##_field;                       \
00106         if ((((_val) << _shift) & ~(_mask)) != 0) {                     \
00107             ADI_SENSE_LOG_ERROR("Value 0x%08X invalid for register field %s", \
00108                                 (uint32_t)(_val),                       \
00109                                 STRINGIFY(ADISENSE_##_field));          \
00110             return ADI_SENSE_INVALID_PARAM;                             \
00111         }                                                               \
00112     } while(false)
00113 
00114 /*
00115  * Encapsulates the write to a specified register
00116  * NOTE - this will cause the calling function to return on error
00117  */
00118 #define WRITE_REG(_hdev, _val, _name, _type)                            \
00119     do {                                                                \
00120         ADI_SENSE_RESULT _res;                                          \
00121         _type _regval = _val;                                           \
00122         _res = adi_sense_1000_WriteRegister((_hdev),                    \
00123                                             REG_ADISENSE_##_name,       \
00124                                             &_regval, sizeof(_regval)); \
00125         if (_res != ADI_SENSE_SUCCESS)                                  \
00126             return _res;                                                \
00127     } while(false)
00128 
00129 /* Wrapper macro to write a value to a uint32_t register */
00130 #define WRITE_REG_U32(_hdev, _val, _name)       \
00131     WRITE_REG(_hdev, _val, _name, uint32_t)
00132 /* Wrapper macro to write a value to a uint16_t register */
00133 #define WRITE_REG_U16(_hdev, _val, _name)       \
00134     WRITE_REG(_hdev, _val, _name, uint16_t)
00135 /* Wrapper macro to write a value to a uint8_t register */
00136 #define WRITE_REG_U8(_hdev, _val, _name)        \
00137     WRITE_REG(_hdev, _val, _name, uint8_t)
00138 /* Wrapper macro to write a value to a float32_t register */
00139 #define WRITE_REG_FLOAT(_hdev, _val, _name)     \
00140     WRITE_REG(_hdev, _val, _name, float32_t)
00141 
00142 /*
00143  * Encapsulates the read from a specified register
00144  * NOTE - this will cause the calling function to return on error
00145  */
00146 #define READ_REG(_hdev, _val, _name, _type)                             \
00147     do {                                                                \
00148         ADI_SENSE_RESULT _res;                                          \
00149         _type _regval;                                                  \
00150         _res = adi_sense_1000_ReadRegister((_hdev),                     \
00151                                            REG_ADISENSE_##_name,        \
00152                                            &_regval, sizeof(_regval));  \
00153         if (_res != ADI_SENSE_SUCCESS)                                  \
00154             return _res;                                                \
00155         _val = _regval;                                                 \
00156     } while(false)
00157 
00158 /* Wrapper macro to read a value from a uint32_t register */
00159 #define READ_REG_U32(_hdev, _val, _name)        \
00160     READ_REG(_hdev, _val, _name, uint32_t)
00161 /* Wrapper macro to read a value from a uint16_t register */
00162 #define READ_REG_U16(_hdev, _val, _name)        \
00163     READ_REG(_hdev, _val, _name, uint16_t)
00164 /* Wrapper macro to read a value from a uint8_t register */
00165 #define READ_REG_U8(_hdev, _val, _name)         \
00166     READ_REG(_hdev, _val, _name, uint8_t)
00167 /* Wrapper macro to read a value from a float32_t register */
00168 #define READ_REG_FLOAT(_hdev, _val, _name)      \
00169     READ_REG(_hdev, _val, _name, float32_t)
00170 
00171 /*
00172  * Wrapper macro to write an array of values to a uint8_t register
00173  * NOTE - this is intended only for writing to a keyhole data register
00174  */
00175 #define WRITE_REG_U8_ARRAY(_hdev, _arr, _len, _name)                \
00176     do {                                                            \
00177         ADI_SENSE_RESULT _res;                                      \
00178         _res = adi_sense_1000_WriteRegister(_hdev,                  \
00179                                             REG_ADISENSE_##_name,   \
00180                                             _arr, _len);            \
00181         if (_res != ADI_SENSE_SUCCESS)                              \
00182             return _res;                                            \
00183     } while(false)
00184 
00185 /*
00186  * Wrapper macro to read an array of values from a uint8_t register
00187  * NOTE - this is intended only for reading from a keyhole data register
00188  */
00189 #define READ_REG_U8_ARRAY(_hdev, _arr, _len, _name)                 \
00190     do {                                                            \
00191         ADI_SENSE_RESULT _res;                                      \
00192         _res = adi_sense_1000_ReadRegister((_hdev),                 \
00193                                            REG_ADISENSE_##_name,    \
00194                                            _arr, _len);             \
00195         if (_res != ADI_SENSE_SUCCESS)                              \
00196             return _res;                                            \
00197     } while(false)
00198 
00199 #define ADI_SENSE_1000_CHANNEL_IS_ADC(c)                                \
00200     ((c) >= ADI_SENSE_1000_CHANNEL_ID_CJC_0 && (c) <= ADI_SENSE_1000_CHANNEL_ID_CURRENT_0)
00201 
00202 #define ADI_SENSE_1000_CHANNEL_IS_ADC_CJC(c)                            \
00203     ((c) >= ADI_SENSE_1000_CHANNEL_ID_CJC_0 && (c) <= ADI_SENSE_1000_CHANNEL_ID_CJC_1)
00204 
00205 #define ADI_SENSE_1000_CHANNEL_IS_ADC_SENSOR(c)                         \
00206     ((c) >= ADI_SENSE_1000_CHANNEL_ID_SENSOR_0 && (c) <= ADI_SENSE_1000_CHANNEL_ID_SENSOR_3)
00207 
00208 #define ADI_SENSE_1000_CHANNEL_IS_ADC_VOLTAGE(c)    \
00209     ((c) == ADI_SENSE_1000_CHANNEL_ID_VOLTAGE_0)
00210 
00211 #define ADI_SENSE_1000_CHANNEL_IS_ADC_CURRENT(c)    \
00212     ((c) == ADI_SENSE_1000_CHANNEL_ID_CURRENT_0)
00213 
00214 #define ADI_SENSE_1000_CHANNEL_IS_VIRTUAL(c)                            \
00215     ((c) == ADI_SENSE_1000_CHANNEL_ID_SPI_1 || (c) == ADI_SENSE_1000_CHANNEL_ID_SPI_2)
00216 
00217 typedef struct
00218 {
00219     unsigned nDeviceIndex;
00220     ADI_SENSE_SPI_HANDLE  hSpi;
00221     ADI_SENSE_GPIO_HANDLE  hGpio;
00222 } ADI_SENSE_DEVICE_CONTEXT;
00223 
00224 static ADI_SENSE_DEVICE_CONTEXT gDeviceCtx[ADI_SENSE_PLATFORM_MAX_DEVICES];
00225 
00226 /*
00227  * Open an ADI Sense device instance.
00228  */
00229 ADI_SENSE_RESULT  adi_sense_Open(
00230     unsigned                   const nDeviceIndex,
00231     ADI_SENSE_CONNECTION      * const pConnectionInfo,
00232     ADI_SENSE_DEVICE_HANDLE   * const phDevice)
00233 {
00234     ADI_SENSE_DEVICE_CONTEXT *pCtx;
00235     ADI_SENSE_RESULT  eRet;
00236 
00237     if (nDeviceIndex >= ADI_SENSE_PLATFORM_MAX_DEVICES)
00238         return ADI_SENSE_INVALID_DEVICE_NUM ;
00239 
00240     pCtx = &gDeviceCtx[nDeviceIndex];
00241     pCtx->nDeviceIndex = nDeviceIndex;
00242 
00243     eRet = adi_sense_LogOpen();
00244     if (eRet != ADI_SENSE_SUCCESS )
00245         return eRet;
00246 
00247     eRet = adi_sense_GpioOpen(&pConnectionInfo->gpio , &pCtx->hGpio);
00248     if (eRet != ADI_SENSE_SUCCESS )
00249         return eRet;
00250 
00251     eRet = adi_sense_SpiOpen(&pConnectionInfo->spi , &pCtx->hSpi);
00252     if (eRet != ADI_SENSE_SUCCESS )
00253         return eRet;
00254 
00255     *phDevice = pCtx;
00256     return ADI_SENSE_SUCCESS ;
00257 }
00258 
00259 /*
00260  * Get the current state of the specified GPIO input signal.
00261  */
00262 ADI_SENSE_RESULT  adi_sense_GetGpioState(
00263     ADI_SENSE_DEVICE_HANDLE    const hDevice,
00264     ADI_SENSE_GPIO_PIN         const ePinId,
00265     bool_t                  * const pbAsserted)
00266 {
00267     ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
00268 
00269     return adi_sense_GpioGet(pCtx->hGpio, ePinId, pbAsserted);
00270 }
00271 
00272 /*
00273  * Register an application-defined callback function for GPIO interrupts.
00274  */
00275 ADI_SENSE_RESULT  adi_sense_RegisterGpioCallback(
00276     ADI_SENSE_DEVICE_HANDLE           const hDevice,
00277     ADI_SENSE_GPIO_PIN                const ePinId,
00278     ADI_SENSE_GPIO_CALLBACK           const callbackFunction,
00279     void                           * const pCallbackParam)
00280 {
00281     ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
00282 
00283     if (callbackFunction)
00284     {
00285         return adi_sense_GpioIrqEnable(pCtx->hGpio, ePinId, callbackFunction,
00286                                        pCallbackParam);
00287     }
00288     else
00289     {
00290         return adi_sense_GpioIrqDisable(pCtx->hGpio, ePinId);
00291     }
00292 }
00293 
00294 /*
00295  * Reset the specified ADI Sense device.
00296  */
00297 ADI_SENSE_RESULT  adi_sense_Reset(
00298     ADI_SENSE_DEVICE_HANDLE     const hDevice)
00299 {
00300     ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
00301     ADI_SENSE_RESULT  eRet;
00302 
00303     /* Pulse the Reset GPIO pin low for a minimum of 4 microseconds */
00304     eRet = adi_sense_GpioSet(pCtx->hGpio, ADI_SENSE_GPIO_PIN_RESET , false);
00305     if (eRet != ADI_SENSE_SUCCESS )
00306         return eRet;
00307 
00308     adi_sense_TimeDelayUsec(4);
00309 
00310     eRet = adi_sense_GpioSet(pCtx->hGpio, ADI_SENSE_GPIO_PIN_RESET , true);
00311     if (eRet != ADI_SENSE_SUCCESS )
00312         return eRet;
00313 
00314     return ADI_SENSE_SUCCESS ;
00315 }
00316 
00317 
00318 /*!
00319  * @brief Get general status of ADISense module.
00320  *
00321  * @param[in]
00322  * @param[out] pStatus : Pointer to CORE Status struct.
00323  *
00324  * @return Status
00325  *         - #ADI_SENSE_SUCCESS Call completed successfully.
00326  *         - #ADI_SENSE_FAILURE If status register read fails.
00327  *
00328  * @details Read the general status register for the ADISense
00329  *          module. Indicates Error, Alert conditions, data ready
00330  *          and command running.
00331  *
00332  */
00333 ADI_SENSE_RESULT  adi_sense_GetStatus(
00334     ADI_SENSE_DEVICE_HANDLE     const hDevice,
00335     ADI_SENSE_STATUS          * const pStatus)
00336 {
00337     ADI_ADISENSE_CORE_Status_t statusReg;
00338     READ_REG_U8(hDevice, statusReg.VALUE8, CORE_STATUS);
00339 
00340     memset(pStatus, 0, sizeof(*pStatus));
00341 
00342     if (!statusReg.Cmd_Running) /* Active-low, so invert it */
00343         pStatus->deviceStatus  |= ADI_SENSE_DEVICE_STATUS_BUSY ;
00344     if (statusReg.Drdy)
00345         pStatus->deviceStatus  |= ADI_SENSE_DEVICE_STATUS_DATAREADY ;
00346     if (statusReg.FIFO_Error)
00347         pStatus->deviceStatus  |= ADI_SENSE_DEVICE_STATUS_FIFO_ERROR ;
00348     if (statusReg.Alert_Active)
00349     {
00350         pStatus->deviceStatus  |= ADI_SENSE_DEVICE_STATUS_ALERT ;
00351 
00352         ADI_ADISENSE_CORE_Alert_Code_t alertCodeReg;
00353         READ_REG_U16(hDevice, alertCodeReg.VALUE16, CORE_ALERT_CODE);
00354         pStatus->alertCode  = alertCodeReg.Alert_Code;
00355 
00356         ADI_ADISENSE_CORE_Channel_Alert_Status_t channelAlertStatusReg;
00357         READ_REG_U16(hDevice, channelAlertStatusReg.VALUE16,
00358                      CORE_CHANNEL_ALERT_STATUS);
00359 
00360         for (unsigned i = 0; i < ADI_SENSE_1000_MAX_CHANNELS ; i++)
00361         {
00362             if (channelAlertStatusReg.VALUE16 & (1 << i))
00363             {
00364                 ADI_ADISENSE_CORE_Alert_Code_Ch_t channelAlertCodeReg;
00365                 READ_REG_U16(hDevice, channelAlertCodeReg.VALUE16, CORE_ALERT_CODE_CHn(i));
00366                 pStatus->channelAlertCodes [i] = channelAlertCodeReg.Alert_Code_Ch;
00367 
00368                 ADI_ADISENSE_CORE_Alert_Detail_Ch_t alertDetailReg;
00369                 READ_REG_U16(hDevice, alertDetailReg.VALUE16,
00370                              CORE_ALERT_DETAIL_CHn(i));
00371 
00372                 if (alertDetailReg.Time_Out)
00373                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_TIMEOUT ;
00374                 if (alertDetailReg.Under_Range)
00375                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_UNDER_RANGE ;
00376                 if (alertDetailReg.Over_Range)
00377                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_OVER_RANGE ;
00378                 if (alertDetailReg.Low_Limit)
00379                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_LOW_LIMIT ;
00380                 if (alertDetailReg.High_Limit)
00381                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_HIGH_LIMIT ;
00382                 if (alertDetailReg.Sensor_Open)
00383                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_SENSOR_OPEN ;
00384                 if (alertDetailReg.Ref_Detect)
00385                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_REF_DETECT ;
00386                 if (alertDetailReg.Config_Err)
00387                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_CONFIG_ERR ;
00388                 if (alertDetailReg.LUT_Error_Ch)
00389                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_LUT_ERR ;
00390                 if (alertDetailReg.Sensor_Not_Ready)
00391                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_SENSOR_NOT_READY ;
00392                 if (alertDetailReg.Comp_Not_Ready)
00393                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_COMP_NOT_READY ;
00394                 if (alertDetailReg.Under_Voltage)
00395                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_UNDER_VOLTAGE ;
00396                 if (alertDetailReg.Over_Voltage)
00397                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_OVER_VOLTAGE ;
00398                 if (alertDetailReg.Correction_UnderRange)
00399                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_LUT_UNDER_RANGE ;
00400                 if (alertDetailReg.Correction_OverRange)
00401                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_LUT_OVER_RANGE ;
00402             }
00403         }
00404 
00405         ADI_ADISENSE_CORE_Alert_Status_2_t alert2Reg;
00406         READ_REG_U16(hDevice, alert2Reg.VALUE16, CORE_ALERT_STATUS_2);
00407         if (alert2Reg.Configuration_Error)
00408             pStatus->deviceStatus  |= ADI_SENSE_DEVICE_STATUS_CONFIG_ERROR ;
00409         if (alert2Reg.LUT_Error)
00410             pStatus->deviceStatus  |= ADI_SENSE_DEVICE_STATUS_LUT_ERROR ;
00411     }
00412 
00413     if (statusReg.Error)
00414     {
00415         pStatus->deviceStatus  |= ADI_SENSE_DEVICE_STATUS_ERROR ;
00416 
00417         ADI_ADISENSE_CORE_Error_Code_t errorCodeReg;
00418         READ_REG_U16(hDevice, errorCodeReg.VALUE16, CORE_ERROR_CODE);
00419         pStatus->errorCode  = errorCodeReg.Error_Code;
00420 
00421         ADI_ADISENSE_CORE_Diagnostics_Status_t diagStatusReg;
00422         READ_REG_U16(hDevice, diagStatusReg.VALUE16, CORE_DIAGNOSTICS_STATUS);
00423 
00424         if (diagStatusReg.Diag_Checksum_Error)
00425             pStatus->diagnosticsStatus  |= ADI_SENSE_DIAGNOSTICS_STATUS_CHECKSUM_ERROR ;
00426         if (diagStatusReg.Diag_Comms_Error)
00427             pStatus->diagnosticsStatus  |= ADI_SENSE_DIAGNOSTICS_STATUS_COMMS_ERROR ;
00428         if (diagStatusReg.Diag_Supply_Monitor_Error)
00429             pStatus->diagnosticsStatus  |= ADI_SENSE_DIAGNOSTICS_STATUS_SUPPLY_MONITOR_ERROR ;
00430         if (diagStatusReg.Diag_Supply_Cap_Error)
00431             pStatus->diagnosticsStatus  |= ADI_SENSE_DIAGNOSTICS_STATUS_SUPPLY_CAP_ERROR ;
00432         if (diagStatusReg.Diag_Ainm_UV_Error)
00433             pStatus->diagnosticsStatus  |= ADI_SENSE_DIAGNOSTICS_STATUS_AINM_UV_ERROR ;
00434         if (diagStatusReg.Diag_Ainm_OV_Error)
00435             pStatus->diagnosticsStatus  |= ADI_SENSE_DIAGNOSTICS_STATUS_AINM_OV_ERROR ;
00436         if (diagStatusReg.Diag_Ainp_UV_Error)
00437             pStatus->diagnosticsStatus  |= ADI_SENSE_DIAGNOSTICS_STATUS_AINP_UV_ERROR ;
00438         if (diagStatusReg.Diag_Ainp_OV_Error)
00439             pStatus->diagnosticsStatus  |= ADI_SENSE_DIAGNOSTICS_STATUS_AINP_OV_ERROR ;
00440         if (diagStatusReg.Diag_Conversion_Error)
00441             pStatus->diagnosticsStatus  |= ADI_SENSE_DIAGNOSTICS_STATUS_CONVERSION_ERROR ;
00442         if (diagStatusReg.Diag_Calibration_Error)
00443             pStatus->diagnosticsStatus  |= ADI_SENSE_DIAGNOSTICS_STATUS_CALIBRATION_ERROR ;
00444     }
00445 
00446     return ADI_SENSE_SUCCESS ;
00447 }
00448 
00449 ADI_SENSE_RESULT  adi_sense_GetCommandRunningState(
00450     ADI_SENSE_DEVICE_HANDLE  hDevice,
00451     bool_t *pbCommandRunning)
00452 {
00453     ADI_ADISENSE_CORE_Status_t statusReg;
00454 
00455     READ_REG_U8(hDevice, statusReg.VALUE8, CORE_STATUS);
00456 
00457     /* We should never normally see 0xFF here if the module is operational */
00458     if (statusReg.VALUE8 == 0xFF)
00459         return ADI_SENSE_ERR_NOT_INITIALIZED ;
00460 
00461     *pbCommandRunning = !statusReg.Cmd_Running; /* Active-low, so invert it */
00462 
00463     return ADI_SENSE_SUCCESS ;
00464 }
00465 
00466 static ADI_SENSE_RESULT  executeCommand(
00467     ADI_SENSE_DEVICE_HANDLE  const hDevice,
00468     ADI_ADISENSE_CORE_Command_Special_Command  const command,
00469     bool_t const bWaitForCompletion)
00470 {
00471     ADI_ADISENSE_CORE_Command_t commandReg;
00472     bool_t bCommandRunning;
00473     ADI_SENSE_RESULT  eRet;
00474 
00475     /*
00476      * Don't allow another command to be issued if one is already running, but
00477      * make an exception for ADISENSE_CORE_COMMAND_NOP which can be used to
00478      * request a running command to be stopped (e.g. continuous measurement)
00479      */
00480     if (command != ADISENSE_CORE_COMMAND_NOP)
00481     {
00482         eRet = adi_sense_GetCommandRunningState(hDevice, &bCommandRunning);
00483         if (eRet)
00484             return eRet;
00485 
00486         if (bCommandRunning)
00487             return ADI_SENSE_IN_USE ;
00488     }
00489 
00490     commandReg.Special_Command = command;
00491     WRITE_REG_U8(hDevice, commandReg.VALUE8, CORE_COMMAND);
00492 
00493     if (bWaitForCompletion)
00494     {
00495         do {
00496             /* Allow a minimum 50usec delay for status update before checking */
00497             adi_sense_TimeDelayUsec(50);
00498 
00499             eRet = adi_sense_GetCommandRunningState(hDevice, &bCommandRunning);
00500             if (eRet)
00501                 return eRet;
00502         } while (bCommandRunning);
00503     }
00504 
00505     return ADI_SENSE_SUCCESS ;
00506 }
00507 
00508 ADI_SENSE_RESULT  adi_sense_ApplyConfigUpdates(
00509     ADI_SENSE_DEVICE_HANDLE  const hDevice)
00510 {
00511     return executeCommand(hDevice, ADISENSE_CORE_COMMAND_LATCH_CONFIG, true);
00512 }
00513 
00514 /*!
00515  * @brief Start a measurement cycle.
00516  *
00517  * @param[out]
00518  *
00519  * @return Status
00520  *         - #ADI_SENSE_SUCCESS Call completed successfully.
00521  *         - #ADI_SENSE_FAILURE
00522  *
00523  * @details Sends the latch config command. Configuration for channels in
00524  *          conversion cycle should be completed before this function.
00525  *          Channel enabled bit should be set before this function.
00526  *          Starts a conversion and configures the format of the sample.
00527  *
00528  */
00529 ADI_SENSE_RESULT  adi_sense_StartMeasurement(
00530     ADI_SENSE_DEVICE_HANDLE     const hDevice,
00531     ADI_SENSE_MEASUREMENT_MODE  const eMeasurementMode)
00532 {
00533     switch (eMeasurementMode)
00534     {
00535     case ADI_SENSE_MEASUREMENT_MODE_HEALTHCHECK :
00536         return executeCommand(hDevice, ADISENSE_CORE_COMMAND_SYSTEM_CHECK, false);
00537     case ADI_SENSE_MEASUREMENT_MODE_NORMAL :
00538         return executeCommand(hDevice, ADISENSE_CORE_COMMAND_CONVERT_WITH_RAW, false);
00539     case ADI_SENSE_MEASUREMENT_MODE_OMIT_RAW :
00540         return executeCommand(hDevice, ADISENSE_CORE_COMMAND_CONVERT, false);
00541     default:
00542         ADI_SENSE_LOG_ERROR("Invalid measurement mode %d specified",
00543                             eMeasurementMode);
00544         return ADI_SENSE_INVALID_PARAM ;
00545     }
00546 }
00547 
00548 /*
00549  * Store the configuration settings to persistent memory on the device.
00550  * No other command must be running when this is called.
00551  * Do not power down the device while this command is running.
00552  */
00553 ADI_SENSE_RESULT  adi_sense_SaveConfig(
00554     ADI_SENSE_DEVICE_HANDLE     const hDevice)
00555 {
00556     return executeCommand(hDevice, ADISENSE_CORE_COMMAND_SAVE_CONFIG, true);
00557 }
00558 
00559 /*
00560  * Restore the configuration settings from persistent memory on the device.
00561  * No other command must be running when this is called.
00562  */
00563 ADI_SENSE_RESULT  adi_sense_RestoreConfig(
00564     ADI_SENSE_DEVICE_HANDLE     const hDevice)
00565 {
00566     return executeCommand(hDevice, ADISENSE_CORE_COMMAND_LOAD_CONFIG, true);
00567 }
00568 
00569 /*
00570  * Store the LUT data to persistent memory on the device.
00571  * No other command must be running when this is called.
00572  * Do not power down the device while this command is running.
00573  */
00574 ADI_SENSE_RESULT  adi_sense_SaveLutData(
00575     ADI_SENSE_DEVICE_HANDLE     const hDevice)
00576 {
00577     return executeCommand(hDevice, ADISENSE_CORE_COMMAND_SAVE_LUT2, true);
00578 }
00579 
00580 /*
00581  * Restore the LUT data from persistent memory on the device.
00582  * No other command must be running when this is called.
00583  */
00584 ADI_SENSE_RESULT  adi_sense_RestoreLutData(
00585     ADI_SENSE_DEVICE_HANDLE     const hDevice)
00586 {
00587     return executeCommand(hDevice, ADISENSE_CORE_COMMAND_LOAD_LUT, true);
00588 }
00589 
00590 /*
00591  * Stop the measurement cycles on the device.
00592  * To be used only if a measurement command is currently running.
00593  */
00594 ADI_SENSE_RESULT  adi_sense_StopMeasurement(
00595     ADI_SENSE_DEVICE_HANDLE     const hDevice)
00596 {
00597     return executeCommand(hDevice, ADISENSE_CORE_COMMAND_NOP, true);
00598 }
00599 
00600 /*
00601  * Run built-in diagnostic checks on the device.
00602  * Diagnostics are executed according to the current applied settings.
00603  * No other command must be running when this is called.
00604  */
00605 ADI_SENSE_RESULT  adi_sense_RunDiagnostics(
00606     ADI_SENSE_DEVICE_HANDLE     const hDevice)
00607 {
00608     return executeCommand(hDevice, ADISENSE_CORE_COMMAND_RUN_DIAGNOSTICS, true);
00609 }
00610 
00611 /*
00612  * Run self-calibration routines on the device.
00613  * Calibration is executed according to the current applied settings.
00614  * No other command must be running when this is called.
00615  */
00616 ADI_SENSE_RESULT  adi_sense_RunCalibration(
00617     ADI_SENSE_DEVICE_HANDLE     const hDevice)
00618 {
00619     return executeCommand(hDevice, ADISENSE_CORE_COMMAND_SELF_CALIBRATION, true);
00620 }
00621 
00622 /*
00623  * Read a set of data samples from the device.
00624  * This may be called at any time.
00625  */
00626 ADI_SENSE_RESULT  adi_sense_GetData(
00627     ADI_SENSE_DEVICE_HANDLE     const hDevice,
00628     ADI_SENSE_MEASUREMENT_MODE  const eMeasurementMode,
00629     ADI_SENSE_DATA_SAMPLE     * const pSamples,
00630     uint32_t                   const nRequested,
00631     uint32_t                 * const pnReturned)
00632 {
00633     ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
00634     uint16_t command = REG_READ_COMMAND |
00635         (REG_ADISENSE_CORE_DATA_FIFO & REG_ADDRESS_MASK);
00636     uint8_t commandData[2] = {
00637         command >> 8,
00638         command & 0xFF
00639     };
00640     uint8_t commandResponse[2];
00641     unsigned nValidSamples = 0;
00642     ADI_SENSE_RESULT  eRet = ADI_SENSE_SUCCESS ;
00643 
00644     do {
00645         eRet = adi_sense_SpiTransfer(pCtx->hSpi, commandData, commandResponse,
00646                                      sizeof(command), false);
00647         if (eRet)
00648         {
00649             ADI_SENSE_LOG_ERROR("Failed to send read command for FIFO register");
00650             return eRet;
00651         }
00652 
00653         adi_sense_TimeDelayUsec(POST_SPI_TRANSFER_DELAY_USEC);
00654     } while ((commandResponse[0] != REG_COMMAND_RESP_0) ||
00655              (commandResponse[1] != REG_COMMAND_RESP_1));
00656 
00657     for (unsigned i = 0; i < nRequested; i++)
00658     {
00659         ADI_ADISENSE_CORE_Data_FIFO_t dataFifoReg;
00660         bool_t bHoldCs = true;
00661         unsigned readSampleSize = sizeof(dataFifoReg);
00662 
00663         if (eMeasurementMode == ADI_SENSE_MEASUREMENT_MODE_OMIT_RAW )
00664             readSampleSize -= 3; /* 3B raw value omitted in this case */
00665 
00666         /* Keep the CS signal asserted for all but the last sample */
00667         if ((i + 1) == nRequested)
00668             bHoldCs = false;
00669 
00670         eRet = adi_sense_SpiTransfer(pCtx->hSpi, NULL, &dataFifoReg,
00671                                      readSampleSize, bHoldCs);
00672         if (eRet)
00673         {
00674             ADI_SENSE_LOG_ERROR("Failed to read data from FIFO register");
00675             return eRet;
00676         }
00677 
00678         if (! dataFifoReg.Ch_Valid)
00679         {
00680             /*
00681              * Reading an invalid sample indicates that there are no
00682              * more samples available or we've lost sync with the device.
00683              * In the latter case, it might be recoverable, but return here
00684              * to let the application check the device status and decide itself.
00685              */
00686             eRet = ADI_SENSE_INCOMPLETE ;
00687             break;
00688         }
00689 
00690         ADI_SENSE_DATA_SAMPLE  *pSample = &pSamples[nValidSamples];
00691 
00692         pSample->status  = 0;
00693         if (dataFifoReg.Ch_Error)
00694             pSample->status  |= ADI_SENSE_DEVICE_STATUS_ERROR ;
00695         if (dataFifoReg.Ch_Alert)
00696             pSample->status  |= ADI_SENSE_DEVICE_STATUS_ALERT ;
00697 
00698         if (dataFifoReg.Ch_Raw)
00699             pSample->rawValue  = dataFifoReg.Raw_Sample;
00700         else
00701             pSample->rawValue  = 0;
00702 
00703         pSample->channelId  = dataFifoReg.Channel_ID;
00704         pSample->processedValue  = dataFifoReg.Sensor_Result;
00705 
00706         nValidSamples++;
00707     }
00708     *pnReturned = nValidSamples;
00709 
00710     adi_sense_TimeDelayUsec(POST_SPI_TRANSFER_DELAY_USEC);
00711 
00712     return eRet;
00713 }
00714 
00715 /*
00716  * Close the given ADI Sense device.
00717  */
00718 ADI_SENSE_RESULT  adi_sense_Close(
00719     ADI_SENSE_DEVICE_HANDLE     const hDevice)
00720 {
00721     ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
00722 
00723     adi_sense_GpioClose(pCtx->hGpio);
00724     adi_sense_SpiClose(pCtx->hSpi);
00725     adi_sense_LogClose();
00726 
00727     return ADI_SENSE_SUCCESS ;
00728 }
00729 
00730 ADI_SENSE_RESULT  adi_sense_1000_WriteRegister(
00731     ADI_SENSE_DEVICE_HANDLE  hDevice,
00732     uint16_t nAddress,
00733     void *pData,
00734     unsigned nLength)
00735 {
00736     ADI_SENSE_RESULT  eRet;
00737     ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
00738     uint16_t command = REG_WRITE_COMMAND | (nAddress & REG_ADDRESS_MASK);
00739     uint8_t commandData[2] = {
00740         command >> 8,
00741         command & 0xFF
00742     };
00743     uint8_t commandResponse[2];
00744 
00745     do {
00746         eRet = adi_sense_SpiTransfer(pCtx->hSpi, commandData, commandResponse,
00747                                      sizeof(command), false);
00748         if (eRet)
00749         {
00750             ADI_SENSE_LOG_ERROR("Failed to send write command for register %u",
00751                                 nAddress);
00752             return eRet;
00753         }
00754 
00755         adi_sense_TimeDelayUsec(POST_SPI_TRANSFER_DELAY_USEC);
00756     } while ((commandResponse[0] != REG_COMMAND_RESP_0) ||
00757              (commandResponse[1] != REG_COMMAND_RESP_1));
00758 
00759     eRet = adi_sense_SpiTransfer(pCtx->hSpi, pData, NULL, nLength, false);
00760     if (eRet)
00761     {
00762         ADI_SENSE_LOG_ERROR("Failed to write data (%dB) to register %u",
00763                             nLength, nAddress);
00764         return eRet;
00765     }
00766 
00767     adi_sense_TimeDelayUsec(POST_SPI_TRANSFER_DELAY_USEC);
00768 
00769     return ADI_SENSE_SUCCESS ;
00770 }
00771 
00772 ADI_SENSE_RESULT  adi_sense_1000_ReadRegister(
00773     ADI_SENSE_DEVICE_HANDLE  hDevice,
00774     uint16_t nAddress,
00775     void *pData,
00776     unsigned nLength)
00777 {
00778     ADI_SENSE_RESULT  eRet;
00779     ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
00780     uint16_t command = REG_READ_COMMAND | (nAddress & REG_ADDRESS_MASK);
00781     uint8_t commandData[2] = {
00782         command >> 8,
00783         command & 0xFF
00784     };
00785     uint8_t commandResponse[2];
00786 
00787     do {
00788         eRet = adi_sense_SpiTransfer(pCtx->hSpi, commandData, commandResponse,
00789                                      sizeof(command), false);
00790         if (eRet)
00791         {
00792             ADI_SENSE_LOG_ERROR("Failed to send read command for register %u",
00793                                 nAddress);
00794             return eRet;
00795         }
00796 
00797         adi_sense_TimeDelayUsec(POST_SPI_TRANSFER_DELAY_USEC);
00798     } while ((commandResponse[0] != REG_COMMAND_RESP_0) ||
00799              (commandResponse[1] != REG_COMMAND_RESP_1));
00800 
00801     eRet = adi_sense_SpiTransfer(pCtx->hSpi, NULL, pData, nLength, false);
00802     if (eRet)
00803     {
00804         ADI_SENSE_LOG_ERROR("Failed to read data (%uB) from register %u",
00805                             nLength, nAddress);
00806         return eRet;
00807     }
00808 
00809     adi_sense_TimeDelayUsec(POST_SPI_TRANSFER_DELAY_USEC);
00810 
00811     return ADI_SENSE_SUCCESS ;
00812 }
00813 
00814 ADI_SENSE_RESULT  adi_sense_GetDeviceReadyState(
00815     ADI_SENSE_DEVICE_HANDLE    const hDevice,
00816     bool_t                  * const bReady)
00817 {
00818     ADI_ADISENSE_SPI_Chip_Type_t chipTypeReg;
00819 
00820     READ_REG_U8(hDevice, chipTypeReg.VALUE8, SPI_CHIP_TYPE);
00821     /* If we read this register successfully, assume the device is ready */
00822     *bReady = (chipTypeReg.VALUE8 == REG_ADISENSE_SPI_CHIP_TYPE_RESET);
00823 
00824     return ADI_SENSE_SUCCESS ;
00825 }
00826 
00827 ADI_SENSE_RESULT  adi_sense_1000_GetDataReadyModeInfo(
00828     ADI_SENSE_DEVICE_HANDLE          const hDevice,
00829     ADI_SENSE_MEASUREMENT_MODE       const eMeasurementMode,
00830     ADI_SENSE_1000_OPERATING_MODE  * const peOperatingMode,
00831     ADI_SENSE_1000_DATAREADY_MODE  * const peDataReadyMode,
00832     uint32_t                      * const pnSamplesPerDataready,
00833     uint32_t                      * const pnSamplesPerCycle)
00834 {
00835     unsigned nChannelsEnabled = 0;
00836     unsigned nSamplesPerCycle = 0;
00837 
00838     for (ADI_SENSE_1000_CHANNEL_ID  chId = 0; chId < ADI_SENSE_1000_MAX_CHANNELS ; chId++)
00839     {
00840         ADI_ADISENSE_CORE_Sensor_Details_t sensorDetailsReg;
00841         ADI_ADISENSE_CORE_Channel_Count_t channelCountReg;
00842 
00843         if (ADI_SENSE_1000_CHANNEL_IS_VIRTUAL(chId))
00844             continue;
00845 
00846         READ_REG_U8(hDevice, channelCountReg.VALUE8, CORE_CHANNEL_COUNTn(chId));
00847         READ_REG_U32(hDevice, sensorDetailsReg.VALUE32, CORE_SENSOR_DETAILSn(chId));
00848 
00849         if (channelCountReg.Channel_Enable && !sensorDetailsReg.Do_Not_Publish)
00850         {
00851             ADI_ADISENSE_CORE_Sensor_Type_t sensorTypeReg;
00852             unsigned nActualChannels = 1;
00853 
00854             READ_REG_U16(hDevice, sensorTypeReg.VALUE16, CORE_SENSOR_TYPEn(chId));
00855 
00856             if (chId == ADI_SENSE_1000_CHANNEL_ID_SPI_0 )
00857             {
00858                 /* Some sensors automatically generate samples on additional "virtual" channels
00859                  * so these channels must be counted as active when those sensors are selected
00860                  * and we use the count from the corresponding "physical" channel */
00861                 if (sensorTypeReg.Sensor_Type ==
00862                     ADISENSE_CORE_SENSOR_TYPE_SENSOR_SPI_ACCELEROMETER_1)
00863                     nActualChannels += 2;
00864             }
00865 
00866             nChannelsEnabled += nActualChannels;
00867             if (eMeasurementMode == ADI_SENSE_MEASUREMENT_MODE_HEALTHCHECK )
00868                 /* Assume a single sample per channel in test mode */
00869                 nSamplesPerCycle += nActualChannels;
00870             else
00871                 nSamplesPerCycle += nActualChannels *
00872                     (channelCountReg.Channel_Count + 1);
00873         }
00874     }
00875 
00876     if (nChannelsEnabled == 0)
00877     {
00878         *pnSamplesPerDataready = 0;
00879         *pnSamplesPerCycle = 0;
00880         return ADI_SENSE_SUCCESS ;
00881     }
00882 
00883     ADI_ADISENSE_CORE_Mode_t modeReg;
00884     READ_REG_U8(hDevice, modeReg.VALUE8, CORE_MODE);
00885 
00886     *pnSamplesPerCycle = nSamplesPerCycle;
00887 
00888     /* Assume DRDY_PER_CONVERSION behaviour in test mode */
00889     if ((eMeasurementMode == ADI_SENSE_MEASUREMENT_MODE_HEALTHCHECK ) ||
00890         (modeReg.Drdy_Mode == ADISENSE_CORE_MODE_DRDY_PER_CONVERSION))
00891     {
00892         *pnSamplesPerDataready = 1;
00893     }
00894     else if (modeReg.Drdy_Mode == ADISENSE_CORE_MODE_DRDY_PER_CYCLE)
00895     {
00896         *pnSamplesPerDataready = nSamplesPerCycle;
00897     }
00898     else
00899     {
00900         ADI_ADISENSE_CORE_Fifo_Num_Cycles_t fifoNumCyclesReg;
00901         READ_REG_U8(hDevice, fifoNumCyclesReg.VALUE8, CORE_FIFO_NUM_CYCLES);
00902 
00903         *pnSamplesPerDataready =
00904             nSamplesPerCycle * fifoNumCyclesReg.Fifo_Num_Cycles;
00905     }
00906 
00907     /* Assume SINGLECYCLE in test mode */
00908     if ((eMeasurementMode == ADI_SENSE_MEASUREMENT_MODE_HEALTHCHECK ) ||
00909         (modeReg.Conversion_Mode == ADISENSE_CORE_MODE_SINGLECYCLE))
00910         *peOperatingMode = ADI_SENSE_1000_OPERATING_MODE_SINGLECYCLE ;
00911     else if (modeReg.Conversion_Mode == ADISENSE_CORE_MODE_MULTICYCLE)
00912         *peOperatingMode = ADI_SENSE_1000_OPERATING_MODE_MULTICYCLE ;
00913     else
00914         *peOperatingMode = ADI_SENSE_1000_OPERATING_MODE_CONTINUOUS ;
00915 
00916     /* Assume DRDY_PER_CONVERSION behaviour in test mode */
00917     if ((eMeasurementMode == ADI_SENSE_MEASUREMENT_MODE_HEALTHCHECK ) ||
00918         (modeReg.Drdy_Mode == ADISENSE_CORE_MODE_DRDY_PER_CONVERSION))
00919         *peDataReadyMode = ADI_SENSE_1000_DATAREADY_PER_CONVERSION ;
00920     else if (modeReg.Drdy_Mode == ADISENSE_CORE_MODE_DRDY_PER_CYCLE)
00921         *peDataReadyMode = ADI_SENSE_1000_DATAREADY_PER_CYCLE ;
00922     else
00923         *peDataReadyMode = ADI_SENSE_1000_DATAREADY_PER_MULTICYCLE_BURST ;
00924 
00925     return ADI_SENSE_SUCCESS ;
00926 }
00927 
00928 ADI_SENSE_RESULT  adi_sense_GetProductID(
00929     ADI_SENSE_DEVICE_HANDLE  hDevice,
00930     ADI_SENSE_PRODUCT_ID  *pProductId)
00931 {
00932     ADI_ADISENSE_SPI_Product_ID_L_t productIdLoReg;
00933     ADI_ADISENSE_SPI_Product_ID_H_t productIdHiReg;
00934 
00935     READ_REG_U8(hDevice, productIdLoReg.VALUE8, SPI_PRODUCT_ID_L);
00936     READ_REG_U8(hDevice, productIdHiReg.VALUE8, SPI_PRODUCT_ID_H);
00937 
00938     *pProductId = (productIdHiReg.VALUE8 << 8) | productIdLoReg.VALUE8;
00939     return ADI_SENSE_SUCCESS ;
00940 }
00941 
00942 static ADI_SENSE_RESULT  adi_sense_SetPowerMode(
00943     ADI_SENSE_DEVICE_HANDLE  hDevice,
00944     ADI_SENSE_1000_POWER_MODE  powerMode)
00945 {
00946     ADI_ADISENSE_CORE_Power_Config_t powerConfigReg;
00947 
00948     if (powerMode == ADI_SENSE_1000_POWER_MODE_LOW )
00949     {
00950         powerConfigReg.Power_Mode_ADC = ADISENSE_CORE_POWER_CONFIG_ADC_LOW_POWER;
00951         /* TODO - we need an enum in the register map for the MCU power modes */
00952         powerConfigReg.Power_Mode_MCU = 0x0;
00953     }
00954     else if (powerMode == ADI_SENSE_1000_POWER_MODE_MID )
00955     {
00956         powerConfigReg.Power_Mode_ADC = ADISENSE_CORE_POWER_CONFIG_ADC_MID_POWER;
00957         powerConfigReg.Power_Mode_MCU = 0x1;
00958     }
00959     else if (powerMode == ADI_SENSE_1000_POWER_MODE_FULL )
00960     {
00961         powerConfigReg.Power_Mode_ADC = ADISENSE_CORE_POWER_CONFIG_ADC_FULL_POWER;
00962         powerConfigReg.Power_Mode_MCU = 0x2;
00963     }
00964     else
00965     {
00966         ADI_SENSE_LOG_ERROR("Invalid power mode %d specified", powerMode);
00967         return ADI_SENSE_INVALID_PARAM ;
00968     }
00969 
00970     WRITE_REG_U8(hDevice, powerConfigReg.VALUE8, CORE_POWER_CONFIG);
00971 
00972     return ADI_SENSE_SUCCESS ;
00973 }
00974 
00975 static ADI_SENSE_RESULT  adi_sense_SetVddVoltage(
00976     ADI_SENSE_DEVICE_HANDLE  hDevice,
00977     float32_t vddVoltage)
00978 {
00979     WRITE_REG_FLOAT(hDevice, vddVoltage, CORE_AVDD_VOLTAGE);
00980 
00981     return ADI_SENSE_SUCCESS ;
00982 }
00983 
00984 ADI_SENSE_RESULT  adi_sense_1000_SetPowerConfig(
00985     ADI_SENSE_DEVICE_HANDLE  hDevice,
00986     ADI_SENSE_1000_POWER_CONFIG  *pPowerConfig)
00987 {
00988     ADI_SENSE_RESULT  eRet;
00989 
00990     eRet = adi_sense_SetPowerMode(hDevice, pPowerConfig->powerMode );
00991     if (eRet != ADI_SENSE_SUCCESS )
00992     {
00993         ADI_SENSE_LOG_ERROR("Failed to set power mode");
00994         return eRet;
00995     }
00996 
00997     eRet = adi_sense_SetVddVoltage(hDevice, pPowerConfig->supplyVoltage );
00998     if (eRet != ADI_SENSE_SUCCESS )
00999     {
01000         ADI_SENSE_LOG_ERROR("Failed to set AVdd voltage");
01001         return eRet;
01002     }
01003 
01004     return ADI_SENSE_SUCCESS ;
01005 }
01006 
01007 static ADI_SENSE_RESULT  adi_sense_SetMode(
01008     ADI_SENSE_DEVICE_HANDLE  hDevice,
01009     ADI_SENSE_1000_OPERATING_MODE  eOperatingMode,
01010     ADI_SENSE_1000_DATAREADY_MODE  eDataReadyMode)
01011 {
01012     ADI_ADISENSE_CORE_Mode_t modeReg;
01013 
01014     modeReg.VALUE8 = REG_RESET_VAL(CORE_MODE);
01015 
01016     if (eOperatingMode == ADI_SENSE_1000_OPERATING_MODE_SINGLECYCLE )
01017     {
01018         modeReg.Conversion_Mode = ADISENSE_CORE_MODE_SINGLECYCLE;
01019     }
01020     else if (eOperatingMode == ADI_SENSE_1000_OPERATING_MODE_CONTINUOUS )
01021     {
01022         modeReg.Conversion_Mode = ADISENSE_CORE_MODE_CONTINUOUS;
01023     }
01024     else if (eOperatingMode == ADI_SENSE_1000_OPERATING_MODE_MULTICYCLE )
01025     {
01026         modeReg.Conversion_Mode = ADISENSE_CORE_MODE_MULTICYCLE;
01027     }
01028     else
01029     {
01030         ADI_SENSE_LOG_ERROR("Invalid operating mode %d specified",
01031                             eOperatingMode);
01032         return ADI_SENSE_INVALID_PARAM ;
01033     }
01034 
01035     if (eDataReadyMode == ADI_SENSE_1000_DATAREADY_PER_CONVERSION )
01036     {
01037         modeReg.Drdy_Mode = ADISENSE_CORE_MODE_DRDY_PER_CONVERSION;
01038     }
01039     else if (eDataReadyMode == ADI_SENSE_1000_DATAREADY_PER_CYCLE )
01040     {
01041         modeReg.Drdy_Mode = ADISENSE_CORE_MODE_DRDY_PER_CYCLE;
01042     }
01043     else if (eDataReadyMode == ADI_SENSE_1000_DATAREADY_PER_MULTICYCLE_BURST )
01044     {
01045         if (eOperatingMode != ADI_SENSE_1000_OPERATING_MODE_MULTICYCLE )
01046         {
01047             ADI_SENSE_LOG_ERROR(
01048                 "Data-ready mode %d cannot be used with operating mode %d",
01049                 eDataReadyMode, eOperatingMode);
01050             return ADI_SENSE_INVALID_PARAM ;
01051         }
01052         else
01053         {
01054             modeReg.Drdy_Mode = ADISENSE_CORE_MODE_DRDY_PER_FIFO_FILL;
01055         }
01056     }
01057     else
01058     {
01059         ADI_SENSE_LOG_ERROR("Invalid data-ready mode %d specified", eDataReadyMode);
01060         return ADI_SENSE_INVALID_PARAM ;
01061     }
01062 
01063     WRITE_REG_U8(hDevice, modeReg.VALUE8, CORE_MODE);
01064 
01065     return ADI_SENSE_SUCCESS ;
01066 }
01067 
01068 ADI_SENSE_RESULT  adi_sense_SetCycleInterval(
01069     ADI_SENSE_DEVICE_HANDLE  hDevice,
01070     uint32_t nCycleInterval)
01071 {
01072     ADI_ADISENSE_CORE_Cycle_Control_t cycleControlReg;
01073 
01074     cycleControlReg.VALUE16 = REG_RESET_VAL(CORE_CYCLE_CONTROL);
01075 
01076     if (nCycleInterval < (1 << 12))
01077     {
01078         cycleControlReg.Cycle_Time_Units = ADISENSE_CORE_CYCLE_CONTROL_MICROSECONDS;
01079     }
01080     else if (nCycleInterval < (1000 * (1 << 12)))
01081     {
01082         cycleControlReg.Cycle_Time_Units = ADISENSE_CORE_CYCLE_CONTROL_MILLISECONDS;
01083         nCycleInterval /= 1000;
01084     }
01085     else
01086     {
01087         cycleControlReg.Cycle_Time_Units = ADISENSE_CORE_CYCLE_CONTROL_SECONDS;
01088         nCycleInterval /= 1000000;
01089     }
01090 
01091     CHECK_REG_FIELD_VAL(CORE_CYCLE_CONTROL_CYCLE_TIME, nCycleInterval);
01092     cycleControlReg.Cycle_Time = nCycleInterval;
01093 
01094     WRITE_REG_U16(hDevice, cycleControlReg.VALUE16, CORE_CYCLE_CONTROL);
01095 
01096     return ADI_SENSE_SUCCESS ;
01097 }
01098 
01099 static ADI_SENSE_RESULT  adi_sense_SetMultiCycleConfig(
01100     ADI_SENSE_DEVICE_HANDLE  hDevice,
01101     ADI_SENSE_1000_MULTICYCLE_CONFIG  *pMultiCycleConfig)
01102 {
01103     CHECK_REG_FIELD_VAL(CORE_FIFO_NUM_CYCLES_FIFO_NUM_CYCLES,
01104                         pMultiCycleConfig->cyclesPerBurst );
01105 
01106     WRITE_REG_U8(hDevice, pMultiCycleConfig->cyclesPerBurst ,
01107                  CORE_FIFO_NUM_CYCLES);
01108 
01109     WRITE_REG_U32(hDevice, pMultiCycleConfig->burstInterval ,
01110                   CORE_MULTI_CYCLE_REPEAT_INTERVAL);
01111 
01112     return ADI_SENSE_SUCCESS ;
01113 }
01114 
01115 static ADI_SENSE_RESULT  adi_sense_SetExternalReferenceValues(
01116     ADI_SENSE_DEVICE_HANDLE  hDevice,
01117     float32_t externalRef1Value,
01118     float32_t externalRef2Value)
01119 {
01120     WRITE_REG_FLOAT(hDevice, externalRef1Value, CORE_EXTERNAL_REFERENCE1);
01121     WRITE_REG_FLOAT(hDevice, externalRef2Value, CORE_EXTERNAL_REFERENCE2);
01122 
01123     return ADI_SENSE_SUCCESS ;
01124 }
01125 
01126 ADI_SENSE_RESULT  adi_sense_1000_SetMeasurementConfig(
01127     ADI_SENSE_DEVICE_HANDLE  hDevice,
01128     ADI_SENSE_1000_MEASUREMENT_CONFIG  *pMeasConfig)
01129 {
01130     ADI_SENSE_RESULT  eRet;
01131 
01132     eRet = adi_sense_SetMode(hDevice,
01133                             pMeasConfig->operatingMode ,
01134                             pMeasConfig->dataReadyMode );
01135     if (eRet != ADI_SENSE_SUCCESS )
01136     {
01137         ADI_SENSE_LOG_ERROR("Failed to set operating mode");
01138         return eRet;
01139     }
01140 
01141     if (pMeasConfig->operatingMode  != ADI_SENSE_1000_OPERATING_MODE_SINGLECYCLE )
01142     {
01143         eRet = adi_sense_SetCycleInterval(hDevice, pMeasConfig->cycleInterval );
01144         if (eRet != ADI_SENSE_SUCCESS )
01145         {
01146             ADI_SENSE_LOG_ERROR("Failed to set cycle interval");
01147             return eRet;
01148         }
01149     }
01150 
01151     if (pMeasConfig->operatingMode  == ADI_SENSE_1000_OPERATING_MODE_MULTICYCLE )
01152     {
01153         eRet = adi_sense_SetMultiCycleConfig(hDevice,
01154                                             &pMeasConfig->multiCycleConfig );
01155         if (eRet != ADI_SENSE_SUCCESS )
01156         {
01157             ADI_SENSE_LOG_ERROR("Failed to set multi-cycle configuration");
01158             return eRet;
01159         }
01160     }
01161 
01162     eRet = adi_sense_SetExternalReferenceValues(hDevice,
01163                                                 pMeasConfig->externalRef1Value ,
01164                                                 pMeasConfig->externalRef2Value );
01165     if (eRet != ADI_SENSE_SUCCESS )
01166     {
01167         ADI_SENSE_LOG_ERROR("Failed to set external reference values");
01168         return eRet;
01169     }
01170 
01171     return ADI_SENSE_SUCCESS ;
01172 }
01173 
01174 ADI_SENSE_RESULT  adi_sense_1000_SetDiagnosticsConfig(
01175     ADI_SENSE_DEVICE_HANDLE  hDevice,
01176     ADI_SENSE_1000_DIAGNOSTICS_CONFIG  *pDiagnosticsConfig)
01177 {
01178     ADI_ADISENSE_CORE_Diagnostics_Control_t diagnosticsControlReg;
01179 
01180     diagnosticsControlReg.VALUE16 = REG_RESET_VAL(CORE_DIAGNOSTICS_CONTROL);
01181 
01182     if (pDiagnosticsConfig->disableGlobalDiag )
01183         diagnosticsControlReg.Diag_Global_En = 0;
01184     else
01185         diagnosticsControlReg.Diag_Global_En = 1;
01186 
01187     if (pDiagnosticsConfig->disableMeasurementDiag )
01188         diagnosticsControlReg.Diag_Meas_En = 0;
01189     else
01190         diagnosticsControlReg.Diag_Meas_En = 1;
01191 
01192     switch (pDiagnosticsConfig->osdFrequency )
01193     {
01194     case ADI_SENSE_1000_OPEN_SENSOR_DIAGNOSTICS_DISABLED :
01195         diagnosticsControlReg.Diag_OSD_Freq = ADISENSE_CORE_DIAGNOSTICS_CONTROL_OCD_OFF;
01196         break;
01197     case ADI_SENSE_1000_OPEN_SENSOR_DIAGNOSTICS_PER_CYCLE :
01198         diagnosticsControlReg.Diag_OSD_Freq = ADISENSE_CORE_DIAGNOSTICS_CONTROL_OCD_PER_1_CYCLE;
01199         break;
01200     case ADI_SENSE_1000_OPEN_SENSOR_DIAGNOSTICS_PER_100_CYCLES :
01201         diagnosticsControlReg.Diag_OSD_Freq = ADISENSE_CORE_DIAGNOSTICS_CONTROL_OCD_PER_100_CYCLES;
01202         break;
01203     case ADI_SENSE_1000_OPEN_SENSOR_DIAGNOSTICS_PER_1000_CYCLES :
01204         diagnosticsControlReg.Diag_OSD_Freq = ADISENSE_CORE_DIAGNOSTICS_CONTROL_OCD_PER_1000_CYCLES;
01205         break;
01206     default:
01207         ADI_SENSE_LOG_ERROR("Invalid open-sensor diagnostic frequency %d specified",
01208                             pDiagnosticsConfig->osdFrequency );
01209         return ADI_SENSE_INVALID_PARAM ;
01210     }
01211 
01212     WRITE_REG_U16(hDevice, diagnosticsControlReg.VALUE16, CORE_DIAGNOSTICS_CONTROL);
01213 
01214     return ADI_SENSE_SUCCESS ;
01215 }
01216 
01217 ADI_SENSE_RESULT  adi_sense_1000_SetChannelCount(
01218     ADI_SENSE_DEVICE_HANDLE  hDevice,
01219     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01220     uint32_t nMeasurementsPerCycle)
01221 {
01222     ADI_ADISENSE_CORE_Channel_Count_t channelCountReg;
01223 
01224     channelCountReg.VALUE8 = REG_RESET_VAL(CORE_CHANNEL_COUNTn);
01225 
01226     if (nMeasurementsPerCycle > 0)
01227     {
01228         nMeasurementsPerCycle -= 1;
01229 
01230         CHECK_REG_FIELD_VAL(CORE_CHANNEL_COUNT_CHANNEL_COUNT,
01231                             nMeasurementsPerCycle);
01232 
01233         channelCountReg.Channel_Enable = 1;
01234         channelCountReg.Channel_Count = nMeasurementsPerCycle;
01235     }
01236     else
01237     {
01238         channelCountReg.Channel_Enable = 0;
01239     }
01240 
01241     WRITE_REG_U8(hDevice, channelCountReg.VALUE8, CORE_CHANNEL_COUNTn(eChannelId));
01242 
01243     return ADI_SENSE_SUCCESS ;
01244 }
01245 
01246 static ADI_SENSE_RESULT  adi_sense_SetChannelAdcSensorType(
01247     ADI_SENSE_DEVICE_HANDLE  hDevice,
01248     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01249     ADI_SENSE_1000_ADC_SENSOR_TYPE  sensorType)
01250 {
01251     ADI_ADISENSE_CORE_Sensor_Type_t sensorTypeReg;
01252 
01253     sensorTypeReg.VALUE16 = REG_RESET_VAL(CORE_SENSOR_TYPEn);
01254 
01255     /* Ensure that the sensor type is valid for this channel */
01256     switch(sensorType)
01257     {
01258     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_J_DEF_L1 :
01259     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_K_DEF_L1 :
01260     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_T_DEF_L1 :
01261     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_1_DEF_L2 :
01262     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_2_DEF_L2 :
01263     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_3_DEF_L2 :
01264     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_4_DEF_L2 :
01265     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_J_ADV_L1 :
01266     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_K_ADV_L1 :
01267     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_T_ADV_L1 :
01268     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_1_ADV_L2 :
01269     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_2_ADV_L2 :
01270     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_3_ADV_L2 :
01271     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_4_ADV_L2 :
01272     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_PT100_DEF_L1 :
01273     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_PT1000_DEF_L1 :
01274     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_1_DEF_L2 :
01275     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_2_DEF_L2 :
01276     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_3_DEF_L2 :
01277     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_4_DEF_L2 :
01278     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_PT100_ADV_L1 :
01279     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_PT1000_ADV_L1 :
01280     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_1_ADV_L2 :
01281     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_2_ADV_L2 :
01282     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_3_ADV_L2 :
01283     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_4_ADV_L2 :
01284     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_PT100_DEF_L1 :
01285     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_PT1000_DEF_L1 :
01286     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_1_DEF_L2 :
01287     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_2_DEF_L2 :
01288     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_3_DEF_L2 :
01289     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_4_DEF_L2 :
01290     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_PT100_ADV_L1 :
01291     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_PT1000_ADV_L1 :
01292     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_1_ADV_L2 :
01293     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_2_ADV_L2 :
01294     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_3_ADV_L2 :
01295     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_4_ADV_L2 :
01296     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_1_DEF_L2 :
01297     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_2_DEF_L2 :
01298     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_3_DEF_L2 :
01299     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_4_DEF_L2 :
01300     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_1_ADV_L2 :
01301     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_2_ADV_L2 :
01302     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_3_ADV_L2 :
01303     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_4_ADV_L2 :
01304     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_1_DEF_L2 :
01305     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_2_DEF_L2 :
01306     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_3_DEF_L2 :
01307     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_4_DEF_L2 :
01308     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_1_ADV_L2 :
01309     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_2_ADV_L2 :
01310     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_3_ADV_L2 :
01311     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_4_ADV_L2 :
01312     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_A_10K_DEF_L1 :
01313     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_B_10K_DEF_L1 :
01314     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_1_DEF_L2 :
01315     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_2_DEF_L2 :
01316     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_3_DEF_L2 :
01317     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_4_DEF_L2 :
01318     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_A_10K_ADV_L1 :
01319     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_B_10K_ADV_L1 :
01320     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_1_ADV_L2 :
01321     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_2_ADV_L2 :
01322     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_3_ADV_L2 :
01323     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_4_ADV_L2 :
01324         if (! ADI_SENSE_1000_CHANNEL_IS_ADC_SENSOR(eChannelId))
01325         {
01326             ADI_SENSE_LOG_ERROR(
01327                 "Invalid ADC sensor type %d specified for channel %d",
01328                 sensorType, eChannelId);
01329             return ADI_SENSE_INVALID_PARAM ;
01330         }
01331         break;
01332     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_PT100_DEF_L1 :
01333     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_PT1000_DEF_L1 :
01334     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_1_DEF_L2 :
01335     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_2_DEF_L2 :
01336     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_3_DEF_L2 :
01337     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_4_DEF_L2 :
01338     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_PT100_ADV_L1 :
01339     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_PT1000_ADV_L1 :
01340     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_1_ADV_L2 :
01341     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_2_ADV_L2 :
01342     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_3_ADV_L2 :
01343     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_4_ADV_L2 :
01344         if (! (ADI_SENSE_1000_CHANNEL_IS_ADC_SENSOR(eChannelId) ||
01345                ADI_SENSE_1000_CHANNEL_IS_ADC_CJC(eChannelId)))
01346         {
01347             ADI_SENSE_LOG_ERROR(
01348                 "Invalid ADC sensor type %d specified for channel %d",
01349                 sensorType, eChannelId);
01350             return ADI_SENSE_INVALID_PARAM ;
01351         }
01352         break;
01353     case ADI_SENSE_1000_ADC_SENSOR_VOLTAGE :
01354     case ADI_SENSE_1000_ADC_SENSOR_VOLTAGE_PRESSURE_HONEYWELL_TRUSTABILITY :
01355     case ADI_SENSE_1000_ADC_SENSOR_VOLTAGE_PRESSURE_AMPHENOL_NPA300X :
01356     case ADI_SENSE_1000_ADC_SENSOR_VOLTAGE_PRESSURE_3_DEF :
01357         if (! ADI_SENSE_1000_CHANNEL_IS_ADC_VOLTAGE(eChannelId))
01358         {
01359             ADI_SENSE_LOG_ERROR(
01360                 "Invalid ADC sensor type %d specified for channel %d",
01361                 sensorType, eChannelId);
01362             return ADI_SENSE_INVALID_PARAM ;
01363         }
01364         break;
01365     case ADI_SENSE_1000_ADC_SENSOR_CURRENT :
01366     case ADI_SENSE_1000_ADC_SENSOR_CURRENT_PRESSURE_HONEYWELL_PX2 :
01367     case ADI_SENSE_1000_ADC_SENSOR_CURRENT_PRESSURE_2_DEF :
01368         if (! ADI_SENSE_1000_CHANNEL_IS_ADC_CURRENT(eChannelId))
01369         {
01370             ADI_SENSE_LOG_ERROR(
01371                 "Invalid ADC sensor type %d specified for channel %d",
01372                 sensorType, eChannelId);
01373             return ADI_SENSE_INVALID_PARAM ;
01374         }
01375         break;
01376     default:
01377         ADI_SENSE_LOG_ERROR("Invalid/unsupported ADC sensor type %d specified",
01378                             sensorType);
01379         return ADI_SENSE_INVALID_PARAM ;
01380     }
01381 
01382     sensorTypeReg.Sensor_Type = sensorType;
01383 
01384     WRITE_REG_U16(hDevice, sensorTypeReg.VALUE16, CORE_SENSOR_TYPEn(eChannelId));
01385 
01386     return ADI_SENSE_SUCCESS ;
01387 }
01388 
01389 static ADI_SENSE_RESULT  adi_sense_SetChannelAdcSensorDetails(
01390     ADI_SENSE_DEVICE_HANDLE  hDevice,
01391     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01392     ADI_SENSE_1000_CHANNEL_CONFIG  *pChannelConfig)
01393 /*
01394  * TODO - it would be nice if the general- vs. ADC-specific sensor details could be split into separate registers
01395  * General details:
01396  * - Measurement_Units
01397  * - Compensation_Channel
01398  * - CJC_Publish (if "CJC" was removed from the name)
01399  * ADC-specific details:
01400  * - PGA_Gain
01401  * - Reference_Select
01402  * - Reference_Buffer_Disable
01403  * - Vbias
01404  */
01405 {
01406     ADI_SENSE_1000_ADC_CHANNEL_CONFIG  *pAdcChannelConfig = &pChannelConfig->adcChannelConfig ;
01407     ADI_SENSE_1000_ADC_REFERENCE_CONFIG  *pRefConfig = &pAdcChannelConfig->reference ;
01408     ADI_ADISENSE_CORE_Sensor_Details_t sensorDetailsReg;
01409 
01410     sensorDetailsReg.VALUE32 = REG_RESET_VAL(CORE_SENSOR_DETAILSn);
01411 
01412     switch(pChannelConfig->measurementUnit )
01413     {
01414     case ADI_SENSE_1000_MEASUREMENT_UNIT_FAHRENHEIT :
01415         sensorDetailsReg.Measurement_Units = ADISENSE_CORE_SENSOR_DETAILS_UNITS_DEGF;
01416         break;
01417     case ADI_SENSE_1000_MEASUREMENT_UNIT_CELSIUS :
01418     case ADI_SENSE_1000_MEASUREMENT_UNIT_DEFAULT :
01419         sensorDetailsReg.Measurement_Units = ADISENSE_CORE_SENSOR_DETAILS_UNITS_DEGC;
01420         break;
01421     default:
01422         ADI_SENSE_LOG_ERROR("Invalid measurement unit %d specified",
01423                             pChannelConfig->measurementUnit );
01424         return ADI_SENSE_INVALID_PARAM ;
01425     }
01426 
01427     sensorDetailsReg.Compensation_Channel = pChannelConfig->compensationChannel ;
01428 
01429     switch(pRefConfig->type )
01430     {
01431     case ADI_SENSE_1000_ADC_REFERENCE_RESISTOR_INTERNAL_1 :
01432         sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_RINT1;
01433         break;
01434     case ADI_SENSE_1000_ADC_REFERENCE_RESISTOR_INTERNAL_2 :
01435         sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_RINT2;
01436         break;
01437     case ADI_SENSE_1000_ADC_REFERENCE_VOLTAGE_INTERNAL :
01438         sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_INT;
01439         break;
01440     case ADI_SENSE_1000_ADC_REFERENCE_VOLTAGE_AVDD :
01441         sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_AVDD;
01442         break;
01443     case ADI_SENSE_1000_ADC_REFERENCE_RESISTOR_EXTERNAL_1 :
01444         sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_REXT1;
01445         break;
01446     case ADI_SENSE_1000_ADC_REFERENCE_RESISTOR_EXTERNAL_2 :
01447         sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_REXT2;
01448         break;
01449     case ADI_SENSE_1000_ADC_REFERENCE_VOLTAGE_EXTERNAL_1 :
01450         sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_VEXT1;
01451         break;
01452     case ADI_SENSE_1000_ADC_REFERENCE_VOLTAGE_EXTERNAL_2 :
01453         sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_VEXT2;
01454         break;
01455     case ADI_SENSE_1000_ADC_REFERENCE_BRIDGE_EXCITATION :
01456         sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_EXC;
01457         break;
01458     default:
01459         ADI_SENSE_LOG_ERROR("Invalid ADC reference type %d specified",
01460                             pRefConfig->type );
01461         return ADI_SENSE_INVALID_PARAM ;
01462     }
01463 
01464     switch(pAdcChannelConfig->gain )
01465     {
01466     case ADI_SENSE_1000_ADC_GAIN_1X :
01467         sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_1;
01468         break;
01469     case ADI_SENSE_1000_ADC_GAIN_2X :
01470         sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_2;
01471         break;
01472     case ADI_SENSE_1000_ADC_GAIN_4X :
01473         sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_4;
01474         break;
01475     case ADI_SENSE_1000_ADC_GAIN_8X :
01476         sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_8;
01477         break;
01478     case ADI_SENSE_1000_ADC_GAIN_16X :
01479         sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_16;
01480         break;
01481     case ADI_SENSE_1000_ADC_GAIN_32X :
01482         sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_32;
01483         break;
01484     case ADI_SENSE_1000_ADC_GAIN_64X :
01485         sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_64;
01486         break;
01487     case ADI_SENSE_1000_ADC_GAIN_128X :
01488         sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_128;
01489         break;
01490     default:
01491         ADI_SENSE_LOG_ERROR("Invalid ADC gain %d specified",
01492                             pAdcChannelConfig->gain );
01493         return ADI_SENSE_INVALID_PARAM ;
01494     }
01495 
01496     if (pAdcChannelConfig->enableVbias )
01497         sensorDetailsReg.Vbias = 1;
01498     else
01499         sensorDetailsReg.Vbias = 0;
01500 
01501     if (pAdcChannelConfig->reference .disableBuffer )
01502         sensorDetailsReg.Reference_Buffer_Disable = 1;
01503     else
01504         sensorDetailsReg.Reference_Buffer_Disable = 0;
01505 
01506     if (pChannelConfig->disablePublishing )
01507         sensorDetailsReg.Do_Not_Publish = 1;
01508     else
01509         sensorDetailsReg.Do_Not_Publish = 0;
01510 
01511     WRITE_REG_U32(hDevice, sensorDetailsReg.VALUE32, CORE_SENSOR_DETAILSn(eChannelId));
01512 
01513     return ADI_SENSE_SUCCESS ;
01514 }
01515 
01516 static ADI_SENSE_RESULT  adi_sense_SetChannelAdcFilter(
01517     ADI_SENSE_DEVICE_HANDLE  hDevice,
01518     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01519     ADI_SENSE_1000_ADC_FILTER_CONFIG  *pFilterConfig)
01520 {
01521     ADI_ADISENSE_CORE_Filter_Select_t filterSelectReg;
01522 
01523     filterSelectReg.VALUE32 = REG_RESET_VAL(CORE_FILTER_SELECTn);
01524 
01525     if (pFilterConfig->type  == ADI_SENSE_1000_ADC_FILTER_SINC4 )
01526     {
01527         filterSelectReg.ADC_Filter_Type = ADISENSE_CORE_FILTER_SELECT_FILTER_SINC4;
01528         filterSelectReg.ADC_FS = pFilterConfig->fs ;
01529     }
01530     else if (pFilterConfig->type  == ADI_SENSE_1000_ADC_FILTER_FIR_20SPS )
01531     {
01532         filterSelectReg.ADC_Filter_Type = ADISENSE_CORE_FILTER_SELECT_FILTER_FIR_20SPS;
01533     }
01534     else if (pFilterConfig->type  == ADI_SENSE_1000_ADC_FILTER_FIR_25SPS )
01535     {
01536         filterSelectReg.ADC_Filter_Type = ADISENSE_CORE_FILTER_SELECT_FILTER_FIR_25SPS;
01537     }
01538     else
01539     {
01540         ADI_SENSE_LOG_ERROR("Invalid ADC filter type %d specified",
01541                             pFilterConfig->type );
01542         return ADI_SENSE_INVALID_PARAM ;
01543     }
01544 
01545     WRITE_REG_U32(hDevice, filterSelectReg.VALUE32, CORE_FILTER_SELECTn(eChannelId));
01546 
01547     return ADI_SENSE_SUCCESS ;
01548 }
01549 
01550 static ADI_SENSE_RESULT  adi_sense_SetChannelAdcCurrentConfig(
01551     ADI_SENSE_DEVICE_HANDLE  hDevice,
01552     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01553     ADI_SENSE_1000_ADC_EXC_CURRENT_CONFIG  *pCurrentConfig)
01554 {
01555     ADI_ADISENSE_CORE_Channel_Excitation_t channelExcitationReg;
01556 
01557     channelExcitationReg.VALUE8 = REG_RESET_VAL(CORE_CHANNEL_EXCITATIONn);
01558 
01559     if (pCurrentConfig->outputLevel  == ADI_SENSE_1000_ADC_EXC_CURRENT_NONE )
01560     {
01561         channelExcitationReg.IOUT0_Disable = 1;
01562         channelExcitationReg.IOUT1_Disable = 1;
01563 
01564         channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_OFF;
01565     }
01566     else
01567     {
01568         channelExcitationReg.IOUT0_Disable = 0;
01569         channelExcitationReg.IOUT1_Disable = 0;
01570 
01571         if (pCurrentConfig->outputLevel  == ADI_SENSE_1000_ADC_EXC_CURRENT_50uA )
01572             channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_50UA;
01573         else if (pCurrentConfig->outputLevel  == ADI_SENSE_1000_ADC_EXC_CURRENT_100uA )
01574             channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_100UA;
01575         else if (pCurrentConfig->outputLevel  == ADI_SENSE_1000_ADC_EXC_CURRENT_250uA )
01576             channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_250UA;
01577         else if (pCurrentConfig->outputLevel  == ADI_SENSE_1000_ADC_EXC_CURRENT_500uA )
01578             channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_500UA;
01579         else if (pCurrentConfig->outputLevel  == ADI_SENSE_1000_ADC_EXC_CURRENT_750uA )
01580             channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_750UA;
01581         else if (pCurrentConfig->outputLevel  == ADI_SENSE_1000_ADC_EXC_CURRENT_1000uA )
01582             channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_1000UA;
01583         else
01584         {
01585             ADI_SENSE_LOG_ERROR("Invalid ADC excitation current %d specified",
01586                                 pCurrentConfig->outputLevel );
01587             return ADI_SENSE_INVALID_PARAM ;
01588         }
01589 
01590         if (pCurrentConfig->swapOption  == ADI_SENSE_1000_ADC_EXC_CURRENT_SWAP_DYNAMIC )
01591         {
01592             channelExcitationReg.IOUT_Dont_Swap_3Wire = 0;
01593             channelExcitationReg.IOUT_Static_Swap_3Wire = 0;
01594         }
01595         else if (pCurrentConfig->swapOption  == ADI_SENSE_1000_ADC_EXC_CURRENT_SWAP_STATIC )
01596         {
01597             channelExcitationReg.IOUT_Dont_Swap_3Wire = 1;
01598             channelExcitationReg.IOUT_Static_Swap_3Wire = 1;
01599         }
01600         else if (pCurrentConfig->swapOption  == ADI_SENSE_1000_ADC_EXC_CURRENT_SWAP_NONE )
01601         {
01602             channelExcitationReg.IOUT_Dont_Swap_3Wire = 1;
01603             channelExcitationReg.IOUT_Static_Swap_3Wire = 0;
01604         }
01605         else
01606         {
01607             ADI_SENSE_LOG_ERROR(
01608                 "Invalid ADC excitation current swap option %d specified",
01609                 pCurrentConfig->swapOption );
01610             return ADI_SENSE_INVALID_PARAM ;
01611         }
01612     }
01613 
01614     WRITE_REG_U8(hDevice, channelExcitationReg.VALUE8, CORE_CHANNEL_EXCITATIONn(eChannelId));
01615 
01616     return ADI_SENSE_SUCCESS ;
01617 }
01618 
01619 ADI_SENSE_RESULT  adi_sense_SetAdcChannelConfig(
01620     ADI_SENSE_DEVICE_HANDLE  hDevice,
01621     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01622     ADI_SENSE_1000_CHANNEL_CONFIG  *pChannelConfig)
01623 {
01624     ADI_SENSE_RESULT  eRet;
01625     ADI_SENSE_1000_ADC_CHANNEL_CONFIG  *pAdcChannelConfig =
01626         &pChannelConfig->adcChannelConfig ;
01627 
01628     eRet = adi_sense_SetChannelAdcSensorType(hDevice, eChannelId,
01629                                              pAdcChannelConfig->sensor );
01630     if (eRet != ADI_SENSE_SUCCESS )
01631     {
01632         ADI_SENSE_LOG_ERROR("Failed to set ADC sensor type for channel %d",
01633                             eChannelId);
01634         return eRet;
01635     }
01636 
01637     eRet = adi_sense_SetChannelAdcSensorDetails(hDevice, eChannelId,
01638                                                 pChannelConfig);
01639     if (eRet != ADI_SENSE_SUCCESS )
01640     {
01641         ADI_SENSE_LOG_ERROR("Failed to set ADC sensor details for channel %d",
01642                             eChannelId);
01643         return eRet;
01644     }
01645 
01646     eRet = adi_sense_SetChannelAdcFilter(hDevice, eChannelId,
01647                                          &pAdcChannelConfig->filter );
01648     if (eRet != ADI_SENSE_SUCCESS )
01649     {
01650         ADI_SENSE_LOG_ERROR("Failed to set ADC filter for channel %d",
01651                             eChannelId);
01652         return eRet;
01653     }
01654 
01655     eRet = adi_sense_SetChannelAdcCurrentConfig(hDevice, eChannelId,
01656                                                 &pAdcChannelConfig->current );
01657     if (eRet != ADI_SENSE_SUCCESS )
01658     {
01659         ADI_SENSE_LOG_ERROR("Failed to set ADC current for channel %d",
01660                             eChannelId);
01661         return eRet;
01662     }
01663 
01664     return ADI_SENSE_SUCCESS ;
01665 }
01666 
01667 
01668 static ADI_SENSE_RESULT  adi_sense_SetDigitalSensorCommands(
01669     ADI_SENSE_DEVICE_HANDLE  hDevice,
01670     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01671     ADI_SENSE_1000_DIGITAL_SENSOR_COMMAND  *pConfigCommand,
01672     ADI_SENSE_1000_DIGITAL_SENSOR_COMMAND  *pDataRequestCommand)
01673 {
01674     ADI_ADISENSE_CORE_Digital_Sensor_Num_Cmds_t numCmdsReg;
01675 
01676     numCmdsReg.VALUE8 = REG_RESET_VAL(CORE_DIGITAL_SENSOR_NUM_CMDSn);
01677 
01678     CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_NUM_CMDS_DIGITAL_SENSOR_NUM_CFG_CMDS,
01679                         pConfigCommand->commandLength );
01680     CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_NUM_CMDS_DIGITAL_SENSOR_NUM_READ_CMDS,
01681                         pDataRequestCommand->commandLength );
01682 
01683     numCmdsReg.Digital_Sensor_Num_Cfg_Cmds = pConfigCommand->commandLength ;
01684     numCmdsReg.Digital_Sensor_Num_Read_Cmds = pDataRequestCommand->commandLength ;
01685 
01686     WRITE_REG_U8(hDevice, numCmdsReg.VALUE8,
01687                  CORE_DIGITAL_SENSOR_NUM_CMDSn(eChannelId));
01688 
01689     switch (pConfigCommand->commandLength )
01690     {
01691         /* NOTE - intentional fall-through cases below */
01692     case 7:
01693         WRITE_REG_U8(hDevice, pConfigCommand->command [6],
01694                      CORE_DIGITAL_SENSOR_COMMAND7n(eChannelId));
01695     case 6:
01696         WRITE_REG_U8(hDevice, pConfigCommand->command [5],
01697                      CORE_DIGITAL_SENSOR_COMMAND6n(eChannelId));
01698     case 5:
01699         WRITE_REG_U8(hDevice, pConfigCommand->command [4],
01700                      CORE_DIGITAL_SENSOR_COMMAND5n(eChannelId));
01701     case 4:
01702         WRITE_REG_U8(hDevice, pConfigCommand->command [3],
01703                      CORE_DIGITAL_SENSOR_COMMAND4n(eChannelId));
01704     case 3:
01705         WRITE_REG_U8(hDevice, pConfigCommand->command [2],
01706                      CORE_DIGITAL_SENSOR_COMMAND3n(eChannelId));
01707     case 2:
01708         WRITE_REG_U8(hDevice, pConfigCommand->command [1],
01709                      CORE_DIGITAL_SENSOR_COMMAND2n(eChannelId));
01710     case 1:
01711         WRITE_REG_U8(hDevice, pConfigCommand->command [0],
01712                      CORE_DIGITAL_SENSOR_COMMAND1n(eChannelId));
01713     case 0:
01714     default:
01715         break;
01716     };
01717 
01718     switch (pDataRequestCommand->commandLength )
01719     {
01720         /* NOTE - intentional fall-through cases below */
01721     case 7:
01722         WRITE_REG_U8(hDevice, pDataRequestCommand->command [6],
01723                      CORE_DIGITAL_SENSOR_READ_CMD7n(eChannelId));
01724     case 6:
01725         WRITE_REG_U8(hDevice, pDataRequestCommand->command [5],
01726                      CORE_DIGITAL_SENSOR_READ_CMD6n(eChannelId));
01727     case 5:
01728         WRITE_REG_U8(hDevice, pDataRequestCommand->command [4],
01729                      CORE_DIGITAL_SENSOR_READ_CMD5n(eChannelId));
01730     case 4:
01731         WRITE_REG_U8(hDevice, pDataRequestCommand->command [3],
01732                      CORE_DIGITAL_SENSOR_READ_CMD4n(eChannelId));
01733     case 3:
01734         WRITE_REG_U8(hDevice, pDataRequestCommand->command [2],
01735                      CORE_DIGITAL_SENSOR_READ_CMD3n(eChannelId));
01736     case 2:
01737         WRITE_REG_U8(hDevice, pDataRequestCommand->command [1],
01738                      CORE_DIGITAL_SENSOR_READ_CMD2n(eChannelId));
01739     case 1:
01740         WRITE_REG_U8(hDevice, pDataRequestCommand->command [0],
01741                      CORE_DIGITAL_SENSOR_READ_CMD1n(eChannelId));
01742     case 0:
01743     default:
01744         break;
01745     };
01746 
01747     return ADI_SENSE_SUCCESS ;
01748 }
01749 
01750 static ADI_SENSE_RESULT  adi_sense_SetDigitalSensorFormat(
01751     ADI_SENSE_DEVICE_HANDLE  hDevice,
01752     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01753     ADI_SENSE_1000_DIGITAL_SENSOR_DATA_FORMAT  *pDataFormat)
01754 {
01755     ADI_ADISENSE_CORE_Digital_Sensor_Config_t sensorConfigReg;
01756 
01757     sensorConfigReg.VALUE16 = REG_RESET_VAL(CORE_DIGITAL_SENSOR_CONFIGn);
01758 
01759     if (pDataFormat->coding != ADI_SENSE_1000_DIGITAL_SENSOR_DATA_CODING_NONE)
01760     {
01761         if (pDataFormat->frameLength == 0)
01762         {
01763             ADI_SENSE_LOG_ERROR("Invalid frame length specified for digital sensor data format");
01764             return ADI_SENSE_INVALID_PARAM ;
01765         }
01766         if (pDataFormat->numDataBits == 0)
01767         {
01768             ADI_SENSE_LOG_ERROR("Invalid frame length specified for digital sensor data format");
01769             return ADI_SENSE_INVALID_PARAM ;
01770         }
01771 
01772         CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_CONFIG_DIGITAL_SENSOR_READ_BYTES,
01773                             pDataFormat->frameLength - 1);
01774         CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_CONFIG_DIGITAL_SENSOR_DATA_BITS,
01775                             pDataFormat->numDataBits - 1);
01776         CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_CONFIG_DIGITAL_SENSOR_BIT_OFFSET,
01777                             pDataFormat->bitOffset);
01778 
01779         sensorConfigReg.Digital_Sensor_Read_Bytes = pDataFormat->frameLength - 1;
01780         sensorConfigReg.Digital_Sensor_Data_Bits = pDataFormat->numDataBits - 1;
01781         sensorConfigReg.Digital_Sensor_Bit_Offset = pDataFormat->bitOffset;
01782         sensorConfigReg.Digital_Sensor_LeftAligned = pDataFormat->leftJustified ? 1 : 0;
01783         sensorConfigReg.Digital_Sensor_LittleEndian = pDataFormat->littleEndian ? 1 : 0;
01784 
01785         switch (pDataFormat->coding)
01786         {
01787         case ADI_SENSE_1000_DIGITAL_SENSOR_DATA_CODING_UNIPOLAR:
01788             sensorConfigReg.Digital_Sensor_Coding = ADISENSE_CORE_DIGITAL_SENSOR_CONFIG_CODING_UNIPOLAR;
01789             break;
01790         case ADI_SENSE_1000_DIGITAL_SENSOR_DATA_CODING_TWOS_COMPLEMENT:
01791             sensorConfigReg.Digital_Sensor_Coding = ADISENSE_CORE_DIGITAL_SENSOR_CONFIG_CODING_TWOS_COMPL;
01792             break;
01793         case ADI_SENSE_1000_DIGITAL_SENSOR_DATA_CODING_OFFSET_BINARY:
01794             sensorConfigReg.Digital_Sensor_Coding = ADISENSE_CORE_DIGITAL_SENSOR_CONFIG_CODING_OFFSET_BINARY;
01795             break;
01796         default:
01797             ADI_SENSE_LOG_ERROR("Invalid coding specified for digital sensor data format");
01798             return ADI_SENSE_INVALID_PARAM ;
01799         }
01800     }
01801 
01802     WRITE_REG_U16(hDevice, sensorConfigReg.VALUE16,
01803                   CORE_DIGITAL_SENSOR_CONFIGn(eChannelId));
01804 
01805 
01806     return ADI_SENSE_SUCCESS ;
01807 }
01808 
01809 static ADI_SENSE_RESULT  adi_sense_SetChannelI2cSensorType(
01810     ADI_SENSE_DEVICE_HANDLE  hDevice,
01811     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01812     ADI_SENSE_1000_I2C_SENSOR_TYPE  sensorType)
01813 {
01814     ADI_ADISENSE_CORE_Sensor_Type_t sensorTypeReg;
01815 
01816     sensorTypeReg.VALUE16 = REG_RESET_VAL(CORE_SENSOR_TYPEn);
01817 
01818     /* Ensure that the sensor type is valid for this channel */
01819     switch(sensorType)
01820     {
01821     case ADI_SENSE_1000_I2C_SENSOR_HUMIDITY_HONEYWELL_HUMIDICON :
01822         sensorTypeReg.Sensor_Type = ADISENSE_CORE_SENSOR_TYPE_SENSOR_I2C_HUMIDITY_HONEYWELL_HUMIDICON;
01823         break;
01824     case ADI_SENSE_1000_I2C_SENSOR_HUMIDITY_SENSIRION_SHT3X :
01825         sensorTypeReg.Sensor_Type = ADISENSE_CORE_SENSOR_TYPE_SENSOR_I2C_HUMIDITY_SENSIRION_SHT3X;
01826         break;
01827     default:
01828         ADI_SENSE_LOG_ERROR("Unsupported I2C sensor type %d specified", sensorType);
01829         return ADI_SENSE_INVALID_PARAM ;
01830     }
01831 
01832     WRITE_REG_U16(hDevice, sensorTypeReg.VALUE16, CORE_SENSOR_TYPEn(eChannelId));
01833 
01834     return ADI_SENSE_SUCCESS ;
01835 }
01836 
01837 static ADI_SENSE_RESULT  adi_sense_SetChannelI2cSensorAddress(
01838     ADI_SENSE_DEVICE_HANDLE  hDevice,
01839     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01840     uint32_t deviceAddress)
01841 {
01842     CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_ADDRESS_DIGITAL_SENSOR_ADDRESS, deviceAddress);
01843     WRITE_REG_U8(hDevice, deviceAddress, CORE_DIGITAL_SENSOR_ADDRESSn(eChannelId));
01844 
01845     return ADI_SENSE_SUCCESS ;
01846 }
01847 
01848 ADI_SENSE_RESULT  adi_sense_SetI2cChannelConfig(
01849     ADI_SENSE_DEVICE_HANDLE  hDevice,
01850     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01851     ADI_SENSE_1000_I2C_CHANNEL_CONFIG  *pI2cChannelConfig)
01852 {
01853     ADI_SENSE_RESULT  eRet;
01854 
01855     eRet = adi_sense_SetChannelI2cSensorType(hDevice, eChannelId,
01856                                             pI2cChannelConfig->sensor );
01857     if (eRet != ADI_SENSE_SUCCESS )
01858     {
01859         ADI_SENSE_LOG_ERROR("Failed to set I2C sensor type for channel %d",
01860                             eChannelId);
01861         return eRet;
01862     }
01863 
01864     eRet = adi_sense_SetChannelI2cSensorAddress(hDevice, eChannelId,
01865                                                pI2cChannelConfig->deviceAddress );
01866     if (eRet != ADI_SENSE_SUCCESS )
01867     {
01868         ADI_SENSE_LOG_ERROR("Failed to set I2C sensor address for channel %d",
01869                             eChannelId);
01870         return eRet;
01871     }
01872 
01873     eRet = adi_sense_SetDigitalSensorCommands(hDevice, eChannelId,
01874                                               &pI2cChannelConfig->configurationCommand ,
01875                                               &pI2cChannelConfig->dataRequestCommand );
01876     if (eRet != ADI_SENSE_SUCCESS )
01877     {
01878         ADI_SENSE_LOG_ERROR("Failed to set I2C sensor commands for channel %d",
01879                             eChannelId);
01880         return eRet;
01881     }
01882 
01883     eRet = adi_sense_SetDigitalSensorFormat(hDevice, eChannelId,
01884                                             &pI2cChannelConfig->dataFormat );
01885     if (eRet != ADI_SENSE_SUCCESS )
01886     {
01887         ADI_SENSE_LOG_ERROR("Failed to set I2C sensor data format for channel %d",
01888                             eChannelId);
01889         return eRet;
01890     }
01891 
01892     return ADI_SENSE_SUCCESS ;
01893 }
01894 
01895 static ADI_SENSE_RESULT  adi_sense_SetChannelSpiSensorType(
01896     ADI_SENSE_DEVICE_HANDLE  hDevice,
01897     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01898     ADI_SENSE_1000_SPI_SENSOR_TYPE  sensorType)
01899 {
01900     ADI_ADISENSE_CORE_Sensor_Type_t sensorTypeReg;
01901 
01902     sensorTypeReg.VALUE16 = REG_RESET_VAL(CORE_SENSOR_TYPEn);
01903 
01904     /* Ensure that the sensor type is valid for this channel */
01905     switch(sensorType)
01906     {
01907     case ADI_SENSE_1000_SPI_SENSOR_PRESSURE_HONEYWELL_TRUSTABILITY :
01908         sensorTypeReg.Sensor_Type = ADISENSE_CORE_SENSOR_TYPE_SENSOR_SPI_PRESSURE_HONEYWELL_TRUSTABILITY;
01909         break;
01910     case ADI_SENSE_1000_SPI_SENSOR_ACCELEROMETER_ADI_ADXL362 :
01911         sensorTypeReg.Sensor_Type = ADISENSE_CORE_SENSOR_TYPE_SENSOR_SPI_ACCELEROMETER_1;
01912         break;
01913     default:
01914         ADI_SENSE_LOG_ERROR("Unsupported SPI sensor type %d specified", sensorType);
01915         return ADI_SENSE_INVALID_PARAM ;
01916     }
01917 
01918     WRITE_REG_U16(hDevice, sensorTypeReg.VALUE16, CORE_SENSOR_TYPEn(eChannelId));
01919 
01920     return ADI_SENSE_SUCCESS ;
01921 }
01922 
01923 ADI_SENSE_RESULT  adi_sense_SetSpiChannelConfig(
01924     ADI_SENSE_DEVICE_HANDLE  hDevice,
01925     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01926     ADI_SENSE_1000_SPI_CHANNEL_CONFIG  *pSpiChannelConfig)
01927 {
01928     ADI_SENSE_RESULT  eRet;
01929 
01930     eRet = adi_sense_SetChannelSpiSensorType(hDevice, eChannelId,
01931                                              pSpiChannelConfig->sensor );
01932     if (eRet != ADI_SENSE_SUCCESS )
01933     {
01934         ADI_SENSE_LOG_ERROR("Failed to set SPI sensor type for channel %d",
01935                             eChannelId);
01936         return eRet;
01937     }
01938 
01939     eRet = adi_sense_SetDigitalSensorCommands(hDevice, eChannelId,
01940                                               &pSpiChannelConfig->configurationCommand ,
01941                                               &pSpiChannelConfig->dataRequestCommand );
01942     if (eRet != ADI_SENSE_SUCCESS )
01943     {
01944         ADI_SENSE_LOG_ERROR("Failed to set SPI sensor commands for channel %d",
01945                             eChannelId);
01946         return eRet;
01947     }
01948 
01949     eRet = adi_sense_SetDigitalSensorFormat(hDevice, eChannelId,
01950                                             &pSpiChannelConfig->dataFormat );
01951     if (eRet != ADI_SENSE_SUCCESS )
01952     {
01953         ADI_SENSE_LOG_ERROR("Failed to set SPI sensor data format for channel %d",
01954                             eChannelId);
01955         return eRet;
01956     }
01957 
01958     return ADI_SENSE_SUCCESS ;
01959 }
01960 
01961 ADI_SENSE_RESULT  adi_sense_1000_SetChannelThresholdLimits(
01962     ADI_SENSE_DEVICE_HANDLE  hDevice,
01963     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01964     float32_t fHighThresholdLimit,
01965     float32_t fLowThresholdLimit)
01966 {
01967     /*
01968      * If the low/high limits are *both* set to 0 in memory, or NaNs, assume
01969      * that they are unset, or not required, and use infinity defaults instead
01970      */
01971     if (fHighThresholdLimit == 0.0 && fLowThresholdLimit == 0.0)
01972     {
01973         fHighThresholdLimit = INFINITY;
01974         fLowThresholdLimit = -INFINITY;
01975     }
01976     else
01977     {
01978         if (isnan(fHighThresholdLimit))
01979             fHighThresholdLimit = INFINITY;
01980         if (isnan(fLowThresholdLimit))
01981             fLowThresholdLimit = -INFINITY;
01982     }
01983 
01984     WRITE_REG_FLOAT(hDevice, fHighThresholdLimit,
01985                     CORE_HIGH_THRESHOLD_LIMITn(eChannelId));
01986     WRITE_REG_FLOAT(hDevice, fLowThresholdLimit,
01987                     CORE_LOW_THRESHOLD_LIMITn(eChannelId));
01988 
01989     return ADI_SENSE_SUCCESS ;
01990 }
01991 
01992 ADI_SENSE_RESULT  adi_sense_1000_SetOffsetGain(
01993     ADI_SENSE_DEVICE_HANDLE  hDevice,
01994     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01995     float32_t fOffsetAdjustment,
01996     float32_t fGainAdjustment)
01997 {
01998     /* Replace with default values if NaNs are specified (or 0.0 for gain) */
01999     if (isnan(fGainAdjustment) || (fGainAdjustment == 0.0))
02000         fGainAdjustment = 1.0;
02001     if (isnan(fOffsetAdjustment))
02002         fOffsetAdjustment = 0.0;
02003 
02004     WRITE_REG_FLOAT(hDevice, fGainAdjustment, CORE_SENSOR_GAINn(eChannelId));
02005     WRITE_REG_FLOAT(hDevice, fOffsetAdjustment, CORE_SENSOR_OFFSETn(eChannelId));
02006 
02007     return ADI_SENSE_SUCCESS ;
02008 }
02009 
02010 ADI_SENSE_RESULT  adi_sense_1000_SetChannelSettlingTime(
02011     ADI_SENSE_DEVICE_HANDLE  hDevice,
02012     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
02013     uint32_t nSettlingTime)
02014 {
02015     CHECK_REG_FIELD_VAL(CORE_SETTLING_TIME_SETTLING_TIME, nSettlingTime);
02016 
02017     WRITE_REG_U16(hDevice, nSettlingTime, CORE_SETTLING_TIMEn(eChannelId));
02018 
02019     return ADI_SENSE_SUCCESS ;
02020 }
02021 
02022 ADI_SENSE_RESULT  adi_sense_1000_SetChannelConfig(
02023     ADI_SENSE_DEVICE_HANDLE  hDevice,
02024     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
02025     ADI_SENSE_1000_CHANNEL_CONFIG  *pChannelConfig)
02026 {
02027     ADI_SENSE_RESULT  eRet;
02028 
02029     if (! ADI_SENSE_1000_CHANNEL_IS_VIRTUAL(eChannelId))
02030     {
02031         /* If the channel is not enabled, disable it and return */
02032         if (! pChannelConfig->enableChannel )
02033             return adi_sense_1000_SetChannelCount(hDevice, eChannelId, 0);
02034 
02035         eRet = adi_sense_1000_SetChannelCount(hDevice, eChannelId,
02036                                               pChannelConfig->measurementsPerCycle );
02037         if (eRet != ADI_SENSE_SUCCESS )
02038         {
02039             ADI_SENSE_LOG_ERROR("Failed to set measurement count for channel %d",
02040                                 eChannelId);
02041             return eRet;
02042         }
02043 
02044         switch (eChannelId)
02045         {
02046         case ADI_SENSE_1000_CHANNEL_ID_CJC_0 :
02047         case ADI_SENSE_1000_CHANNEL_ID_CJC_1 :
02048         case ADI_SENSE_1000_CHANNEL_ID_SENSOR_0 :
02049         case ADI_SENSE_1000_CHANNEL_ID_SENSOR_1 :
02050         case ADI_SENSE_1000_CHANNEL_ID_SENSOR_2 :
02051         case ADI_SENSE_1000_CHANNEL_ID_SENSOR_3 :
02052         case ADI_SENSE_1000_CHANNEL_ID_VOLTAGE_0 :
02053         case ADI_SENSE_1000_CHANNEL_ID_CURRENT_0 :
02054             eRet = adi_sense_SetAdcChannelConfig(hDevice, eChannelId, pChannelConfig);
02055             break;
02056         case ADI_SENSE_1000_CHANNEL_ID_I2C_0 :
02057         case ADI_SENSE_1000_CHANNEL_ID_I2C_1 :
02058             eRet = adi_sense_SetI2cChannelConfig(hDevice, eChannelId,
02059                                                  &pChannelConfig->i2cChannelConfig );
02060             break;
02061         case ADI_SENSE_1000_CHANNEL_ID_SPI_0 :
02062             eRet = adi_sense_SetSpiChannelConfig(hDevice, eChannelId,
02063                                                  &pChannelConfig->spiChannelConfig );
02064             break;
02065         default:
02066             ADI_SENSE_LOG_ERROR("Invalid channel ID %d specified", eChannelId);
02067             return ADI_SENSE_INVALID_PARAM ;
02068         }
02069 
02070         eRet = adi_sense_1000_SetChannelSettlingTime(hDevice, eChannelId,
02071                                                      pChannelConfig->extraSettlingTime );
02072         if (eRet != ADI_SENSE_SUCCESS )
02073         {
02074             ADI_SENSE_LOG_ERROR("Failed to set settling time for channel %d",
02075                                 eChannelId);
02076             return eRet;
02077         }
02078     }
02079 
02080     if (pChannelConfig->enableChannel )
02081     {
02082         /* Threshold limits can be configured individually for virtual channels */
02083         eRet = adi_sense_1000_SetChannelThresholdLimits(hDevice, eChannelId,
02084                                                         pChannelConfig->highThreshold ,
02085                                                         pChannelConfig->lowThreshold );
02086         if (eRet != ADI_SENSE_SUCCESS )
02087         {
02088             ADI_SENSE_LOG_ERROR("Failed to set threshold limits for channel %d",
02089                                 eChannelId);
02090             return eRet;
02091         }
02092 
02093         /* Offset and gain can be configured individually for virtual channels */
02094         eRet = adi_sense_1000_SetOffsetGain(hDevice, eChannelId,
02095                                             pChannelConfig->offsetAdjustment ,
02096                                             pChannelConfig->gainAdjustment );
02097         if (eRet != ADI_SENSE_SUCCESS )
02098         {
02099             ADI_SENSE_LOG_ERROR("Failed to set offset/gain for channel %d",
02100                                 eChannelId);
02101             return eRet;
02102         }
02103     }
02104 
02105     return ADI_SENSE_SUCCESS ;
02106 }
02107 
02108 ADI_SENSE_RESULT  adi_sense_SetConfig(
02109     ADI_SENSE_DEVICE_HANDLE     const hDevice,
02110     ADI_SENSE_CONFIG          * const pConfig)
02111 {
02112     ADI_SENSE_1000_CONFIG  *pDeviceConfig;
02113     ADI_SENSE_PRODUCT_ID  productId;
02114     ADI_SENSE_RESULT  eRet;
02115 
02116     if (pConfig->productId  != ADI_SENSE_PRODUCT_ID_1000 )
02117     {
02118         ADI_SENSE_LOG_ERROR("Configuration Product ID (0x%X) is not supported (0x%0X)",
02119                             pConfig->productId , ADI_SENSE_PRODUCT_ID_1000 );
02120         return ADI_SENSE_INVALID_PARAM ;
02121     }
02122 
02123     /* Check that the actual Product ID is a match? */
02124     eRet = adi_sense_GetProductID(hDevice, &productId);
02125     if (eRet)
02126     {
02127         ADI_SENSE_LOG_ERROR("Failed to read device Product ID register");
02128         return eRet;
02129     }
02130     if (pConfig->productId  != productId)
02131     {
02132         ADI_SENSE_LOG_ERROR("Configuration Product ID (0x%X) does not match device (0x%0X)",
02133                             pConfig->productId , productId);
02134         return ADI_SENSE_INVALID_PARAM ;
02135     }
02136 
02137     pDeviceConfig = &pConfig->adisense1000 ;
02138 
02139     eRet = adi_sense_1000_SetPowerConfig(hDevice, &pDeviceConfig->power );
02140     if (eRet)
02141     {
02142         ADI_SENSE_LOG_ERROR("Failed to set power configuration");
02143         return eRet;
02144     }
02145 
02146     eRet = adi_sense_1000_SetMeasurementConfig(hDevice, &pDeviceConfig->measurement );
02147     if (eRet)
02148     {
02149         ADI_SENSE_LOG_ERROR("Failed to set measurement configuration");
02150         return eRet;
02151     }
02152 
02153     eRet = adi_sense_1000_SetDiagnosticsConfig(hDevice, &pDeviceConfig->diagnostics );
02154     if (eRet)
02155     {
02156         ADI_SENSE_LOG_ERROR("Failed to set diagnostics configuration");
02157         return eRet;
02158     }
02159 
02160     for (ADI_SENSE_1000_CHANNEL_ID  id = 0; id < ADI_SENSE_1000_MAX_CHANNELS ; id++)
02161     {
02162         eRet = adi_sense_1000_SetChannelConfig(hDevice, id,
02163                                                &pDeviceConfig->channels [id]);
02164         if (eRet)
02165         {
02166             ADI_SENSE_LOG_ERROR("Failed to set channel %d configuration", id);
02167             return eRet;
02168         }
02169     }
02170 
02171     return ADI_SENSE_SUCCESS ;
02172 }
02173 
02174 ADI_SENSE_RESULT  adi_sense_1000_SetLutData(
02175     ADI_SENSE_DEVICE_HANDLE     const hDevice,
02176     ADI_SENSE_1000_LUT       * const pLutData)
02177 {
02178     ADI_SENSE_1000_LUT_HEADER *pLutHeader = &pLutData->header;
02179     ADI_SENSE_1000_LUT_TABLE *pLutTable = pLutData->tables;
02180     unsigned actualLength = 0;
02181 
02182     if (pLutData->header.signature != ADI_SENSE_LUT_SIGNATURE)
02183     {
02184         ADI_SENSE_LOG_ERROR("LUT signature incorrect (expected 0x%X, actual 0x%X)",
02185                             ADI_SENSE_LUT_SIGNATURE, pLutHeader->signature);
02186         return ADI_SENSE_INVALID_SIGNATURE ;
02187     }
02188 
02189     for (unsigned i = 0; i < pLutHeader->numTables; i++)
02190     {
02191         ADI_SENSE_1000_LUT_DESCRIPTOR *pDesc = &pLutTable->descriptor;
02192         ADI_SENSE_1000_LUT_TABLE_DATA  *pData = &pLutTable->data;
02193         unsigned short calculatedCrc;
02194 
02195         switch (pDesc->geometry)
02196         {
02197         case ADI_SENSE_1000_LUT_GEOMETRY_COEFFS:
02198                 switch (pDesc->equation)
02199                 {
02200                 case ADI_SENSE_1000_LUT_EQUATION_POLYN:
02201                 case ADI_SENSE_1000_LUT_EQUATION_POLYNEXP:
02202                 case ADI_SENSE_1000_LUT_EQUATION_QUADRATIC:
02203                 case ADI_SENSE_1000_LUT_EQUATION_STEINHART:
02204                 case ADI_SENSE_1000_LUT_EQUATION_LOGARITHMIC:
02205                 case ADI_SENSE_1000_LUT_EQUATION_EXPONENTIAL:
02206                 case ADI_SENSE_1000_LUT_EQUATION_BIVARIATE_POLYN:
02207                 break;
02208                 default:
02209                     ADI_SENSE_LOG_ERROR("Invalid equation %u specified for LUT table %u",
02210                                         pDesc->equation, i);
02211                     return ADI_SENSE_INVALID_PARAM ;
02212                 }
02213             break;
02214         case ADI_SENSE_1000_LUT_GEOMETRY_NES_1D:
02215         case ADI_SENSE_1000_LUT_GEOMETRY_NES_2D:
02216         case ADI_SENSE_1000_LUT_GEOMETRY_ES_1D:
02217         case ADI_SENSE_1000_LUT_GEOMETRY_ES_2D:
02218                 if (pDesc->equation != ADI_SENSE_1000_LUT_EQUATION_LUT) {
02219                     ADI_SENSE_LOG_ERROR("Invalid equation %u specified for LUT table %u",
02220                                         pDesc->equation, i);
02221                     return ADI_SENSE_INVALID_PARAM ;
02222                 }
02223             break;
02224         default:
02225             ADI_SENSE_LOG_ERROR("Invalid geometry %u specified for LUT table %u",
02226                                 pDesc->geometry, i);
02227             return ADI_SENSE_INVALID_PARAM ;
02228         }
02229 
02230         switch (pDesc->dataType)
02231         {
02232         case ADI_SENSE_1000_LUT_DATA_TYPE_FLOAT32:
02233         case ADI_SENSE_1000_LUT_DATA_TYPE_FLOAT64:
02234             break;
02235         default:
02236             ADI_SENSE_LOG_ERROR("Invalid vector format %u specified for LUT table %u",
02237                                 pDesc->dataType, i);
02238             return ADI_SENSE_INVALID_PARAM ;
02239         }
02240 
02241         calculatedCrc = crc16_ccitt(pData, pDesc->length);
02242         if (calculatedCrc != pDesc->crc16)
02243         {
02244             ADI_SENSE_LOG_ERROR("CRC validation failed on LUT table %u (expected 0x%04X, actual 0x%04X)",
02245                                 i, pDesc->crc16, calculatedCrc);
02246             return ADI_SENSE_CRC_ERROR ;
02247         }
02248 
02249         actualLength += sizeof(*pDesc) + pDesc->length;
02250 
02251         /* Move to the next look-up table */
02252         pLutTable = (ADI_SENSE_1000_LUT_TABLE *)((uint8_t *)pLutTable + sizeof(*pDesc) + pDesc->length);
02253     }
02254 
02255     if (actualLength != pLutHeader->totalLength)
02256     {
02257         ADI_SENSE_LOG_ERROR("LUT table length mismatch (expected %u, actual %u)",
02258                             pLutHeader->totalLength, actualLength);
02259         return ADI_SENSE_WRONG_SIZE ;
02260     }
02261 
02262     if (sizeof(*pLutHeader) + pLutHeader->totalLength > ADI_SENSE_LUT_MAX_SIZE)
02263     {
02264         ADI_SENSE_LOG_ERROR("Maximum LUT table length (%u bytes) exceeded",
02265                             ADI_SENSE_LUT_MAX_SIZE);
02266         return ADI_SENSE_WRONG_SIZE ;
02267     }
02268 
02269     /* Write the LUT data to the device */
02270     unsigned lutSize = sizeof(*pLutHeader) + pLutHeader->totalLength;
02271     WRITE_REG_U16(hDevice, 0, CORE_LUT_OFFSET);
02272     WRITE_REG_U8_ARRAY(hDevice, (uint8_t *)pLutData, lutSize, CORE_LUT_DATA);
02273 
02274     return ADI_SENSE_SUCCESS ;
02275 }
02276 
02277 ADI_SENSE_RESULT  adi_sense_1000_SetLutDataRaw(
02278     ADI_SENSE_DEVICE_HANDLE     const hDevice,
02279     ADI_SENSE_1000_LUT_RAW   * const pLutData)
02280 {
02281     return adi_sense_1000_SetLutData(hDevice,
02282                                      (ADI_SENSE_1000_LUT * const)pLutData);
02283 }
02284 
02285 static ADI_SENSE_RESULT  getLutTableSize(
02286     ADI_SENSE_1000_LUT_DESCRIPTOR * const pDesc,
02287     ADI_SENSE_1000_LUT_TABLE_DATA  * const pData,
02288     unsigned *pLength)
02289 {
02290     switch (pDesc->geometry)
02291     {
02292     case ADI_SENSE_1000_LUT_GEOMETRY_COEFFS:
02293         if (pDesc->equation == ADI_SENSE_1000_LUT_EQUATION_BIVARIATE_POLYN)
02294             *pLength = ADI_SENSE_1000_LUT_2D_POLYN_COEFF_LIST_SIZE(pData->coeffList2d);
02295         else
02296             *pLength = ADI_SENSE_1000_LUT_COEFF_LIST_SIZE(pData->coeffList);
02297         break;
02298     case ADI_SENSE_1000_LUT_GEOMETRY_NES_1D:
02299         *pLength = ADI_SENSE_1000_LUT_1D_NES_SIZE(pData->lut1dNes);
02300         break;
02301     case ADI_SENSE_1000_LUT_GEOMETRY_NES_2D:
02302         *pLength = ADI_SENSE_1000_LUT_2D_NES_SIZE(pData->lut2dNes);
02303         break;
02304     case ADI_SENSE_1000_LUT_GEOMETRY_ES_1D:
02305         *pLength = ADI_SENSE_1000_LUT_1D_ES_SIZE(pData->lut1dEs);
02306         break;
02307     case ADI_SENSE_1000_LUT_GEOMETRY_ES_2D:
02308         *pLength = ADI_SENSE_1000_LUT_2D_ES_SIZE(pData->lut2dEs);
02309         break;
02310     default:
02311         ADI_SENSE_LOG_ERROR("Invalid LUT table geometry %d specified\r\n",
02312                             pDesc->geometry);
02313         return ADI_SENSE_INVALID_PARAM ;
02314     }
02315 
02316     return ADI_SENSE_SUCCESS ;
02317 }
02318 
02319 ADI_SENSE_RESULT  adi_sense_1000_AssembleLutData(
02320     ADI_SENSE_1000_LUT                  * pLutBuffer,
02321     unsigned                              nLutBufferSize,
02322     unsigned                        const nNumTables,
02323     ADI_SENSE_1000_LUT_DESCRIPTOR * const ppDesc[],
02324     ADI_SENSE_1000_LUT_TABLE_DATA  * const ppData[])
02325 {
02326     ADI_SENSE_1000_LUT_HEADER *pHdr = &pLutBuffer->header;
02327     uint8_t *pLutTableData = (uint8_t *)pLutBuffer + sizeof(*pHdr);
02328 
02329     if (sizeof(*pHdr) > nLutBufferSize)
02330     {
02331         ADI_SENSE_LOG_ERROR("Insufficient LUT buffer size provided");
02332         return ADI_SENSE_INVALID_PARAM ;
02333     }
02334 
02335     /* First initialise the top-level header */
02336     pHdr->signature = ADI_SENSE_LUT_SIGNATURE;
02337     pHdr->version.major = 1;
02338     pHdr->version.minor = 0;
02339     pHdr->numTables = 0;
02340     pHdr->totalLength = 0;
02341 
02342     /*
02343      * Walk through the list of table pointers provided, appending the table
02344      * descriptor+data from each one to the provided LUT buffer
02345      */
02346     for (unsigned i = 0; i < nNumTables; i++)
02347     {
02348         ADI_SENSE_1000_LUT_DESCRIPTOR * const pDesc = ppDesc[i];
02349         ADI_SENSE_1000_LUT_TABLE_DATA  * const pData = ppData[i];
02350         ADI_SENSE_RESULT  res;
02351         unsigned dataLength = 0;
02352 
02353         /* Calculate the length of the table data */
02354         res = getLutTableSize(pDesc, pData, &dataLength);
02355         if (res != ADI_SENSE_SUCCESS )
02356             return res;
02357 
02358         /* Fill in the table descriptor length and CRC fields */
02359         pDesc->length = dataLength;
02360         pDesc->crc16 = crc16_ccitt(pData, dataLength);
02361 
02362         if ((sizeof(*pHdr) + pHdr->totalLength + sizeof(*pDesc) + dataLength) > nLutBufferSize)
02363         {
02364             ADI_SENSE_LOG_ERROR("Insufficient LUT buffer size provided");
02365             return ADI_SENSE_INVALID_PARAM ;
02366         }
02367 
02368         /* Append the table to the LUT buffer (desc + data) */
02369         memcpy(pLutTableData + pHdr->totalLength, pDesc, sizeof(*pDesc));
02370         pHdr->totalLength += sizeof(*pDesc);
02371         memcpy(pLutTableData + pHdr->totalLength, pData, dataLength);
02372         pHdr->totalLength += dataLength;
02373 
02374         pHdr->numTables++;
02375     }
02376 
02377     return ADI_SENSE_SUCCESS ;
02378 }
02379 
02380 #define CAL_TABLE_ROWS ADI_SENSE_1000_CAL_NUM_TABLES
02381 #define CAL_TABLE_COLS ADI_SENSE_1000_CAL_NUM_TEMPS
02382 #define CAL_TABLE_SIZE (sizeof(float) * CAL_TABLE_ROWS * CAL_TABLE_COLS)
02383 
02384 ADI_SENSE_RESULT  adi_sense_1000_ReadCalTable(
02385     ADI_SENSE_DEVICE_HANDLE  hDevice,
02386     float *pfBuffer,
02387     unsigned nMaxLen,
02388     unsigned *pnDataLen,
02389     unsigned *pnRows,
02390     unsigned *pnColumns)
02391 {
02392     *pnDataLen = sizeof(float) * CAL_TABLE_ROWS * CAL_TABLE_COLS;
02393     *pnRows = CAL_TABLE_ROWS;
02394     *pnColumns = CAL_TABLE_COLS;
02395 
02396     if (nMaxLen > *pnDataLen)
02397         nMaxLen = *pnDataLen;
02398 
02399     WRITE_REG_U16(hDevice, 0, CORE_CAL_OFFSET);
02400     READ_REG_U8_ARRAY(hDevice, (uint8_t *)pfBuffer, nMaxLen, CORE_CAL_DATA);
02401 
02402     return ADI_SENSE_SUCCESS ;
02403 }
02404