As Internet of Things (IoT) networks become more complicated, IoT endpoints are performing more complex processing at the edge. This can require upgrading an existing endpoint with a system that has a microcontroller with a faster clock speed, more memory, and a more powerful processor core.
This can also demand sensors and analog-to-digital converters (ADCs) that have a high level of accuracy, and which might require periodic calibration. Linear errors can be easily compensated for with a formula. However, nonlinear errors do not follow a set pattern of deviation from the sensor reading, and so cannot be easily compensated for mathematically. Often the simplest way to compensate for non-linear errors in firmware is to store the required correction data in memory with a data lookup table.
This article will briefly cover sensor and ADC errors and discuss the advantages of using data lookup tables for correcting such errors. It will then explain how to implement a practical and cost-effective data Flash lookup table in an STMicroelectronics STM32L496VG microcontroller-based system using an external ON Semiconductor LE25S161PCTXG serial peripheral interface (SPI) Flash memory chip.
Sensors that detect analog conditions such as temperature, pressure, and voltage can have nonlinear errors. It is important during the development phase of a project to test sensors against an accurate reference and compare the reference value against the sensor’s digital output. This allows the developer to determine early on the nature of any sensor deviations from the reference values and if the deviations are acceptable given the application requirements. The developer can then decide if it is necessary to compensate for any deviations, and if so whether the deviations should be compensated for in hardware or firmware.
Some sensor errors can be predictable linear errors. Compensating for these errors can be as simple as adding or subtracting a constant value to the sensor output. Sometimes these errors can vary over the sensor scale. For example, from zero to one-third full scale it might be necessary to add a constant; from one-third scale to one-half scale, a different constant may be needed.
These errors are predictable and obviously easy to correct. However, the deviation from an accurate reading might change over time. In addition, new sensor errors might develop later due to reasons such as exposure to extreme temperatures, high ambient humidity, or aging of the sensors. Whether or not these errors need to be corrected is always application dependent. It might be necessary to test the system in extremes of temperature, pressure, and humidity to determine the sensor behavior. These environmental tests are required for some applications such as automotive, military, and some industrial systems. However, many new IoT endpoints are going where no sensors have gone before, and so sensor testing might be a new requirement.
Common microcontroller analog peripherals such ADCs can also require periodic in-system calibration like any analog sensor. ADC errors are not always predictable, and even if the initial error can be corrected with an algorithm, the error might change over time, potentially in a manner that cannot be easily corrected with an algorithm. This can result in a system that can no longer function with the required accuracy, leading to expensive replacement costs.
Advantages of using a data lookup table for analog sensor error correction
A data lookup table can be a practical and efficient method to quickly perform some common calculations as complicated as trigonometric functions, or as simple as byte bit reversal or converting a byte to Gray code. Using a 256-byte lookup table for byte bit reversal is significantly faster than performing bit reversal in firmware. It’s safe to store this lookup table in program or data Flash memory as it takes up little space and never needs to be changed.
A data lookup table is also a very practical method for storing sensor calibration data. A microcontroller analog peripheral like a built-in ADC might require periodic calibration using exactly the same method as an analog sensor. The ADCs found in most microcontrollers can be accurate to ±2 or ±3 least significant bits (LSBs). While these can be adequate for most applications, for systems that require high accuracy it makes sense to periodically calibrate the ADCs.
A partial calibration lookup table for correcting 24-bit data might look something like Table 1.
Table 1: An excerpt of an example of a data lookup table for 24-bit calibration data. The raw input value is the source reading that needs to be corrected for errors. This raw value is then used as a 24-bit address and is used to look up a corresponding 32-bit corrected value where the most significant byte is always 00h. (Table data source: Digi-Key Electronics)
In this example, the raw input value is the source reading that needs to be corrected for errors. This raw value is then used as a 24-bit address, and is used to look up a corresponding 32-bit corrected value where the most significant byte is always 00h. An offset may be added to the raw input value if the lookup table does not start at address zero.
Before deciding where to store the lookup table, it’s important to decide how large the lookup table needs to be, and whether it needs to be rewritten. Both are important. A lookup table that fits in the microcontroller’s available on-chip Flash makes sense if it never needs to be rewritten. But if the sensor requires periodic recalibration, this means rewriting the internal Flash, requiring the entire Flash sector with the table to be erased and reprogrammed.
If the Flash sector shares space with program memory, it can require recompiling the code. Even if the lookup table is in its own dedicated sector, memory requirements might change or expand at a later date, resulting in repurposing some of the lookup table sector space for additional code. This complicates sensor calibration in the field and can prevent independent self-calibration of the IoT endpoint by requiring recompiled code to be downloaded over the network. The problem is further complicated if multiple sensors are involved.
Large lookup tables such as a 16,777,216 entry table for calibration of 24-bit digital data are impractical or impossible for on-chip Flash program memory. The size of the lookup table can be halved if only every other entry is stored and the results for the missing entries interpolated based on the existing table data. This results in a small performance hit and a possible loss of accuracy of ±1 LSB. However, even this 8,388,608 entry lookup table can be impractical to store in internal Flash.
The best solution for these large data lookup tables in a microcontroller-based system is external Flash memory. This provides an easy way to add multiple megabytes of lookup tables without sacrificing internal Flash program memory. This also allows the system to easily rewrite the lookup table without interfering with the internal Flash memory of the microcontroller.
For high performance systems, adding external parallel Flash memory has been common for both program and data memory expansion. However, this requires a microcontroller with an external data bus. The additional address and data buses, and the required control signals, can use 36 or more pins of the microcontroller. This requirement limits the microcontrollers available for the application. These external buses also take up additional pc board space and can increase the electromagnetic interference (EMI) of the system.
For most systems the best solution is to use an external serial data Flash memory that uses a serial peripheral interface (SPI) for data transfer. This can require as little as four pins on the microcontroller.
A good example of such a Flash memory device is the LE25S161PCTXG from ON Semiconductor. This is a 16 megabit (Mbit) serial Flash memory device that supports an SPI clock of 70 megahertz (MHz). However, it also supports dual SPI mode which allows it to transfer data at a top speed of 140 Mbits/sec. Internal status registers are used to configure the device's read, write, and low-power modes.
The LE25S161PCTXG has the usual SPI signals for clock, data, and chip select (Figure 1). It also has two additional pins. WP\ is an active-low write protect signal that prevents writing to the status registers of the device. This can be used to prevent low priority firmware tasks from an unauthorized rewriting of the device. HOLD\ pauses a data transfer in progress. This is useful if the microcontroller has to service an interrupt while a data transfer is in progress. The data transfer can be paused until the interrupt is serviced, and then resumed where it left off.
Figure 1: The ON Semiconductor LE25S161PCTXG serial Flash memory is available in an 8-pin UDFN package with an ultra-small 3 x 4 millimeter (mm) footprint, and has the usual SPI signals for clock, data, and chip select. (Image source: ON Semiconductor)
The easiest way to read a simple two column lookup table stored in this device is to take the sensor reading, add a memory offset, and then read the memory contents at that address location. The contents of the memory at that address represent the corrected sensor reading.
A high performance IoT endpoint requires a fast clock speed, a high performance processor, and a flexible SPI. For these applications STMicroelectronics provides the high performance STM32L4 microcontroller family. For example, the STM32L496VG microcontroller is a member of the STM32L4 product family that runs at 80 MHz and has an Arm® Cortex®-M4 core with a floating point unit (FPU). It has 8 Mbits of Flash and 320 kilobytes (Kbytes) of SRAM. It supports an operating voltage of 1.71 to 3.6 volts, overlapping that of the ON Semiconductor LE25S161PCTXG’s operating voltage of 1.65 to 1.95 volts.
The STM32L496VG has a full range of peripherals for a high performance IoT endpoint including a real-time clock (RTC) with calendar, three 5 megasample per second (MSPS) ADCs, a two-channel digital-to-analog converter (DAC), two controller area network (CAN) interfaces, and four I2C interfaces (Figure 2). It also has three standard SPI interfaces and one quad SPI interface.
Figure 2: The STM32L496 microcontroller is based on an 80 MHz Arm Cortex-M4 with FPU and has a full array of peripherals, including a 40 MHz quad SPI interface. (Image source: STMicroelectronics)
Development for the STM32L496VG is supported by the STM32L496G-DISCO discovery board (Figure 3). It is a full-featured development board for an IoT endpoint and includes stereo microelectromechanical systems (MEMS) microphones, an 8-bit camera connector, eight LEDs, a four direction joystick, and a 240 x 240 pixel color LCD. The ADC inputs, quad SPI pins, and most of the I/O are available at the connector pins.
Figure 3: The STM32L496G-DISCO discovery board is a full evaluation environment for hardware and firmware development for the ST32L496VG. (Image source: STMicroelectronics)
The quad SPI on the STM32L496VG supports a maximum SPI clock of 40 MHz and supports standard and memory mapped SPI modes. The quad SPI supports dual SPI mode, allowing data transfers at a maximum 80 Mbits/sec.
STMicroelectronics’ quad SPI provides a fast interface to serial data Flash memory devices. In standard SPI mode, all operations are performed using the SPI registers. Data is transferred by reading and writing the SPI data register. An interrupt is generated when data is received. This is the same operating mode as the three standard SPIs on the STM32L496VG. Standard SPI mode supports single, dual, and quad data transfers. The ON Semiconductor LE25S161 supports single and dual SPI modes and can easily interface with the STM32L496VG in dual SPI mode (Figure 4).
Figure 4: The STMicroelectronics STM32L496VG’s quad SPI serial port can interface to the ON Semiconductor LE25S161 in dual SPI mode, allowing bidirectional transfers of data along SIO0 and SIO1 with a 40 MHz SCLK at 80 Mbits/sec. (Image source: Digi-Key Electronics)
Implementing a data lookup table in this situation is made simple due to the choice of the components from ON Semiconductor and STMicroelectronics, resulting in a straightforward implementation. The quad SPI also has a FIFO which is useful for bulk data transfers. However, for a lookup table where only one memory location needs to be accessed at a time, it is recommended to disable the FIFO as it is not needed and may even add an unnecessary delay.
Quad-SPI with memory-mapped mode
The quad SPI also supports a memory mapped mode. This maps the external serial Flash into either the microcontroller’s program or data memory space. This lets the microcontroller firmware access the external SPI Flash as if it was part of the microcontroller’s own memory, resulting in the operation of the quad SPI that is transparent to the firmware.
If lookup table accesses are done infrequently, implementing a lookup table with memory mapped mode compared to standard SPI mode may not have any significant advantages other than simplifying the application firmware. However, if the application is a frequent interrupt environment, SPI transfers may be repeatedly paused to service them. This can be further complicated if one quad SPI lookup operation is interrupted for another one.
A combination of frequent lookup table accesses plus a high interrupt environment can rapidly make memory mapped mode more efficient compared to standard SPI mode. It simplifies firmware, prevents problems due to simultaneous quad SPI accesses of different priorities, and reduces interrupt conflicts.
However, one disadvantage of implementing a memory mapped lookup table is the possibility of polluting the data cache. While the STM32L496 does not have a data cache, some microcontrollers that target high performance real-time applications do. Accessing the lookup table will most likely result in a cache miss. This is because for most applications there is a very low possibility of needing to access the same lookup table location twice in the same thread or subroutine. The lookup table data therefore is not initially cached, and caching the data can result in important data being removed from the data cache. While this is only a problem in extremely high performance applications, it is these high performance applications that require a data cache in the first place.
Solutions for data cache pollution by a lookup table are limited. If the hardware allows it, the lookup table area can be marked as non-cacheable. Another solution is to disable and then re-enable the data cache before and after accessing the lookup table. This may be acceptable if the performance hit of toggling the cache on and off is acceptable. Some data caches support architecture specific cache control instructions that can provide support for preventing cache pollution. It’s important to benchmark the performance of the system when configuring the data cache to find the best method for a specific application.
The serial Flash should be laid out on the pc board so that no trace is longer than 120 millimeters (mm). To avoid interference, the SPI clock signal path should be at least three times the width of the pc board traces away from other signals. The two bidirectional data signals should all be within 10 mm of each other to avoid skew.
An external SPI Flash device can be an efficient solution for implementing large data lookup tables in an IoT endpoint. It is easy to reprogram in-system, easy to upgrade, and uses minimal microcontroller resources.