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