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