initial commit

Files at this revision

API Documentation at this revision

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

bridge_4w_load_cell_config.c Show annotated file Show diff for this revision Revisions of this file
inc/admw_api.h Show annotated file Show diff for this revision Revisions of this file
lut_data.c Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
src/admw_1001.c Show annotated file Show diff for this revision Revisions of this file
--- 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