Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
admw_1001.c
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 if (statusReg.Drdy) 00320 pStatus->deviceStatus |= ADMW_DEVICE_STATUS_DATAREADY ; 00321 if (statusReg.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) { 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 ADMW_RESULT admw1001_SetMeasurementConfig( 01067 ADMW_DEVICE_HANDLE hDevice, 01068 ADMW1001_MEASUREMENT_CONFIG *pMeasConfig) 01069 { 01070 ADMW_RESULT eRet; 01071 01072 eRet = admw_SetMode(hDevice, 01073 pMeasConfig->operatingMode , 01074 pMeasConfig->dataReadyMode ); 01075 if (eRet != ADMW_SUCCESS ) { 01076 ADMW_LOG_ERROR("Failed to set operating mode"); 01077 return eRet; 01078 } 01079 01080 eRet = admw_SetCycleControl(hDevice, pMeasConfig->cycleInterval , 01081 pMeasConfig->vBiasEnable , 01082 pMeasConfig->excitationState , 01083 pMeasConfig->groundSwitch ); 01084 if (eRet != ADMW_SUCCESS ) { 01085 ADMW_LOG_ERROR("Failed to set cycle control"); 01086 return eRet; 01087 } 01088 01089 if (pMeasConfig->fifoNumCycles > 0) { 01090 eRet = admw_SetFifoNumCycles(hDevice, 01091 pMeasConfig->fifoNumCycles ); 01092 } 01093 01094 if (eRet != ADMW_SUCCESS ) { 01095 ADMW_LOG_ERROR("Failed to set the FIFO number of cycles."); 01096 return eRet; 01097 } 01098 01099 if(pMeasConfig->externalRef1Value > 0) { 01100 eRet = admw_SetExternalReferenceValues(hDevice, 01101 pMeasConfig->externalRef1Value ); 01102 } 01103 01104 if (eRet != ADMW_SUCCESS ) { 01105 ADMW_LOG_ERROR("Failed to set external reference values"); 01106 return eRet; 01107 } 01108 01109 if((pMeasConfig->AVDDVoltage >= 3.0) && (pMeasConfig->AVDDVoltage <= 3.6)) { 01110 eRet = admw_SetAVDDVoltage(hDevice, 01111 pMeasConfig->AVDDVoltage ); 01112 } 01113 01114 if (eRet != ADMW_SUCCESS ) { 01115 ADMW_LOG_ERROR("Failed to set AVDD Voltge"); 01116 return eRet; 01117 } 01118 01119 eRet = admw_SetRSenseValue(hDevice, pMeasConfig->RSenseValue ); 01120 if (eRet != ADMW_SUCCESS ) { 01121 ADMW_LOG_ERROR("Failed to set RSenseValue"); 01122 return eRet; 01123 } 01124 01125 eRet = admw_SetExternalReferenceVoltage(hDevice, pMeasConfig->externalRefVoltage ); 01126 if (eRet != ADMW_SUCCESS ) { 01127 ADMW_LOG_ERROR("Failed to set External reference Voltage"); 01128 return eRet; 01129 } 01130 01131 return ADMW_SUCCESS ; 01132 } 01133 ADMW_RESULT admw1001_SetDiagnosticsConfig( 01134 ADMW_DEVICE_HANDLE hDevice, 01135 ADMW1001_DIAGNOSTICS_CONFIG *pDiagnosticsConfig) 01136 { 01137 ADMW_CORE_Diagnostics_Control_t diagnosticsControlReg; 01138 01139 diagnosticsControlReg.VALUE8 = REG_RESET_VAL(CORE_DIAGNOSTICS_CONTROL); 01140 01141 if (pDiagnosticsConfig->disableMeasurementDiag ) 01142 diagnosticsControlReg.Diag_Meas_En = 0; 01143 else 01144 diagnosticsControlReg.Diag_Meas_En = 1; 01145 01146 if(pDiagnosticsConfig->osdFrequency <= 0x7F) { 01147 diagnosticsControlReg.Diag_OSD_Freq = pDiagnosticsConfig->osdFrequency ; 01148 } else { 01149 ADMW_LOG_ERROR("Invalid open-sensor diagnostic frequency %d specified", 01150 pDiagnosticsConfig->osdFrequency ); 01151 return ADMW_INVALID_PARAM ; 01152 } 01153 WRITE_REG_U8(hDevice, diagnosticsControlReg.VALUE8, CORE_DIAGNOSTICS_CONTROL); 01154 01155 return ADMW_SUCCESS ; 01156 } 01157 01158 ADMW_RESULT admw1001_SetChannelCount( 01159 ADMW_DEVICE_HANDLE hDevice, 01160 ADMW1001_CH_ID eChannelId, 01161 uint32_t nMeasurementsPerCycle) 01162 { 01163 ADMW_CORE_Channel_Count_t channelCountReg; 01164 01165 channelCountReg.VALUE8 = REG_RESET_VAL(CORE_CHANNEL_COUNTn); 01166 01167 if (nMeasurementsPerCycle > 0) { 01168 nMeasurementsPerCycle -= 1; 01169 01170 CHECK_REG_FIELD_VAL(CORE_CHANNEL_COUNT_CHANNEL_COUNT, 01171 nMeasurementsPerCycle); 01172 01173 channelCountReg.Channel_Enable = 1; 01174 channelCountReg.Channel_Count = nMeasurementsPerCycle; 01175 } else { 01176 channelCountReg.Channel_Enable = 0; 01177 } 01178 01179 WRITE_REG_U8(hDevice, channelCountReg.VALUE8, CORE_CHANNEL_COUNTn(eChannelId)); 01180 01181 return ADMW_SUCCESS ; 01182 } 01183 01184 ADMW_RESULT admw1001_SetChannelOptions( 01185 ADMW_DEVICE_HANDLE hDevice, 01186 ADMW1001_CH_ID eChannelId, 01187 ADMW1001_CHANNEL_PRIORITY ePriority) 01188 { 01189 ADMW_CORE_Channel_Options_t channelOptionsReg; 01190 01191 channelOptionsReg.VALUE8 = REG_RESET_VAL(CORE_CHANNEL_OPTIONSn); 01192 01193 CHECK_REG_FIELD_VAL(CORE_CHANNEL_OPTIONS_CHANNEL_PRIORITY, ePriority); 01194 channelOptionsReg.Channel_Priority = ePriority; 01195 01196 WRITE_REG_U8(hDevice, channelOptionsReg.VALUE8, CORE_CHANNEL_OPTIONSn(eChannelId)); 01197 01198 return ADMW_SUCCESS ; 01199 } 01200 01201 ADMW_RESULT admw1001_SetChannelSkipCount( 01202 ADMW_DEVICE_HANDLE hDevice, 01203 ADMW1001_CH_ID eChannelId, 01204 uint32_t nCycleSkipCount) 01205 { 01206 ADMW_CORE_Channel_Skip_t channelSkipReg; 01207 01208 channelSkipReg.VALUE16 = REG_RESET_VAL(CORE_CHANNEL_SKIPn); 01209 01210 CHECK_REG_FIELD_VAL(CORE_CHANNEL_SKIP_CHANNEL_SKIP, nCycleSkipCount); 01211 01212 channelSkipReg.Channel_Skip = nCycleSkipCount; 01213 01214 WRITE_REG_U16(hDevice, channelSkipReg.VALUE16, CORE_CHANNEL_SKIPn(eChannelId)); 01215 01216 return ADMW_SUCCESS ; 01217 } 01218 01219 static ADMW_RESULT admw_SetChannelAdcSensorType( 01220 ADMW_DEVICE_HANDLE hDevice, 01221 ADMW1001_CH_ID eChannelId, 01222 ADMW1001_ADC_SENSOR_TYPE sensorType) 01223 { 01224 ADMW_CORE_Sensor_Type_t sensorTypeReg; 01225 01226 sensorTypeReg.VALUE16 = REG_RESET_VAL(CORE_SENSOR_TYPEn); 01227 01228 /* Ensure that the sensor type is valid for this channel */ 01229 switch(sensorType) { 01230 case ADMW1001_ADC_SENSOR_RTD_2WIRE_PT10 : 01231 01232 case ADMW1001_ADC_SENSOR_RTD_2WIRE_PT50 : 01233 case ADMW1001_ADC_SENSOR_RTD_2WIRE_PT100 : 01234 case ADMW1001_ADC_SENSOR_RTD_2WIRE_PT200 : 01235 case ADMW1001_ADC_SENSOR_RTD_2WIRE_PT500 : 01236 case ADMW1001_ADC_SENSOR_RTD_2WIRE_PT1000 : 01237 case ADMW1001_ADC_SENSOR_RTD_2WIRE_PT1000_0P00375 : 01238 case ADMW1001_ADC_SENSOR_RTD_2WIRE_NI120 : 01239 case ADMW1001_ADC_SENSOR_RTD_2WIRE_CUSTOM : 01240 case ADMW1001_ADC_SENSOR_RTD_4WIRE_PT10 : 01241 01242 case ADMW1001_ADC_SENSOR_RTD_4WIRE_PT50 : 01243 case ADMW1001_ADC_SENSOR_RTD_4WIRE_PT100 : 01244 case ADMW1001_ADC_SENSOR_RTD_4WIRE_PT200 : 01245 case ADMW1001_ADC_SENSOR_RTD_4WIRE_PT500 : 01246 case ADMW1001_ADC_SENSOR_RTD_4WIRE_PT1000 : 01247 case ADMW1001_ADC_SENSOR_RTD_4WIRE_PT1000_0P00375 : 01248 case ADMW1001_ADC_SENSOR_RTD_4WIRE_NI120 : 01249 case ADMW1001_ADC_SENSOR_RTD_4WIRE_CUSTOM : 01250 case ADMW1001_ADC_SENSOR_RTD_3WIRE_PT10 : 01251 01252 case ADMW1001_ADC_SENSOR_RTD_3WIRE_PT50 : 01253 case ADMW1001_ADC_SENSOR_RTD_3WIRE_PT100 : 01254 case ADMW1001_ADC_SENSOR_RTD_3WIRE_PT200 : 01255 case ADMW1001_ADC_SENSOR_RTD_3WIRE_PT500 : 01256 case ADMW1001_ADC_SENSOR_RTD_3WIRE_PT1000 : 01257 case ADMW1001_ADC_SENSOR_RTD_3WIRE_PT1000_0P00375 : 01258 01259 case ADMW1001_ADC_SENSOR_RTD_3WIRE_NI120 : 01260 case ADMW1001_ADC_SENSOR_RTD_3WIRE_CUSTOM : 01261 case ADMW1001_ADC_SENSOR_BRIDGE_4WIRE : 01262 case ADMW1001_ADC_SENSOR_BRIDGE_6WIRE : 01263 case ADMW1001_ADC_SENSOR_DIODE : 01264 case ADMW1001_ADC_SENSOR_THERMISTOR_44004_44033_2P252K_AT_25C : 01265 case ADMW1001_ADC_SENSOR_THERMISTOR_44005_44030_3K_AT_25C : 01266 case ADMW1001_ADC_SENSOR_THERMISTOR_44007_44034_5K_AT_25C : 01267 case ADMW1001_ADC_SENSOR_THERMISTOR_44006_44031_10K_AT_25C : 01268 case ADMW1001_ADC_SENSOR_THERMISTOR_44008_44032_30K_AT_25C : 01269 case ADMW1001_ADC_SENSOR_THERMISTOR_YSI_400 : 01270 case ADMW1001_ADC_SENSOR_THERMISTOR_SPECTRUM_1003K_1K : 01271 case ADMW1001_ADC_SENSOR_THERMISTOR_CUSTOM_STEINHART_HART : 01272 case ADMW1001_ADC_SENSOR_THERMISTOR_CUSTOM_TABLE : 01273 case ADMW1001_ADC_SENSOR_SINGLE_ENDED_ABSOLUTE : 01274 case ADMW1001_ADC_SENSOR_DIFFERENTIAL_ABSOLUTE : 01275 case ADMW1001_ADC_SENSOR_SINGLE_ENDED_RATIO : 01276 case ADMW1001_ADC_SENSOR_DIFFERENTIAL_RATIO : 01277 01278 if (! (ADMW1001_CHANNEL_IS_ADC_CJC(eChannelId) || 01279 ADMW1001_CHANNEL_IS_ADC(eChannelId) )) { 01280 ADMW_LOG_ERROR( 01281 "Invalid ADC sensor type %d specified for channel %d", 01282 sensorType, eChannelId); 01283 return ADMW_INVALID_PARAM ; 01284 } 01285 break; 01286 case ADMW1001_ADC_SENSOR_THERMOCOUPLE_J : 01287 case ADMW1001_ADC_SENSOR_THERMOCOUPLE_K : 01288 case ADMW1001_ADC_SENSOR_THERMOCOUPLE_T : 01289 case ADMW1001_ADC_SENSOR_THERMOCOUPLE_E : 01290 case ADMW1001_ADC_SENSOR_THERMOCOUPLE_N : 01291 case ADMW1001_ADC_SENSOR_THERMOCOUPLE_R : 01292 case ADMW1001_ADC_SENSOR_THERMOCOUPLE_S : 01293 case ADMW1001_ADC_SENSOR_THERMOCOUPLE_B : 01294 case ADMW1001_ADC_SENSOR_THERMOCOUPLE_CUSTOM : 01295 if (! ADMW1001_CHANNEL_IS_ADC_VOLTAGE(eChannelId)) { 01296 ADMW_LOG_ERROR( 01297 "Invalid ADC sensor type %d specified for channel %d", 01298 sensorType, eChannelId); 01299 return ADMW_INVALID_PARAM ; 01300 } 01301 break; 01302 default: 01303 ADMW_LOG_ERROR("Invalid/unsupported ADC sensor type %d specified", 01304 sensorType); 01305 return ADMW_INVALID_PARAM ; 01306 } 01307 01308 sensorTypeReg.Sensor_Type = sensorType; 01309 01310 WRITE_REG_U16(hDevice, sensorTypeReg.VALUE16, CORE_SENSOR_TYPEn(eChannelId)); 01311 01312 return ADMW_SUCCESS ; 01313 } 01314 01315 static ADMW_RESULT admw_SetChannelAdcSensorDetails( 01316 ADMW_DEVICE_HANDLE hDevice, 01317 ADMW1001_CH_ID eChannelId, 01318 ADMW1001_CHANNEL_CONFIG *pChannelConfig) 01319 /* 01320 * TODO - it would be nice if the general- vs. ADC-specific sensor details could be split into separate registers 01321 * General details: 01322 * - Measurement_Units 01323 * - Compensation_Channel 01324 * - CJC_Publish (if "CJC" was removed from the name) 01325 * ADC-specific details: 01326 * - PGA_Gain 01327 * - Reference_Select 01328 * - Reference_Buffer_Disable 01329 */ 01330 { 01331 ADMW1001_ADC_CHANNEL_CONFIG *pAdcChannelConfig = &pChannelConfig->adcChannelConfig ; 01332 ADMW1001_ADC_REFERENCE_TYPE refType = pAdcChannelConfig->reference ; 01333 ADMW_CORE_Sensor_Details_t sensorDetailsReg; 01334 01335 sensorDetailsReg.VALUE32 = REG_RESET_VAL(CORE_SENSOR_DETAILSn); 01336 01337 switch(pChannelConfig->measurementUnit ) { 01338 case ADMW1001_MEASUREMENT_UNIT_FAHRENHEIT : 01339 sensorDetailsReg.Measurement_Units = CORE_SENSOR_DETAILS_UNITS_DEGF; 01340 break; 01341 case ADMW1001_MEASUREMENT_UNIT_CELSIUS : 01342 sensorDetailsReg.Measurement_Units = CORE_SENSOR_DETAILS_UNITS_DEGC; 01343 break; 01344 case ADMW1001_MEASUREMENT_UNIT_UNSPECIFIED : 01345 sensorDetailsReg.Measurement_Units = CORE_SENSOR_DETAILS_UNITS_UNSPECIFIED; 01346 break; 01347 default: 01348 ADMW_LOG_ERROR("Invalid measurement unit %d specified", 01349 pChannelConfig->measurementUnit ); 01350 return ADMW_INVALID_PARAM ; 01351 } 01352 01353 if (pChannelConfig->compensationChannel == ADMW1001_CH_ID_NONE ) { 01354 sensorDetailsReg.Compensation_Disable = 1; 01355 sensorDetailsReg.Compensation_Channel = 0; 01356 } else { 01357 sensorDetailsReg.Compensation_Disable = 0; 01358 sensorDetailsReg.Compensation_Channel = pChannelConfig->compensationChannel ; 01359 } 01360 01361 switch(refType) { 01362 case ADMW1001_ADC_REFERENCE_VOLTAGE_INTERNAL : 01363 sensorDetailsReg.Reference_Select = CORE_SENSOR_DETAILS_REF_VINT; 01364 break; 01365 case ADMW1001_ADC_REFERENCE_VOLTAGE_EXTERNAL_1 : 01366 sensorDetailsReg.Reference_Select = CORE_SENSOR_DETAILS_REF_VEXT1; 01367 break; 01368 case ADMW1001_ADC_REFERENCE_VOLTAGE_AVDD : 01369 sensorDetailsReg.Reference_Select = CORE_SENSOR_DETAILS_REF_AVDD; 01370 break; 01371 default: 01372 ADMW_LOG_ERROR("Invalid ADC reference type %d specified", refType); 01373 return ADMW_INVALID_PARAM ; 01374 } 01375 01376 switch(pAdcChannelConfig->gain ) { 01377 case ADMW1001_ADC_GAIN_1X : 01378 sensorDetailsReg.PGA_Gain = CORE_SENSOR_DETAILS_PGA_GAIN_1; 01379 break; 01380 case ADMW1001_ADC_GAIN_2X : 01381 sensorDetailsReg.PGA_Gain = CORE_SENSOR_DETAILS_PGA_GAIN_2; 01382 break; 01383 case ADMW1001_ADC_GAIN_4X : 01384 sensorDetailsReg.PGA_Gain = CORE_SENSOR_DETAILS_PGA_GAIN_4; 01385 break; 01386 case ADMW1001_ADC_GAIN_8X : 01387 sensorDetailsReg.PGA_Gain = CORE_SENSOR_DETAILS_PGA_GAIN_8; 01388 break; 01389 case ADMW1001_ADC_GAIN_16X : 01390 sensorDetailsReg.PGA_Gain = CORE_SENSOR_DETAILS_PGA_GAIN_16; 01391 break; 01392 case ADMW1001_ADC_GAIN_32X : 01393 sensorDetailsReg.PGA_Gain = CORE_SENSOR_DETAILS_PGA_GAIN_32; 01394 break; 01395 case ADMW1001_ADC_GAIN_64X : 01396 sensorDetailsReg.PGA_Gain = CORE_SENSOR_DETAILS_PGA_GAIN_64; 01397 break; 01398 default: 01399 ADMW_LOG_ERROR("Invalid ADC gain %d specified", 01400 pAdcChannelConfig->gain ); 01401 return ADMW_INVALID_PARAM ; 01402 } 01403 01404 switch(pAdcChannelConfig->rtdCurve ) { 01405 case ADMW1001_ADC_RTD_CURVE_EUROPEAN : 01406 sensorDetailsReg.RTD_Curve = CORE_SENSOR_DETAILS_EUROPEAN_CURVE; 01407 break; 01408 case ADMW1001_ADC_RTD_CURVE_AMERICAN : 01409 sensorDetailsReg.RTD_Curve = CORE_SENSOR_DETAILS_AMERICAN_CURVE; 01410 break; 01411 case ADMW1001_ADC_RTD_CURVE_JAPANESE : 01412 sensorDetailsReg.RTD_Curve = CORE_SENSOR_DETAILS_JAPANESE_CURVE; 01413 break; 01414 case ADMW1001_ADC_RTD_CURVE_ITS90 : 01415 sensorDetailsReg.RTD_Curve = CORE_SENSOR_DETAILS_ITS90_CURVE; 01416 break; 01417 default: 01418 ADMW_LOG_ERROR("Invalid RTD Curve %d specified", 01419 pAdcChannelConfig->rtdCurve ); 01420 return ADMW_INVALID_PARAM ; 01421 } 01422 01423 if (pChannelConfig->disablePublishing ) { 01424 sensorDetailsReg.Do_Not_Publish = 1; 01425 } else { 01426 sensorDetailsReg.Do_Not_Publish = 0; 01427 } 01428 01429 switch (pChannelConfig->lutSelect ) { 01430 case ADMW1001_LUT_DEFAULT : 01431 case ADMW1001_LUT_CUSTOM : 01432 sensorDetailsReg.LUT_Select = pChannelConfig->lutSelect ; 01433 break; 01434 default: 01435 ADMW_LOG_ERROR("Invalid LUT selection %d specified", 01436 pChannelConfig->lutSelect ); 01437 return ADMW_INVALID_PARAM ; 01438 } 01439 01440 WRITE_REG_U32(hDevice, sensorDetailsReg.VALUE32, CORE_SENSOR_DETAILSn(eChannelId)); 01441 01442 return ADMW_SUCCESS ; 01443 } 01444 01445 static ADMW_RESULT admw_SetChannelAdcMeasurementSetup( 01446 ADMW_DEVICE_HANDLE hDevice, 01447 ADMW1001_CH_ID eChannelId, 01448 ADMW1001_ADC_CHANNEL_CONFIG *pAdcChannelConfig) 01449 { 01450 ADMW_CORE_Measurement_Setup_t MeasSetupReg; 01451 ADMW1001_ADC_FILTER_CONFIG *pFilterConfig = &pAdcChannelConfig->filter ; 01452 MeasSetupReg.VALUE32 = REG_RESET_VAL(CORE_MEASUREMENT_SETUPn); 01453 MeasSetupReg.Buffer_Bypass = pAdcChannelConfig->bufferBypass ; 01454 01455 if (pFilterConfig->type == ADMW1001_ADC_FILTER_SINC4 ) { 01456 MeasSetupReg.ADC_Filter_Type = CORE_MEASUREMENT_SETUP_ENABLE_SINC4; 01457 MeasSetupReg.ADC_SF = pFilterConfig->sf ; 01458 } else if (pFilterConfig->type == ADMW1001_ADC_FILTER_SINC3 ) { 01459 MeasSetupReg.ADC_Filter_Type = CORE_MEASUREMENT_SETUP_ENABLE_SINC3; 01460 MeasSetupReg.ADC_SF = pFilterConfig->sf ; 01461 } else { 01462 ADMW_LOG_ERROR("Invalid ADC filter type %d specified", 01463 pFilterConfig->type ); 01464 return ADMW_INVALID_PARAM ; 01465 } 01466 01467 /* chop mod ecan be 0 (none), 1 (HW, 2 (SW, 3 (HW+SW). */ 01468 MeasSetupReg.Chop_Mode = pFilterConfig->chopMode ; 01469 01470 if(pFilterConfig->notch1p2 ) 01471 MeasSetupReg.NOTCH_EN_2 = 1; 01472 else 01473 MeasSetupReg.NOTCH_EN_2 = 0; 01474 01475 WRITE_REG_U32(hDevice, MeasSetupReg.VALUE32, CORE_MEASUREMENT_SETUPn(eChannelId)); 01476 01477 return ADMW_SUCCESS ; 01478 } 01479 01480 static ADMW_RESULT admw_SetChannelAdcCurrentConfig( 01481 ADMW_DEVICE_HANDLE hDevice, 01482 ADMW1001_CH_ID eChannelId, 01483 ADMW1001_ADC_EXC_CURRENT_CONFIG *pCurrentConfig) 01484 { 01485 ADMW_CORE_Channel_Excitation_t channelExcitationReg; 01486 01487 channelExcitationReg.VALUE16 = REG_RESET_VAL(CORE_CHANNEL_EXCITATIONn); 01488 01489 if (pCurrentConfig->outputLevel == ADMW1001_ADC_NO_EXTERNAL_EXC_CURRENT ) 01490 channelExcitationReg.IOUT_Excitation_Current = CORE_CHANNEL_EXCITATION_NONE; 01491 else if (pCurrentConfig->outputLevel == ADMW1001_ADC_EXC_CURRENT_EXTERNAL ) 01492 channelExcitationReg.IOUT_Excitation_Current = CORE_CHANNEL_EXCITATION_EXTERNAL; 01493 else if (pCurrentConfig->outputLevel == ADMW1001_ADC_EXC_CURRENT_50uA ) 01494 channelExcitationReg.IOUT_Excitation_Current = CORE_CHANNEL_EXCITATION_IEXC_50UA; 01495 else if (pCurrentConfig->outputLevel == ADMW1001_ADC_EXC_CURRENT_100uA ) 01496 channelExcitationReg.IOUT_Excitation_Current = CORE_CHANNEL_EXCITATION_IEXC_100UA; 01497 else if (pCurrentConfig->outputLevel == ADMW1001_ADC_EXC_CURRENT_250uA ) 01498 channelExcitationReg.IOUT_Excitation_Current = CORE_CHANNEL_EXCITATION_IEXC_250UA; 01499 else if (pCurrentConfig->outputLevel == ADMW1001_ADC_EXC_CURRENT_500uA ) 01500 channelExcitationReg.IOUT_Excitation_Current = CORE_CHANNEL_EXCITATION_IEXC_500UA; 01501 else if (pCurrentConfig->outputLevel == ADMW1001_ADC_EXC_CURRENT_1000uA ) 01502 channelExcitationReg.IOUT_Excitation_Current = CORE_CHANNEL_EXCITATION_IEXC_1000UA; 01503 else { 01504 ADMW_LOG_ERROR("Invalid ADC excitation current %d specified", 01505 pCurrentConfig->outputLevel ); 01506 return ADMW_INVALID_PARAM ; 01507 } 01508 01509 WRITE_REG_U16(hDevice, channelExcitationReg.VALUE16, CORE_CHANNEL_EXCITATIONn(eChannelId)); 01510 01511 return ADMW_SUCCESS ; 01512 } 01513 01514 ADMW_RESULT admw_SetAdcChannelConfig( 01515 ADMW_DEVICE_HANDLE hDevice, 01516 ADMW1001_CH_ID eChannelId, 01517 ADMW1001_CHANNEL_CONFIG *pChannelConfig) 01518 { 01519 ADMW_RESULT eRet; 01520 ADMW1001_ADC_CHANNEL_CONFIG *pAdcChannelConfig = 01521 &pChannelConfig->adcChannelConfig ; 01522 01523 eRet = admw_SetChannelAdcSensorType(hDevice, eChannelId, 01524 pAdcChannelConfig->sensor ); 01525 if (eRet != ADMW_SUCCESS ) { 01526 ADMW_LOG_ERROR("Failed to set ADC sensor type for channel %d", 01527 eChannelId); 01528 return eRet; 01529 } 01530 01531 eRet = admw_SetChannelAdcSensorDetails(hDevice, eChannelId, 01532 pChannelConfig); 01533 if (eRet != ADMW_SUCCESS ) { 01534 ADMW_LOG_ERROR("Failed to set ADC sensor details for channel %d", 01535 eChannelId); 01536 return eRet; 01537 } 01538 01539 eRet = admw_SetChannelAdcMeasurementSetup(hDevice, eChannelId, 01540 pAdcChannelConfig); 01541 if (eRet != ADMW_SUCCESS ) { 01542 ADMW_LOG_ERROR("Failed to set ADC filter for channel %d", 01543 eChannelId); 01544 return eRet; 01545 } 01546 01547 eRet = admw_SetChannelAdcCurrentConfig(hDevice, eChannelId, 01548 &pAdcChannelConfig->current ); 01549 if (eRet != ADMW_SUCCESS ) { 01550 ADMW_LOG_ERROR("Failed to set ADC current for channel %d", 01551 eChannelId); 01552 return eRet; 01553 } 01554 01555 return ADMW_SUCCESS ; 01556 } 01557 01558 static ADMW_RESULT admw_SetChannelDigitalSensorDetails( 01559 ADMW_DEVICE_HANDLE hDevice, 01560 ADMW1001_CH_ID eChannelId, 01561 ADMW1001_CHANNEL_CONFIG *pChannelConfig) 01562 { 01563 ADMW_CORE_Sensor_Details_t sensorDetailsReg; 01564 01565 sensorDetailsReg.VALUE32 = REG_RESET_VAL(CORE_SENSOR_DETAILSn); 01566 01567 if (pChannelConfig->compensationChannel == ADMW1001_CH_ID_NONE ) { 01568 sensorDetailsReg.Compensation_Disable = 1; 01569 sensorDetailsReg.Compensation_Channel = 0; 01570 } else { 01571 ADMW_LOG_ERROR("Invalid compensation channel specified for digital sensor"); 01572 return ADMW_INVALID_PARAM ; 01573 } 01574 01575 if (pChannelConfig->measurementUnit == ADMW1001_MEASUREMENT_UNIT_UNSPECIFIED ) { 01576 sensorDetailsReg.Measurement_Units = CORE_SENSOR_DETAILS_UNITS_UNSPECIFIED; 01577 } else { 01578 ADMW_LOG_ERROR("Invalid measurement unit specified for digital channel"); 01579 return ADMW_INVALID_PARAM ; 01580 } 01581 01582 if (pChannelConfig->disablePublishing ) 01583 sensorDetailsReg.Do_Not_Publish = 1; 01584 else 01585 sensorDetailsReg.Do_Not_Publish = 0; 01586 01587 WRITE_REG_U32(hDevice, sensorDetailsReg.VALUE32, CORE_SENSOR_DETAILSn(eChannelId)); 01588 01589 return ADMW_SUCCESS ; 01590 } 01591 01592 static ADMW_RESULT admw_SetDigitalSensorFormat( 01593 ADMW_DEVICE_HANDLE hDevice, 01594 ADMW1001_CH_ID eChannelId, 01595 ADMW1001_DIGITAL_SENSOR_DATA_FORMAT *pDataFormat) 01596 { 01597 ADMW_CORE_Digital_Sensor_Config_t sensorConfigReg; 01598 01599 sensorConfigReg.VALUE16 = REG_RESET_VAL(CORE_DIGITAL_SENSOR_CONFIGn); 01600 01601 if (pDataFormat->coding != ADMW1001_DIGITAL_SENSOR_DATA_CODING_NONE) { 01602 if (pDataFormat->frameLength == 0) { 01603 ADMW_LOG_ERROR("Invalid frame length specified for digital sensor data format"); 01604 return ADMW_INVALID_PARAM ; 01605 } 01606 if (pDataFormat->numDataBits == 0) { 01607 ADMW_LOG_ERROR("Invalid frame length specified for digital sensor data format"); 01608 return ADMW_INVALID_PARAM ; 01609 } 01610 01611 CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_CONFIG_DIGITAL_SENSOR_READ_BYTES, 01612 pDataFormat->frameLength - 1); 01613 CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_CONFIG_DIGITAL_SENSOR_DATA_BITS, 01614 pDataFormat->numDataBits - 1); 01615 CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_CONFIG_DIGITAL_SENSOR_BIT_OFFSET, 01616 pDataFormat->bitOffset); 01617 01618 sensorConfigReg.Digital_Sensor_Read_Bytes = pDataFormat->frameLength - 1; 01619 sensorConfigReg.Digital_Sensor_Data_Bits = pDataFormat->numDataBits - 1; 01620 sensorConfigReg.Digital_Sensor_Bit_Offset = pDataFormat->bitOffset; 01621 sensorConfigReg.Digital_Sensor_Left_Aligned = pDataFormat->leftJustified ? 1 : 0; 01622 sensorConfigReg.Digital_Sensor_Little_Endian = pDataFormat->littleEndian ? 1 : 0; 01623 01624 switch (pDataFormat->coding) { 01625 case ADMW1001_DIGITAL_SENSOR_DATA_CODING_UNIPOLAR: 01626 sensorConfigReg.Digital_Sensor_Coding = CORE_DIGITAL_SENSOR_CONFIG_CODING_UNIPOLAR; 01627 break; 01628 case ADMW1001_DIGITAL_SENSOR_DATA_CODING_TWOS_COMPLEMENT: 01629 sensorConfigReg.Digital_Sensor_Coding = CORE_DIGITAL_SENSOR_CONFIG_CODING_TWOS_COMPL; 01630 break; 01631 case ADMW1001_DIGITAL_SENSOR_DATA_CODING_OFFSET_BINARY: 01632 sensorConfigReg.Digital_Sensor_Coding = CORE_DIGITAL_SENSOR_CONFIG_CODING_OFFSET_BINARY; 01633 break; 01634 default: 01635 ADMW_LOG_ERROR("Invalid coding specified for digital sensor data format"); 01636 return ADMW_INVALID_PARAM ; 01637 } 01638 } else { 01639 sensorConfigReg.Digital_Sensor_Coding = CORE_DIGITAL_SENSOR_CONFIG_CODING_NONE; 01640 } 01641 01642 WRITE_REG_U16(hDevice, sensorConfigReg.VALUE16, 01643 CORE_DIGITAL_SENSOR_CONFIGn(eChannelId)); 01644 01645 01646 return ADMW_SUCCESS ; 01647 } 01648 01649 01650 static ADMW_RESULT admw_SetChannelI2cSensorType( 01651 ADMW_DEVICE_HANDLE hDevice, 01652 ADMW1001_CH_ID eChannelId, 01653 ADMW1001_I2C_SENSOR_TYPE sensorType) 01654 { 01655 ADMW_CORE_Sensor_Type_t sensorTypeReg; 01656 01657 sensorTypeReg.VALUE16 = REG_RESET_VAL(CORE_SENSOR_TYPEn); 01658 01659 /* Ensure that the sensor type is valid for this channel */ 01660 switch(sensorType) { 01661 case ADMW1001_I2C_SENSOR_HUMIDITY : 01662 case ADMW1001_I2C_SENSOR_TEMPERATURE_ADT742X : 01663 sensorTypeReg.Sensor_Type = sensorType; 01664 break; 01665 default: 01666 ADMW_LOG_ERROR("Unsupported I2C sensor type %d specified", sensorType); 01667 return ADMW_INVALID_PARAM ; 01668 } 01669 01670 WRITE_REG_U16(hDevice, sensorTypeReg.VALUE16, CORE_SENSOR_TYPEn(eChannelId)); 01671 01672 return ADMW_SUCCESS ; 01673 } 01674 01675 static ADMW_RESULT admw_SetChannelI2cSensorAddress( 01676 ADMW_DEVICE_HANDLE hDevice, 01677 ADMW1001_CH_ID eChannelId, 01678 uint32_t deviceAddress) 01679 { 01680 CHECK_REG_FIELD_VAL(CORE_DIGITAL_SENSOR_ADDRESS_DIGITAL_SENSOR_ADDRESS, deviceAddress); 01681 WRITE_REG_U8(hDevice, deviceAddress, CORE_DIGITAL_SENSOR_ADDRESSn(eChannelId)); 01682 01683 return ADMW_SUCCESS ; 01684 } 01685 01686 static ADMW_RESULT admw_SetDigitalChannelComms( 01687 ADMW_DEVICE_HANDLE hDevice, 01688 ADMW1001_CH_ID eChannelId, 01689 ADMW1001_DIGITAL_SENSOR_COMMS *pDigitalComms) 01690 { 01691 ADMW_CORE_Digital_Sensor_Comms_t digitalSensorComms; 01692 01693 digitalSensorComms.VALUE16 = REG_RESET_VAL(CORE_DIGITAL_SENSOR_COMMSn); 01694 01695 if(pDigitalComms->useCustomCommsConfig ) { 01696 01697 if(pDigitalComms->i2cClockSpeed == ADMW1001_DIGITAL_SENSOR_COMMS_I2C_CLOCK_SPEED_100K ) { 01698 digitalSensorComms.I2C_Clock = CORE_DIGITAL_SENSOR_COMMS_I2C_100K; 01699 } else if(pDigitalComms->i2cClockSpeed == ADMW1001_DIGITAL_SENSOR_COMMS_I2C_CLOCK_SPEED_400K ) { 01700 digitalSensorComms.I2C_Clock = CORE_DIGITAL_SENSOR_COMMS_I2C_400K; 01701 } else { 01702 ADMW_LOG_ERROR("Invalid I2C clock speed %d specified", 01703 pDigitalComms->i2cClockSpeed ); 01704 return ADMW_INVALID_PARAM ; 01705 } 01706 } 01707 WRITE_REG_U16(hDevice, digitalSensorComms.VALUE16, CORE_DIGITAL_SENSOR_COMMSn(eChannelId)); 01708 01709 return ADMW_SUCCESS ; 01710 } 01711 01712 ADMW_RESULT admw_SetI2cChannelConfig( 01713 ADMW_DEVICE_HANDLE hDevice, 01714 ADMW1001_CH_ID eChannelId, 01715 ADMW1001_CHANNEL_CONFIG *pChannelConfig) 01716 { 01717 ADMW_RESULT eRet; 01718 ADMW1001_I2C_CHANNEL_CONFIG *pI2cChannelConfig = 01719 &pChannelConfig->i2cChannelConfig ; 01720 01721 eRet = admw_SetChannelI2cSensorType(hDevice, eChannelId, 01722 pI2cChannelConfig->sensor ); 01723 if (eRet != ADMW_SUCCESS ) { 01724 ADMW_LOG_ERROR("Failed to set I2C sensor type for channel %d", 01725 eChannelId); 01726 return eRet; 01727 } 01728 01729 eRet = admw_SetChannelI2cSensorAddress(hDevice, eChannelId, 01730 pI2cChannelConfig->deviceAddress ); 01731 if (eRet != ADMW_SUCCESS ) { 01732 ADMW_LOG_ERROR("Failed to set I2C sensor address for channel %d", 01733 eChannelId); 01734 return eRet; 01735 } 01736 01737 eRet = admw_SetChannelDigitalSensorDetails(hDevice, eChannelId, 01738 pChannelConfig); 01739 if (eRet != ADMW_SUCCESS ) { 01740 ADMW_LOG_ERROR("Failed to set I2C sensor details for channel %d", 01741 eChannelId); 01742 return eRet; 01743 } 01744 01745 eRet = admw_SetDigitalSensorFormat(hDevice, eChannelId, 01746 &pI2cChannelConfig->dataFormat ); 01747 if (eRet != ADMW_SUCCESS ) { 01748 ADMW_LOG_ERROR("Failed to set I2C sensor data format for channel %d", 01749 eChannelId); 01750 return eRet; 01751 } 01752 01753 01754 eRet = admw_SetDigitalChannelComms(hDevice, eChannelId, 01755 &pI2cChannelConfig->configureComms ); 01756 if (eRet != ADMW_SUCCESS ) { 01757 ADMW_LOG_ERROR("Failed to set I2C comms for channel %d", 01758 eChannelId); 01759 return eRet; 01760 } 01761 01762 return ADMW_SUCCESS ; 01763 } 01764 01765 static ADMW_RESULT admw_SetChannelSpiSensorType( 01766 ADMW_DEVICE_HANDLE hDevice, 01767 ADMW1001_CH_ID eChannelId, 01768 ADMW1001_SPI_SENSOR_TYPE sensorType) 01769 { 01770 ADMW_CORE_Sensor_Type_t sensorTypeReg; 01771 01772 sensorTypeReg.VALUE16 = REG_RESET_VAL(CORE_SENSOR_TYPEn); 01773 01774 /* Ensure that the sensor type is valid for this channel */ 01775 switch(sensorType) { 01776 case ADMW1001_SPI_SENSOR: 01777 01778 sensorTypeReg.Sensor_Type = sensorType; 01779 break; 01780 default: 01781 ADMW_LOG_ERROR("Unsupported SPI sensor type %d specified", sensorType); 01782 return ADMW_INVALID_PARAM ; 01783 } 01784 01785 WRITE_REG_U16(hDevice, sensorTypeReg.VALUE16, CORE_SENSOR_TYPEn(eChannelId)); 01786 01787 return ADMW_SUCCESS ; 01788 } 01789 01790 01791 ADMW_RESULT admw1001_SetChannelThresholdLimits( 01792 ADMW_DEVICE_HANDLE hDevice, 01793 ADMW1001_CH_ID eChannelId, 01794 float32_t fHighThresholdLimit, 01795 float32_t fLowThresholdLimit) 01796 { 01797 /* 01798 * If the low/high limits are *both* set to 0 in memory, or NaNs, assume 01799 * that they are unset, or not required, and use infinity defaults instead 01800 */ 01801 if (fHighThresholdLimit == 0.0f && fLowThresholdLimit == 0.0f) { 01802 fHighThresholdLimit = INFINITY; 01803 fLowThresholdLimit = -INFINITY; 01804 } else { 01805 if (isnan(fHighThresholdLimit)) 01806 fHighThresholdLimit = INFINITY; 01807 if (isnan(fLowThresholdLimit)) 01808 fLowThresholdLimit = -INFINITY; 01809 } 01810 01811 WRITE_REG_FLOAT(hDevice, fHighThresholdLimit, 01812 CORE_HIGH_THRESHOLD_LIMITn(eChannelId)); 01813 WRITE_REG_FLOAT(hDevice, fLowThresholdLimit, 01814 CORE_LOW_THRESHOLD_LIMITn(eChannelId)); 01815 01816 return ADMW_SUCCESS ; 01817 } 01818 01819 ADMW_RESULT admw1001_SetOffsetGain( 01820 ADMW_DEVICE_HANDLE hDevice, 01821 ADMW1001_CH_ID eChannelId, 01822 float32_t fOffsetAdjustment, 01823 float32_t fGainAdjustment) 01824 { 01825 /* Replace with default values if NaNs are specified (or 0.0 for gain) */ 01826 if (isnan(fGainAdjustment) || (fGainAdjustment == 0.0f)) 01827 fGainAdjustment = 1.0f; 01828 if (isnan(fOffsetAdjustment)) 01829 fOffsetAdjustment = 0.0f; 01830 01831 WRITE_REG_FLOAT(hDevice, fGainAdjustment, CORE_SENSOR_GAINn(eChannelId)); 01832 WRITE_REG_FLOAT(hDevice, fOffsetAdjustment, CORE_SENSOR_OFFSETn(eChannelId)); 01833 01834 return ADMW_SUCCESS ; 01835 } 01836 01837 ADMW_RESULT admw1001_SetSensorParameter( 01838 ADMW_DEVICE_HANDLE hDevice, 01839 ADMW1001_CH_ID eChannelId, 01840 float32_t fSensorParam) 01841 { 01842 if (fSensorParam == 0.0f) 01843 fSensorParam = NAN; 01844 01845 //WRITE_REG_FLOAT(hDevice, fSensorParam, CORE_SENSOR_PARAMETERn(eChannelId)); 01846 01847 return ADMW_SUCCESS ; 01848 } 01849 01850 ADMW_RESULT admw1001_SetChannelSettlingTime( 01851 ADMW_DEVICE_HANDLE hDevice, 01852 ADMW1001_CH_ID eChannelId, 01853 uint32_t nSettlingTime) 01854 { 01855 ADMW_CORE_Settling_Time_t settlingTimeReg; 01856 01857 CHECK_REG_FIELD_VAL(CORE_SETTLING_TIME_SETTLING_TIME, nSettlingTime); 01858 settlingTimeReg.Settling_Time = nSettlingTime; 01859 01860 WRITE_REG_U16(hDevice, settlingTimeReg.VALUE16, CORE_SETTLING_TIMEn(eChannelId)); 01861 01862 return ADMW_SUCCESS ; 01863 } 01864 01865 ADMW_RESULT admw1001_SetChannelConfig( 01866 ADMW_DEVICE_HANDLE hDevice, 01867 ADMW1001_CH_ID eChannelId, 01868 ADMW1001_CHANNEL_CONFIG *pChannelConfig) 01869 { 01870 ADMW_RESULT eRet; 01871 01872 eRet = admw1001_SetChannelCount(hDevice, eChannelId, 01873 pChannelConfig->enableChannel ? 01874 pChannelConfig->measurementsPerCycle : 0); 01875 if (eRet != ADMW_SUCCESS ) { 01876 ADMW_LOG_ERROR("Failed to set measurement count for channel %d", 01877 eChannelId); 01878 return eRet; 01879 } 01880 01881 eRet = admw1001_SetChannelOptions(hDevice, eChannelId, 01882 pChannelConfig->priority ); 01883 if (eRet != ADMW_SUCCESS ) { 01884 ADMW_LOG_ERROR("Failed to set priority for channel %d", 01885 eChannelId); 01886 return eRet; 01887 } 01888 01889 /* If the channel is not enabled, we can skip the following steps */ 01890 if (pChannelConfig->enableChannel ) { 01891 eRet = admw1001_SetChannelSkipCount(hDevice, eChannelId, 01892 pChannelConfig->cycleSkipCount ); 01893 if (eRet != ADMW_SUCCESS ) { 01894 ADMW_LOG_ERROR("Failed to set cycle skip count for channel %d", 01895 eChannelId); 01896 return eRet; 01897 } 01898 01899 switch (eChannelId) { 01900 case ADMW1001_CH_ID_ANLG_1_UNIVERSAL : 01901 case ADMW1001_CH_ID_ANLG_2_UNIVERSAL : 01902 case ADMW1001_CH_ID_ANLG_1_DIFFERENTIAL : 01903 case ADMW1001_CH_ID_ANLG_2_DIFFERENTIAL : 01904 eRet = admw_SetAdcChannelConfig(hDevice, eChannelId, pChannelConfig); 01905 break; 01906 case ADMW1001_CH_ID_DIG_I2C_0 : 01907 case ADMW1001_CH_ID_DIG_I2C_1 : 01908 eRet = admw_SetI2cChannelConfig(hDevice, eChannelId, pChannelConfig); 01909 break; 01910 default: 01911 ADMW_LOG_ERROR("Invalid channel ID %d specified", eChannelId); 01912 eRet = ADMW_INVALID_PARAM ; 01913 #if 0 01914 /* when using i2c sensors there is an error ( dataformat->length=0) 01915 the code below catches this error and this causes further problems.*/ 01916 break; 01917 } 01918 if (eRet != ADMW_SUCCESS ) { 01919 ADMW_LOG_ERROR("Failed to set config for channel %d", 01920 eChannelId); 01921 return eRet; 01922 #endif 01923 } 01924 01925 eRet = admw1001_SetChannelSettlingTime(hDevice, eChannelId, 01926 pChannelConfig->extraSettlingTime ); 01927 if (eRet != ADMW_SUCCESS ) { 01928 ADMW_LOG_ERROR("Failed to set settling time for channel %d", 01929 eChannelId); 01930 return eRet; 01931 } 01932 } 01933 01934 if (pChannelConfig->enableChannel ) { 01935 /* Threshold limits can be configured individually for virtual channels */ 01936 eRet = admw1001_SetChannelThresholdLimits(hDevice, eChannelId, 01937 pChannelConfig->highThreshold , 01938 pChannelConfig->lowThreshold ); 01939 if (eRet != ADMW_SUCCESS ) { 01940 ADMW_LOG_ERROR("Failed to set threshold limits for channel %d", 01941 eChannelId); 01942 return eRet; 01943 } 01944 01945 /* Offset and gain can be configured individually for virtual channels */ 01946 eRet = admw1001_SetOffsetGain(hDevice, eChannelId, 01947 pChannelConfig->offsetAdjustment , 01948 pChannelConfig->gainAdjustment ); 01949 if (eRet != ADMW_SUCCESS ) { 01950 ADMW_LOG_ERROR("Failed to set offset/gain for channel %d", 01951 eChannelId); 01952 return eRet; 01953 } 01954 01955 /* Set sensor specific parameter */ 01956 eRet = admw1001_SetSensorParameter(hDevice, eChannelId, 01957 pChannelConfig->sensorParameter ); 01958 if (eRet != ADMW_SUCCESS ) { 01959 ADMW_LOG_ERROR("Failed to set sensor parameter for channel %d", 01960 eChannelId); 01961 return eRet; 01962 } 01963 } 01964 01965 return ADMW_SUCCESS ; 01966 } 01967 01968 ADMW_RESULT admw_SetConfig( 01969 ADMW_DEVICE_HANDLE const hDevice, 01970 ADMW_CONFIG * const pConfig) 01971 { 01972 ADMW1001_CONFIG *pDeviceConfig; 01973 ADMW_PRODUCT_ID productId; 01974 ADMW_RESULT eRet; 01975 01976 if (pConfig->productId != ADMW_PRODUCT_ID_ADMW1001 ) { 01977 ADMW_LOG_ERROR("Configuration Product ID (0x%X) is not supported (0x%0X)", 01978 pConfig->productId , ADMW_PRODUCT_ID_ADMW1001 ); 01979 return ADMW_INVALID_PARAM ; 01980 } 01981 01982 if (!((pConfig->versionId .major ==VERSIONID_MAJOR) && 01983 (pConfig->versionId .minor ==VERSIONID_MINOR))) { 01984 ADMW_LOG_ERROR("Configuration Version ID (0x%X) is not supported", 01985 pConfig->versionId ); 01986 return ADMW_INVALID_PARAM ; 01987 } 01988 01989 01990 /* Check that the actual Product ID is a match? */ 01991 eRet = admw_GetProductID(hDevice, &productId); 01992 if (eRet) { 01993 ADMW_LOG_ERROR("Failed to read device Product ID register"); 01994 return eRet; 01995 } 01996 if (pConfig->productId != productId) { 01997 ADMW_LOG_ERROR("Configuration Product ID (0x%X) does not match device (0x%0X)", 01998 pConfig->productId , productId); 01999 return ADMW_INVALID_PARAM ; 02000 } 02001 02002 pDeviceConfig = &pConfig->admw1001 ; 02003 02004 eRet = admw1001_SetPowerConfig(hDevice, &pDeviceConfig->power ); 02005 if (eRet) { 02006 ADMW_LOG_ERROR("Failed to set power configuration"); 02007 return eRet; 02008 } 02009 02010 eRet = admw1001_SetMeasurementConfig(hDevice, &pDeviceConfig->measurement ); 02011 if (eRet) { 02012 ADMW_LOG_ERROR("Failed to set measurement configuration"); 02013 return eRet; 02014 } 02015 02016 eRet = admw1001_SetDiagnosticsConfig(hDevice, &pDeviceConfig->diagnostics ); 02017 if (eRet) { 02018 ADMW_LOG_ERROR("Failed to set diagnostics configuration"); 02019 return eRet; 02020 } 02021 02022 for (ADMW1001_CH_ID id = ADMW1001_CH_ID_ANLG_1_UNIVERSAL ; 02023 id < ADMW1001_MAX_CHANNELS ; 02024 id++) { 02025 eRet = admw1001_SetChannelConfig(hDevice, id, 02026 &pDeviceConfig->channels [id]); 02027 if (eRet) { 02028 ADMW_LOG_ERROR("Failed to set channel %d configuration", id); 02029 return eRet; 02030 } 02031 } 02032 02033 return ADMW_SUCCESS ; 02034 } 02035 02036 02037 ADMW_RESULT admw1001_SetLutDataRaw( 02038 ADMW_DEVICE_HANDLE const hDevice, 02039 ADMW1001_LUT_RAW * const pLutData) 02040 { 02041 return admw1001_SetLutData(hDevice, 02042 (ADMW1001_LUT *)pLutData); 02043 } 02044 02045 static ADMW_RESULT getLutTableSize( 02046 ADMW1001_LUT_DESCRIPTOR * const pDesc, 02047 ADMW1001_LUT_TABLE_DATA * const pData, 02048 unsigned *pLength) 02049 { 02050 switch (pDesc->geometry) { 02051 case ADMW1001_LUT_GEOMETRY_NES_1D: 02052 *pLength = ADMW1001_LUT_1D_NES_SIZE(pData->lut1dNes); 02053 break; 02054 default: 02055 ADMW_LOG_ERROR("Invalid LUT table geometry %d specified\r\n", 02056 pDesc->geometry); 02057 return ADMW_INVALID_PARAM ; 02058 } 02059 02060 return ADMW_SUCCESS ; 02061 } 02062 02063 ADMW_RESULT admw1001_AssembleLutData( 02064 ADMW1001_LUT * pLutBuffer, 02065 unsigned nLutBufferSize, 02066 unsigned const nNumTables, 02067 ADMW1001_LUT_DESCRIPTOR * const ppDesc[], 02068 ADMW1001_LUT_TABLE_DATA * const ppData[]) 02069 { 02070 ADMW1001_LUT_HEADER *pHdr = &pLutBuffer->header; 02071 uint8_t *pLutTableData = (uint8_t *)pLutBuffer + sizeof(*pHdr); 02072 02073 if (sizeof(*pHdr) > nLutBufferSize) 02074 { 02075 ADMW_LOG_ERROR("Insufficient LUT buffer size provided"); 02076 return ADMW_INVALID_PARAM ; 02077 } 02078 02079 /* First initialise the top-level header */ 02080 pHdr->signature = ADMW_LUT_SIGNATURE; 02081 pHdr->version.major = 1; 02082 pHdr->version.minor = 0; 02083 pHdr->numTables = 0; 02084 pHdr->totalLength = 0; 02085 02086 /* 02087 * Walk through the list of table pointers provided, appending the table 02088 * descriptor+data from each one to the provided LUT buffer 02089 */ 02090 for (unsigned i = 0; i < nNumTables; i++) 02091 { 02092 ADMW1001_LUT_DESCRIPTOR * const pDesc = ppDesc[i]; 02093 ADMW1001_LUT_TABLE_DATA * const pData = ppData[i]; 02094 ADMW_RESULT res; 02095 unsigned dataLength = 0; 02096 02097 /* Calculate the length of the table data */ 02098 res = getLutTableSize(pDesc, pData, &dataLength); 02099 if (res != ADMW_SUCCESS ) 02100 return res; 02101 02102 /* Fill in the table descriptor length and CRC fields */ 02103 pDesc->length = dataLength; 02104 02105 if ((sizeof(*pHdr) + pHdr->totalLength + sizeof(*pDesc) + dataLength) > nLutBufferSize) 02106 { 02107 ADMW_LOG_ERROR("Insufficient LUT buffer size provided"); 02108 return ADMW_INVALID_PARAM ; 02109 } 02110 02111 /* Append the table to the LUT buffer (desc + data) */ 02112 memcpy(pLutTableData + pHdr->totalLength, pDesc, sizeof(*pDesc)); 02113 pHdr->totalLength += sizeof(*pDesc); 02114 memcpy(pLutTableData + pHdr->totalLength, pData, dataLength); 02115 pHdr->totalLength += dataLength; 02116 02117 pHdr->numTables++; 02118 } 02119 02120 return ADMW_SUCCESS ; 02121 } 02122 ADMW_RESULT admw1001_SetLutData( 02123 ADMW_DEVICE_HANDLE const hDevice, 02124 ADMW1001_LUT * const pLutData) 02125 { 02126 #pragma diag_suppress=Pa039 02127 ADMW1001_LUT_HEADER *pLutHeader = &pLutData->header; 02128 ADMW1001_LUT_TABLE *pLutTable = pLutData->tables; 02129 02130 unsigned actualLength = 0; 02131 02132 if (pLutData->header.signature != ADMW_LUT_SIGNATURE) 02133 { 02134 ADMW_LOG_ERROR("LUT signature incorrect (expected 0x%X, actual 0x%X)", 02135 ADMW_LUT_SIGNATURE, pLutHeader->signature); 02136 return ADMW_INVALID_SIGNATURE ; 02137 } 02138 if ((pLutData->tables->descriptor.geometry!= ADMW1001_LUT_GEOMETRY_NES_1D) && 02139 (pLutData->tables->data.lut1dNes.nElements > MAX_LUT_NUM_ENTRIES)) 02140 { 02141 return ADMW_INVALID_PARAM ; 02142 } 02143 for (unsigned i = 0; i < pLutHeader->numTables; i++) 02144 { 02145 ADMW1001_LUT_DESCRIPTOR *pDesc = &pLutTable->descriptor; 02146 02147 switch (pDesc->geometry) 02148 { 02149 case ADMW1001_LUT_GEOMETRY_COEFFS: 02150 switch (pDesc->equation) 02151 { 02152 case ADMW1001_LUT_EQUATION_POLYN: 02153 case ADMW1001_LUT_EQUATION_POLYNEXP: 02154 case ADMW1001_LUT_EQUATION_QUADRATIC: 02155 case ADMW1001_LUT_EQUATION_STEINHART: 02156 case ADMW1001_LUT_EQUATION_LOGARITHMIC: 02157 case ADMW1001_LUT_EQUATION_BIVARIATE_POLYN: 02158 break; 02159 default: 02160 ADMW_LOG_ERROR("Invalid equation %u specified for LUT table %u", 02161 pDesc->equation, i); 02162 return ADMW_INVALID_PARAM ; 02163 } 02164 break; 02165 case ADMW1001_LUT_GEOMETRY_NES_1D: 02166 break; 02167 default: 02168 ADMW_LOG_ERROR("Invalid geometry %u specified for LUT table %u", 02169 pDesc->geometry, i); 02170 return ADMW_INVALID_PARAM ; 02171 } 02172 02173 switch (pDesc->dataType) 02174 { 02175 case ADMW1001_LUT_DATA_TYPE_FLOAT32: 02176 case ADMW1001_LUT_DATA_TYPE_FLOAT64: 02177 break; 02178 default: 02179 ADMW_LOG_ERROR("Invalid vector format %u specified for LUT table %u", 02180 pDesc->dataType, i); 02181 return ADMW_INVALID_PARAM ; 02182 } 02183 02184 02185 actualLength += sizeof(*pDesc) + pDesc->length; 02186 02187 /* Move to the next look-up table */ 02188 pLutTable = (ADMW1001_LUT_TABLE *)((uint8_t *)pLutTable + sizeof(*pDesc) + pDesc->length); 02189 } 02190 02191 if (actualLength != pLutHeader->totalLength) 02192 { 02193 ADMW_LOG_ERROR("LUT table length mismatch (expected %u, actual %u)", 02194 pLutHeader->totalLength, actualLength); 02195 return ADMW_WRONG_SIZE ; 02196 } 02197 02198 if (sizeof(*pLutHeader) + pLutHeader->totalLength > ADMW_LUT_MAX_SIZE) 02199 { 02200 ADMW_LOG_ERROR("Maximum LUT table length (%u bytes) exceeded", 02201 ADMW_LUT_MAX_SIZE); 02202 return ADMW_WRONG_SIZE ; 02203 } 02204 02205 /* Write the LUT data to the device */ 02206 unsigned lutSize = sizeof(*pLutHeader) + pLutHeader->totalLength; 02207 WRITE_REG_U16(hDevice, 0, CORE_LUT_OFFSET); 02208 WRITE_REG_U8_ARRAY(hDevice, (uint8_t *)pLutData, lutSize, CORE_LUT_DATA); 02209 02210 return ADMW_SUCCESS ; 02211 }
Generated on Wed Jul 13 2022 01:26:32 by
1.7.2