ADISense1000 Version 2.1 code base

Fork of AdiSense1000_V21 by Sean Wilson

Committer:
kevin1990
Date:
Tue Dec 05 19:08:53 2017 +0000
Revision:
16:e4f2689363bb
Child:
17:fd5ab3d27b15
v1.0_RC2 Release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kevin1990 16:e4f2689363bb 1 /*!
kevin1990 16:e4f2689363bb 2 ******************************************************************************
kevin1990 16:e4f2689363bb 3 * @file: adi_sense_1000.c
kevin1990 16:e4f2689363bb 4 * @brief: ADI Sense API implementation for ADI Sense 1000
kevin1990 16:e4f2689363bb 5 *-----------------------------------------------------------------------------
kevin1990 16:e4f2689363bb 6 */
kevin1990 16:e4f2689363bb 7
kevin1990 16:e4f2689363bb 8 /******************************************************************************
kevin1990 16:e4f2689363bb 9 Copyright (c) 2017 Emutex Ltd. / Analog Devices, Inc.
kevin1990 16:e4f2689363bb 10
kevin1990 16:e4f2689363bb 11 All rights reserved.
kevin1990 16:e4f2689363bb 12
kevin1990 16:e4f2689363bb 13 Redistribution and use in source and binary forms, with or without modification,
kevin1990 16:e4f2689363bb 14 are permitted provided that the following conditions are met:
kevin1990 16:e4f2689363bb 15 - Redistributions of source code must retain the above copyright notice,
kevin1990 16:e4f2689363bb 16 this list of conditions and the following disclaimer.
kevin1990 16:e4f2689363bb 17 - Redistributions in binary form must reproduce the above copyright notice,
kevin1990 16:e4f2689363bb 18 this list of conditions and the following disclaimer in the documentation
kevin1990 16:e4f2689363bb 19 and/or other materials provided with the distribution.
kevin1990 16:e4f2689363bb 20 - Modified versions of the software must be conspicuously marked as such.
kevin1990 16:e4f2689363bb 21 - This software is licensed solely and exclusively for use with processors
kevin1990 16:e4f2689363bb 22 manufactured by or for Analog Devices, Inc.
kevin1990 16:e4f2689363bb 23 - This software may not be combined or merged with other code in any manner
kevin1990 16:e4f2689363bb 24 that would cause the software to become subject to terms and conditions
kevin1990 16:e4f2689363bb 25 which differ from those listed here.
kevin1990 16:e4f2689363bb 26 - Neither the name of Analog Devices, Inc. nor the names of its
kevin1990 16:e4f2689363bb 27 contributors may be used to endorse or promote products derived
kevin1990 16:e4f2689363bb 28 from this software without specific prior written permission.
kevin1990 16:e4f2689363bb 29 - The use of this software may or may not infringe the patent rights of one
kevin1990 16:e4f2689363bb 30 or more patent holders. This license does not release you from the
kevin1990 16:e4f2689363bb 31 requirement that you obtain separate licenses from these patent holders
kevin1990 16:e4f2689363bb 32 to use this software.
kevin1990 16:e4f2689363bb 33
kevin1990 16:e4f2689363bb 34 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. AND CONTRIBUTORS "AS IS" AND ANY
kevin1990 16:e4f2689363bb 35 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
kevin1990 16:e4f2689363bb 36 TITLE, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
kevin1990 16:e4f2689363bb 37 NO EVENT SHALL ANALOG DEVICES, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
kevin1990 16:e4f2689363bb 38 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR CONSEQUENTIAL DAMAGES
kevin1990 16:e4f2689363bb 39 (INCLUDING, BUT NOT LIMITED TO, DAMAGES ARISING OUT OF CLAIMS OF INTELLECTUAL
kevin1990 16:e4f2689363bb 40 PROPERTY RIGHTS INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
kevin1990 16:e4f2689363bb 41 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
kevin1990 16:e4f2689363bb 42 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
kevin1990 16:e4f2689363bb 43 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
kevin1990 16:e4f2689363bb 44 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
kevin1990 16:e4f2689363bb 45 *
kevin1990 16:e4f2689363bb 46 *****************************************************************************/
kevin1990 16:e4f2689363bb 47 #include <float.h>
kevin1990 16:e4f2689363bb 48 #include <math.h>
kevin1990 16:e4f2689363bb 49 #include <string.h>
kevin1990 16:e4f2689363bb 50
kevin1990 16:e4f2689363bb 51 #include "inc/adi_sense_platform.h"
kevin1990 16:e4f2689363bb 52 #include "inc/adi_sense_api.h"
kevin1990 16:e4f2689363bb 53 #include "inc/adi_sense_1000/adi_sense_1000_api.h"
kevin1990 16:e4f2689363bb 54
kevin1990 16:e4f2689363bb 55 #include "adi_sense_1000/ADISENSE1000_REGISTERS_typedefs.h"
kevin1990 16:e4f2689363bb 56 #include "adi_sense_1000/ADISENSE1000_REGISTERS.h"
kevin1990 16:e4f2689363bb 57 #include "adi_sense_1000/adi_sense_1000_lut_data.h"
kevin1990 16:e4f2689363bb 58 #include "adi_sense_1000/adi_sense_1000_calibration.h"
kevin1990 16:e4f2689363bb 59
kevin1990 16:e4f2689363bb 60 #include "crc16.h"
kevin1990 16:e4f2689363bb 61
kevin1990 16:e4f2689363bb 62 /*
kevin1990 16:e4f2689363bb 63 * The host is expected to transfer a 16-bit command, followed by data bytes, in 2
kevin1990 16:e4f2689363bb 64 * separate transfers delineated by the CS signal and a short delay in between.
kevin1990 16:e4f2689363bb 65 *
kevin1990 16:e4f2689363bb 66 * The 16-bit command contains a right-justified 11-bit register address (offset),
kevin1990 16:e4f2689363bb 67 * and the remaining upper 5 bits are reserved as command bits assigned as follows:
kevin1990 16:e4f2689363bb 68 * [15:11] 10000b = write command, 01000b = read command, anything else is invalid
kevin1990 16:e4f2689363bb 69 * [10:0] register address (0-2047)
kevin1990 16:e4f2689363bb 70 */
kevin1990 16:e4f2689363bb 71
kevin1990 16:e4f2689363bb 72 /* Register address space is limited to 2048 bytes (11 bit address) */
kevin1990 16:e4f2689363bb 73 #define REG_COMMAND_MASK 0xF800
kevin1990 16:e4f2689363bb 74 #define REG_ADDRESS_MASK 0x07FF
kevin1990 16:e4f2689363bb 75
kevin1990 16:e4f2689363bb 76 /*
kevin1990 16:e4f2689363bb 77 * The following commands are currently supported, anything else is treated
kevin1990 16:e4f2689363bb 78 * as an error
kevin1990 16:e4f2689363bb 79 */
kevin1990 16:e4f2689363bb 80 #define REG_WRITE_COMMAND 0x8000
kevin1990 16:e4f2689363bb 81 #define REG_READ_COMMAND 0x4000
kevin1990 16:e4f2689363bb 82
kevin1990 16:e4f2689363bb 83 /*
kevin1990 16:e4f2689363bb 84 * The following bytes are sent back to the host when a command is recieved,
kevin1990 16:e4f2689363bb 85 * to be used by the host to verify that we were ready to receive the command.
kevin1990 16:e4f2689363bb 86 */
kevin1990 16:e4f2689363bb 87 #define REG_COMMAND_RESP_0 0xF0
kevin1990 16:e4f2689363bb 88 #define REG_COMMAND_RESP_1 0xE1
kevin1990 16:e4f2689363bb 89
kevin1990 16:e4f2689363bb 90 /*
kevin1990 16:e4f2689363bb 91 * The following minimum delay must be inserted after each SPI transfer to allow
kevin1990 16:e4f2689363bb 92 * time for it to be processed by the device
kevin1990 16:e4f2689363bb 93 */
kevin1990 16:e4f2689363bb 94 #define POST_SPI_TRANSFER_DELAY_USEC (20)
kevin1990 16:e4f2689363bb 95
kevin1990 16:e4f2689363bb 96 /*
kevin1990 16:e4f2689363bb 97 * The following macros are used to encapsulate the register access code
kevin1990 16:e4f2689363bb 98 * to improve readability in the functions further below in this file
kevin1990 16:e4f2689363bb 99 */
kevin1990 16:e4f2689363bb 100 #define STRINGIFY(name) #name
kevin1990 16:e4f2689363bb 101
kevin1990 16:e4f2689363bb 102 /* Expand the full name of the reset value macro for the specified register */
kevin1990 16:e4f2689363bb 103 #define REG_RESET_VAL(_name) REG_ADISENSE_##_name##_RESET
kevin1990 16:e4f2689363bb 104
kevin1990 16:e4f2689363bb 105 /* Checks if a value is outside the bounds of the specified register field */
kevin1990 16:e4f2689363bb 106 #define CHECK_REG_FIELD_VAL(_field, _val) \
kevin1990 16:e4f2689363bb 107 do { \
kevin1990 16:e4f2689363bb 108 uint32_t _mask = BITM_ADISENSE_##_field; \
kevin1990 16:e4f2689363bb 109 uint32_t _shift = BITP_ADISENSE_##_field; \
kevin1990 16:e4f2689363bb 110 if ((((_val) << _shift) & ~(_mask)) != 0) { \
kevin1990 16:e4f2689363bb 111 ADI_SENSE_LOG_ERROR("Value 0x%08X invalid for register field %s", \
kevin1990 16:e4f2689363bb 112 (uint32_t)(_val), \
kevin1990 16:e4f2689363bb 113 STRINGIFY(ADISENSE_##_field)); \
kevin1990 16:e4f2689363bb 114 return ADI_SENSE_INVALID_PARAM; \
kevin1990 16:e4f2689363bb 115 } \
kevin1990 16:e4f2689363bb 116 } while(false)
kevin1990 16:e4f2689363bb 117
kevin1990 16:e4f2689363bb 118 /*
kevin1990 16:e4f2689363bb 119 * Encapsulates the write to a specified register
kevin1990 16:e4f2689363bb 120 * NOTE - this will cause the calling function to return on error
kevin1990 16:e4f2689363bb 121 */
kevin1990 16:e4f2689363bb 122 #define WRITE_REG(_hdev, _val, _name, _type) \
kevin1990 16:e4f2689363bb 123 do { \
kevin1990 16:e4f2689363bb 124 ADI_SENSE_RESULT _res; \
kevin1990 16:e4f2689363bb 125 _type _regval = _val; \
kevin1990 16:e4f2689363bb 126 _res = adi_sense_1000_WriteRegister((_hdev), \
kevin1990 16:e4f2689363bb 127 REG_ADISENSE_##_name, \
kevin1990 16:e4f2689363bb 128 &_regval, sizeof(_regval)); \
kevin1990 16:e4f2689363bb 129 if (_res != ADI_SENSE_SUCCESS) \
kevin1990 16:e4f2689363bb 130 return _res; \
kevin1990 16:e4f2689363bb 131 } while(false)
kevin1990 16:e4f2689363bb 132
kevin1990 16:e4f2689363bb 133 /* Wrapper macro to write a value to a uint32_t register */
kevin1990 16:e4f2689363bb 134 #define WRITE_REG_U32(_hdev, _val, _name) \
kevin1990 16:e4f2689363bb 135 WRITE_REG(_hdev, _val, _name, uint32_t)
kevin1990 16:e4f2689363bb 136 /* Wrapper macro to write a value to a uint16_t register */
kevin1990 16:e4f2689363bb 137 #define WRITE_REG_U16(_hdev, _val, _name) \
kevin1990 16:e4f2689363bb 138 WRITE_REG(_hdev, _val, _name, uint16_t)
kevin1990 16:e4f2689363bb 139 /* Wrapper macro to write a value to a uint8_t register */
kevin1990 16:e4f2689363bb 140 #define WRITE_REG_U8(_hdev, _val, _name) \
kevin1990 16:e4f2689363bb 141 WRITE_REG(_hdev, _val, _name, uint8_t)
kevin1990 16:e4f2689363bb 142 /* Wrapper macro to write a value to a float32_t register */
kevin1990 16:e4f2689363bb 143 #define WRITE_REG_FLOAT(_hdev, _val, _name) \
kevin1990 16:e4f2689363bb 144 WRITE_REG(_hdev, _val, _name, float32_t)
kevin1990 16:e4f2689363bb 145
kevin1990 16:e4f2689363bb 146 /*
kevin1990 16:e4f2689363bb 147 * Encapsulates the read from a specified register
kevin1990 16:e4f2689363bb 148 * NOTE - this will cause the calling function to return on error
kevin1990 16:e4f2689363bb 149 */
kevin1990 16:e4f2689363bb 150 #define READ_REG(_hdev, _val, _name, _type) \
kevin1990 16:e4f2689363bb 151 do { \
kevin1990 16:e4f2689363bb 152 ADI_SENSE_RESULT _res; \
kevin1990 16:e4f2689363bb 153 _type _regval; \
kevin1990 16:e4f2689363bb 154 _res = adi_sense_1000_ReadRegister((_hdev), \
kevin1990 16:e4f2689363bb 155 REG_ADISENSE_##_name, \
kevin1990 16:e4f2689363bb 156 &_regval, sizeof(_regval)); \
kevin1990 16:e4f2689363bb 157 if (_res != ADI_SENSE_SUCCESS) \
kevin1990 16:e4f2689363bb 158 return _res; \
kevin1990 16:e4f2689363bb 159 _val = _regval; \
kevin1990 16:e4f2689363bb 160 } while(false)
kevin1990 16:e4f2689363bb 161
kevin1990 16:e4f2689363bb 162 /* Wrapper macro to read a value from a uint32_t register */
kevin1990 16:e4f2689363bb 163 #define READ_REG_U32(_hdev, _val, _name) \
kevin1990 16:e4f2689363bb 164 READ_REG(_hdev, _val, _name, uint32_t)
kevin1990 16:e4f2689363bb 165 /* Wrapper macro to read a value from a uint16_t register */
kevin1990 16:e4f2689363bb 166 #define READ_REG_U16(_hdev, _val, _name) \
kevin1990 16:e4f2689363bb 167 READ_REG(_hdev, _val, _name, uint16_t)
kevin1990 16:e4f2689363bb 168 /* Wrapper macro to read a value from a uint8_t register */
kevin1990 16:e4f2689363bb 169 #define READ_REG_U8(_hdev, _val, _name) \
kevin1990 16:e4f2689363bb 170 READ_REG(_hdev, _val, _name, uint8_t)
kevin1990 16:e4f2689363bb 171 /* Wrapper macro to read a value from a float32_t register */
kevin1990 16:e4f2689363bb 172 #define READ_REG_FLOAT(_hdev, _val, _name) \
kevin1990 16:e4f2689363bb 173 READ_REG(_hdev, _val, _name, float32_t)
kevin1990 16:e4f2689363bb 174
kevin1990 16:e4f2689363bb 175 /*
kevin1990 16:e4f2689363bb 176 * Wrapper macro to write an array of values to a uint8_t register
kevin1990 16:e4f2689363bb 177 * NOTE - this is intended only for writing to a keyhole data register
kevin1990 16:e4f2689363bb 178 */
kevin1990 16:e4f2689363bb 179 #define WRITE_REG_U8_ARRAY(_hdev, _arr, _len, _name) \
kevin1990 16:e4f2689363bb 180 do { \
kevin1990 16:e4f2689363bb 181 ADI_SENSE_RESULT _res; \
kevin1990 16:e4f2689363bb 182 _res = adi_sense_1000_WriteRegister(_hdev, \
kevin1990 16:e4f2689363bb 183 REG_ADISENSE_##_name, \
kevin1990 16:e4f2689363bb 184 _arr, _len); \
kevin1990 16:e4f2689363bb 185 if (_res != ADI_SENSE_SUCCESS) \
kevin1990 16:e4f2689363bb 186 return _res; \
kevin1990 16:e4f2689363bb 187 } while(false)
kevin1990 16:e4f2689363bb 188
kevin1990 16:e4f2689363bb 189 /*
kevin1990 16:e4f2689363bb 190 * Wrapper macro to read an array of values from a uint8_t register
kevin1990 16:e4f2689363bb 191 * NOTE - this is intended only for reading from a keyhole data register
kevin1990 16:e4f2689363bb 192 */
kevin1990 16:e4f2689363bb 193 #define READ_REG_U8_ARRAY(_hdev, _arr, _len, _name) \
kevin1990 16:e4f2689363bb 194 do { \
kevin1990 16:e4f2689363bb 195 ADI_SENSE_RESULT _res; \
kevin1990 16:e4f2689363bb 196 _res = adi_sense_1000_ReadRegister((_hdev), \
kevin1990 16:e4f2689363bb 197 REG_ADISENSE_##_name, \
kevin1990 16:e4f2689363bb 198 _arr, _len); \
kevin1990 16:e4f2689363bb 199 if (_res != ADI_SENSE_SUCCESS) \
kevin1990 16:e4f2689363bb 200 return _res; \
kevin1990 16:e4f2689363bb 201 } while(false)
kevin1990 16:e4f2689363bb 202
kevin1990 16:e4f2689363bb 203 #define ADI_SENSE_1000_CHANNEL_IS_ADC(c) \
kevin1990 16:e4f2689363bb 204 ((c) >= ADI_SENSE_1000_CHANNEL_ID_CJC_0 && (c) <= ADI_SENSE_1000_CHANNEL_ID_CURRENT_0)
kevin1990 16:e4f2689363bb 205
kevin1990 16:e4f2689363bb 206 #define ADI_SENSE_1000_CHANNEL_IS_ADC_CJC(c) \
kevin1990 16:e4f2689363bb 207 ((c) >= ADI_SENSE_1000_CHANNEL_ID_CJC_0 && (c) <= ADI_SENSE_1000_CHANNEL_ID_CJC_1)
kevin1990 16:e4f2689363bb 208
kevin1990 16:e4f2689363bb 209 #define ADI_SENSE_1000_CHANNEL_IS_ADC_SENSOR(c) \
kevin1990 16:e4f2689363bb 210 ((c) >= ADI_SENSE_1000_CHANNEL_ID_SENSOR_0 && (c) <= ADI_SENSE_1000_CHANNEL_ID_SENSOR_3)
kevin1990 16:e4f2689363bb 211
kevin1990 16:e4f2689363bb 212 #define ADI_SENSE_1000_CHANNEL_IS_ADC_VOLTAGE(c) \
kevin1990 16:e4f2689363bb 213 ((c) == ADI_SENSE_1000_CHANNEL_ID_VOLTAGE_0)
kevin1990 16:e4f2689363bb 214
kevin1990 16:e4f2689363bb 215 #define ADI_SENSE_1000_CHANNEL_IS_ADC_CURRENT(c) \
kevin1990 16:e4f2689363bb 216 ((c) == ADI_SENSE_1000_CHANNEL_ID_CURRENT_0)
kevin1990 16:e4f2689363bb 217
kevin1990 16:e4f2689363bb 218 #define ADI_SENSE_1000_CHANNEL_IS_VIRTUAL(c) \
kevin1990 16:e4f2689363bb 219 ((c) == ADI_SENSE_1000_CHANNEL_ID_SPI_1 || (c) == ADI_SENSE_1000_CHANNEL_ID_SPI_2)
kevin1990 16:e4f2689363bb 220
kevin1990 16:e4f2689363bb 221 typedef struct
kevin1990 16:e4f2689363bb 222 {
kevin1990 16:e4f2689363bb 223 unsigned nDeviceIndex;
kevin1990 16:e4f2689363bb 224 ADI_SENSE_SPI_HANDLE hSpi;
kevin1990 16:e4f2689363bb 225 ADI_SENSE_GPIO_HANDLE hGpio;
kevin1990 16:e4f2689363bb 226 } ADI_SENSE_DEVICE_CONTEXT;
kevin1990 16:e4f2689363bb 227
kevin1990 16:e4f2689363bb 228 static ADI_SENSE_DEVICE_CONTEXT gDeviceCtx[ADI_SENSE_PLATFORM_MAX_DEVICES];
kevin1990 16:e4f2689363bb 229
kevin1990 16:e4f2689363bb 230 /*
kevin1990 16:e4f2689363bb 231 * Open an ADI Sense device instance.
kevin1990 16:e4f2689363bb 232 */
kevin1990 16:e4f2689363bb 233 ADI_SENSE_RESULT adi_sense_Open(
kevin1990 16:e4f2689363bb 234 unsigned const nDeviceIndex,
kevin1990 16:e4f2689363bb 235 ADI_SENSE_CONNECTION * const pConnectionInfo,
kevin1990 16:e4f2689363bb 236 ADI_SENSE_DEVICE_HANDLE * const phDevice)
kevin1990 16:e4f2689363bb 237 {
kevin1990 16:e4f2689363bb 238 ADI_SENSE_DEVICE_CONTEXT *pCtx;
kevin1990 16:e4f2689363bb 239 ADI_SENSE_RESULT eRet;
kevin1990 16:e4f2689363bb 240
kevin1990 16:e4f2689363bb 241 if (nDeviceIndex >= ADI_SENSE_PLATFORM_MAX_DEVICES)
kevin1990 16:e4f2689363bb 242 return ADI_SENSE_INVALID_DEVICE_NUM;
kevin1990 16:e4f2689363bb 243
kevin1990 16:e4f2689363bb 244 pCtx = &gDeviceCtx[nDeviceIndex];
kevin1990 16:e4f2689363bb 245 pCtx->nDeviceIndex = nDeviceIndex;
kevin1990 16:e4f2689363bb 246
kevin1990 16:e4f2689363bb 247 eRet = adi_sense_LogOpen();
kevin1990 16:e4f2689363bb 248 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 249 return eRet;
kevin1990 16:e4f2689363bb 250
kevin1990 16:e4f2689363bb 251 eRet = adi_sense_GpioOpen(&pConnectionInfo->gpio, &pCtx->hGpio);
kevin1990 16:e4f2689363bb 252 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 253 return eRet;
kevin1990 16:e4f2689363bb 254
kevin1990 16:e4f2689363bb 255 eRet = adi_sense_SpiOpen(&pConnectionInfo->spi, &pCtx->hSpi);
kevin1990 16:e4f2689363bb 256 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 257 return eRet;
kevin1990 16:e4f2689363bb 258
kevin1990 16:e4f2689363bb 259 *phDevice = pCtx;
kevin1990 16:e4f2689363bb 260 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 261 }
kevin1990 16:e4f2689363bb 262
kevin1990 16:e4f2689363bb 263 /*
kevin1990 16:e4f2689363bb 264 * Get the current state of the specified GPIO input signal.
kevin1990 16:e4f2689363bb 265 */
kevin1990 16:e4f2689363bb 266 ADI_SENSE_RESULT adi_sense_GetGpioState(
kevin1990 16:e4f2689363bb 267 ADI_SENSE_DEVICE_HANDLE const hDevice,
kevin1990 16:e4f2689363bb 268 ADI_SENSE_GPIO_PIN const ePinId,
kevin1990 16:e4f2689363bb 269 bool_t * const pbAsserted)
kevin1990 16:e4f2689363bb 270 {
kevin1990 16:e4f2689363bb 271 ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
kevin1990 16:e4f2689363bb 272
kevin1990 16:e4f2689363bb 273 return adi_sense_GpioGet(pCtx->hGpio, ePinId, pbAsserted);
kevin1990 16:e4f2689363bb 274 }
kevin1990 16:e4f2689363bb 275
kevin1990 16:e4f2689363bb 276 /*
kevin1990 16:e4f2689363bb 277 * Register an application-defined callback function for GPIO interrupts.
kevin1990 16:e4f2689363bb 278 */
kevin1990 16:e4f2689363bb 279 ADI_SENSE_RESULT adi_sense_RegisterGpioCallback(
kevin1990 16:e4f2689363bb 280 ADI_SENSE_DEVICE_HANDLE const hDevice,
kevin1990 16:e4f2689363bb 281 ADI_SENSE_GPIO_PIN const ePinId,
kevin1990 16:e4f2689363bb 282 ADI_SENSE_GPIO_CALLBACK const callbackFunction,
kevin1990 16:e4f2689363bb 283 void * const pCallbackParam)
kevin1990 16:e4f2689363bb 284 {
kevin1990 16:e4f2689363bb 285 ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
kevin1990 16:e4f2689363bb 286
kevin1990 16:e4f2689363bb 287 if (callbackFunction)
kevin1990 16:e4f2689363bb 288 {
kevin1990 16:e4f2689363bb 289 return adi_sense_GpioIrqEnable(pCtx->hGpio, ePinId, callbackFunction,
kevin1990 16:e4f2689363bb 290 pCallbackParam);
kevin1990 16:e4f2689363bb 291 }
kevin1990 16:e4f2689363bb 292 else
kevin1990 16:e4f2689363bb 293 {
kevin1990 16:e4f2689363bb 294 return adi_sense_GpioIrqDisable(pCtx->hGpio, ePinId);
kevin1990 16:e4f2689363bb 295 }
kevin1990 16:e4f2689363bb 296 }
kevin1990 16:e4f2689363bb 297
kevin1990 16:e4f2689363bb 298 /*
kevin1990 16:e4f2689363bb 299 * Reset the specified ADI Sense device.
kevin1990 16:e4f2689363bb 300 */
kevin1990 16:e4f2689363bb 301 ADI_SENSE_RESULT adi_sense_Reset(
kevin1990 16:e4f2689363bb 302 ADI_SENSE_DEVICE_HANDLE const hDevice)
kevin1990 16:e4f2689363bb 303 {
kevin1990 16:e4f2689363bb 304 ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
kevin1990 16:e4f2689363bb 305 ADI_SENSE_RESULT eRet;
kevin1990 16:e4f2689363bb 306
kevin1990 16:e4f2689363bb 307 /* Pulse the Reset GPIO pin low for a minimum of 4 microseconds */
kevin1990 16:e4f2689363bb 308 eRet = adi_sense_GpioSet(pCtx->hGpio, ADI_SENSE_GPIO_PIN_RESET, false);
kevin1990 16:e4f2689363bb 309 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 310 return eRet;
kevin1990 16:e4f2689363bb 311
kevin1990 16:e4f2689363bb 312 adi_sense_TimeDelayUsec(4);
kevin1990 16:e4f2689363bb 313
kevin1990 16:e4f2689363bb 314 eRet = adi_sense_GpioSet(pCtx->hGpio, ADI_SENSE_GPIO_PIN_RESET, true);
kevin1990 16:e4f2689363bb 315 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 316 return eRet;
kevin1990 16:e4f2689363bb 317
kevin1990 16:e4f2689363bb 318 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 319 }
kevin1990 16:e4f2689363bb 320
kevin1990 16:e4f2689363bb 321
kevin1990 16:e4f2689363bb 322 /*!
kevin1990 16:e4f2689363bb 323 * @brief Get general status of ADISense module.
kevin1990 16:e4f2689363bb 324 *
kevin1990 16:e4f2689363bb 325 * @param[in]
kevin1990 16:e4f2689363bb 326 * @param[out] pStatus : Pointer to CORE Status struct.
kevin1990 16:e4f2689363bb 327 *
kevin1990 16:e4f2689363bb 328 * @return Status
kevin1990 16:e4f2689363bb 329 * - #ADI_SENSE_SUCCESS Call completed successfully.
kevin1990 16:e4f2689363bb 330 * - #ADI_SENSE_FAILURE If status register read fails.
kevin1990 16:e4f2689363bb 331 *
kevin1990 16:e4f2689363bb 332 * @details Read the general status register for the ADISense
kevin1990 16:e4f2689363bb 333 * module. Indicates Error, Alert conditions, data ready
kevin1990 16:e4f2689363bb 334 * and command running.
kevin1990 16:e4f2689363bb 335 *
kevin1990 16:e4f2689363bb 336 */
kevin1990 16:e4f2689363bb 337 ADI_SENSE_RESULT adi_sense_GetStatus(
kevin1990 16:e4f2689363bb 338 ADI_SENSE_DEVICE_HANDLE const hDevice,
kevin1990 16:e4f2689363bb 339 ADI_SENSE_STATUS * const pStatus)
kevin1990 16:e4f2689363bb 340 {
kevin1990 16:e4f2689363bb 341 ADI_ADISENSE_CORE_Status_t statusReg;
kevin1990 16:e4f2689363bb 342 READ_REG_U8(hDevice, statusReg.VALUE8, CORE_STATUS);
kevin1990 16:e4f2689363bb 343
kevin1990 16:e4f2689363bb 344 memset(pStatus, 0, sizeof(*pStatus));
kevin1990 16:e4f2689363bb 345
kevin1990 16:e4f2689363bb 346 if (!statusReg.Cmd_Running) /* Active-low, so invert it */
kevin1990 16:e4f2689363bb 347 pStatus->deviceStatus |= ADI_SENSE_DEVICE_STATUS_BUSY;
kevin1990 16:e4f2689363bb 348 if (statusReg.Drdy)
kevin1990 16:e4f2689363bb 349 pStatus->deviceStatus |= ADI_SENSE_DEVICE_STATUS_DATAREADY;
kevin1990 16:e4f2689363bb 350 if (statusReg.FIFO_Error)
kevin1990 16:e4f2689363bb 351 pStatus->deviceStatus |= ADI_SENSE_DEVICE_STATUS_FIFO_ERROR;
kevin1990 16:e4f2689363bb 352 if (statusReg.Alert_Active)
kevin1990 16:e4f2689363bb 353 {
kevin1990 16:e4f2689363bb 354 pStatus->deviceStatus |= ADI_SENSE_DEVICE_STATUS_ALERT;
kevin1990 16:e4f2689363bb 355
kevin1990 16:e4f2689363bb 356 ADI_ADISENSE_CORE_Alert_Code_t alertCodeReg;
kevin1990 16:e4f2689363bb 357 READ_REG_U16(hDevice, alertCodeReg.VALUE16, CORE_ALERT_CODE);
kevin1990 16:e4f2689363bb 358 pStatus->alertCode = alertCodeReg.Alert_Code;
kevin1990 16:e4f2689363bb 359
kevin1990 16:e4f2689363bb 360 ADI_ADISENSE_CORE_Channel_Alert_Status_t channelAlertStatusReg;
kevin1990 16:e4f2689363bb 361 READ_REG_U16(hDevice, channelAlertStatusReg.VALUE16,
kevin1990 16:e4f2689363bb 362 CORE_CHANNEL_ALERT_STATUS);
kevin1990 16:e4f2689363bb 363
kevin1990 16:e4f2689363bb 364 for (unsigned i = 0; i < ADI_SENSE_1000_MAX_CHANNELS; i++)
kevin1990 16:e4f2689363bb 365 {
kevin1990 16:e4f2689363bb 366 if (channelAlertStatusReg.VALUE16 & (1 << i))
kevin1990 16:e4f2689363bb 367 {
kevin1990 16:e4f2689363bb 368 ADI_ADISENSE_CORE_Alert_Code_Ch_t channelAlertCodeReg;
kevin1990 16:e4f2689363bb 369 READ_REG_U16(hDevice, channelAlertCodeReg.VALUE16, CORE_ALERT_CODE_CHn(i));
kevin1990 16:e4f2689363bb 370 pStatus->channelAlertCodes[i] = channelAlertCodeReg.Alert_Code_Ch;
kevin1990 16:e4f2689363bb 371
kevin1990 16:e4f2689363bb 372 ADI_ADISENSE_CORE_Alert_Detail_Ch_t alertDetailReg;
kevin1990 16:e4f2689363bb 373 READ_REG_U16(hDevice, alertDetailReg.VALUE16,
kevin1990 16:e4f2689363bb 374 CORE_ALERT_DETAIL_CHn(i));
kevin1990 16:e4f2689363bb 375
kevin1990 16:e4f2689363bb 376 if (alertDetailReg.Time_Out)
kevin1990 16:e4f2689363bb 377 pStatus->channelAlerts[i] |= ADI_SENSE_CHANNEL_ALERT_TIMEOUT;
kevin1990 16:e4f2689363bb 378 if (alertDetailReg.Under_Range)
kevin1990 16:e4f2689363bb 379 pStatus->channelAlerts[i] |= ADI_SENSE_CHANNEL_ALERT_UNDER_RANGE;
kevin1990 16:e4f2689363bb 380 if (alertDetailReg.Over_Range)
kevin1990 16:e4f2689363bb 381 pStatus->channelAlerts[i] |= ADI_SENSE_CHANNEL_ALERT_OVER_RANGE;
kevin1990 16:e4f2689363bb 382 if (alertDetailReg.Low_Limit)
kevin1990 16:e4f2689363bb 383 pStatus->channelAlerts[i] |= ADI_SENSE_CHANNEL_ALERT_LOW_LIMIT;
kevin1990 16:e4f2689363bb 384 if (alertDetailReg.High_Limit)
kevin1990 16:e4f2689363bb 385 pStatus->channelAlerts[i] |= ADI_SENSE_CHANNEL_ALERT_HIGH_LIMIT;
kevin1990 16:e4f2689363bb 386 if (alertDetailReg.Sensor_Open)
kevin1990 16:e4f2689363bb 387 pStatus->channelAlerts[i] |= ADI_SENSE_CHANNEL_ALERT_SENSOR_OPEN;
kevin1990 16:e4f2689363bb 388 if (alertDetailReg.Ref_Detect)
kevin1990 16:e4f2689363bb 389 pStatus->channelAlerts[i] |= ADI_SENSE_CHANNEL_ALERT_REF_DETECT;
kevin1990 16:e4f2689363bb 390 if (alertDetailReg.Config_Err)
kevin1990 16:e4f2689363bb 391 pStatus->channelAlerts[i] |= ADI_SENSE_CHANNEL_ALERT_CONFIG_ERR;
kevin1990 16:e4f2689363bb 392 if (alertDetailReg.LUT_Error_Ch)
kevin1990 16:e4f2689363bb 393 pStatus->channelAlerts[i] |= ADI_SENSE_CHANNEL_ALERT_LUT_ERR;
kevin1990 16:e4f2689363bb 394 if (alertDetailReg.Sensor_Not_Ready)
kevin1990 16:e4f2689363bb 395 pStatus->channelAlerts[i] |= ADI_SENSE_CHANNEL_ALERT_SENSOR_NOT_READY;
kevin1990 16:e4f2689363bb 396 if (alertDetailReg.Comp_Not_Ready)
kevin1990 16:e4f2689363bb 397 pStatus->channelAlerts[i] |= ADI_SENSE_CHANNEL_ALERT_COMP_NOT_READY;
kevin1990 16:e4f2689363bb 398 if (alertDetailReg.Under_Voltage)
kevin1990 16:e4f2689363bb 399 pStatus->channelAlerts[i] |= ADI_SENSE_CHANNEL_ALERT_UNDER_VOLTAGE;
kevin1990 16:e4f2689363bb 400 if (alertDetailReg.Over_Voltage)
kevin1990 16:e4f2689363bb 401 pStatus->channelAlerts[i] |= ADI_SENSE_CHANNEL_ALERT_OVER_VOLTAGE;
kevin1990 16:e4f2689363bb 402 if (alertDetailReg.Correction_UnderRange)
kevin1990 16:e4f2689363bb 403 pStatus->channelAlerts[i] |= ADI_SENSE_CHANNEL_ALERT_LUT_UNDER_RANGE;
kevin1990 16:e4f2689363bb 404 if (alertDetailReg.Correction_OverRange)
kevin1990 16:e4f2689363bb 405 pStatus->channelAlerts[i] |= ADI_SENSE_CHANNEL_ALERT_LUT_OVER_RANGE;
kevin1990 16:e4f2689363bb 406 }
kevin1990 16:e4f2689363bb 407 }
kevin1990 16:e4f2689363bb 408
kevin1990 16:e4f2689363bb 409 ADI_ADISENSE_CORE_Alert_Status_2_t alert2Reg;
kevin1990 16:e4f2689363bb 410 READ_REG_U16(hDevice, alert2Reg.VALUE16, CORE_ALERT_STATUS_2);
kevin1990 16:e4f2689363bb 411 if (alert2Reg.Configuration_Error)
kevin1990 16:e4f2689363bb 412 pStatus->deviceStatus |= ADI_SENSE_DEVICE_STATUS_CONFIG_ERROR;
kevin1990 16:e4f2689363bb 413 if (alert2Reg.LUT_Error)
kevin1990 16:e4f2689363bb 414 pStatus->deviceStatus |= ADI_SENSE_DEVICE_STATUS_LUT_ERROR;
kevin1990 16:e4f2689363bb 415 }
kevin1990 16:e4f2689363bb 416
kevin1990 16:e4f2689363bb 417 if (statusReg.Error)
kevin1990 16:e4f2689363bb 418 {
kevin1990 16:e4f2689363bb 419 pStatus->deviceStatus |= ADI_SENSE_DEVICE_STATUS_ERROR;
kevin1990 16:e4f2689363bb 420
kevin1990 16:e4f2689363bb 421 ADI_ADISENSE_CORE_Error_Code_t errorCodeReg;
kevin1990 16:e4f2689363bb 422 READ_REG_U16(hDevice, errorCodeReg.VALUE16, CORE_ERROR_CODE);
kevin1990 16:e4f2689363bb 423 pStatus->errorCode = errorCodeReg.Error_Code;
kevin1990 16:e4f2689363bb 424
kevin1990 16:e4f2689363bb 425 ADI_ADISENSE_CORE_Diagnostics_Status_t diagStatusReg;
kevin1990 16:e4f2689363bb 426 READ_REG_U16(hDevice, diagStatusReg.VALUE16, CORE_DIAGNOSTICS_STATUS);
kevin1990 16:e4f2689363bb 427
kevin1990 16:e4f2689363bb 428 if (diagStatusReg.Diag_Checksum_Error)
kevin1990 16:e4f2689363bb 429 pStatus->diagnosticsStatus |= ADI_SENSE_DIAGNOSTICS_STATUS_CHECKSUM_ERROR;
kevin1990 16:e4f2689363bb 430 if (diagStatusReg.Diag_Comms_Error)
kevin1990 16:e4f2689363bb 431 pStatus->diagnosticsStatus |= ADI_SENSE_DIAGNOSTICS_STATUS_COMMS_ERROR;
kevin1990 16:e4f2689363bb 432 if (diagStatusReg.Diag_Supply_Monitor_Error)
kevin1990 16:e4f2689363bb 433 pStatus->diagnosticsStatus |= ADI_SENSE_DIAGNOSTICS_STATUS_SUPPLY_MONITOR_ERROR;
kevin1990 16:e4f2689363bb 434 if (diagStatusReg.Diag_Supply_Cap_Error)
kevin1990 16:e4f2689363bb 435 pStatus->diagnosticsStatus |= ADI_SENSE_DIAGNOSTICS_STATUS_SUPPLY_CAP_ERROR;
kevin1990 16:e4f2689363bb 436 if (diagStatusReg.Diag_Ainm_UV_Error)
kevin1990 16:e4f2689363bb 437 pStatus->diagnosticsStatus |= ADI_SENSE_DIAGNOSTICS_STATUS_AINM_UV_ERROR;
kevin1990 16:e4f2689363bb 438 if (diagStatusReg.Diag_Ainm_OV_Error)
kevin1990 16:e4f2689363bb 439 pStatus->diagnosticsStatus |= ADI_SENSE_DIAGNOSTICS_STATUS_AINM_OV_ERROR;
kevin1990 16:e4f2689363bb 440 if (diagStatusReg.Diag_Ainp_UV_Error)
kevin1990 16:e4f2689363bb 441 pStatus->diagnosticsStatus |= ADI_SENSE_DIAGNOSTICS_STATUS_AINP_UV_ERROR;
kevin1990 16:e4f2689363bb 442 if (diagStatusReg.Diag_Ainp_OV_Error)
kevin1990 16:e4f2689363bb 443 pStatus->diagnosticsStatus |= ADI_SENSE_DIAGNOSTICS_STATUS_AINP_OV_ERROR;
kevin1990 16:e4f2689363bb 444 if (diagStatusReg.Diag_Conversion_Error)
kevin1990 16:e4f2689363bb 445 pStatus->diagnosticsStatus |= ADI_SENSE_DIAGNOSTICS_STATUS_CONVERSION_ERROR;
kevin1990 16:e4f2689363bb 446 if (diagStatusReg.Diag_Calibration_Error)
kevin1990 16:e4f2689363bb 447 pStatus->diagnosticsStatus |= ADI_SENSE_DIAGNOSTICS_STATUS_CALIBRATION_ERROR;
kevin1990 16:e4f2689363bb 448 }
kevin1990 16:e4f2689363bb 449
kevin1990 16:e4f2689363bb 450 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 451 }
kevin1990 16:e4f2689363bb 452
kevin1990 16:e4f2689363bb 453 ADI_SENSE_RESULT adi_sense_GetCommandRunningState(
kevin1990 16:e4f2689363bb 454 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 455 bool_t *pbCommandRunning)
kevin1990 16:e4f2689363bb 456 {
kevin1990 16:e4f2689363bb 457 ADI_ADISENSE_CORE_Status_t statusReg;
kevin1990 16:e4f2689363bb 458
kevin1990 16:e4f2689363bb 459 READ_REG_U8(hDevice, statusReg.VALUE8, CORE_STATUS);
kevin1990 16:e4f2689363bb 460
kevin1990 16:e4f2689363bb 461 /* We should never normally see 0xFF here if the module is operational */
kevin1990 16:e4f2689363bb 462 if (statusReg.VALUE8 == 0xFF)
kevin1990 16:e4f2689363bb 463 return ADI_SENSE_ERR_NOT_INITIALIZED;
kevin1990 16:e4f2689363bb 464
kevin1990 16:e4f2689363bb 465 *pbCommandRunning = !statusReg.Cmd_Running; /* Active-low, so invert it */
kevin1990 16:e4f2689363bb 466
kevin1990 16:e4f2689363bb 467 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 468 }
kevin1990 16:e4f2689363bb 469
kevin1990 16:e4f2689363bb 470 static ADI_SENSE_RESULT executeCommand(
kevin1990 16:e4f2689363bb 471 ADI_SENSE_DEVICE_HANDLE const hDevice,
kevin1990 16:e4f2689363bb 472 ADI_ADISENSE_CORE_Command_Special_Command const command,
kevin1990 16:e4f2689363bb 473 bool_t const bWaitForCompletion)
kevin1990 16:e4f2689363bb 474 {
kevin1990 16:e4f2689363bb 475 ADI_ADISENSE_CORE_Command_t commandReg;
kevin1990 16:e4f2689363bb 476 bool_t bCommandRunning;
kevin1990 16:e4f2689363bb 477 ADI_SENSE_RESULT eRet;
kevin1990 16:e4f2689363bb 478
kevin1990 16:e4f2689363bb 479 /*
kevin1990 16:e4f2689363bb 480 * Don't allow another command to be issued if one is already running, but
kevin1990 16:e4f2689363bb 481 * make an exception for ADISENSE_CORE_COMMAND_NOP which can be used to
kevin1990 16:e4f2689363bb 482 * request a running command to be stopped (e.g. continuous measurement)
kevin1990 16:e4f2689363bb 483 */
kevin1990 16:e4f2689363bb 484 if (command != ADISENSE_CORE_COMMAND_NOP)
kevin1990 16:e4f2689363bb 485 {
kevin1990 16:e4f2689363bb 486 eRet = adi_sense_GetCommandRunningState(hDevice, &bCommandRunning);
kevin1990 16:e4f2689363bb 487 if (eRet)
kevin1990 16:e4f2689363bb 488 return eRet;
kevin1990 16:e4f2689363bb 489
kevin1990 16:e4f2689363bb 490 if (bCommandRunning)
kevin1990 16:e4f2689363bb 491 return ADI_SENSE_IN_USE;
kevin1990 16:e4f2689363bb 492 }
kevin1990 16:e4f2689363bb 493
kevin1990 16:e4f2689363bb 494 commandReg.Special_Command = command;
kevin1990 16:e4f2689363bb 495 WRITE_REG_U8(hDevice, commandReg.VALUE8, CORE_COMMAND);
kevin1990 16:e4f2689363bb 496
kevin1990 16:e4f2689363bb 497 if (bWaitForCompletion)
kevin1990 16:e4f2689363bb 498 {
kevin1990 16:e4f2689363bb 499 do {
kevin1990 16:e4f2689363bb 500 /* Allow a minimum 50usec delay for status update before checking */
kevin1990 16:e4f2689363bb 501 adi_sense_TimeDelayUsec(50);
kevin1990 16:e4f2689363bb 502
kevin1990 16:e4f2689363bb 503 eRet = adi_sense_GetCommandRunningState(hDevice, &bCommandRunning);
kevin1990 16:e4f2689363bb 504 if (eRet)
kevin1990 16:e4f2689363bb 505 return eRet;
kevin1990 16:e4f2689363bb 506 } while (bCommandRunning);
kevin1990 16:e4f2689363bb 507 }
kevin1990 16:e4f2689363bb 508
kevin1990 16:e4f2689363bb 509 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 510 }
kevin1990 16:e4f2689363bb 511
kevin1990 16:e4f2689363bb 512 ADI_SENSE_RESULT adi_sense_ApplyConfigUpdates(
kevin1990 16:e4f2689363bb 513 ADI_SENSE_DEVICE_HANDLE const hDevice)
kevin1990 16:e4f2689363bb 514 {
kevin1990 16:e4f2689363bb 515 return executeCommand(hDevice, ADISENSE_CORE_COMMAND_LATCH_CONFIG, true);
kevin1990 16:e4f2689363bb 516 }
kevin1990 16:e4f2689363bb 517
kevin1990 16:e4f2689363bb 518 /*!
kevin1990 16:e4f2689363bb 519 * @brief Start a measurement cycle.
kevin1990 16:e4f2689363bb 520 *
kevin1990 16:e4f2689363bb 521 * @param[out]
kevin1990 16:e4f2689363bb 522 *
kevin1990 16:e4f2689363bb 523 * @return Status
kevin1990 16:e4f2689363bb 524 * - #ADI_SENSE_SUCCESS Call completed successfully.
kevin1990 16:e4f2689363bb 525 * - #ADI_SENSE_FAILURE
kevin1990 16:e4f2689363bb 526 *
kevin1990 16:e4f2689363bb 527 * @details Sends the latch config command. Configuration for channels in
kevin1990 16:e4f2689363bb 528 * conversion cycle should be completed before this function.
kevin1990 16:e4f2689363bb 529 * Channel enabled bit should be set before this function.
kevin1990 16:e4f2689363bb 530 * Starts a conversion and configures the format of the sample.
kevin1990 16:e4f2689363bb 531 *
kevin1990 16:e4f2689363bb 532 */
kevin1990 16:e4f2689363bb 533 ADI_SENSE_RESULT adi_sense_StartMeasurement(
kevin1990 16:e4f2689363bb 534 ADI_SENSE_DEVICE_HANDLE const hDevice,
kevin1990 16:e4f2689363bb 535 ADI_SENSE_MEASUREMENT_MODE const eMeasurementMode)
kevin1990 16:e4f2689363bb 536 {
kevin1990 16:e4f2689363bb 537 switch (eMeasurementMode)
kevin1990 16:e4f2689363bb 538 {
kevin1990 16:e4f2689363bb 539 case ADI_SENSE_MEASUREMENT_MODE_HEALTHCHECK:
kevin1990 16:e4f2689363bb 540 return executeCommand(hDevice, ADISENSE_CORE_COMMAND_SYSTEM_CHECK, false);
kevin1990 16:e4f2689363bb 541 case ADI_SENSE_MEASUREMENT_MODE_NORMAL:
kevin1990 16:e4f2689363bb 542 return executeCommand(hDevice, ADISENSE_CORE_COMMAND_CONVERT_WITH_RAW, false);
kevin1990 16:e4f2689363bb 543 case ADI_SENSE_MEASUREMENT_MODE_OMIT_RAW:
kevin1990 16:e4f2689363bb 544 return executeCommand(hDevice, ADISENSE_CORE_COMMAND_CONVERT, false);
kevin1990 16:e4f2689363bb 545 default:
kevin1990 16:e4f2689363bb 546 ADI_SENSE_LOG_ERROR("Invalid measurement mode %d specified",
kevin1990 16:e4f2689363bb 547 eMeasurementMode);
kevin1990 16:e4f2689363bb 548 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 549 }
kevin1990 16:e4f2689363bb 550 }
kevin1990 16:e4f2689363bb 551
kevin1990 16:e4f2689363bb 552 /*
kevin1990 16:e4f2689363bb 553 * Store the configuration settings to persistent memory on the device.
kevin1990 16:e4f2689363bb 554 * No other command must be running when this is called.
kevin1990 16:e4f2689363bb 555 * Do not power down the device while this command is running.
kevin1990 16:e4f2689363bb 556 */
kevin1990 16:e4f2689363bb 557 ADI_SENSE_RESULT adi_sense_SaveConfig(
kevin1990 16:e4f2689363bb 558 ADI_SENSE_DEVICE_HANDLE const hDevice)
kevin1990 16:e4f2689363bb 559 {
kevin1990 16:e4f2689363bb 560 return executeCommand(hDevice, ADISENSE_CORE_COMMAND_SAVE_CONFIG, true);
kevin1990 16:e4f2689363bb 561 }
kevin1990 16:e4f2689363bb 562
kevin1990 16:e4f2689363bb 563 /*
kevin1990 16:e4f2689363bb 564 * Restore the configuration settings from persistent memory on the device.
kevin1990 16:e4f2689363bb 565 * No other command must be running when this is called.
kevin1990 16:e4f2689363bb 566 */
kevin1990 16:e4f2689363bb 567 ADI_SENSE_RESULT adi_sense_RestoreConfig(
kevin1990 16:e4f2689363bb 568 ADI_SENSE_DEVICE_HANDLE const hDevice)
kevin1990 16:e4f2689363bb 569 {
kevin1990 16:e4f2689363bb 570 return executeCommand(hDevice, ADISENSE_CORE_COMMAND_LOAD_CONFIG, true);
kevin1990 16:e4f2689363bb 571 }
kevin1990 16:e4f2689363bb 572
kevin1990 16:e4f2689363bb 573 /*
kevin1990 16:e4f2689363bb 574 * Store the LUT data to persistent memory on the device.
kevin1990 16:e4f2689363bb 575 * No other command must be running when this is called.
kevin1990 16:e4f2689363bb 576 * Do not power down the device while this command is running.
kevin1990 16:e4f2689363bb 577 */
kevin1990 16:e4f2689363bb 578 ADI_SENSE_RESULT adi_sense_SaveLutData(
kevin1990 16:e4f2689363bb 579 ADI_SENSE_DEVICE_HANDLE const hDevice)
kevin1990 16:e4f2689363bb 580 {
kevin1990 16:e4f2689363bb 581 return executeCommand(hDevice, ADISENSE_CORE_COMMAND_SAVE_LUT2, true);
kevin1990 16:e4f2689363bb 582 }
kevin1990 16:e4f2689363bb 583
kevin1990 16:e4f2689363bb 584 /*
kevin1990 16:e4f2689363bb 585 * Restore the LUT data from persistent memory on the device.
kevin1990 16:e4f2689363bb 586 * No other command must be running when this is called.
kevin1990 16:e4f2689363bb 587 */
kevin1990 16:e4f2689363bb 588 ADI_SENSE_RESULT adi_sense_RestoreLutData(
kevin1990 16:e4f2689363bb 589 ADI_SENSE_DEVICE_HANDLE const hDevice)
kevin1990 16:e4f2689363bb 590 {
kevin1990 16:e4f2689363bb 591 return executeCommand(hDevice, ADISENSE_CORE_COMMAND_LOAD_LUT, true);
kevin1990 16:e4f2689363bb 592 }
kevin1990 16:e4f2689363bb 593
kevin1990 16:e4f2689363bb 594 /*
kevin1990 16:e4f2689363bb 595 * Stop the measurement cycles on the device.
kevin1990 16:e4f2689363bb 596 * To be used only if a measurement command is currently running.
kevin1990 16:e4f2689363bb 597 */
kevin1990 16:e4f2689363bb 598 ADI_SENSE_RESULT adi_sense_StopMeasurement(
kevin1990 16:e4f2689363bb 599 ADI_SENSE_DEVICE_HANDLE const hDevice)
kevin1990 16:e4f2689363bb 600 {
kevin1990 16:e4f2689363bb 601 return executeCommand(hDevice, ADISENSE_CORE_COMMAND_NOP, true);
kevin1990 16:e4f2689363bb 602 }
kevin1990 16:e4f2689363bb 603
kevin1990 16:e4f2689363bb 604 /*
kevin1990 16:e4f2689363bb 605 * Run built-in diagnostic checks on the device.
kevin1990 16:e4f2689363bb 606 * Diagnostics are executed according to the current applied settings.
kevin1990 16:e4f2689363bb 607 * No other command must be running when this is called.
kevin1990 16:e4f2689363bb 608 */
kevin1990 16:e4f2689363bb 609 ADI_SENSE_RESULT adi_sense_RunDiagnostics(
kevin1990 16:e4f2689363bb 610 ADI_SENSE_DEVICE_HANDLE const hDevice)
kevin1990 16:e4f2689363bb 611 {
kevin1990 16:e4f2689363bb 612 return executeCommand(hDevice, ADISENSE_CORE_COMMAND_RUN_DIAGNOSTICS, true);
kevin1990 16:e4f2689363bb 613 }
kevin1990 16:e4f2689363bb 614
kevin1990 16:e4f2689363bb 615 /*
kevin1990 16:e4f2689363bb 616 * Run self-calibration routines on the device.
kevin1990 16:e4f2689363bb 617 * Calibration is executed according to the current applied settings.
kevin1990 16:e4f2689363bb 618 * No other command must be running when this is called.
kevin1990 16:e4f2689363bb 619 */
kevin1990 16:e4f2689363bb 620 ADI_SENSE_RESULT adi_sense_RunCalibration(
kevin1990 16:e4f2689363bb 621 ADI_SENSE_DEVICE_HANDLE const hDevice)
kevin1990 16:e4f2689363bb 622 {
kevin1990 16:e4f2689363bb 623 return executeCommand(hDevice, ADISENSE_CORE_COMMAND_SELF_CALIBRATION, true);
kevin1990 16:e4f2689363bb 624 }
kevin1990 16:e4f2689363bb 625
kevin1990 16:e4f2689363bb 626 /*
kevin1990 16:e4f2689363bb 627 * Read a set of data samples from the device.
kevin1990 16:e4f2689363bb 628 * This may be called at any time.
kevin1990 16:e4f2689363bb 629 */
kevin1990 16:e4f2689363bb 630 ADI_SENSE_RESULT adi_sense_GetData(
kevin1990 16:e4f2689363bb 631 ADI_SENSE_DEVICE_HANDLE const hDevice,
kevin1990 16:e4f2689363bb 632 ADI_SENSE_MEASUREMENT_MODE const eMeasurementMode,
kevin1990 16:e4f2689363bb 633 ADI_SENSE_DATA_SAMPLE * const pSamples,
kevin1990 16:e4f2689363bb 634 uint32_t const nRequested,
kevin1990 16:e4f2689363bb 635 uint32_t * const pnReturned)
kevin1990 16:e4f2689363bb 636 {
kevin1990 16:e4f2689363bb 637 ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
kevin1990 16:e4f2689363bb 638 uint16_t command = REG_READ_COMMAND |
kevin1990 16:e4f2689363bb 639 (REG_ADISENSE_CORE_DATA_FIFO & REG_ADDRESS_MASK);
kevin1990 16:e4f2689363bb 640 uint8_t commandData[2] = {
kevin1990 16:e4f2689363bb 641 command >> 8,
kevin1990 16:e4f2689363bb 642 command & 0xFF
kevin1990 16:e4f2689363bb 643 };
kevin1990 16:e4f2689363bb 644 uint8_t commandResponse[2];
kevin1990 16:e4f2689363bb 645 unsigned nValidSamples = 0;
kevin1990 16:e4f2689363bb 646 ADI_SENSE_RESULT eRet = ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 647
kevin1990 16:e4f2689363bb 648 do {
kevin1990 16:e4f2689363bb 649 eRet = adi_sense_SpiTransfer(pCtx->hSpi, commandData, commandResponse,
kevin1990 16:e4f2689363bb 650 sizeof(command), false);
kevin1990 16:e4f2689363bb 651 if (eRet)
kevin1990 16:e4f2689363bb 652 {
kevin1990 16:e4f2689363bb 653 ADI_SENSE_LOG_ERROR("Failed to send read command for FIFO register");
kevin1990 16:e4f2689363bb 654 return eRet;
kevin1990 16:e4f2689363bb 655 }
kevin1990 16:e4f2689363bb 656
kevin1990 16:e4f2689363bb 657 adi_sense_TimeDelayUsec(POST_SPI_TRANSFER_DELAY_USEC);
kevin1990 16:e4f2689363bb 658 } while ((commandResponse[0] != REG_COMMAND_RESP_0) ||
kevin1990 16:e4f2689363bb 659 (commandResponse[1] != REG_COMMAND_RESP_1));
kevin1990 16:e4f2689363bb 660
kevin1990 16:e4f2689363bb 661 for (unsigned i = 0; i < nRequested; i++)
kevin1990 16:e4f2689363bb 662 {
kevin1990 16:e4f2689363bb 663 ADI_ADISENSE_CORE_Data_FIFO_t dataFifoReg;
kevin1990 16:e4f2689363bb 664 bool_t bHoldCs = true;
kevin1990 16:e4f2689363bb 665 unsigned readSampleSize = sizeof(dataFifoReg);
kevin1990 16:e4f2689363bb 666
kevin1990 16:e4f2689363bb 667 if (eMeasurementMode == ADI_SENSE_MEASUREMENT_MODE_OMIT_RAW)
kevin1990 16:e4f2689363bb 668 readSampleSize -= 3; /* 3B raw value omitted in this case */
kevin1990 16:e4f2689363bb 669
kevin1990 16:e4f2689363bb 670 /* Keep the CS signal asserted for all but the last sample */
kevin1990 16:e4f2689363bb 671 if ((i + 1) == nRequested)
kevin1990 16:e4f2689363bb 672 bHoldCs = false;
kevin1990 16:e4f2689363bb 673
kevin1990 16:e4f2689363bb 674 eRet = adi_sense_SpiTransfer(pCtx->hSpi, NULL, &dataFifoReg,
kevin1990 16:e4f2689363bb 675 readSampleSize, bHoldCs);
kevin1990 16:e4f2689363bb 676 if (eRet)
kevin1990 16:e4f2689363bb 677 {
kevin1990 16:e4f2689363bb 678 ADI_SENSE_LOG_ERROR("Failed to read data from FIFO register");
kevin1990 16:e4f2689363bb 679 return eRet;
kevin1990 16:e4f2689363bb 680 }
kevin1990 16:e4f2689363bb 681
kevin1990 16:e4f2689363bb 682 if (! dataFifoReg.Ch_Valid)
kevin1990 16:e4f2689363bb 683 {
kevin1990 16:e4f2689363bb 684 /*
kevin1990 16:e4f2689363bb 685 * Reading an invalid sample indicates that there are no
kevin1990 16:e4f2689363bb 686 * more samples available or we've lost sync with the device.
kevin1990 16:e4f2689363bb 687 * In the latter case, it might be recoverable, but return here
kevin1990 16:e4f2689363bb 688 * to let the application check the device status and decide itself.
kevin1990 16:e4f2689363bb 689 */
kevin1990 16:e4f2689363bb 690 eRet = ADI_SENSE_INCOMPLETE;
kevin1990 16:e4f2689363bb 691 break;
kevin1990 16:e4f2689363bb 692 }
kevin1990 16:e4f2689363bb 693
kevin1990 16:e4f2689363bb 694 ADI_SENSE_DATA_SAMPLE *pSample = &pSamples[nValidSamples];
kevin1990 16:e4f2689363bb 695
kevin1990 16:e4f2689363bb 696 pSample->status = 0;
kevin1990 16:e4f2689363bb 697 if (dataFifoReg.Ch_Error)
kevin1990 16:e4f2689363bb 698 pSample->status |= ADI_SENSE_DEVICE_STATUS_ERROR;
kevin1990 16:e4f2689363bb 699 if (dataFifoReg.Ch_Alert)
kevin1990 16:e4f2689363bb 700 pSample->status |= ADI_SENSE_DEVICE_STATUS_ALERT;
kevin1990 16:e4f2689363bb 701
kevin1990 16:e4f2689363bb 702 if (dataFifoReg.Ch_Raw)
kevin1990 16:e4f2689363bb 703 pSample->rawValue = dataFifoReg.Raw_Sample;
kevin1990 16:e4f2689363bb 704 else
kevin1990 16:e4f2689363bb 705 pSample->rawValue = 0;
kevin1990 16:e4f2689363bb 706
kevin1990 16:e4f2689363bb 707 pSample->channelId = dataFifoReg.Channel_ID;
kevin1990 16:e4f2689363bb 708 pSample->processedValue = dataFifoReg.Sensor_Result;
kevin1990 16:e4f2689363bb 709
kevin1990 16:e4f2689363bb 710 nValidSamples++;
kevin1990 16:e4f2689363bb 711 }
kevin1990 16:e4f2689363bb 712 *pnReturned = nValidSamples;
kevin1990 16:e4f2689363bb 713
kevin1990 16:e4f2689363bb 714 adi_sense_TimeDelayUsec(POST_SPI_TRANSFER_DELAY_USEC);
kevin1990 16:e4f2689363bb 715
kevin1990 16:e4f2689363bb 716 return eRet;
kevin1990 16:e4f2689363bb 717 }
kevin1990 16:e4f2689363bb 718
kevin1990 16:e4f2689363bb 719 /*
kevin1990 16:e4f2689363bb 720 * Close the given ADI Sense device.
kevin1990 16:e4f2689363bb 721 */
kevin1990 16:e4f2689363bb 722 ADI_SENSE_RESULT adi_sense_Close(
kevin1990 16:e4f2689363bb 723 ADI_SENSE_DEVICE_HANDLE const hDevice)
kevin1990 16:e4f2689363bb 724 {
kevin1990 16:e4f2689363bb 725 ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
kevin1990 16:e4f2689363bb 726
kevin1990 16:e4f2689363bb 727 adi_sense_GpioClose(pCtx->hGpio);
kevin1990 16:e4f2689363bb 728 adi_sense_SpiClose(pCtx->hSpi);
kevin1990 16:e4f2689363bb 729
kevin1990 16:e4f2689363bb 730 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 731 }
kevin1990 16:e4f2689363bb 732
kevin1990 16:e4f2689363bb 733 ADI_SENSE_RESULT adi_sense_1000_WriteRegister(
kevin1990 16:e4f2689363bb 734 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 735 uint16_t nAddress,
kevin1990 16:e4f2689363bb 736 void *pData,
kevin1990 16:e4f2689363bb 737 unsigned nLength)
kevin1990 16:e4f2689363bb 738 {
kevin1990 16:e4f2689363bb 739 ADI_SENSE_RESULT eRet;
kevin1990 16:e4f2689363bb 740 ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
kevin1990 16:e4f2689363bb 741 uint16_t command = REG_WRITE_COMMAND | (nAddress & REG_ADDRESS_MASK);
kevin1990 16:e4f2689363bb 742 uint8_t commandData[2] = {
kevin1990 16:e4f2689363bb 743 command >> 8,
kevin1990 16:e4f2689363bb 744 command & 0xFF
kevin1990 16:e4f2689363bb 745 };
kevin1990 16:e4f2689363bb 746 uint8_t commandResponse[2];
kevin1990 16:e4f2689363bb 747
kevin1990 16:e4f2689363bb 748 do {
kevin1990 16:e4f2689363bb 749 eRet = adi_sense_SpiTransfer(pCtx->hSpi, commandData, commandResponse,
kevin1990 16:e4f2689363bb 750 sizeof(command), false);
kevin1990 16:e4f2689363bb 751 if (eRet)
kevin1990 16:e4f2689363bb 752 {
kevin1990 16:e4f2689363bb 753 ADI_SENSE_LOG_ERROR("Failed to send write command for register %u",
kevin1990 16:e4f2689363bb 754 nAddress);
kevin1990 16:e4f2689363bb 755 return eRet;
kevin1990 16:e4f2689363bb 756 }
kevin1990 16:e4f2689363bb 757
kevin1990 16:e4f2689363bb 758 adi_sense_TimeDelayUsec(POST_SPI_TRANSFER_DELAY_USEC);
kevin1990 16:e4f2689363bb 759 } while ((commandResponse[0] != REG_COMMAND_RESP_0) ||
kevin1990 16:e4f2689363bb 760 (commandResponse[1] != REG_COMMAND_RESP_1));
kevin1990 16:e4f2689363bb 761
kevin1990 16:e4f2689363bb 762 eRet = adi_sense_SpiTransfer(pCtx->hSpi, pData, NULL, nLength, false);
kevin1990 16:e4f2689363bb 763 if (eRet)
kevin1990 16:e4f2689363bb 764 {
kevin1990 16:e4f2689363bb 765 ADI_SENSE_LOG_ERROR("Failed to write data (%dB) to register %u",
kevin1990 16:e4f2689363bb 766 nLength, nAddress);
kevin1990 16:e4f2689363bb 767 return eRet;
kevin1990 16:e4f2689363bb 768 }
kevin1990 16:e4f2689363bb 769
kevin1990 16:e4f2689363bb 770 adi_sense_TimeDelayUsec(POST_SPI_TRANSFER_DELAY_USEC);
kevin1990 16:e4f2689363bb 771
kevin1990 16:e4f2689363bb 772 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 773 }
kevin1990 16:e4f2689363bb 774
kevin1990 16:e4f2689363bb 775 ADI_SENSE_RESULT adi_sense_1000_ReadRegister(
kevin1990 16:e4f2689363bb 776 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 777 uint16_t nAddress,
kevin1990 16:e4f2689363bb 778 void *pData,
kevin1990 16:e4f2689363bb 779 unsigned nLength)
kevin1990 16:e4f2689363bb 780 {
kevin1990 16:e4f2689363bb 781 ADI_SENSE_RESULT eRet;
kevin1990 16:e4f2689363bb 782 ADI_SENSE_DEVICE_CONTEXT *pCtx = hDevice;
kevin1990 16:e4f2689363bb 783 uint16_t command = REG_READ_COMMAND | (nAddress & REG_ADDRESS_MASK);
kevin1990 16:e4f2689363bb 784 uint8_t commandData[2] = {
kevin1990 16:e4f2689363bb 785 command >> 8,
kevin1990 16:e4f2689363bb 786 command & 0xFF
kevin1990 16:e4f2689363bb 787 };
kevin1990 16:e4f2689363bb 788 uint8_t commandResponse[2];
kevin1990 16:e4f2689363bb 789
kevin1990 16:e4f2689363bb 790 do {
kevin1990 16:e4f2689363bb 791 eRet = adi_sense_SpiTransfer(pCtx->hSpi, commandData, commandResponse,
kevin1990 16:e4f2689363bb 792 sizeof(command), false);
kevin1990 16:e4f2689363bb 793 if (eRet)
kevin1990 16:e4f2689363bb 794 {
kevin1990 16:e4f2689363bb 795 ADI_SENSE_LOG_ERROR("Failed to send read command for register %u",
kevin1990 16:e4f2689363bb 796 nAddress);
kevin1990 16:e4f2689363bb 797 return eRet;
kevin1990 16:e4f2689363bb 798 }
kevin1990 16:e4f2689363bb 799
kevin1990 16:e4f2689363bb 800 adi_sense_TimeDelayUsec(POST_SPI_TRANSFER_DELAY_USEC);
kevin1990 16:e4f2689363bb 801 } while ((commandResponse[0] != REG_COMMAND_RESP_0) ||
kevin1990 16:e4f2689363bb 802 (commandResponse[1] != REG_COMMAND_RESP_1));
kevin1990 16:e4f2689363bb 803
kevin1990 16:e4f2689363bb 804 eRet = adi_sense_SpiTransfer(pCtx->hSpi, NULL, pData, nLength, false);
kevin1990 16:e4f2689363bb 805 if (eRet)
kevin1990 16:e4f2689363bb 806 {
kevin1990 16:e4f2689363bb 807 ADI_SENSE_LOG_ERROR("Failed to read data (%uB) from register %u",
kevin1990 16:e4f2689363bb 808 nLength, nAddress);
kevin1990 16:e4f2689363bb 809 return eRet;
kevin1990 16:e4f2689363bb 810 }
kevin1990 16:e4f2689363bb 811
kevin1990 16:e4f2689363bb 812 adi_sense_TimeDelayUsec(POST_SPI_TRANSFER_DELAY_USEC);
kevin1990 16:e4f2689363bb 813
kevin1990 16:e4f2689363bb 814 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 815 }
kevin1990 16:e4f2689363bb 816
kevin1990 16:e4f2689363bb 817 ADI_SENSE_RESULT adi_sense_GetDeviceReadyState(
kevin1990 16:e4f2689363bb 818 ADI_SENSE_DEVICE_HANDLE const hDevice,
kevin1990 16:e4f2689363bb 819 bool_t * const bReady)
kevin1990 16:e4f2689363bb 820 {
kevin1990 16:e4f2689363bb 821 ADI_ADISENSE_SPI_Chip_Type_t chipTypeReg;
kevin1990 16:e4f2689363bb 822
kevin1990 16:e4f2689363bb 823 READ_REG_U8(hDevice, chipTypeReg.VALUE8, SPI_CHIP_TYPE);
kevin1990 16:e4f2689363bb 824 /* If we read this register successfully, assume the device is ready */
kevin1990 16:e4f2689363bb 825 *bReady = (chipTypeReg.VALUE8 == REG_ADISENSE_SPI_CHIP_TYPE_RESET);
kevin1990 16:e4f2689363bb 826
kevin1990 16:e4f2689363bb 827 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 828 }
kevin1990 16:e4f2689363bb 829
kevin1990 16:e4f2689363bb 830 ADI_SENSE_RESULT adi_sense_1000_GetDataReadyModeInfo(
kevin1990 16:e4f2689363bb 831 ADI_SENSE_DEVICE_HANDLE const hDevice,
kevin1990 16:e4f2689363bb 832 ADI_SENSE_MEASUREMENT_MODE const eMeasurementMode,
kevin1990 16:e4f2689363bb 833 ADI_SENSE_1000_OPERATING_MODE * const peOperatingMode,
kevin1990 16:e4f2689363bb 834 ADI_SENSE_1000_DATAREADY_MODE * const peDataReadyMode,
kevin1990 16:e4f2689363bb 835 uint32_t * const pnSamplesPerDataready,
kevin1990 16:e4f2689363bb 836 uint32_t * const pnSamplesPerCycle)
kevin1990 16:e4f2689363bb 837 {
kevin1990 16:e4f2689363bb 838 unsigned nChannelsEnabled = 0;
kevin1990 16:e4f2689363bb 839 unsigned nSamplesPerCycle = 0;
kevin1990 16:e4f2689363bb 840
kevin1990 16:e4f2689363bb 841 for (ADI_SENSE_1000_CHANNEL_ID chId = 0; chId < ADI_SENSE_1000_MAX_CHANNELS; chId++)
kevin1990 16:e4f2689363bb 842 {
kevin1990 16:e4f2689363bb 843 ADI_ADISENSE_CORE_Sensor_Details_t sensorDetailsReg;
kevin1990 16:e4f2689363bb 844 ADI_ADISENSE_CORE_Channel_Count_t channelCountReg;
kevin1990 16:e4f2689363bb 845
kevin1990 16:e4f2689363bb 846 if (ADI_SENSE_1000_CHANNEL_IS_VIRTUAL(chId))
kevin1990 16:e4f2689363bb 847 continue;
kevin1990 16:e4f2689363bb 848
kevin1990 16:e4f2689363bb 849 READ_REG_U8(hDevice, channelCountReg.VALUE8, CORE_CHANNEL_COUNTn(chId));
kevin1990 16:e4f2689363bb 850 READ_REG_U32(hDevice, sensorDetailsReg.VALUE32, CORE_SENSOR_DETAILSn(chId));
kevin1990 16:e4f2689363bb 851
kevin1990 16:e4f2689363bb 852 if (channelCountReg.Channel_Enable && !sensorDetailsReg.Do_Not_Publish)
kevin1990 16:e4f2689363bb 853 {
kevin1990 16:e4f2689363bb 854 ADI_ADISENSE_CORE_Sensor_Type_t sensorTypeReg;
kevin1990 16:e4f2689363bb 855 unsigned nActualChannels = 1;
kevin1990 16:e4f2689363bb 856
kevin1990 16:e4f2689363bb 857 READ_REG_U16(hDevice, sensorTypeReg.VALUE16, CORE_SENSOR_TYPEn(chId));
kevin1990 16:e4f2689363bb 858
kevin1990 16:e4f2689363bb 859 if (chId == ADI_SENSE_1000_CHANNEL_ID_SPI_0)
kevin1990 16:e4f2689363bb 860 {
kevin1990 16:e4f2689363bb 861 /* Some sensors automatically generate samples on additional "virtual" channels
kevin1990 16:e4f2689363bb 862 * so these channels must be counted as active when those sensors are selected
kevin1990 16:e4f2689363bb 863 * and we use the count from the corresponding "physical" channel */
kevin1990 16:e4f2689363bb 864 if (sensorTypeReg.Sensor_Type ==
kevin1990 16:e4f2689363bb 865 ADISENSE_CORE_SENSOR_TYPE_SENSOR_SPI_ACCELEROMETER_1)
kevin1990 16:e4f2689363bb 866 nActualChannels += 2;
kevin1990 16:e4f2689363bb 867 }
kevin1990 16:e4f2689363bb 868
kevin1990 16:e4f2689363bb 869 nChannelsEnabled += nActualChannels;
kevin1990 16:e4f2689363bb 870 if (eMeasurementMode == ADI_SENSE_MEASUREMENT_MODE_HEALTHCHECK)
kevin1990 16:e4f2689363bb 871 /* Assume a single sample per channel in test mode */
kevin1990 16:e4f2689363bb 872 nSamplesPerCycle += nActualChannels;
kevin1990 16:e4f2689363bb 873 else
kevin1990 16:e4f2689363bb 874 nSamplesPerCycle += nActualChannels *
kevin1990 16:e4f2689363bb 875 (channelCountReg.Channel_Count + 1);
kevin1990 16:e4f2689363bb 876 }
kevin1990 16:e4f2689363bb 877 }
kevin1990 16:e4f2689363bb 878
kevin1990 16:e4f2689363bb 879 if (nChannelsEnabled == 0)
kevin1990 16:e4f2689363bb 880 {
kevin1990 16:e4f2689363bb 881 *pnSamplesPerDataready = 0;
kevin1990 16:e4f2689363bb 882 *pnSamplesPerCycle = 0;
kevin1990 16:e4f2689363bb 883 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 884 }
kevin1990 16:e4f2689363bb 885
kevin1990 16:e4f2689363bb 886 ADI_ADISENSE_CORE_Mode_t modeReg;
kevin1990 16:e4f2689363bb 887 READ_REG_U8(hDevice, modeReg.VALUE8, CORE_MODE);
kevin1990 16:e4f2689363bb 888
kevin1990 16:e4f2689363bb 889 *pnSamplesPerCycle = nSamplesPerCycle;
kevin1990 16:e4f2689363bb 890
kevin1990 16:e4f2689363bb 891 /* Assume DRDY_PER_CONVERSION behaviour in test mode */
kevin1990 16:e4f2689363bb 892 if ((eMeasurementMode == ADI_SENSE_MEASUREMENT_MODE_HEALTHCHECK) ||
kevin1990 16:e4f2689363bb 893 (modeReg.Drdy_Mode == ADISENSE_CORE_MODE_DRDY_PER_CONVERSION))
kevin1990 16:e4f2689363bb 894 {
kevin1990 16:e4f2689363bb 895 *pnSamplesPerDataready = 1;
kevin1990 16:e4f2689363bb 896 }
kevin1990 16:e4f2689363bb 897 else if (modeReg.Drdy_Mode == ADISENSE_CORE_MODE_DRDY_PER_CYCLE)
kevin1990 16:e4f2689363bb 898 {
kevin1990 16:e4f2689363bb 899 *pnSamplesPerDataready = nSamplesPerCycle;
kevin1990 16:e4f2689363bb 900 }
kevin1990 16:e4f2689363bb 901 else
kevin1990 16:e4f2689363bb 902 {
kevin1990 16:e4f2689363bb 903 ADI_ADISENSE_CORE_Fifo_Num_Cycles_t fifoNumCyclesReg;
kevin1990 16:e4f2689363bb 904 READ_REG_U8(hDevice, fifoNumCyclesReg.VALUE8, CORE_FIFO_NUM_CYCLES);
kevin1990 16:e4f2689363bb 905
kevin1990 16:e4f2689363bb 906 *pnSamplesPerDataready =
kevin1990 16:e4f2689363bb 907 nSamplesPerCycle * fifoNumCyclesReg.Fifo_Num_Cycles;
kevin1990 16:e4f2689363bb 908 }
kevin1990 16:e4f2689363bb 909
kevin1990 16:e4f2689363bb 910 /* Assume SINGLECYCLE in test mode */
kevin1990 16:e4f2689363bb 911 if ((eMeasurementMode == ADI_SENSE_MEASUREMENT_MODE_HEALTHCHECK) ||
kevin1990 16:e4f2689363bb 912 (modeReg.Conversion_Mode == ADISENSE_CORE_MODE_SINGLECYCLE))
kevin1990 16:e4f2689363bb 913 *peOperatingMode = ADI_SENSE_1000_OPERATING_MODE_SINGLECYCLE;
kevin1990 16:e4f2689363bb 914 else if (modeReg.Conversion_Mode == ADISENSE_CORE_MODE_MULTICYCLE)
kevin1990 16:e4f2689363bb 915 *peOperatingMode = ADI_SENSE_1000_OPERATING_MODE_MULTICYCLE;
kevin1990 16:e4f2689363bb 916 else
kevin1990 16:e4f2689363bb 917 *peOperatingMode = ADI_SENSE_1000_OPERATING_MODE_CONTINUOUS;
kevin1990 16:e4f2689363bb 918
kevin1990 16:e4f2689363bb 919 /* Assume DRDY_PER_CONVERSION behaviour in test mode */
kevin1990 16:e4f2689363bb 920 if ((eMeasurementMode == ADI_SENSE_MEASUREMENT_MODE_HEALTHCHECK) ||
kevin1990 16:e4f2689363bb 921 (modeReg.Drdy_Mode == ADISENSE_CORE_MODE_DRDY_PER_CONVERSION))
kevin1990 16:e4f2689363bb 922 *peDataReadyMode = ADI_SENSE_1000_DATAREADY_PER_CONVERSION;
kevin1990 16:e4f2689363bb 923 else if (modeReg.Drdy_Mode == ADISENSE_CORE_MODE_DRDY_PER_CYCLE)
kevin1990 16:e4f2689363bb 924 *peDataReadyMode = ADI_SENSE_1000_DATAREADY_PER_CYCLE;
kevin1990 16:e4f2689363bb 925 else
kevin1990 16:e4f2689363bb 926 *peDataReadyMode = ADI_SENSE_1000_DATAREADY_PER_MULTICYCLE_BURST;
kevin1990 16:e4f2689363bb 927
kevin1990 16:e4f2689363bb 928 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 929 }
kevin1990 16:e4f2689363bb 930
kevin1990 16:e4f2689363bb 931 ADI_SENSE_RESULT adi_sense_GetProductID(
kevin1990 16:e4f2689363bb 932 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 933 ADI_SENSE_PRODUCT_ID *pProductId)
kevin1990 16:e4f2689363bb 934 {
kevin1990 16:e4f2689363bb 935 ADI_ADISENSE_SPI_Product_ID_L_t productIdLoReg;
kevin1990 16:e4f2689363bb 936 ADI_ADISENSE_SPI_Product_ID_H_t productIdHiReg;
kevin1990 16:e4f2689363bb 937
kevin1990 16:e4f2689363bb 938 READ_REG_U8(hDevice, productIdLoReg.VALUE8, SPI_PRODUCT_ID_L);
kevin1990 16:e4f2689363bb 939 READ_REG_U8(hDevice, productIdHiReg.VALUE8, SPI_PRODUCT_ID_H);
kevin1990 16:e4f2689363bb 940
kevin1990 16:e4f2689363bb 941 *pProductId = (productIdHiReg.VALUE8 << 8) | productIdLoReg.VALUE8;
kevin1990 16:e4f2689363bb 942 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 943 }
kevin1990 16:e4f2689363bb 944
kevin1990 16:e4f2689363bb 945 static ADI_SENSE_RESULT adi_sense_SetPowerMode(
kevin1990 16:e4f2689363bb 946 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 947 ADI_SENSE_1000_POWER_MODE powerMode)
kevin1990 16:e4f2689363bb 948 {
kevin1990 16:e4f2689363bb 949 ADI_ADISENSE_CORE_Power_Config_t powerConfigReg;
kevin1990 16:e4f2689363bb 950
kevin1990 16:e4f2689363bb 951 if (powerMode == ADI_SENSE_1000_POWER_MODE_LOW)
kevin1990 16:e4f2689363bb 952 {
kevin1990 16:e4f2689363bb 953 powerConfigReg.Power_Mode_ADC = ADISENSE_CORE_POWER_CONFIG_ADC_LOW_POWER;
kevin1990 16:e4f2689363bb 954 /* TODO - we need an enum in the register map for the MCU power modes */
kevin1990 16:e4f2689363bb 955 powerConfigReg.Power_Mode_MCU = 0x0;
kevin1990 16:e4f2689363bb 956 }
kevin1990 16:e4f2689363bb 957 else if (powerMode == ADI_SENSE_1000_POWER_MODE_MID)
kevin1990 16:e4f2689363bb 958 {
kevin1990 16:e4f2689363bb 959 powerConfigReg.Power_Mode_ADC = ADISENSE_CORE_POWER_CONFIG_ADC_MID_POWER;
kevin1990 16:e4f2689363bb 960 powerConfigReg.Power_Mode_MCU = 0x1;
kevin1990 16:e4f2689363bb 961 }
kevin1990 16:e4f2689363bb 962 else if (powerMode == ADI_SENSE_1000_POWER_MODE_FULL)
kevin1990 16:e4f2689363bb 963 {
kevin1990 16:e4f2689363bb 964 powerConfigReg.Power_Mode_ADC = ADISENSE_CORE_POWER_CONFIG_ADC_FULL_POWER;
kevin1990 16:e4f2689363bb 965 powerConfigReg.Power_Mode_MCU = 0x2;
kevin1990 16:e4f2689363bb 966 }
kevin1990 16:e4f2689363bb 967 else
kevin1990 16:e4f2689363bb 968 {
kevin1990 16:e4f2689363bb 969 ADI_SENSE_LOG_ERROR("Invalid power mode %d specified", powerMode);
kevin1990 16:e4f2689363bb 970 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 971 }
kevin1990 16:e4f2689363bb 972
kevin1990 16:e4f2689363bb 973 WRITE_REG_U8(hDevice, powerConfigReg.VALUE8, CORE_POWER_CONFIG);
kevin1990 16:e4f2689363bb 974
kevin1990 16:e4f2689363bb 975 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 976 }
kevin1990 16:e4f2689363bb 977
kevin1990 16:e4f2689363bb 978 static ADI_SENSE_RESULT adi_sense_SetVddVoltage(
kevin1990 16:e4f2689363bb 979 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 980 float32_t vddVoltage)
kevin1990 16:e4f2689363bb 981 {
kevin1990 16:e4f2689363bb 982 WRITE_REG_FLOAT(hDevice, vddVoltage, CORE_AVDD_VOLTAGE);
kevin1990 16:e4f2689363bb 983
kevin1990 16:e4f2689363bb 984 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 985 }
kevin1990 16:e4f2689363bb 986
kevin1990 16:e4f2689363bb 987 ADI_SENSE_RESULT adi_sense_1000_SetPowerConfig(
kevin1990 16:e4f2689363bb 988 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 989 ADI_SENSE_1000_POWER_CONFIG *pPowerConfig)
kevin1990 16:e4f2689363bb 990 {
kevin1990 16:e4f2689363bb 991 ADI_SENSE_RESULT eRet;
kevin1990 16:e4f2689363bb 992
kevin1990 16:e4f2689363bb 993 eRet = adi_sense_SetPowerMode(hDevice, pPowerConfig->powerMode);
kevin1990 16:e4f2689363bb 994 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 995 {
kevin1990 16:e4f2689363bb 996 ADI_SENSE_LOG_ERROR("Failed to set power mode");
kevin1990 16:e4f2689363bb 997 return eRet;
kevin1990 16:e4f2689363bb 998 }
kevin1990 16:e4f2689363bb 999
kevin1990 16:e4f2689363bb 1000 eRet = adi_sense_SetVddVoltage(hDevice, pPowerConfig->supplyVoltage);
kevin1990 16:e4f2689363bb 1001 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 1002 {
kevin1990 16:e4f2689363bb 1003 ADI_SENSE_LOG_ERROR("Failed to set AVdd voltage");
kevin1990 16:e4f2689363bb 1004 return eRet;
kevin1990 16:e4f2689363bb 1005 }
kevin1990 16:e4f2689363bb 1006
kevin1990 16:e4f2689363bb 1007 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1008 }
kevin1990 16:e4f2689363bb 1009
kevin1990 16:e4f2689363bb 1010 static ADI_SENSE_RESULT adi_sense_SetMode(
kevin1990 16:e4f2689363bb 1011 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1012 ADI_SENSE_1000_OPERATING_MODE eOperatingMode,
kevin1990 16:e4f2689363bb 1013 ADI_SENSE_1000_DATAREADY_MODE eDataReadyMode)
kevin1990 16:e4f2689363bb 1014 {
kevin1990 16:e4f2689363bb 1015 ADI_ADISENSE_CORE_Mode_t modeReg;
kevin1990 16:e4f2689363bb 1016
kevin1990 16:e4f2689363bb 1017 modeReg.VALUE8 = REG_RESET_VAL(CORE_MODE);
kevin1990 16:e4f2689363bb 1018
kevin1990 16:e4f2689363bb 1019 if (eOperatingMode == ADI_SENSE_1000_OPERATING_MODE_SINGLECYCLE)
kevin1990 16:e4f2689363bb 1020 {
kevin1990 16:e4f2689363bb 1021 modeReg.Conversion_Mode = ADISENSE_CORE_MODE_SINGLECYCLE;
kevin1990 16:e4f2689363bb 1022 }
kevin1990 16:e4f2689363bb 1023 else if (eOperatingMode == ADI_SENSE_1000_OPERATING_MODE_CONTINUOUS)
kevin1990 16:e4f2689363bb 1024 {
kevin1990 16:e4f2689363bb 1025 modeReg.Conversion_Mode = ADISENSE_CORE_MODE_CONTINUOUS;
kevin1990 16:e4f2689363bb 1026 }
kevin1990 16:e4f2689363bb 1027 else if (eOperatingMode == ADI_SENSE_1000_OPERATING_MODE_MULTICYCLE)
kevin1990 16:e4f2689363bb 1028 {
kevin1990 16:e4f2689363bb 1029 modeReg.Conversion_Mode = ADISENSE_CORE_MODE_MULTICYCLE;
kevin1990 16:e4f2689363bb 1030 }
kevin1990 16:e4f2689363bb 1031 else
kevin1990 16:e4f2689363bb 1032 {
kevin1990 16:e4f2689363bb 1033 ADI_SENSE_LOG_ERROR("Invalid operating mode %d specified",
kevin1990 16:e4f2689363bb 1034 eOperatingMode);
kevin1990 16:e4f2689363bb 1035 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 1036 }
kevin1990 16:e4f2689363bb 1037
kevin1990 16:e4f2689363bb 1038 if (eDataReadyMode == ADI_SENSE_1000_DATAREADY_PER_CONVERSION)
kevin1990 16:e4f2689363bb 1039 {
kevin1990 16:e4f2689363bb 1040 modeReg.Drdy_Mode = ADISENSE_CORE_MODE_DRDY_PER_CONVERSION;
kevin1990 16:e4f2689363bb 1041 }
kevin1990 16:e4f2689363bb 1042 else if (eDataReadyMode == ADI_SENSE_1000_DATAREADY_PER_CYCLE)
kevin1990 16:e4f2689363bb 1043 {
kevin1990 16:e4f2689363bb 1044 modeReg.Drdy_Mode = ADISENSE_CORE_MODE_DRDY_PER_CYCLE;
kevin1990 16:e4f2689363bb 1045 }
kevin1990 16:e4f2689363bb 1046 else if (eDataReadyMode == ADI_SENSE_1000_DATAREADY_PER_MULTICYCLE_BURST)
kevin1990 16:e4f2689363bb 1047 {
kevin1990 16:e4f2689363bb 1048 if (eOperatingMode != ADI_SENSE_1000_OPERATING_MODE_MULTICYCLE)
kevin1990 16:e4f2689363bb 1049 {
kevin1990 16:e4f2689363bb 1050 ADI_SENSE_LOG_ERROR(
kevin1990 16:e4f2689363bb 1051 "Data-ready mode %d cannot be used with operating mode %d",
kevin1990 16:e4f2689363bb 1052 eDataReadyMode, eOperatingMode);
kevin1990 16:e4f2689363bb 1053 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 1054 }
kevin1990 16:e4f2689363bb 1055 else
kevin1990 16:e4f2689363bb 1056 {
kevin1990 16:e4f2689363bb 1057 modeReg.Drdy_Mode = ADISENSE_CORE_MODE_DRDY_PER_FIFO_FILL;
kevin1990 16:e4f2689363bb 1058 }
kevin1990 16:e4f2689363bb 1059 }
kevin1990 16:e4f2689363bb 1060 else
kevin1990 16:e4f2689363bb 1061 {
kevin1990 16:e4f2689363bb 1062 ADI_SENSE_LOG_ERROR("Invalid data-ready mode %d specified", eDataReadyMode);
kevin1990 16:e4f2689363bb 1063 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 1064 }
kevin1990 16:e4f2689363bb 1065
kevin1990 16:e4f2689363bb 1066 WRITE_REG_U8(hDevice, modeReg.VALUE8, CORE_MODE);
kevin1990 16:e4f2689363bb 1067
kevin1990 16:e4f2689363bb 1068 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1069 }
kevin1990 16:e4f2689363bb 1070
kevin1990 16:e4f2689363bb 1071 ADI_SENSE_RESULT adi_sense_SetCycleInterval(
kevin1990 16:e4f2689363bb 1072 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1073 uint32_t nCycleInterval)
kevin1990 16:e4f2689363bb 1074 {
kevin1990 16:e4f2689363bb 1075 ADI_ADISENSE_CORE_Cycle_Control_t cycleControlReg;
kevin1990 16:e4f2689363bb 1076
kevin1990 16:e4f2689363bb 1077 cycleControlReg.VALUE16 = REG_RESET_VAL(CORE_CYCLE_CONTROL);
kevin1990 16:e4f2689363bb 1078
kevin1990 16:e4f2689363bb 1079 if (nCycleInterval < (1 << 12))
kevin1990 16:e4f2689363bb 1080 {
kevin1990 16:e4f2689363bb 1081 cycleControlReg.Cycle_Time_Units = ADISENSE_CORE_CYCLE_CONTROL_MICROSECONDS;
kevin1990 16:e4f2689363bb 1082 }
kevin1990 16:e4f2689363bb 1083 else if (nCycleInterval < (1000 * (1 << 12)))
kevin1990 16:e4f2689363bb 1084 {
kevin1990 16:e4f2689363bb 1085 cycleControlReg.Cycle_Time_Units = ADISENSE_CORE_CYCLE_CONTROL_MILLISECONDS;
kevin1990 16:e4f2689363bb 1086 nCycleInterval /= 1000;
kevin1990 16:e4f2689363bb 1087 }
kevin1990 16:e4f2689363bb 1088 else
kevin1990 16:e4f2689363bb 1089 {
kevin1990 16:e4f2689363bb 1090 cycleControlReg.Cycle_Time_Units = ADISENSE_CORE_CYCLE_CONTROL_SECONDS;
kevin1990 16:e4f2689363bb 1091 nCycleInterval /= 1000000;
kevin1990 16:e4f2689363bb 1092 }
kevin1990 16:e4f2689363bb 1093
kevin1990 16:e4f2689363bb 1094 CHECK_REG_FIELD_VAL(CORE_CYCLE_CONTROL_CYCLE_TIME, nCycleInterval);
kevin1990 16:e4f2689363bb 1095 cycleControlReg.Cycle_Time = nCycleInterval;
kevin1990 16:e4f2689363bb 1096
kevin1990 16:e4f2689363bb 1097 WRITE_REG_U16(hDevice, cycleControlReg.VALUE16, CORE_CYCLE_CONTROL);
kevin1990 16:e4f2689363bb 1098
kevin1990 16:e4f2689363bb 1099 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1100 }
kevin1990 16:e4f2689363bb 1101
kevin1990 16:e4f2689363bb 1102 static ADI_SENSE_RESULT adi_sense_SetMultiCycleConfig(
kevin1990 16:e4f2689363bb 1103 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1104 ADI_SENSE_1000_MULTICYCLE_CONFIG *pMultiCycleConfig)
kevin1990 16:e4f2689363bb 1105 {
kevin1990 16:e4f2689363bb 1106 CHECK_REG_FIELD_VAL(CORE_FIFO_NUM_CYCLES_FIFO_NUM_CYCLES,
kevin1990 16:e4f2689363bb 1107 pMultiCycleConfig->cyclesPerBurst);
kevin1990 16:e4f2689363bb 1108
kevin1990 16:e4f2689363bb 1109 WRITE_REG_U8(hDevice, pMultiCycleConfig->cyclesPerBurst,
kevin1990 16:e4f2689363bb 1110 CORE_FIFO_NUM_CYCLES);
kevin1990 16:e4f2689363bb 1111
kevin1990 16:e4f2689363bb 1112 WRITE_REG_U32(hDevice, pMultiCycleConfig->burstInterval,
kevin1990 16:e4f2689363bb 1113 CORE_MULTI_CYCLE_REPEAT_INTERVAL);
kevin1990 16:e4f2689363bb 1114
kevin1990 16:e4f2689363bb 1115 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1116 }
kevin1990 16:e4f2689363bb 1117
kevin1990 16:e4f2689363bb 1118 static ADI_SENSE_RESULT adi_sense_SetExternalReferenceValues(
kevin1990 16:e4f2689363bb 1119 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1120 float32_t externalRef1Value,
kevin1990 16:e4f2689363bb 1121 float32_t externalRef2Value)
kevin1990 16:e4f2689363bb 1122 {
kevin1990 16:e4f2689363bb 1123 WRITE_REG_FLOAT(hDevice, externalRef1Value, CORE_EXTERNAL_REFERENCE1);
kevin1990 16:e4f2689363bb 1124 WRITE_REG_FLOAT(hDevice, externalRef2Value, CORE_EXTERNAL_REFERENCE2);
kevin1990 16:e4f2689363bb 1125
kevin1990 16:e4f2689363bb 1126 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1127 }
kevin1990 16:e4f2689363bb 1128
kevin1990 16:e4f2689363bb 1129 ADI_SENSE_RESULT adi_sense_1000_SetMeasurementConfig(
kevin1990 16:e4f2689363bb 1130 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1131 ADI_SENSE_1000_MEASUREMENT_CONFIG *pMeasConfig)
kevin1990 16:e4f2689363bb 1132 {
kevin1990 16:e4f2689363bb 1133 ADI_SENSE_RESULT eRet;
kevin1990 16:e4f2689363bb 1134
kevin1990 16:e4f2689363bb 1135 eRet = adi_sense_SetMode(hDevice,
kevin1990 16:e4f2689363bb 1136 pMeasConfig->operatingMode,
kevin1990 16:e4f2689363bb 1137 pMeasConfig->dataReadyMode);
kevin1990 16:e4f2689363bb 1138 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 1139 {
kevin1990 16:e4f2689363bb 1140 ADI_SENSE_LOG_ERROR("Failed to set operating mode");
kevin1990 16:e4f2689363bb 1141 return eRet;
kevin1990 16:e4f2689363bb 1142 }
kevin1990 16:e4f2689363bb 1143
kevin1990 16:e4f2689363bb 1144 if (pMeasConfig->operatingMode != ADI_SENSE_1000_OPERATING_MODE_SINGLECYCLE)
kevin1990 16:e4f2689363bb 1145 {
kevin1990 16:e4f2689363bb 1146 eRet = adi_sense_SetCycleInterval(hDevice, pMeasConfig->cycleInterval);
kevin1990 16:e4f2689363bb 1147 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 1148 {
kevin1990 16:e4f2689363bb 1149 ADI_SENSE_LOG_ERROR("Failed to set cycle interval");
kevin1990 16:e4f2689363bb 1150 return eRet;
kevin1990 16:e4f2689363bb 1151 }
kevin1990 16:e4f2689363bb 1152 }
kevin1990 16:e4f2689363bb 1153
kevin1990 16:e4f2689363bb 1154 if (pMeasConfig->operatingMode == ADI_SENSE_1000_OPERATING_MODE_MULTICYCLE)
kevin1990 16:e4f2689363bb 1155 {
kevin1990 16:e4f2689363bb 1156 eRet = adi_sense_SetMultiCycleConfig(hDevice,
kevin1990 16:e4f2689363bb 1157 &pMeasConfig->multiCycleConfig);
kevin1990 16:e4f2689363bb 1158 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 1159 {
kevin1990 16:e4f2689363bb 1160 ADI_SENSE_LOG_ERROR("Failed to set multi-cycle configuration");
kevin1990 16:e4f2689363bb 1161 return eRet;
kevin1990 16:e4f2689363bb 1162 }
kevin1990 16:e4f2689363bb 1163 }
kevin1990 16:e4f2689363bb 1164
kevin1990 16:e4f2689363bb 1165 eRet = adi_sense_SetExternalReferenceValues(hDevice,
kevin1990 16:e4f2689363bb 1166 pMeasConfig->externalRef1Value,
kevin1990 16:e4f2689363bb 1167 pMeasConfig->externalRef2Value);
kevin1990 16:e4f2689363bb 1168 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 1169 {
kevin1990 16:e4f2689363bb 1170 ADI_SENSE_LOG_ERROR("Failed to set external reference values");
kevin1990 16:e4f2689363bb 1171 return eRet;
kevin1990 16:e4f2689363bb 1172 }
kevin1990 16:e4f2689363bb 1173
kevin1990 16:e4f2689363bb 1174 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1175 }
kevin1990 16:e4f2689363bb 1176
kevin1990 16:e4f2689363bb 1177 ADI_SENSE_RESULT adi_sense_1000_SetDiagnosticsConfig(
kevin1990 16:e4f2689363bb 1178 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1179 ADI_SENSE_1000_DIAGNOSTICS_CONFIG *pDiagnosticsConfig)
kevin1990 16:e4f2689363bb 1180 {
kevin1990 16:e4f2689363bb 1181 ADI_ADISENSE_CORE_Diagnostics_Control_t diagnosticsControlReg;
kevin1990 16:e4f2689363bb 1182
kevin1990 16:e4f2689363bb 1183 diagnosticsControlReg.VALUE16 = REG_RESET_VAL(CORE_DIAGNOSTICS_CONTROL);
kevin1990 16:e4f2689363bb 1184
kevin1990 16:e4f2689363bb 1185 if (pDiagnosticsConfig->disableGlobalDiag)
kevin1990 16:e4f2689363bb 1186 diagnosticsControlReg.Diag_Global_En = 0;
kevin1990 16:e4f2689363bb 1187 else
kevin1990 16:e4f2689363bb 1188 diagnosticsControlReg.Diag_Global_En = 1;
kevin1990 16:e4f2689363bb 1189
kevin1990 16:e4f2689363bb 1190 if (pDiagnosticsConfig->disableMeasurementDiag)
kevin1990 16:e4f2689363bb 1191 diagnosticsControlReg.Diag_Meas_En = 0;
kevin1990 16:e4f2689363bb 1192 else
kevin1990 16:e4f2689363bb 1193 diagnosticsControlReg.Diag_Meas_En = 1;
kevin1990 16:e4f2689363bb 1194
kevin1990 16:e4f2689363bb 1195 switch (pDiagnosticsConfig->osdFrequency)
kevin1990 16:e4f2689363bb 1196 {
kevin1990 16:e4f2689363bb 1197 case ADI_SENSE_1000_OPEN_SENSOR_DIAGNOSTICS_DISABLED:
kevin1990 16:e4f2689363bb 1198 diagnosticsControlReg.Diag_OSD_Freq = ADISENSE_CORE_DIAGNOSTICS_CONTROL_OCD_OFF;
kevin1990 16:e4f2689363bb 1199 break;
kevin1990 16:e4f2689363bb 1200 case ADI_SENSE_1000_OPEN_SENSOR_DIAGNOSTICS_PER_CYCLE:
kevin1990 16:e4f2689363bb 1201 diagnosticsControlReg.Diag_OSD_Freq = ADISENSE_CORE_DIAGNOSTICS_CONTROL_OCD_PER_1_CYCLE;
kevin1990 16:e4f2689363bb 1202 break;
kevin1990 16:e4f2689363bb 1203 case ADI_SENSE_1000_OPEN_SENSOR_DIAGNOSTICS_PER_100_CYCLES:
kevin1990 16:e4f2689363bb 1204 diagnosticsControlReg.Diag_OSD_Freq = ADISENSE_CORE_DIAGNOSTICS_CONTROL_OCD_PER_100_CYCLES;
kevin1990 16:e4f2689363bb 1205 break;
kevin1990 16:e4f2689363bb 1206 case ADI_SENSE_1000_OPEN_SENSOR_DIAGNOSTICS_PER_1000_CYCLES:
kevin1990 16:e4f2689363bb 1207 diagnosticsControlReg.Diag_OSD_Freq = ADISENSE_CORE_DIAGNOSTICS_CONTROL_OCD_PER_1000_CYCLES;
kevin1990 16:e4f2689363bb 1208 break;
kevin1990 16:e4f2689363bb 1209 default:
kevin1990 16:e4f2689363bb 1210 ADI_SENSE_LOG_ERROR("Invalid open-sensor diagnostic frequency %d specified",
kevin1990 16:e4f2689363bb 1211 pDiagnosticsConfig->osdFrequency);
kevin1990 16:e4f2689363bb 1212 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 1213 }
kevin1990 16:e4f2689363bb 1214
kevin1990 16:e4f2689363bb 1215 WRITE_REG_U16(hDevice, diagnosticsControlReg.VALUE16, CORE_DIAGNOSTICS_CONTROL);
kevin1990 16:e4f2689363bb 1216
kevin1990 16:e4f2689363bb 1217 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1218 }
kevin1990 16:e4f2689363bb 1219
kevin1990 16:e4f2689363bb 1220 ADI_SENSE_RESULT adi_sense_1000_SetChannelCount(
kevin1990 16:e4f2689363bb 1221 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1222 ADI_SENSE_1000_CHANNEL_ID eChannelId,
kevin1990 16:e4f2689363bb 1223 uint32_t nMeasurementsPerCycle)
kevin1990 16:e4f2689363bb 1224 {
kevin1990 16:e4f2689363bb 1225 ADI_ADISENSE_CORE_Channel_Count_t channelCountReg;
kevin1990 16:e4f2689363bb 1226
kevin1990 16:e4f2689363bb 1227 channelCountReg.VALUE8 = REG_RESET_VAL(CORE_CHANNEL_COUNTn);
kevin1990 16:e4f2689363bb 1228
kevin1990 16:e4f2689363bb 1229 if (nMeasurementsPerCycle > 0)
kevin1990 16:e4f2689363bb 1230 {
kevin1990 16:e4f2689363bb 1231 nMeasurementsPerCycle -= 1;
kevin1990 16:e4f2689363bb 1232
kevin1990 16:e4f2689363bb 1233 CHECK_REG_FIELD_VAL(CORE_CHANNEL_COUNT_CHANNEL_COUNT,
kevin1990 16:e4f2689363bb 1234 nMeasurementsPerCycle);
kevin1990 16:e4f2689363bb 1235
kevin1990 16:e4f2689363bb 1236 channelCountReg.Channel_Enable = 1;
kevin1990 16:e4f2689363bb 1237 channelCountReg.Channel_Count = nMeasurementsPerCycle;
kevin1990 16:e4f2689363bb 1238 }
kevin1990 16:e4f2689363bb 1239 else
kevin1990 16:e4f2689363bb 1240 {
kevin1990 16:e4f2689363bb 1241 channelCountReg.Channel_Enable = 0;
kevin1990 16:e4f2689363bb 1242 }
kevin1990 16:e4f2689363bb 1243
kevin1990 16:e4f2689363bb 1244 WRITE_REG_U8(hDevice, channelCountReg.VALUE8, CORE_CHANNEL_COUNTn(eChannelId));
kevin1990 16:e4f2689363bb 1245
kevin1990 16:e4f2689363bb 1246 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1247 }
kevin1990 16:e4f2689363bb 1248
kevin1990 16:e4f2689363bb 1249 static ADI_SENSE_RESULT adi_sense_SetChannelAdcSensorType(
kevin1990 16:e4f2689363bb 1250 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1251 ADI_SENSE_1000_CHANNEL_ID eChannelId,
kevin1990 16:e4f2689363bb 1252 ADI_SENSE_1000_ADC_SENSOR_TYPE sensorType)
kevin1990 16:e4f2689363bb 1253 {
kevin1990 16:e4f2689363bb 1254 ADI_ADISENSE_CORE_Sensor_Type_t sensorTypeReg;
kevin1990 16:e4f2689363bb 1255
kevin1990 16:e4f2689363bb 1256 sensorTypeReg.VALUE16 = REG_RESET_VAL(CORE_SENSOR_TYPEn);
kevin1990 16:e4f2689363bb 1257
kevin1990 16:e4f2689363bb 1258 /* Ensure that the sensor type is valid for this channel */
kevin1990 16:e4f2689363bb 1259 switch(sensorType)
kevin1990 16:e4f2689363bb 1260 {
kevin1990 16:e4f2689363bb 1261 case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_J_DEF_L1:
kevin1990 16:e4f2689363bb 1262 case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_K_DEF_L1:
kevin1990 16:e4f2689363bb 1263 case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_T_DEF_L1:
kevin1990 16:e4f2689363bb 1264 case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_1_DEF_L2:
kevin1990 16:e4f2689363bb 1265 case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_2_DEF_L2:
kevin1990 16:e4f2689363bb 1266 case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_3_DEF_L2:
kevin1990 16:e4f2689363bb 1267 case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_4_DEF_L2:
kevin1990 16:e4f2689363bb 1268 case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_J_ADV_L1:
kevin1990 16:e4f2689363bb 1269 case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_K_ADV_L1:
kevin1990 16:e4f2689363bb 1270 case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_T_ADV_L1:
kevin1990 16:e4f2689363bb 1271 case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_1_ADV_L2:
kevin1990 16:e4f2689363bb 1272 case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_2_ADV_L2:
kevin1990 16:e4f2689363bb 1273 case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_3_ADV_L2:
kevin1990 16:e4f2689363bb 1274 case ADI_SENSE_1000_ADC_SENSOR_THERMOCOUPLE_4_ADV_L2:
kevin1990 16:e4f2689363bb 1275 case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_PT100_DEF_L1:
kevin1990 16:e4f2689363bb 1276 case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_PT1000_DEF_L1:
kevin1990 16:e4f2689363bb 1277 case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_1_DEF_L2:
kevin1990 16:e4f2689363bb 1278 case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_2_DEF_L2:
kevin1990 16:e4f2689363bb 1279 case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_3_DEF_L2:
kevin1990 16:e4f2689363bb 1280 case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_4_DEF_L2:
kevin1990 16:e4f2689363bb 1281 case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_PT100_ADV_L1:
kevin1990 16:e4f2689363bb 1282 case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_PT1000_ADV_L1:
kevin1990 16:e4f2689363bb 1283 case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_1_ADV_L2:
kevin1990 16:e4f2689363bb 1284 case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_2_ADV_L2:
kevin1990 16:e4f2689363bb 1285 case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_3_ADV_L2:
kevin1990 16:e4f2689363bb 1286 case ADI_SENSE_1000_ADC_SENSOR_RTD_3WIRE_4_ADV_L2:
kevin1990 16:e4f2689363bb 1287 case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_PT100_DEF_L1:
kevin1990 16:e4f2689363bb 1288 case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_PT1000_DEF_L1:
kevin1990 16:e4f2689363bb 1289 case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_1_DEF_L2:
kevin1990 16:e4f2689363bb 1290 case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_2_DEF_L2:
kevin1990 16:e4f2689363bb 1291 case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_3_DEF_L2:
kevin1990 16:e4f2689363bb 1292 case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_4_DEF_L2:
kevin1990 16:e4f2689363bb 1293 case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_PT100_ADV_L1:
kevin1990 16:e4f2689363bb 1294 case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_PT1000_ADV_L1:
kevin1990 16:e4f2689363bb 1295 case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_1_ADV_L2:
kevin1990 16:e4f2689363bb 1296 case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_2_ADV_L2:
kevin1990 16:e4f2689363bb 1297 case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_3_ADV_L2:
kevin1990 16:e4f2689363bb 1298 case ADI_SENSE_1000_ADC_SENSOR_RTD_4WIRE_4_ADV_L2:
kevin1990 16:e4f2689363bb 1299 case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_1_DEF_L2:
kevin1990 16:e4f2689363bb 1300 case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_2_DEF_L2:
kevin1990 16:e4f2689363bb 1301 case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_3_DEF_L2:
kevin1990 16:e4f2689363bb 1302 case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_4_DEF_L2:
kevin1990 16:e4f2689363bb 1303 case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_1_ADV_L2:
kevin1990 16:e4f2689363bb 1304 case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_2_ADV_L2:
kevin1990 16:e4f2689363bb 1305 case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_3_ADV_L2:
kevin1990 16:e4f2689363bb 1306 case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_4WIRE_4_ADV_L2:
kevin1990 16:e4f2689363bb 1307 case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_1_DEF_L2:
kevin1990 16:e4f2689363bb 1308 case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_2_DEF_L2:
kevin1990 16:e4f2689363bb 1309 case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_3_DEF_L2:
kevin1990 16:e4f2689363bb 1310 case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_4_DEF_L2:
kevin1990 16:e4f2689363bb 1311 case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_1_ADV_L2:
kevin1990 16:e4f2689363bb 1312 case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_2_ADV_L2:
kevin1990 16:e4f2689363bb 1313 case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_3_ADV_L2:
kevin1990 16:e4f2689363bb 1314 case ADI_SENSE_1000_ADC_SENSOR_BRIDGE_6WIRE_4_ADV_L2:
kevin1990 16:e4f2689363bb 1315 case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_A_10K_DEF_L1:
kevin1990 16:e4f2689363bb 1316 case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_B_10K_DEF_L1:
kevin1990 16:e4f2689363bb 1317 case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_1_DEF_L2:
kevin1990 16:e4f2689363bb 1318 case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_2_DEF_L2:
kevin1990 16:e4f2689363bb 1319 case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_3_DEF_L2:
kevin1990 16:e4f2689363bb 1320 case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_4_DEF_L2:
kevin1990 16:e4f2689363bb 1321 case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_A_10K_ADV_L1:
kevin1990 16:e4f2689363bb 1322 case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_B_10K_ADV_L1:
kevin1990 16:e4f2689363bb 1323 case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_1_ADV_L2:
kevin1990 16:e4f2689363bb 1324 case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_2_ADV_L2:
kevin1990 16:e4f2689363bb 1325 case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_3_ADV_L2:
kevin1990 16:e4f2689363bb 1326 case ADI_SENSE_1000_ADC_SENSOR_THERMISTOR_4_ADV_L2:
kevin1990 16:e4f2689363bb 1327 if (! ADI_SENSE_1000_CHANNEL_IS_ADC_SENSOR(eChannelId))
kevin1990 16:e4f2689363bb 1328 {
kevin1990 16:e4f2689363bb 1329 ADI_SENSE_LOG_ERROR(
kevin1990 16:e4f2689363bb 1330 "Invalid ADC sensor type %d specified for channel %d",
kevin1990 16:e4f2689363bb 1331 sensorType, eChannelId);
kevin1990 16:e4f2689363bb 1332 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 1333 }
kevin1990 16:e4f2689363bb 1334 break;
kevin1990 16:e4f2689363bb 1335 case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_PT100_DEF_L1:
kevin1990 16:e4f2689363bb 1336 case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_PT1000_DEF_L1:
kevin1990 16:e4f2689363bb 1337 case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_1_DEF_L2:
kevin1990 16:e4f2689363bb 1338 case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_2_DEF_L2:
kevin1990 16:e4f2689363bb 1339 case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_3_DEF_L2:
kevin1990 16:e4f2689363bb 1340 case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_4_DEF_L2:
kevin1990 16:e4f2689363bb 1341 case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_PT100_ADV_L1:
kevin1990 16:e4f2689363bb 1342 case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_PT1000_ADV_L1:
kevin1990 16:e4f2689363bb 1343 case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_1_ADV_L2:
kevin1990 16:e4f2689363bb 1344 case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_2_ADV_L2:
kevin1990 16:e4f2689363bb 1345 case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_3_ADV_L2:
kevin1990 16:e4f2689363bb 1346 case ADI_SENSE_1000_ADC_SENSOR_RTD_2WIRE_4_ADV_L2:
kevin1990 16:e4f2689363bb 1347 if (! (ADI_SENSE_1000_CHANNEL_IS_ADC_SENSOR(eChannelId) ||
kevin1990 16:e4f2689363bb 1348 ADI_SENSE_1000_CHANNEL_IS_ADC_CJC(eChannelId)))
kevin1990 16:e4f2689363bb 1349 {
kevin1990 16:e4f2689363bb 1350 ADI_SENSE_LOG_ERROR(
kevin1990 16:e4f2689363bb 1351 "Invalid ADC sensor type %d specified for channel %d",
kevin1990 16:e4f2689363bb 1352 sensorType, eChannelId);
kevin1990 16:e4f2689363bb 1353 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 1354 }
kevin1990 16:e4f2689363bb 1355 break;
kevin1990 16:e4f2689363bb 1356 case ADI_SENSE_1000_ADC_SENSOR_VOLTAGE:
kevin1990 16:e4f2689363bb 1357 case ADI_SENSE_1000_ADC_SENSOR_VOLTAGE_PRESSURE_HONEYWELL_TRUSTABILITY:
kevin1990 16:e4f2689363bb 1358 case ADI_SENSE_1000_ADC_SENSOR_VOLTAGE_PRESSURE_AMPHENOL_NPA300X:
kevin1990 16:e4f2689363bb 1359 case ADI_SENSE_1000_ADC_SENSOR_VOLTAGE_PRESSURE_3_DEF:
kevin1990 16:e4f2689363bb 1360 if (! ADI_SENSE_1000_CHANNEL_IS_ADC_VOLTAGE(eChannelId))
kevin1990 16:e4f2689363bb 1361 {
kevin1990 16:e4f2689363bb 1362 ADI_SENSE_LOG_ERROR(
kevin1990 16:e4f2689363bb 1363 "Invalid ADC sensor type %d specified for channel %d",
kevin1990 16:e4f2689363bb 1364 sensorType, eChannelId);
kevin1990 16:e4f2689363bb 1365 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 1366 }
kevin1990 16:e4f2689363bb 1367 break;
kevin1990 16:e4f2689363bb 1368 case ADI_SENSE_1000_ADC_SENSOR_CURRENT:
kevin1990 16:e4f2689363bb 1369 case ADI_SENSE_1000_ADC_SENSOR_CURRENT_PRESSURE_HONEYWELL_PX2:
kevin1990 16:e4f2689363bb 1370 case ADI_SENSE_1000_ADC_SENSOR_CURRENT_PRESSURE_2_DEF:
kevin1990 16:e4f2689363bb 1371 if (! ADI_SENSE_1000_CHANNEL_IS_ADC_CURRENT(eChannelId))
kevin1990 16:e4f2689363bb 1372 {
kevin1990 16:e4f2689363bb 1373 ADI_SENSE_LOG_ERROR(
kevin1990 16:e4f2689363bb 1374 "Invalid ADC sensor type %d specified for channel %d",
kevin1990 16:e4f2689363bb 1375 sensorType, eChannelId);
kevin1990 16:e4f2689363bb 1376 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 1377 }
kevin1990 16:e4f2689363bb 1378 break;
kevin1990 16:e4f2689363bb 1379 default:
kevin1990 16:e4f2689363bb 1380 ADI_SENSE_LOG_ERROR("Invalid/unsupported ADC sensor type %d specified",
kevin1990 16:e4f2689363bb 1381 sensorType);
kevin1990 16:e4f2689363bb 1382 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 1383 }
kevin1990 16:e4f2689363bb 1384
kevin1990 16:e4f2689363bb 1385 sensorTypeReg.Sensor_Type = sensorType;
kevin1990 16:e4f2689363bb 1386
kevin1990 16:e4f2689363bb 1387 WRITE_REG_U16(hDevice, sensorTypeReg.VALUE16, CORE_SENSOR_TYPEn(eChannelId));
kevin1990 16:e4f2689363bb 1388
kevin1990 16:e4f2689363bb 1389 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1390 }
kevin1990 16:e4f2689363bb 1391
kevin1990 16:e4f2689363bb 1392 static ADI_SENSE_RESULT adi_sense_SetChannelAdcSensorDetails(
kevin1990 16:e4f2689363bb 1393 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1394 ADI_SENSE_1000_CHANNEL_ID eChannelId,
kevin1990 16:e4f2689363bb 1395 ADI_SENSE_1000_CHANNEL_CONFIG *pChannelConfig)
kevin1990 16:e4f2689363bb 1396 /*
kevin1990 16:e4f2689363bb 1397 * TODO - it would be nice if the general- vs. ADC-specific sensor details could be split into separate registers
kevin1990 16:e4f2689363bb 1398 * General details:
kevin1990 16:e4f2689363bb 1399 * - Measurement_Units
kevin1990 16:e4f2689363bb 1400 * - Compensation_Channel
kevin1990 16:e4f2689363bb 1401 * - CJC_Publish (if "CJC" was removed from the name)
kevin1990 16:e4f2689363bb 1402 * ADC-specific details:
kevin1990 16:e4f2689363bb 1403 * - PGA_Gain
kevin1990 16:e4f2689363bb 1404 * - Reference_Select
kevin1990 16:e4f2689363bb 1405 * - Reference_Buffer_Disable
kevin1990 16:e4f2689363bb 1406 * - Vbias
kevin1990 16:e4f2689363bb 1407 */
kevin1990 16:e4f2689363bb 1408 {
kevin1990 16:e4f2689363bb 1409 ADI_SENSE_1000_ADC_CHANNEL_CONFIG *pAdcChannelConfig = &pChannelConfig->adcChannelConfig;
kevin1990 16:e4f2689363bb 1410 ADI_SENSE_1000_ADC_REFERENCE_CONFIG *pRefConfig = &pAdcChannelConfig->reference;
kevin1990 16:e4f2689363bb 1411 ADI_ADISENSE_CORE_Sensor_Details_t sensorDetailsReg;
kevin1990 16:e4f2689363bb 1412
kevin1990 16:e4f2689363bb 1413 sensorDetailsReg.VALUE32 = REG_RESET_VAL(CORE_SENSOR_DETAILSn);
kevin1990 16:e4f2689363bb 1414
kevin1990 16:e4f2689363bb 1415 switch(pChannelConfig->measurementUnit)
kevin1990 16:e4f2689363bb 1416 {
kevin1990 16:e4f2689363bb 1417 case ADI_SENSE_1000_MEASUREMENT_UNIT_FAHRENHEIT:
kevin1990 16:e4f2689363bb 1418 sensorDetailsReg.Measurement_Units = ADISENSE_CORE_SENSOR_DETAILS_UNITS_DEGF;
kevin1990 16:e4f2689363bb 1419 break;
kevin1990 16:e4f2689363bb 1420 case ADI_SENSE_1000_MEASUREMENT_UNIT_CELSIUS:
kevin1990 16:e4f2689363bb 1421 case ADI_SENSE_1000_MEASUREMENT_UNIT_DEFAULT:
kevin1990 16:e4f2689363bb 1422 sensorDetailsReg.Measurement_Units = ADISENSE_CORE_SENSOR_DETAILS_UNITS_DEGC;
kevin1990 16:e4f2689363bb 1423 break;
kevin1990 16:e4f2689363bb 1424 default:
kevin1990 16:e4f2689363bb 1425 ADI_SENSE_LOG_ERROR("Invalid measurement unit %d specified",
kevin1990 16:e4f2689363bb 1426 pChannelConfig->measurementUnit);
kevin1990 16:e4f2689363bb 1427 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 1428 }
kevin1990 16:e4f2689363bb 1429
kevin1990 16:e4f2689363bb 1430 sensorDetailsReg.Compensation_Channel = pChannelConfig->compensationChannel;
kevin1990 16:e4f2689363bb 1431
kevin1990 16:e4f2689363bb 1432 switch(pRefConfig->type)
kevin1990 16:e4f2689363bb 1433 {
kevin1990 16:e4f2689363bb 1434 case ADI_SENSE_1000_ADC_REFERENCE_RESISTOR_INTERNAL_1:
kevin1990 16:e4f2689363bb 1435 sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_RINT1;
kevin1990 16:e4f2689363bb 1436 break;
kevin1990 16:e4f2689363bb 1437 case ADI_SENSE_1000_ADC_REFERENCE_RESISTOR_INTERNAL_2:
kevin1990 16:e4f2689363bb 1438 sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_RINT2;
kevin1990 16:e4f2689363bb 1439 break;
kevin1990 16:e4f2689363bb 1440 case ADI_SENSE_1000_ADC_REFERENCE_VOLTAGE_INTERNAL:
kevin1990 16:e4f2689363bb 1441 sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_INT;
kevin1990 16:e4f2689363bb 1442 break;
kevin1990 16:e4f2689363bb 1443 case ADI_SENSE_1000_ADC_REFERENCE_VOLTAGE_AVDD:
kevin1990 16:e4f2689363bb 1444 sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_AVDD;
kevin1990 16:e4f2689363bb 1445 break;
kevin1990 16:e4f2689363bb 1446 case ADI_SENSE_1000_ADC_REFERENCE_RESISTOR_EXTERNAL_1:
kevin1990 16:e4f2689363bb 1447 sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_REXT1;
kevin1990 16:e4f2689363bb 1448 break;
kevin1990 16:e4f2689363bb 1449 case ADI_SENSE_1000_ADC_REFERENCE_RESISTOR_EXTERNAL_2:
kevin1990 16:e4f2689363bb 1450 sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_REXT2;
kevin1990 16:e4f2689363bb 1451 break;
kevin1990 16:e4f2689363bb 1452 case ADI_SENSE_1000_ADC_REFERENCE_VOLTAGE_EXTERNAL_1:
kevin1990 16:e4f2689363bb 1453 sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_VEXT1;
kevin1990 16:e4f2689363bb 1454 break;
kevin1990 16:e4f2689363bb 1455 case ADI_SENSE_1000_ADC_REFERENCE_VOLTAGE_EXTERNAL_2:
kevin1990 16:e4f2689363bb 1456 sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_VEXT2;
kevin1990 16:e4f2689363bb 1457 break;
kevin1990 16:e4f2689363bb 1458 case ADI_SENSE_1000_ADC_REFERENCE_BRIDGE_EXCITATION:
kevin1990 16:e4f2689363bb 1459 sensorDetailsReg.Reference_Select = ADISENSE_CORE_SENSOR_DETAILS_REF_EXC;
kevin1990 16:e4f2689363bb 1460 break;
kevin1990 16:e4f2689363bb 1461 default:
kevin1990 16:e4f2689363bb 1462 ADI_SENSE_LOG_ERROR("Invalid ADC reference type %d specified",
kevin1990 16:e4f2689363bb 1463 pRefConfig->type);
kevin1990 16:e4f2689363bb 1464 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 1465 }
kevin1990 16:e4f2689363bb 1466
kevin1990 16:e4f2689363bb 1467 switch(pAdcChannelConfig->gain)
kevin1990 16:e4f2689363bb 1468 {
kevin1990 16:e4f2689363bb 1469 case ADI_SENSE_1000_ADC_GAIN_1X:
kevin1990 16:e4f2689363bb 1470 sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_1;
kevin1990 16:e4f2689363bb 1471 break;
kevin1990 16:e4f2689363bb 1472 case ADI_SENSE_1000_ADC_GAIN_2X:
kevin1990 16:e4f2689363bb 1473 sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_2;
kevin1990 16:e4f2689363bb 1474 break;
kevin1990 16:e4f2689363bb 1475 case ADI_SENSE_1000_ADC_GAIN_4X:
kevin1990 16:e4f2689363bb 1476 sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_4;
kevin1990 16:e4f2689363bb 1477 break;
kevin1990 16:e4f2689363bb 1478 case ADI_SENSE_1000_ADC_GAIN_8X:
kevin1990 16:e4f2689363bb 1479 sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_8;
kevin1990 16:e4f2689363bb 1480 break;
kevin1990 16:e4f2689363bb 1481 case ADI_SENSE_1000_ADC_GAIN_16X:
kevin1990 16:e4f2689363bb 1482 sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_16;
kevin1990 16:e4f2689363bb 1483 break;
kevin1990 16:e4f2689363bb 1484 case ADI_SENSE_1000_ADC_GAIN_32X:
kevin1990 16:e4f2689363bb 1485 sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_32;
kevin1990 16:e4f2689363bb 1486 break;
kevin1990 16:e4f2689363bb 1487 case ADI_SENSE_1000_ADC_GAIN_64X:
kevin1990 16:e4f2689363bb 1488 sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_64;
kevin1990 16:e4f2689363bb 1489 break;
kevin1990 16:e4f2689363bb 1490 case ADI_SENSE_1000_ADC_GAIN_128X:
kevin1990 16:e4f2689363bb 1491 sensorDetailsReg.PGA_Gain = ADISENSE_CORE_SENSOR_DETAILS_PGA_GAIN_128;
kevin1990 16:e4f2689363bb 1492 break;
kevin1990 16:e4f2689363bb 1493 default:
kevin1990 16:e4f2689363bb 1494 ADI_SENSE_LOG_ERROR("Invalid ADC gain %d specified",
kevin1990 16:e4f2689363bb 1495 pAdcChannelConfig->gain);
kevin1990 16:e4f2689363bb 1496 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 1497 }
kevin1990 16:e4f2689363bb 1498
kevin1990 16:e4f2689363bb 1499 if (pAdcChannelConfig->enableVbias)
kevin1990 16:e4f2689363bb 1500 sensorDetailsReg.Vbias = 1;
kevin1990 16:e4f2689363bb 1501 else
kevin1990 16:e4f2689363bb 1502 sensorDetailsReg.Vbias = 0;
kevin1990 16:e4f2689363bb 1503
kevin1990 16:e4f2689363bb 1504 if (pAdcChannelConfig->reference.disableBuffer)
kevin1990 16:e4f2689363bb 1505 sensorDetailsReg.Reference_Buffer_Disable = 1;
kevin1990 16:e4f2689363bb 1506 else
kevin1990 16:e4f2689363bb 1507 sensorDetailsReg.Reference_Buffer_Disable = 0;
kevin1990 16:e4f2689363bb 1508
kevin1990 16:e4f2689363bb 1509 if (pChannelConfig->disablePublishing)
kevin1990 16:e4f2689363bb 1510 sensorDetailsReg.Do_Not_Publish = 1;
kevin1990 16:e4f2689363bb 1511 else
kevin1990 16:e4f2689363bb 1512 sensorDetailsReg.Do_Not_Publish = 0;
kevin1990 16:e4f2689363bb 1513
kevin1990 16:e4f2689363bb 1514 WRITE_REG_U32(hDevice, sensorDetailsReg.VALUE32, CORE_SENSOR_DETAILSn(eChannelId));
kevin1990 16:e4f2689363bb 1515
kevin1990 16:e4f2689363bb 1516 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1517 }
kevin1990 16:e4f2689363bb 1518
kevin1990 16:e4f2689363bb 1519 static ADI_SENSE_RESULT adi_sense_SetChannelAdcFilter(
kevin1990 16:e4f2689363bb 1520 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1521 ADI_SENSE_1000_CHANNEL_ID eChannelId,
kevin1990 16:e4f2689363bb 1522 ADI_SENSE_1000_ADC_FILTER_CONFIG *pFilterConfig)
kevin1990 16:e4f2689363bb 1523 {
kevin1990 16:e4f2689363bb 1524 ADI_ADISENSE_CORE_Filter_Select_t filterSelectReg;
kevin1990 16:e4f2689363bb 1525
kevin1990 16:e4f2689363bb 1526 filterSelectReg.VALUE32 = REG_RESET_VAL(CORE_FILTER_SELECTn);
kevin1990 16:e4f2689363bb 1527
kevin1990 16:e4f2689363bb 1528 if (pFilterConfig->type == ADI_SENSE_1000_ADC_FILTER_SINC4)
kevin1990 16:e4f2689363bb 1529 {
kevin1990 16:e4f2689363bb 1530 filterSelectReg.ADC_Filter_Type = ADISENSE_CORE_FILTER_SELECT_FILTER_SINC4;
kevin1990 16:e4f2689363bb 1531 filterSelectReg.ADC_FS = pFilterConfig->fs;
kevin1990 16:e4f2689363bb 1532 }
kevin1990 16:e4f2689363bb 1533 else if (pFilterConfig->type == ADI_SENSE_1000_ADC_FILTER_FIR_20SPS)
kevin1990 16:e4f2689363bb 1534 {
kevin1990 16:e4f2689363bb 1535 filterSelectReg.ADC_Filter_Type = ADISENSE_CORE_FILTER_SELECT_FILTER_FIR_20SPS;
kevin1990 16:e4f2689363bb 1536 }
kevin1990 16:e4f2689363bb 1537 else if (pFilterConfig->type == ADI_SENSE_1000_ADC_FILTER_FIR_25SPS)
kevin1990 16:e4f2689363bb 1538 {
kevin1990 16:e4f2689363bb 1539 filterSelectReg.ADC_Filter_Type = ADISENSE_CORE_FILTER_SELECT_FILTER_FIR_25SPS;
kevin1990 16:e4f2689363bb 1540 }
kevin1990 16:e4f2689363bb 1541 else
kevin1990 16:e4f2689363bb 1542 {
kevin1990 16:e4f2689363bb 1543 ADI_SENSE_LOG_ERROR("Invalid ADC filter type %d specified",
kevin1990 16:e4f2689363bb 1544 pFilterConfig->type);
kevin1990 16:e4f2689363bb 1545 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 1546 }
kevin1990 16:e4f2689363bb 1547
kevin1990 16:e4f2689363bb 1548 WRITE_REG_U32(hDevice, filterSelectReg.VALUE32, CORE_FILTER_SELECTn(eChannelId));
kevin1990 16:e4f2689363bb 1549
kevin1990 16:e4f2689363bb 1550 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1551 }
kevin1990 16:e4f2689363bb 1552
kevin1990 16:e4f2689363bb 1553 static ADI_SENSE_RESULT adi_sense_SetChannelAdcCurrentConfig(
kevin1990 16:e4f2689363bb 1554 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1555 ADI_SENSE_1000_CHANNEL_ID eChannelId,
kevin1990 16:e4f2689363bb 1556 ADI_SENSE_1000_ADC_EXC_CURRENT_CONFIG *pCurrentConfig)
kevin1990 16:e4f2689363bb 1557 {
kevin1990 16:e4f2689363bb 1558 ADI_ADISENSE_CORE_Channel_Excitation_t channelExcitationReg;
kevin1990 16:e4f2689363bb 1559
kevin1990 16:e4f2689363bb 1560 channelExcitationReg.VALUE8 = REG_RESET_VAL(CORE_CHANNEL_EXCITATIONn);
kevin1990 16:e4f2689363bb 1561
kevin1990 16:e4f2689363bb 1562 if (pCurrentConfig->outputLevel == ADI_SENSE_1000_ADC_EXC_CURRENT_NONE)
kevin1990 16:e4f2689363bb 1563 {
kevin1990 16:e4f2689363bb 1564 channelExcitationReg.IOUT0_Disable = 1;
kevin1990 16:e4f2689363bb 1565 channelExcitationReg.IOUT1_Disable = 1;
kevin1990 16:e4f2689363bb 1566
kevin1990 16:e4f2689363bb 1567 channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_OFF;
kevin1990 16:e4f2689363bb 1568 }
kevin1990 16:e4f2689363bb 1569 else
kevin1990 16:e4f2689363bb 1570 {
kevin1990 16:e4f2689363bb 1571 channelExcitationReg.IOUT0_Disable = 0;
kevin1990 16:e4f2689363bb 1572 channelExcitationReg.IOUT1_Disable = 0;
kevin1990 16:e4f2689363bb 1573
kevin1990 16:e4f2689363bb 1574 if (pCurrentConfig->outputLevel == ADI_SENSE_1000_ADC_EXC_CURRENT_50uA)
kevin1990 16:e4f2689363bb 1575 channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_50UA;
kevin1990 16:e4f2689363bb 1576 else if (pCurrentConfig->outputLevel == ADI_SENSE_1000_ADC_EXC_CURRENT_100uA)
kevin1990 16:e4f2689363bb 1577 channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_100UA;
kevin1990 16:e4f2689363bb 1578 else if (pCurrentConfig->outputLevel == ADI_SENSE_1000_ADC_EXC_CURRENT_250uA)
kevin1990 16:e4f2689363bb 1579 channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_250UA;
kevin1990 16:e4f2689363bb 1580 else if (pCurrentConfig->outputLevel == ADI_SENSE_1000_ADC_EXC_CURRENT_500uA)
kevin1990 16:e4f2689363bb 1581 channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_500UA;
kevin1990 16:e4f2689363bb 1582 else if (pCurrentConfig->outputLevel == ADI_SENSE_1000_ADC_EXC_CURRENT_750uA)
kevin1990 16:e4f2689363bb 1583 channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_750UA;
kevin1990 16:e4f2689363bb 1584 else if (pCurrentConfig->outputLevel == ADI_SENSE_1000_ADC_EXC_CURRENT_1000uA)
kevin1990 16:e4f2689363bb 1585 channelExcitationReg.IOUT_Excitation_Current = ADISENSE_CORE_CHANNEL_EXCITATION_IEXC_1000UA;
kevin1990 16:e4f2689363bb 1586 else
kevin1990 16:e4f2689363bb 1587 {
kevin1990 16:e4f2689363bb 1588 ADI_SENSE_LOG_ERROR("Invalid ADC excitation current %d specified",
kevin1990 16:e4f2689363bb 1589 pCurrentConfig->outputLevel);
kevin1990 16:e4f2689363bb 1590 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 1591 }
kevin1990 16:e4f2689363bb 1592
kevin1990 16:e4f2689363bb 1593 if (pCurrentConfig->swapOption == ADI_SENSE_1000_ADC_EXC_CURRENT_SWAP_DYNAMIC)
kevin1990 16:e4f2689363bb 1594 {
kevin1990 16:e4f2689363bb 1595 channelExcitationReg.IOUT_Dont_Swap_3Wire = 0;
kevin1990 16:e4f2689363bb 1596 channelExcitationReg.IOUT_Static_Swap_3Wire = 0;
kevin1990 16:e4f2689363bb 1597 }
kevin1990 16:e4f2689363bb 1598 else if (pCurrentConfig->swapOption == ADI_SENSE_1000_ADC_EXC_CURRENT_SWAP_STATIC)
kevin1990 16:e4f2689363bb 1599 {
kevin1990 16:e4f2689363bb 1600 channelExcitationReg.IOUT_Dont_Swap_3Wire = 1;
kevin1990 16:e4f2689363bb 1601 channelExcitationReg.IOUT_Static_Swap_3Wire = 1;
kevin1990 16:e4f2689363bb 1602 }
kevin1990 16:e4f2689363bb 1603 else if (pCurrentConfig->swapOption == ADI_SENSE_1000_ADC_EXC_CURRENT_SWAP_NONE)
kevin1990 16:e4f2689363bb 1604 {
kevin1990 16:e4f2689363bb 1605 channelExcitationReg.IOUT_Dont_Swap_3Wire = 1;
kevin1990 16:e4f2689363bb 1606 channelExcitationReg.IOUT_Static_Swap_3Wire = 0;
kevin1990 16:e4f2689363bb 1607 }
kevin1990 16:e4f2689363bb 1608 else
kevin1990 16:e4f2689363bb 1609 {
kevin1990 16:e4f2689363bb 1610 ADI_SENSE_LOG_ERROR(
kevin1990 16:e4f2689363bb 1611 "Invalid ADC excitation current swap option %d specified",
kevin1990 16:e4f2689363bb 1612 pCurrentConfig->swapOption);
kevin1990 16:e4f2689363bb 1613 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 1614 }
kevin1990 16:e4f2689363bb 1615 }
kevin1990 16:e4f2689363bb 1616
kevin1990 16:e4f2689363bb 1617 WRITE_REG_U8(hDevice, channelExcitationReg.VALUE8, CORE_CHANNEL_EXCITATIONn(eChannelId));
kevin1990 16:e4f2689363bb 1618
kevin1990 16:e4f2689363bb 1619 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1620 }
kevin1990 16:e4f2689363bb 1621
kevin1990 16:e4f2689363bb 1622 ADI_SENSE_RESULT adi_sense_SetAdcChannelConfig(
kevin1990 16:e4f2689363bb 1623 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1624 ADI_SENSE_1000_CHANNEL_ID eChannelId,
kevin1990 16:e4f2689363bb 1625 ADI_SENSE_1000_CHANNEL_CONFIG *pChannelConfig)
kevin1990 16:e4f2689363bb 1626 {
kevin1990 16:e4f2689363bb 1627 ADI_SENSE_RESULT eRet;
kevin1990 16:e4f2689363bb 1628 ADI_SENSE_1000_ADC_CHANNEL_CONFIG *pAdcChannelConfig =
kevin1990 16:e4f2689363bb 1629 &pChannelConfig->adcChannelConfig;
kevin1990 16:e4f2689363bb 1630
kevin1990 16:e4f2689363bb 1631 eRet = adi_sense_SetChannelAdcSensorType(hDevice, eChannelId,
kevin1990 16:e4f2689363bb 1632 pAdcChannelConfig->sensor);
kevin1990 16:e4f2689363bb 1633 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 1634 {
kevin1990 16:e4f2689363bb 1635 ADI_SENSE_LOG_ERROR("Failed to set ADC sensor type for channel %d",
kevin1990 16:e4f2689363bb 1636 eChannelId);
kevin1990 16:e4f2689363bb 1637 return eRet;
kevin1990 16:e4f2689363bb 1638 }
kevin1990 16:e4f2689363bb 1639
kevin1990 16:e4f2689363bb 1640 eRet = adi_sense_SetChannelAdcSensorDetails(hDevice, eChannelId,
kevin1990 16:e4f2689363bb 1641 pChannelConfig);
kevin1990 16:e4f2689363bb 1642 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 1643 {
kevin1990 16:e4f2689363bb 1644 ADI_SENSE_LOG_ERROR("Failed to set ADC sensor details for channel %d",
kevin1990 16:e4f2689363bb 1645 eChannelId);
kevin1990 16:e4f2689363bb 1646 return eRet;
kevin1990 16:e4f2689363bb 1647 }
kevin1990 16:e4f2689363bb 1648
kevin1990 16:e4f2689363bb 1649 eRet = adi_sense_SetChannelAdcFilter(hDevice, eChannelId,
kevin1990 16:e4f2689363bb 1650 &pAdcChannelConfig->filter);
kevin1990 16:e4f2689363bb 1651 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 1652 {
kevin1990 16:e4f2689363bb 1653 ADI_SENSE_LOG_ERROR("Failed to set ADC filter for channel %d",
kevin1990 16:e4f2689363bb 1654 eChannelId);
kevin1990 16:e4f2689363bb 1655 return eRet;
kevin1990 16:e4f2689363bb 1656 }
kevin1990 16:e4f2689363bb 1657
kevin1990 16:e4f2689363bb 1658 eRet = adi_sense_SetChannelAdcCurrentConfig(hDevice, eChannelId,
kevin1990 16:e4f2689363bb 1659 &pAdcChannelConfig->current);
kevin1990 16:e4f2689363bb 1660 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 1661 {
kevin1990 16:e4f2689363bb 1662 ADI_SENSE_LOG_ERROR("Failed to set ADC current for channel %d",
kevin1990 16:e4f2689363bb 1663 eChannelId);
kevin1990 16:e4f2689363bb 1664 return eRet;
kevin1990 16:e4f2689363bb 1665 }
kevin1990 16:e4f2689363bb 1666
kevin1990 16:e4f2689363bb 1667 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1668 }
kevin1990 16:e4f2689363bb 1669
kevin1990 16:e4f2689363bb 1670
kevin1990 16:e4f2689363bb 1671 static ADI_SENSE_RESULT adi_sense_SetDigitalSensorCommands(
kevin1990 16:e4f2689363bb 1672 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1673 ADI_SENSE_1000_CHANNEL_ID eChannelId,
kevin1990 16:e4f2689363bb 1674 ADI_SENSE_1000_DIGITAL_SENSOR_COMMAND *pConfigCommand,
kevin1990 16:e4f2689363bb 1675 ADI_SENSE_1000_DIGITAL_SENSOR_COMMAND *pDataRequestCommand)
kevin1990 16:e4f2689363bb 1676 {
kevin1990 16:e4f2689363bb 1677 ADI_ADISENSE_CORE_Digital_Sensor_Num_Cmds_t numCmdsReg;
kevin1990 16:e4f2689363bb 1678
kevin1990 16:e4f2689363bb 1679 numCmdsReg.VALUE8 = REG_RESET_VAL(CORE_DIGITAL_SENSOR_NUM_CMDSn);
kevin1990 16:e4f2689363bb 1680
kevin1990 16:e4f2689363bb 1681 CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_NUM_CMDS_DIGITAL_SENSOR_NUM_CFG_CMDS,
kevin1990 16:e4f2689363bb 1682 pConfigCommand->commandLength);
kevin1990 16:e4f2689363bb 1683 CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_NUM_CMDS_DIGITAL_SENSOR_NUM_READ_CMDS,
kevin1990 16:e4f2689363bb 1684 pDataRequestCommand->commandLength);
kevin1990 16:e4f2689363bb 1685
kevin1990 16:e4f2689363bb 1686 numCmdsReg.Digital_Sensor_Num_Cfg_Cmds = pConfigCommand->commandLength;
kevin1990 16:e4f2689363bb 1687 numCmdsReg.Digital_Sensor_Num_Read_Cmds = pDataRequestCommand->commandLength;
kevin1990 16:e4f2689363bb 1688
kevin1990 16:e4f2689363bb 1689 WRITE_REG_U8(hDevice, numCmdsReg.VALUE8,
kevin1990 16:e4f2689363bb 1690 CORE_DIGITAL_SENSOR_NUM_CMDSn(eChannelId));
kevin1990 16:e4f2689363bb 1691
kevin1990 16:e4f2689363bb 1692 switch (pConfigCommand->commandLength)
kevin1990 16:e4f2689363bb 1693 {
kevin1990 16:e4f2689363bb 1694 /* NOTE - intentional fall-through cases below */
kevin1990 16:e4f2689363bb 1695 case 7:
kevin1990 16:e4f2689363bb 1696 WRITE_REG_U8(hDevice, pConfigCommand->command[6],
kevin1990 16:e4f2689363bb 1697 CORE_DIGITAL_SENSOR_COMMAND7n(eChannelId));
kevin1990 16:e4f2689363bb 1698 case 6:
kevin1990 16:e4f2689363bb 1699 WRITE_REG_U8(hDevice, pConfigCommand->command[5],
kevin1990 16:e4f2689363bb 1700 CORE_DIGITAL_SENSOR_COMMAND6n(eChannelId));
kevin1990 16:e4f2689363bb 1701 case 5:
kevin1990 16:e4f2689363bb 1702 WRITE_REG_U8(hDevice, pConfigCommand->command[4],
kevin1990 16:e4f2689363bb 1703 CORE_DIGITAL_SENSOR_COMMAND5n(eChannelId));
kevin1990 16:e4f2689363bb 1704 case 4:
kevin1990 16:e4f2689363bb 1705 WRITE_REG_U8(hDevice, pConfigCommand->command[3],
kevin1990 16:e4f2689363bb 1706 CORE_DIGITAL_SENSOR_COMMAND4n(eChannelId));
kevin1990 16:e4f2689363bb 1707 case 3:
kevin1990 16:e4f2689363bb 1708 WRITE_REG_U8(hDevice, pConfigCommand->command[2],
kevin1990 16:e4f2689363bb 1709 CORE_DIGITAL_SENSOR_COMMAND3n(eChannelId));
kevin1990 16:e4f2689363bb 1710 case 2:
kevin1990 16:e4f2689363bb 1711 WRITE_REG_U8(hDevice, pConfigCommand->command[1],
kevin1990 16:e4f2689363bb 1712 CORE_DIGITAL_SENSOR_COMMAND2n(eChannelId));
kevin1990 16:e4f2689363bb 1713 case 1:
kevin1990 16:e4f2689363bb 1714 WRITE_REG_U8(hDevice, pConfigCommand->command[0],
kevin1990 16:e4f2689363bb 1715 CORE_DIGITAL_SENSOR_COMMAND1n(eChannelId));
kevin1990 16:e4f2689363bb 1716 case 0:
kevin1990 16:e4f2689363bb 1717 default:
kevin1990 16:e4f2689363bb 1718 break;
kevin1990 16:e4f2689363bb 1719 };
kevin1990 16:e4f2689363bb 1720
kevin1990 16:e4f2689363bb 1721 switch (pDataRequestCommand->commandLength)
kevin1990 16:e4f2689363bb 1722 {
kevin1990 16:e4f2689363bb 1723 /* NOTE - intentional fall-through cases below */
kevin1990 16:e4f2689363bb 1724 case 7:
kevin1990 16:e4f2689363bb 1725 WRITE_REG_U8(hDevice, pDataRequestCommand->command[6],
kevin1990 16:e4f2689363bb 1726 CORE_DIGITAL_SENSOR_READ_CMD7n(eChannelId));
kevin1990 16:e4f2689363bb 1727 case 6:
kevin1990 16:e4f2689363bb 1728 WRITE_REG_U8(hDevice, pDataRequestCommand->command[5],
kevin1990 16:e4f2689363bb 1729 CORE_DIGITAL_SENSOR_READ_CMD6n(eChannelId));
kevin1990 16:e4f2689363bb 1730 case 5:
kevin1990 16:e4f2689363bb 1731 WRITE_REG_U8(hDevice, pDataRequestCommand->command[4],
kevin1990 16:e4f2689363bb 1732 CORE_DIGITAL_SENSOR_READ_CMD5n(eChannelId));
kevin1990 16:e4f2689363bb 1733 case 4:
kevin1990 16:e4f2689363bb 1734 WRITE_REG_U8(hDevice, pDataRequestCommand->command[3],
kevin1990 16:e4f2689363bb 1735 CORE_DIGITAL_SENSOR_READ_CMD4n(eChannelId));
kevin1990 16:e4f2689363bb 1736 case 3:
kevin1990 16:e4f2689363bb 1737 WRITE_REG_U8(hDevice, pDataRequestCommand->command[2],
kevin1990 16:e4f2689363bb 1738 CORE_DIGITAL_SENSOR_READ_CMD3n(eChannelId));
kevin1990 16:e4f2689363bb 1739 case 2:
kevin1990 16:e4f2689363bb 1740 WRITE_REG_U8(hDevice, pDataRequestCommand->command[1],
kevin1990 16:e4f2689363bb 1741 CORE_DIGITAL_SENSOR_READ_CMD2n(eChannelId));
kevin1990 16:e4f2689363bb 1742 case 1:
kevin1990 16:e4f2689363bb 1743 WRITE_REG_U8(hDevice, pDataRequestCommand->command[0],
kevin1990 16:e4f2689363bb 1744 CORE_DIGITAL_SENSOR_READ_CMD1n(eChannelId));
kevin1990 16:e4f2689363bb 1745 case 0:
kevin1990 16:e4f2689363bb 1746 default:
kevin1990 16:e4f2689363bb 1747 break;
kevin1990 16:e4f2689363bb 1748 };
kevin1990 16:e4f2689363bb 1749
kevin1990 16:e4f2689363bb 1750 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1751 }
kevin1990 16:e4f2689363bb 1752
kevin1990 16:e4f2689363bb 1753 static ADI_SENSE_RESULT adi_sense_SetChannelI2cSensorType(
kevin1990 16:e4f2689363bb 1754 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1755 ADI_SENSE_1000_CHANNEL_ID eChannelId,
kevin1990 16:e4f2689363bb 1756 ADI_SENSE_1000_I2C_SENSOR_TYPE sensorType)
kevin1990 16:e4f2689363bb 1757 {
kevin1990 16:e4f2689363bb 1758 ADI_ADISENSE_CORE_Sensor_Type_t sensorTypeReg;
kevin1990 16:e4f2689363bb 1759
kevin1990 16:e4f2689363bb 1760 sensorTypeReg.VALUE16 = REG_RESET_VAL(CORE_SENSOR_TYPEn);
kevin1990 16:e4f2689363bb 1761
kevin1990 16:e4f2689363bb 1762 /* Ensure that the sensor type is valid for this channel */
kevin1990 16:e4f2689363bb 1763 switch(sensorType)
kevin1990 16:e4f2689363bb 1764 {
kevin1990 16:e4f2689363bb 1765 case ADI_SENSE_1000_I2C_SENSOR_HUMIDITY_HONEYWELL_HUMIDICON:
kevin1990 16:e4f2689363bb 1766 sensorTypeReg.Sensor_Type = ADISENSE_CORE_SENSOR_TYPE_SENSOR_I2C_HUMIDITY_HONEYWELL_HUMIDICON;
kevin1990 16:e4f2689363bb 1767 break;
kevin1990 16:e4f2689363bb 1768 case ADI_SENSE_1000_I2C_SENSOR_HUMIDITY_SENSIRION_SHT3X:
kevin1990 16:e4f2689363bb 1769 sensorTypeReg.Sensor_Type = ADISENSE_CORE_SENSOR_TYPE_SENSOR_I2C_HUMIDITY_SENSIRION_SHT3X;
kevin1990 16:e4f2689363bb 1770 break;
kevin1990 16:e4f2689363bb 1771 default:
kevin1990 16:e4f2689363bb 1772 /* TODO - add support for custom I2C sensors */
kevin1990 16:e4f2689363bb 1773 ADI_SENSE_LOG_ERROR("Unsupported I2C sensor type %d specified", sensorType);
kevin1990 16:e4f2689363bb 1774 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 1775 }
kevin1990 16:e4f2689363bb 1776
kevin1990 16:e4f2689363bb 1777 WRITE_REG_U16(hDevice, sensorTypeReg.VALUE16, CORE_SENSOR_TYPEn(eChannelId));
kevin1990 16:e4f2689363bb 1778
kevin1990 16:e4f2689363bb 1779 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1780 }
kevin1990 16:e4f2689363bb 1781
kevin1990 16:e4f2689363bb 1782 static ADI_SENSE_RESULT adi_sense_SetChannelI2cSensorAddress(
kevin1990 16:e4f2689363bb 1783 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1784 ADI_SENSE_1000_CHANNEL_ID eChannelId,
kevin1990 16:e4f2689363bb 1785 uint32_t deviceAddress)
kevin1990 16:e4f2689363bb 1786 {
kevin1990 16:e4f2689363bb 1787 CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_ADDRESS_DIGITAL_SENSOR_ADDRESS, deviceAddress);
kevin1990 16:e4f2689363bb 1788 WRITE_REG_U8(hDevice, deviceAddress, CORE_DIGITAL_SENSOR_ADDRESSn(eChannelId));
kevin1990 16:e4f2689363bb 1789
kevin1990 16:e4f2689363bb 1790 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1791 }
kevin1990 16:e4f2689363bb 1792
kevin1990 16:e4f2689363bb 1793 ADI_SENSE_RESULT adi_sense_SetI2cChannelConfig(
kevin1990 16:e4f2689363bb 1794 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1795 ADI_SENSE_1000_CHANNEL_ID eChannelId,
kevin1990 16:e4f2689363bb 1796 ADI_SENSE_1000_I2C_CHANNEL_CONFIG *pI2cChannelConfig)
kevin1990 16:e4f2689363bb 1797 {
kevin1990 16:e4f2689363bb 1798 ADI_SENSE_RESULT eRet;
kevin1990 16:e4f2689363bb 1799
kevin1990 16:e4f2689363bb 1800 eRet = adi_sense_SetChannelI2cSensorType(hDevice, eChannelId,
kevin1990 16:e4f2689363bb 1801 pI2cChannelConfig->sensor);
kevin1990 16:e4f2689363bb 1802 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 1803 {
kevin1990 16:e4f2689363bb 1804 ADI_SENSE_LOG_ERROR("Failed to set I2C sensor type for channel %d",
kevin1990 16:e4f2689363bb 1805 eChannelId);
kevin1990 16:e4f2689363bb 1806 return eRet;
kevin1990 16:e4f2689363bb 1807 }
kevin1990 16:e4f2689363bb 1808
kevin1990 16:e4f2689363bb 1809 eRet = adi_sense_SetChannelI2cSensorAddress(hDevice, eChannelId,
kevin1990 16:e4f2689363bb 1810 pI2cChannelConfig->deviceAddress);
kevin1990 16:e4f2689363bb 1811 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 1812 {
kevin1990 16:e4f2689363bb 1813 ADI_SENSE_LOG_ERROR("Failed to set I2C sensor address for channel %d",
kevin1990 16:e4f2689363bb 1814 eChannelId);
kevin1990 16:e4f2689363bb 1815 return eRet;
kevin1990 16:e4f2689363bb 1816 }
kevin1990 16:e4f2689363bb 1817
kevin1990 16:e4f2689363bb 1818 eRet = adi_sense_SetDigitalSensorCommands(hDevice, eChannelId,
kevin1990 16:e4f2689363bb 1819 &pI2cChannelConfig->configurationCommand,
kevin1990 16:e4f2689363bb 1820 &pI2cChannelConfig->dataRequestCommand);
kevin1990 16:e4f2689363bb 1821 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 1822 {
kevin1990 16:e4f2689363bb 1823 ADI_SENSE_LOG_ERROR("Failed to set I2C sensor commands for channel %d",
kevin1990 16:e4f2689363bb 1824 eChannelId);
kevin1990 16:e4f2689363bb 1825 return eRet;
kevin1990 16:e4f2689363bb 1826 }
kevin1990 16:e4f2689363bb 1827
kevin1990 16:e4f2689363bb 1828 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1829 }
kevin1990 16:e4f2689363bb 1830
kevin1990 16:e4f2689363bb 1831 static ADI_SENSE_RESULT adi_sense_SetChannelSpiSensorType(
kevin1990 16:e4f2689363bb 1832 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1833 ADI_SENSE_1000_CHANNEL_ID eChannelId,
kevin1990 16:e4f2689363bb 1834 ADI_SENSE_1000_SPI_SENSOR_TYPE sensorType)
kevin1990 16:e4f2689363bb 1835 {
kevin1990 16:e4f2689363bb 1836 ADI_ADISENSE_CORE_Sensor_Type_t sensorTypeReg;
kevin1990 16:e4f2689363bb 1837
kevin1990 16:e4f2689363bb 1838 sensorTypeReg.VALUE16 = REG_RESET_VAL(CORE_SENSOR_TYPEn);
kevin1990 16:e4f2689363bb 1839
kevin1990 16:e4f2689363bb 1840 /* Ensure that the sensor type is valid for this channel */
kevin1990 16:e4f2689363bb 1841 switch(sensorType)
kevin1990 16:e4f2689363bb 1842 {
kevin1990 16:e4f2689363bb 1843 case ADI_SENSE_1000_SPI_SENSOR_PRESSURE_HONEYWELL_TRUSTABILITY:
kevin1990 16:e4f2689363bb 1844 sensorTypeReg.Sensor_Type = ADISENSE_CORE_SENSOR_TYPE_SENSOR_SPI_PRESSURE_HONEYWELL_TRUSTABILITY;
kevin1990 16:e4f2689363bb 1845 break;
kevin1990 16:e4f2689363bb 1846 case ADI_SENSE_1000_SPI_SENSOR_ACCELEROMETER_ADI_ADXL362:
kevin1990 16:e4f2689363bb 1847 sensorTypeReg.Sensor_Type = ADISENSE_CORE_SENSOR_TYPE_SENSOR_SPI_ACCELEROMETER_1;
kevin1990 16:e4f2689363bb 1848 break;
kevin1990 16:e4f2689363bb 1849 default:
kevin1990 16:e4f2689363bb 1850 /* TODO - add support for custom SPI sensors */
kevin1990 16:e4f2689363bb 1851 ADI_SENSE_LOG_ERROR("Unsupported SPI sensor type %d specified", sensorType);
kevin1990 16:e4f2689363bb 1852 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 1853 }
kevin1990 16:e4f2689363bb 1854
kevin1990 16:e4f2689363bb 1855 WRITE_REG_U16(hDevice, sensorTypeReg.VALUE16, CORE_SENSOR_TYPEn(eChannelId));
kevin1990 16:e4f2689363bb 1856
kevin1990 16:e4f2689363bb 1857 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1858 }
kevin1990 16:e4f2689363bb 1859
kevin1990 16:e4f2689363bb 1860 ADI_SENSE_RESULT adi_sense_SetSpiChannelConfig(
kevin1990 16:e4f2689363bb 1861 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1862 ADI_SENSE_1000_CHANNEL_ID eChannelId,
kevin1990 16:e4f2689363bb 1863 ADI_SENSE_1000_SPI_CHANNEL_CONFIG *pSpiChannelConfig)
kevin1990 16:e4f2689363bb 1864 {
kevin1990 16:e4f2689363bb 1865 ADI_SENSE_RESULT eRet;
kevin1990 16:e4f2689363bb 1866
kevin1990 16:e4f2689363bb 1867 eRet = adi_sense_SetChannelSpiSensorType(hDevice, eChannelId,
kevin1990 16:e4f2689363bb 1868 pSpiChannelConfig->sensor);
kevin1990 16:e4f2689363bb 1869 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 1870 {
kevin1990 16:e4f2689363bb 1871 ADI_SENSE_LOG_ERROR("Failed to set SPI sensor type for channel %d",
kevin1990 16:e4f2689363bb 1872 eChannelId);
kevin1990 16:e4f2689363bb 1873 return eRet;
kevin1990 16:e4f2689363bb 1874 }
kevin1990 16:e4f2689363bb 1875
kevin1990 16:e4f2689363bb 1876 eRet = adi_sense_SetDigitalSensorCommands(hDevice, eChannelId,
kevin1990 16:e4f2689363bb 1877 &pSpiChannelConfig->configurationCommand,
kevin1990 16:e4f2689363bb 1878 &pSpiChannelConfig->dataRequestCommand);
kevin1990 16:e4f2689363bb 1879 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 1880 {
kevin1990 16:e4f2689363bb 1881 ADI_SENSE_LOG_ERROR("Failed to set SPI sensor commands for channel %d",
kevin1990 16:e4f2689363bb 1882 eChannelId);
kevin1990 16:e4f2689363bb 1883 return eRet;
kevin1990 16:e4f2689363bb 1884 }
kevin1990 16:e4f2689363bb 1885
kevin1990 16:e4f2689363bb 1886 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1887 }
kevin1990 16:e4f2689363bb 1888
kevin1990 16:e4f2689363bb 1889 ADI_SENSE_RESULT adi_sense_1000_SetChannelThresholdLimits(
kevin1990 16:e4f2689363bb 1890 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1891 ADI_SENSE_1000_CHANNEL_ID eChannelId,
kevin1990 16:e4f2689363bb 1892 float32_t fHighThresholdLimit,
kevin1990 16:e4f2689363bb 1893 float32_t fLowThresholdLimit)
kevin1990 16:e4f2689363bb 1894 {
kevin1990 16:e4f2689363bb 1895 /*
kevin1990 16:e4f2689363bb 1896 * If the low/high limits are *both* set to 0 in memory, or NaNs, assume
kevin1990 16:e4f2689363bb 1897 * that they are unset, or not required, and use infinity defaults instead
kevin1990 16:e4f2689363bb 1898 */
kevin1990 16:e4f2689363bb 1899 if (fHighThresholdLimit == 0.0 && fLowThresholdLimit == 0.0)
kevin1990 16:e4f2689363bb 1900 {
kevin1990 16:e4f2689363bb 1901 fHighThresholdLimit = INFINITY;
kevin1990 16:e4f2689363bb 1902 fLowThresholdLimit = -INFINITY;
kevin1990 16:e4f2689363bb 1903 }
kevin1990 16:e4f2689363bb 1904 else
kevin1990 16:e4f2689363bb 1905 {
kevin1990 16:e4f2689363bb 1906 if (isnan(fHighThresholdLimit))
kevin1990 16:e4f2689363bb 1907 fHighThresholdLimit = INFINITY;
kevin1990 16:e4f2689363bb 1908 if (isnan(fLowThresholdLimit))
kevin1990 16:e4f2689363bb 1909 fLowThresholdLimit = -INFINITY;
kevin1990 16:e4f2689363bb 1910 }
kevin1990 16:e4f2689363bb 1911
kevin1990 16:e4f2689363bb 1912 WRITE_REG_FLOAT(hDevice, fHighThresholdLimit,
kevin1990 16:e4f2689363bb 1913 CORE_HIGH_THRESHOLD_LIMITn(eChannelId));
kevin1990 16:e4f2689363bb 1914 WRITE_REG_FLOAT(hDevice, fLowThresholdLimit,
kevin1990 16:e4f2689363bb 1915 CORE_LOW_THRESHOLD_LIMITn(eChannelId));
kevin1990 16:e4f2689363bb 1916
kevin1990 16:e4f2689363bb 1917 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1918 }
kevin1990 16:e4f2689363bb 1919
kevin1990 16:e4f2689363bb 1920 ADI_SENSE_RESULT adi_sense_1000_SetOffsetGain(
kevin1990 16:e4f2689363bb 1921 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1922 ADI_SENSE_1000_CHANNEL_ID eChannelId,
kevin1990 16:e4f2689363bb 1923 float32_t fOffsetAdjustment,
kevin1990 16:e4f2689363bb 1924 float32_t fGainAdjustment)
kevin1990 16:e4f2689363bb 1925 {
kevin1990 16:e4f2689363bb 1926 /* Replace with default values if NaNs are specified (or 0.0 for gain) */
kevin1990 16:e4f2689363bb 1927 if (isnan(fGainAdjustment) || (fGainAdjustment == 0.0))
kevin1990 16:e4f2689363bb 1928 fGainAdjustment = 1.0;
kevin1990 16:e4f2689363bb 1929 if (isnan(fOffsetAdjustment))
kevin1990 16:e4f2689363bb 1930 fOffsetAdjustment = 0.0;
kevin1990 16:e4f2689363bb 1931
kevin1990 16:e4f2689363bb 1932 WRITE_REG_FLOAT(hDevice, fGainAdjustment, CORE_SENSOR_GAINn(eChannelId));
kevin1990 16:e4f2689363bb 1933 WRITE_REG_FLOAT(hDevice, fOffsetAdjustment, CORE_SENSOR_OFFSETn(eChannelId));
kevin1990 16:e4f2689363bb 1934
kevin1990 16:e4f2689363bb 1935 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1936 }
kevin1990 16:e4f2689363bb 1937
kevin1990 16:e4f2689363bb 1938 ADI_SENSE_RESULT adi_sense_1000_SetChannelSettlingTime(
kevin1990 16:e4f2689363bb 1939 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1940 ADI_SENSE_1000_CHANNEL_ID eChannelId,
kevin1990 16:e4f2689363bb 1941 uint32_t nSettlingTime)
kevin1990 16:e4f2689363bb 1942 {
kevin1990 16:e4f2689363bb 1943 CHECK_REG_FIELD_VAL(CORE_SETTLING_TIME_SETTLING_TIME, nSettlingTime);
kevin1990 16:e4f2689363bb 1944
kevin1990 16:e4f2689363bb 1945 WRITE_REG_U16(hDevice, nSettlingTime, CORE_SETTLING_TIMEn(eChannelId));
kevin1990 16:e4f2689363bb 1946
kevin1990 16:e4f2689363bb 1947 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 1948 }
kevin1990 16:e4f2689363bb 1949
kevin1990 16:e4f2689363bb 1950 ADI_SENSE_RESULT adi_sense_1000_SetChannelConfig(
kevin1990 16:e4f2689363bb 1951 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 1952 ADI_SENSE_1000_CHANNEL_ID eChannelId,
kevin1990 16:e4f2689363bb 1953 ADI_SENSE_1000_CHANNEL_CONFIG *pChannelConfig)
kevin1990 16:e4f2689363bb 1954 {
kevin1990 16:e4f2689363bb 1955 ADI_SENSE_RESULT eRet;
kevin1990 16:e4f2689363bb 1956
kevin1990 16:e4f2689363bb 1957 if (! ADI_SENSE_1000_CHANNEL_IS_VIRTUAL(eChannelId))
kevin1990 16:e4f2689363bb 1958 {
kevin1990 16:e4f2689363bb 1959 /* If the channel is not enabled, disable it and return */
kevin1990 16:e4f2689363bb 1960 if (! pChannelConfig->enableChannel)
kevin1990 16:e4f2689363bb 1961 return adi_sense_1000_SetChannelCount(hDevice, eChannelId, 0);
kevin1990 16:e4f2689363bb 1962
kevin1990 16:e4f2689363bb 1963 eRet = adi_sense_1000_SetChannelCount(hDevice, eChannelId,
kevin1990 16:e4f2689363bb 1964 pChannelConfig->measurementsPerCycle);
kevin1990 16:e4f2689363bb 1965 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 1966 {
kevin1990 16:e4f2689363bb 1967 ADI_SENSE_LOG_ERROR("Failed to set measurement count for channel %d",
kevin1990 16:e4f2689363bb 1968 eChannelId);
kevin1990 16:e4f2689363bb 1969 return eRet;
kevin1990 16:e4f2689363bb 1970 }
kevin1990 16:e4f2689363bb 1971
kevin1990 16:e4f2689363bb 1972 switch (eChannelId)
kevin1990 16:e4f2689363bb 1973 {
kevin1990 16:e4f2689363bb 1974 case ADI_SENSE_1000_CHANNEL_ID_CJC_0:
kevin1990 16:e4f2689363bb 1975 case ADI_SENSE_1000_CHANNEL_ID_CJC_1:
kevin1990 16:e4f2689363bb 1976 case ADI_SENSE_1000_CHANNEL_ID_SENSOR_0:
kevin1990 16:e4f2689363bb 1977 case ADI_SENSE_1000_CHANNEL_ID_SENSOR_1:
kevin1990 16:e4f2689363bb 1978 case ADI_SENSE_1000_CHANNEL_ID_SENSOR_2:
kevin1990 16:e4f2689363bb 1979 case ADI_SENSE_1000_CHANNEL_ID_SENSOR_3:
kevin1990 16:e4f2689363bb 1980 case ADI_SENSE_1000_CHANNEL_ID_VOLTAGE_0:
kevin1990 16:e4f2689363bb 1981 case ADI_SENSE_1000_CHANNEL_ID_CURRENT_0:
kevin1990 16:e4f2689363bb 1982 eRet = adi_sense_SetAdcChannelConfig(hDevice, eChannelId, pChannelConfig);
kevin1990 16:e4f2689363bb 1983 break;
kevin1990 16:e4f2689363bb 1984 case ADI_SENSE_1000_CHANNEL_ID_I2C_0:
kevin1990 16:e4f2689363bb 1985 case ADI_SENSE_1000_CHANNEL_ID_I2C_1:
kevin1990 16:e4f2689363bb 1986 eRet = adi_sense_SetI2cChannelConfig(hDevice, eChannelId,
kevin1990 16:e4f2689363bb 1987 &pChannelConfig->i2cChannelConfig);
kevin1990 16:e4f2689363bb 1988 break;
kevin1990 16:e4f2689363bb 1989 case ADI_SENSE_1000_CHANNEL_ID_SPI_0:
kevin1990 16:e4f2689363bb 1990 eRet = adi_sense_SetSpiChannelConfig(hDevice, eChannelId,
kevin1990 16:e4f2689363bb 1991 &pChannelConfig->spiChannelConfig);
kevin1990 16:e4f2689363bb 1992 break;
kevin1990 16:e4f2689363bb 1993 default:
kevin1990 16:e4f2689363bb 1994 ADI_SENSE_LOG_ERROR("Invalid channel ID %d specified", eChannelId);
kevin1990 16:e4f2689363bb 1995 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 1996 }
kevin1990 16:e4f2689363bb 1997
kevin1990 16:e4f2689363bb 1998 eRet = adi_sense_1000_SetChannelSettlingTime(hDevice, eChannelId,
kevin1990 16:e4f2689363bb 1999 pChannelConfig->extraSettlingTime);
kevin1990 16:e4f2689363bb 2000 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 2001 {
kevin1990 16:e4f2689363bb 2002 ADI_SENSE_LOG_ERROR("Failed to set settling time for channel %d",
kevin1990 16:e4f2689363bb 2003 eChannelId);
kevin1990 16:e4f2689363bb 2004 return eRet;
kevin1990 16:e4f2689363bb 2005 }
kevin1990 16:e4f2689363bb 2006 }
kevin1990 16:e4f2689363bb 2007
kevin1990 16:e4f2689363bb 2008 if (pChannelConfig->enableChannel)
kevin1990 16:e4f2689363bb 2009 {
kevin1990 16:e4f2689363bb 2010 /* Threshold limits can be configured individually for virtual channels */
kevin1990 16:e4f2689363bb 2011 eRet = adi_sense_1000_SetChannelThresholdLimits(hDevice, eChannelId,
kevin1990 16:e4f2689363bb 2012 pChannelConfig->highThreshold,
kevin1990 16:e4f2689363bb 2013 pChannelConfig->lowThreshold);
kevin1990 16:e4f2689363bb 2014 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 2015 {
kevin1990 16:e4f2689363bb 2016 ADI_SENSE_LOG_ERROR("Failed to set threshold limits for channel %d",
kevin1990 16:e4f2689363bb 2017 eChannelId);
kevin1990 16:e4f2689363bb 2018 return eRet;
kevin1990 16:e4f2689363bb 2019 }
kevin1990 16:e4f2689363bb 2020
kevin1990 16:e4f2689363bb 2021 /* Offset and gain can be configured individually for virtual channels */
kevin1990 16:e4f2689363bb 2022 eRet = adi_sense_1000_SetOffsetGain(hDevice, eChannelId,
kevin1990 16:e4f2689363bb 2023 pChannelConfig->offsetAdjustment,
kevin1990 16:e4f2689363bb 2024 pChannelConfig->gainAdjustment);
kevin1990 16:e4f2689363bb 2025 if (eRet != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 2026 {
kevin1990 16:e4f2689363bb 2027 ADI_SENSE_LOG_ERROR("Failed to set offset/gain for channel %d",
kevin1990 16:e4f2689363bb 2028 eChannelId);
kevin1990 16:e4f2689363bb 2029 return eRet;
kevin1990 16:e4f2689363bb 2030 }
kevin1990 16:e4f2689363bb 2031 }
kevin1990 16:e4f2689363bb 2032
kevin1990 16:e4f2689363bb 2033 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 2034 }
kevin1990 16:e4f2689363bb 2035
kevin1990 16:e4f2689363bb 2036 ADI_SENSE_RESULT adi_sense_SetConfig(
kevin1990 16:e4f2689363bb 2037 ADI_SENSE_DEVICE_HANDLE const hDevice,
kevin1990 16:e4f2689363bb 2038 ADI_SENSE_CONFIG * const pConfig)
kevin1990 16:e4f2689363bb 2039 {
kevin1990 16:e4f2689363bb 2040 ADI_SENSE_1000_CONFIG *pDeviceConfig;
kevin1990 16:e4f2689363bb 2041 ADI_SENSE_PRODUCT_ID productId;
kevin1990 16:e4f2689363bb 2042 ADI_SENSE_RESULT eRet;
kevin1990 16:e4f2689363bb 2043
kevin1990 16:e4f2689363bb 2044 if (pConfig->productId != ADI_SENSE_PRODUCT_ID_1000)
kevin1990 16:e4f2689363bb 2045 {
kevin1990 16:e4f2689363bb 2046 ADI_SENSE_LOG_ERROR("Configuration Product ID (0x%X) is not supported (0x%0X)",
kevin1990 16:e4f2689363bb 2047 pConfig->productId, ADI_SENSE_PRODUCT_ID_1000);
kevin1990 16:e4f2689363bb 2048 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 2049 }
kevin1990 16:e4f2689363bb 2050
kevin1990 16:e4f2689363bb 2051 /* Check that the actual Product ID is a match? */
kevin1990 16:e4f2689363bb 2052 eRet = adi_sense_GetProductID(hDevice, &productId);
kevin1990 16:e4f2689363bb 2053 if (eRet)
kevin1990 16:e4f2689363bb 2054 {
kevin1990 16:e4f2689363bb 2055 ADI_SENSE_LOG_ERROR("Failed to read device Product ID register");
kevin1990 16:e4f2689363bb 2056 return eRet;
kevin1990 16:e4f2689363bb 2057 }
kevin1990 16:e4f2689363bb 2058 if (pConfig->productId != productId)
kevin1990 16:e4f2689363bb 2059 {
kevin1990 16:e4f2689363bb 2060 ADI_SENSE_LOG_ERROR("Configuration Product ID (0x%X) does not match device (0x%0X)",
kevin1990 16:e4f2689363bb 2061 pConfig->productId, productId);
kevin1990 16:e4f2689363bb 2062 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 2063 }
kevin1990 16:e4f2689363bb 2064
kevin1990 16:e4f2689363bb 2065 pDeviceConfig = &pConfig->adisense1000;
kevin1990 16:e4f2689363bb 2066
kevin1990 16:e4f2689363bb 2067 eRet = adi_sense_1000_SetPowerConfig(hDevice, &pDeviceConfig->power);
kevin1990 16:e4f2689363bb 2068 if (eRet)
kevin1990 16:e4f2689363bb 2069 {
kevin1990 16:e4f2689363bb 2070 ADI_SENSE_LOG_ERROR("Failed to set power configuration");
kevin1990 16:e4f2689363bb 2071 return eRet;
kevin1990 16:e4f2689363bb 2072 }
kevin1990 16:e4f2689363bb 2073
kevin1990 16:e4f2689363bb 2074 eRet = adi_sense_1000_SetMeasurementConfig(hDevice, &pDeviceConfig->measurement);
kevin1990 16:e4f2689363bb 2075 if (eRet)
kevin1990 16:e4f2689363bb 2076 {
kevin1990 16:e4f2689363bb 2077 ADI_SENSE_LOG_ERROR("Failed to set measurement configuration");
kevin1990 16:e4f2689363bb 2078 return eRet;
kevin1990 16:e4f2689363bb 2079 }
kevin1990 16:e4f2689363bb 2080
kevin1990 16:e4f2689363bb 2081 eRet = adi_sense_1000_SetDiagnosticsConfig(hDevice, &pDeviceConfig->diagnostics);
kevin1990 16:e4f2689363bb 2082 if (eRet)
kevin1990 16:e4f2689363bb 2083 {
kevin1990 16:e4f2689363bb 2084 ADI_SENSE_LOG_ERROR("Failed to set diagnostics configuration");
kevin1990 16:e4f2689363bb 2085 return eRet;
kevin1990 16:e4f2689363bb 2086 }
kevin1990 16:e4f2689363bb 2087
kevin1990 16:e4f2689363bb 2088 for (ADI_SENSE_1000_CHANNEL_ID id = 0; id < ADI_SENSE_1000_MAX_CHANNELS; id++)
kevin1990 16:e4f2689363bb 2089 {
kevin1990 16:e4f2689363bb 2090 eRet = adi_sense_1000_SetChannelConfig(hDevice, id,
kevin1990 16:e4f2689363bb 2091 &pDeviceConfig->channels[id]);
kevin1990 16:e4f2689363bb 2092 if (eRet)
kevin1990 16:e4f2689363bb 2093 {
kevin1990 16:e4f2689363bb 2094 ADI_SENSE_LOG_ERROR("Failed to set channel %d configuration", id);
kevin1990 16:e4f2689363bb 2095 return eRet;
kevin1990 16:e4f2689363bb 2096 }
kevin1990 16:e4f2689363bb 2097 }
kevin1990 16:e4f2689363bb 2098
kevin1990 16:e4f2689363bb 2099 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 2100 }
kevin1990 16:e4f2689363bb 2101
kevin1990 16:e4f2689363bb 2102 ADI_SENSE_RESULT adi_sense_1000_SetLutData(
kevin1990 16:e4f2689363bb 2103 ADI_SENSE_DEVICE_HANDLE const hDevice,
kevin1990 16:e4f2689363bb 2104 ADI_SENSE_1000_LUT * const pLutData)
kevin1990 16:e4f2689363bb 2105 {
kevin1990 16:e4f2689363bb 2106 ADI_SENSE_1000_LUT_HEADER *pLutHeader = &pLutData->header;
kevin1990 16:e4f2689363bb 2107 ADI_SENSE_1000_LUT_TABLE *pLutTable = pLutData->tables;
kevin1990 16:e4f2689363bb 2108 unsigned actualLength = 0;
kevin1990 16:e4f2689363bb 2109
kevin1990 16:e4f2689363bb 2110 if (pLutData->header.signature != ADI_SENSE_LUT_SIGNATURE)
kevin1990 16:e4f2689363bb 2111 {
kevin1990 16:e4f2689363bb 2112 ADI_SENSE_LOG_ERROR("LUT signature incorrect (expected 0x%X, actual 0x%X)",
kevin1990 16:e4f2689363bb 2113 ADI_SENSE_LUT_SIGNATURE, pLutHeader->signature);
kevin1990 16:e4f2689363bb 2114 return ADI_SENSE_INVALID_SIGNATURE;
kevin1990 16:e4f2689363bb 2115 }
kevin1990 16:e4f2689363bb 2116
kevin1990 16:e4f2689363bb 2117 for (unsigned i = 0; i < pLutHeader->numTables; i++)
kevin1990 16:e4f2689363bb 2118 {
kevin1990 16:e4f2689363bb 2119 ADI_SENSE_1000_LUT_DESCRIPTOR *pDesc = &pLutTable->descriptor;
kevin1990 16:e4f2689363bb 2120 ADI_SENSE_1000_LUT_TABLE_DATA *pData = &pLutTable->data;
kevin1990 16:e4f2689363bb 2121 unsigned short calculatedCrc;
kevin1990 16:e4f2689363bb 2122
kevin1990 16:e4f2689363bb 2123 switch (pDesc->geometry)
kevin1990 16:e4f2689363bb 2124 {
kevin1990 16:e4f2689363bb 2125 case ADI_SENSE_1000_LUT_GEOMETRY_COEFFS:
kevin1990 16:e4f2689363bb 2126 switch (pDesc->equation)
kevin1990 16:e4f2689363bb 2127 {
kevin1990 16:e4f2689363bb 2128 case ADI_SENSE_1000_LUT_EQUATION_POLYN:
kevin1990 16:e4f2689363bb 2129 case ADI_SENSE_1000_LUT_EQUATION_POLYNEXP:
kevin1990 16:e4f2689363bb 2130 case ADI_SENSE_1000_LUT_EQUATION_QUADRATIC:
kevin1990 16:e4f2689363bb 2131 case ADI_SENSE_1000_LUT_EQUATION_STEINHART:
kevin1990 16:e4f2689363bb 2132 case ADI_SENSE_1000_LUT_EQUATION_LOGARITHMIC:
kevin1990 16:e4f2689363bb 2133 case ADI_SENSE_1000_LUT_EQUATION_EXPONENTIAL:
kevin1990 16:e4f2689363bb 2134 case ADI_SENSE_1000_LUT_EQUATION_BIVARIATE_POLYN:
kevin1990 16:e4f2689363bb 2135 break;
kevin1990 16:e4f2689363bb 2136 default:
kevin1990 16:e4f2689363bb 2137 ADI_SENSE_LOG_ERROR("Invalid equation %u specified for LUT table %u",
kevin1990 16:e4f2689363bb 2138 pDesc->equation, i);
kevin1990 16:e4f2689363bb 2139 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 2140 }
kevin1990 16:e4f2689363bb 2141 break;
kevin1990 16:e4f2689363bb 2142 case ADI_SENSE_1000_LUT_GEOMETRY_NES_1D:
kevin1990 16:e4f2689363bb 2143 case ADI_SENSE_1000_LUT_GEOMETRY_NES_2D:
kevin1990 16:e4f2689363bb 2144 case ADI_SENSE_1000_LUT_GEOMETRY_ES_1D:
kevin1990 16:e4f2689363bb 2145 case ADI_SENSE_1000_LUT_GEOMETRY_ES_2D:
kevin1990 16:e4f2689363bb 2146 if (pDesc->equation != ADI_SENSE_1000_LUT_EQUATION_LUT) {
kevin1990 16:e4f2689363bb 2147 ADI_SENSE_LOG_ERROR("Invalid equation %u specified for LUT table %u",
kevin1990 16:e4f2689363bb 2148 pDesc->equation, i);
kevin1990 16:e4f2689363bb 2149 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 2150 }
kevin1990 16:e4f2689363bb 2151 break;
kevin1990 16:e4f2689363bb 2152 default:
kevin1990 16:e4f2689363bb 2153 ADI_SENSE_LOG_ERROR("Invalid geometry %u specified for LUT table %u",
kevin1990 16:e4f2689363bb 2154 pDesc->geometry, i);
kevin1990 16:e4f2689363bb 2155 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 2156 }
kevin1990 16:e4f2689363bb 2157
kevin1990 16:e4f2689363bb 2158 switch (pDesc->dataType)
kevin1990 16:e4f2689363bb 2159 {
kevin1990 16:e4f2689363bb 2160 case ADI_SENSE_1000_LUT_DATA_TYPE_FLOAT32:
kevin1990 16:e4f2689363bb 2161 case ADI_SENSE_1000_LUT_DATA_TYPE_FLOAT64:
kevin1990 16:e4f2689363bb 2162 break;
kevin1990 16:e4f2689363bb 2163 default:
kevin1990 16:e4f2689363bb 2164 ADI_SENSE_LOG_ERROR("Invalid vector format %u specified for LUT table %u",
kevin1990 16:e4f2689363bb 2165 pDesc->dataType, i);
kevin1990 16:e4f2689363bb 2166 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 2167 }
kevin1990 16:e4f2689363bb 2168
kevin1990 16:e4f2689363bb 2169 calculatedCrc = crc16_ccitt(pData, pDesc->length);
kevin1990 16:e4f2689363bb 2170 if (calculatedCrc != pDesc->crc16)
kevin1990 16:e4f2689363bb 2171 {
kevin1990 16:e4f2689363bb 2172 ADI_SENSE_LOG_ERROR("CRC validation failed on LUT table %u (expected 0x%04X, actual 0x%04X)",
kevin1990 16:e4f2689363bb 2173 i, pDesc->crc16, calculatedCrc);
kevin1990 16:e4f2689363bb 2174 return ADI_SENSE_CRC_ERROR;
kevin1990 16:e4f2689363bb 2175 }
kevin1990 16:e4f2689363bb 2176
kevin1990 16:e4f2689363bb 2177 actualLength += sizeof(*pDesc) + pDesc->length;
kevin1990 16:e4f2689363bb 2178
kevin1990 16:e4f2689363bb 2179 /* Move to the next look-up table */
kevin1990 16:e4f2689363bb 2180 pLutTable = (ADI_SENSE_1000_LUT_TABLE *)((uint8_t *)pLutTable + sizeof(*pDesc) + pDesc->length);
kevin1990 16:e4f2689363bb 2181 }
kevin1990 16:e4f2689363bb 2182
kevin1990 16:e4f2689363bb 2183 if (actualLength != pLutHeader->totalLength)
kevin1990 16:e4f2689363bb 2184 {
kevin1990 16:e4f2689363bb 2185 ADI_SENSE_LOG_ERROR("LUT table length mismatch (expected %u, actual %u)",
kevin1990 16:e4f2689363bb 2186 pLutHeader->totalLength, actualLength);
kevin1990 16:e4f2689363bb 2187 return ADI_SENSE_WRONG_SIZE;
kevin1990 16:e4f2689363bb 2188 }
kevin1990 16:e4f2689363bb 2189
kevin1990 16:e4f2689363bb 2190 if (sizeof(*pLutHeader) + pLutHeader->totalLength > ADI_SENSE_LUT_MAX_SIZE)
kevin1990 16:e4f2689363bb 2191 {
kevin1990 16:e4f2689363bb 2192 ADI_SENSE_LOG_ERROR("Maximum LUT table length (%u bytes) exceeded",
kevin1990 16:e4f2689363bb 2193 ADI_SENSE_LUT_MAX_SIZE);
kevin1990 16:e4f2689363bb 2194 return ADI_SENSE_WRONG_SIZE;
kevin1990 16:e4f2689363bb 2195 }
kevin1990 16:e4f2689363bb 2196
kevin1990 16:e4f2689363bb 2197 /* Write the LUT data to the device */
kevin1990 16:e4f2689363bb 2198 unsigned lutSize = sizeof(*pLutHeader) + pLutHeader->totalLength;
kevin1990 16:e4f2689363bb 2199 WRITE_REG_U16(hDevice, 0, CORE_LUT_OFFSET);
kevin1990 16:e4f2689363bb 2200 WRITE_REG_U8_ARRAY(hDevice, (uint8_t *)pLutData, lutSize, CORE_LUT_DATA);
kevin1990 16:e4f2689363bb 2201
kevin1990 16:e4f2689363bb 2202 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 2203 }
kevin1990 16:e4f2689363bb 2204
kevin1990 16:e4f2689363bb 2205 ADI_SENSE_RESULT adi_sense_1000_SetLutDataRaw(
kevin1990 16:e4f2689363bb 2206 ADI_SENSE_DEVICE_HANDLE const hDevice,
kevin1990 16:e4f2689363bb 2207 ADI_SENSE_1000_LUT_RAW * const pLutData)
kevin1990 16:e4f2689363bb 2208 {
kevin1990 16:e4f2689363bb 2209 return adi_sense_1000_SetLutData(hDevice,
kevin1990 16:e4f2689363bb 2210 (ADI_SENSE_1000_LUT * const)pLutData);
kevin1990 16:e4f2689363bb 2211 }
kevin1990 16:e4f2689363bb 2212
kevin1990 16:e4f2689363bb 2213 static ADI_SENSE_RESULT getLutTableSize(
kevin1990 16:e4f2689363bb 2214 ADI_SENSE_1000_LUT_DESCRIPTOR * const pDesc,
kevin1990 16:e4f2689363bb 2215 ADI_SENSE_1000_LUT_TABLE_DATA * const pData,
kevin1990 16:e4f2689363bb 2216 unsigned *pLength)
kevin1990 16:e4f2689363bb 2217 {
kevin1990 16:e4f2689363bb 2218 switch (pDesc->geometry)
kevin1990 16:e4f2689363bb 2219 {
kevin1990 16:e4f2689363bb 2220 case ADI_SENSE_1000_LUT_GEOMETRY_COEFFS:
kevin1990 16:e4f2689363bb 2221 if (pDesc->equation == ADI_SENSE_1000_LUT_EQUATION_BIVARIATE_POLYN)
kevin1990 16:e4f2689363bb 2222 *pLength = ADI_SENSE_1000_LUT_2D_POLYN_COEFF_LIST_SIZE(pData->coeffList2d);
kevin1990 16:e4f2689363bb 2223 else
kevin1990 16:e4f2689363bb 2224 *pLength = ADI_SENSE_1000_LUT_COEFF_LIST_SIZE(pData->coeffList);
kevin1990 16:e4f2689363bb 2225 break;
kevin1990 16:e4f2689363bb 2226 case ADI_SENSE_1000_LUT_GEOMETRY_NES_1D:
kevin1990 16:e4f2689363bb 2227 *pLength = ADI_SENSE_1000_LUT_1D_NES_SIZE(pData->lut1dNes);
kevin1990 16:e4f2689363bb 2228 break;
kevin1990 16:e4f2689363bb 2229 case ADI_SENSE_1000_LUT_GEOMETRY_NES_2D:
kevin1990 16:e4f2689363bb 2230 *pLength = ADI_SENSE_1000_LUT_2D_NES_SIZE(pData->lut2dNes);
kevin1990 16:e4f2689363bb 2231 break;
kevin1990 16:e4f2689363bb 2232 case ADI_SENSE_1000_LUT_GEOMETRY_ES_1D:
kevin1990 16:e4f2689363bb 2233 *pLength = ADI_SENSE_1000_LUT_1D_ES_SIZE(pData->lut1dEs);
kevin1990 16:e4f2689363bb 2234 break;
kevin1990 16:e4f2689363bb 2235 case ADI_SENSE_1000_LUT_GEOMETRY_ES_2D:
kevin1990 16:e4f2689363bb 2236 *pLength = ADI_SENSE_1000_LUT_2D_ES_SIZE(pData->lut2dEs);
kevin1990 16:e4f2689363bb 2237 break;
kevin1990 16:e4f2689363bb 2238 default:
kevin1990 16:e4f2689363bb 2239 ADI_SENSE_LOG_ERROR("Invalid LUT table geometry %d specified\r\n",
kevin1990 16:e4f2689363bb 2240 pDesc->geometry);
kevin1990 16:e4f2689363bb 2241 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 2242 }
kevin1990 16:e4f2689363bb 2243
kevin1990 16:e4f2689363bb 2244 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 2245 }
kevin1990 16:e4f2689363bb 2246
kevin1990 16:e4f2689363bb 2247 ADI_SENSE_RESULT adi_sense_1000_AssembleLutData(
kevin1990 16:e4f2689363bb 2248 ADI_SENSE_1000_LUT * pLutBuffer,
kevin1990 16:e4f2689363bb 2249 unsigned nLutBufferSize,
kevin1990 16:e4f2689363bb 2250 unsigned const nNumTables,
kevin1990 16:e4f2689363bb 2251 ADI_SENSE_1000_LUT_DESCRIPTOR * const ppDesc[],
kevin1990 16:e4f2689363bb 2252 ADI_SENSE_1000_LUT_TABLE_DATA * const ppData[])
kevin1990 16:e4f2689363bb 2253 {
kevin1990 16:e4f2689363bb 2254 ADI_SENSE_1000_LUT_HEADER *pHdr = &pLutBuffer->header;
kevin1990 16:e4f2689363bb 2255 uint8_t *pLutTableData = (uint8_t *)pLutBuffer + sizeof(*pHdr);
kevin1990 16:e4f2689363bb 2256
kevin1990 16:e4f2689363bb 2257 if (sizeof(*pHdr) > nLutBufferSize)
kevin1990 16:e4f2689363bb 2258 {
kevin1990 16:e4f2689363bb 2259 ADI_SENSE_LOG_ERROR("Insufficient LUT buffer size provided");
kevin1990 16:e4f2689363bb 2260 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 2261 }
kevin1990 16:e4f2689363bb 2262
kevin1990 16:e4f2689363bb 2263 /* First initialise the top-level header */
kevin1990 16:e4f2689363bb 2264 pHdr->signature = ADI_SENSE_LUT_SIGNATURE;
kevin1990 16:e4f2689363bb 2265 pHdr->version.major = 1;
kevin1990 16:e4f2689363bb 2266 pHdr->version.minor = 0;
kevin1990 16:e4f2689363bb 2267 pHdr->numTables = 0;
kevin1990 16:e4f2689363bb 2268 pHdr->totalLength = 0;
kevin1990 16:e4f2689363bb 2269
kevin1990 16:e4f2689363bb 2270 /*
kevin1990 16:e4f2689363bb 2271 * Walk through the list of table pointers provided, appending the table
kevin1990 16:e4f2689363bb 2272 * descriptor+data from each one to the provided LUT buffer
kevin1990 16:e4f2689363bb 2273 */
kevin1990 16:e4f2689363bb 2274 for (unsigned i = 0; i < nNumTables; i++)
kevin1990 16:e4f2689363bb 2275 {
kevin1990 16:e4f2689363bb 2276 ADI_SENSE_1000_LUT_DESCRIPTOR * const pDesc = ppDesc[i];
kevin1990 16:e4f2689363bb 2277 ADI_SENSE_1000_LUT_TABLE_DATA * const pData = ppData[i];
kevin1990 16:e4f2689363bb 2278 ADI_SENSE_RESULT res;
kevin1990 16:e4f2689363bb 2279 unsigned dataLength = 0;
kevin1990 16:e4f2689363bb 2280
kevin1990 16:e4f2689363bb 2281 /* Calculate the length of the table data */
kevin1990 16:e4f2689363bb 2282 res = getLutTableSize(pDesc, pData, &dataLength);
kevin1990 16:e4f2689363bb 2283 if (res != ADI_SENSE_SUCCESS)
kevin1990 16:e4f2689363bb 2284 return res;
kevin1990 16:e4f2689363bb 2285
kevin1990 16:e4f2689363bb 2286 /* Fill in the table descriptor length and CRC fields */
kevin1990 16:e4f2689363bb 2287 pDesc->length = dataLength;
kevin1990 16:e4f2689363bb 2288 pDesc->crc16 = crc16_ccitt(pData, dataLength);
kevin1990 16:e4f2689363bb 2289
kevin1990 16:e4f2689363bb 2290 if ((sizeof(*pHdr) + pHdr->totalLength + sizeof(*pDesc) + dataLength) > nLutBufferSize)
kevin1990 16:e4f2689363bb 2291 {
kevin1990 16:e4f2689363bb 2292 ADI_SENSE_LOG_ERROR("Insufficient LUT buffer size provided");
kevin1990 16:e4f2689363bb 2293 return ADI_SENSE_INVALID_PARAM;
kevin1990 16:e4f2689363bb 2294 }
kevin1990 16:e4f2689363bb 2295
kevin1990 16:e4f2689363bb 2296 /* Append the table to the LUT buffer (desc + data) */
kevin1990 16:e4f2689363bb 2297 memcpy(pLutTableData + pHdr->totalLength, pDesc, sizeof(*pDesc));
kevin1990 16:e4f2689363bb 2298 pHdr->totalLength += sizeof(*pDesc);
kevin1990 16:e4f2689363bb 2299 memcpy(pLutTableData + pHdr->totalLength, pData, dataLength);
kevin1990 16:e4f2689363bb 2300 pHdr->totalLength += dataLength;
kevin1990 16:e4f2689363bb 2301
kevin1990 16:e4f2689363bb 2302 pHdr->numTables++;
kevin1990 16:e4f2689363bb 2303 }
kevin1990 16:e4f2689363bb 2304
kevin1990 16:e4f2689363bb 2305 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 2306 }
kevin1990 16:e4f2689363bb 2307
kevin1990 16:e4f2689363bb 2308 #define CAL_TABLE_ROWS ADI_SENSE_1000_CAL_NUM_TABLES
kevin1990 16:e4f2689363bb 2309 #define CAL_TABLE_COLS ADI_SENSE_1000_CAL_NUM_TEMPS
kevin1990 16:e4f2689363bb 2310 #define CAL_TABLE_SIZE (sizeof(float) * CAL_TABLE_ROWS * CAL_TABLE_COLS)
kevin1990 16:e4f2689363bb 2311
kevin1990 16:e4f2689363bb 2312 ADI_SENSE_RESULT adi_sense_1000_ReadCalTable(
kevin1990 16:e4f2689363bb 2313 ADI_SENSE_DEVICE_HANDLE hDevice,
kevin1990 16:e4f2689363bb 2314 float *pfBuffer,
kevin1990 16:e4f2689363bb 2315 unsigned nMaxLen,
kevin1990 16:e4f2689363bb 2316 unsigned *pnDataLen,
kevin1990 16:e4f2689363bb 2317 unsigned *pnRows,
kevin1990 16:e4f2689363bb 2318 unsigned *pnColumns)
kevin1990 16:e4f2689363bb 2319 {
kevin1990 16:e4f2689363bb 2320 *pnDataLen = sizeof(float) * CAL_TABLE_ROWS * CAL_TABLE_COLS;
kevin1990 16:e4f2689363bb 2321 *pnRows = CAL_TABLE_ROWS;
kevin1990 16:e4f2689363bb 2322 *pnColumns = CAL_TABLE_COLS;
kevin1990 16:e4f2689363bb 2323
kevin1990 16:e4f2689363bb 2324 if (nMaxLen > *pnDataLen)
kevin1990 16:e4f2689363bb 2325 nMaxLen = *pnDataLen;
kevin1990 16:e4f2689363bb 2326
kevin1990 16:e4f2689363bb 2327 WRITE_REG_U16(hDevice, 0, CORE_CAL_OFFSET);
kevin1990 16:e4f2689363bb 2328 READ_REG_U8_ARRAY(hDevice, (uint8_t *)pfBuffer, nMaxLen, CORE_CAL_DATA);
kevin1990 16:e4f2689363bb 2329
kevin1990 16:e4f2689363bb 2330 return ADI_SENSE_SUCCESS;
kevin1990 16:e4f2689363bb 2331 }
kevin1990 16:e4f2689363bb 2332