DeterministicESPAsyncWebServer v6.28.0
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
ldc1614.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file ldc1614.h
6 * @brief TI LDC1614 inductance-to-digital field-sensing codec (DETWS_ENABLE_LDC1614).
7 *
8 * The LDC1614 measures the resonant frequency of an external LC tank driven by a coil; a nearby
9 * conductor changes the coil's effective inductance (eddy currents), moving that frequency - so the
10 * 28-bit conversion result tracks metal proximity, displacement, and EM-field perturbation without
11 * contact. It shares TI's FDC/LDC register architecture: each channel's result is a DATA MSB register
12 * (top 4 bits error flags, low 12 bits data MSB) plus a DATA LSB register, combining into 28 bits, with
13 * `f_sensor = data / 2^28 * f_ref` and `L = 1 / (C * (2*pi*f)^2)` derived by the app from the tank C.
14 *
15 * This codec is pure and host-tested: ::ldc1614_data combines the register pair, ::ldc1614_error pulls
16 * the flags, ::ldc1614_sensor_freq_hz scales to frequency, and ::ldc1614_build_config emits a
17 * single-channel bring-up. On an ESP32 the binding replays that config and reads the channel over I2C;
18 * only that touches hardware. Bridge the readings northbound like any sensor.
19 */
20
21#ifndef DETERMINISTICESPASYNCWEBSERVER_LDC1614_H
22#define DETERMINISTICESPASYNCWEBSERVER_LDC1614_H
23
24#include <stddef.h>
25#include <stdint.h>
26
27// Register map (channel 0).
28#define LDC1614_REG_DATA_CH0_MSB 0x00
29#define LDC1614_REG_DATA_CH0_LSB 0x01
30#define LDC1614_REG_RCOUNT_CH0 0x08
31#define LDC1614_REG_SETTLECOUNT_CH0 0x10
32#define LDC1614_REG_CLOCK_DIVIDERS_CH0 0x14
33#define LDC1614_REG_STATUS 0x18
34#define LDC1614_REG_ERROR_CONFIG 0x19
35#define LDC1614_REG_CONFIG 0x1A
36#define LDC1614_REG_MUX_CONFIG 0x1B
37#define LDC1614_REG_DRIVE_CURRENT_CH0 0x1E
38#define LDC1614_REG_MANUFACTURER_ID 0x7E
39#define LDC1614_REG_DEVICE_ID 0x7F
40
41#define LDC1614_MANUFACTURER_ID 0x5449 ///< "TI".
42#define LDC1614_DEVICE_ID 0x3055 ///< LDC1614 / LDC1612.
43
44/** @brief Largest config sequence in bytes: 7 register writes * 3 bytes (reg, msb, lsb). */
45#define LDC1614_CONFIG_MAX 21
46
47/** @brief Combine a DATA MSB register (low 12 bits) and DATA LSB register into the 28-bit result. */
48uint32_t ldc1614_data(uint16_t msb_reg, uint16_t lsb_reg);
49
50/** @brief The 4 error flags from the top of a DATA MSB register (bits 15:12). */
51uint8_t ldc1614_error(uint16_t msb_reg);
52
53/** @brief Sensor frequency in Hz for a 28-bit result against a reference clock: data / 2^28 * fref. */
54uint64_t ldc1614_sensor_freq_hz(uint32_t data28, uint32_t fref_hz);
55
56/**
57 * @brief Emit a single-channel (CH0) continuous-conversion bring-up as `(reg, val_msb, val_lsb)` triples.
58 *
59 * Writes RCOUNT, SETTLECOUNT, CLOCK_DIVIDERS, DRIVE_CURRENT, ERROR_CONFIG, MUX_CONFIG, then CONFIG last
60 * (CONFIG starts the conversion). Replay each triple as a 16-bit I2C register write.
61 * @return bytes written (7 * 3 = 21), or 0 if @p cap < LDC1614_CONFIG_MAX.
62 */
63size_t ldc1614_build_config(uint8_t *buf, size_t cap, uint16_t rcount, uint16_t settlecount);
64
65// --- ESP32 binding (I2C via Wire; no-ops on a host build) ------------------------------------
66
67/** @brief Verify the device id and apply the CH0 config at @p addr. @return true if present + acked. */
68bool ldc1614_begin(uint8_t addr, uint16_t rcount, uint16_t settlecount);
69
70/** @brief Read channel 0's 28-bit conversion result into @p out. @return false on I2C error. */
71bool ldc1614_read_ch0(uint32_t *out);
72
73#endif // DETERMINISTICESPASYNCWEBSERVER_LDC1614_H
size_t ldc1614_build_config(uint8_t *buf, size_t cap, uint16_t rcount, uint16_t settlecount)
Emit a single-channel (CH0) continuous-conversion bring-up as (reg, val_msb, val_lsb) triples.
uint64_t ldc1614_sensor_freq_hz(uint32_t data28, uint32_t fref_hz)
Sensor frequency in Hz for a 28-bit result against a reference clock: data / 2^28 * fref.
bool ldc1614_begin(uint8_t addr, uint16_t rcount, uint16_t settlecount)
Verify the device id and apply the CH0 config at addr.
bool ldc1614_read_ch0(uint32_t *out)
Read channel 0's 28-bit conversion result into out.
uint8_t ldc1614_error(uint16_t msb_reg)
The 4 error flags from the top of a DATA MSB register (bits 15:12).
uint32_t ldc1614_data(uint16_t msb_reg, uint16_t lsb_reg)
Combine a DATA MSB register (low 12 bits) and DATA LSB register into the 28-bit result.