Vybhav Kadaba
/
EV-PRO-MW1001_Development_updateFW
Bumped Mbed FW version to 01.20.0080
Embed:
(wiki syntax)
Show/hide line numbers
admw_1001.c
Go to the documentation of this file.
00001 /* 00002 Copyright 2019 (c) Analog Devices, Inc. 00003 00004 All rights reserved. 00005 00006 Redistribution and use in source and binary forms, with or without 00007 modification, are permitted provided that the following conditions are met: 00008 - Redistributions of source code must retain the above copyright 00009 notice, this list of conditions and the following disclaimer. 00010 - Redistributions in binary form must reproduce the above copyright 00011 notice, this list of conditions and the following disclaimer in 00012 the documentation and/or other materials provided with the 00013 distribution. 00014 - Neither the name of Analog Devices, Inc. nor the names of its 00015 contributors may be used to endorse or promote products derived 00016 from this software without specific prior written permission. 00017 - The use of this software may or may not infringe the patent rights 00018 of one or more patent holders. This license does not release you 00019 from the requirement that you obtain separate licenses from these 00020 patent holders to use this software. 00021 - Use of the software either in source or binary form, must be run 00022 on or directly connected to an Analog Devices Inc. component. 00023 00024 THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR 00025 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, 00026 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00027 IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, 00028 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00029 LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR 00030 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00031 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00032 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00033 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 */ 00035 00036 /*! 00037 ****************************************************************************** 00038 * @file: 00039 * @brief: API implementation for ADMW1001 00040 *----------------------------------------------------------------------------- 00041 */ 00042 00043 #include <float.h> 00044 #include <math.h> 00045 #include <string.h> 00046 00047 #include "admw_platform.h" 00048 #include "admw_api.h" 00049 #include "admw1001/admw1001_api.h" 00050 00051 #include "admw1001/ADMW1001_REGISTERS_typedefs.h" 00052 #include "admw1001/ADMW1001_REGISTERS.h" 00053 #include "admw1001/admw1001_lut_data.h" 00054 #include "admw1001/admw1001_host_comms.h" 00055 #include "inc/mbedVersion.h" 00056 #define VERSIONID_MAJOR 2 00057 #define VERSIONID_MINOR 0 00058 00059 uint32_t getDataCnt = 0; 00060 #define ADMW_VERSION_REG_VAL_SIZE 4u 00061 #define ADMW_FORMATTED_VERSION_SIZE 11u 00062 00063 #define ADMW_SFL_READ_STATUS_SIZE 42u 00064 /* 00065 * The following macros are used to encapsulate the register access code 00066 * to improve readability in the functions further below in this file 00067 */ 00068 #define STRINGIFY(name) #name 00069 00070 /* Expand the full name of the reset value macro for the specified register */ 00071 #define REG_RESET_VAL(_name) REG_##_name##_RESET 00072 00073 /* Checks if a value is outside the bounds of the specified register field */ 00074 #define CHECK_REG_FIELD_VAL(_field, _val) \ 00075 do { \ 00076 uint32_t _mask = BITM_##_field; \ 00077 uint32_t _shift = BITP_##_field; \ 00078 if ((((_val) << _shift) & ~(_mask)) != 0) { \ 00079 ADMW_LOG_ERROR("Value 0x%08X invalid for register field %s",\ 00080 (uint32_t)(_val), \ 00081 STRINGIFY(ADMW_##_field)); \ 00082 return ADMW_INVALID_PARAM; \ 00083 } \ 00084 } while(false) 00085 00086 /* 00087 * Encapsulates the write to a specified register 00088 * NOTE - this will cause the calling function to return on error 00089 */ 00090 #define WRITE_REG(_hdev, _val, _name, _type) \ 00091 do { \ 00092 ADMW_RESULT _res; \ 00093 _type _regval = _val; \ 00094 _res = admw1001_WriteRegister((_hdev), \ 00095 REG_##_name, \ 00096 &_regval, sizeof(_regval)); \ 00097 if (_res != ADMW_SUCCESS) \ 00098 return _res; \ 00099 } while(false) 00100 00101 /* Wrapper macro to write a value to a uint32_t register */ 00102 #define WRITE_REG_U32(_hdev, _val, _name) \ 00103 WRITE_REG(_hdev, _val, _name, uint32_t) 00104 /* Wrapper macro to write a value to a uint16_t register */ 00105 #define WRITE_REG_U16(_hdev, _val, _name) \ 00106 WRITE_REG(_hdev, _val, _name, uint16_t) 00107 /* Wrapper macro to write a value to a uint8_t register */ 00108 #define WRITE_REG_U8(_hdev, _val, _name) \ 00109 WRITE_REG(_hdev, _val, _name, uint8_t) 00110 /* Wrapper macro to write a value to a float32_t register */ 00111 #define WRITE_REG_FLOAT(_hdev, _val, _name) \ 00112 WRITE_REG(_hdev, _val, _name, float32_t) 00113 00114 /* 00115 * Encapsulates the read from a specified register 00116 * NOTE - this will cause the calling function to return on error 00117 */ 00118 #define READ_REG(_hdev, _val, _name, _type) \ 00119 do { \ 00120 ADMW_RESULT _res; \ 00121 _type _regval; \ 00122 _res = admw1001_ReadRegister((_hdev), \ 00123 REG_##_name, \ 00124 &_regval, sizeof(_regval)); \ 00125 if (_res != ADMW_SUCCESS) \ 00126 return _res; \ 00127 _val = _regval; \ 00128 } while(false) 00129 00130 /* Wrapper macro to read a value from a uint32_t register */ 00131 #define READ_REG_U32(_hdev, _val, _name) \ 00132 READ_REG(_hdev, _val, _name, uint32_t) 00133 /* Wrapper macro to read a value from a uint16_t register */ 00134 #define READ_REG_U16(_hdev, _val, _name) \ 00135 READ_REG(_hdev, _val, _name, uint16_t) 00136 /* Wrapper macro to read a value from a uint8_t register */ 00137 #define READ_REG_U8(_hdev, _val, _name) \ 00138 READ_REG(_hdev, _val, _name, uint8_t) 00139 /* Wrapper macro to read a value from a float32_t register */ 00140 #define READ_REG_FLOAT(_hdev, _val, _name) \ 00141 READ_REG(_hdev, _val, _name, float32_t) 00142 00143 /* 00144 * Wrapper macro to write an array of values to a uint8_t register 00145 * NOTE - this is intended only for writing to a keyhole data register 00146 */ 00147 #define WRITE_REG_U8_ARRAY(_hdev, _arr, _len, _name) \ 00148 do { \ 00149 ADMW_RESULT _res; \ 00150 _res = admw1001_WriteRegister(_hdev, \ 00151 REG_##_name, \ 00152 _arr, _len); \ 00153 if (_res != ADMW_SUCCESS) \ 00154 return _res; \ 00155 } while(false) 00156 00157 /* 00158 * Wrapper macro to read an array of values from a uint8_t register 00159 * NOTE - this is intended only for reading from a keyhole data register 00160 */ 00161 #define READ_REG_U8_ARRAY(_hdev, _arr, _len, _name) \ 00162 do { \ 00163 ADMW_RESULT _res; \ 00164 _res = admw1001_ReadRegister((_hdev), \ 00165 REG##_name, \ 00166 _arr, _len); \ 00167 if (_res != ADMW_SUCCESS) \ 00168 return _res; \ 00169 } while(false) 00170 00171 #define ADMW1001_CHANNEL_IS_ADC(c) \ 00172 ((c) >= ADMW1001_CH_ID_ANLG_1_UNIVERSAL && (c) <= ADMW1001_CH_ID_ANLG_2_DIFFERENTIAL) 00173 00174 #define ADMW1001_CHANNEL_IS_ADC_CJC(c) \ 00175 ((c) >= ADMW1001_CH_ID_ANLG_1_UNIVERSAL && (c) <= ADMW1001_CH_ID_ANLG_2_UNIVERSAL) 00176 00177 #define ADMW1001_CHANNEL_IS_ADC_SENSOR(c) \ 00178 ((c) >= ADMW1001_CH_ID_ANLG_1_UNIVERSAL && (c) <= ADMW1001_CH_ID_ANLG_2_UNIVERSAL) 00179 00180 #define ADMW1001_CHANNEL_IS_ADC_VOLTAGE(c) \ 00181 ((c) == ADMW1001_CH_ID_ANLG_1_DIFFERENTIAL || ADMW1001_CH_ID_ANLG_2_DIFFERENTIAL) 00182 00183 #define ADMW1001_CHANNEL_IS_ADC_CURRENT(c) \ 00184 ((c) == ADMW1001_CH_ID_ANLG_1_UNIVERSAL || (c) == ADMW1001_CH_ID_ANLG_2_UNIVERSAL) 00185 00186 00187 //typedef struct { 00188 // unsigned nDeviceIndex; 00189 // ADMW_SPI_HANDLE hSpi; 00190 // ADMW_GPIO_HANDLE hGpio; 00191 // 00192 //} ADMW_DEVICE_CONTEXT; 00193 00194 static ADMW_DEVICE_CONTEXT gDeviceCtx[ADMW_PLATFORM_MAX_DEVICES]; 00195 00196 /* 00197 * Open an ADMW device instance. 00198 */ 00199 ADMW_RESULT admw_Open( 00200 unsigned const nDeviceIndex, 00201 ADMW_CONNECTION * const pConnectionInfo, 00202 ADMW_DEVICE_HANDLE * const phDevice) 00203 { 00204 ADMW_DEVICE_CONTEXT *pCtx; 00205 ADMW_RESULT eRet; 00206 00207 if (nDeviceIndex >= ADMW_PLATFORM_MAX_DEVICES) 00208 return ADMW_INVALID_DEVICE_NUM ; 00209 00210 pCtx = &gDeviceCtx[nDeviceIndex]; 00211 pCtx->nDeviceIndex = nDeviceIndex; 00212 00213 eRet = admw_LogOpen(&pConnectionInfo->log ); 00214 if (eRet != ADMW_SUCCESS ) 00215 return eRet; 00216 00217 eRet = admw_GpioOpen(&pConnectionInfo->gpio , &pCtx->hGpio); 00218 if (eRet != ADMW_SUCCESS ) 00219 return eRet; 00220 00221 eRet = admw_SpiOpen(&pConnectionInfo->spi , &pCtx->hSpi); 00222 if (eRet != ADMW_SUCCESS ) 00223 return eRet; 00224 00225 *phDevice = pCtx; 00226 return ADMW_SUCCESS ; 00227 } 00228 00229 /* 00230 * Get the current state of the specified GPIO input signal. 00231 */ 00232 ADMW_RESULT admw_GetGpioState( 00233 ADMW_DEVICE_HANDLE const hDevice, 00234 ADMW_GPIO_PIN const ePinId, 00235 bool * const pbAsserted) 00236 { 00237 ADMW_DEVICE_CONTEXT *pCtx = hDevice; 00238 00239 return admw_GpioGet(pCtx->hGpio, ePinId, pbAsserted); 00240 } 00241 00242 /* 00243 * Register an application-defined callback function for GPIO interrupts. 00244 */ 00245 ADMW_RESULT admw_RegisterGpioCallback( 00246 ADMW_DEVICE_HANDLE const hDevice, 00247 ADMW_GPIO_PIN const ePinId, 00248 ADMW_GPIO_CALLBACK const callbackFunction, 00249 void * const pCallbackParam) 00250 { 00251 ADMW_DEVICE_CONTEXT *pCtx = hDevice; 00252 00253 if (callbackFunction) { 00254 return admw_GpioIrqEnable(pCtx->hGpio, ePinId, callbackFunction, 00255 pCallbackParam); 00256 } else { 00257 return admw_GpioIrqDisable(pCtx->hGpio, ePinId); 00258 } 00259 } 00260 00261 /*! 00262 * @brief Reset the specified ADMW device. 00263 * 00264 * @param[in] hDevice - handle of ADMW device to reset. 00265 * 00266 * @return Status 00267 * - #ADMW_SUCCESS Call completed successfully. 00268 * - #ADMW_FAILURE If reseet faisl 00269 * 00270 * @details Toggle reset pin of the ADMW device low for a 00271 * minimum of 4 usec. 00272 * 00273 */ 00274 ADMW_RESULT admw_Reset(ADMW_DEVICE_HANDLE const hDevice) 00275 { 00276 ADMW_DEVICE_CONTEXT *pCtx = hDevice; 00277 ADMW_RESULT eRet; 00278 00279 /* Pulse the Reset GPIO pin low for a minimum of 4 microseconds */ 00280 eRet = admw_GpioSet(pCtx->hGpio, ADMW_GPIO_PIN_RESET , false); 00281 if (eRet != ADMW_SUCCESS ) 00282 return eRet; 00283 00284 admw_TimeDelayUsec(4); 00285 00286 eRet = admw_GpioSet(pCtx->hGpio, ADMW_GPIO_PIN_RESET , true); 00287 if (eRet != ADMW_SUCCESS ) 00288 return eRet; 00289 00290 return ADMW_SUCCESS ; 00291 } 00292 00293 /*! 00294 * @brief Get general status of ADMW module. 00295 * 00296 * @param[in] 00297 * @param[out] pStatus : Pointer to CORE Status struct. 00298 * 00299 * @return Status 00300 * - #ADMW_SUCCESS Call completed successfully. 00301 * - #ADMW_FAILURE If status register read fails. 00302 * 00303 * @details Read the general status register for the ADMW 00304 * module. Indicates Error, Alert conditions, data ready 00305 * and command running. 00306 * 00307 */ 00308 ADMW_RESULT admw_GetStatus( 00309 ADMW_DEVICE_HANDLE const hDevice, 00310 ADMW_STATUS * const pStatus) 00311 { 00312 ADMW_CORE_Status_t statusReg; 00313 READ_REG_U8(hDevice, statusReg.VALUE8, CORE_STATUS); 00314 00315 memset(pStatus, 0, sizeof(*pStatus)); 00316 00317 if (!statusReg.Cmd_Running) /* Active-low, so invert it */ 00318 pStatus->deviceStatus |= ADMW_DEVICE_STATUS_BUSY ; 00319 else if (statusReg.Drdy) 00320 pStatus->deviceStatus |= ADMW_DEVICE_STATUS_DATAREADY ; 00321 else if(statusReg.FIFO_Error == ADMW_DEVICE_STATUS_FIFO_ERROR ) 00322 pStatus->deviceStatus |= ADMW_DEVICE_STATUS_FIFO_ERROR ; 00323 if (statusReg.Alert_Active) { 00324 pStatus->deviceStatus |= ADMW_DEVICE_STATUS_ALERT ; 00325 00326 ADMW_CORE_Channel_Alert_Status_t channelAlertStatusReg; 00327 READ_REG_U16(hDevice, channelAlertStatusReg.VALUE16, 00328 CORE_CHANNEL_ALERT_STATUS); 00329 00330 for (unsigned i = 0; i < ADMW1001_MAX_CHANNELS ; i++) { 00331 if (channelAlertStatusReg.VALUE16 & (1 << i)) { 00332 ADMW_CORE_Alert_Detail_Ch_t alertDetailReg; 00333 READ_REG_U16(hDevice, alertDetailReg.VALUE16, 00334 CORE_ALERT_DETAIL_CHn(i)); 00335 00336 if (alertDetailReg.ADC_Near_Overrange) 00337 pStatus->channelAlerts [i] |= ADMW_ALERT_DETAIL_CH_ADC_NEAR_OVERRANGE ; 00338 if (alertDetailReg.Sensor_UnderRange) 00339 pStatus->channelAlerts [i] |= ADMW_ALERT_DETAIL_CH_SENSOR_UNDERRANGE ; 00340 if (alertDetailReg.Sensor_OverRange) 00341 pStatus->channelAlerts [i] |= ADMW_ALERT_DETAIL_CH_SENSOR_OVERRANGE ; 00342 if (alertDetailReg.CJ_Soft_Fault) 00343 pStatus->channelAlerts [i] |= ADMW_ALERT_DETAIL_CH_CJ_SOFT_FAULT ; 00344 if (alertDetailReg.CJ_Hard_Fault) 00345 pStatus->channelAlerts [i] |= ADMW_ALERT_DETAIL_CH_CJ_HARD_FAULT ; 00346 if (alertDetailReg.ADC_Input_OverRange) 00347 pStatus->channelAlerts [i] |= ADMW_ALERT_DETAIL_CH_ADC_INPUT_OVERRANGE ; 00348 if (alertDetailReg.Sensor_HardFault) 00349 pStatus->channelAlerts [i] |= ADMW_ALERT_DETAIL_CH_SENSOR_HARDFAULT ; 00350 00351 } 00352 } 00353 00354 if (statusReg.Configuration_Error) 00355 pStatus->deviceStatus |= ADMW_DEVICE_STATUS_CONFIG_ERROR ; 00356 if (statusReg.LUT_Error) 00357 pStatus->deviceStatus |= ADMW_DEVICE_STATUS_LUT_ERROR ; 00358 } 00359 00360 if (statusReg.Error == ADMW_DEVICE_STATUS_ERROR ) { 00361 pStatus->deviceStatus |= ADMW_DEVICE_STATUS_ERROR ; 00362 00363 ADMW_CORE_Error_Code_t errorCodeReg; 00364 READ_REG_U16(hDevice, errorCodeReg.VALUE16, CORE_ERROR_CODE); 00365 pStatus->errorCode = errorCodeReg.Error_Code; 00366 00367 } 00368 return ADMW_SUCCESS ; 00369 } 00370 00371 ADMW_RESULT admw_GetCommandRunningState( 00372 ADMW_DEVICE_HANDLE hDevice, 00373 bool *pbCommandRunning) 00374 { 00375 ADMW_CORE_Status_t statusReg; 00376 00377 READ_REG_U8(hDevice, statusReg.VALUE8, CORE_STATUS); 00378 00379 /* We should never normally see 0xFF here if the module is operational */ 00380 if (statusReg.VALUE8 == 0xFF) 00381 return ADMW_ERR_NOT_INITIALIZED ; 00382 00383 *pbCommandRunning = !statusReg.Cmd_Running; /* Active-low, so invert it */ 00384 00385 return ADMW_SUCCESS ; 00386 } 00387 00388 ADMW_RESULT admw_deviceInformation(ADMW_DEVICE_HANDLE hDevice) 00389 { 00390 uint16_t nAddress = REG_CORE_REVISION; 00391 char nData[ADMW_VERSION_REG_VAL_SIZE]; //4 Bytes of version register data 00392 ADMW_RESULT res; 00393 res=admw1001_ReadRegister(hDevice,nAddress,nData,sizeof(nData)); 00394 if(res != ADMW_SUCCESS ) { 00395 //if reading version register failed, sending 00.00.0000 as ADMW1001 firmware version 00396 //strcat(nData, ADMW1001_FIRMWARE_VERSION_DEFAULT); 00397 ADMW_LOG_INFO("Firmware Version Id is %X.%X",nData[2],nData[0]); 00398 } else { 00399 char buffer[ADMW_FORMATTED_VERSION_SIZE]; //00.00.0000 8 digits + 2 Bytes "." + one null character at the end 00400 strcat(nData, buffer); 00401 ADMW_LOG_INFO("Firmware Version Id is %X.%X.%X",nData[3],nData[2],nData[0]); 00402 } 00403 return ADMW_SUCCESS ; 00404 } 00405 00406 static ADMW_RESULT executeCommand( 00407 ADMW_DEVICE_HANDLE const hDevice, 00408 ADMW_CORE_Command_Special_Command const command, 00409 bool const bWaitForCompletion) 00410 { 00411 ADMW_CORE_Command_t commandReg; 00412 bool bCommandRunning; 00413 ADMW_RESULT eRet; 00414 00415 /* 00416 * Don't allow another command to be issued if one is already running, but 00417 * make an exception for ENUM_CORE_COMMAND_NOP which can be used to 00418 * request a running command to be stopped (e.g. continuous measurement) 00419 */ 00420 if (command != ENUM_CORE_COMMAND_NOP) { 00421 eRet = admw_GetCommandRunningState(hDevice, &bCommandRunning); 00422 if (eRet) 00423 return eRet; 00424 00425 if (bCommandRunning) 00426 return ADMW_IN_USE ; 00427 } 00428 00429 commandReg.Special_Command = command; 00430 WRITE_REG_U8(hDevice, commandReg.VALUE8, CORE_COMMAND); 00431 00432 if (bWaitForCompletion) { 00433 do { 00434 /* Allow a minimum 100usec delay for status update before checking */ 00435 admw_TimeDelayUsec(100); 00436 00437 eRet = admw_GetCommandRunningState(hDevice, &bCommandRunning); 00438 if (eRet) 00439 return eRet; 00440 } while (bCommandRunning); 00441 } 00442 00443 return ADMW_SUCCESS ; 00444 } 00445 00446 ADMW_RESULT admw_ApplyConfigUpdates( 00447 ADMW_DEVICE_HANDLE const hDevice) 00448 { 00449 return executeCommand(hDevice, CORE_COMMAND_LATCH_CONFIG, true); 00450 } 00451 00452 /*! 00453 * @brief Start a measurement cycle. 00454 * 00455 * @param[out] 00456 * 00457 * @return Status 00458 * - #ADMW_SUCCESS Call completed successfully. 00459 * - #ADMW_FAILURE 00460 * 00461 * @details Sends the latch config command. Configuration for channels in 00462 * conversion cycle should be completed before this function. 00463 * Channel enabled bit should be set before this function. 00464 * Starts a conversion and configures the format of the sample. 00465 * 00466 */ 00467 ADMW_RESULT admw_StartMeasurement( 00468 ADMW_DEVICE_HANDLE const hDevice, 00469 ADMW_MEASUREMENT_MODE const eMeasurementMode) 00470 { 00471 switch (eMeasurementMode) { 00472 case ADMW_MEASUREMENT_MODE_NORMAL : 00473 return executeCommand(hDevice, CORE_COMMAND_CONVERT_WITH_RAW, false); 00474 case ADMW_MEASUREMENT_MODE_OMIT_RAW : 00475 return executeCommand(hDevice, CORE_COMMAND_CONVERT, false); 00476 default: 00477 ADMW_LOG_ERROR("Invalid measurement mode %d specified", 00478 eMeasurementMode); 00479 return ADMW_INVALID_PARAM ; 00480 } 00481 } 00482 00483 /* 00484 * Store the configuration settings to persistent memory on the device. 00485 * The settings can be saved to 4 different flash memory areas (slots). 00486 * No other command must be running when this is called. 00487 * Do not power down the device while this command is running. 00488 */ 00489 ADMW_RESULT admw_SaveConfig( 00490 ADMW_DEVICE_HANDLE const hDevice, 00491 ADMW_USER_CONFIG_SLOT const eSlotId) 00492 { 00493 switch (eSlotId) { 00494 case ADMW_FLASH_CONFIG_1: 00495 return executeCommand(hDevice, CORE_COMMAND_SAVE_CONFIG_1, true); 00496 default: 00497 ADMW_LOG_ERROR("Invalid user config target slot %d specified", 00498 eSlotId); 00499 return ADMW_INVALID_PARAM ; 00500 } 00501 } 00502 00503 /* 00504 * Restore the configuration settings from persistent memory on the device. 00505 * No other command must be running when this is called. 00506 */ 00507 ADMW_RESULT admw_RestoreConfig( 00508 ADMW_DEVICE_HANDLE const hDevice, 00509 ADMW_USER_CONFIG_SLOT const eSlotId) 00510 { 00511 switch (eSlotId) { 00512 case ADMW_FLASH_CONFIG_1: 00513 return executeCommand(hDevice, CORE_COMMAND_LOAD_CONFIG_1, true); 00514 default: 00515 ADMW_LOG_ERROR("Invalid user config source slot %d specified", 00516 eSlotId); 00517 return ADMW_INVALID_PARAM ; 00518 } 00519 } 00520 00521 /* 00522 * Store the LUT data to persistent memory on the device. 00523 * No other command must be running when this is called. 00524 * Do not power down the device while this command is running. 00525 */ 00526 ADMW_RESULT admw_SaveLutData( 00527 ADMW_DEVICE_HANDLE const hDevice) 00528 { 00529 return executeCommand(hDevice, CORE_COMMAND_SAVE_LUT, true); 00530 } 00531 00532 /* 00533 * Restore the LUT data from persistent memory on the device. 00534 * No other command must be running when this is called. 00535 */ 00536 ADMW_RESULT admw_RestoreLutData( 00537 ADMW_DEVICE_HANDLE const hDevice) 00538 { 00539 return executeCommand(hDevice, CORE_COMMAND_LOAD_LUT, true); 00540 } 00541 00542 /* 00543 * Stop the measurement cycles on the device. 00544 * To be used only if a measurement command is currently running. 00545 */ 00546 ADMW_RESULT admw_StopMeasurement( 00547 ADMW_DEVICE_HANDLE const hDevice) 00548 { 00549 return executeCommand(hDevice, CORE_COMMAND_NOP, true); 00550 } 00551 00552 /* 00553 * 00554 */ 00555 ADMW_RESULT admw1001_sendRun( ADMW_DEVICE_HANDLE const hDevice) 00556 { 00557 bool bitCommand; 00558 ADMW_RESULT eRet; 00559 uint8_t pinreg = 0x1; 00560 00561 ADMW_DEVICE_CONTEXT *pCtx = hDevice; 00562 static uint8_t DataBuffer[SPI_BUFFER_SIZE] = {0}; 00563 uint16_t nSize; 00564 00565 //Construct Read Status command 00566 DataBuffer[0] = 0x07; 00567 DataBuffer[1] = 0x0E; //Packet ID 00568 00569 DataBuffer[2] = 0x00; 00570 DataBuffer[3] = 0x00; //Data words 00571 00572 DataBuffer[4] = 0x45; 00573 DataBuffer[5] = 0x00; //Command ID 00574 00575 DataBuffer[6] = 0x00; 00576 DataBuffer[7] = 0x50; 00577 DataBuffer[8] = 0x00; 00578 DataBuffer[9] = 0x00; //Address 00579 00580 DataBuffer[10] = 0x95; 00581 DataBuffer[11] = 0x00; 00582 DataBuffer[12] = 0x00; 00583 DataBuffer[13] = 0x00; //Checksum 00584 00585 nSize = SFL_READ_STATUS_HDR_SIZE; 00586 00587 do { 00588 // Get the SFL command irq pin to check if SFL is ready to receive commands 00589 // Status pin is not checked since SFL is just booted, there should not be any issue with SFL 00590 eRet = admw_GetGpioState( hDevice, ADMW_GPIO_PIN_DATAREADY , &bitCommand ); 00591 if( eRet != ADMW_SUCCESS ) { 00592 return eRet; 00593 } 00594 00595 // Command IRQ pin should be low and Status IRQ pin should be high for SFL to be in good state and ready to recieve commands 00596 // pinreg == '0x00' - Error occured in SFL 00597 // pinreg == '0x01' - SFL is ready to recieve commands 00598 // pinreg == '0x02' - Error occured in handling any commands in SFL 00599 // pinreg == '0x03' - SFL not booted 00600 00601 pinreg = (bitCommand); 00602 00603 } while(pinreg != 0x0u); 00604 00605 eRet = admw_SpiTransfer(pCtx->hSpi, DataBuffer, NULL, 00606 nSize, false); 00607 00608 return eRet; 00609 } 00610 00611 /* 00612 * Read a set of data samples from the device. 00613 * This may be called at any time. 00614 */ 00615 00616 ADMW_RESULT admw_GetData( 00617 ADMW_DEVICE_HANDLE const hDevice, 00618 ADMW_MEASUREMENT_MODE const eMeasurementMode, 00619 ADMW_DATA_SAMPLE * const pSamples, 00620 uint8_t const nBytesPerSample, 00621 uint32_t const nRequested, 00622 uint32_t * const pnReturned) 00623 { 00624 ADMW1001_Sensor_Result_t sensorResult; 00625 ADMW_DEVICE_CONTEXT *pCtx = hDevice; 00626 uint16_t command = ADMW1001_HOST_COMMS_READ_CMD | 00627 (REG_CORE_DATA_FIFO & ADMW1001_HOST_COMMS_ADR_MASK); 00628 uint8_t commandData[2] = { 00629 command >> 8, 00630 command & 0xFF 00631 }; 00632 uint8_t commandResponse[2]; 00633 unsigned nValidSamples = 0; 00634 ADMW_RESULT eRet = ADMW_SUCCESS ; 00635 00636 do { 00637 eRet = admw_SpiTransfer(pCtx->hSpi, commandData, commandResponse, 00638 sizeof(command), false); 00639 if (eRet) { 00640 ADMW_LOG_ERROR("Failed to send read command for FIFO register"); 00641 return eRet; 00642 } 00643 admw_TimeDelayUsec(ADMW1001_HOST_COMMS_XFER_DELAY); 00644 } while ((commandResponse[0] != ADMW1001_HOST_COMMS_CMD_RESP_0) || 00645 (commandResponse[1] != ADMW1001_HOST_COMMS_CMD_RESP_1)); 00646 00647 for (unsigned i = 0; i < nRequested; i++) { 00648 00649 bool bHoldCs = true; 00650 /* Keep the CS signal asserted for all but the last sample */ 00651 if ((i + 1) == nRequested) 00652 bHoldCs = false; 00653 00654 getDataCnt++; 00655 00656 eRet = admw_SpiTransfer(pCtx->hSpi, NULL, &sensorResult, 00657 nBytesPerSample, bHoldCs); 00658 if (eRet) { 00659 ADMW_LOG_ERROR("Failed to read data from FIFO register"); 00660 return eRet; 00661 } 00662 00663 if (! sensorResult.Ch_Valid) { 00664 /* 00665 * Reading an invalid sample indicates that there are no 00666 * more samples available or we've lost sync with the device. 00667 * In the latter case, it might be recoverable, but return here 00668 * to let the application check the device status and decide itself. 00669 */ 00670 eRet = ADMW_INCOMPLETE ; 00671 break; 00672 } 00673 00674 ADMW_DATA_SAMPLE *pSample = &pSamples[nValidSamples]; 00675 memcpy(pSample,&sensorResult,sizeof(sensorResult)); 00676 nValidSamples++; 00677 00678 admw_TimeDelayUsec(ADMW1001_HOST_COMMS_XFER_DELAY); 00679 } 00680 *pnReturned = nValidSamples; 00681 00682 return eRet; 00683 } 00684 00685 /* 00686 * Close the given ADMW device. 00687 */ 00688 ADMW_RESULT admw_Close( 00689 ADMW_DEVICE_HANDLE const hDevice) 00690 { 00691 ADMW_DEVICE_CONTEXT *pCtx = hDevice; 00692 00693 admw_GpioClose(pCtx->hGpio); 00694 admw_SpiClose(pCtx->hSpi); 00695 admw_LogClose(); 00696 00697 return ADMW_SUCCESS ; 00698 } 00699 00700 ADMW_RESULT admw1001_WriteRegister( 00701 ADMW_DEVICE_HANDLE hDevice, 00702 uint16_t nAddress, 00703 void *pData, 00704 unsigned nLength) 00705 { 00706 ADMW_RESULT eRet; 00707 ADMW_DEVICE_CONTEXT *pCtx = hDevice; 00708 uint16_t command = ADMW1001_HOST_COMMS_WRITE_CMD | 00709 (nAddress & ADMW1001_HOST_COMMS_ADR_MASK); 00710 uint8_t commandData[2] = { 00711 command >> 8, 00712 command & 0xFF 00713 }; 00714 uint8_t commandResponse[2]; 00715 00716 do { 00717 eRet = admw_SpiTransfer(pCtx->hSpi, commandData, commandResponse, 00718 sizeof(command), false); 00719 if (eRet) { 00720 ADMW_LOG_ERROR("Failed to send write command for register %u", 00721 nAddress); 00722 return eRet; 00723 } 00724 00725 admw_TimeDelayUsec(ADMW1001_HOST_COMMS_XFER_DELAY); 00726 } while ((commandResponse[0] != ADMW1001_HOST_COMMS_CMD_RESP_0) || 00727 (commandResponse[1] != ADMW1001_HOST_COMMS_CMD_RESP_1)); 00728 00729 eRet = admw_SpiTransfer(pCtx->hSpi, pData, NULL, nLength, false); 00730 if (eRet) { 00731 ADMW_LOG_ERROR("Failed to write data (%dB) to register %u", 00732 nLength, nAddress); 00733 return eRet; 00734 } 00735 00736 admw_TimeDelayUsec(ADMW1001_HOST_COMMS_XFER_DELAY); 00737 00738 return ADMW_SUCCESS ; 00739 } 00740 00741 ADMW_RESULT admw_GetDeviceReadyState( 00742 ADMW_DEVICE_HANDLE const hDevice, 00743 bool * const bReady) 00744 { 00745 ADMW_SPI_Chip_Type_t chipTypeReg; 00746 00747 READ_REG_U8(hDevice, chipTypeReg.VALUE8, SPI_CHIP_TYPE); 00748 /* If we read this register successfully, assume the device is ready */ 00749 *bReady = (chipTypeReg.VALUE8 == REG_SPI_CHIP_TYPE_RESET); 00750 00751 return ADMW_SUCCESS ; 00752 } 00753 00754 ADMW_RESULT admw1001_ReadRegister( 00755 ADMW_DEVICE_HANDLE hDevice, 00756 uint16_t nAddress, 00757 void *pData, 00758 unsigned nLength) 00759 { 00760 ADMW_RESULT eRet; 00761 ADMW_DEVICE_CONTEXT *pCtx = hDevice; 00762 uint16_t command = ADMW1001_HOST_COMMS_READ_CMD | 00763 (nAddress & ADMW1001_HOST_COMMS_ADR_MASK); 00764 uint8_t commandData[2] = { 00765 command >> 8, 00766 command & 0xFF 00767 }; 00768 uint8_t commandResponse[2]; 00769 00770 do { 00771 eRet = admw_SpiTransfer(pCtx->hSpi, commandData, commandResponse, 00772 sizeof(command), false); 00773 if (eRet) { 00774 ADMW_LOG_ERROR("Failed to send read command for register %u", 00775 nAddress); 00776 return eRet; 00777 } 00778 00779 admw_TimeDelayUsec(ADMW1001_HOST_COMMS_XFER_DELAY); 00780 } while ((commandResponse[0] != ADMW1001_HOST_COMMS_CMD_RESP_0) || 00781 (commandResponse[1] != ADMW1001_HOST_COMMS_CMD_RESP_1)); 00782 00783 eRet = admw_SpiTransfer(pCtx->hSpi, NULL, pData, nLength, false); 00784 if (eRet) { 00785 ADMW_LOG_ERROR("Failed to read data (%uB) from register %u", 00786 nLength, nAddress); 00787 return eRet; 00788 } 00789 00790 admw_TimeDelayUsec(ADMW1001_HOST_COMMS_XFER_DELAY); 00791 00792 return ADMW_SUCCESS ; 00793 } 00794 00795 ADMW_RESULT admw1001_GetDataReadyModeInfo( 00796 ADMW_DEVICE_HANDLE const hDevice, 00797 ADMW_MEASUREMENT_MODE const eMeasurementMode, 00798 ADMW1001_OPERATING_MODE * const peOperatingMode, 00799 ADMW1001_DATAREADY_MODE * const peDataReadyMode, 00800 uint32_t * const pnSamplesPerDataready, 00801 uint32_t * const pnSamplesPerCycle, 00802 uint8_t * const pnBytesPerSample) 00803 { 00804 unsigned nChannelsEnabled = 0; 00805 unsigned nSamplesPerCycle = 0; 00806 00807 ADMW_CORE_Mode_t modeReg; 00808 READ_REG_U8(hDevice, modeReg.VALUE8, CORE_MODE); 00809 00810 if (modeReg.Conversion_Mode == CORE_MODE_SINGLECYCLE) 00811 *peOperatingMode = ADMW1001_OPERATING_MODE_SINGLECYCLE ; 00812 else 00813 *peOperatingMode = ADMW1001_OPERATING_MODE_CONTINUOUS ; 00814 00815 if (eMeasurementMode == ADMW_MEASUREMENT_MODE_OMIT_RAW ) { 00816 *pnBytesPerSample = 8; 00817 } else { 00818 *pnBytesPerSample = 12; 00819 } 00820 00821 for (ADMW1001_CH_ID chId = ADMW1001_CH_ID_ANLG_1_UNIVERSAL ; 00822 chId < ADMW1001_MAX_CHANNELS ; 00823 chId++) { 00824 ADMW_CORE_Sensor_Details_t sensorDetailsReg; 00825 ADMW_CORE_Channel_Count_t channelCountReg; 00826 00827 00828 READ_REG_U8(hDevice, channelCountReg.VALUE8, CORE_CHANNEL_COUNTn(chId)); 00829 READ_REG_U32(hDevice, sensorDetailsReg.VALUE32, CORE_SENSOR_DETAILSn(chId)); 00830 00831 if (channelCountReg.Channel_Enable && !sensorDetailsReg.Do_Not_Publish) { 00832 unsigned nActualChannels = 1; 00833 00834 nChannelsEnabled += nActualChannels; 00835 00836 nSamplesPerCycle += nActualChannels * 00837 (channelCountReg.Channel_Count + 1); 00838 } 00839 } 00840 00841 if (nChannelsEnabled == 0) { 00842 *pnSamplesPerDataready = 0; 00843 *pnSamplesPerCycle = 0; 00844 return ADMW_SUCCESS ; 00845 } 00846 00847 *pnSamplesPerCycle = nSamplesPerCycle; 00848 00849 if (modeReg.Drdy_Mode == CORE_MODE_DRDY_PER_CONVERSION) { 00850 *pnSamplesPerDataready = 1; 00851 } else if (modeReg.Drdy_Mode == CORE_MODE_DRDY_PER_CYCLE) { 00852 *pnSamplesPerDataready = nSamplesPerCycle; 00853 } else if (modeReg.Drdy_Mode == CORE_MODE_DRDY_PER_FIFO_FILL) { 00854 ADMW_CORE_Fifo_Num_Cycles_t fifoNumCyclesReg; 00855 00856 READ_REG_U8(hDevice, fifoNumCyclesReg.VALUE8, CORE_FIFO_NUM_CYCLES); 00857 00858 *pnSamplesPerDataready = nSamplesPerCycle * fifoNumCyclesReg.Fifo_Num_Cycles; 00859 } else { 00860 ADMW_LOG_ERROR("Invalid DRDY mode %d specified", 00861 modeReg.Drdy_Mode); 00862 return ADMW_INVALID_PARAM ; 00863 } 00864 00865 if (modeReg.Drdy_Mode == CORE_MODE_DRDY_PER_CONVERSION) { 00866 *peDataReadyMode = ADMW1001_DATAREADY_PER_CONVERSION ; 00867 } else if (modeReg.Drdy_Mode == CORE_MODE_DRDY_PER_CYCLE) { 00868 *peDataReadyMode = ADMW1001_DATAREADY_PER_CYCLE ; 00869 } else if (modeReg.Drdy_Mode == CORE_MODE_DRDY_PER_FIFO_FILL) { 00870 *peDataReadyMode = ADMW1001_DATAREADY_PER_FIFO_FILL ; 00871 } else { 00872 ADMW_LOG_ERROR("Invalid DRDY mode %d specified", 00873 modeReg.Drdy_Mode); 00874 return ADMW_INVALID_PARAM ; 00875 } 00876 00877 return ADMW_SUCCESS ; 00878 } 00879 00880 ADMW_RESULT admw_GetProductID( 00881 ADMW_DEVICE_HANDLE hDevice, 00882 ADMW_PRODUCT_ID *pProductId) 00883 { 00884 ADMW_SPI_Product_ID_L_t productIdLoReg; 00885 ADMW_SPI_Product_ID_H_t productIdHiReg; 00886 00887 READ_REG_U8(hDevice, productIdLoReg.VALUE8, SPI_PRODUCT_ID_L); 00888 READ_REG_U8(hDevice, productIdHiReg.VALUE8, SPI_PRODUCT_ID_H); 00889 00890 *pProductId = (ADMW_PRODUCT_ID )((productIdHiReg.VALUE8 << 8) | 00891 productIdLoReg.VALUE8); 00892 return ADMW_SUCCESS ; 00893 } 00894 00895 static ADMW_RESULT admw_SetPowerMode( 00896 ADMW_DEVICE_HANDLE hDevice, 00897 ADMW1001_POWER_MODE powerMode) 00898 { 00899 ADMW_CORE_Power_Config_t powerConfigReg = { 0 }; 00900 00901 if (powerMode == ADMW1001_POWER_MODE_HIBERNATION ) { 00902 powerConfigReg.Power_Mode_MCU = CORE_POWER_CONFIG_HIBERNATION; 00903 } else if (powerMode == ADMW1001_POWER_MODE_ACTIVE ) { 00904 powerConfigReg.Power_Mode_MCU = CORE_POWER_CONFIG_ACTIVE_MODE; 00905 } else { 00906 ADMW_LOG_ERROR("Invalid power mode %d specified", powerMode); 00907 return ADMW_INVALID_PARAM ; 00908 } 00909 00910 WRITE_REG_U8(hDevice, powerConfigReg.VALUE8, CORE_POWER_CONFIG); 00911 00912 return ADMW_SUCCESS ; 00913 } 00914 00915 ADMW_RESULT admw1001_SetPowerConfig( 00916 ADMW_DEVICE_HANDLE hDevice, 00917 ADMW1001_POWER_CONFIG *pPowerConfig) 00918 { 00919 ADMW_RESULT eRet; 00920 00921 eRet = admw_SetPowerMode(hDevice, pPowerConfig->powerMode ); 00922 if (eRet != ADMW_SUCCESS ) { 00923 ADMW_LOG_ERROR("Failed to set power mode"); 00924 return eRet; 00925 } 00926 00927 return ADMW_SUCCESS ; 00928 } 00929 00930 static ADMW_RESULT admw_SetRSenseValue( 00931 ADMW_DEVICE_HANDLE hDevice, 00932 float32_t RSenseValue) 00933 { 00934 ADMW_CORE_External_Reference_Resistor_t RefResistorConfigReg; 00935 00936 RefResistorConfigReg.Ext_Refin1_Value = RSenseValue; 00937 00938 WRITE_REG_FLOAT(hDevice, RefResistorConfigReg.VALUE32, CORE_EXTERNAL_REFERENCE_RESISTOR); 00939 00940 return ADMW_SUCCESS ; 00941 00942 } 00943 static ADMW_RESULT admw_SetMode( 00944 ADMW_DEVICE_HANDLE hDevice, 00945 ADMW1001_OPERATING_MODE eOperatingMode, 00946 ADMW1001_DATAREADY_MODE eDataReadyMode) 00947 { 00948 ADMW_CORE_Mode_t modeReg; 00949 00950 modeReg.VALUE8 = REG_RESET_VAL(CORE_MODE); 00951 00952 if (eOperatingMode == ADMW1001_OPERATING_MODE_SINGLECYCLE ) { 00953 modeReg.Conversion_Mode = CORE_MODE_SINGLECYCLE; 00954 } else if (eOperatingMode == ADMW1001_OPERATING_MODE_CONTINUOUS ) { 00955 modeReg.Conversion_Mode = CORE_MODE_CONTINUOUS; 00956 } else { 00957 ADMW_LOG_ERROR("Invalid operating mode %d specified", 00958 eOperatingMode); 00959 return ADMW_INVALID_PARAM ; 00960 } 00961 00962 if (eDataReadyMode == ADMW1001_DATAREADY_PER_CONVERSION ) { 00963 modeReg.Drdy_Mode = CORE_MODE_DRDY_PER_CONVERSION; 00964 } else if (eDataReadyMode == ADMW1001_DATAREADY_PER_CYCLE ) { 00965 modeReg.Drdy_Mode = CORE_MODE_DRDY_PER_CYCLE; 00966 } else if (eDataReadyMode == ADMW1001_DATAREADY_PER_FIFO_FILL ) { 00967 modeReg.Drdy_Mode = CORE_MODE_DRDY_PER_FIFO_FILL; 00968 } else { 00969 ADMW_LOG_ERROR("Invalid data-ready mode %d specified", eDataReadyMode); 00970 return ADMW_INVALID_PARAM ; 00971 } 00972 00973 WRITE_REG_U8(hDevice, modeReg.VALUE8, CORE_MODE); 00974 00975 return ADMW_SUCCESS ; 00976 } 00977 00978 ADMW_RESULT admw_SetCycleControl(ADMW_DEVICE_HANDLE hDevice, 00979 uint32_t nCycleInterval, 00980 bool vBiasEnable, 00981 bool vPostExecCurrentState, 00982 bool vGroundSwitch) 00983 { 00984 ADMW_CORE_Cycle_Control_t cycleControlReg; 00985 00986 cycleControlReg.VALUE16 = REG_RESET_VAL(CORE_CYCLE_CONTROL); 00987 00988 if (nCycleInterval < (1 << 12)) { 00989 cycleControlReg.Cycle_Time_Units = CORE_CYCLE_CONTROL_SECONDS; 00990 } else { 00991 ADMW_LOG_ERROR("Invalid nCycleInterval %d specified", nCycleInterval); 00992 return ADMW_INVALID_PARAM ; 00993 } 00994 00995 if (vBiasEnable == true) { 00996 cycleControlReg.Vbias = 1; 00997 } 00998 CHECK_REG_FIELD_VAL(CORE_CYCLE_CONTROL_CYCLE_TIME, nCycleInterval); 00999 cycleControlReg.Cycle_Time = nCycleInterval; 01000 01001 switch(vPostExecCurrentState) { 01002 case ADMW1001_ADC_EXC_STATE_CYCLE_POWER : 01003 cycleControlReg.PST_MEAS_EXC_CTRL = CORE_CYCLE_CONTROL_POWERCYCLE; 01004 break; 01005 case ADMW1001_ADC_EXC_STATE_ALWAYS_ON : 01006 cycleControlReg.PST_MEAS_EXC_CTRL = CORE_CYCLE_CONTROL_ALWAYSON; 01007 break; 01008 default: 01009 ADMW_LOG_ERROR("Invalid Post measurement Excitation Current state %d specified", 01010 vPostExecCurrentState); 01011 return ADMW_INVALID_PARAM ; 01012 } 01013 01014 switch(vGroundSwitch) { 01015 case ADMW1001_ADC_GND_SW_OPEN : 01016 cycleControlReg.GND_SW_CTRL = CORE_CYCLE_CONTROL_OPEN_SW; 01017 break; 01018 case ADMW1001_ADC_GND_SW_CLOSED : 01019 cycleControlReg.GND_SW_CTRL = CORE_CYCLE_CONTROL_CLOSE_SW; 01020 break; 01021 default: 01022 ADMW_LOG_ERROR("Invalid ground switch state %d specified", 01023 vGroundSwitch); 01024 return ADMW_INVALID_PARAM ; 01025 } 01026 01027 WRITE_REG_U16(hDevice, cycleControlReg.VALUE16, CORE_CYCLE_CONTROL); 01028 01029 return ADMW_SUCCESS ; 01030 } 01031 static ADMW_RESULT admw_SetExternalReferenceVoltage( 01032 ADMW_DEVICE_HANDLE hDevice, 01033 float32_t externalRefVoltage) 01034 { 01035 WRITE_REG_FLOAT(hDevice, externalRefVoltage, CORE_EXTERNAL_VOLTAGE_REFERENCE); 01036 01037 return ADMW_SUCCESS ; 01038 } 01039 static ADMW_RESULT admw_SetFifoNumCycles( 01040 ADMW_DEVICE_HANDLE hDevice, 01041 uint8_t fifoNumCycles) 01042 { 01043 WRITE_REG_U8(hDevice, fifoNumCycles, CORE_FIFO_NUM_CYCLES); 01044 01045 return ADMW_SUCCESS ; 01046 } 01047 01048 static ADMW_RESULT admw_SetExternalReferenceValues( 01049 ADMW_DEVICE_HANDLE hDevice, 01050 float32_t externalRef1Value) 01051 { 01052 WRITE_REG_FLOAT(hDevice, externalRef1Value, CORE_EXTERNAL_REFERENCE_RESISTOR); 01053 01054 return ADMW_SUCCESS ; 01055 } 01056 static ADMW_RESULT admw_SetAVDDVoltage( 01057 ADMW_DEVICE_HANDLE hDevice, 01058 float32_t AVDDVoltage) 01059 { 01060 01061 WRITE_REG_FLOAT(hDevice, AVDDVoltage, CORE_AVDD_VOLTAGE); 01062 01063 return ADMW_SUCCESS ; 01064 } 01065 01066 static ADMW_RESULT admw_SetExtVrefBufferMode( 01067 ADMW_DEVICE_HANDLE hDevice, 01068 ADMW1001_VREF_BUFFER_MODE extVrefBufferMode) 01069 { 01070 ADMW_CORE_EXT_VBUFF_t VrefBuffReg = { 0 }; 01071 01072 if (extVrefBufferMode == ADMW1001_VREF_BUFF_MODE_DISABLE_BOTH ) 01073 { 01074 VrefBuffReg.EXT_VBUFF = CORE_EXT_VBUFF_BOTH_INACTIVE_MODE; 01075 } 01076 else if (extVrefBufferMode == ADMW1001_VREF_BUFF_MODE_ONLY_POS ) 01077 { 01078 VrefBuffReg.EXT_VBUFF = CORE_EXT_VBUFF_ONLY_VPOS_MODE; 01079 } 01080 else if (extVrefBufferMode == ADMW1001_VREF_BUFF_MODE_ENABLE_BOTH ) 01081 { 01082 VrefBuffReg.EXT_VBUFF = CORE_EXT_VBUFF_BOTH_ACTIVE_MODE; 01083 } 01084 else 01085 { 01086 ADMW_LOG_ERROR("Unsupported Ext Vref Buffer mode %d specified", extVrefBufferMode); 01087 return ADMW_INVALID_PARAM ; 01088 } 01089 01090 WRITE_REG_U8(hDevice, VrefBuffReg.VALUE8, CORE_EXT_VBUFF); 01091 01092 return ADMW_SUCCESS ; 01093 01094 } 01095 01096 ADMW_RESULT admw1001_SetMeasurementConfig( 01097 ADMW_DEVICE_HANDLE hDevice, 01098 ADMW1001_MEASUREMENT_CONFIG *pMeasConfig) 01099 { 01100 ADMW_RESULT eRet; 01101 01102 eRet = admw_SetMode(hDevice, 01103 pMeasConfig->operatingMode , 01104 pMeasConfig->dataReadyMode ); 01105 if (eRet != ADMW_SUCCESS ) { 01106 ADMW_LOG_ERROR("Failed to set operating mode"); 01107 return eRet; 01108 } 01109 01110 eRet = admw_SetCycleControl(hDevice, pMeasConfig->cycleInterval , 01111 pMeasConfig->vBiasEnable , 01112 pMeasConfig->excitationState , 01113 pMeasConfig->groundSwitch ); 01114 if (eRet != ADMW_SUCCESS ) { 01115 ADMW_LOG_ERROR("Failed to set cycle control"); 01116 return eRet; 01117 } 01118 01119 if (pMeasConfig->fifoNumCycles > 0) { 01120 eRet = admw_SetFifoNumCycles(hDevice, 01121 pMeasConfig->fifoNumCycles ); 01122 } 01123 01124 if (eRet != ADMW_SUCCESS ) { 01125 ADMW_LOG_ERROR("Failed to set the FIFO number of cycles."); 01126 return eRet; 01127 } 01128 01129 if(pMeasConfig->externalRef1Value > 0) { 01130 eRet = admw_SetExternalReferenceValues(hDevice, 01131 pMeasConfig->externalRef1Value ); 01132 } 01133 01134 if (eRet != ADMW_SUCCESS ) { 01135 ADMW_LOG_ERROR("Failed to set external reference values"); 01136 return eRet; 01137 } 01138 01139 if((pMeasConfig->AVDDVoltage >= 3.0) && (pMeasConfig->AVDDVoltage <= 3.6)) { 01140 eRet = admw_SetAVDDVoltage(hDevice, 01141 pMeasConfig->AVDDVoltage ); 01142 } 01143 01144 if (eRet != ADMW_SUCCESS ) { 01145 ADMW_LOG_ERROR("Failed to set AVDD Voltge"); 01146 return eRet; 01147 } 01148 01149 eRet = admw_SetRSenseValue(hDevice, pMeasConfig->RSenseValue ); 01150 if (eRet != ADMW_SUCCESS ) { 01151 ADMW_LOG_ERROR("Failed to set RSenseValue"); 01152 return eRet; 01153 } 01154 01155 eRet = admw_SetExternalReferenceVoltage(hDevice, pMeasConfig->externalRefVoltage ); 01156 if (eRet != ADMW_SUCCESS ) { 01157 ADMW_LOG_ERROR("Failed to set External reference Voltage"); 01158 return eRet; 01159 } 01160 eRet = admw_SetExtVrefBufferMode(hDevice, (ADMW1001_VREF_BUFFER_MODE )pMeasConfig->extVrefBuffMode ); 01161 if (eRet != ADMW_SUCCESS ) 01162 { 01163 ADMW_LOG_ERROR("Failed to set External Vref Buffer Mode"); 01164 return eRet; 01165 } 01166 01167 return ADMW_SUCCESS ; 01168 } 01169 ADMW_RESULT admw1001_SetDiagnosticsConfig( 01170 ADMW_DEVICE_HANDLE hDevice, 01171 ADMW1001_DIAGNOSTICS_CONFIG *pDiagnosticsConfig) 01172 { 01173 ADMW_CORE_Diagnostics_Control_t diagnosticsControlReg; 01174 01175 diagnosticsControlReg.VALUE8 = REG_RESET_VAL(CORE_DIAGNOSTICS_CONTROL); 01176 01177 if (pDiagnosticsConfig->disableMeasurementDiag ) 01178 diagnosticsControlReg.Diag_Meas_En = 0; 01179 else 01180 diagnosticsControlReg.Diag_Meas_En = 1; 01181 01182 if(pDiagnosticsConfig->osdFrequency <= 0x7F) { 01183 diagnosticsControlReg.Diag_OSD_Freq = pDiagnosticsConfig->osdFrequency ; 01184 } else { 01185 ADMW_LOG_ERROR("Invalid open-sensor diagnostic frequency %d specified", 01186 pDiagnosticsConfig->osdFrequency ); 01187 return ADMW_INVALID_PARAM ; 01188 } 01189 WRITE_REG_U8(hDevice, diagnosticsControlReg.VALUE8, CORE_DIAGNOSTICS_CONTROL); 01190 01191 return ADMW_SUCCESS ; 01192 } 01193 01194 uint16_t totalChannelCount(ADMW_DEVICE_HANDLE hDevice,ADMW1001_CHANNEL_CONFIG *pChannelConfig) 01195 { 01196 uint16_t channelCount=0; 01197 channelCount=pChannelConfig->measurementsPerCycle ; 01198 return channelCount; 01199 } 01200 01201 ADMW_RESULT admw1001_SetChannelCount( 01202 ADMW_DEVICE_HANDLE hDevice, 01203 ADMW1001_CH_ID eChannelId, 01204 uint32_t nMeasurementsPerCycle) 01205 { 01206 ADMW_CORE_Channel_Count_t channelCountReg; 01207 01208 channelCountReg.VALUE8 = REG_RESET_VAL(CORE_CHANNEL_COUNTn); 01209 01210 if (nMeasurementsPerCycle > 0) { 01211 nMeasurementsPerCycle -= 1; 01212 01213 CHECK_REG_FIELD_VAL(CORE_CHANNEL_COUNT_CHANNEL_COUNT, 01214 nMeasurementsPerCycle); 01215 01216 channelCountReg.Channel_Enable = 1; 01217 channelCountReg.Channel_Count = nMeasurementsPerCycle; 01218 } else { 01219 channelCountReg.Channel_Enable = 0; 01220 } 01221 01222 WRITE_REG_U8(hDevice, channelCountReg.VALUE8, CORE_CHANNEL_COUNTn(eChannelId)); 01223 01224 return ADMW_SUCCESS ; 01225 } 01226 01227 ADMW_RESULT admw1001_SetChannelOptions( 01228 ADMW_DEVICE_HANDLE hDevice, 01229 ADMW1001_CH_ID eChannelId, 01230 ADMW1001_CHANNEL_PRIORITY ePriority) 01231 { 01232 ADMW_CORE_Channel_Options_t channelOptionsReg; 01233 01234 channelOptionsReg.VALUE8 = REG_RESET_VAL(CORE_CHANNEL_OPTIONSn); 01235 01236 CHECK_REG_FIELD_VAL(CORE_CHANNEL_OPTIONS_CHANNEL_PRIORITY, ePriority); 01237 channelOptionsReg.Channel_Priority = ePriority; 01238 01239 WRITE_REG_U8(hDevice, channelOptionsReg.VALUE8, CORE_CHANNEL_OPTIONSn(eChannelId)); 01240 01241 return ADMW_SUCCESS ; 01242 } 01243 01244 ADMW_RESULT admw1001_SetChannelSkipCount( 01245 ADMW_DEVICE_HANDLE hDevice, 01246 ADMW1001_CH_ID eChannelId, 01247 uint32_t nCycleSkipCount) 01248 { 01249 ADMW_CORE_Channel_Skip_t channelSkipReg; 01250 01251 channelSkipReg.VALUE16 = REG_RESET_VAL(CORE_CHANNEL_SKIPn); 01252 01253 CHECK_REG_FIELD_VAL(CORE_CHANNEL_SKIP_CHANNEL_SKIP, nCycleSkipCount); 01254 01255 channelSkipReg.Channel_Skip = nCycleSkipCount; 01256 01257 WRITE_REG_U16(hDevice, channelSkipReg.VALUE16, CORE_CHANNEL_SKIPn(eChannelId)); 01258 01259 return ADMW_SUCCESS ; 01260 } 01261 01262 static ADMW_RESULT admw_SetChannelAdcSensorType( 01263 ADMW_DEVICE_HANDLE hDevice, 01264 ADMW1001_CH_ID eChannelId, 01265 ADMW1001_ADC_SENSOR_TYPE sensorType) 01266 { 01267 ADMW_CORE_Sensor_Type_t sensorTypeReg; 01268 01269 sensorTypeReg.VALUE16 = REG_RESET_VAL(CORE_SENSOR_TYPEn); 01270 01271 /* Ensure that the sensor type is valid for this channel */ 01272 switch(sensorType) { 01273 case ADMW1001_ADC_SENSOR_RTD_2WIRE_PT10 : 01274 01275 case ADMW1001_ADC_SENSOR_RTD_2WIRE_PT50 : 01276 case ADMW1001_ADC_SENSOR_RTD_2WIRE_PT100 : 01277 case ADMW1001_ADC_SENSOR_RTD_2WIRE_PT200 : 01278 case ADMW1001_ADC_SENSOR_RTD_2WIRE_PT500 : 01279 case ADMW1001_ADC_SENSOR_RTD_2WIRE_PT1000 : 01280 case ADMW1001_ADC_SENSOR_RTD_2WIRE_PT1000_0P00375 : 01281 case ADMW1001_ADC_SENSOR_RTD_2WIRE_NI120 : 01282 case ADMW1001_ADC_SENSOR_RTD_2WIRE_CUSTOM : 01283 case ADMW1001_ADC_SENSOR_RTD_4WIRE_PT10 : 01284 01285 case ADMW1001_ADC_SENSOR_RTD_4WIRE_PT50 : 01286 case ADMW1001_ADC_SENSOR_RTD_4WIRE_PT100 : 01287 case ADMW1001_ADC_SENSOR_RTD_4WIRE_PT200 : 01288 case ADMW1001_ADC_SENSOR_RTD_4WIRE_PT500 : 01289 case ADMW1001_ADC_SENSOR_RTD_4WIRE_PT1000 : 01290 case ADMW1001_ADC_SENSOR_RTD_4WIRE_PT1000_0P00375 : 01291 case ADMW1001_ADC_SENSOR_RTD_4WIRE_NI120 : 01292 case ADMW1001_ADC_SENSOR_RTD_4WIRE_CUSTOM : 01293 case ADMW1001_ADC_SENSOR_RTD_3WIRE_PT10 : 01294 01295 case ADMW1001_ADC_SENSOR_RTD_3WIRE_PT50 : 01296 case ADMW1001_ADC_SENSOR_RTD_3WIRE_PT100 : 01297 case ADMW1001_ADC_SENSOR_RTD_3WIRE_PT200 : 01298 case ADMW1001_ADC_SENSOR_RTD_3WIRE_PT500 : 01299 case ADMW1001_ADC_SENSOR_RTD_3WIRE_PT1000 : 01300 case ADMW1001_ADC_SENSOR_RTD_3WIRE_PT1000_0P00375 : 01301 01302 case ADMW1001_ADC_SENSOR_RTD_3WIRE_NI120 : 01303 case ADMW1001_ADC_SENSOR_RTD_3WIRE_CUSTOM : 01304 case ADMW1001_ADC_SENSOR_BRIDGE_4WIRE : 01305 case ADMW1001_ADC_SENSOR_BRIDGE_6WIRE : 01306 case ADMW1001_ADC_SENSOR_DIODE : 01307 case ADMW1001_ADC_SENSOR_THERMISTOR_44004_44033_2P252K_AT_25C : 01308 case ADMW1001_ADC_SENSOR_THERMISTOR_44005_44030_3K_AT_25C : 01309 case ADMW1001_ADC_SENSOR_THERMISTOR_44007_44034_5K_AT_25C : 01310 case ADMW1001_ADC_SENSOR_THERMISTOR_44006_44031_10K_AT_25C : 01311 case ADMW1001_ADC_SENSOR_THERMISTOR_44008_44032_30K_AT_25C : 01312 case ADMW1001_ADC_SENSOR_THERMISTOR_YSI_400 : 01313 case ADMW1001_ADC_SENSOR_THERMISTOR_SPECTRUM_1003K_1K : 01314 case ADMW1001_ADC_SENSOR_THERMISTOR_CUSTOM_STEINHART_HART : 01315 case ADMW1001_ADC_SENSOR_THERMISTOR_CUSTOM_TABLE : 01316 case ADMW1001_ADC_SENSOR_SINGLE_ENDED_ABSOLUTE : 01317 case ADMW1001_ADC_SENSOR_DIFFERENTIAL_ABSOLUTE : 01318 case ADMW1001_ADC_SENSOR_SINGLE_ENDED_RATIO : 01319 case ADMW1001_ADC_SENSOR_DIFFERENTIAL_RATIO : 01320 01321 if (! (ADMW1001_CHANNEL_IS_ADC_CJC(eChannelId) || 01322 ADMW1001_CHANNEL_IS_ADC(eChannelId) )) { 01323 ADMW_LOG_ERROR( 01324 "Invalid ADC sensor type %d specified for channel %d", 01325 sensorType, eChannelId); 01326 return ADMW_INVALID_PARAM ; 01327 } 01328 break; 01329 case ADMW1001_ADC_SENSOR_THERMOCOUPLE_J : 01330 case ADMW1001_ADC_SENSOR_THERMOCOUPLE_K : 01331 case ADMW1001_ADC_SENSOR_THERMOCOUPLE_T : 01332 case ADMW1001_ADC_SENSOR_THERMOCOUPLE_E : 01333 case ADMW1001_ADC_SENSOR_THERMOCOUPLE_N : 01334 case ADMW1001_ADC_SENSOR_THERMOCOUPLE_R : 01335 case ADMW1001_ADC_SENSOR_THERMOCOUPLE_S : 01336 case ADMW1001_ADC_SENSOR_THERMOCOUPLE_B : 01337 case ADMW1001_ADC_SENSOR_THERMOCOUPLE_CUSTOM : 01338 if (! ADMW1001_CHANNEL_IS_ADC_VOLTAGE(eChannelId)) { 01339 ADMW_LOG_ERROR( 01340 "Invalid ADC sensor type %d specified for channel %d", 01341 sensorType, eChannelId); 01342 return ADMW_INVALID_PARAM ; 01343 } 01344 break; 01345 default: 01346 ADMW_LOG_ERROR("Invalid/unsupported ADC sensor type %d specified", 01347 sensorType); 01348 return ADMW_INVALID_PARAM ; 01349 } 01350 01351 sensorTypeReg.Sensor_Type = sensorType; 01352 01353 WRITE_REG_U16(hDevice, sensorTypeReg.VALUE16, CORE_SENSOR_TYPEn(eChannelId)); 01354 01355 return ADMW_SUCCESS ; 01356 } 01357 01358 static ADMW_RESULT admw_SetChannelAdcSensorDetails( 01359 ADMW_DEVICE_HANDLE hDevice, 01360 ADMW1001_CH_ID eChannelId, 01361 ADMW1001_CHANNEL_CONFIG *pChannelConfig) 01362 /* 01363 * TODO - it would be nice if the general- vs. ADC-specific sensor details could be split into separate registers 01364 * General details: 01365 * - Measurement_Units 01366 * - Compensation_Channel 01367 * - CJC_Publish (if "CJC" was removed from the name) 01368 * ADC-specific details: 01369 * - PGA_Gain 01370 * - Reference_Select 01371 * - Reference_Buffer_Disable 01372 */ 01373 { 01374 ADMW1001_ADC_CHANNEL_CONFIG *pAdcChannelConfig = &pChannelConfig->adcChannelConfig ; 01375 ADMW1001_ADC_REFERENCE_TYPE refType = pAdcChannelConfig->reference ; 01376 ADMW_CORE_Sensor_Details_t sensorDetailsReg; 01377 01378 sensorDetailsReg.VALUE32 = REG_RESET_VAL(CORE_SENSOR_DETAILSn); 01379 01380 switch(pChannelConfig->measurementUnit ) { 01381 case ADMW1001_MEASUREMENT_UNIT_FAHRENHEIT : 01382 sensorDetailsReg.Measurement_Units = CORE_SENSOR_DETAILS_UNITS_DEGF; 01383 break; 01384 case ADMW1001_MEASUREMENT_UNIT_CELSIUS : 01385 sensorDetailsReg.Measurement_Units = CORE_SENSOR_DETAILS_UNITS_DEGC; 01386 break; 01387 case ADMW1001_MEASUREMENT_UNIT_UNSPECIFIED : 01388 sensorDetailsReg.Measurement_Units = CORE_SENSOR_DETAILS_UNITS_UNSPECIFIED; 01389 break; 01390 default: 01391 ADMW_LOG_ERROR("Invalid measurement unit %d specified", 01392 pChannelConfig->measurementUnit ); 01393 return ADMW_INVALID_PARAM ; 01394 } 01395 01396 if (pChannelConfig->compensationChannel == ADMW1001_CH_ID_NONE ) { 01397 sensorDetailsReg.Compensation_Disable = 1; 01398 sensorDetailsReg.Compensation_Channel = 0; 01399 } else { 01400 sensorDetailsReg.Compensation_Disable = 0; 01401 sensorDetailsReg.Compensation_Channel = pChannelConfig->compensationChannel ; 01402 } 01403 01404 switch(refType) { 01405 case ADMW1001_ADC_REFERENCE_VOLTAGE_INTERNAL : 01406 sensorDetailsReg.Reference_Select = CORE_SENSOR_DETAILS_REF_VINT; 01407 break; 01408 case ADMW1001_ADC_REFERENCE_VOLTAGE_EXTERNAL_1 : 01409 sensorDetailsReg.Reference_Select = CORE_SENSOR_DETAILS_REF_VEXT1; 01410 break; 01411 case ADMW1001_ADC_REFERENCE_VOLTAGE_AVDD : 01412 sensorDetailsReg.Reference_Select = CORE_SENSOR_DETAILS_REF_AVDD; 01413 break; 01414 default: 01415 ADMW_LOG_ERROR("Invalid ADC reference type %d specified", refType); 01416 return ADMW_INVALID_PARAM ; 01417 } 01418 01419 switch(pAdcChannelConfig->gain ) { 01420 case ADMW1001_ADC_GAIN_1X : 01421 sensorDetailsReg.PGA_Gain = CORE_SENSOR_DETAILS_PGA_GAIN_1; 01422 break; 01423 case ADMW1001_ADC_GAIN_2X : 01424 sensorDetailsReg.PGA_Gain = CORE_SENSOR_DETAILS_PGA_GAIN_2; 01425 break; 01426 case ADMW1001_ADC_GAIN_4X : 01427 sensorDetailsReg.PGA_Gain = CORE_SENSOR_DETAILS_PGA_GAIN_4; 01428 break; 01429 case ADMW1001_ADC_GAIN_8X : 01430 sensorDetailsReg.PGA_Gain = CORE_SENSOR_DETAILS_PGA_GAIN_8; 01431 break; 01432 case ADMW1001_ADC_GAIN_16X : 01433 sensorDetailsReg.PGA_Gain = CORE_SENSOR_DETAILS_PGA_GAIN_16; 01434 break; 01435 case ADMW1001_ADC_GAIN_32X : 01436 sensorDetailsReg.PGA_Gain = CORE_SENSOR_DETAILS_PGA_GAIN_32; 01437 break; 01438 case ADMW1001_ADC_GAIN_64X : 01439 sensorDetailsReg.PGA_Gain = CORE_SENSOR_DETAILS_PGA_GAIN_64; 01440 break; 01441 default: 01442 ADMW_LOG_ERROR("Invalid ADC gain %d specified", 01443 pAdcChannelConfig->gain ); 01444 return ADMW_INVALID_PARAM ; 01445 } 01446 01447 switch(pAdcChannelConfig->rtdCurve ) { 01448 case ADMW1001_ADC_RTD_CURVE_EUROPEAN : 01449 sensorDetailsReg.RTD_Curve = CORE_SENSOR_DETAILS_EUROPEAN_CURVE; 01450 break; 01451 case ADMW1001_ADC_RTD_CURVE_AMERICAN : 01452 sensorDetailsReg.RTD_Curve = CORE_SENSOR_DETAILS_AMERICAN_CURVE; 01453 break; 01454 case ADMW1001_ADC_RTD_CURVE_JAPANESE : 01455 sensorDetailsReg.RTD_Curve = CORE_SENSOR_DETAILS_JAPANESE_CURVE; 01456 break; 01457 case ADMW1001_ADC_RTD_CURVE_ITS90 : 01458 sensorDetailsReg.RTD_Curve = CORE_SENSOR_DETAILS_ITS90_CURVE; 01459 break; 01460 default: 01461 ADMW_LOG_ERROR("Invalid RTD Curve %d specified", 01462 pAdcChannelConfig->rtdCurve ); 01463 return ADMW_INVALID_PARAM ; 01464 } 01465 01466 if (pChannelConfig->disablePublishing ) { 01467 sensorDetailsReg.Do_Not_Publish = 1; 01468 } else { 01469 sensorDetailsReg.Do_Not_Publish = 0; 01470 } 01471 01472 switch (pChannelConfig->lutSelect ) { 01473 case ADMW1001_LUT_DEFAULT : 01474 case ADMW1001_LUT_CUSTOM : 01475 sensorDetailsReg.LUT_Select = pChannelConfig->lutSelect ; 01476 break; 01477 default: 01478 ADMW_LOG_ERROR("Invalid LUT selection %d specified", 01479 pChannelConfig->lutSelect ); 01480 return ADMW_INVALID_PARAM ; 01481 } 01482 01483 WRITE_REG_U32(hDevice, sensorDetailsReg.VALUE32, CORE_SENSOR_DETAILSn(eChannelId)); 01484 01485 return ADMW_SUCCESS ; 01486 } 01487 01488 static ADMW_RESULT admw_SetChannelAdcMeasurementSetup( 01489 ADMW_DEVICE_HANDLE hDevice, 01490 ADMW1001_CH_ID eChannelId, 01491 ADMW1001_ADC_CHANNEL_CONFIG *pAdcChannelConfig) 01492 { 01493 ADMW_CORE_Measurement_Setup_t MeasSetupReg; 01494 ADMW1001_ADC_FILTER_CONFIG *pFilterConfig = &pAdcChannelConfig->filter ; 01495 MeasSetupReg.VALUE32 = REG_RESET_VAL(CORE_MEASUREMENT_SETUPn); 01496 MeasSetupReg.Buffer_Bypass = pAdcChannelConfig->bufferBypass ; 01497 01498 if (pFilterConfig->type == ADMW1001_ADC_FILTER_SINC4 ) { 01499 MeasSetupReg.ADC_Filter_Type = CORE_MEASUREMENT_SETUP_ENABLE_SINC4; 01500 MeasSetupReg.ADC_SF = pFilterConfig->sf ; 01501 } else if (pFilterConfig->type == ADMW1001_ADC_FILTER_SINC3 ) { 01502 MeasSetupReg.ADC_Filter_Type = CORE_MEASUREMENT_SETUP_ENABLE_SINC3; 01503 MeasSetupReg.ADC_SF = pFilterConfig->sf ; 01504 } else { 01505 ADMW_LOG_ERROR("Invalid ADC filter type %d specified", 01506 pFilterConfig->type ); 01507 return ADMW_INVALID_PARAM ; 01508 } 01509 01510 /* chop mod ecan be 0 (none), 1 (HW, 2 (SW, 3 (HW+SW). */ 01511 MeasSetupReg.Chop_Mode = pFilterConfig->chopMode ; 01512 01513 if(pFilterConfig->notch1p2 ) 01514 MeasSetupReg.NOTCH_EN_2 = 1; 01515 else 01516 MeasSetupReg.NOTCH_EN_2 = 0; 01517 01518 WRITE_REG_U32(hDevice, MeasSetupReg.VALUE32, CORE_MEASUREMENT_SETUPn(eChannelId)); 01519 01520 return ADMW_SUCCESS ; 01521 } 01522 01523 static ADMW_RESULT admw_SetChannelAdcCurrentConfig( 01524 ADMW_DEVICE_HANDLE hDevice, 01525 ADMW1001_CH_ID eChannelId, 01526 ADMW1001_ADC_EXC_CURRENT_CONFIG *pCurrentConfig) 01527 { 01528 ADMW_CORE_Channel_Excitation_t channelExcitationReg; 01529 01530 channelExcitationReg.VALUE16 = REG_RESET_VAL(CORE_CHANNEL_EXCITATIONn); 01531 01532 if (pCurrentConfig->outputLevel == ADMW1001_ADC_NO_EXTERNAL_EXC_CURRENT ) 01533 channelExcitationReg.IOUT_Excitation_Current = CORE_CHANNEL_EXCITATION_NONE; 01534 else if (pCurrentConfig->outputLevel == ADMW1001_ADC_EXC_CURRENT_EXTERNAL ) 01535 channelExcitationReg.IOUT_Excitation_Current = CORE_CHANNEL_EXCITATION_EXTERNAL; 01536 else if (pCurrentConfig->outputLevel == ADMW1001_ADC_EXC_CURRENT_50uA ) 01537 channelExcitationReg.IOUT_Excitation_Current = CORE_CHANNEL_EXCITATION_IEXC_50UA; 01538 else if (pCurrentConfig->outputLevel == ADMW1001_ADC_EXC_CURRENT_100uA ) 01539 channelExcitationReg.IOUT_Excitation_Current = CORE_CHANNEL_EXCITATION_IEXC_100UA; 01540 else if (pCurrentConfig->outputLevel == ADMW1001_ADC_EXC_CURRENT_250uA ) 01541 channelExcitationReg.IOUT_Excitation_Current = CORE_CHANNEL_EXCITATION_IEXC_250UA; 01542 else if (pCurrentConfig->outputLevel == ADMW1001_ADC_EXC_CURRENT_500uA ) 01543 channelExcitationReg.IOUT_Excitation_Current = CORE_CHANNEL_EXCITATION_IEXC_500UA; 01544 else if (pCurrentConfig->outputLevel == ADMW1001_ADC_EXC_CURRENT_1000uA ) 01545 channelExcitationReg.IOUT_Excitation_Current = CORE_CHANNEL_EXCITATION_IEXC_1000UA; 01546 else { 01547 ADMW_LOG_ERROR("Invalid ADC excitation current %d specified", 01548 pCurrentConfig->outputLevel ); 01549 return ADMW_INVALID_PARAM ; 01550 } 01551 01552 WRITE_REG_U16(hDevice, channelExcitationReg.VALUE16, CORE_CHANNEL_EXCITATIONn(eChannelId)); 01553 01554 return ADMW_SUCCESS ; 01555 } 01556 01557 ADMW_RESULT admw_SetAdcChannelConfig( 01558 ADMW_DEVICE_HANDLE hDevice, 01559 ADMW1001_CH_ID eChannelId, 01560 ADMW1001_CHANNEL_CONFIG *pChannelConfig) 01561 { 01562 ADMW_RESULT eRet; 01563 ADMW1001_ADC_CHANNEL_CONFIG *pAdcChannelConfig = 01564 &pChannelConfig->adcChannelConfig ; 01565 01566 eRet = admw_SetChannelAdcSensorType(hDevice, eChannelId, 01567 pAdcChannelConfig->sensor ); 01568 if (eRet != ADMW_SUCCESS ) { 01569 ADMW_LOG_ERROR("Failed to set ADC sensor type for channel %d", 01570 eChannelId); 01571 return eRet; 01572 } 01573 01574 eRet = admw_SetChannelAdcSensorDetails(hDevice, eChannelId, 01575 pChannelConfig); 01576 if (eRet != ADMW_SUCCESS ) { 01577 ADMW_LOG_ERROR("Failed to set ADC sensor details for channel %d", 01578 eChannelId); 01579 return eRet; 01580 } 01581 01582 eRet = admw_SetChannelAdcMeasurementSetup(hDevice, eChannelId, 01583 pAdcChannelConfig); 01584 if (eRet != ADMW_SUCCESS ) { 01585 ADMW_LOG_ERROR("Failed to set ADC filter for channel %d", 01586 eChannelId); 01587 return eRet; 01588 } 01589 01590 eRet = admw_SetChannelAdcCurrentConfig(hDevice, eChannelId, 01591 &pAdcChannelConfig->current ); 01592 if (eRet != ADMW_SUCCESS ) { 01593 ADMW_LOG_ERROR("Failed to set ADC current for channel %d", 01594 eChannelId); 01595 return eRet; 01596 } 01597 01598 return ADMW_SUCCESS ; 01599 } 01600 01601 static ADMW_RESULT admw_SetChannelDigitalSensorDetails( 01602 ADMW_DEVICE_HANDLE hDevice, 01603 ADMW1001_CH_ID eChannelId, 01604 ADMW1001_CHANNEL_CONFIG *pChannelConfig) 01605 { 01606 ADMW_CORE_Sensor_Details_t sensorDetailsReg; 01607 01608 sensorDetailsReg.VALUE32 = REG_RESET_VAL(CORE_SENSOR_DETAILSn); 01609 01610 if (pChannelConfig->compensationChannel == ADMW1001_CH_ID_NONE ) { 01611 sensorDetailsReg.Compensation_Disable = 1; 01612 sensorDetailsReg.Compensation_Channel = 0; 01613 } else { 01614 ADMW_LOG_ERROR("Invalid compensation channel specified for digital sensor"); 01615 return ADMW_INVALID_PARAM ; 01616 } 01617 01618 if (pChannelConfig->measurementUnit == ADMW1001_MEASUREMENT_UNIT_UNSPECIFIED ) { 01619 sensorDetailsReg.Measurement_Units = CORE_SENSOR_DETAILS_UNITS_UNSPECIFIED; 01620 } else { 01621 ADMW_LOG_ERROR("Invalid measurement unit specified for digital channel"); 01622 return ADMW_INVALID_PARAM ; 01623 } 01624 01625 if (pChannelConfig->disablePublishing ) 01626 sensorDetailsReg.Do_Not_Publish = 1; 01627 else 01628 sensorDetailsReg.Do_Not_Publish = 0; 01629 01630 WRITE_REG_U32(hDevice, sensorDetailsReg.VALUE32, CORE_SENSOR_DETAILSn(eChannelId)); 01631 01632 return ADMW_SUCCESS ; 01633 } 01634 01635 static ADMW_RESULT admw_SetDigitalSensorFormat( 01636 ADMW_DEVICE_HANDLE hDevice, 01637 ADMW1001_CH_ID eChannelId, 01638 ADMW1001_DIGITAL_SENSOR_DATA_FORMAT *pDataFormat) 01639 { 01640 ADMW_CORE_Digital_Sensor_Config_t sensorConfigReg; 01641 01642 sensorConfigReg.VALUE16 = REG_RESET_VAL(CORE_DIGITAL_SENSOR_CONFIGn); 01643 01644 if (pDataFormat->coding != ADMW1001_DIGITAL_SENSOR_DATA_CODING_NONE) { 01645 if (pDataFormat->frameLength == 0) { 01646 ADMW_LOG_ERROR("Invalid frame length specified for digital sensor data format"); 01647 return ADMW_INVALID_PARAM ; 01648 } 01649 if (pDataFormat->numDataBits == 0) { 01650 ADMW_LOG_ERROR("Invalid frame length specified for digital sensor data format"); 01651 return ADMW_INVALID_PARAM ; 01652 } 01653 01654 CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_CONFIG_DIGITAL_SENSOR_READ_BYTES, 01655 pDataFormat->frameLength - 1); 01656 CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_CONFIG_DIGITAL_SENSOR_DATA_BITS, 01657 pDataFormat->numDataBits - 1); 01658 CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_CONFIG_DIGITAL_SENSOR_BIT_OFFSET, 01659 pDataFormat->bitOffset); 01660 01661 sensorConfigReg.Digital_Sensor_Read_Bytes = pDataFormat->frameLength - 1; 01662 sensorConfigReg.Digital_Sensor_Data_Bits = pDataFormat->numDataBits - 1; 01663 sensorConfigReg.Digital_Sensor_Bit_Offset = pDataFormat->bitOffset; 01664 sensorConfigReg.Digital_Sensor_Left_Aligned = pDataFormat->leftJustified ? 1 : 0; 01665 sensorConfigReg.Digital_Sensor_Little_Endian = pDataFormat->littleEndian ? 1 : 0; 01666 01667 switch (pDataFormat->coding) { 01668 case ADMW1001_DIGITAL_SENSOR_DATA_CODING_UNIPOLAR: 01669 sensorConfigReg.Digital_Sensor_Coding = CORE_DIGITAL_SENSOR_CONFIG_CODING_UNIPOLAR; 01670 break; 01671 case ADMW1001_DIGITAL_SENSOR_DATA_CODING_TWOS_COMPLEMENT: 01672 sensorConfigReg.Digital_Sensor_Coding = CORE_DIGITAL_SENSOR_CONFIG_CODING_TWOS_COMPL; 01673 break; 01674 case ADMW1001_DIGITAL_SENSOR_DATA_CODING_OFFSET_BINARY: 01675 sensorConfigReg.Digital_Sensor_Coding = CORE_DIGITAL_SENSOR_CONFIG_CODING_OFFSET_BINARY; 01676 break; 01677 default: 01678 ADMW_LOG_ERROR("Invalid coding specified for digital sensor data format"); 01679 return ADMW_INVALID_PARAM ; 01680 } 01681 } else { 01682 sensorConfigReg.Digital_Sensor_Coding = CORE_DIGITAL_SENSOR_CONFIG_CODING_NONE; 01683 } 01684 01685 WRITE_REG_U16(hDevice, sensorConfigReg.VALUE16, 01686 CORE_DIGITAL_SENSOR_CONFIGn(eChannelId)); 01687 01688 01689 return ADMW_SUCCESS ; 01690 } 01691 01692 01693 static ADMW_RESULT admw_SetChannelI2cSensorType( 01694 ADMW_DEVICE_HANDLE hDevice, 01695 ADMW1001_CH_ID eChannelId, 01696 ADMW1001_I2C_SENSOR_TYPE sensorType) 01697 { 01698 ADMW_CORE_Sensor_Type_t sensorTypeReg; 01699 01700 sensorTypeReg.VALUE16 = REG_RESET_VAL(CORE_SENSOR_TYPEn); 01701 01702 /* Ensure that the sensor type is valid for this channel */ 01703 switch(sensorType) { 01704 case ADMW1001_I2C_SENSOR_HUMIDITY : 01705 case ADMW1001_I2C_SENSOR_TEMPERATURE_ADT742X : 01706 sensorTypeReg.Sensor_Type = sensorType; 01707 break; 01708 default: 01709 ADMW_LOG_ERROR("Unsupported I2C sensor type %d specified", sensorType); 01710 return ADMW_INVALID_PARAM ; 01711 } 01712 01713 WRITE_REG_U16(hDevice, sensorTypeReg.VALUE16, CORE_SENSOR_TYPEn(eChannelId)); 01714 01715 return ADMW_SUCCESS ; 01716 } 01717 01718 static ADMW_RESULT admw_SetChannelI2cSensorAddress( 01719 ADMW_DEVICE_HANDLE hDevice, 01720 ADMW1001_CH_ID eChannelId, 01721 uint32_t deviceAddress) 01722 { 01723 CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_ADDRESS_DIGITAL_SENSOR_ADDRESS, deviceAddress); 01724 WRITE_REG_U8(hDevice, deviceAddress, CORE_DIGITAL_SENSOR_ADDRESSn(eChannelId)); 01725 01726 return ADMW_SUCCESS ; 01727 } 01728 01729 static ADMW_RESULT admw_SetDigitalChannelComms( 01730 ADMW_DEVICE_HANDLE hDevice, 01731 ADMW1001_CH_ID eChannelId, 01732 ADMW1001_DIGITAL_SENSOR_COMMS *pDigitalComms) 01733 { 01734 ADMW_CORE_Digital_Sensor_Comms_t digitalSensorComms; 01735 01736 digitalSensorComms.VALUE16 = REG_RESET_VAL(CORE_DIGITAL_SENSOR_COMMSn); 01737 01738 if(pDigitalComms->useCustomCommsConfig ) { 01739 01740 if(pDigitalComms->i2cClockSpeed == ADMW1001_DIGITAL_SENSOR_COMMS_I2C_CLOCK_SPEED_100K ) { 01741 digitalSensorComms.I2C_Clock = CORE_DIGITAL_SENSOR_COMMS_I2C_100K; 01742 } else if(pDigitalComms->i2cClockSpeed == ADMW1001_DIGITAL_SENSOR_COMMS_I2C_CLOCK_SPEED_400K ) { 01743 digitalSensorComms.I2C_Clock = CORE_DIGITAL_SENSOR_COMMS_I2C_400K; 01744 } else { 01745 ADMW_LOG_ERROR("Invalid I2C clock speed %d specified", 01746 pDigitalComms->i2cClockSpeed ); 01747 return ADMW_INVALID_PARAM ; 01748 } 01749 } 01750 WRITE_REG_U16(hDevice, digitalSensorComms.VALUE16, CORE_DIGITAL_SENSOR_COMMSn(eChannelId)); 01751 01752 return ADMW_SUCCESS ; 01753 } 01754 01755 ADMW_RESULT admw_SetI2cChannelConfig( 01756 ADMW_DEVICE_HANDLE hDevice, 01757 ADMW1001_CH_ID eChannelId, 01758 ADMW1001_CHANNEL_CONFIG *pChannelConfig) 01759 { 01760 ADMW_RESULT eRet; 01761 ADMW1001_I2C_CHANNEL_CONFIG *pI2cChannelConfig = 01762 &pChannelConfig->i2cChannelConfig ; 01763 01764 eRet = admw_SetChannelI2cSensorType(hDevice, eChannelId, 01765 pI2cChannelConfig->sensor ); 01766 if (eRet != ADMW_SUCCESS ) { 01767 ADMW_LOG_ERROR("Failed to set I2C sensor type for channel %d", 01768 eChannelId); 01769 return eRet; 01770 } 01771 01772 eRet = admw_SetChannelI2cSensorAddress(hDevice, eChannelId, 01773 pI2cChannelConfig->deviceAddress ); 01774 if (eRet != ADMW_SUCCESS ) { 01775 ADMW_LOG_ERROR("Failed to set I2C sensor address for channel %d", 01776 eChannelId); 01777 return eRet; 01778 } 01779 01780 eRet = admw_SetChannelDigitalSensorDetails(hDevice, eChannelId, 01781 pChannelConfig); 01782 if (eRet != ADMW_SUCCESS ) { 01783 ADMW_LOG_ERROR("Failed to set I2C sensor details for channel %d", 01784 eChannelId); 01785 return eRet; 01786 } 01787 01788 eRet = admw_SetDigitalSensorFormat(hDevice, eChannelId, 01789 &pI2cChannelConfig->dataFormat ); 01790 if (eRet != ADMW_SUCCESS ) { 01791 ADMW_LOG_ERROR("Failed to set I2C sensor data format for channel %d", 01792 eChannelId); 01793 return eRet; 01794 } 01795 01796 01797 eRet = admw_SetDigitalChannelComms(hDevice, eChannelId, 01798 &pI2cChannelConfig->configureComms ); 01799 if (eRet != ADMW_SUCCESS ) { 01800 ADMW_LOG_ERROR("Failed to set I2C comms for channel %d", 01801 eChannelId); 01802 return eRet; 01803 } 01804 01805 return ADMW_SUCCESS ; 01806 } 01807 01808 static ADMW_RESULT admw_SetChannelSpiSensorType( 01809 ADMW_DEVICE_HANDLE hDevice, 01810 ADMW1001_CH_ID eChannelId, 01811 ADMW1001_SPI_SENSOR_TYPE sensorType) 01812 { 01813 ADMW_CORE_Sensor_Type_t sensorTypeReg; 01814 01815 sensorTypeReg.VALUE16 = REG_RESET_VAL(CORE_SENSOR_TYPEn); 01816 01817 /* Ensure that the sensor type is valid for this channel */ 01818 switch(sensorType) { 01819 case ADMW1001_SPI_SENSOR: 01820 01821 sensorTypeReg.Sensor_Type = sensorType; 01822 break; 01823 default: 01824 ADMW_LOG_ERROR("Unsupported SPI sensor type %d specified", sensorType); 01825 return ADMW_INVALID_PARAM ; 01826 } 01827 01828 WRITE_REG_U16(hDevice, sensorTypeReg.VALUE16, CORE_SENSOR_TYPEn(eChannelId)); 01829 01830 return ADMW_SUCCESS ; 01831 } 01832 01833 01834 ADMW_RESULT admw1001_SetChannelThresholdLimits( 01835 ADMW_DEVICE_HANDLE hDevice, 01836 ADMW1001_CH_ID eChannelId, 01837 float32_t fHighThresholdLimit, 01838 float32_t fLowThresholdLimit) 01839 { 01840 /* 01841 * If the low/high limits are *both* set to 0 in memory, or NaNs, assume 01842 * that they are unset, or not required, and use infinity defaults instead 01843 */ 01844 if (fHighThresholdLimit == 0.0f && fLowThresholdLimit == 0.0f) { 01845 fHighThresholdLimit = INFINITY; 01846 fLowThresholdLimit = -INFINITY; 01847 } else { 01848 if (isnan(fHighThresholdLimit)) 01849 fHighThresholdLimit = INFINITY; 01850 if (isnan(fLowThresholdLimit)) 01851 fLowThresholdLimit = -INFINITY; 01852 } 01853 01854 WRITE_REG_FLOAT(hDevice, fHighThresholdLimit, 01855 CORE_HIGH_THRESHOLD_LIMITn(eChannelId)); 01856 WRITE_REG_FLOAT(hDevice, fLowThresholdLimit, 01857 CORE_LOW_THRESHOLD_LIMITn(eChannelId)); 01858 01859 return ADMW_SUCCESS ; 01860 } 01861 01862 ADMW_RESULT admw1001_SetOffsetGain( 01863 ADMW_DEVICE_HANDLE hDevice, 01864 ADMW1001_CH_ID eChannelId, 01865 float32_t fOffsetAdjustment, 01866 float32_t fGainAdjustment) 01867 { 01868 /* Replace with default values if NaNs are specified (or 0.0 for gain) */ 01869 if (isnan(fGainAdjustment) || (fGainAdjustment == 0.0f)) 01870 fGainAdjustment = 1.0f; 01871 if (isnan(fOffsetAdjustment)) 01872 fOffsetAdjustment = 0.0f; 01873 01874 WRITE_REG_FLOAT(hDevice, fGainAdjustment, CORE_SENSOR_GAINn(eChannelId)); 01875 WRITE_REG_FLOAT(hDevice, fOffsetAdjustment, CORE_SENSOR_OFFSETn(eChannelId)); 01876 01877 return ADMW_SUCCESS ; 01878 } 01879 01880 ADMW_RESULT admw1001_SetSensorParameter( 01881 ADMW_DEVICE_HANDLE hDevice, 01882 ADMW1001_CH_ID eChannelId, 01883 float32_t fSensorParam) 01884 { 01885 if (fSensorParam == 0.0f) 01886 fSensorParam = NAN; 01887 01888 //WRITE_REG_FLOAT(hDevice, fSensorParam, CORE_SENSOR_PARAMETERn(eChannelId)); 01889 01890 return ADMW_SUCCESS ; 01891 } 01892 01893 ADMW_RESULT admw1001_SetChannelSettlingTime( 01894 ADMW_DEVICE_HANDLE hDevice, 01895 ADMW1001_CH_ID eChannelId, 01896 uint32_t nSettlingTime) 01897 { 01898 ADMW_CORE_Settling_Time_t settlingTimeReg; 01899 01900 CHECK_REG_FIELD_VAL(CORE_SETTLING_TIME_SETTLING_TIME, nSettlingTime); 01901 settlingTimeReg.Settling_Time = nSettlingTime; 01902 01903 WRITE_REG_U16(hDevice, settlingTimeReg.VALUE16, CORE_SETTLING_TIMEn(eChannelId)); 01904 01905 return ADMW_SUCCESS ; 01906 } 01907 01908 ADMW_RESULT admw1001_SetChannelConfig( 01909 ADMW_DEVICE_HANDLE hDevice, 01910 ADMW1001_CH_ID eChannelId, 01911 ADMW1001_CHANNEL_CONFIG *pChannelConfig) 01912 { 01913 ADMW_RESULT eRet; 01914 01915 eRet = admw1001_SetChannelCount(hDevice, eChannelId, 01916 pChannelConfig->enableChannel ? 01917 pChannelConfig->measurementsPerCycle : 0); 01918 if (eRet != ADMW_SUCCESS ) { 01919 ADMW_LOG_ERROR("Failed to set measurement count for channel %d", 01920 eChannelId); 01921 return eRet; 01922 } 01923 01924 eRet = admw1001_SetChannelOptions(hDevice, eChannelId, 01925 pChannelConfig->priority ); 01926 if (eRet != ADMW_SUCCESS ) { 01927 ADMW_LOG_ERROR("Failed to set priority for channel %d", 01928 eChannelId); 01929 return eRet; 01930 } 01931 01932 /* If the channel is not enabled, we can skip the following steps */ 01933 if (pChannelConfig->enableChannel ) { 01934 eRet = admw1001_SetChannelSkipCount(hDevice, eChannelId, 01935 pChannelConfig->cycleSkipCount ); 01936 if (eRet != ADMW_SUCCESS ) { 01937 ADMW_LOG_ERROR("Failed to set cycle skip count for channel %d", 01938 eChannelId); 01939 return eRet; 01940 } 01941 01942 switch (eChannelId) { 01943 case ADMW1001_CH_ID_ANLG_1_UNIVERSAL : 01944 case ADMW1001_CH_ID_ANLG_2_UNIVERSAL : 01945 case ADMW1001_CH_ID_ANLG_1_DIFFERENTIAL : 01946 case ADMW1001_CH_ID_ANLG_2_DIFFERENTIAL : 01947 eRet = admw_SetAdcChannelConfig(hDevice, eChannelId, pChannelConfig); 01948 break; 01949 case ADMW1001_CH_ID_DIG_I2C_0 : 01950 case ADMW1001_CH_ID_DIG_I2C_1 : 01951 eRet = admw_SetI2cChannelConfig(hDevice, eChannelId, pChannelConfig); 01952 break; 01953 default: 01954 ADMW_LOG_ERROR("Invalid channel ID %d specified", eChannelId); 01955 eRet = ADMW_INVALID_PARAM ; 01956 #if 0 01957 /* when using i2c sensors there is an error ( dataformat->length=0) 01958 the code below catches this error and this causes further problems.*/ 01959 break; 01960 } 01961 if (eRet != ADMW_SUCCESS ) { 01962 ADMW_LOG_ERROR("Failed to set config for channel %d", 01963 eChannelId); 01964 return eRet; 01965 #endif 01966 } 01967 01968 eRet = admw1001_SetChannelSettlingTime(hDevice, eChannelId, 01969 pChannelConfig->extraSettlingTime ); 01970 if (eRet != ADMW_SUCCESS ) { 01971 ADMW_LOG_ERROR("Failed to set settling time for channel %d", 01972 eChannelId); 01973 return eRet; 01974 } 01975 } 01976 01977 if (pChannelConfig->enableChannel ) { 01978 /* Threshold limits can be configured individually for virtual channels */ 01979 eRet = admw1001_SetChannelThresholdLimits(hDevice, eChannelId, 01980 pChannelConfig->highThreshold , 01981 pChannelConfig->lowThreshold ); 01982 if (eRet != ADMW_SUCCESS ) { 01983 ADMW_LOG_ERROR("Failed to set threshold limits for channel %d", 01984 eChannelId); 01985 return eRet; 01986 } 01987 01988 /* Offset and gain can be configured individually for virtual channels */ 01989 eRet = admw1001_SetOffsetGain(hDevice, eChannelId, 01990 pChannelConfig->offsetAdjustment , 01991 pChannelConfig->gainAdjustment ); 01992 if (eRet != ADMW_SUCCESS ) { 01993 ADMW_LOG_ERROR("Failed to set offset/gain for channel %d", 01994 eChannelId); 01995 return eRet; 01996 } 01997 01998 /* Set sensor specific parameter */ 01999 eRet = admw1001_SetSensorParameter(hDevice, eChannelId, 02000 pChannelConfig->sensorParameter ); 02001 if (eRet != ADMW_SUCCESS ) { 02002 ADMW_LOG_ERROR("Failed to set sensor parameter for channel %d", 02003 eChannelId); 02004 return eRet; 02005 } 02006 } 02007 02008 return ADMW_SUCCESS ; 02009 } 02010 02011 ADMW_RESULT admw_SetConfig( 02012 ADMW_DEVICE_HANDLE const hDevice, 02013 ADMW_CONFIG * const pConfig) 02014 { 02015 ADMW1001_CONFIG *pDeviceConfig; 02016 ADMW_PRODUCT_ID productId; 02017 ADMW_RESULT eRet; 02018 02019 if (pConfig->productId != ADMW_PRODUCT_ID_ADMW1001 ) { 02020 ADMW_LOG_ERROR("Configuration Product ID (0x%X) is not supported (0x%0X)", 02021 pConfig->productId , ADMW_PRODUCT_ID_ADMW1001 ); 02022 return ADMW_INVALID_PARAM ; 02023 } 02024 02025 if (!((pConfig->versionId .major ==VERSIONID_MAJOR) && 02026 (pConfig->versionId .minor ==VERSIONID_MINOR))) { 02027 ADMW_LOG_ERROR("Configuration Version ID (0x%X) is not supported", 02028 pConfig->versionId ); 02029 return ADMW_INVALID_PARAM ; 02030 } 02031 02032 02033 /* Check that the actual Product ID is a match? */ 02034 eRet = admw_GetProductID(hDevice, &productId); 02035 if (eRet) { 02036 ADMW_LOG_ERROR("Failed to read device Product ID register"); 02037 return eRet; 02038 } 02039 if (pConfig->productId != productId) { 02040 ADMW_LOG_ERROR("Configuration Product ID (0x%X) does not match device (0x%0X)", 02041 pConfig->productId , productId); 02042 return ADMW_INVALID_PARAM ; 02043 } 02044 02045 pDeviceConfig = &pConfig->admw1001 ; 02046 02047 eRet = admw1001_SetPowerConfig(hDevice, &pDeviceConfig->power ); 02048 if (eRet) { 02049 ADMW_LOG_ERROR("Failed to set power configuration"); 02050 return eRet; 02051 } 02052 02053 eRet = admw1001_SetMeasurementConfig(hDevice, &pDeviceConfig->measurement ); 02054 if (eRet) { 02055 ADMW_LOG_ERROR("Failed to set measurement configuration"); 02056 return eRet; 02057 } 02058 02059 eRet = admw1001_SetDiagnosticsConfig(hDevice, &pDeviceConfig->diagnostics ); 02060 if (eRet) { 02061 ADMW_LOG_ERROR("Failed to set diagnostics configuration"); 02062 return eRet; 02063 } 02064 02065 for (ADMW1001_CH_ID id = ADMW1001_CH_ID_ANLG_1_UNIVERSAL ; 02066 id < ADMW1001_MAX_CHANNELS ; 02067 id++) { 02068 eRet = admw1001_SetChannelConfig(hDevice, id, 02069 &pDeviceConfig->channels [id]); 02070 if (eRet) { 02071 ADMW_LOG_ERROR("Failed to set channel %d configuration", id); 02072 return eRet; 02073 } 02074 } 02075 02076 return ADMW_SUCCESS ; 02077 } 02078 02079 02080 ADMW_RESULT admw1001_SetLutDataRaw( 02081 ADMW_DEVICE_HANDLE const hDevice, 02082 ADMW1001_LUT_RAW * const pLutData) 02083 { 02084 return admw1001_SetLutData(hDevice, 02085 (ADMW1001_LUT *)pLutData); 02086 } 02087 02088 static ADMW_RESULT getLutTableSize( 02089 ADMW1001_LUT_DESCRIPTOR * const pDesc, 02090 ADMW1001_LUT_TABLE_DATA * const pData, 02091 unsigned *pLength) 02092 { 02093 switch (pDesc->geometry) { 02094 case ADMW1001_LUT_GEOMETRY_NES_1D: 02095 *pLength = ADMW1001_LUT_1D_NES_SIZE(pData->lut1dNes); 02096 break; 02097 default: 02098 ADMW_LOG_ERROR("Invalid LUT table geometry %d specified\r\n", 02099 pDesc->geometry); 02100 return ADMW_INVALID_PARAM ; 02101 } 02102 02103 return ADMW_SUCCESS ; 02104 } 02105 02106 ADMW_RESULT admw1001_AssembleLutData( 02107 ADMW1001_LUT * pLutBuffer, 02108 unsigned nLutBufferSize, 02109 unsigned const nNumTables, 02110 ADMW1001_LUT_DESCRIPTOR * const ppDesc[], 02111 ADMW1001_LUT_TABLE_DATA * const ppData[]) 02112 { 02113 ADMW1001_LUT_HEADER *pHdr = &pLutBuffer->header; 02114 uint8_t *pLutTableData = (uint8_t *)pLutBuffer + sizeof(*pHdr); 02115 02116 if (sizeof(*pHdr) > nLutBufferSize) 02117 { 02118 ADMW_LOG_ERROR("Insufficient LUT buffer size provided"); 02119 return ADMW_INVALID_PARAM ; 02120 } 02121 02122 /* First initialise the top-level header */ 02123 pHdr->signature = ADMW_LUT_SIGNATURE; 02124 pHdr->version.major = 1; 02125 pHdr->version.minor = 0; 02126 pHdr->numTables = 0; 02127 pHdr->totalLength = 0; 02128 02129 /* 02130 * Walk through the list of table pointers provided, appending the table 02131 * descriptor+data from each one to the provided LUT buffer 02132 */ 02133 for (unsigned i = 0; i < nNumTables; i++) 02134 { 02135 ADMW1001_LUT_DESCRIPTOR * const pDesc = ppDesc[i]; 02136 ADMW1001_LUT_TABLE_DATA * const pData = ppData[i]; 02137 ADMW_RESULT res; 02138 unsigned dataLength = 0; 02139 02140 /* Calculate the length of the table data */ 02141 res = getLutTableSize(pDesc, pData, &dataLength); 02142 if (res != ADMW_SUCCESS ) 02143 return res; 02144 02145 /* Fill in the table descriptor length and CRC fields */ 02146 pDesc->length = dataLength; 02147 02148 if ((sizeof(*pHdr) + pHdr->totalLength + sizeof(*pDesc) + dataLength) > nLutBufferSize) 02149 { 02150 ADMW_LOG_ERROR("Insufficient LUT buffer size provided"); 02151 return ADMW_INVALID_PARAM ; 02152 } 02153 02154 /* Append the table to the LUT buffer (desc + data) */ 02155 memcpy(pLutTableData + pHdr->totalLength, pDesc, sizeof(*pDesc)); 02156 pHdr->totalLength += sizeof(*pDesc); 02157 memcpy(pLutTableData + pHdr->totalLength, pData, dataLength); 02158 pHdr->totalLength += dataLength; 02159 02160 pHdr->numTables++; 02161 } 02162 02163 return ADMW_SUCCESS ; 02164 } 02165 ADMW_RESULT admw1001_SetLutData( 02166 ADMW_DEVICE_HANDLE const hDevice, 02167 ADMW1001_LUT * const pLutData) 02168 { 02169 #pragma diag_suppress=Pa039 02170 ADMW1001_LUT_HEADER *pLutHeader = &pLutData->header; 02171 ADMW1001_LUT_TABLE *pLutTable = pLutData->tables; 02172 02173 unsigned actualLength = 0; 02174 02175 if (pLutData->header.signature != ADMW_LUT_SIGNATURE) 02176 { 02177 ADMW_LOG_ERROR("LUT signature incorrect (expected 0x%X, actual 0x%X)", 02178 ADMW_LUT_SIGNATURE, pLutHeader->signature); 02179 return ADMW_INVALID_SIGNATURE ; 02180 } 02181 if ((pLutData->tables->descriptor.geometry!= ADMW1001_LUT_GEOMETRY_NES_1D) && 02182 (pLutData->tables->data.lut1dNes.nElements > MAX_LUT_NUM_ENTRIES)) 02183 { 02184 return ADMW_INVALID_PARAM ; 02185 } 02186 for (unsigned i = 0; i < pLutHeader->numTables; i++) 02187 { 02188 ADMW1001_LUT_DESCRIPTOR *pDesc = &pLutTable->descriptor; 02189 02190 switch (pDesc->geometry) 02191 { 02192 case ADMW1001_LUT_GEOMETRY_COEFFS: 02193 switch (pDesc->equation) 02194 { 02195 case ADMW1001_LUT_EQUATION_POLYN: 02196 case ADMW1001_LUT_EQUATION_POLYNEXP: 02197 case ADMW1001_LUT_EQUATION_QUADRATIC: 02198 case ADMW1001_LUT_EQUATION_STEINHART: 02199 case ADMW1001_LUT_EQUATION_LOGARITHMIC: 02200 case ADMW1001_LUT_EQUATION_BIVARIATE_POLYN: 02201 break; 02202 default: 02203 ADMW_LOG_ERROR("Invalid equation %u specified for LUT table %u", 02204 pDesc->equation, i); 02205 return ADMW_INVALID_PARAM ; 02206 } 02207 break; 02208 case ADMW1001_LUT_GEOMETRY_NES_1D: 02209 break; 02210 default: 02211 ADMW_LOG_ERROR("Invalid geometry %u specified for LUT table %u", 02212 pDesc->geometry, i); 02213 return ADMW_INVALID_PARAM ; 02214 } 02215 02216 switch (pDesc->dataType) 02217 { 02218 case ADMW1001_LUT_DATA_TYPE_FLOAT32: 02219 case ADMW1001_LUT_DATA_TYPE_FLOAT64: 02220 break; 02221 default: 02222 ADMW_LOG_ERROR("Invalid vector format %u specified for LUT table %u", 02223 pDesc->dataType, i); 02224 return ADMW_INVALID_PARAM ; 02225 } 02226 02227 02228 actualLength += sizeof(*pDesc) + pDesc->length; 02229 02230 /* Move to the next look-up table */ 02231 pLutTable = (ADMW1001_LUT_TABLE *)((uint8_t *)pLutTable + sizeof(*pDesc) + pDesc->length); 02232 } 02233 02234 if (actualLength != pLutHeader->totalLength) 02235 { 02236 ADMW_LOG_ERROR("LUT table length mismatch (expected %u, actual %u)", 02237 pLutHeader->totalLength, actualLength); 02238 return ADMW_WRONG_SIZE ; 02239 } 02240 02241 if (sizeof(*pLutHeader) + pLutHeader->totalLength > ADMW_LUT_MAX_SIZE) 02242 { 02243 ADMW_LOG_ERROR("Maximum LUT table length (%u bytes) exceeded", 02244 ADMW_LUT_MAX_SIZE); 02245 return ADMW_WRONG_SIZE ; 02246 } 02247 02248 /* Write the LUT data to the device */ 02249 unsigned lutSize = sizeof(*pLutHeader) + pLutHeader->totalLength; 02250 WRITE_REG_U16(hDevice, 0, CORE_LUT_OFFSET); 02251 WRITE_REG_U8_ARRAY(hDevice, (uint8_t *)pLutData, lutSize, CORE_LUT_DATA); 02252 02253 return ADMW_SUCCESS ; 02254 }
Generated on Thu Jul 14 2022 10:33:00 by 1.7.2