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