ADISense1000 Version 2.1 code base

Fork of AdiSense1000_V21 by Sean Wilson

Revision:
26:12d0204be712
Child:
27:567abf893938
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/key_topics.md	Mon Mar 26 14:50:05 2018 +0000
@@ -0,0 +1,451 @@
+Key Topics
+==========
+
+[TOC]
+
+# Register Interface {#registerinterface}
+The ADSNS1000 module provides a register-style interface for the purpose
+of exchanging configuration, status, and data with the host application
+processor.
+
+## Overview {#registerinterface_overview}
+The registers can be divided broadly into the following categories:
+* Command input register
+  - This special register is used to issue commands to the module.
+  - Commands are issued to tell the ADSNS1000 what operation is required.
+  - New commands are typically ignored until the running command has completed
+    (as indicated via the Status registers).
+* Configuration input registers
+  - Configuration registers are used to specify the required configuration
+    parameters for use by the module, typically specifying details such as
+    operating mode, sensor information, measurement thresholds, and many other
+    options.
+  - Changes to configuration input registers are typically ignored until a
+    command is issued to "apply" the configuration on the device.
+* Status output registers
+  - Status information is provided by the ADSNS1000 module via these read-only
+    registers.
+  - Dedicated output signals (e.g. ERROR and ALERT) are linked with this status
+    information.
+  - The host application processor may acknowledge and reset/clear the status
+    indicators by reading the relevant status registers.  The status indicators
+    will be set again if the underlying condition is present.
+* Data output registers
+  - Measurement data samples produced by the ADSNS1000 are accessed via a
+    FIFO-style register which may be read repeatedly until all available data
+    has been consumed.
+  - Data samples are provided in a pre-determined format according to the
+    measurement command selected.
+  - When a CONVERT command is issued the output spans 5 bytes and is comprised
+    of the 32 bit floating point measurement result and a byte of status
+    information.
+  - When a CONVERT\_WITH\_RAW command is issued the output spans 8 bytes and is
+    comprised of the 32 bit floating point measurement result, a byte of status
+    information and 3 bytes of raw uncompensated data sample retrieved from the
+    sensor input channel.
+  - Status information provided with the measurement result indicate the channel
+    number and indicate ALERT or ERROR conditions.
+* Keyhole access registers
+  - Access to large internal memory regions within the module is typically
+    provided via a pair of "keyhole" registers, consisting of an address
+    register and a data register.
+  - An address (i.e. a starting offset within the region) must first be written
+    to the address register, then the companion data register may be accessed
+    repeatedly to read/write data to the corresponding region.  The address is
+    automatically incremented with each access to the data register, so that
+    data can be transferred in a single burst for efficiency.
+
+# Configuration {#configuration}
+The ADSNS1000 module is a flexible measurement module which must be configured
+via the [register interface](@ref registerinterface) before it can be used to
+acquire and process data from external sensor inputs.
+
+## Overview {#configuration_overview}
+A configuration consists of the following elements:
+* Global configuration register settings, such as:
+  - Operating modes
+  - Power modes
+  - Measurement cycle times
+  - External reference options
+* Channel-specific register settings, such as:
+  - measurement count
+  - sensor type
+  - sensor configuration details
+  - settling time
+  - filter options
+  - threshold limits
+  - calibration adjustments
+* Measurement Correction data
+  - used to compensate for the non-linear characteristics of analog
+    sensors/transducers
+  - supplied via a Look-Up Table data structure with a specific format
+  - ADSNS1000 provides the complete sensor measurement solution for custom
+    sensors - excitation, measurement and correction
+
+## Configuration data structure {#configuration_data}
+Although the module can be configured and managed directly via the
+[register interface](@ref registerinterface), the ADISENSE Host Library
+provides a level of abstraction above this which allows a more simplified
+programming paradigm between the Host processor and the ADSNS1000 module.
+
+A single C-language configuration data structure can be used to define all
+configuration values for the ADSNS1000 module. This can be passed to the
+relevant ADISENSE Host Library API functions, which will do the work of
+translating the configuration details into the appropriate register values and
+sending them to the ADSNS1000 module via its host SPI communication interface.
+
+Individual configurations are stored and compiled as .c files and a
+configuration may be selected and loaded by the application code.  Note that
+only the essential configuration fields are filled, depending on the specific
+sensor configuration and operating mode required.
+
+## Loading and Applying a configuration {#configuration_loading}
+Configuration data must first be loaded via the @ref adi_sense_SetConfig API
+function. This function updates the registers on the ADSNS1000 module according
+to the supplied configuration details. The new configuration is then activated
+by calling the @ref adi_sense_ApplyConfigUpdates function. This function issues
+a special command to instruct the module to apply the new configuration.  If
+user-defined linearisation data is also required, this must also be loaded via
+the @ref adi_sense_1000_SetLutData function _before_ applying the new
+configuration.
+
+To avoid loading the configuration details to the module every time it is
+powered on, it is possible to save the configuration to non-volatile memory
+on the module using @ref adi_sense_SaveConfig and @ref adi_sense_SaveLutData.
+The saved configuration is automatically restored by default when the module is
+subsequently reset or power cycled. This configuration can be reloaded on demand
+if required using the @ref adi_sense_RestoreConfig and @ref
+adi_sense_RestoreLutData functions.  Note that, in all cases, @ref
+adi_sense_ApplyConfigUpdates _must_ be called to instruct the module to
+apply/activate the configuration before it will be used.
+
+Once a valid configuration has been loaded and applied, the user may issue
+commands to the ADSNS1000 module to initiate measurement cycles, internal
+calibration, or diagnostic routines (all of which depend on a valid
+configuration being applied in advance).
+
+## Configuration errors {#configuration_errors}
+Attempts to load invalid configuration details will be flagged via the relevant
+status registers and signals.  After calling @ref adi_sense_ApplyConfigUpdates,
+it is advisable to check the status of the module by calling @ref
+adi_sense_GetStatus and examining the relevant status information returned from
+the module.  Subsequent commands issued to the module may not execute correctly
+in the presence of unresolved configuration errors.
+
+# Measurement Cycles {#measurementcycles}
+## Overview {#measurementcycles_overview}
+Conversions are carried out sequentially across each of the enabled channels in
+a predictable pattern which has a defined order and user-specified number of
+conversions per channel.  This is typically referred to as the _Measurement
+Sequence_.
+
+A _Measurement Cycle_ essentially consists of a single _Measurement Sequence_
+which may be repeated at specified time intervals.
+
+The configuration parameters required to define the Measurement Cycle and
+Sequence are as follows:
+* Cycle interval time (specified in microseconds/milliseconds/seconds)
+* For each enabled sensor input channel:
+  - Number of conversions-per-cycle
+  - Extra settling time (specified in microseconds)
+
+In addition to the cycle time, the following operating modes dictate when and
+how many cycles should be executed:
+* **Single-Cycle Mode**
+  - Executes a single Measurement Cycle and stops
+* **Continuous Mode**
+  - Executes Measurement Cycles continuously until stopped by the host
+    application processor
+* **Multi-Cycle Mode**
+  - Executes a specified number (burst) of Measurement Cycles and stores the
+    results in a buffer for retrieval by the host.
+  - Repeats this indefinitely at specified intervals (multi-cycle burst
+    interval) until stopped by the host application processor.
+
+## Executing Measurement Cycles {#measurementcycles_executing}
+Once a valid configuration is loaded (see @ref configuration),
+Measurement Cycles are initiated by the host application processor via @ref
+adi_sense_StartMeasurement, and may be stopped if necessary via @ref
+adi_sense_StopMeasurement.  These functions issue the relevant commands to the
+ADSNS1000 module via its dedicate command register.
+
+Certain auxiliary tasks may also be carried out internally by the module on a
+per-cycle basis, such as Calibration and Diagnostics.  These are discussed in
+in later sections below.
+
+## Sequence Order {#measurementcycles_sequence}
+The sequence is constructed according to which channels are enabled and how many
+measurements must be performed per channel.  The arrangement is similar to
+round-robin scheduling - a measurement is carried out on each enabled channel,
+in ascending channel order, and then the loop is repeated until the requested
+number of measurements on each channel has been satisfied.
+
+For example, lets say channels [0, 3, 4, 5] are enabled, with
+measurementsPerCycle set as follows:
+
+channelId | measurementsPerCycle
+--------- | --------------------
+    CJC_1 | 4
+ SENSOR_0 | 2
+    I2C_1 | 3
+    SPI_0 | 1
+
+The length of the sequence would be 10 measurements in total, and the order in
+which the channel measurements appear in the sequence would look like this:
+
+| **CJC_1** | **SENSOR_0** | **I2C_1** | **SPI_0** | **CJC_1** | **SENSOR_0** | **I2C_1** | **CJC_1** | **I2C_1** | **CJC_1** |
+
+When measurement data samples are retrieved from the ADISENSE by the host
+application, this is the order in which those data samples will appear.
+
+The ADSNS1000 module has 11 measurement ports however when ADXL used on the SPI
+port this equates to 3 measurements. The ADSNS1000 allows for a maximum of 128
+measurementsPerCycle. Therefore a single cycle can produce a maximum of 1664
+measurements. In other words, the maximum length of the sequence is 1664.
+
+## Sequence Timing {#measurementcycles_timing}
+The timing of each measurement within the sequence depends on a number of
+factors:
+* **Settling time**
+  - A settling time is applied when switching between each channel (unless there
+    is only a single channel in the sequence), particularly to allow the analog
+    front-end circuit to settle before a conversion is performed.
+  - Each channel is subject to a minimum settling time (as specified in the
+    ADSNS1000 datasheet)
+  - Additional settling time can be configured per-channel if required
+  - As the analog sensor channels are multiplexed into the ADC, with each
+    channel potentially having a different front-end circuit depending on the
+    sensor type selected, the settling and conversion of the analog channels
+    must be done one-at-a-time in series.  Their settling time starts only when
+    the channel is reached in the sequence.
+  - Digital sensors operate independently, and so are activated in parallel to
+    other sensors.  Consequently, their settling time may start at the start of
+    a cycle, or immediately after a previous conversion result has been obtained
+    from the digital sensor.
+* **Conversion time**
+  - Once the settling time has passed, a conversion is initiated to obtain a raw
+    measurement value from the sensor input.
+  - The time required for the conversion may be influenced by factors such as
+    filter configuration (in the case of analog channels) or specific digital
+    sensor performance characteristics and configuration options.
+* **Processing time**
+  - Once the raw conversion result is obtained, it is subjected to further
+    processing to apply correction for non-linear sensors, calibration
+    adjustments, and conversion into final measurement units
+  - The processing time varies depending on the sensor type and correction
+    algorithms to be applied, but a standard budget of processing time (as
+    specified in the ADSNS1000 datasheet) is allocated to each channel to
+    produce consistent and predictable time separation between the channel
+    measurement results.
+
+So, to summarise, the distinct phases for each measurement on each channel
+typically look like this:
+
+**settling** > **conversion** > **processing** > **publishing**
+
+Taking the sequence example in the previous section, let's assume a base
+settling time (_Ts_) and processing time (_Tp_) of 500 microseconds for each
+channel and the following variable timing parameters _Te_ and _Tc_ (in units of
+microseconds):
+
+channelId | extraSettlingTime (_Te_) | conversionTime (_Tc_) | sum (_Ts_ + _Te_ + _Tc_ + _Tp_) | measurementsPerCycle | total
+--------- | ------------------------ | --------------------- | ------------------------------- | -------------------- | -----
+    CJC_1 | 4000                     | 50000                 | 55000                           | 4                    | 220000
+ SENSOR_0 | 1000                     | 50000                 | 52000                           | 2                    | 104000
+    I2C_1 | 20000                    | 1000                  | 22000                           | 3                    | 66000
+    SPI_0 | 0                        | 800                   | 1800                            | 1                    | 1800
+
+To clarify: _Te_ above comes directly from the channel configuration.  _Tc_,
+however, is dictated by the sensor and its configuration.
+
+The minimum time required for the cycle to complete is, in the above example,
+391800 microseconds.
+
+If the selected operating mode is Continuous or Multi-Cycle mode, the
+configuration must also specify the interval between successive cycles
+(cycleInterval).   If this is less than the actual time required to
+complete the cycle, the next cycle will start immediately after the
+completion of the previous one; if it is more, there will be a delay
+until the next cycle is started.
+
+## Measurement Results storage and retrieval {#measurementcycles_publishing}
+As part of module configuration, a data-ready mode must be selected to indicate
+how measurements results are made available and retained for consumption by the
+host application processor:
+
+* **Per-Conversion**
+  - In this mode, each measurement result is made available as soon as it is
+    ready.
+  - Only a single result is stored, and it is overwritten when the next
+    measurement result becomes ready.  Only the latest result is retained.
+  - The host application processor must consume each  measurement result (by
+    reading the DATA_FIFO register) as soon as the result becomes available. The
+    availability of each result is identified by a DRDY rising edge.
+* **Per-Cycle**
+  - In this mode, the measurement results from a full cycle (10 data samples, in
+    the example above) are made available only when the measurement cycle is
+    complete.
+  - The results are overwritten when the next measurement cycle (if any) is
+    completed.
+  - The host application processor must consume the measurement results in a
+    batch as soon as they become available.
+* **Per-Multicycle-Burst**
+  - In this mode, the measurement results from a burst of measurement cycles are
+    made available only when the measurement cycles are completed.
+  - The results are overwritten when the next burst of measurement cycles are
+    completed.
+  - The host application processor must consume the measurement results in a
+    batch as soon as they become available.
+  - Note that this data-ready mode is only available when the Multi-Cycle
+    operating mode is also selected.
+
+When new measurement results are ready for retrieval, the DRDY output signal
+is asserted.  The host application may check this signal continuously, or attach
+an interrupt notification to this signal, to ensure that measurement results are
+retrieved in a timely fashion before they are subsequently overwritten by the
+next conversion/cycle.  Alternatively, the host application may also read the
+STATUS register to check the DRDY status indicator.
+
+The ADISENSE Host Library API provides the following functions which are
+relevant for data retrieval:
+* @ref adi_sense_RegisterGpioCallback for receiving DRDY interrupt notifications
+* @ref adi_sense_GetGpioState for polling the state of the DRDY signal
+* @ref adi_sense_GetStatus for reading the module status registers
+* @ref adi_sense_GetData for retrieving the measurement results from the module
+
+The @ref adi_sense_1000_GetDataReadyModeInfo API function, specific to the
+ADSNS1000, is useful for obtaining information on the number of measurement
+results to expect when the DRDY indicator is asserted, based on the operating
+and data-ready mode configuration settings currently set in the ADSNS1000 module
+registers.
+
+# Calibration {#calibration}
+The ADSNS1000 module incorporates a number of calibration measures to ensure
+the accuracy of measurement results, described in the following sections.  These
+mostly pertain to the analog measurement channels, but some provisions are also
+included for calibration of digital sensors.
+
+## Factory calibration {#calibration_factory}
+Calibration is performed during factory production for removal of errors
+introduced by components (e.g. resistors, switches) present on the signal paths
+of the module's analog front-end.  Calibration offset and gain values are
+calculated and stored in non-volatile memory within the module as part of the
+production process.  These are applied automatically without intervention from
+the host application.
+
+## Internal auto-calibration {#calibration_internal}
+The high-accuracy ADC incorporated within the ADSNS1000 module includes internal
+calibration functions to assist in removing offset or gain errors internal to
+that ADC.  As this is a time-consuming process, it is invoked only in the
+following circumstances:
+* The host application issues a self-calibration command (@ref
+  adi_sense_RunCalibration)
+* The host application updates the module configuration and the module
+  determines, based on the configuration changes, that re-calibration is
+  required.  In this case, the calibration is carried out at the point where the
+  new configuration settings are applied (@ref adi_sense_ApplyConfigUpdates)
+
+In all cases, a valid configuration must be set and is used as part of the
+calibration process.  External sensors and reference circuits must be
+connected for calibration to work correctly.
+
+## User calibration {#calibration_user}
+Additional gain and offset correction parameters may be specified per-channel as
+part of the module configuration.  These are applied as a final step to each
+measurement result from the channel during the final stages of processing before
+the data sample is made available to the host processor.
+
+# Diagnostics {#diagnostics}
+The ADC within the ADSNS1000 module includes a range of sophisticated diagnostic
+features to automatically detect error conditions such as under-/over-voltage on
+analog input signals, supply voltage errors, reference detection errors and more
+as detailed in the ADSNS1000 Datasheet.  These diagnostics are enabled by
+default and, if triggered, will result in an ERROR or ALERT signal being
+asserted by the module.  Diagnostic status can be queried via the module status
+registers (@ref adi_sense_GetStatus).
+
+Additional diagnostic tests may be executed by the module to detect additional
+error conditions such as a disconnected or mis-wired sensor.  These tests can be
+time-consuming, and so are carried out only if selected by the user:
+* Sensor diagnostics may be requested by executing a dedicated diagnostics
+  command (@ref adi_sense_RunDiagnostics)
+* Sensor diagnostics may be optionally executed at the start of each measurement
+  cycle, at a frequency determined by the user through the configuration
+  parameters (see @ref ADI_SENSE_1000_DIAGNOSTICS_CONFIG)
+
+# Sensor Linearisation {#linearisation}
+Analog sensors can produce an output which may not be completely linear or
+directly proportional with respect to their input.  Different sensor types
+generally have different linearity characteristics, each requiring different
+correction methods or coefficients for accurate translation of the sensor output
+back to the corresponding input.  Typical methods include use of linearisation
+formulae (e.g. polynomial equations with variable coefficients), or tables of
+sample input values and their corresponding outputs which can be used with
+interpolation to perform the translation.
+
+The ADSNS1000 module performs linearisation and calibration correction of the
+analog sensor measurements, and incorporates the linearisation functions
+complete with coefficients or translation tables for a range of supported sensor
+types.  On the ADSNS1000 module, for example, measurement results from any
+[sensor types](@ref ADI_SENSE_1000_ADC_SENSOR_TYPE) named with the "_L1" suffix
+will be automatically linearised using built-in linearisation functions and
+coefficients or translation tables.
+
+It is also possible to have ADSNS1000 perform linearisation on other custom
+sensor types.  A range of [sensor type IDs](@ref ADI_SENSE_1000_ADC_SENSOR_TYPE)
+named with an "_L2" suffix are reserved for this purpose.  By specifying one of
+these sensor types, and by providing the necessary linearisation information for
+that sensor type as part of a "look-up table" data structure loaded via the @ref
+adi_sense_1000_SetLutData API function, the ADSNS1000 module can be extended to
+work with sensor variants which require a different linearisation than what is
+already provided through built-in methods. Linearisation data may be provided
+in the form of a coefficient list for a polynomial equation, or as a translation
+table, depending on what is most appropriate for that sensor.
+
+Translation tables can be expressed in a number of formats, such as 1- or
+2-Dimensional tables, with equally- or non-equally-spaced vectors.  2-D tables
+are used where the sensor output is affected by both the sensor input and
+another factor such as the operating temperature of the sensor itself.  If the
+sensor output values can be captured for an equally-spaced set of input values
+(i.e. values separated by a constant increment, such as 3,6,9,12,etc.), the
+equally-spaced table formats allow for a more compact representation as only the
+output values need to be listed individually.
+
+Multiple coefficient lists can be specified for a given sensor type, along with
+an applicable range of input values, as it may be necessary to apply different
+equations depending on the input range.  For example, RTD sensors feature a
+different linearity curve for input ranges above/below 0 degrees Celsius.
+
+The ADSNS1000 module allows a flexible look-up table (LUT) data structure up to
+a [maximum size](@ref ADI_SENSE_LUT_MAX_SIZE) to be loaded by the user for use
+with custom "L2" sensor types.  The LUT data structure format, defined as @ref
+ADI_SENSE_1000_LUT, allows for a variable set of tables of different formats
+to be included as part of the overall data structure.  Each table is preceeded
+by a descriptor which specifies the format of the following table.  A single
+top-level header at the start of the LUT specifies how many tables are contained
+within.  The LUT structure basically looks like this:
+
+    |---------------------|
+    | top-level header    |
+    |---------------------|
+    | table #0 descriptor |
+    | table #0 data       |
+    |---------------------|
+    | table #1 descriptor |
+    | table #1 data       |
+    |---------------------|
+             ~~~
+    |---------------------|
+    | table #N descriptor |
+    | table #N data       |
+    |---------------------|
+
+To cater for this flexibility, the data structure definition can appear to be
+complex. To absorb some of this complexity, a supplementary API function named
+@ref adi_sense_1000_AssembleLutData is provided. By providing a list of
+pointers to descriptors and data elements for each table to be included in the
+LUT structure, along with buffer of allocated memory, this function constructs
+the top-level header and appends each table and also fills some fields within
+the table descriptors (e.g. length, CRC).  Please refer to the "user_lut_data"
+application example for an illustration of how this function can be used.
+