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.
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