![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
initial commit
Revision 54:31921ad29828, committed 2020-02-19
- Comitter:
- Vkadaba
- Date:
- Wed Feb 19 10:08:13 2020 +0000
- Parent:
- 53:644c5f6300da
- Child:
- 55:215da406282b
- Commit message:
- Added LUT support
Changed in this revision
--- a/bridge_4w_load_cell_config.c Wed Feb 19 09:09:59 2020 +0000 +++ b/bridge_4w_load_cell_config.c Wed Feb 19 10:08:13 2020 +0000 @@ -68,14 +68,14 @@ .enableChannel = true, .disablePublishing = false, .compensationChannel = ADMW1001_CH_ID_NONE, - .lutSelect = ADMW1001_LUT_DEFAULT, + .lutSelect = ADMW1001_LUT_CUSTOM, .measurementUnit = ADMW1001_MEASUREMENT_UNIT_UNSPECIFIED, .lowThreshold = 0, .highThreshold = 45359.2, .offsetAdjustment = 0.0, .gainAdjustment = 0.0, .sensorParameter = 0.0, - .measurementsPerCycle = 1, + .measurementsPerCycle = 10, .cycleSkipCount = 0, .extraSettlingTime = 5, .priority = 0,
--- a/inc/admw_api.h Wed Feb 19 09:09:59 2020 +0000 +++ b/inc/admw_api.h Wed Feb 19 10:08:13 2020 +0000 @@ -51,6 +51,7 @@ #include "inc/admw_log.h" #include "inc/admw_time.h" #include "inc/admw1001/admw1001_sensor_types.h" +#include "inc/admw1001/admw1001_lut_data.h" /*! @defgroup ADMW_Api ADMW Host Library API * Host library API common to the ADMW product family. @@ -658,6 +659,72 @@ ADMW_STATUS * const pStatus); /*! + * @brief Assemble a list of separate Look-Up Tables into a single buffer + * + * @param[out] pLutBuffer Pointer to the Look-Up Table data buffer where + * the assembled Look-Up Table data will be placed + * @param[in] nLutBufferSize Allocated size, in bytes, of the output data buffer + * @param[in] nNumTables Number of tables to add to the Look-Up Table buffer + * @param[in] ppDesc Array of pointers to the table descriptors to be added + * @param[in] ppData Array of pointers to the table data to be added + * + * @return Status + * - #ADMW_SUCCESS Call completed successfully. + * + * @details This utiliity function fills the Look-up Table header fields; then + * walks through the array of individual table descriptor and data + * pointers provided, appending (copying) each one to the Look-Up Table + * data buffer. The length and crc16 fields of each table descriptor + * will be calculated and filled by this function, but other fields in + * the descriptor structure must be filled by the caller beforehand. + * + * @note The assembled LUT data buffer filled by this function can then be + * written to the device memory using @ref admw1001_SetLutData. + */ +ADMW_RESULT admw1001_AssembleLutData( + ADMW1001_LUT *pLutBuffer, + unsigned nLutBufferSize, + unsigned const nNumTables, + ADMW1001_LUT_DESCRIPTOR *const ppDesc[], + ADMW1001_LUT_TABLE_DATA *const ppData[]); + +/*! + * @brief Write Look-Up Table data to the device memory + * + * @param[in] hDevice ADMW1001 device context handle + * @param[out] pLutData Pointer to the Look-Up Table data structure + * + * @return Status + * - #ADMW_SUCCESS Call completed successfully. + * + * @details Validates the Look-Up Table data format and loads it into + * device memory via dedicated keyhole registers. + * + * @note Settings are not applied until admw_ApplyConfigUpdates() is called + */ +ADMW_RESULT admw1001_SetLutData( + ADMW_DEVICE_HANDLE hDevice, + ADMW1001_LUT *const pLutData); + +/*! + * @brief Write Look-Up Table raw data to the device memory + * + * @param[in] hDevice ADMW device context handle + * @param[out] pLutData Pointer to the Look-Up Table raw data structure + * + * @return Status + * - #ADMW_SUCCESS Call completed successfully. + * + * @details This can be used instead of @ref admw1001_SetLutData for + * loading LUT data from the alternative raw data format. See + * @ref admw1001_SetLutData for more information. + * + * @note Settings are not applied until admw_ApplyConfigUpdates() is called + */ +ADMW_RESULT admw1001_SetLutDataRaw( + ADMW_DEVICE_HANDLE hDevice, + ADMW1001_LUT_RAW *const pLutData); +/*! * @brief Read measurement data samples from the device registers. * * @param[in] hDevice ADMW device context handle
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lut_data.c Wed Feb 19 10:08:13 2020 +0000 @@ -0,0 +1,45 @@ +#include "admw1001/admw1001_lut_data.h" +#include "admw1001/admw1001_sensor_types.h" +#include "inc/admw_config_types.h" +/* + * The following table provide linearisation data for a 4-wire bridge sensor + * identified with the ADMW1001_ADC_SENSOR_BRIDGE_4WIRE_1 + * sensor type. The Look-Up Table provided maps a range of input (X) + * values to a corresponding range of output (Y) values. In this example, + * the bridge sensor input in millivolts is effectively translated to volts. + */ +ADMW1001_LUT_DESCRIPTOR bridge_4wire_1_range1_desc = { + .geometry = ADMW1001_LUT_GEOMETRY_NES_1D, + .channel =ADMW1001_CH_ID_ANLG_1_UNIVERSAL, + .equation = ADMW1001_LUT_EQUATION_LUT, + .dir = ADMW1001_LUT_TC_DIRECTION_FORWARD, + .sensor = ADMW1001_ADC_SENSOR_BRIDGE_4WIRE_1, + .dataType = ADMW1001_LUT_DATA_TYPE_FLOAT32, + .length = 0, /* Filled by admw_1001_AssembleLutData() */ + .crc16 = 0 /* Filled by admw_1001_AssembleLutData() */ +}; +ADMW1001_LUT_1D_NES bridge_4wire_1_range1_data = { + .nElements = 2, + .lut = { + -0.5f, /* x(min) */ + +0.5f, /* x(max) */ + -0.5f, /* y(min) */ + +0.5f, /* y(max) */ + }, +}; + +/* + * The following variables can be passed as parameters to + * admw_1001_AssembleLutData() + */ +ADMW1001_LUT_DESCRIPTOR *lut_desc_list[] = { + &bridge_4wire_1_range1_desc, +}; + +ADMW1001_LUT_TABLE_DATA *lut_data_list[] = { + (ADMW1001_LUT_TABLE_DATA *) &bridge_4wire_1_range1_data, +}; + +unsigned lut_num_tables = + (sizeof(lut_desc_list) / sizeof(lut_desc_list[0])); +
--- a/main.cpp Wed Feb 19 09:09:59 2020 +0000 +++ b/main.cpp Wed Feb 19 10:08:13 2020 +0000 @@ -45,7 +45,10 @@ #include "admw_log.h" #include "common/utils.h" #include "common/platform.h" +#include "admw1001/ADMW1001_REGISTERS_typedefs.h" #include "admw1001/ADMW1001_REGISTERS.h" +#include "admw1001/admw1001_lut_data.h" +#include "admw1001/admw1001_host_comms.h" extern ADMW_CONFIG thermocouple_typeK_cjc0_config; extern ADMW_CONFIG thermocouple_typeT_cjc0_config; @@ -60,7 +63,12 @@ extern ADMW_CONFIG measureware_config; /* Change the following pointer to load or change the configurations */ -static ADMW_CONFIG *pSelectedConfig = &thermocouple_typeK_cjc0_config; +static ADMW_CONFIG *pSelectedConfig = &bridge_4w_load_cell_config; + +/* use the following to load LUT */ +extern ADMW1001_LUT_DESCRIPTOR *lut_desc_list[]; +extern ADMW1001_LUT_TABLE_DATA *lut_data_list[]; +extern unsigned lut_num_tables; static ADMW_CONNECTION connectionInfo = PLATFORM_CONNECTION_INFO; @@ -114,6 +122,28 @@ ADMW_LOG_ERROR("Failed to set device configuration"); return res; } + unsigned lutBufferSize = ADMW_LUT_MAX_SIZE; + ADMW1001_LUT *pLutBuffer = (ADMW1001_LUT *) malloc(lutBufferSize); + if (pLutBuffer == NULL) { + return 1; + } + + res=admw1001_AssembleLutData(pLutBuffer, lutBufferSize, + lut_num_tables, + lut_desc_list, + lut_data_list); + if( res != ADMW_SUCCESS ) { + ADMW_LOG_ERROR("Failed to assemble user-defined LUT data"); + return res; + } + + res=admw1001_SetLutData(hDevice, + pLutBuffer); + if( res != ADMW_SUCCESS ) { + ADMW_LOG_ERROR("Failed to set user-defined LUT data"); + } + + free( pLutBuffer ); res = admw_ApplyConfigUpdates(hDevice); if (res != ADMW_SUCCESS) { ADMW_LOG_ERROR("Failed to apply device configuration");
--- a/src/admw_1001.c Wed Feb 19 09:09:59 2020 +0000 +++ b/src/admw_1001.c Wed Feb 19 10:08:13 2020 +0000 @@ -2341,95 +2341,7 @@ return ADMW_SUCCESS; } -ADMW_RESULT admw1001_SetLutData( - ADMW_DEVICE_HANDLE const hDevice, - ADMW1001_LUT * const pLutData) -{ - ADMW1001_LUT_HEADER *pLutHeader = &pLutData->header; - ADMW1001_LUT_TABLE *pLutTable = pLutData->tables; - unsigned actualLength = 0; - - if (pLutData->header.signature != ADMW_LUT_SIGNATURE) { - ADMW_LOG_ERROR("LUT signature incorrect (expected 0x%X, actual 0x%X)", - ADMW_LUT_SIGNATURE, pLutHeader->signature); - return ADMW_INVALID_SIGNATURE; - } - if ((pLutData->tables->descriptor.geometry!= ADMW1001_LUT_GEOMETRY_NES_1D) && - (pLutData->tables->data.lut1dNes.nElements > MAX_LUT_NUM_ENTRIES)) { - return ADMW_INVALID_PARAM; - } - for (unsigned i = 0; i < pLutHeader->numTables; i++) { - ADMW1001_LUT_DESCRIPTOR *pDesc = &pLutTable->descriptor; - ADMW1001_LUT_TABLE_DATA *pData = &pLutTable->data; - unsigned short calculatedCrc; - - switch (pDesc->geometry) { - case ADMW1001_LUT_GEOMETRY_COEFFS: - switch (pDesc->equation) { - case ADMW1001_LUT_EQUATION_POLYN: - case ADMW1001_LUT_EQUATION_POLYNEXP: - case ADMW1001_LUT_EQUATION_QUADRATIC: - case ADMW1001_LUT_EQUATION_STEINHART: - case ADMW1001_LUT_EQUATION_LOGARITHMIC: - case ADMW1001_LUT_EQUATION_BIVARIATE_POLYN: - break; - default: - ADMW_LOG_ERROR("Invalid equation %u specified for LUT table %u", - pDesc->equation, i); - return ADMW_INVALID_PARAM; - } - break; - case ADMW1001_LUT_GEOMETRY_NES_1D: - break; - default: - ADMW_LOG_ERROR("Invalid geometry %u specified for LUT table %u", - pDesc->geometry, i); - return ADMW_INVALID_PARAM; - } - - switch (pDesc->dataType) { - case ADMW1001_LUT_DATA_TYPE_FLOAT32: - case ADMW1001_LUT_DATA_TYPE_FLOAT64: - break; - default: - ADMW_LOG_ERROR("Invalid vector format %u specified for LUT table %u", - pDesc->dataType, i); - return ADMW_INVALID_PARAM; - } - - calculatedCrc = admw_crc16_ccitt(pData, pDesc->length); - if (calculatedCrc != pDesc->crc16) { - ADMW_LOG_ERROR("CRC validation failed on LUT table %u (expected 0x%04X, actual 0x%04X)", - i, pDesc->crc16, calculatedCrc); - return ADMW_CRC_ERROR; - } - - actualLength += sizeof(*pDesc) + pDesc->length; - - /* Move to the next look-up table */ - pLutTable = (ADMW1001_LUT_TABLE *)((uint8_t *)pLutTable + sizeof(*pDesc) + pDesc->length); - } - - if (actualLength != pLutHeader->totalLength) { - ADMW_LOG_ERROR("LUT table length mismatch (expected %u, actual %u)", - pLutHeader->totalLength, actualLength); - return ADMW_WRONG_SIZE; - } - - if (sizeof(*pLutHeader) + pLutHeader->totalLength > ADMW_LUT_MAX_SIZE) { - ADMW_LOG_ERROR("Maximum LUT table length (%u bytes) exceeded", - ADMW_LUT_MAX_SIZE); - return ADMW_WRONG_SIZE; - } - - /* Write the LUT data to the device */ - unsigned lutSize = sizeof(*pLutHeader) + pLutHeader->totalLength; - WRITE_REG_U16(hDevice, 0, CORE_LUT_OFFSET); - WRITE_REG_U8_ARRAY(hDevice, (uint8_t *)pLutData, lutSize, CORE_LUT_DATA); - - return ADMW_SUCCESS; -} ADMW_RESULT admw1001_SetLutDataRaw( ADMW_DEVICE_HANDLE const hDevice, ADMW1001_LUT_RAW * const pLutData) @@ -2517,3 +2429,102 @@ return ADMW_SUCCESS; } +ADMW_RESULT admw1001_SetLutData( + ADMW_DEVICE_HANDLE const hDevice, + ADMW1001_LUT * const pLutData) +{ + ADMW1001_LUT_HEADER *pLutHeader = &pLutData->header; + ADMW1001_LUT_TABLE *pLutTable = pLutData->tables; + + unsigned actualLength = 0; + + if (pLutData->header.signature != ADMW_LUT_SIGNATURE) + { + ADMW_LOG_ERROR("LUT signature incorrect (expected 0x%X, actual 0x%X)", + ADMW_LUT_SIGNATURE, pLutHeader->signature); + return ADMW_INVALID_SIGNATURE; + } + if ((pLutData->tables->descriptor.geometry!= ADMW1001_LUT_GEOMETRY_NES_1D) && + (pLutData->tables->data.lut1dNes.nElements > MAX_LUT_NUM_ENTRIES)) + { + return ADMW_INVALID_PARAM; + } + + for (unsigned i = 0; i < pLutHeader->numTables; i++) + { + ADMW1001_LUT_DESCRIPTOR *pDesc = &pLutTable->descriptor; + ADMW1001_LUT_TABLE_DATA *pData = &pLutTable->data; + unsigned short calculatedCrc; + + switch (pDesc->geometry) + { + case ADMW1001_LUT_GEOMETRY_COEFFS: + switch (pDesc->equation) + { + case ADMW1001_LUT_EQUATION_POLYN: + case ADMW1001_LUT_EQUATION_POLYNEXP: + case ADMW1001_LUT_EQUATION_QUADRATIC: + case ADMW1001_LUT_EQUATION_STEINHART: + case ADMW1001_LUT_EQUATION_LOGARITHMIC: + case ADMW1001_LUT_EQUATION_BIVARIATE_POLYN: + break; + default: + ADMW_LOG_ERROR("Invalid equation %u specified for LUT table %u", + pDesc->equation, i); + return ADMW_INVALID_PARAM; + } + break; + case ADMW1001_LUT_GEOMETRY_NES_1D: + break; + default: + ADMW_LOG_ERROR("Invalid geometry %u specified for LUT table %u", + pDesc->geometry, i); + return ADMW_INVALID_PARAM; + } + + switch (pDesc->dataType) + { + case ADMW1001_LUT_DATA_TYPE_FLOAT32: + case ADMW1001_LUT_DATA_TYPE_FLOAT64: + break; + default: + ADMW_LOG_ERROR("Invalid vector format %u specified for LUT table %u", + pDesc->dataType, i); + return ADMW_INVALID_PARAM; + } + + calculatedCrc = admw_crc16_ccitt(pData, pDesc->length); + if (calculatedCrc != pDesc->crc16) + { + ADMW_LOG_ERROR("CRC validation failed on LUT table %u (expected 0x%04X, actual 0x%04X)", + i, pDesc->crc16, calculatedCrc); + return ADMW_CRC_ERROR; + } + + actualLength += sizeof(*pDesc) + pDesc->length; + + /* Move to the next look-up table */ + pLutTable = (ADMW1001_LUT_TABLE *)((uint8_t *)pLutTable + sizeof(*pDesc) + pDesc->length); + } + + if (actualLength != pLutHeader->totalLength) + { + ADMW_LOG_ERROR("LUT table length mismatch (expected %u, actual %u)", + pLutHeader->totalLength, actualLength); + return ADMW_WRONG_SIZE; + } + + if (sizeof(*pLutHeader) + pLutHeader->totalLength > ADMW_LUT_MAX_SIZE) + { + ADMW_LOG_ERROR("Maximum LUT table length (%u bytes) exceeded", + ADMW_LUT_MAX_SIZE); + return ADMW_WRONG_SIZE; + } + + /* Write the LUT data to the device */ + unsigned lutSize = sizeof(*pLutHeader) + pLutHeader->totalLength; + WRITE_REG_U16(hDevice, 0, CORE_LUT_OFFSET); + WRITE_REG_U8_ARRAY(hDevice, (uint8_t *)pLutData, lutSize, CORE_LUT_DATA); + + return ADMW_SUCCESS; +} \ No newline at end of file