Sean Wilson / Mbed OS AdiSense1000_V21

Fork of AdiSense1000 by PoC_Team

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 CONFIDENTIAL AND PROPRIETARY INFORMATION
00003 
00004 Copyright (c) 2018 Emutex Ltd. All rights reserved.
00005 This software and documentation contain confidential and
00006 proprietary information that is the property of
00007 Emutex Ltd. The software and documentation are
00008 furnished under a license agreement and may be used
00009 or copied only in accordance with the terms of the license
00010 agreement. No part of the software and documentation
00011 may be reproduced, transmitted, or translated, in any
00012 form or by any means, electronic, mechanical, manual,
00013 optical, or otherwise, without prior written permission
00014 of Emutex Ltd., or as expressly provided by the license agreement.
00015 Reverse engineering is prohibited, and reproduction,
00016 disclosure or use without specific written authorization
00017 of Emutex Ltd. is strictly forbidden.
00018  */
00019 
00020 /******************************************************************************
00021 Copyright 2017 (c) Analog Devices, Inc.
00022 
00023 All rights reserved.
00024 
00025 Redistribution and use in source and binary forms, with or without
00026 modification, are permitted provided that the following conditions are met:
00027   - Redistributions of source code must retain the above copyright
00028     notice, this list of conditions and the following disclaimer.
00029   - Redistributions in binary form must reproduce the above copyright
00030     notice, this list of conditions and the following disclaimer in
00031     the documentation and/or other materials provided with the
00032     distribution.
00033   - Neither the name of Analog Devices, Inc. nor the names of its
00034     contributors may be used to endorse or promote products derived
00035     from this software without specific prior written permission.
00036   - The use of this software may or may not infringe the patent rights
00037     of one or more patent holders. This license does not release you
00038     from the requirement that you obtain separate licenses from these
00039     patent holders to use this software.
00040   - Use of the software either in source or binary form, must be run
00041     on or directly connected to an Analog Devices Inc. component.
00042 
00043 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
00044 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
00045 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00046 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
00047 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00048 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
00049 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00050 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00051 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00052 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00053  *
00054  *****************************************************************************/
00055 
00056 /*!
00057  ******************************************************************************
00058  * @file:
00059  * @brief: ADISENSE API implementation for ADSNS1000
00060  *-----------------------------------------------------------------------------
00061  */
00062 
00063 #include <float.h>
00064 #include <math.h>
00065 #include <string.h>
00066 
00067 #include "inc/adi_sense_platform.h"
00068 #include "inc/adi_sense_api.h"
00069 #include "inc/adi_sense_1000/adi_sense_1000_api.h"
00070 
00071 #include "adi_sense_1000/ADISENSE1000_REGISTERS_typedefs.h"
00072 #include "adi_sense_1000/ADISENSE1000_REGISTERS.h"
00073 #include "adi_sense_1000/adi_sense_1000_lut_data.h"
00074 #include "adi_sense_1000/adi_sense_1000_host_comms.h"
00075 
00076 #include "crc16.h"
00077 
00078 /*
00079  * The following macros are used to encapsulate the register access code
00080  * to improve readability in the functions further below in this file
00081  */
00082 #define STRINGIFY(name) #name
00083 
00084 /* Expand the full name of the reset value macro for the specified register */
00085 #define REG_RESET_VAL(_name) REG_ADISENSE_##_name##_RESET
00086 
00087 /* Checks if a value is outside the bounds of the specified register field */
00088 #define CHECK_REG_FIELD_VAL(_field, _val)                               \
00089     do {                                                                \
00090         uint32_t _mask  = BITM_ADISENSE_##_field;                       \
00091         uint32_t _shift = BITP_ADISENSE_##_field;                       \
00092         if ((((_val) << _shift) & ~(_mask)) != 0) {                     \
00093             ADI_SENSE_LOG_ERROR("Value 0x%08X invalid for register field %s", \
00094                                 (uint32_t)(_val),                       \
00095                                 STRINGIFY(ADISENSE_##_field));          \
00096             return ADI_SENSE_INVALID_PARAM;                             \
00097         }                                                               \
00098     } while(false)
00099 
00100 /*
00101  * Encapsulates the write to a specified register
00102  * NOTE - this will cause the calling function to return on error
00103  */
00104 #define WRITE_REG(_hdev, _val, _name, _type)                            \
00105     do {                                                                \
00106         ADI_SENSE_RESULT _res;                                          \
00107         _type _regval = _val;                                           \
00108         _res = adi_sense_1000_WriteRegister((_hdev),                    \
00109                                             REG_ADISENSE_##_name,       \
00110                                             &_regval, sizeof(_regval)); \
00111         if (_res != ADI_SENSE_SUCCESS)                                  \
00112             return _res;                                                \
00113     } while(false)
00114 
00115 /* Wrapper macro to write a value to a uint32_t register */
00116 #define WRITE_REG_U32(_hdev, _val, _name)       \
00117     WRITE_REG(_hdev, _val, _name, uint32_t)
00118 /* Wrapper macro to write a value to a uint16_t register */
00119 #define WRITE_REG_U16(_hdev, _val, _name)       \
00120     WRITE_REG(_hdev, _val, _name, uint16_t)
00121 /* Wrapper macro to write a value to a uint8_t register */
00122 #define WRITE_REG_U8(_hdev, _val, _name)        \
00123     WRITE_REG(_hdev, _val, _name, uint8_t)
00124 /* Wrapper macro to write a value to a float32_t register */
00125 #define WRITE_REG_FLOAT(_hdev, _val, _name)     \
00126     WRITE_REG(_hdev, _val, _name, float32_t)
00127 
00128 /*
00129  * Encapsulates the read from a specified register
00130  * NOTE - this will cause the calling function to return on error
00131  */
00132 #define READ_REG(_hdev, _val, _name, _type)                             \
00133     do {                                                                \
00134         ADI_SENSE_RESULT _res;                                          \
00135         _type _regval;                                                  \
00136         _res = adi_sense_1000_ReadRegister((_hdev),                     \
00137                                            REG_ADISENSE_##_name,        \
00138                                            &_regval, sizeof(_regval));  \
00139         if (_res != ADI_SENSE_SUCCESS)                                  \
00140             return _res;                                                \
00141         _val = _regval;                                                 \
00142     } while(false)
00143 
00144 /* Wrapper macro to read a value from a uint32_t register */
00145 #define READ_REG_U32(_hdev, _val, _name)        \
00146     READ_REG(_hdev, _val, _name, uint32_t)
00147 /* Wrapper macro to read a value from a uint16_t register */
00148 #define READ_REG_U16(_hdev, _val, _name)        \
00149     READ_REG(_hdev, _val, _name, uint16_t)
00150 /* Wrapper macro to read a value from a uint8_t register */
00151 #define READ_REG_U8(_hdev, _val, _name)         \
00152     READ_REG(_hdev, _val, _name, uint8_t)
00153 /* Wrapper macro to read a value from a float32_t register */
00154 #define READ_REG_FLOAT(_hdev, _val, _name)      \
00155     READ_REG(_hdev, _val, _name, float32_t)
00156 
00157 /*
00158  * Wrapper macro to write an array of values to a uint8_t register
00159  * NOTE - this is intended only for writing to a keyhole data register
00160  */
00161 #define WRITE_REG_U8_ARRAY(_hdev, _arr, _len, _name)                \
00162     do {                                                            \
00163         ADI_SENSE_RESULT _res;                                      \
00164         _res = adi_sense_1000_WriteRegister(_hdev,                  \
00165                                             REG_ADISENSE_##_name,   \
00166                                             _arr, _len);            \
00167         if (_res != ADI_SENSE_SUCCESS)                              \
00168             return _res;                                            \
00169     } while(false)
00170 
00171 /*
00172  * Wrapper macro to read an array of values from a uint8_t register
00173  * NOTE - this is intended only for reading from a keyhole data register
00174  */
00175 #define READ_REG_U8_ARRAY(_hdev, _arr, _len, _name)                 \
00176     do {                                                            \
00177         ADI_SENSE_RESULT _res;                                      \
00178         _res = adi_sense_1000_ReadRegister((_hdev),                 \
00179                                            REG_ADISENSE_##_name,    \
00180                                            _arr, _len);             \
00181         if (_res != ADI_SENSE_SUCCESS)                              \
00182             return _res;                                            \
00183     } while(false)
00184 
00185 #define ADI_SENSE_1000_CHANNEL_IS_ADC(c)                                \
00186     ((c) >= ADI_SENSE_1000_CHANNEL_ID_CJC_0 && (c) <= ADI_SENSE_1000_CHANNEL_ID_CURRENT_0)
00187 
00188 #define ADI_SENSE_1000_CHANNEL_IS_ADC_CJC(c)                            \
00189     ((c) >= ADI_SENSE_1000_CHANNEL_ID_CJC_0 && (c) <= ADI_SENSE_1000_CHANNEL_ID_CJC_1)
00190 
00191 #define ADI_SENSE_1000_CHANNEL_IS_ADC_SENSOR(c)                         \
00192     ((c) >= ADI_SENSE_1000_CHANNEL_ID_SENSOR_0 && (c) <= ADI_SENSE_1000_CHANNEL_ID_SENSOR_3)
00193 
00194 #define ADI_SENSE_1000_CHANNEL_IS_ADC_VOLTAGE(c)    \
00195     ((c) == ADI_SENSE_1000_CHANNEL_ID_VOLTAGE_0)
00196 
00197 #define ADI_SENSE_1000_CHANNEL_IS_ADC_CURRENT(c)    \
00198     ((c) == ADI_SENSE_1000_CHANNEL_ID_CURRENT_0)
00199 
00200 #define ADI_SENSE_1000_CHANNEL_IS_VIRTUAL(c)                            \
00201     ((c) == ADI_SENSE_1000_CHANNEL_ID_SPI_1 || (c) == ADI_SENSE_1000_CHANNEL_ID_SPI_2)
00202 
00203 typedef struct
00204 {
00205     unsigned nDeviceIndex;
00206     ADI_SENSE_SPI_HANDLE  hSpi;
00207     ADI_SENSE_GPIO_HANDLE  hGpio;
00208 } ADI_SENSE_DEVICE_CONTEXT;
00209 
00210 static ADI_SENSE_DEVICE_CONTEXT gDeviceCtx[ADI_SENSE_PLATFORM_MAX_DEVICES];
00211 
00212 /*
00213  * Open an ADISENSE device instance.
00214  */
00215 ADI_SENSE_RESULT  adi_sense_Open(
00216     unsigned                   const nDeviceIndex,
00217     ADI_SENSE_CONNECTION      * const pConnectionInfo,
00218     ADI_SENSE_DEVICE_HANDLE   * const phDevice)
00219 {
00220     ADI_SENSE_DEVICE_CONTEXT *pCtx;
00221     ADI_SENSE_RESULT  eRet;
00222 
00223     if (nDeviceIndex >= ADI_SENSE_PLATFORM_MAX_DEVICES)
00224         return ADI_SENSE_INVALID_DEVICE_NUM ;
00225 
00226     pCtx = &gDeviceCtx[nDeviceIndex];
00227     pCtx->nDeviceIndex = nDeviceIndex;
00228 
00229     eRet = adi_sense_LogOpen(&pConnectionInfo->log );
00230     if (eRet != ADI_SENSE_SUCCESS )
00231         return eRet;
00232 
00233     eRet = adi_sense_GpioOpen(&pConnectionInfo->gpio , &pCtx->hGpio);
00234     if (eRet != ADI_SENSE_SUCCESS )
00235         return eRet;
00236 
00237     eRet = adi_sense_SpiOpen(&pConnectionInfo->spi , &pCtx->hSpi);
00238     if (eRet != ADI_SENSE_SUCCESS )
00239         return eRet;
00240 
00241     *phDevice = pCtx;
00242     return ADI_SENSE_SUCCESS ;
00243 }
00244 
00245 /*
00246  * Get the current state of the specified GPIO input signal.
00247  */
00248 ADI_SENSE_RESULT  adi_sense_GetGpioState(
00249     ADI_SENSE_DEVICE_HANDLE    const hDevice,
00250     ADI_SENSE_GPIO_PIN         const ePinId,
00251     bool_t                  * const pbAsserted)
00252 {
00253     ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
00254 
00255     return adi_sense_GpioGet(pCtx->hGpio, ePinId, pbAsserted);
00256 }
00257 
00258 /*
00259  * Register an application-defined callback function for GPIO interrupts.
00260  */
00261 ADI_SENSE_RESULT  adi_sense_RegisterGpioCallback(
00262     ADI_SENSE_DEVICE_HANDLE           const hDevice,
00263     ADI_SENSE_GPIO_PIN                const ePinId,
00264     ADI_SENSE_GPIO_CALLBACK           const callbackFunction,
00265     void                           * const pCallbackParam)
00266 {
00267     ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
00268 
00269     if (callbackFunction)
00270     {
00271         return adi_sense_GpioIrqEnable(pCtx->hGpio, ePinId, callbackFunction,
00272                                        pCallbackParam);
00273     }
00274     else
00275     {
00276         return adi_sense_GpioIrqDisable(pCtx->hGpio, ePinId);
00277     }
00278 }
00279 
00280 /*
00281  * Reset the specified ADISENSE device.
00282  */
00283 ADI_SENSE_RESULT  adi_sense_Reset(
00284     ADI_SENSE_DEVICE_HANDLE     const hDevice)
00285 {
00286     ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
00287     ADI_SENSE_RESULT  eRet;
00288 
00289     /* Pulse the Reset GPIO pin low for a minimum of 4 microseconds */
00290     eRet = adi_sense_GpioSet(pCtx->hGpio, ADI_SENSE_GPIO_PIN_RESET , false);
00291     if (eRet != ADI_SENSE_SUCCESS )
00292         return eRet;
00293 
00294     adi_sense_TimeDelayUsec(4);
00295 
00296     eRet = adi_sense_GpioSet(pCtx->hGpio, ADI_SENSE_GPIO_PIN_RESET , true);
00297     if (eRet != ADI_SENSE_SUCCESS )
00298         return eRet;
00299 
00300     return ADI_SENSE_SUCCESS ;
00301 }
00302 
00303 
00304 /*!
00305  * @brief Get general status of ADISense module.
00306  *
00307  * @param[in]
00308  * @param[out] pStatus : Pointer to CORE Status struct.
00309  *
00310  * @return Status
00311  *         - #ADI_SENSE_SUCCESS Call completed successfully.
00312  *         - #ADI_SENSE_FAILURE If status register read fails.
00313  *
00314  * @details Read the general status register for the ADISense
00315  *          module. Indicates Error, Alert conditions, data ready
00316  *          and command running.
00317  *
00318  */
00319 ADI_SENSE_RESULT  adi_sense_GetStatus(
00320     ADI_SENSE_DEVICE_HANDLE     const hDevice,
00321     ADI_SENSE_STATUS          * const pStatus)
00322 {
00323     ADI_ADISENSE_CORE_Status_t statusReg;
00324     READ_REG_U8(hDevice, statusReg.VALUE8, CORE_STATUS);
00325 
00326     ADI_ADISENSE_CORE_Alert_Status_2_t alert2Reg;
00327     READ_REG_U16(hDevice, alert2Reg.VALUE16, CORE_ALERT_STATUS_2);
00328 
00329     memset(pStatus, 0, sizeof(*pStatus));
00330 
00331     if (!statusReg.Cmd_Running) /* Active-low, so invert it */
00332         pStatus->deviceStatus  |= ADI_SENSE_DEVICE_STATUS_BUSY ;
00333     if (statusReg.Drdy)
00334         pStatus->deviceStatus  |= ADI_SENSE_DEVICE_STATUS_DATAREADY ;
00335     if (statusReg.FIFO_Error)
00336         pStatus->deviceStatus  |= ADI_SENSE_DEVICE_STATUS_FIFO_ERROR ;
00337     if (alert2Reg.Ext_Flash_Error)
00338         pStatus->deviceStatus  |= ADI_SENSE_DEVICE_STATUS_EXT_FLASH_ERROR ;
00339     if (statusReg.Alert_Active)
00340     {
00341         pStatus->deviceStatus  |= ADI_SENSE_DEVICE_STATUS_ALERT ;
00342 
00343         ADI_ADISENSE_CORE_Alert_Code_t alertCodeReg;
00344         READ_REG_U16(hDevice, alertCodeReg.VALUE16, CORE_ALERT_CODE);
00345         pStatus->alertCode  = alertCodeReg.Alert_Code;
00346 
00347         ADI_ADISENSE_CORE_Channel_Alert_Status_t channelAlertStatusReg;
00348         READ_REG_U16(hDevice, channelAlertStatusReg.VALUE16,
00349                      CORE_CHANNEL_ALERT_STATUS);
00350 
00351         for (unsigned i = 0; i < ADI_SENSE_1000_MAX_CHANNELS ; i++)
00352         {
00353             if (channelAlertStatusReg.VALUE16 & (1 << i))
00354             {
00355                 ADI_ADISENSE_CORE_Alert_Code_Ch_t channelAlertCodeReg;
00356                 READ_REG_U16(hDevice, channelAlertCodeReg.VALUE16, CORE_ALERT_CODE_CHn(i));
00357                 pStatus->channelAlertCodes [i] = channelAlertCodeReg.Alert_Code_Ch;
00358 
00359                 ADI_ADISENSE_CORE_Alert_Detail_Ch_t alertDetailReg;
00360                 READ_REG_U16(hDevice, alertDetailReg.VALUE16,
00361                              CORE_ALERT_DETAIL_CHn(i));
00362 
00363                 if (alertDetailReg.Time_Out)
00364                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_TIMEOUT ;
00365                 if (alertDetailReg.Under_Range)
00366                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_UNDER_RANGE ;
00367                 if (alertDetailReg.Over_Range)
00368                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_OVER_RANGE ;
00369                 if (alertDetailReg.Low_Limit)
00370                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_LOW_LIMIT ;
00371                 if (alertDetailReg.High_Limit)
00372                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_HIGH_LIMIT ;
00373                 if (alertDetailReg.Sensor_Open)
00374                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_SENSOR_OPEN ;
00375                 if (alertDetailReg.Ref_Detect)
00376                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_REF_DETECT ;
00377                 if (alertDetailReg.Config_Err)
00378                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_CONFIG_ERR ;
00379                 if (alertDetailReg.LUT_Error_Ch)
00380                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_LUT_ERR ;
00381                 if (alertDetailReg.Sensor_Not_Ready)
00382                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_SENSOR_NOT_READY ;
00383                 if (alertDetailReg.Comp_Not_Ready)
00384                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_COMP_NOT_READY ;
00385                 if (alertDetailReg.Correction_UnderRange)
00386                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_LUT_UNDER_RANGE ;
00387                 if (alertDetailReg.Correction_OverRange)
00388                     pStatus->channelAlerts [i] |= ADI_SENSE_CHANNEL_ALERT_LUT_OVER_RANGE ;
00389             }
00390         }
00391 
00392         if (alert2Reg.Configuration_Error)
00393             pStatus->deviceStatus  |= ADI_SENSE_DEVICE_STATUS_CONFIG_ERROR ;
00394         if (alert2Reg.LUT_Error)
00395             pStatus->deviceStatus  |= ADI_SENSE_DEVICE_STATUS_LUT_ERROR ;
00396     }
00397 
00398     if (statusReg.Error)
00399     {
00400         pStatus->deviceStatus  |= ADI_SENSE_DEVICE_STATUS_ERROR ;
00401 
00402         ADI_ADISENSE_CORE_Error_Code_t errorCodeReg;
00403         READ_REG_U16(hDevice, errorCodeReg.VALUE16, CORE_ERROR_CODE);
00404         pStatus->errorCode  = errorCodeReg.Error_Code;
00405 
00406         ADI_ADISENSE_CORE_Diagnostics_Status_t diagStatusReg;
00407         READ_REG_U16(hDevice, diagStatusReg.VALUE16, CORE_DIAGNOSTICS_STATUS);
00408 
00409         if (diagStatusReg.Diag_Checksum_Error)
00410             pStatus->diagnosticsStatus  |= ADI_SENSE_DIAGNOSTICS_STATUS_CHECKSUM_ERROR ;
00411         if (diagStatusReg.Diag_Comms_Error)
00412             pStatus->diagnosticsStatus  |= ADI_SENSE_DIAGNOSTICS_STATUS_COMMS_ERROR ;
00413         if (diagStatusReg.Diag_Supply_Monitor_Error)
00414             pStatus->diagnosticsStatus  |= ADI_SENSE_DIAGNOSTICS_STATUS_SUPPLY_MONITOR_ERROR ;
00415         if (diagStatusReg.Diag_Supply_Cap_Error)
00416             pStatus->diagnosticsStatus  |= ADI_SENSE_DIAGNOSTICS_STATUS_SUPPLY_CAP_ERROR ;
00417         if (diagStatusReg.Diag_Conversion_Error)
00418             pStatus->diagnosticsStatus  |= ADI_SENSE_DIAGNOSTICS_STATUS_CONVERSION_ERROR ;
00419         if (diagStatusReg.Diag_Calibration_Error)
00420             pStatus->diagnosticsStatus  |= ADI_SENSE_DIAGNOSTICS_STATUS_CALIBRATION_ERROR ;
00421     }
00422 
00423     return ADI_SENSE_SUCCESS ;
00424 }
00425 
00426 ADI_SENSE_RESULT  adi_sense_GetCommandRunningState(
00427     ADI_SENSE_DEVICE_HANDLE  hDevice,
00428     bool_t *pbCommandRunning)
00429 {
00430     ADI_ADISENSE_CORE_Status_t statusReg;
00431 
00432     READ_REG_U8(hDevice, statusReg.VALUE8, CORE_STATUS);
00433 
00434     /* We should never normally see 0xFF here if the module is operational */
00435     if (statusReg.VALUE8 == 0xFF)
00436         return ADI_SENSE_ERR_NOT_INITIALIZED ;
00437 
00438     *pbCommandRunning = !statusReg.Cmd_Running; /* Active-low, so invert it */
00439 
00440     return ADI_SENSE_SUCCESS ;
00441 }
00442 
00443 static ADI_SENSE_RESULT  executeCommand(
00444     ADI_SENSE_DEVICE_HANDLE  const hDevice,
00445     ADI_ADISENSE_CORE_Command_Special_Command  const command,
00446     bool_t const bWaitForCompletion)
00447 {
00448     ADI_ADISENSE_CORE_Command_t commandReg;
00449     bool_t bCommandRunning;
00450     ADI_SENSE_RESULT  eRet;
00451 
00452     /*
00453      * Don't allow another command to be issued if one is already running, but
00454      * make an exception for ADISENSE_CORE_COMMAND_NOP which can be used to
00455      * request a running command to be stopped (e.g. continuous measurement)
00456      */
00457     if (command != ADISENSE_CORE_COMMAND_NOP)
00458     {
00459         eRet = adi_sense_GetCommandRunningState(hDevice, &bCommandRunning);
00460         if (eRet)
00461             return eRet;
00462 
00463         if (bCommandRunning)
00464             return ADI_SENSE_IN_USE ;
00465     }
00466 
00467     commandReg.Special_Command = command;
00468     WRITE_REG_U8(hDevice, commandReg.VALUE8, CORE_COMMAND);
00469 
00470     if (bWaitForCompletion)
00471     {
00472         do {
00473             /* Allow a minimum 50usec delay for status update before checking */
00474             adi_sense_TimeDelayUsec(50);
00475 
00476             eRet = adi_sense_GetCommandRunningState(hDevice, &bCommandRunning);
00477             if (eRet)
00478                 return eRet;
00479         } while (bCommandRunning);
00480     }
00481 
00482     return ADI_SENSE_SUCCESS ;
00483 }
00484 
00485 ADI_SENSE_RESULT  adi_sense_Shutdown(
00486     ADI_SENSE_DEVICE_HANDLE  const hDevice)
00487 {
00488     return executeCommand(hDevice, ADISENSE_CORE_COMMAND_POWER_DOWN, false);
00489 }
00490 
00491 
00492 ADI_SENSE_RESULT  adi_sense_ApplyConfigUpdates(
00493     ADI_SENSE_DEVICE_HANDLE  const hDevice)
00494 {
00495     return executeCommand(hDevice, ADISENSE_CORE_COMMAND_LATCH_CONFIG, true);
00496 }
00497 
00498 /*!
00499  * @brief Start a measurement cycle.
00500  *
00501  * @param[out]
00502  *
00503  * @return Status
00504  *         - #ADI_SENSE_SUCCESS Call completed successfully.
00505  *         - #ADI_SENSE_FAILURE
00506  *
00507  * @details Sends the latch config command. Configuration for channels in
00508  *          conversion cycle should be completed before this function.
00509  *          Channel enabled bit should be set before this function.
00510  *          Starts a conversion and configures the format of the sample.
00511  *
00512  */
00513 ADI_SENSE_RESULT  adi_sense_StartMeasurement(
00514     ADI_SENSE_DEVICE_HANDLE     const hDevice,
00515     ADI_SENSE_MEASUREMENT_MODE  const eMeasurementMode)
00516 {
00517     switch (eMeasurementMode)
00518     {
00519     case ADI_SENSE_MEASUREMENT_MODE_HEALTHCHECK :
00520         return executeCommand(hDevice, ADISENSE_CORE_COMMAND_SYSTEM_CHECK, false);
00521     case ADI_SENSE_MEASUREMENT_MODE_NORMAL :
00522         return executeCommand(hDevice, ADISENSE_CORE_COMMAND_CONVERT_WITH_RAW, false);
00523     case ADI_SENSE_MEASUREMENT_MODE_OMIT_RAW :
00524         return executeCommand(hDevice, ADISENSE_CORE_COMMAND_CONVERT, false);
00525     case ADI_SENSE_MEASUREMENT_MODE_FFT :
00526         return executeCommand(hDevice, ADISENSE_CORE_COMMAND_CONVERT_FFT, false);
00527     default:
00528         ADI_SENSE_LOG_ERROR("Invalid measurement mode %d specified",
00529                             eMeasurementMode);
00530         return ADI_SENSE_INVALID_PARAM ;
00531     }
00532 }
00533 
00534 /*
00535  * Store the configuration settings to persistent memory on the device.
00536  * The settings can be saved to 4 different flash memory areas (slots).
00537  * No other command must be running when this is called.
00538  * Do not power down the device while this command is running.
00539  */
00540 ADI_SENSE_RESULT  adi_sense_SaveConfig(
00541     ADI_SENSE_DEVICE_HANDLE     const hDevice,
00542     ADI_SENSE_USER_CONFIG_SLOT  const eSlotId)
00543 {
00544     switch (eSlotId)
00545     {
00546         case ADI_SENSE_FLASH_CONFIG_1:
00547             return executeCommand(hDevice, ADISENSE_CORE_COMMAND_SAVE_CONFIG_1, true);
00548         case ADI_SENSE_FLASH_CONFIG_2:
00549             return executeCommand(hDevice, ADISENSE_CORE_COMMAND_SAVE_CONFIG_2, true);
00550         case ADI_SENSE_FLASH_CONFIG_3:
00551             return executeCommand(hDevice, ADISENSE_CORE_COMMAND_SAVE_CONFIG_3, true);
00552         case ADI_SENSE_FLASH_CONFIG_4:
00553             return executeCommand(hDevice, ADISENSE_CORE_COMMAND_SAVE_CONFIG_4, true);
00554         default:
00555             ADI_SENSE_LOG_ERROR("Invalid user config target slot %d specified",
00556                                 eSlotId);
00557             return ADI_SENSE_INVALID_PARAM ;
00558     }
00559 }
00560 
00561 /*
00562  * Restore the configuration settings from persistent memory on the device.
00563  * No other command must be running when this is called.
00564  */
00565 ADI_SENSE_RESULT  adi_sense_RestoreConfig(
00566     ADI_SENSE_DEVICE_HANDLE     const hDevice,
00567     ADI_SENSE_USER_CONFIG_SLOT  const eSlotId)
00568 {
00569     switch (eSlotId)
00570     {
00571         case ADI_SENSE_FLASH_CONFIG_1:
00572             return executeCommand(hDevice, ADISENSE_CORE_COMMAND_LOAD_CONFIG_1, true);
00573         case ADI_SENSE_FLASH_CONFIG_2:
00574             return executeCommand(hDevice, ADISENSE_CORE_COMMAND_LOAD_CONFIG_2, true);
00575         case ADI_SENSE_FLASH_CONFIG_3:
00576             return executeCommand(hDevice, ADISENSE_CORE_COMMAND_LOAD_CONFIG_3, true);
00577         case ADI_SENSE_FLASH_CONFIG_4:
00578             return executeCommand(hDevice, ADISENSE_CORE_COMMAND_LOAD_CONFIG_4, true);
00579         default:
00580             ADI_SENSE_LOG_ERROR("Invalid user config source slot %d specified",
00581                                 eSlotId);
00582             return ADI_SENSE_INVALID_PARAM ;
00583     }
00584 }
00585 
00586 /*
00587  * Erase the entire external flash memory.
00588  * No other command must be running when this is called.
00589  */
00590 ADI_SENSE_RESULT  adi_sense_EraseExternalFlash(
00591     ADI_SENSE_DEVICE_HANDLE     const hDevice)
00592 {
00593     return executeCommand(hDevice, ADISENSE_CORE_COMMAND_ERASE_EXTERNAL_FLASH, true);
00594 }
00595 
00596 /*
00597  * Read the number of samples stored in external flash memory.
00598  * No other command must be running when this is called.
00599  */
00600 ADI_SENSE_RESULT  adi_sense_GetExternalFlashSampleCount(
00601     ADI_SENSE_DEVICE_HANDLE     const hDevice,
00602     uint32_t * nSampleCount)
00603 {
00604     ADI_ADISENSE_CORE_Ext_Flash_Sample_Count_t nCount;
00605 
00606     READ_REG_U32(hDevice, nCount.VALUE32, CORE_EXT_FLASH_SAMPLE_COUNT);
00607 
00608     *nSampleCount = nCount.VALUE32;
00609 
00610     return ADI_SENSE_SUCCESS ;
00611 }
00612 
00613 // DEBUG - TO BE DELETED
00614 ADI_SENSE_RESULT  adi_sense_SetExternalFlashIndex(
00615     ADI_SENSE_DEVICE_HANDLE     const hDevice,
00616     uint32_t nStartIndex)
00617 {
00618     WRITE_REG_U32(hDevice, nStartIndex, CORE_EXT_FLASH_INDEX);
00619 
00620     return ADI_SENSE_SUCCESS ;
00621 }
00622 
00623 /*
00624  * Read a set of data samples stored in the device external flash memory.
00625  * This may be called at any time.
00626  */
00627 ADI_SENSE_RESULT  adi_sense_GetExternalFlashData(
00628     ADI_SENSE_DEVICE_HANDLE     const hDevice,
00629     ADI_SENSE_DATA_SAMPLE     * const pSamples,
00630     uint32_t                   const nStartIndex,
00631     uint32_t                   const nRequested,
00632     uint32_t                 * const pnReturned)
00633 {
00634     ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
00635     uint16_t command = ADI_SENSE_1000_HOST_COMMS_READ_CMD |
00636         (REG_ADISENSE_CORE_EXT_FLASH_DATA & ADI_SENSE_1000_HOST_COMMS_ADR_MASK);
00637     uint8_t commandData[2] = {
00638         command >> 8,
00639         command & 0xFF
00640     };
00641     uint8_t commandResponse[2];
00642     unsigned nValidSamples = 0;
00643     ADI_SENSE_RESULT  eRet = ADI_SENSE_SUCCESS ;
00644 
00645     /* Setup initial sample */
00646     WRITE_REG_U32(hDevice, nStartIndex, CORE_EXT_FLASH_INDEX);
00647 
00648     /* Send flash read command */
00649     do {
00650         eRet = adi_sense_SpiTransfer(pCtx->hSpi, commandData, commandResponse,
00651                                      sizeof(command), false);
00652         if (eRet)
00653         {
00654             ADI_SENSE_LOG_ERROR("Failed to send read command for external flash");
00655             return eRet;
00656         }
00657 
00658         adi_sense_TimeDelayUsec(ADI_SENSE_1000_HOST_COMMS_XFER_DELAY);
00659     } while ((commandResponse[0] != ADI_SENSE_1000_HOST_COMMS_CMD_RESP_0) ||
00660              (commandResponse[1] != ADI_SENSE_1000_HOST_COMMS_CMD_RESP_1));
00661 
00662     /* Read samples from external flash memory */
00663     for (unsigned i = 0; i < nRequested; i++)
00664     {
00665         ADI_SENSE_1000_Sensor_Result_t  sensorResult;
00666         bool_t bHoldCs = true;
00667 
00668         /* Keep the CS signal asserted for all but the last sample */
00669         if ((i + 1) == nRequested)
00670             bHoldCs = false;
00671 
00672         eRet = adi_sense_SpiTransfer(pCtx->hSpi, NULL, (uint8_t *) (&sensorResult),
00673                                      8, bHoldCs);
00674         if (eRet)
00675         {
00676             ADI_SENSE_LOG_ERROR("Failed to read data from external flash");
00677             return eRet;
00678         }
00679 
00680         ADI_SENSE_DATA_SAMPLE  *pSample = &pSamples[nValidSamples];
00681 
00682         pSample->status  = (ADI_SENSE_DEVICE_STATUS_FLAGS )0;
00683         if (sensorResult.Ch_Error)
00684             pSample->status  |= ADI_SENSE_DEVICE_STATUS_ERROR ;
00685         if (sensorResult.Ch_Alert)
00686             pSample->status  |= ADI_SENSE_DEVICE_STATUS_ALERT ;
00687 
00688         if (sensorResult.Ch_Raw)
00689             pSample->rawValue  = sensorResult.Raw_Sample;
00690         else
00691             pSample->rawValue  = 0;
00692 
00693         pSample->channelId  = sensorResult.Channel_ID;
00694         pSample->processedValue  = sensorResult.Sensor_Result;
00695 
00696         nValidSamples++;
00697     }
00698     *pnReturned = nValidSamples;
00699 
00700     adi_sense_TimeDelayUsec(ADI_SENSE_1000_HOST_COMMS_XFER_DELAY);
00701 
00702     return eRet;
00703 }
00704 
00705 
00706 /*
00707  * Store the LUT data to persistent memory on the device.
00708  * No other command must be running when this is called.
00709  * Do not power down the device while this command is running.
00710  */
00711 ADI_SENSE_RESULT  adi_sense_SaveLutData(
00712     ADI_SENSE_DEVICE_HANDLE     const hDevice)
00713 {
00714     return executeCommand(hDevice, ADISENSE_CORE_COMMAND_SAVE_LUT, true);
00715 }
00716 
00717 /*
00718  * Restore the LUT data from persistent memory on the device.
00719  * No other command must be running when this is called.
00720  */
00721 ADI_SENSE_RESULT  adi_sense_RestoreLutData(
00722     ADI_SENSE_DEVICE_HANDLE     const hDevice)
00723 {
00724     return executeCommand(hDevice, ADISENSE_CORE_COMMAND_LOAD_LUT, true);
00725 }
00726 
00727 /*
00728  * Stop the measurement cycles on the device.
00729  * To be used only if a measurement command is currently running.
00730  */
00731 ADI_SENSE_RESULT  adi_sense_StopMeasurement(
00732     ADI_SENSE_DEVICE_HANDLE     const hDevice)
00733 {
00734     return executeCommand(hDevice, ADISENSE_CORE_COMMAND_NOP, true);
00735 }
00736 
00737 /*
00738  * Run built-in diagnostic checks on the device.
00739  * Diagnostics are executed according to the current applied settings.
00740  * No other command must be running when this is called.
00741  */
00742 ADI_SENSE_RESULT  adi_sense_RunDiagnostics(
00743     ADI_SENSE_DEVICE_HANDLE     const hDevice)
00744 {
00745     return executeCommand(hDevice, ADISENSE_CORE_COMMAND_RUN_DIAGNOSTICS, true);
00746 }
00747 
00748 /*
00749  * Run self-calibration routines on the device.
00750  * Calibration is executed according to the current applied settings.
00751  * No other command must be running when this is called.
00752  */
00753 ADI_SENSE_RESULT  adi_sense_RunCalibration(
00754     ADI_SENSE_DEVICE_HANDLE     const hDevice)
00755 {
00756     return executeCommand(hDevice, ADISENSE_CORE_COMMAND_SELF_CALIBRATION, true);
00757 }
00758 
00759 /*
00760  * Run digital calibration routines on the device.
00761  * Calibration is executed according to the current applied settings.
00762  * No other command must be running when this is called.
00763  */
00764 ADI_SENSE_RESULT  adi_sense_RunDigitalCalibration(
00765     ADI_SENSE_DEVICE_HANDLE     const hDevice)
00766 {
00767     return executeCommand(hDevice, ADISENSE_CORE_COMMAND_CALIBRATE_DIGITAL, true);
00768 }
00769 
00770 /*
00771  * Read a set of data samples from the device.
00772  * This may be called at any time.
00773  */
00774 ADI_SENSE_RESULT  adi_sense_GetData(
00775     ADI_SENSE_DEVICE_HANDLE     const hDevice,
00776     ADI_SENSE_MEASUREMENT_MODE  const eMeasurementMode,
00777     ADI_SENSE_DATA_SAMPLE     * const pSamples,
00778     uint8_t                    const nBytesPerSample,
00779     uint32_t                   const nRequested,
00780     uint32_t                 * const pnReturned)
00781 {
00782     ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
00783     uint16_t command = ADI_SENSE_1000_HOST_COMMS_READ_CMD |
00784         (REG_ADISENSE_CORE_DATA_FIFO & ADI_SENSE_1000_HOST_COMMS_ADR_MASK);
00785     uint8_t commandData[2] = {
00786         command >> 8,
00787         command & 0xFF
00788     };
00789     uint8_t commandResponse[2];
00790     unsigned nValidSamples = 0;
00791     ADI_SENSE_RESULT  eRet = ADI_SENSE_SUCCESS ;
00792 
00793     do {
00794         eRet = adi_sense_SpiTransfer(pCtx->hSpi, commandData, commandResponse,
00795                                      sizeof(command), false);
00796         if (eRet)
00797         {
00798             ADI_SENSE_LOG_ERROR("Failed to send read command for FIFO register");
00799             return eRet;
00800         }
00801         adi_sense_TimeDelayUsec(ADI_SENSE_1000_HOST_COMMS_XFER_DELAY);
00802     } while ((commandResponse[0] != ADI_SENSE_1000_HOST_COMMS_CMD_RESP_0) ||
00803              (commandResponse[1] != ADI_SENSE_1000_HOST_COMMS_CMD_RESP_1));
00804 
00805     for (unsigned i = 0; i < nRequested; i++)
00806     {
00807         ADI_SENSE_1000_Sensor_Result_t  sensorResult;
00808         bool_t bHoldCs = true;
00809 
00810         /* Keep the CS signal asserted for all but the last sample */
00811         if ((i + 1) == nRequested)
00812             bHoldCs = false;
00813 
00814         eRet = adi_sense_SpiTransfer(pCtx->hSpi, NULL, &sensorResult,
00815                                      nBytesPerSample, bHoldCs);
00816         if (eRet)
00817         {
00818             ADI_SENSE_LOG_ERROR("Failed to read data from FIFO register");
00819             return eRet;
00820         }
00821 
00822         if (! sensorResult.Ch_Valid)
00823         {
00824             /*
00825              * Reading an invalid sample indicates that there are no
00826              * more samples available or we've lost sync with the device.
00827              * In the latter case, it might be recoverable, but return here
00828              * to let the application check the device status and decide itself.
00829              */
00830             eRet = ADI_SENSE_INCOMPLETE ;
00831             break;
00832         }
00833 
00834         ADI_SENSE_DATA_SAMPLE  *pSample = &pSamples[nValidSamples];
00835 
00836         pSample->status  = (ADI_SENSE_DEVICE_STATUS_FLAGS )0;
00837         if (sensorResult.Ch_Error)
00838             pSample->status  |= ADI_SENSE_DEVICE_STATUS_ERROR ;
00839         if (sensorResult.Ch_Alert)
00840             pSample->status  |= ADI_SENSE_DEVICE_STATUS_ALERT ;
00841 
00842         if (sensorResult.Ch_Raw)
00843             pSample->rawValue  = sensorResult.Raw_Sample;
00844         else
00845             pSample->rawValue  = 0;
00846 
00847         pSample->channelId  = sensorResult.Channel_ID;
00848         pSample->processedValue  = sensorResult.Sensor_Result;
00849 
00850         nValidSamples++;
00851     }
00852     *pnReturned = nValidSamples;
00853 
00854     adi_sense_TimeDelayUsec(ADI_SENSE_1000_HOST_COMMS_XFER_DELAY);
00855 
00856     return eRet;
00857 }
00858 
00859 /*
00860  * Close the given ADISENSE device.
00861  */
00862 ADI_SENSE_RESULT  adi_sense_Close(
00863     ADI_SENSE_DEVICE_HANDLE     const hDevice)
00864 {
00865     ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
00866 
00867     adi_sense_GpioClose(pCtx->hGpio);
00868     adi_sense_SpiClose(pCtx->hSpi);
00869     adi_sense_LogClose();
00870 
00871     return ADI_SENSE_SUCCESS ;
00872 }
00873 
00874 ADI_SENSE_RESULT  adi_sense_1000_WriteRegister(
00875     ADI_SENSE_DEVICE_HANDLE  hDevice,
00876     uint16_t nAddress,
00877     void *pData,
00878     unsigned nLength)
00879 {
00880     ADI_SENSE_RESULT  eRet;
00881     ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
00882     uint16_t command = ADI_SENSE_1000_HOST_COMMS_WRITE_CMD |
00883         (nAddress & ADI_SENSE_1000_HOST_COMMS_ADR_MASK);
00884     uint8_t commandData[2] = {
00885         command >> 8,
00886         command & 0xFF
00887     };
00888     uint8_t commandResponse[2];
00889 
00890     do {
00891         eRet = adi_sense_SpiTransfer(pCtx->hSpi, commandData, commandResponse,
00892                                      sizeof(command), false);
00893         if (eRet)
00894         {
00895             ADI_SENSE_LOG_ERROR("Failed to send write command for register %u",
00896                                 nAddress);
00897             return eRet;
00898         }
00899 
00900         adi_sense_TimeDelayUsec(ADI_SENSE_1000_HOST_COMMS_XFER_DELAY);
00901     } while ((commandResponse[0] != ADI_SENSE_1000_HOST_COMMS_CMD_RESP_0) ||
00902              (commandResponse[1] != ADI_SENSE_1000_HOST_COMMS_CMD_RESP_1));
00903 
00904     eRet = adi_sense_SpiTransfer(pCtx->hSpi, pData, NULL, nLength, false);
00905     if (eRet)
00906     {
00907         ADI_SENSE_LOG_ERROR("Failed to write data (%dB) to register %u",
00908                             nLength, nAddress);
00909         return eRet;
00910     }
00911 
00912     adi_sense_TimeDelayUsec(ADI_SENSE_1000_HOST_COMMS_XFER_DELAY);
00913 
00914     return ADI_SENSE_SUCCESS ;
00915 }
00916 
00917 ADI_SENSE_RESULT  adi_sense_1000_ReadRegister(
00918     ADI_SENSE_DEVICE_HANDLE  hDevice,
00919     uint16_t nAddress,
00920     void *pData,
00921     unsigned nLength)
00922 {
00923     ADI_SENSE_RESULT  eRet;
00924     ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
00925     uint16_t command = ADI_SENSE_1000_HOST_COMMS_READ_CMD |
00926         (nAddress & ADI_SENSE_1000_HOST_COMMS_ADR_MASK);
00927     uint8_t commandData[2] = {
00928         command >> 8,
00929         command & 0xFF
00930     };
00931     uint8_t commandResponse[2];
00932 
00933     do {
00934         eRet = adi_sense_SpiTransfer(pCtx->hSpi, commandData, commandResponse,
00935                                      sizeof(command), false);
00936         if (eRet)
00937         {
00938             ADI_SENSE_LOG_ERROR("Failed to send read command for register %u",
00939                                 nAddress);
00940             return eRet;
00941         }
00942 
00943         adi_sense_TimeDelayUsec(ADI_SENSE_1000_HOST_COMMS_XFER_DELAY);
00944     } while ((commandResponse[0] != ADI_SENSE_1000_HOST_COMMS_CMD_RESP_0) ||
00945              (commandResponse[1] != ADI_SENSE_1000_HOST_COMMS_CMD_RESP_1));
00946 
00947     eRet = adi_sense_SpiTransfer(pCtx->hSpi, NULL, pData, nLength, false);
00948     if (eRet)
00949     {
00950         ADI_SENSE_LOG_ERROR("Failed to read data (%uB) from register %u",
00951                             nLength, nAddress);
00952         return eRet;
00953     }
00954 
00955     adi_sense_TimeDelayUsec(ADI_SENSE_1000_HOST_COMMS_XFER_DELAY);
00956 
00957     return ADI_SENSE_SUCCESS ;
00958 }
00959 
00960 ADI_SENSE_RESULT  adi_sense_GetDeviceReadyState(
00961     ADI_SENSE_DEVICE_HANDLE    const hDevice,
00962     bool_t                  * const bReady)
00963 {
00964     ADI_ADISENSE_SPI_Chip_Type_t chipTypeReg;
00965 
00966     READ_REG_U8(hDevice, chipTypeReg.VALUE8, SPI_CHIP_TYPE);
00967     /* If we read this register successfully, assume the device is ready */
00968     *bReady = (chipTypeReg.VALUE8 == REG_ADISENSE_SPI_CHIP_TYPE_RESET);
00969 
00970     return ADI_SENSE_SUCCESS ;
00971 }
00972 
00973 ADI_SENSE_RESULT  adi_sense_1000_GetDataReadyModeInfo(
00974     ADI_SENSE_DEVICE_HANDLE          const hDevice,
00975     ADI_SENSE_MEASUREMENT_MODE       const eMeasurementMode,
00976     ADI_SENSE_1000_OPERATING_MODE  * const peOperatingMode,
00977     ADI_SENSE_1000_DATAREADY_MODE  * const peDataReadyMode,
00978     uint32_t                      * const pnSamplesPerDataready,
00979     uint32_t                      * const pnSamplesPerCycle,
00980     uint8_t                       * const pnBytesPerSample)
00981 {
00982     unsigned nChannelsEnabled = 0;
00983     unsigned nSamplesPerCycle = 0;
00984 
00985     ADI_ADISENSE_CORE_Mode_t modeReg;
00986     READ_REG_U8(hDevice, modeReg.VALUE8, CORE_MODE);
00987 
00988     if ((eMeasurementMode == ADI_SENSE_MEASUREMENT_MODE_HEALTHCHECK ) ||
00989         (modeReg.Conversion_Mode == ADISENSE_CORE_MODE_SINGLECYCLE))
00990         *peOperatingMode = ADI_SENSE_1000_OPERATING_MODE_SINGLECYCLE ;
00991     else if (modeReg.Conversion_Mode == ADISENSE_CORE_MODE_MULTICYCLE)
00992         *peOperatingMode = ADI_SENSE_1000_OPERATING_MODE_MULTICYCLE ;
00993     else
00994         *peOperatingMode = ADI_SENSE_1000_OPERATING_MODE_CONTINUOUS ;
00995 
00996 
00997     /* FFT mode is quite different to the other modes:
00998      * - Each FFT result produces a batch of samples
00999      * - The size of the batch depends on selected FFT size and output config options
01000      * - DATAREADY will fire for each FFT result (once per channel)
01001      * - The size of the cycle depends on the number of channels enabled for FFT
01002      */
01003     if (eMeasurementMode == ADI_SENSE_MEASUREMENT_MODE_FFT )
01004     {
01005         ADI_ADISENSE_CORE_FFT_Config_t fftConfigReg;
01006 
01007         unsigned nFftChannels;
01008         unsigned nSamplesPerChannel;
01009 
01010         READ_REG_U32(hDevice, fftConfigReg.VALUE32, CORE_FFT_CONFIG);
01011 
01012         nFftChannels = fftConfigReg.FFT_Num_Channels + 1;
01013 
01014         if (fftConfigReg.FFT_Output == ADISENSE_CORE_FFT_CONFIG_FFT_OUTPUT_MAX16)
01015         {
01016             nSamplesPerChannel = 16;
01017             *pnBytesPerSample = 8;
01018         }
01019         else if (fftConfigReg.FFT_Output == ADISENSE_CORE_FFT_CONFIG_FFT_OUTPUT_FULL)
01020         {
01021             nSamplesPerChannel = (256 << fftConfigReg.FFT_Num_Bins) >> 1;
01022             *pnBytesPerSample = 5;
01023         }
01024         else if (fftConfigReg.FFT_Output == ADISENSE_CORE_FFT_CONFIG_FFT_OUTPUT_FULL_WITH_RAW)
01025         {
01026             nSamplesPerChannel = (256 << fftConfigReg.FFT_Num_Bins);
01027             *pnBytesPerSample = 8;
01028         }
01029         else
01030         {
01031             ADI_SENSE_LOG_ERROR("Invalid FFT output format option %d configured",
01032                                 fftConfigReg.FFT_Output);
01033             return ADI_SENSE_INVALID_PARAM ;
01034         }
01035 
01036         *pnSamplesPerDataready = nSamplesPerChannel;
01037         *pnSamplesPerCycle = nSamplesPerChannel * nFftChannels;
01038 
01039         *peDataReadyMode = ADI_SENSE_1000_DATAREADY_PER_CYCLE ;
01040     }
01041     else
01042     {
01043         if (eMeasurementMode == ADI_SENSE_MEASUREMENT_MODE_OMIT_RAW )
01044         {
01045             *pnBytesPerSample = 5;
01046         }
01047         else
01048         {
01049             *pnBytesPerSample = 8;
01050         }
01051 
01052         for (ADI_SENSE_1000_CHANNEL_ID  chId = ADI_SENSE_1000_CHANNEL_ID_CJC_0 ;
01053              chId < ADI_SENSE_1000_MAX_CHANNELS ;
01054              chId++)
01055         {
01056             ADI_ADISENSE_CORE_Sensor_Details_t sensorDetailsReg;
01057             ADI_ADISENSE_CORE_Channel_Count_t channelCountReg;
01058 
01059             if (ADI_SENSE_1000_CHANNEL_IS_VIRTUAL(chId))
01060                 continue;
01061 
01062             READ_REG_U8(hDevice, channelCountReg.VALUE8, CORE_CHANNEL_COUNTn(chId));
01063             READ_REG_U32(hDevice, sensorDetailsReg.VALUE32, CORE_SENSOR_DETAILSn(chId));
01064 
01065             if (channelCountReg.Channel_Enable && !sensorDetailsReg.Do_Not_Publish)
01066             {
01067                 ADI_ADISENSE_CORE_Sensor_Type_t sensorTypeReg;
01068                 unsigned nActualChannels = 1;
01069 
01070                 READ_REG_U16(hDevice, sensorTypeReg.VALUE16, CORE_SENSOR_TYPEn(chId));
01071 
01072                 if (chId == ADI_SENSE_1000_CHANNEL_ID_SPI_0 )
01073                 {
01074                     /* Some sensors automatically generate samples on additional "virtual" channels
01075                      * so these channels must be counted as active when those sensors are selected
01076                      * and we use the count from the corresponding "physical" channel */
01077                     if ((sensorTypeReg.Sensor_Type >=
01078                          ADISENSE_CORE_SENSOR_TYPE_SENSOR_SPI_ACCELEROMETER_A_DEF_L1) &&
01079                         (sensorTypeReg.Sensor_Type <=
01080                          ADISENSE_CORE_SENSOR_TYPE_SENSOR_SPI_ACCELEROMETER_B_ADV_L2))
01081                         nActualChannels += 2;
01082                 }
01083 
01084                 nChannelsEnabled += nActualChannels;
01085                 if (eMeasurementMode == ADI_SENSE_MEASUREMENT_MODE_HEALTHCHECK )
01086                     /* Assume a single sample per channel in test mode */
01087                     nSamplesPerCycle += nActualChannels;
01088                 else
01089                     nSamplesPerCycle += nActualChannels *
01090                         (channelCountReg.Channel_Count + 1);
01091             }
01092         }
01093 
01094         if (nChannelsEnabled == 0)
01095         {
01096             *pnSamplesPerDataready = 0;
01097             *pnSamplesPerCycle = 0;
01098             return ADI_SENSE_SUCCESS ;
01099         }
01100 
01101         *pnSamplesPerCycle = nSamplesPerCycle;
01102 
01103         if (modeReg.Drdy_Mode == ADISENSE_CORE_MODE_DRDY_PER_CONVERSION)
01104         {
01105             *pnSamplesPerDataready = 1;
01106         }
01107         else if (modeReg.Drdy_Mode == ADISENSE_CORE_MODE_DRDY_PER_CYCLE)
01108         {
01109             *pnSamplesPerDataready = nSamplesPerCycle;
01110         }
01111         else
01112         {
01113             /* Assume DRDY will be asserted after max. 1 cycle in test mode */
01114             if (eMeasurementMode == ADI_SENSE_MEASUREMENT_MODE_HEALTHCHECK )
01115             {
01116                 *pnSamplesPerDataready = nSamplesPerCycle;
01117             }
01118             else
01119             {
01120                 ADI_ADISENSE_CORE_Fifo_Num_Cycles_t fifoNumCyclesReg;
01121                 READ_REG_U8(hDevice, fifoNumCyclesReg.VALUE8, CORE_FIFO_NUM_CYCLES);
01122 
01123                 *pnSamplesPerDataready =
01124                 nSamplesPerCycle * fifoNumCyclesReg.Fifo_Num_Cycles;
01125             }
01126         }
01127 
01128         if (modeReg.Drdy_Mode == ADISENSE_CORE_MODE_DRDY_PER_CONVERSION)
01129             *peDataReadyMode = ADI_SENSE_1000_DATAREADY_PER_CONVERSION ;
01130         else if (modeReg.Drdy_Mode == ADISENSE_CORE_MODE_DRDY_PER_CYCLE)
01131             *peDataReadyMode = ADI_SENSE_1000_DATAREADY_PER_CYCLE ;
01132         else
01133         {
01134             /* Assume DRDY will be asserted after max. 1 cycle in test mode */
01135             if (eMeasurementMode == ADI_SENSE_MEASUREMENT_MODE_HEALTHCHECK )
01136                 *peDataReadyMode = ADI_SENSE_1000_DATAREADY_PER_CYCLE ;
01137             else
01138                 *peDataReadyMode = ADI_SENSE_1000_DATAREADY_PER_MULTICYCLE_BURST ;
01139         }
01140     }
01141 
01142     return ADI_SENSE_SUCCESS ;
01143 }
01144 
01145 ADI_SENSE_RESULT  adi_sense_GetProductID(
01146     ADI_SENSE_DEVICE_HANDLE  hDevice,
01147     ADI_SENSE_PRODUCT_ID  *pProductId)
01148 {
01149     ADI_ADISENSE_SPI_Product_ID_L_t productIdLoReg;
01150     ADI_ADISENSE_SPI_Product_ID_H_t productIdHiReg;
01151 
01152     READ_REG_U8(hDevice, productIdLoReg.VALUE8, SPI_PRODUCT_ID_L);
01153     READ_REG_U8(hDevice, productIdHiReg.VALUE8, SPI_PRODUCT_ID_H);
01154 
01155     *pProductId = (ADI_SENSE_PRODUCT_ID )((productIdHiReg.VALUE8 << 8)
01156                                          | productIdLoReg.VALUE8);
01157     return ADI_SENSE_SUCCESS ;
01158 }
01159 
01160 static ADI_SENSE_RESULT  adi_sense_SetPowerMode(
01161     ADI_SENSE_DEVICE_HANDLE  hDevice,
01162     ADI_SENSE_1000_POWER_MODE  powerMode)
01163 {
01164     ADI_ADISENSE_CORE_Power_Config_t powerConfigReg;
01165 
01166     if (powerMode == ADI_SENSE_1000_POWER_MODE_LOW )
01167     {
01168         powerConfigReg.Power_Mode_ADC = ADISENSE_CORE_POWER_CONFIG_ADC_LOW_POWER;
01169     }
01170     else if (powerMode == ADI_SENSE_1000_POWER_MODE_MID )
01171     {
01172         powerConfigReg.Power_Mode_ADC = ADISENSE_CORE_POWER_CONFIG_ADC_MID_POWER;
01173     }
01174     else if (powerMode == ADI_SENSE_1000_POWER_MODE_FULL )
01175     {
01176         powerConfigReg.Power_Mode_ADC = ADISENSE_CORE_POWER_CONFIG_ADC_FULL_POWER;
01177     }
01178     else
01179     {
01180         ADI_SENSE_LOG_ERROR("Invalid power mode %d specified", powerMode);
01181         return ADI_SENSE_INVALID_PARAM ;
01182     }
01183 
01184     WRITE_REG_U8(hDevice, powerConfigReg.VALUE8, CORE_POWER_CONFIG);
01185 
01186     return ADI_SENSE_SUCCESS ;
01187 }
01188 
01189 ADI_SENSE_RESULT  adi_sense_1000_SetPowerConfig(
01190     ADI_SENSE_DEVICE_HANDLE  hDevice,
01191     ADI_SENSE_1000_POWER_CONFIG  *pPowerConfig)
01192 {
01193     ADI_SENSE_RESULT  eRet;
01194 
01195     eRet = adi_sense_SetPowerMode(hDevice, pPowerConfig->powerMode );
01196     if (eRet != ADI_SENSE_SUCCESS )
01197     {
01198         ADI_SENSE_LOG_ERROR("Failed to set power mode");
01199         return eRet;
01200     }
01201 
01202     return ADI_SENSE_SUCCESS ;
01203 }
01204 
01205 static ADI_SENSE_RESULT  adi_sense_SetMode(
01206     ADI_SENSE_DEVICE_HANDLE  hDevice,
01207     ADI_SENSE_1000_OPERATING_MODE  eOperatingMode,
01208     ADI_SENSE_1000_DATAREADY_MODE  eDataReadyMode,
01209     ADI_SENSE_1000_CALIBRATION_MODE  eCalibrationMode,
01210     bool bEnableExtFlash)
01211 {
01212     ADI_ADISENSE_CORE_Mode_t modeReg;
01213 
01214     modeReg.VALUE8 = REG_RESET_VAL(CORE_MODE);
01215 
01216     if (eOperatingMode == ADI_SENSE_1000_OPERATING_MODE_SINGLECYCLE )
01217     {
01218         modeReg.Conversion_Mode = ADISENSE_CORE_MODE_SINGLECYCLE;
01219     }
01220     else if (eOperatingMode == ADI_SENSE_1000_OPERATING_MODE_CONTINUOUS )
01221     {
01222         modeReg.Conversion_Mode = ADISENSE_CORE_MODE_CONTINUOUS;
01223     }
01224     else if (eOperatingMode == ADI_SENSE_1000_OPERATING_MODE_MULTICYCLE )
01225     {
01226         modeReg.Conversion_Mode = ADISENSE_CORE_MODE_MULTICYCLE;
01227     }
01228     else
01229     {
01230         ADI_SENSE_LOG_ERROR("Invalid operating mode %d specified",
01231                             eOperatingMode);
01232         return ADI_SENSE_INVALID_PARAM ;
01233     }
01234 
01235     if (eDataReadyMode == ADI_SENSE_1000_DATAREADY_PER_CONVERSION )
01236     {
01237         modeReg.Drdy_Mode = ADISENSE_CORE_MODE_DRDY_PER_CONVERSION;
01238     }
01239     else if (eDataReadyMode == ADI_SENSE_1000_DATAREADY_PER_CYCLE )
01240     {
01241         modeReg.Drdy_Mode = ADISENSE_CORE_MODE_DRDY_PER_CYCLE;
01242     }
01243     else if (eDataReadyMode == ADI_SENSE_1000_DATAREADY_PER_MULTICYCLE_BURST )
01244     {
01245         if (eOperatingMode != ADI_SENSE_1000_OPERATING_MODE_MULTICYCLE )
01246         {
01247             ADI_SENSE_LOG_ERROR(
01248                 "Data-ready mode %d cannot be used with operating mode %d",
01249                 eDataReadyMode, eOperatingMode);
01250             return ADI_SENSE_INVALID_PARAM ;
01251         }
01252         else
01253         {
01254             modeReg.Drdy_Mode = ADISENSE_CORE_MODE_DRDY_PER_FIFO_FILL;
01255         }
01256     }
01257     else
01258     {
01259         ADI_SENSE_LOG_ERROR("Invalid data-ready mode %d specified", eDataReadyMode);
01260         return ADI_SENSE_INVALID_PARAM ;
01261     }
01262 
01263     if (eCalibrationMode == ADI_SENSE_1000_NO_CALIBRATION )
01264     {
01265         modeReg.Calibration_Method = ADISENSE_CORE_MODE_NO_CAL;
01266     }
01267     else if (eCalibrationMode == ADI_SENSE_1000_DO_CALIBRATION )
01268     {
01269         modeReg.Calibration_Method = ADISENSE_CORE_MODE_DO_CAL;
01270     }
01271     else
01272     {
01273         ADI_SENSE_LOG_ERROR("Invalid calibration mode %d specified",
01274                             eCalibrationMode);
01275         return ADI_SENSE_INVALID_PARAM ;
01276     }
01277 
01278     modeReg.Ext_Flash_Store = (bEnableExtFlash ?
01279                                 ADISENSE_CORE_MODE_EXT_FLASH_USED :
01280                                 ADISENSE_CORE_MODE_EXT_FLASH_NOT_USED);
01281 
01282     WRITE_REG_U8(hDevice, modeReg.VALUE8, CORE_MODE);
01283 
01284     return ADI_SENSE_SUCCESS ;
01285 }
01286 
01287 ADI_SENSE_RESULT  adi_sense_SetCycleControl(
01288     ADI_SENSE_DEVICE_HANDLE  hDevice,
01289     uint32_t nCycleInterval,
01290     ADI_SENSE_1000_CYCLE_TYPE  eCycleType)
01291 {
01292     ADI_ADISENSE_CORE_Cycle_Control_t cycleControlReg;
01293 
01294     cycleControlReg.VALUE16 = REG_RESET_VAL(CORE_CYCLE_CONTROL);
01295 
01296     if (nCycleInterval < (1 << 12))
01297     {
01298         cycleControlReg.Cycle_Time_Units = ADISENSE_CORE_CYCLE_CONTROL_MICROSECONDS;
01299     }
01300     else if (nCycleInterval < (1000 * (1 << 12)))
01301     {
01302         cycleControlReg.Cycle_Time_Units = ADISENSE_CORE_CYCLE_CONTROL_MILLISECONDS;
01303         nCycleInterval /= 1000;
01304     }
01305     else
01306     {
01307         cycleControlReg.Cycle_Time_Units = ADISENSE_CORE_CYCLE_CONTROL_SECONDS;
01308         nCycleInterval /= 1000000;
01309     }
01310 
01311     CHECK_REG_FIELD_VAL(CORE_CYCLE_CONTROL_CYCLE_TIME, nCycleInterval);
01312     cycleControlReg.Cycle_Time = nCycleInterval;
01313 
01314     if (eCycleType == ADI_SENSE_1000_CYCLE_TYPE_SWITCH )
01315     {
01316         cycleControlReg.Cycle_Type = ADISENSE_CORE_CYCLE_CONTROL_CYCLE_TYPE_SWITCH;
01317     }
01318     else if (eCycleType == ADI_SENSE_1000_CYCLE_TYPE_FULL )
01319     {
01320         cycleControlReg.Cycle_Type = ADISENSE_CORE_CYCLE_CONTROL_CYCLE_TYPE_FULL;
01321     }
01322     else
01323     {
01324         ADI_SENSE_LOG_ERROR("Invalid cycle type %d specified", eCycleType);
01325         return ADI_SENSE_INVALID_PARAM ;
01326     }
01327 
01328     WRITE_REG_U16(hDevice, cycleControlReg.VALUE16, CORE_CYCLE_CONTROL);
01329 
01330     return ADI_SENSE_SUCCESS ;
01331 }
01332 
01333 static ADI_SENSE_RESULT  adi_sense_SetMultiCycleConfig(
01334     ADI_SENSE_DEVICE_HANDLE  hDevice,
01335     ADI_SENSE_1000_MULTICYCLE_CONFIG  *pMultiCycleConfig)
01336 {
01337     CHECK_REG_FIELD_VAL(CORE_FIFO_NUM_CYCLES_FIFO_NUM_CYCLES,
01338                         pMultiCycleConfig->cyclesPerBurst );
01339 
01340     WRITE_REG_U8(hDevice, pMultiCycleConfig->cyclesPerBurst ,
01341                  CORE_FIFO_NUM_CYCLES);
01342 
01343     WRITE_REG_U32(hDevice, pMultiCycleConfig->burstInterval ,
01344                   CORE_MULTI_CYCLE_REPEAT_INTERVAL);
01345 
01346     return ADI_SENSE_SUCCESS ;
01347 }
01348 
01349 static ADI_SENSE_RESULT  adi_sense_SetExternalReferenceValues(
01350     ADI_SENSE_DEVICE_HANDLE  hDevice,
01351     float32_t externalRef1Value,
01352     float32_t externalRef2Value)
01353 {
01354     WRITE_REG_FLOAT(hDevice, externalRef1Value, CORE_EXTERNAL_REFERENCE1);
01355     WRITE_REG_FLOAT(hDevice, externalRef2Value, CORE_EXTERNAL_REFERENCE2);
01356 
01357     return ADI_SENSE_SUCCESS ;
01358 }
01359 
01360 ADI_SENSE_RESULT  adi_sense_1000_SetMeasurementConfig(
01361     ADI_SENSE_DEVICE_HANDLE  hDevice,
01362     ADI_SENSE_1000_MEASUREMENT_CONFIG  *pMeasConfig)
01363 {
01364     ADI_SENSE_RESULT  eRet;
01365 
01366     eRet = adi_sense_SetMode(hDevice,
01367                              pMeasConfig->operatingMode ,
01368                              pMeasConfig->dataReadyMode ,
01369                              pMeasConfig->calibrationMode ,
01370                              pMeasConfig->enableExternalFlash );
01371     if (eRet != ADI_SENSE_SUCCESS )
01372     {
01373         ADI_SENSE_LOG_ERROR("Failed to set operating mode");
01374         return eRet;
01375     }
01376 
01377     eRet = adi_sense_SetCycleControl(hDevice,
01378                                      pMeasConfig->cycleInterval ,
01379                                      pMeasConfig->cycleType );
01380     if (eRet != ADI_SENSE_SUCCESS )
01381     {
01382         ADI_SENSE_LOG_ERROR("Failed to set cycle control");
01383         return eRet;
01384     }
01385 
01386     if (pMeasConfig->operatingMode  == ADI_SENSE_1000_OPERATING_MODE_MULTICYCLE )
01387     {
01388         eRet = adi_sense_SetMultiCycleConfig(hDevice,
01389                                             &pMeasConfig->multiCycleConfig );
01390         if (eRet != ADI_SENSE_SUCCESS )
01391         {
01392             ADI_SENSE_LOG_ERROR("Failed to set multi-cycle configuration");
01393             return eRet;
01394         }
01395     }
01396 
01397     eRet = adi_sense_SetExternalReferenceValues(hDevice,
01398                                                 pMeasConfig->externalRef1Value ,
01399                                                 pMeasConfig->externalRef2Value );
01400     if (eRet != ADI_SENSE_SUCCESS )
01401     {
01402         ADI_SENSE_LOG_ERROR("Failed to set external reference values");
01403         return eRet;
01404     }
01405 
01406     return ADI_SENSE_SUCCESS ;
01407 }
01408 
01409 ADI_SENSE_RESULT  adi_sense_1000_SetDiagnosticsConfig(
01410     ADI_SENSE_DEVICE_HANDLE  hDevice,
01411     ADI_SENSE_1000_DIAGNOSTICS_CONFIG  *pDiagnosticsConfig)
01412 {
01413     ADI_ADISENSE_CORE_Diagnostics_Control_t diagnosticsControlReg;
01414 
01415     diagnosticsControlReg.VALUE16 = REG_RESET_VAL(CORE_DIAGNOSTICS_CONTROL);
01416 
01417     if (pDiagnosticsConfig->disableGlobalDiag )
01418         diagnosticsControlReg.Diag_Global_En = 0;
01419     else
01420         diagnosticsControlReg.Diag_Global_En = 1;
01421 
01422     if (pDiagnosticsConfig->disableMeasurementDiag )
01423         diagnosticsControlReg.Diag_Meas_En = 0;
01424     else
01425         diagnosticsControlReg.Diag_Meas_En = 1;
01426 
01427     switch (pDiagnosticsConfig->osdFrequency )
01428     {
01429     case ADI_SENSE_1000_OPEN_SENSOR_DIAGNOSTICS_DISABLED :
01430         diagnosticsControlReg.Diag_OSD_Freq = ADISENSE_CORE_DIAGNOSTICS_CONTROL_OCD_OFF;
01431         break;
01432     case ADI_SENSE_1000_OPEN_SENSOR_DIAGNOSTICS_PER_CYCLE :
01433         diagnosticsControlReg.Diag_OSD_Freq = ADISENSE_CORE_DIAGNOSTICS_CONTROL_OCD_PER_1_CYCLE;
01434         break;
01435     case ADI_SENSE_1000_OPEN_SENSOR_DIAGNOSTICS_PER_100_CYCLES :
01436         diagnosticsControlReg.Diag_OSD_Freq = ADISENSE_CORE_DIAGNOSTICS_CONTROL_OCD_PER_100_CYCLES;
01437         break;
01438     case ADI_SENSE_1000_OPEN_SENSOR_DIAGNOSTICS_PER_1000_CYCLES :
01439         diagnosticsControlReg.Diag_OSD_Freq = ADISENSE_CORE_DIAGNOSTICS_CONTROL_OCD_PER_1000_CYCLES;
01440         break;
01441     default:
01442         ADI_SENSE_LOG_ERROR("Invalid open-sensor diagnostic frequency %d specified",
01443                             pDiagnosticsConfig->osdFrequency );
01444         return ADI_SENSE_INVALID_PARAM ;
01445     }
01446 
01447     WRITE_REG_U16(hDevice, diagnosticsControlReg.VALUE16, CORE_DIAGNOSTICS_CONTROL);
01448 
01449     return ADI_SENSE_SUCCESS ;
01450 }
01451 
01452 ADI_SENSE_RESULT  adi_sense_1000_SetFftConfig(
01453     ADI_SENSE_DEVICE_HANDLE  hDevice,
01454     ADI_SENSE_1000_FFT_CONFIG  *pFftConfig,
01455     ADI_SENSE_1000_CHANNEL_CONFIG  *pChannels)
01456 {
01457     ADI_ADISENSE_CORE_FFT_Config_t fftConfigReg;
01458     ADI_ADISENSE_CORE_Mode_t modeReg;
01459     uint32_t numFftChannels = 0;
01460 
01461     fftConfigReg.VALUE32 = REG_RESET_VAL(CORE_FFT_CONFIG);
01462 
01463     for (ADI_SENSE_1000_CHANNEL_ID  id = ADI_SENSE_1000_CHANNEL_ID_CJC_0 ;
01464          id < ADI_SENSE_1000_MAX_CHANNELS ;
01465          id++)
01466     {
01467         if (pChannels[id].enableFFT)
01468         {
01469             if (numFftChannels >= 4) /* TODO - temporary limit */
01470             {
01471                 ADI_SENSE_LOG_ERROR("Maximum limit of 4 FFT channels exceeded");
01472                 return ADI_SENSE_INVALID_PARAM ;
01473             }
01474 
01475             numFftChannels++;
01476         }
01477     }
01478 
01479     if (numFftChannels > 0)
01480     {
01481         fftConfigReg.FFT_Num_Channels = numFftChannels - 1;
01482 
01483         switch (pFftConfig->size )
01484         {
01485         case ADI_SENSE_1000_FFT_SIZE_256 :
01486             fftConfigReg.FFT_Num_Bins = ADISENSE_CORE_FFT_CONFIG_FFT_BINS_256;
01487             break;
01488         case ADI_SENSE_1000_FFT_SIZE_512 :
01489             fftConfigReg.FFT_Num_Bins = ADISENSE_CORE_FFT_CONFIG_FFT_BINS_512;
01490             break;
01491         case ADI_SENSE_1000_FFT_SIZE_1024 :
01492             fftConfigReg.FFT_Num_Bins = ADISENSE_CORE_FFT_CONFIG_FFT_BINS_1024;
01493             break;
01494         case ADI_SENSE_1000_FFT_SIZE_2048 :
01495             fftConfigReg.FFT_Num_Bins = ADISENSE_CORE_FFT_CONFIG_FFT_BINS_2048;
01496             break;
01497         default:
01498             ADI_SENSE_LOG_ERROR("Invalid FFT size option %d specified",
01499                                 pFftConfig->size );
01500             return ADI_SENSE_INVALID_PARAM ;
01501         }
01502 
01503         switch (pFftConfig->window )
01504         {
01505         case ADI_SENSE_1000_FFT_WINDOW_NONE :
01506             fftConfigReg.FFT_Window = ADISENSE_CORE_FFT_CONFIG_FFT_WINDOW_NONE;
01507             break;
01508         case ADI_SENSE_1000_FFT_WINDOW_HANN :
01509             fftConfigReg.FFT_Window = ADISENSE_CORE_FFT_CONFIG_FFT_WINDOW_HANN;
01510             break;
01511         case ADI_SENSE_1000_FFT_WINDOW_BLACKMAN_HARRIS :
01512             fftConfigReg.FFT_Window = ADISENSE_CORE_FFT_CONFIG_FFT_WINDOW_BLACKMANN_HARRIS;
01513             break;
01514         default:
01515             ADI_SENSE_LOG_ERROR("Invalid FFT window option %d specified",
01516                                 pFftConfig->window );
01517             return ADI_SENSE_INVALID_PARAM ;
01518         }
01519 
01520         switch (pFftConfig->output )
01521         {
01522         case ADI_SENSE_1000_FFT_OUTPUT_FULL :
01523             fftConfigReg.FFT_Output = ADISENSE_CORE_FFT_CONFIG_FFT_OUTPUT_FULL;
01524             break;
01525         case ADI_SENSE_1000_FFT_OUTPUT_MAX16 :
01526             fftConfigReg.FFT_Output = ADISENSE_CORE_FFT_CONFIG_FFT_OUTPUT_MAX16;
01527             break;
01528         case ADI_SENSE_1000_FFT_OUTPUT_FULL_WITH_RAW:
01529             fftConfigReg.FFT_Output = ADISENSE_CORE_FFT_CONFIG_FFT_OUTPUT_FULL_WITH_RAW;
01530             break;
01531         default:
01532             ADI_SENSE_LOG_ERROR("Invalid FFT output format option %d specified",
01533                                 pFftConfig->output );
01534             return ADI_SENSE_INVALID_PARAM ;
01535         }
01536     }
01537     WRITE_REG_U32(hDevice, fftConfigReg.VALUE32, CORE_FFT_CONFIG);
01538 
01539     if (numFftChannels > 0)
01540     {
01541         READ_REG_U8(hDevice, modeReg.VALUE8, CORE_MODE);
01542 
01543         if (pFftConfig->mode  == ADI_SENSE_1000_FFT_MODE_SINGLE )
01544         {
01545             modeReg.FFT_Mode = ADISENSE_CORE_MODE_FFT_MODE_SINGLE;
01546         }
01547         else if (pFftConfig->mode  == ADI_SENSE_1000_FFT_MODE_CONTINUOUS )
01548         {
01549             modeReg.FFT_Mode = ADISENSE_CORE_MODE_FFT_MODE_CONTINUOUS;
01550         }
01551         else
01552         {
01553             ADI_SENSE_LOG_ERROR("Invalid FFT mode %d specified",
01554                                 pFftConfig->mode );
01555             return ADI_SENSE_INVALID_PARAM ;
01556         }
01557 
01558         WRITE_REG_U8(hDevice, modeReg.VALUE8, CORE_MODE);
01559     }
01560 
01561     return ADI_SENSE_SUCCESS ;
01562 }
01563 
01564 ADI_SENSE_RESULT  adi_sense_1000_SetChannelCount(
01565     ADI_SENSE_DEVICE_HANDLE  hDevice,
01566     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01567     uint32_t nMeasurementsPerCycle)
01568 {
01569     ADI_ADISENSE_CORE_Channel_Count_t channelCountReg;
01570 
01571     channelCountReg.VALUE8 = REG_RESET_VAL(CORE_CHANNEL_COUNTn);
01572 
01573     if (nMeasurementsPerCycle > 0)
01574     {
01575         nMeasurementsPerCycle -= 1;
01576 
01577         CHECK_REG_FIELD_VAL(CORE_CHANNEL_COUNT_CHANNEL_COUNT,
01578                             nMeasurementsPerCycle);
01579 
01580         channelCountReg.Channel_Enable = 1;
01581         channelCountReg.Channel_Count = nMeasurementsPerCycle;
01582     }
01583     else
01584     {
01585         channelCountReg.Channel_Enable = 0;
01586     }
01587 
01588     WRITE_REG_U8(hDevice, channelCountReg.VALUE8, CORE_CHANNEL_COUNTn(eChannelId));
01589 
01590     return ADI_SENSE_SUCCESS ;
01591 }
01592 
01593 ADI_SENSE_RESULT  adi_sense_1000_SetChannelOptions(
01594     ADI_SENSE_DEVICE_HANDLE  hDevice,
01595     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01596     ADI_SENSE_1000_CHANNEL_PRIORITY  ePriority,
01597     bool bEnableFft)
01598 {
01599     ADI_ADISENSE_CORE_Channel_Options_t channelOptionsReg;
01600 
01601     channelOptionsReg.VALUE8 = REG_RESET_VAL(CORE_CHANNEL_OPTIONSn);
01602 
01603     CHECK_REG_FIELD_VAL(CORE_CHANNEL_OPTIONS_CHANNEL_PRIORITY, ePriority);
01604     channelOptionsReg.Channel_Priority = ePriority;
01605     channelOptionsReg.FFT_Enable_Ch = bEnableFft ? 1 : 0;
01606 
01607     WRITE_REG_U8(hDevice, channelOptionsReg.VALUE8, CORE_CHANNEL_OPTIONSn(eChannelId));
01608 
01609     return ADI_SENSE_SUCCESS ;
01610 }
01611 
01612 ADI_SENSE_RESULT  adi_sense_1000_SetChannelSkipCount(
01613     ADI_SENSE_DEVICE_HANDLE  hDevice,
01614     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01615     uint32_t nCycleSkipCount)
01616 {
01617     ADI_ADISENSE_CORE_Channel_Skip_t channelSkipReg;
01618 
01619     channelSkipReg.VALUE16 = REG_RESET_VAL(CORE_CHANNEL_SKIPn);
01620 
01621     CHECK_REG_FIELD_VAL(CORE_CHANNEL_SKIP_CHANNEL_SKIP, nCycleSkipCount);
01622 
01623     channelSkipReg.Channel_Skip = nCycleSkipCount;
01624 
01625     WRITE_REG_U16(hDevice, channelSkipReg.VALUE16, CORE_CHANNEL_SKIPn(eChannelId));
01626 
01627     return ADI_SENSE_SUCCESS ;
01628 }
01629 
01630 static ADI_SENSE_RESULT  adi_sense_SetChannelAdcSensorType(
01631     ADI_SENSE_DEVICE_HANDLE  hDevice,
01632     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01633     ADI_SENSE_1000_ADC_SENSOR_TYPE  sensorType)
01634 {
01635     ADI_ADISENSE_CORE_Sensor_Type_t sensorTypeReg;
01636 
01637     sensorTypeReg.VALUE16 = REG_RESET_VAL(CORE_SENSOR_TYPEn);
01638 
01639     /* Ensure that the sensor type is valid for this channel */
01640     switch(sensorType)
01641     {
01642     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_J_DEF_L1 :
01643     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_K_DEF_L1 :
01644     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_T_DEF_L1 :
01645     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_1_DEF_L2 :
01646     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_2_DEF_L2 :
01647     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_3_DEF_L2 :
01648     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_4_DEF_L2 :
01649     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_J_ADV_L1 :
01650     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_K_ADV_L1 :
01651     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_T_ADV_L1 :
01652     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_1_ADV_L2 :
01653     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_2_ADV_L2 :
01654     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_3_ADV_L2 :
01655     case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_4_ADV_L2 :
01656     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_PT100_DEF_L1 :
01657     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_PT1000_DEF_L1 :
01658     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_1_DEF_L2 :
01659     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_2_DEF_L2 :
01660     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_3_DEF_L2 :
01661     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_4_DEF_L2 :
01662     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_PT100_ADV_L1 :
01663     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_PT1000_ADV_L1 :
01664     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_1_ADV_L2 :
01665     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_2_ADV_L2 :
01666     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_3_ADV_L2 :
01667     case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_4_ADV_L2 :
01668     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_PT100_DEF_L1 :
01669     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_PT1000_DEF_L1 :
01670     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_1_DEF_L2 :
01671     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_2_DEF_L2 :
01672     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_3_DEF_L2 :
01673     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_4_DEF_L2 :
01674     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_PT100_ADV_L1 :
01675     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_PT1000_ADV_L1 :
01676     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_1_ADV_L2 :
01677     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_2_ADV_L2 :
01678     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_3_ADV_L2 :
01679     case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_4_ADV_L2 :
01680     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_1_DEF_L2 :
01681     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_2_DEF_L2 :
01682     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_3_DEF_L2 :
01683     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_4_DEF_L2 :
01684     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_1_ADV_L2 :
01685     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_2_ADV_L2 :
01686     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_3_ADV_L2 :
01687     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_4_ADV_L2 :
01688     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_1_DEF_L2 :
01689     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_2_DEF_L2 :
01690     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_3_DEF_L2 :
01691     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_4_DEF_L2 :
01692     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_1_ADV_L2 :
01693     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_2_ADV_L2 :
01694     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_3_ADV_L2 :
01695     case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_4_ADV_L2 :
01696     case ADI_SENSE_1000_ADC_SENSOR_MICROPHONE_A_DEF_L1 :
01697     case ADI_SENSE_1000_ADC_SENSOR_MICROPHONE_B_DEF_L1 :
01698     case ADI_SENSE_1000_ADC_SENSOR_MICROPHONE_1_DEF_L2 :
01699     case ADI_SENSE_1000_ADC_SENSOR_MICROPHONE_2_DEF_L2 :
01700     case ADI_SENSE_1000_ADC_SENSOR_MICROPHONE_A_ADV_L1 :
01701     case ADI_SENSE_1000_ADC_SENSOR_MICROPHONE_B_ADV_L1 :
01702     case ADI_SENSE_1000_ADC_SENSOR_MICROPHONE_1_ADV_L2 :
01703     case ADI_SENSE_1000_ADC_SENSOR_MICROPHONE_2_ADV_L2 :
01704         if (! ADI_SENSE_1000_CHANNEL_IS_ADC_SENSOR(eChannelId))
01705         {
01706             ADI_SENSE_LOG_ERROR(
01707                 "Invalid ADC sensor type %d specified for channel %d",
01708                 sensorType, eChannelId);
01709             return ADI_SENSE_INVALID_PARAM ;
01710         }
01711         break;
01712     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_PT100_DEF_L1 :
01713     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_PT1000_DEF_L1 :
01714     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_1_DEF_L2 :
01715     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_2_DEF_L2 :
01716     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_3_DEF_L2 :
01717     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_4_DEF_L2 :
01718     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_PT100_ADV_L1 :
01719     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_PT1000_ADV_L1 :
01720     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_1_ADV_L2 :
01721     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_2_ADV_L2 :
01722     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_3_ADV_L2 :
01723     case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_4_ADV_L2 :
01724     case ADI_SENSE_1000_ADC_SENSOR_DIODE_2C_TYPEA_DEF_L1 :
01725     case ADI_SENSE_1000_ADC_SENSOR_DIODE_3C_TYPEA_DEF_L1 :
01726     case ADI_SENSE_1000_ADC_SENSOR_DIODE_2C_1_DEF_L2 :
01727     case ADI_SENSE_1000_ADC_SENSOR_DIODE_3C_1_DEF_L2 :
01728     case ADI_SENSE_1000_ADC_SENSOR_DIODE_2C_TYPEA_ADV_L1 :
01729     case ADI_SENSE_1000_ADC_SENSOR_DIODE_3C_TYPEA_ADV_L1 :
01730     case ADI_SENSE_1000_ADC_SENSOR_DIODE_2C_1_ADV_L2 :
01731     case ADI_SENSE_1000_ADC_SENSOR_DIODE_3C_1_ADV_L2 :
01732     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_A_10K_DEF_L1 :
01733     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_B_10K_DEF_L1 :
01734     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_1_DEF_L2 :
01735     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_2_DEF_L2 :
01736     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_3_DEF_L2 :
01737     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_4_DEF_L2 :
01738     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_A_10K_ADV_L1 :
01739     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_B_10K_ADV_L1 :
01740     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_1_ADV_L2 :
01741     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_2_ADV_L2 :
01742     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_3_ADV_L2 :
01743     case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_4_ADV_L2 :
01744         if (! (ADI_SENSE_1000_CHANNEL_IS_ADC_SENSOR(eChannelId) ||
01745                ADI_SENSE_1000_CHANNEL_IS_ADC_CJC(eChannelId)))
01746         {
01747             ADI_SENSE_LOG_ERROR(
01748                 "Invalid ADC sensor type %d specified for channel %d",
01749                 sensorType, eChannelId);
01750             return ADI_SENSE_INVALID_PARAM ;
01751         }
01752         break;
01753     case ADI_SENSE_1000_ADC_SENSOR_VOLTAGE :
01754     case ADI_SENSE_1000_ADC_SENSOR_VOLTAGE_PRESSURE_A_DEF_L1 :
01755     case ADI_SENSE_1000_ADC_SENSOR_VOLTAGE_PRESSURE_B_DEF_L1 :
01756     case ADI_SENSE_1000_ADC_SENSOR_VOLTAGE_PRESSURE_1_DEF_L2 :
01757     case ADI_SENSE_1000_ADC_SENSOR_VOLTAGE_PRESSURE_2_DEF_L2 :
01758     case ADI_SENSE_1000_ADC_SENSOR_VOLTAGE_PRESSURE_A_ADV_L1 :
01759     case ADI_SENSE_1000_ADC_SENSOR_VOLTAGE_PRESSURE_B_ADV_L1 :
01760     case ADI_SENSE_1000_ADC_SENSOR_VOLTAGE_PRESSURE_1_ADV_L2 :
01761     case ADI_SENSE_1000_ADC_SENSOR_VOLTAGE_PRESSURE_2_ADV_L2 :
01762         if (! ADI_SENSE_1000_CHANNEL_IS_ADC_VOLTAGE(eChannelId))
01763         {
01764             ADI_SENSE_LOG_ERROR(
01765                 "Invalid ADC sensor type %d specified for channel %d",
01766                 sensorType, eChannelId);
01767             return ADI_SENSE_INVALID_PARAM ;
01768         }
01769         break;
01770     case ADI_SENSE_1000_ADC_SENSOR_CURRENT :
01771     case ADI_SENSE_1000_ADC_SENSOR_CURRENT_PRESSURE_A_DEF_L1 :
01772     case ADI_SENSE_1000_ADC_SENSOR_CURRENT_PRESSURE_1_DEF_L2 :
01773     case ADI_SENSE_1000_ADC_SENSOR_CURRENT_PRESSURE_2_DEF_L2 :
01774     case ADI_SENSE_1000_ADC_SENSOR_CURRENT_PRESSURE_A_ADV_L1 :
01775     case ADI_SENSE_1000_ADC_SENSOR_CURRENT_PRESSURE_1_ADV_L2 :
01776     case ADI_SENSE_1000_ADC_SENSOR_CURRENT_PRESSURE_2_ADV_L2 :
01777         if (! ADI_SENSE_1000_CHANNEL_IS_ADC_CURRENT(eChannelId))
01778         {
01779             ADI_SENSE_LOG_ERROR(
01780                 "Invalid ADC sensor type %d specified for channel %d",
01781                 sensorType, eChannelId);
01782             return ADI_SENSE_INVALID_PARAM ;
01783         }
01784         break;
01785     default:
01786         ADI_SENSE_LOG_ERROR("Invalid/unsupported ADC sensor type %d specified",
01787                             sensorType);
01788         return ADI_SENSE_INVALID_PARAM ;
01789     }
01790 
01791     sensorTypeReg.Sensor_Type = sensorType;
01792 
01793     WRITE_REG_U16(hDevice, sensorTypeReg.VALUE16, CORE_SENSOR_TYPEn(eChannelId));
01794 
01795     return ADI_SENSE_SUCCESS ;
01796 }
01797 
01798 static ADI_SENSE_RESULT  adi_sense_SetChannelAdcSensorDetails(
01799     ADI_SENSE_DEVICE_HANDLE  hDevice,
01800     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01801     ADI_SENSE_1000_CHANNEL_CONFIG  *pChannelConfig)
01802 /*
01803  * TODO - it would be nice if the general- vs. ADC-specific sensor details could be split into separate registers
01804  * General details:
01805  * - Measurement_Units
01806  * - Compensation_Channel
01807  * - CJC_Publish (if "CJC" was removed from the name)
01808  * ADC-specific details:
01809  * - PGA_Gain
01810  * - Reference_Select
01811  * - Reference_Buffer_Disable
01812  * - Vbias
01813  */
01814 {
01815     ADI_SENSE_1000_ADC_CHANNEL_CONFIG  *pAdcChannelConfig = &pChannelConfig->adcChannelConfig ;
01816     ADI_SENSE_1000_ADC_REFERENCE_CONFIG  *pRefConfig = &pAdcChannelConfig->reference ;
01817     ADI_ADISENSE_CORE_Sensor_Details_t sensorDetailsReg;
01818 
01819     sensorDetailsReg.VALUE32 = REG_RESET_VAL(CORE_SENSOR_DETAILSn);
01820 
01821     switch(pChannelConfig->measurementUnit )
01822     {
01823     case ADI_SENSE_1000_MEASUREMENT_UNIT_FAHRENHEIT :
01824         sensorDetailsReg.Measurement_Units = ADISENSE_CORE_SENSOR_DETAILS_UNITS_DEGF;
01825         break;
01826     case ADI_SENSE_1000_MEASUREMENT_UNIT_CELSIUS :
01827         sensorDetailsReg.Measurement_Units = ADISENSE_CORE_SENSOR_DETAILS_UNITS_DEGC;
01828         break;
01829     case ADI_SENSE_1000_MEASUREMENT_UNIT_UNSPECIFIED :
01830         sensorDetailsReg.Measurement_Units = ADISENSE_CORE_SENSOR_DETAILS_UNITS_UNSPECIFIED;
01831         break;
01832     default:
01833         ADI_SENSE_LOG_ERROR("Invalid measurement unit %d specified",
01834                             pChannelConfig->measurementUnit );
01835         return ADI_SENSE_INVALID_PARAM ;
01836     }
01837 
01838     if (pChannelConfig->compensationChannel  == ADI_SENSE_1000_CHANNEL_ID_NONE )
01839     {
01840         sensorDetailsReg.Compensation_Disable = 1;
01841         sensorDetailsReg.Compensation_Channel = 0;
01842     }
01843     else
01844     {
01845         sensorDetailsReg.Compensation_Disable = 0;
01846         sensorDetailsReg.Compensation_Channel = pChannelConfig->compensationChannel ;
01847     }
01848 
01849     switch(pRefConfig->type )
01850     {
01851     case ADI_SENSE_1000_ADC_REFERENCE_RESISTOR_INTERNAL_1 :
01852         sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_RINT1;
01853         break;
01854     case ADI_SENSE_1000_ADC_REFERENCE_RESISTOR_INTERNAL_2 :
01855         sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_RINT2;
01856         break;
01857     case ADI_SENSE_1000_ADC_REFERENCE_VOLTAGE_INTERNAL :
01858         sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_INT;
01859         break;
01860     case ADI_SENSE_1000_ADC_REFERENCE_VOLTAGE_AVDD :
01861         sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_AVDD;
01862         break;
01863     case ADI_SENSE_1000_ADC_REFERENCE_RESISTOR_EXTERNAL_1 :
01864         sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_REXT1;
01865         break;
01866     case ADI_SENSE_1000_ADC_REFERENCE_RESISTOR_EXTERNAL_2 :
01867         sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_REXT2;
01868         break;
01869     case ADI_SENSE_1000_ADC_REFERENCE_VOLTAGE_EXTERNAL_1 :
01870         sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_VEXT1;
01871         break;
01872     case ADI_SENSE_1000_ADC_REFERENCE_VOLTAGE_EXTERNAL_2 :
01873         sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_VEXT2;
01874         break;
01875     case ADI_SENSE_1000_ADC_REFERENCE_BRIDGE_EXCITATION :
01876         sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_EXC;
01877         break;
01878     default:
01879         ADI_SENSE_LOG_ERROR("Invalid ADC reference type %d specified",
01880                             pRefConfig->type );
01881         return ADI_SENSE_INVALID_PARAM ;
01882     }
01883 
01884     switch(pAdcChannelConfig->gain )
01885     {
01886     case ADI_SENSE_1000_ADC_GAIN_1X :
01887         sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_1;
01888         break;
01889     case ADI_SENSE_1000_ADC_GAIN_2X :
01890         sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_2;
01891         break;
01892     case ADI_SENSE_1000_ADC_GAIN_4X :
01893         sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_4;
01894         break;
01895     case ADI_SENSE_1000_ADC_GAIN_8X :
01896         sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_8;
01897         break;
01898     case ADI_SENSE_1000_ADC_GAIN_16X :
01899         sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_16;
01900         break;
01901     case ADI_SENSE_1000_ADC_GAIN_32X :
01902         sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_32;
01903         break;
01904     case ADI_SENSE_1000_ADC_GAIN_64X :
01905         sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_64;
01906         break;
01907     case ADI_SENSE_1000_ADC_GAIN_128X :
01908         sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_128;
01909         break;
01910     default:
01911         ADI_SENSE_LOG_ERROR("Invalid ADC gain %d specified",
01912                             pAdcChannelConfig->gain );
01913         return ADI_SENSE_INVALID_PARAM ;
01914     }
01915 
01916     if (pAdcChannelConfig->enableVbias )
01917         sensorDetailsReg.Vbias = 1;
01918     else
01919         sensorDetailsReg.Vbias = 0;
01920 
01921     if (pAdcChannelConfig->reference .disableBuffer )
01922         sensorDetailsReg.Reference_Buffer_Disable = 1;
01923     else
01924         sensorDetailsReg.Reference_Buffer_Disable = 0;
01925 
01926     if (pChannelConfig->disablePublishing )
01927         sensorDetailsReg.Do_Not_Publish = 1;
01928     else
01929         sensorDetailsReg.Do_Not_Publish = 0;
01930 
01931     if (pChannelConfig->enableUnityLut )
01932         sensorDetailsReg.Unity_LUT_Select = 1;
01933     else
01934         sensorDetailsReg.Unity_LUT_Select = 0;
01935 
01936     WRITE_REG_U32(hDevice, sensorDetailsReg.VALUE32, CORE_SENSOR_DETAILSn(eChannelId));
01937 
01938     return ADI_SENSE_SUCCESS ;
01939 }
01940 
01941 static ADI_SENSE_RESULT  adi_sense_SetChannelAdcFilter(
01942     ADI_SENSE_DEVICE_HANDLE  hDevice,
01943     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01944     ADI_SENSE_1000_ADC_FILTER_CONFIG  *pFilterConfig)
01945 {
01946     ADI_ADISENSE_CORE_Filter_Select_t filterSelectReg;
01947 
01948     filterSelectReg.VALUE32 = REG_RESET_VAL(CORE_FILTER_SELECTn);
01949 
01950     if (pFilterConfig->type  == ADI_SENSE_1000_ADC_FILTER_SINC4 )
01951     {
01952         filterSelectReg.ADC_Filter_Type = ADISENSE_CORE_FILTER_SELECT_FILTER_SINC4;
01953         filterSelectReg.ADC_FS = pFilterConfig->fs ;
01954     }
01955     else if (pFilterConfig->type  == ADI_SENSE_1000_ADC_FILTER_FIR_20SPS )
01956     {
01957         filterSelectReg.ADC_Filter_Type = ADISENSE_CORE_FILTER_SELECT_FILTER_FIR_20SPS;
01958     }
01959     else if (pFilterConfig->type  == ADI_SENSE_1000_ADC_FILTER_FIR_25SPS )
01960     {
01961         filterSelectReg.ADC_Filter_Type = ADISENSE_CORE_FILTER_SELECT_FILTER_FIR_25SPS;
01962     }
01963     else
01964     {
01965         ADI_SENSE_LOG_ERROR("Invalid ADC filter type %d specified",
01966                             pFilterConfig->type );
01967         return ADI_SENSE_INVALID_PARAM ;
01968     }
01969 
01970     WRITE_REG_U32(hDevice, filterSelectReg.VALUE32, CORE_FILTER_SELECTn(eChannelId));
01971 
01972     return ADI_SENSE_SUCCESS ;
01973 }
01974 
01975 static ADI_SENSE_RESULT  adi_sense_SetChannelAdcCurrentConfig(
01976     ADI_SENSE_DEVICE_HANDLE  hDevice,
01977     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
01978     ADI_SENSE_1000_ADC_EXC_CURRENT_CONFIG  *pCurrentConfig)
01979 {
01980     ADI_ADISENSE_CORE_Channel_Excitation_t channelExcitationReg;
01981 
01982     channelExcitationReg.VALUE8 = REG_RESET_VAL(CORE_CHANNEL_EXCITATIONn);
01983 
01984     if (pCurrentConfig->outputLevel  == ADI_SENSE_1000_ADC_EXC_CURRENT_NONE )
01985     {
01986         channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_OFF;
01987     }
01988     else
01989     {
01990         if (pCurrentConfig->outputLevel  == ADI_SENSE_1000_ADC_EXC_CURRENT_50uA )
01991             channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_50UA;
01992         else if (pCurrentConfig->outputLevel  == ADI_SENSE_1000_ADC_EXC_CURRENT_100uA )
01993             channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_100UA;
01994         else if (pCurrentConfig->outputLevel  == ADI_SENSE_1000_ADC_EXC_CURRENT_250uA )
01995             channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_250UA;
01996         else if (pCurrentConfig->outputLevel  == ADI_SENSE_1000_ADC_EXC_CURRENT_500uA )
01997             channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_500UA;
01998         else if (pCurrentConfig->outputLevel  == ADI_SENSE_1000_ADC_EXC_CURRENT_750uA )
01999             channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_750UA;
02000         else if (pCurrentConfig->outputLevel  == ADI_SENSE_1000_ADC_EXC_CURRENT_1000uA )
02001             channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_1000UA;
02002         else
02003         {
02004             ADI_SENSE_LOG_ERROR("Invalid ADC excitation current %d specified",
02005                                 pCurrentConfig->outputLevel );
02006             return ADI_SENSE_INVALID_PARAM ;
02007         }
02008     }
02009 
02010     if (pCurrentConfig->diodeRatio  == ADI_SENSE_1000_ADC_EXC_CURRENT_IOUT_DIODE_DEFAULT)
02011     {
02012         channelExcitationReg.IOUT_Diode_Ratio = 0;
02013     }
02014     else
02015     {
02016         channelExcitationReg.IOUT_Diode_Ratio = 1;
02017     }
02018 
02019     WRITE_REG_U8(hDevice, channelExcitationReg.VALUE8, CORE_CHANNEL_EXCITATIONn(eChannelId));
02020 
02021     return ADI_SENSE_SUCCESS ;
02022 }
02023 
02024 ADI_SENSE_RESULT  adi_sense_SetAdcChannelConfig(
02025     ADI_SENSE_DEVICE_HANDLE  hDevice,
02026     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
02027     ADI_SENSE_1000_CHANNEL_CONFIG  *pChannelConfig)
02028 {
02029     ADI_SENSE_RESULT  eRet;
02030     ADI_SENSE_1000_ADC_CHANNEL_CONFIG  *pAdcChannelConfig =
02031         &pChannelConfig->adcChannelConfig ;
02032 
02033     eRet = adi_sense_SetChannelAdcSensorType(hDevice, eChannelId,
02034                                              pAdcChannelConfig->sensor );
02035     if (eRet != ADI_SENSE_SUCCESS )
02036     {
02037         ADI_SENSE_LOG_ERROR("Failed to set ADC sensor type for channel %d",
02038                             eChannelId);
02039         return eRet;
02040     }
02041 
02042     eRet = adi_sense_SetChannelAdcSensorDetails(hDevice, eChannelId,
02043                                                 pChannelConfig);
02044     if (eRet != ADI_SENSE_SUCCESS )
02045     {
02046         ADI_SENSE_LOG_ERROR("Failed to set ADC sensor details for channel %d",
02047                             eChannelId);
02048         return eRet;
02049     }
02050 
02051     eRet = adi_sense_SetChannelAdcFilter(hDevice, eChannelId,
02052                                          &pAdcChannelConfig->filter );
02053     if (eRet != ADI_SENSE_SUCCESS )
02054     {
02055         ADI_SENSE_LOG_ERROR("Failed to set ADC filter for channel %d",
02056                             eChannelId);
02057         return eRet;
02058     }
02059 
02060     eRet = adi_sense_SetChannelAdcCurrentConfig(hDevice, eChannelId,
02061                                                 &pAdcChannelConfig->current );
02062     if (eRet != ADI_SENSE_SUCCESS )
02063     {
02064         ADI_SENSE_LOG_ERROR("Failed to set ADC current for channel %d",
02065                             eChannelId);
02066         return eRet;
02067     }
02068 
02069     return ADI_SENSE_SUCCESS ;
02070 }
02071 
02072 static ADI_SENSE_RESULT  adi_sense_SetChannelDigitalSensorDetails(
02073     ADI_SENSE_DEVICE_HANDLE  hDevice,
02074     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
02075     ADI_SENSE_1000_CHANNEL_CONFIG  *pChannelConfig)
02076 {
02077     ADI_ADISENSE_CORE_Sensor_Details_t sensorDetailsReg;
02078 
02079     sensorDetailsReg.VALUE32 = REG_RESET_VAL(CORE_SENSOR_DETAILSn);
02080 
02081     if (pChannelConfig->compensationChannel  == ADI_SENSE_1000_CHANNEL_ID_NONE )
02082     {
02083         sensorDetailsReg.Compensation_Disable = 1;
02084         sensorDetailsReg.Compensation_Channel = 0;
02085     }
02086     else
02087     {
02088         ADI_SENSE_LOG_ERROR("Invalid compensation channel specified for digital sensor");
02089         return ADI_SENSE_INVALID_PARAM ;
02090     }
02091 
02092     if (pChannelConfig->measurementUnit  == ADI_SENSE_1000_MEASUREMENT_UNIT_UNSPECIFIED )
02093     {
02094         sensorDetailsReg.Measurement_Units = ADISENSE_CORE_SENSOR_DETAILS_UNITS_UNSPECIFIED;
02095     }
02096     else
02097     {
02098         ADI_SENSE_LOG_ERROR("Invalid measurement unit specified for digital channel");
02099         return ADI_SENSE_INVALID_PARAM ;
02100     }
02101 
02102     if (pChannelConfig->disablePublishing )
02103         sensorDetailsReg.Do_Not_Publish = 1;
02104     else
02105         sensorDetailsReg.Do_Not_Publish = 0;
02106 
02107     if (pChannelConfig->enableUnityLut )
02108         sensorDetailsReg.Unity_LUT_Select = 1;
02109     else
02110         sensorDetailsReg.Unity_LUT_Select = 0;
02111 
02112     sensorDetailsReg.Vbias = 0;
02113     sensorDetailsReg.Reference_Buffer_Disable = 1;
02114 
02115     WRITE_REG_U32(hDevice, sensorDetailsReg.VALUE32, CORE_SENSOR_DETAILSn(eChannelId));
02116 
02117     return ADI_SENSE_SUCCESS ;
02118 }
02119 
02120 static ADI_SENSE_RESULT  adi_sense_SetDigitalSensorCommands(
02121     ADI_SENSE_DEVICE_HANDLE  hDevice,
02122     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
02123     ADI_SENSE_1000_DIGITAL_SENSOR_COMMAND  *pConfigCommand,
02124     ADI_SENSE_1000_DIGITAL_SENSOR_COMMAND  *pDataRequestCommand)
02125 {
02126     ADI_ADISENSE_CORE_Digital_Sensor_Num_Cmds_t numCmdsReg;
02127 
02128     numCmdsReg.VALUE8 = REG_RESET_VAL(CORE_DIGITAL_SENSOR_NUM_CMDSn);
02129 
02130     CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_NUM_CMDS_DIGITAL_SENSOR_NUM_CFG_CMDS,
02131                         pConfigCommand->commandLength );
02132     CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_NUM_CMDS_DIGITAL_SENSOR_NUM_READ_CMDS,
02133                         pDataRequestCommand->commandLength );
02134 
02135     numCmdsReg.Digital_Sensor_Num_Cfg_Cmds = pConfigCommand->commandLength ;
02136     numCmdsReg.Digital_Sensor_Num_Read_Cmds = pDataRequestCommand->commandLength ;
02137 
02138     WRITE_REG_U8(hDevice, numCmdsReg.VALUE8,
02139                  CORE_DIGITAL_SENSOR_NUM_CMDSn(eChannelId));
02140 
02141     /*
02142      * NOTE - the fall-through cases in the switch statement below are
02143      * intentional, so temporarily disable related compiler warnings which may
02144      * be produced here by GCC
02145      */
02146 #ifndef __CC_ARM
02147 #pragma GCC diagnostic push
02148 #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
02149 #endif
02150 
02151     switch (pConfigCommand->commandLength )
02152     {
02153     case 7:
02154         WRITE_REG_U8(hDevice, pConfigCommand->command [6],
02155                      CORE_DIGITAL_SENSOR_COMMAND7n(eChannelId));
02156     case 6:
02157         WRITE_REG_U8(hDevice, pConfigCommand->command [5],
02158                      CORE_DIGITAL_SENSOR_COMMAND6n(eChannelId));
02159     case 5:
02160         WRITE_REG_U8(hDevice, pConfigCommand->command [4],
02161                      CORE_DIGITAL_SENSOR_COMMAND5n(eChannelId));
02162     case 4:
02163         WRITE_REG_U8(hDevice, pConfigCommand->command [3],
02164                      CORE_DIGITAL_SENSOR_COMMAND4n(eChannelId));
02165     case 3:
02166         WRITE_REG_U8(hDevice, pConfigCommand->command [2],
02167                      CORE_DIGITAL_SENSOR_COMMAND3n(eChannelId));
02168     case 2:
02169         WRITE_REG_U8(hDevice, pConfigCommand->command [1],
02170                      CORE_DIGITAL_SENSOR_COMMAND2n(eChannelId));
02171     case 1:
02172         WRITE_REG_U8(hDevice, pConfigCommand->command [0],
02173                      CORE_DIGITAL_SENSOR_COMMAND1n(eChannelId));
02174     case 0:
02175     default:
02176         break;
02177     };
02178 
02179     switch (pDataRequestCommand->commandLength )
02180     {
02181     case 7:
02182         WRITE_REG_U8(hDevice, pDataRequestCommand->command [6],
02183                      CORE_DIGITAL_SENSOR_READ_CMD7n(eChannelId));
02184     case 6:
02185         WRITE_REG_U8(hDevice, pDataRequestCommand->command [5],
02186                      CORE_DIGITAL_SENSOR_READ_CMD6n(eChannelId));
02187     case 5:
02188         WRITE_REG_U8(hDevice, pDataRequestCommand->command [4],
02189                      CORE_DIGITAL_SENSOR_READ_CMD5n(eChannelId));
02190     case 4:
02191         WRITE_REG_U8(hDevice, pDataRequestCommand->command [3],
02192                      CORE_DIGITAL_SENSOR_READ_CMD4n(eChannelId));
02193     case 3:
02194         WRITE_REG_U8(hDevice, pDataRequestCommand->command [2],
02195                      CORE_DIGITAL_SENSOR_READ_CMD3n(eChannelId));
02196     case 2:
02197         WRITE_REG_U8(hDevice, pDataRequestCommand->command [1],
02198                      CORE_DIGITAL_SENSOR_READ_CMD2n(eChannelId));
02199     case 1:
02200         WRITE_REG_U8(hDevice, pDataRequestCommand->command [0],
02201                      CORE_DIGITAL_SENSOR_READ_CMD1n(eChannelId));
02202     case 0:
02203     default:
02204         break;
02205     };
02206 
02207     /* Re-enable the implicit-fallthrough warning */
02208 #ifndef __CC_ARM
02209 #pragma GCC diagnostic pop
02210 #endif
02211 
02212     return ADI_SENSE_SUCCESS ;
02213 }
02214 
02215 static ADI_SENSE_RESULT  adi_sense_SetDigitalSensorFormat(
02216     ADI_SENSE_DEVICE_HANDLE  hDevice,
02217     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
02218     ADI_SENSE_1000_DIGITAL_SENSOR_DATA_FORMAT  *pDataFormat)
02219 {
02220     ADI_ADISENSE_CORE_Digital_Sensor_Config_t sensorConfigReg;
02221 
02222     sensorConfigReg.VALUE16 = REG_RESET_VAL(CORE_DIGITAL_SENSOR_CONFIGn);
02223 
02224     if (pDataFormat->coding != ADI_SENSE_1000_DIGITAL_SENSOR_DATA_CODING_NONE)
02225     {
02226         if (pDataFormat->frameLength == 0)
02227         {
02228             ADI_SENSE_LOG_ERROR("Invalid frame length specified for digital sensor data format");
02229             return ADI_SENSE_INVALID_PARAM ;
02230         }
02231         if (pDataFormat->numDataBits == 0)
02232         {
02233             ADI_SENSE_LOG_ERROR("Invalid frame length specified for digital sensor data format");
02234             return ADI_SENSE_INVALID_PARAM ;
02235         }
02236 
02237         CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_CONFIG_DIGITAL_SENSOR_READ_BYTES,
02238                             pDataFormat->frameLength - 1);
02239         CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_CONFIG_DIGITAL_SENSOR_DATA_BITS,
02240                             pDataFormat->numDataBits - 1);
02241         CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_CONFIG_DIGITAL_SENSOR_BIT_OFFSET,
02242                             pDataFormat->bitOffset);
02243 
02244         sensorConfigReg.Digital_Sensor_Read_Bytes = pDataFormat->frameLength - 1;
02245         sensorConfigReg.Digital_Sensor_Data_Bits = pDataFormat->numDataBits - 1;
02246         sensorConfigReg.Digital_Sensor_Bit_Offset = pDataFormat->bitOffset;
02247         sensorConfigReg.Digital_Sensor_Left_Aligned = pDataFormat->leftJustified ? 1 : 0;
02248         sensorConfigReg.Digital_Sensor_Little_Endian = pDataFormat->littleEndian ? 1 : 0;
02249 
02250         switch (pDataFormat->coding)
02251         {
02252         case ADI_SENSE_1000_DIGITAL_SENSOR_DATA_CODING_UNIPOLAR:
02253             sensorConfigReg.Digital_Sensor_Coding = ADISENSE_CORE_DIGITAL_SENSOR_CONFIG_CODING_UNIPOLAR;
02254             break;
02255         case ADI_SENSE_1000_DIGITAL_SENSOR_DATA_CODING_TWOS_COMPLEMENT:
02256             sensorConfigReg.Digital_Sensor_Coding = ADISENSE_CORE_DIGITAL_SENSOR_CONFIG_CODING_TWOS_COMPL;
02257             break;
02258         case ADI_SENSE_1000_DIGITAL_SENSOR_DATA_CODING_OFFSET_BINARY:
02259             sensorConfigReg.Digital_Sensor_Coding = ADISENSE_CORE_DIGITAL_SENSOR_CONFIG_CODING_OFFSET_BINARY;
02260             break;
02261         default:
02262             ADI_SENSE_LOG_ERROR("Invalid coding specified for digital sensor data format");
02263             return ADI_SENSE_INVALID_PARAM ;
02264         }
02265     }
02266     else
02267     {
02268         sensorConfigReg.Digital_Sensor_Coding = ADISENSE_CORE_DIGITAL_SENSOR_CONFIG_CODING_NONE;
02269     }
02270 
02271     WRITE_REG_U16(hDevice, sensorConfigReg.VALUE16,
02272                   CORE_DIGITAL_SENSOR_CONFIGn(eChannelId));
02273 
02274 
02275     return ADI_SENSE_SUCCESS ;
02276 }
02277 
02278 static ADI_SENSE_RESULT  adi_sense_SetDigitalCalibrationParam(
02279         ADI_SENSE_DEVICE_HANDLE  hDevice,
02280         ADI_SENSE_1000_CHANNEL_ID  eChannelId,
02281         ADI_SENSE_1000_DIGITAL_CALIBRATION_COMMAND  *pCalibrationParam)
02282 {
02283     ADI_ADISENSE_CORE_Calibration_Parameter_t calibrationParamReg;
02284 
02285     calibrationParamReg.VALUE32 = REG_RESET_VAL(CORE_CALIBRATION_PARAMETERn);
02286 
02287     if (pCalibrationParam->enableCalibrationParam  == false)
02288         calibrationParamReg.Calibration_Parameter_Enable = 0;
02289     else
02290         calibrationParamReg.Calibration_Parameter_Enable = 1;
02291 
02292     CHECK_REG_FIELD_VAL(CORE_CALIBRATION_PARAMETER_CALIBRATION_PARAMETER,
02293         pCalibrationParam->calibrationParam );
02294 
02295     calibrationParamReg.Calibration_Parameter = pCalibrationParam->calibrationParam ;
02296 
02297     WRITE_REG_U32(hDevice, calibrationParamReg.VALUE32,
02298                   CORE_CALIBRATION_PARAMETERn(eChannelId));
02299 
02300     return ADI_SENSE_SUCCESS ;
02301 }
02302 
02303 static ADI_SENSE_RESULT  adi_sense_SetChannelI2cSensorType(
02304     ADI_SENSE_DEVICE_HANDLE  hDevice,
02305     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
02306     ADI_SENSE_1000_I2C_SENSOR_TYPE  sensorType)
02307 {
02308     ADI_ADISENSE_CORE_Sensor_Type_t sensorTypeReg;
02309 
02310     sensorTypeReg.VALUE16 = REG_RESET_VAL(CORE_SENSOR_TYPEn);
02311 
02312     /* Ensure that the sensor type is valid for this channel */
02313     switch(sensorType)
02314     {
02315     case ADI_SENSE_1000_I2C_SENSOR_HUMIDITY_A_DEF_L1 :
02316     case ADI_SENSE_1000_I2C_SENSOR_HUMIDITY_B_DEF_L1 :
02317     case ADI_SENSE_1000_I2C_SENSOR_HUMIDITY_A_DEF_L2 :
02318     case ADI_SENSE_1000_I2C_SENSOR_HUMIDITY_B_DEF_L2 :
02319     case ADI_SENSE_1000_I2C_SENSOR_HUMIDITY_A_ADV_L1 :
02320     case ADI_SENSE_1000_I2C_SENSOR_HUMIDITY_B_ADV_L1 :
02321     case ADI_SENSE_1000_I2C_SENSOR_HUMIDITY_A_ADV_L2 :
02322     case ADI_SENSE_1000_I2C_SENSOR_HUMIDITY_B_ADV_L2 :
02323     case ADI_SENSE_1000_I2C_SENSOR_AMBIENTLIGHT_A_DEF_L1 :
02324     case ADI_SENSE_1000_I2C_SENSOR_AMBIENTLIGHT_A_DEF_L2 :
02325     case ADI_SENSE_1000_I2C_SENSOR_AMBIENTLIGHT_A_ADV_L1 :
02326     case ADI_SENSE_1000_I2C_SENSOR_AMBIENTLIGHT_A_ADV_L2 :
02327         sensorTypeReg.Sensor_Type = sensorType;
02328         break;
02329     default:
02330         ADI_SENSE_LOG_ERROR("Unsupported I2C sensor type %d specified", sensorType);
02331         return ADI_SENSE_INVALID_PARAM ;
02332     }
02333 
02334     WRITE_REG_U16(hDevice, sensorTypeReg.VALUE16, CORE_SENSOR_TYPEn(eChannelId));
02335 
02336     return ADI_SENSE_SUCCESS ;
02337 }
02338 
02339 static ADI_SENSE_RESULT  adi_sense_SetChannelI2cSensorAddress(
02340     ADI_SENSE_DEVICE_HANDLE  hDevice,
02341     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
02342     uint32_t deviceAddress)
02343 {
02344     CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_ADDRESS_DIGITAL_SENSOR_ADDRESS, deviceAddress);
02345     WRITE_REG_U8(hDevice, deviceAddress, CORE_DIGITAL_SENSOR_ADDRESSn(eChannelId));
02346 
02347     return ADI_SENSE_SUCCESS ;
02348 }
02349 
02350 static ADI_SENSE_RESULT  adi_sense_SetDigitalChannelComms(
02351     ADI_SENSE_DEVICE_HANDLE  hDevice,
02352     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
02353     ADI_SENSE_1000_DIGITAL_SENSOR_COMMS  *pDigitalComms)
02354 {
02355     ADI_ADISENSE_CORE_Digital_Sensor_Comms_t digitalSensorComms;
02356 
02357     digitalSensorComms.VALUE16 = REG_RESET_VAL(CORE_DIGITAL_SENSOR_COMMSn);
02358 
02359     if(pDigitalComms->useCustomCommsConfig )
02360     {
02361         digitalSensorComms.Digital_Sensor_Comms_En = 1;
02362 
02363         if(pDigitalComms->i2cClockSpeed  == ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_I2C_CLOCK_SPEED_100K )
02364         {
02365             digitalSensorComms.I2C_Clock = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_I2C_100K;
02366         }
02367         else if(pDigitalComms->i2cClockSpeed  == ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_I2C_CLOCK_SPEED_400K )
02368         {
02369             digitalSensorComms.I2C_Clock = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_I2C_400K;
02370         }
02371         else
02372         {
02373             ADI_SENSE_LOG_ERROR("Invalid I2C clock speed %d specified",
02374                                 pDigitalComms->i2cClockSpeed );
02375             return ADI_SENSE_INVALID_PARAM ;
02376         }
02377 
02378         if(pDigitalComms->spiMode  == ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_SPI_MODE_0 )
02379         {
02380             digitalSensorComms.SPI_Mode = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_SPI_MODE_0;
02381         }
02382         else if(pDigitalComms->spiMode  == ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_SPI_MODE_1 )
02383         {
02384             digitalSensorComms.SPI_Mode = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_SPI_MODE_1;
02385         }
02386         else if(pDigitalComms->spiMode  == ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_SPI_MODE_2 )
02387         {
02388             digitalSensorComms.SPI_Mode = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_SPI_MODE_2;
02389         }
02390         else if(pDigitalComms->spiMode  == ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_SPI_MODE_3 )
02391         {
02392             digitalSensorComms.SPI_Mode = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_SPI_MODE_3;
02393         }
02394         else
02395         {
02396             ADI_SENSE_LOG_ERROR("Invalid SPI mode %d specified",
02397                                 pDigitalComms->spiMode );
02398             return ADI_SENSE_INVALID_PARAM ;
02399         }
02400 
02401         switch (pDigitalComms->spiClock )
02402         {
02403         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_SPI_CLOCK_13MHZ :
02404             digitalSensorComms.SPI_Clock = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_SPI_13MHZ;
02405             break;
02406         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_SPI_CLOCK_6_5MHZ :
02407             digitalSensorComms.SPI_Clock = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_SPI_6_5MHZ;
02408             break;
02409         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_SPI_CLOCK_3_25MHZ :
02410             digitalSensorComms.SPI_Clock = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_SPI_3_25MHZ;
02411             break;
02412         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_SPI_CLOCK_1_625MHZ :
02413             digitalSensorComms.SPI_Clock = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_SPI_1_625MHZ;
02414             break;
02415         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_SPI_CLOCK_812KHZ :
02416             digitalSensorComms.SPI_Clock = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_SPI_812KHZ;
02417             break;
02418         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_SPI_CLOCK_406KHZ :
02419             digitalSensorComms.SPI_Clock = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_SPI_406KHZ;
02420             break;
02421         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_SPI_CLOCK_203KHZ :
02422             digitalSensorComms.SPI_Clock = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_SPI_203KHZ;
02423             break;
02424         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_SPI_CLOCK_101KHZ :
02425             digitalSensorComms.SPI_Clock = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_SPI_101KHZ;
02426             break;
02427         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_SPI_CLOCK_50KHZ :
02428             digitalSensorComms.SPI_Clock = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_SPI_50KHZ;
02429             break;
02430         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_SPI_CLOCK_25KHZ :
02431             digitalSensorComms.SPI_Clock = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_SPI_25KHZ;
02432             break;
02433         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_SPI_CLOCK_12KHZ :
02434             digitalSensorComms.SPI_Clock = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_SPI_12KHZ;
02435             break;
02436         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_SPI_CLOCK_6KHZ :
02437             digitalSensorComms.SPI_Clock = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_SPI_6KHZ;
02438             break;
02439         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_SPI_CLOCK_3KHZ :
02440             digitalSensorComms.SPI_Clock = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_SPI_3KHZ;
02441             break;
02442         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_SPI_CLOCK_1_5KHZ :
02443             digitalSensorComms.SPI_Clock = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_SPI_1_5KHZ;
02444             break;
02445         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_SPI_CLOCK_793HZ :
02446             digitalSensorComms.SPI_Clock = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_SPI_793HZ;
02447             break;
02448         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_SPI_CLOCK_396HZ :
02449             digitalSensorComms.SPI_Clock = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_SPI_396HZ;
02450             break;
02451         default:
02452             ADI_SENSE_LOG_ERROR("Invalid SPI clock %d specified",
02453                                 pDigitalComms->spiClock );
02454             return ADI_SENSE_INVALID_PARAM ;
02455         }
02456 
02457         switch (pDigitalComms->uartLineConfig )
02458         {
02459         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_UART_LINE_CONFIG_8N1 :
02460             digitalSensorComms.Uart_Mode = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_LINECONTROL_8N1;
02461             break;
02462         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_UART_LINE_CONFIG_8N2 :
02463             digitalSensorComms.Uart_Mode = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_LINECONTROL_8N2;
02464             break;
02465         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_UART_LINE_CONFIG_8N3 :
02466             digitalSensorComms.Uart_Mode = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_LINECONTROL_8N3;
02467             break;
02468         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_UART_LINE_CONFIG_8E1 :
02469             digitalSensorComms.Uart_Mode = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_LINECONTROL_8E1;
02470             break;
02471         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_UART_LINE_CONFIG_8E2 :
02472             digitalSensorComms.Uart_Mode = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_LINECONTROL_8E2;
02473             break;
02474         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_UART_LINE_CONFIG_8E3 :
02475             digitalSensorComms.Uart_Mode = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_LINECONTROL_8E3;
02476             break;
02477         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_UART_LINE_CONFIG_8O1 :
02478             digitalSensorComms.Uart_Mode = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_LINECONTROL_8O1;
02479             break;
02480         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_UART_LINE_CONFIG_8O2 :
02481             digitalSensorComms.Uart_Mode = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_LINECONTROL_8O2;
02482             break;
02483         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_UART_LINE_CONFIG_8O3 :
02484             digitalSensorComms.Uart_Mode = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_LINECONTROL_8O3;
02485             break;
02486         default:
02487             ADI_SENSE_LOG_ERROR("Invalid UART mode %d specified",
02488                                 pDigitalComms->uartLineConfig );
02489             return ADI_SENSE_INVALID_PARAM ;
02490         }
02491 
02492         switch (pDigitalComms->uartBaudRate )
02493         {
02494         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_UART_BAUD_RATE_115200 :
02495             digitalSensorComms.Uart_Baud = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_UART_115200;
02496             break;
02497         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_UART_BAUD_RATE_57600 :
02498             digitalSensorComms.Uart_Baud = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_UART_57600;
02499             break;
02500         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_UART_BAUD_RATE_38400 :
02501             digitalSensorComms.Uart_Baud = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_UART_38400;
02502             break;
02503         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_UART_BAUD_RATE_19200 :
02504             digitalSensorComms.Uart_Baud = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_UART_19200;
02505             break;
02506         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_UART_BAUD_RATE_9600 :
02507             digitalSensorComms.Uart_Baud = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_UART_9600;
02508             break;
02509         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_UART_BAUD_RATE_4800 :
02510             digitalSensorComms.Uart_Baud = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_UART_4800;
02511             break;
02512         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_UART_BAUD_RATE_2400 :
02513             digitalSensorComms.Uart_Baud = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_UART_2400;
02514             break;
02515         case ADI_SENSE_1000_DIGITAL_SENSOR_COMMS_UART_BAUD_RATE_1200 :
02516             digitalSensorComms.Uart_Baud = ADISENSE_CORE_DIGITAL_SENSOR_COMMS_UART_1200;
02517             break;
02518         default:
02519             ADI_SENSE_LOG_ERROR("Invalid UART baud rate %d specified",
02520                                 pDigitalComms->uartBaudRate );
02521             return ADI_SENSE_INVALID_PARAM ;
02522         }
02523     }
02524     else
02525     {
02526         digitalSensorComms.Digital_Sensor_Comms_En = 0;
02527     }
02528 
02529     WRITE_REG_U16(hDevice, digitalSensorComms.VALUE16, CORE_DIGITAL_SENSOR_COMMSn(eChannelId));
02530 
02531     return ADI_SENSE_SUCCESS ;
02532 }
02533 
02534 ADI_SENSE_RESULT  adi_sense_SetI2cChannelConfig(
02535     ADI_SENSE_DEVICE_HANDLE  hDevice,
02536     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
02537     ADI_SENSE_1000_CHANNEL_CONFIG  *pChannelConfig)
02538 {
02539     ADI_SENSE_RESULT  eRet;
02540     ADI_SENSE_1000_I2C_CHANNEL_CONFIG  *pI2cChannelConfig =
02541         &pChannelConfig->i2cChannelConfig ;
02542 
02543     eRet = adi_sense_SetChannelI2cSensorType(hDevice, eChannelId,
02544                                             pI2cChannelConfig->sensor );
02545     if (eRet != ADI_SENSE_SUCCESS )
02546     {
02547         ADI_SENSE_LOG_ERROR("Failed to set I2C sensor type for channel %d",
02548                             eChannelId);
02549         return eRet;
02550     }
02551 
02552     eRet = adi_sense_SetChannelI2cSensorAddress(hDevice, eChannelId,
02553                                                pI2cChannelConfig->deviceAddress );
02554     if (eRet != ADI_SENSE_SUCCESS )
02555     {
02556         ADI_SENSE_LOG_ERROR("Failed to set I2C sensor address for channel %d",
02557                             eChannelId);
02558         return eRet;
02559     }
02560 
02561     eRet = adi_sense_SetChannelDigitalSensorDetails(hDevice, eChannelId,
02562                                                     pChannelConfig);
02563     if (eRet != ADI_SENSE_SUCCESS )
02564     {
02565         ADI_SENSE_LOG_ERROR("Failed to set I2C sensor details for channel %d",
02566                             eChannelId);
02567         return eRet;
02568     }
02569 
02570     eRet = adi_sense_SetDigitalSensorCommands(hDevice, eChannelId,
02571                                               &pI2cChannelConfig->configurationCommand ,
02572                                               &pI2cChannelConfig->dataRequestCommand );
02573     if (eRet != ADI_SENSE_SUCCESS )
02574     {
02575         ADI_SENSE_LOG_ERROR("Failed to set I2C sensor commands for channel %d",
02576                             eChannelId);
02577         return eRet;
02578     }
02579 
02580     eRet = adi_sense_SetDigitalSensorFormat(hDevice, eChannelId,
02581                                             &pI2cChannelConfig->dataFormat );
02582     if (eRet != ADI_SENSE_SUCCESS )
02583     {
02584         ADI_SENSE_LOG_ERROR("Failed to set I2C sensor data format for channel %d",
02585                             eChannelId);
02586         return eRet;
02587     }
02588 
02589     eRet = adi_sense_SetDigitalCalibrationParam(hDevice, eChannelId,
02590                                             &pI2cChannelConfig->digitalCalibrationParam );
02591     if (eRet != ADI_SENSE_SUCCESS )
02592     {
02593         ADI_SENSE_LOG_ERROR("Failed to set I2C digital calibration param for channel %d",
02594                             eChannelId);
02595         return eRet;
02596     }
02597 
02598     eRet = adi_sense_SetDigitalChannelComms(hDevice, eChannelId,
02599                                             &pI2cChannelConfig->configureComms );
02600     if (eRet != ADI_SENSE_SUCCESS )
02601     {
02602         ADI_SENSE_LOG_ERROR("Failed to set I2C comms for channel %d",
02603                             eChannelId);
02604         return eRet;
02605     }
02606 
02607     return ADI_SENSE_SUCCESS ;
02608 }
02609 
02610 static ADI_SENSE_RESULT  adi_sense_SetChannelSpiSensorType(
02611     ADI_SENSE_DEVICE_HANDLE  hDevice,
02612     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
02613     ADI_SENSE_1000_SPI_SENSOR_TYPE  sensorType)
02614 {
02615     ADI_ADISENSE_CORE_Sensor_Type_t sensorTypeReg;
02616 
02617     sensorTypeReg.VALUE16 = REG_RESET_VAL(CORE_SENSOR_TYPEn);
02618 
02619     /* Ensure that the sensor type is valid for this channel */
02620     switch(sensorType)
02621     {
02622     case ADI_SENSE_1000_SPI_SENSOR_PRESSURE_A_DEF_L1 :
02623     case ADI_SENSE_1000_SPI_SENSOR_PRESSURE_A_DEF_L2 :
02624     case ADI_SENSE_1000_SPI_SENSOR_PRESSURE_A_ADV_L1 :
02625     case ADI_SENSE_1000_SPI_SENSOR_PRESSURE_A_ADV_L2 :
02626     case ADI_SENSE_1000_SPI_SENSOR_ACCELEROMETER_A_DEF_L1 :
02627     case ADI_SENSE_1000_SPI_SENSOR_ACCELEROMETER_B_DEF_L1 :
02628     case ADI_SENSE_1000_SPI_SENSOR_ACCELEROMETER_A_DEF_L2 :
02629     case ADI_SENSE_1000_SPI_SENSOR_ACCELEROMETER_B_DEF_L2 :
02630     case ADI_SENSE_1000_SPI_SENSOR_ACCELEROMETER_A_ADV_L1 :
02631     case ADI_SENSE_1000_SPI_SENSOR_ACCELEROMETER_B_ADV_L1 :
02632     case ADI_SENSE_1000_SPI_SENSOR_ACCELEROMETER_A_ADV_L2 :
02633     case ADI_SENSE_1000_SPI_SENSOR_ACCELEROMETER_B_ADV_L2 :
02634         sensorTypeReg.Sensor_Type = sensorType;
02635         break;
02636     default:
02637         ADI_SENSE_LOG_ERROR("Unsupported SPI sensor type %d specified", sensorType);
02638         return ADI_SENSE_INVALID_PARAM ;
02639     }
02640 
02641     WRITE_REG_U16(hDevice, sensorTypeReg.VALUE16, CORE_SENSOR_TYPEn(eChannelId));
02642 
02643     return ADI_SENSE_SUCCESS ;
02644 }
02645 
02646 ADI_SENSE_RESULT  adi_sense_SetSpiChannelConfig(
02647     ADI_SENSE_DEVICE_HANDLE  hDevice,
02648     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
02649     ADI_SENSE_1000_CHANNEL_CONFIG  *pChannelConfig)
02650 {
02651     ADI_SENSE_RESULT  eRet;
02652     ADI_SENSE_1000_SPI_CHANNEL_CONFIG  *pSpiChannelConfig =
02653         &pChannelConfig->spiChannelConfig ;
02654 
02655     eRet = adi_sense_SetChannelSpiSensorType(hDevice, eChannelId,
02656                                              pSpiChannelConfig->sensor );
02657     if (eRet != ADI_SENSE_SUCCESS )
02658     {
02659         ADI_SENSE_LOG_ERROR("Failed to set SPI sensor type for channel %d",
02660                             eChannelId);
02661         return eRet;
02662     }
02663 
02664     eRet = adi_sense_SetChannelDigitalSensorDetails(hDevice, eChannelId,
02665                                                     pChannelConfig);
02666     if (eRet != ADI_SENSE_SUCCESS )
02667     {
02668         ADI_SENSE_LOG_ERROR("Failed to set SPI sensor details for channel %d",
02669                             eChannelId);
02670         return eRet;
02671     }
02672 
02673     eRet = adi_sense_SetDigitalSensorCommands(hDevice, eChannelId,
02674                                               &pSpiChannelConfig->configurationCommand ,
02675                                               &pSpiChannelConfig->dataRequestCommand );
02676     if (eRet != ADI_SENSE_SUCCESS )
02677     {
02678         ADI_SENSE_LOG_ERROR("Failed to set SPI sensor commands for channel %d",
02679                             eChannelId);
02680         return eRet;
02681     }
02682 
02683     eRet = adi_sense_SetDigitalSensorFormat(hDevice, eChannelId,
02684                                             &pSpiChannelConfig->dataFormat );
02685     if (eRet != ADI_SENSE_SUCCESS )
02686     {
02687         ADI_SENSE_LOG_ERROR("Failed to set SPI sensor data format for channel %d",
02688                             eChannelId);
02689         return eRet;
02690     }
02691 
02692     eRet = adi_sense_SetDigitalCalibrationParam(hDevice, eChannelId,
02693                                             &pSpiChannelConfig->digitalCalibrationParam );
02694     if (eRet != ADI_SENSE_SUCCESS )
02695     {
02696         ADI_SENSE_LOG_ERROR("Failed to set SPI digital calibration param for channel %d",
02697                             eChannelId);
02698         return eRet;
02699     }
02700 
02701     eRet = adi_sense_SetDigitalChannelComms(hDevice, eChannelId,
02702                                             &pSpiChannelConfig->configureComms );
02703     if (eRet != ADI_SENSE_SUCCESS )
02704     {
02705         ADI_SENSE_LOG_ERROR("Failed to set SPI comms for channel %d",
02706                             eChannelId);
02707         return eRet;
02708     }
02709 
02710     return ADI_SENSE_SUCCESS ;
02711 }
02712 
02713 static ADI_SENSE_RESULT  adi_sense_SetChannelUartSensorType(
02714     ADI_SENSE_DEVICE_HANDLE  hDevice,
02715     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
02716     ADI_SENSE_1000_UART_SENSOR_TYPE  sensorType)
02717 {
02718     ADI_ADISENSE_CORE_Sensor_Type_t sensorTypeReg;
02719 
02720     sensorTypeReg.VALUE16 = REG_RESET_VAL(CORE_SENSOR_TYPEn);
02721 
02722     /* Ensure that the sensor type is valid for this channel */
02723     switch(sensorType)
02724     {
02725     case ADI_SENSE_1000_UART_SENSOR_UART_CO2_A_DEF_L1 :
02726     case ADI_SENSE_1000_UART_SENSOR_UART_CO2_B_DEF_L1 :
02727     case ADI_SENSE_1000_UART_SENSOR_UART_CO2_A_DEF_L2 :
02728     case ADI_SENSE_1000_UART_SENSOR_UART_CO2_B_DEF_L2 :
02729     case ADI_SENSE_1000_UART_SENSOR_UART_CO2_A_ADV_L1 :
02730     case ADI_SENSE_1000_UART_SENSOR_UART_CO2_B_ADV_L1 :
02731     case ADI_SENSE_1000_UART_SENSOR_UART_CO2_A_ADV_L2 :
02732     case ADI_SENSE_1000_UART_SENSOR_UART_CO2_B_ADV_L2 :
02733         sensorTypeReg.Sensor_Type = sensorType;
02734         break;
02735     default:
02736         ADI_SENSE_LOG_ERROR("Unsupported UART sensor type %d specified", sensorType);
02737         return ADI_SENSE_INVALID_PARAM ;
02738     }
02739 
02740     WRITE_REG_U16(hDevice, sensorTypeReg.VALUE16, CORE_SENSOR_TYPEn(eChannelId));
02741 
02742     return ADI_SENSE_SUCCESS ;
02743 }
02744 
02745 ADI_SENSE_RESULT  adi_sense_SetUartChannelConfig(
02746     ADI_SENSE_DEVICE_HANDLE  hDevice,
02747     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
02748     ADI_SENSE_1000_CHANNEL_CONFIG  *pChannelConfig)
02749 {
02750     ADI_SENSE_RESULT  eRet;
02751     ADI_SENSE_1000_UART_CHANNEL_CONFIG  *pUartChannelConfig =
02752         &pChannelConfig->uartChannelConfig ;
02753 
02754     eRet = adi_sense_SetChannelUartSensorType(hDevice, eChannelId,
02755                                              pUartChannelConfig->sensor );
02756     if (eRet != ADI_SENSE_SUCCESS )
02757     {
02758         ADI_SENSE_LOG_ERROR("Failed to set UART sensor type for channel %d",
02759                             eChannelId);
02760         return eRet;
02761     }
02762 
02763     eRet = adi_sense_SetChannelDigitalSensorDetails(hDevice, eChannelId,
02764                                                     pChannelConfig);
02765     if (eRet != ADI_SENSE_SUCCESS )
02766     {
02767         ADI_SENSE_LOG_ERROR("Failed to set UART sensor details for channel %d",
02768                             eChannelId);
02769         return eRet;
02770     }
02771 
02772     eRet = adi_sense_SetDigitalCalibrationParam(hDevice, eChannelId,
02773                                             &pUartChannelConfig->digitalCalibrationParam );
02774     if (eRet != ADI_SENSE_SUCCESS )
02775     {
02776         ADI_SENSE_LOG_ERROR("Failed to set UART digital calibration param for channel %d",
02777                             eChannelId);
02778         return eRet;
02779     }
02780 
02781     eRet = adi_sense_SetDigitalChannelComms(hDevice, eChannelId,
02782                                             &pUartChannelConfig->configureComms );
02783     if (eRet != ADI_SENSE_SUCCESS )
02784     {
02785         ADI_SENSE_LOG_ERROR("Failed to set UART comms for channel %d",
02786                             eChannelId);
02787         return eRet;
02788     }
02789 
02790 
02791     return ADI_SENSE_SUCCESS ;
02792 }
02793 
02794 ADI_SENSE_RESULT  adi_sense_1000_SetChannelThresholdLimits(
02795     ADI_SENSE_DEVICE_HANDLE  hDevice,
02796     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
02797     float32_t fHighThresholdLimit,
02798     float32_t fLowThresholdLimit)
02799 {
02800     /*
02801      * If the low/high limits are *both* set to 0 in memory, or NaNs, assume
02802      * that they are unset, or not required, and use infinity defaults instead
02803      */
02804     if (fHighThresholdLimit == 0.0f && fLowThresholdLimit == 0.0f)
02805     {
02806         fHighThresholdLimit = INFINITY;
02807         fLowThresholdLimit = -INFINITY;
02808     }
02809     else
02810     {
02811         if (isnan(fHighThresholdLimit))
02812             fHighThresholdLimit = INFINITY;
02813         if (isnan(fLowThresholdLimit))
02814             fLowThresholdLimit = -INFINITY;
02815     }
02816 
02817     WRITE_REG_FLOAT(hDevice, fHighThresholdLimit,
02818                     CORE_HIGH_THRESHOLD_LIMITn(eChannelId));
02819     WRITE_REG_FLOAT(hDevice, fLowThresholdLimit,
02820                     CORE_LOW_THRESHOLD_LIMITn(eChannelId));
02821 
02822     return ADI_SENSE_SUCCESS ;
02823 }
02824 
02825 ADI_SENSE_RESULT  adi_sense_1000_SetOffsetGain(
02826     ADI_SENSE_DEVICE_HANDLE  hDevice,
02827     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
02828     float32_t fOffsetAdjustment,
02829     float32_t fGainAdjustment)
02830 {
02831     /* Replace with default values if NaNs are specified (or 0.0 for gain) */
02832     if (isnan(fGainAdjustment) || (fGainAdjustment == 0.0f))
02833         fGainAdjustment = 1.0f;
02834     if (isnan(fOffsetAdjustment))
02835         fOffsetAdjustment = 0.0f;
02836 
02837     WRITE_REG_FLOAT(hDevice, fGainAdjustment, CORE_SENSOR_GAINn(eChannelId));
02838     WRITE_REG_FLOAT(hDevice, fOffsetAdjustment, CORE_SENSOR_OFFSETn(eChannelId));
02839 
02840     return ADI_SENSE_SUCCESS ;
02841 }
02842 
02843 ADI_SENSE_RESULT  adi_sense_1000_SetSensorParameter(
02844     ADI_SENSE_DEVICE_HANDLE  hDevice,
02845     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
02846     float32_t fSensorParam)
02847 {
02848     if (fSensorParam == 0.0)
02849         fSensorParam = NAN;
02850 
02851     WRITE_REG_FLOAT(hDevice, fSensorParam, CORE_SENSOR_PARAMETERn(eChannelId));
02852 
02853     return ADI_SENSE_SUCCESS ;
02854 }
02855 
02856 ADI_SENSE_RESULT  adi_sense_1000_SetChannelSettlingTime(
02857     ADI_SENSE_DEVICE_HANDLE  hDevice,
02858     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
02859     uint32_t nSettlingTime)
02860 {
02861     ADI_ADISENSE_CORE_Settling_Time_t settlingTimeReg;
02862 
02863     if (nSettlingTime < (1 << 12))
02864     {
02865         settlingTimeReg.Settling_Time_Units = ADISENSE_CORE_SETTLING_TIME_MICROSECONDS;
02866     }
02867     else if (nSettlingTime < (1000 * (1 << 12)))
02868     {
02869         settlingTimeReg.Settling_Time_Units = ADISENSE_CORE_SETTLING_TIME_MILLISECONDS;
02870         nSettlingTime /= 1000;
02871     }
02872     else
02873     {
02874         settlingTimeReg.Settling_Time_Units = ADISENSE_CORE_SETTLING_TIME_SECONDS;
02875         nSettlingTime /= 1000000;
02876     }
02877 
02878     CHECK_REG_FIELD_VAL(CORE_SETTLING_TIME_SETTLING_TIME, nSettlingTime);
02879     settlingTimeReg.Settling_Time = nSettlingTime;
02880 
02881     WRITE_REG_U16(hDevice, settlingTimeReg.VALUE16, CORE_SETTLING_TIMEn(eChannelId));
02882 
02883     return ADI_SENSE_SUCCESS ;
02884 }
02885 
02886 ADI_SENSE_RESULT  adi_sense_1000_SetChannelConfig(
02887     ADI_SENSE_DEVICE_HANDLE  hDevice,
02888     ADI_SENSE_1000_CHANNEL_ID  eChannelId,
02889     ADI_SENSE_1000_CHANNEL_CONFIG  *pChannelConfig)
02890 {
02891     ADI_SENSE_RESULT  eRet;
02892 
02893     if (! ADI_SENSE_1000_CHANNEL_IS_VIRTUAL(eChannelId))
02894     {
02895         /* If the channel is not enabled, disable it and return */
02896         if (! pChannelConfig->enableChannel )
02897             return adi_sense_1000_SetChannelCount(hDevice, eChannelId, 0);
02898 
02899         eRet = adi_sense_1000_SetChannelCount(hDevice, eChannelId,
02900                                               pChannelConfig->measurementsPerCycle );
02901         if (eRet != ADI_SENSE_SUCCESS )
02902         {
02903             ADI_SENSE_LOG_ERROR("Failed to set measurement count for channel %d",
02904                                 eChannelId);
02905             return eRet;
02906         }
02907 
02908         eRet = adi_sense_1000_SetChannelOptions(hDevice, eChannelId,
02909                                                 pChannelConfig->priority ,
02910                                                 pChannelConfig->enableFFT );
02911         if (eRet != ADI_SENSE_SUCCESS )
02912         {
02913             ADI_SENSE_LOG_ERROR("Failed to set priority for channel %d",
02914                                 eChannelId);
02915             return eRet;
02916         }
02917 
02918         eRet = adi_sense_1000_SetChannelSkipCount(hDevice, eChannelId,
02919                                                   pChannelConfig->cycleSkipCount );
02920         if (eRet != ADI_SENSE_SUCCESS )
02921         {
02922             ADI_SENSE_LOG_ERROR("Failed to set cycle skip count for channel %d",
02923                                 eChannelId);
02924             return eRet;
02925         }
02926 
02927         switch (eChannelId)
02928         {
02929         case ADI_SENSE_1000_CHANNEL_ID_CJC_0 :
02930         case ADI_SENSE_1000_CHANNEL_ID_CJC_1 :
02931         case ADI_SENSE_1000_CHANNEL_ID_SENSOR_0 :
02932         case ADI_SENSE_1000_CHANNEL_ID_SENSOR_1 :
02933         case ADI_SENSE_1000_CHANNEL_ID_SENSOR_2 :
02934         case ADI_SENSE_1000_CHANNEL_ID_SENSOR_3 :
02935         case ADI_SENSE_1000_CHANNEL_ID_VOLTAGE_0 :
02936         case ADI_SENSE_1000_CHANNEL_ID_CURRENT_0 :
02937             eRet = adi_sense_SetAdcChannelConfig(hDevice, eChannelId, pChannelConfig);
02938             break;
02939         case ADI_SENSE_1000_CHANNEL_ID_I2C_0 :
02940         case ADI_SENSE_1000_CHANNEL_ID_I2C_1 :
02941             eRet = adi_sense_SetI2cChannelConfig(hDevice, eChannelId, pChannelConfig);
02942             break;
02943         case ADI_SENSE_1000_CHANNEL_ID_SPI_0 :
02944             eRet = adi_sense_SetSpiChannelConfig(hDevice, eChannelId, pChannelConfig);
02945             break;
02946         case ADI_SENSE_1000_CHANNEL_ID_UART :
02947             eRet = adi_sense_SetUartChannelConfig(hDevice, eChannelId, pChannelConfig);
02948             break;
02949         default:
02950             ADI_SENSE_LOG_ERROR("Invalid channel ID %d specified", eChannelId);
02951             return ADI_SENSE_INVALID_PARAM ;
02952         }
02953 
02954         eRet = adi_sense_1000_SetChannelSettlingTime(hDevice, eChannelId,
02955                                                      pChannelConfig->extraSettlingTime );
02956         if (eRet != ADI_SENSE_SUCCESS )
02957         {
02958             ADI_SENSE_LOG_ERROR("Failed to set settling time for channel %d",
02959                                 eChannelId);
02960             return eRet;
02961         }
02962     }
02963 
02964     if (pChannelConfig->enableChannel )
02965     {
02966         /* Threshold limits can be configured individually for virtual channels */
02967         eRet = adi_sense_1000_SetChannelThresholdLimits(hDevice, eChannelId,
02968                                                         pChannelConfig->highThreshold ,
02969                                                         pChannelConfig->lowThreshold );
02970         if (eRet != ADI_SENSE_SUCCESS )
02971         {
02972             ADI_SENSE_LOG_ERROR("Failed to set threshold limits for channel %d",
02973                                 eChannelId);
02974             return eRet;
02975         }
02976 
02977         /* Offset and gain can be configured individually for virtual channels */
02978         eRet = adi_sense_1000_SetOffsetGain(hDevice, eChannelId,
02979                                             pChannelConfig->offsetAdjustment ,
02980                                             pChannelConfig->gainAdjustment );
02981         if (eRet != ADI_SENSE_SUCCESS )
02982         {
02983             ADI_SENSE_LOG_ERROR("Failed to set offset/gain for channel %d",
02984                                 eChannelId);
02985             return eRet;
02986         }
02987 
02988         /* Set sensor specific parameter */
02989         eRet = adi_sense_1000_SetSensorParameter(hDevice, eChannelId,
02990                                                  pChannelConfig->sensorParameter );
02991         if (eRet != ADI_SENSE_SUCCESS )
02992         {
02993             ADI_SENSE_LOG_ERROR("Failed to set sensor parameter for channel %d",
02994                                 eChannelId);
02995             return eRet;
02996         }
02997     }
02998 
02999     return ADI_SENSE_SUCCESS ;
03000 }
03001 
03002 ADI_SENSE_RESULT  adi_sense_SetConfig(
03003     ADI_SENSE_DEVICE_HANDLE     const hDevice,
03004     ADI_SENSE_CONFIG          * const pConfig)
03005 {
03006     ADI_SENSE_1000_CONFIG  *pDeviceConfig;
03007     ADI_SENSE_PRODUCT_ID  productId;
03008     ADI_SENSE_RESULT  eRet;
03009 
03010     if (pConfig->productId  != ADI_SENSE_PRODUCT_ID_ADSNS1000 )
03011     {
03012         ADI_SENSE_LOG_ERROR("Configuration Product ID (0x%X) is not supported (0x%0X)",
03013                             pConfig->productId , ADI_SENSE_PRODUCT_ID_ADSNS1000 );
03014         return ADI_SENSE_INVALID_PARAM ;
03015     }
03016 
03017     /* Check that the actual Product ID is a match? */
03018     eRet = adi_sense_GetProductID(hDevice, &productId);
03019     if (eRet)
03020     {
03021         ADI_SENSE_LOG_ERROR("Failed to read device Product ID register");
03022         return eRet;
03023     }
03024     if (pConfig->productId  != productId)
03025     {
03026         ADI_SENSE_LOG_ERROR("Configuration Product ID (0x%X) does not match device (0x%0X)",
03027                             pConfig->productId , productId);
03028         return ADI_SENSE_INVALID_PARAM ;
03029     }
03030 
03031     pDeviceConfig = &pConfig->adisense1000 ;
03032 
03033     eRet = adi_sense_1000_SetPowerConfig(hDevice, &pDeviceConfig->power );
03034     if (eRet)
03035     {
03036         ADI_SENSE_LOG_ERROR("Failed to set power configuration");
03037         return eRet;
03038     }
03039 
03040     eRet = adi_sense_1000_SetMeasurementConfig(hDevice, &pDeviceConfig->measurement );
03041     if (eRet)
03042     {
03043         ADI_SENSE_LOG_ERROR("Failed to set measurement configuration");
03044         return eRet;
03045     }
03046 
03047     eRet = adi_sense_1000_SetDiagnosticsConfig(hDevice, &pDeviceConfig->diagnostics );
03048     if (eRet)
03049     {
03050         ADI_SENSE_LOG_ERROR("Failed to set diagnostics configuration");
03051         return eRet;
03052     }
03053 
03054     for (ADI_SENSE_1000_CHANNEL_ID  id = ADI_SENSE_1000_CHANNEL_ID_CJC_0 ;
03055          id < ADI_SENSE_1000_MAX_CHANNELS ;
03056          id++)
03057     {
03058         eRet = adi_sense_1000_SetChannelConfig(hDevice, id,
03059                                                &pDeviceConfig->channels [id]);
03060         if (eRet)
03061         {
03062             ADI_SENSE_LOG_ERROR("Failed to set channel %d configuration", id);
03063             return eRet;
03064         }
03065     }
03066 
03067     eRet = adi_sense_1000_SetFftConfig(hDevice, &pDeviceConfig->fft ,
03068                                        pDeviceConfig->channels );
03069     if (eRet)
03070     {
03071         ADI_SENSE_LOG_ERROR("Failed to set FFT configuration");
03072         return eRet;
03073     }
03074 
03075     return ADI_SENSE_SUCCESS ;
03076 }
03077 
03078 ADI_SENSE_RESULT  adi_sense_1000_SetLutData(
03079     ADI_SENSE_DEVICE_HANDLE     const hDevice,
03080     ADI_SENSE_1000_LUT       * const pLutData)
03081 {
03082     ADI_SENSE_1000_LUT_HEADER *pLutHeader = &pLutData->header;
03083     ADI_SENSE_1000_LUT_TABLE *pLutTable = pLutData->tables;
03084     unsigned actualLength = 0;
03085 
03086     if (pLutData->header.signature != ADI_SENSE_LUT_SIGNATURE)
03087     {
03088         ADI_SENSE_LOG_ERROR("LUT signature incorrect (expected 0x%X, actual 0x%X)",
03089                             ADI_SENSE_LUT_SIGNATURE, pLutHeader->signature);
03090         return ADI_SENSE_INVALID_SIGNATURE ;
03091     }
03092 
03093     for (unsigned i = 0; i < pLutHeader->numTables; i++)
03094     {
03095         ADI_SENSE_1000_LUT_DESCRIPTOR *pDesc = &pLutTable->descriptor;
03096         ADI_SENSE_1000_LUT_TABLE_DATA  *pData = &pLutTable->data;
03097         unsigned short calculatedCrc;
03098 
03099         switch (pDesc->geometry)
03100         {
03101         case ADI_SENSE_1000_LUT_GEOMETRY_COEFFS:
03102                 switch (pDesc->equation)
03103                 {
03104                 case ADI_SENSE_1000_LUT_EQUATION_POLYN:
03105                 case ADI_SENSE_1000_LUT_EQUATION_POLYNEXP:
03106                 case ADI_SENSE_1000_LUT_EQUATION_QUADRATIC:
03107                 case ADI_SENSE_1000_LUT_EQUATION_STEINHART:
03108                 case ADI_SENSE_1000_LUT_EQUATION_LOGARITHMIC:
03109                 case ADI_SENSE_1000_LUT_EQUATION_EXPONENTIAL:
03110                 case ADI_SENSE_1000_LUT_EQUATION_BIVARIATE_POLYN:
03111                 break;
03112                 default:
03113                     ADI_SENSE_LOG_ERROR("Invalid equation %u specified for LUT table %u",
03114                                         pDesc->equation, i);
03115                     return ADI_SENSE_INVALID_PARAM ;
03116                 }
03117             break;
03118         case ADI_SENSE_1000_LUT_GEOMETRY_NES_1D:
03119         case ADI_SENSE_1000_LUT_GEOMETRY_NES_2D:
03120         case ADI_SENSE_1000_LUT_GEOMETRY_ES_1D:
03121         case ADI_SENSE_1000_LUT_GEOMETRY_ES_2D:
03122                 if (pDesc->equation != ADI_SENSE_1000_LUT_EQUATION_LUT) {
03123                     ADI_SENSE_LOG_ERROR("Invalid equation %u specified for LUT table %u",
03124                                         pDesc->equation, i);
03125                     return ADI_SENSE_INVALID_PARAM ;
03126                 }
03127             break;
03128         default:
03129             ADI_SENSE_LOG_ERROR("Invalid geometry %u specified for LUT table %u",
03130                                 pDesc->geometry, i);
03131             return ADI_SENSE_INVALID_PARAM ;
03132         }
03133 
03134         switch (pDesc->dataType)
03135         {
03136         case ADI_SENSE_1000_LUT_DATA_TYPE_FLOAT32:
03137         case ADI_SENSE_1000_LUT_DATA_TYPE_FLOAT64:
03138             break;
03139         default:
03140             ADI_SENSE_LOG_ERROR("Invalid vector format %u specified for LUT table %u",
03141                                 pDesc->dataType, i);
03142             return ADI_SENSE_INVALID_PARAM ;
03143         }
03144 
03145         calculatedCrc = adi_sense_crc16_ccitt(pData, pDesc->length);
03146         if (calculatedCrc != pDesc->crc16)
03147         {
03148             ADI_SENSE_LOG_ERROR("CRC validation failed on LUT table %u (expected 0x%04X, actual 0x%04X)",
03149                                 i, pDesc->crc16, calculatedCrc);
03150             return ADI_SENSE_CRC_ERROR ;
03151         }
03152 
03153         actualLength += sizeof(*pDesc) + pDesc->length;
03154 
03155         /* Move to the next look-up table */
03156         pLutTable = (ADI_SENSE_1000_LUT_TABLE *)((uint8_t *)pLutTable + sizeof(*pDesc) + pDesc->length);
03157     }
03158 
03159     if (actualLength != pLutHeader->totalLength)
03160     {
03161         ADI_SENSE_LOG_ERROR("LUT table length mismatch (expected %u, actual %u)",
03162                             pLutHeader->totalLength, actualLength);
03163         return ADI_SENSE_WRONG_SIZE ;
03164     }
03165 
03166     if (sizeof(*pLutHeader) + pLutHeader->totalLength > ADI_SENSE_LUT_MAX_SIZE)
03167     {
03168         ADI_SENSE_LOG_ERROR("Maximum LUT table length (%u bytes) exceeded",
03169                             ADI_SENSE_LUT_MAX_SIZE);
03170         return ADI_SENSE_WRONG_SIZE ;
03171     }
03172 
03173     /* Write the LUT data to the device */
03174     unsigned lutSize = sizeof(*pLutHeader) + pLutHeader->totalLength;
03175     WRITE_REG_U16(hDevice, 0, CORE_LUT_OFFSET);
03176     WRITE_REG_U8_ARRAY(hDevice, (uint8_t *)pLutData, lutSize, CORE_LUT_DATA);
03177 
03178     return ADI_SENSE_SUCCESS ;
03179 }
03180 
03181 ADI_SENSE_RESULT  adi_sense_1000_SetLutDataRaw(
03182     ADI_SENSE_DEVICE_HANDLE     const hDevice,
03183     ADI_SENSE_1000_LUT_RAW   * const pLutData)
03184 {
03185     return adi_sense_1000_SetLutData(hDevice,
03186                                      (ADI_SENSE_1000_LUT *)pLutData);
03187 }
03188 
03189 static ADI_SENSE_RESULT  getLutTableSize(
03190     ADI_SENSE_1000_LUT_DESCRIPTOR * const pDesc,
03191     ADI_SENSE_1000_LUT_TABLE_DATA  * const pData,
03192     unsigned *pLength)
03193 {
03194     switch (pDesc->geometry)
03195     {
03196     case ADI_SENSE_1000_LUT_GEOMETRY_COEFFS:
03197         if (pDesc->equation == ADI_SENSE_1000_LUT_EQUATION_BIVARIATE_POLYN)
03198             *pLength = ADI_SENSE_1000_LUT_2D_POLYN_COEFF_LIST_SIZE(pData->coeffList2d);
03199         else
03200             *pLength = ADI_SENSE_1000_LUT_COEFF_LIST_SIZE(pData->coeffList);
03201         break;
03202     case ADI_SENSE_1000_LUT_GEOMETRY_NES_1D:
03203         *pLength = ADI_SENSE_1000_LUT_1D_NES_SIZE(pData->lut1dNes);
03204         break;
03205     case ADI_SENSE_1000_LUT_GEOMETRY_NES_2D:
03206         *pLength = ADI_SENSE_1000_LUT_2D_NES_SIZE(pData->lut2dNes);
03207         break;
03208     case ADI_SENSE_1000_LUT_GEOMETRY_ES_1D:
03209         *pLength = ADI_SENSE_1000_LUT_1D_ES_SIZE(pData->lut1dEs);
03210         break;
03211     case ADI_SENSE_1000_LUT_GEOMETRY_ES_2D:
03212         *pLength = ADI_SENSE_1000_LUT_2D_ES_SIZE(pData->lut2dEs);
03213         break;
03214     default:
03215         ADI_SENSE_LOG_ERROR("Invalid LUT table geometry %d specified\r\n",
03216                             pDesc->geometry);
03217         return ADI_SENSE_INVALID_PARAM ;
03218     }
03219 
03220     return ADI_SENSE_SUCCESS ;
03221 }
03222 
03223 ADI_SENSE_RESULT  adi_sense_1000_AssembleLutData(
03224     ADI_SENSE_1000_LUT                  * pLutBuffer,
03225     unsigned                              nLutBufferSize,
03226     unsigned                        const nNumTables,
03227     ADI_SENSE_1000_LUT_DESCRIPTOR * const ppDesc[],
03228     ADI_SENSE_1000_LUT_TABLE_DATA  * const ppData[])
03229 {
03230     ADI_SENSE_1000_LUT_HEADER *pHdr = &pLutBuffer->header;
03231     uint8_t *pLutTableData = (uint8_t *)pLutBuffer + sizeof(*pHdr);
03232 
03233     if (sizeof(*pHdr) > nLutBufferSize)
03234     {
03235         ADI_SENSE_LOG_ERROR("Insufficient LUT buffer size provided");
03236         return ADI_SENSE_INVALID_PARAM ;
03237     }
03238 
03239     /* First initialise the top-level header */
03240     pHdr->signature = ADI_SENSE_LUT_SIGNATURE;
03241     pHdr->version.major = 1;
03242     pHdr->version.minor = 0;
03243     pHdr->numTables = 0;
03244     pHdr->totalLength = 0;
03245 
03246     /*
03247      * Walk through the list of table pointers provided, appending the table
03248      * descriptor+data from each one to the provided LUT buffer
03249      */
03250     for (unsigned i = 0; i < nNumTables; i++)
03251     {
03252         ADI_SENSE_1000_LUT_DESCRIPTOR * const pDesc = ppDesc[i];
03253         ADI_SENSE_1000_LUT_TABLE_DATA  * const pData = ppData[i];
03254         ADI_SENSE_RESULT  res;
03255         unsigned dataLength = 0;
03256 
03257         /* Calculate the length of the table data */
03258         res = getLutTableSize(pDesc, pData, &dataLength);
03259         if (res != ADI_SENSE_SUCCESS )
03260             return res;
03261 
03262         /* Fill in the table descriptor length and CRC fields */
03263         pDesc->length = dataLength;
03264         pDesc->crc16 = adi_sense_crc16_ccitt(pData, dataLength);
03265 
03266         if ((sizeof(*pHdr) + pHdr->totalLength + sizeof(*pDesc) + dataLength) > nLutBufferSize)
03267         {
03268             ADI_SENSE_LOG_ERROR("Insufficient LUT buffer size provided");
03269             return ADI_SENSE_INVALID_PARAM ;
03270         }
03271 
03272         /* Append the table to the LUT buffer (desc + data) */
03273         memcpy(pLutTableData + pHdr->totalLength, pDesc, sizeof(*pDesc));
03274         pHdr->totalLength += sizeof(*pDesc);
03275         memcpy(pLutTableData + pHdr->totalLength, pData, dataLength);
03276         pHdr->totalLength += dataLength;
03277 
03278         pHdr->numTables++;
03279     }
03280 
03281     return ADI_SENSE_SUCCESS ;
03282 }