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