DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
mpr121.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 mpr121.h
6 * @brief NXP MPR121 12-channel capacitive-touch controller codec (DETWS_ENABLE_MPR121).
7 *
8 * The MPR121 reports a 16-bit touch-status word (registers 0x00/0x01): bits 0-11 are the twelve
9 * electrodes, bit 12 is the proximity electrode, and bit 15 is the over-current flag. It also
10 * exposes 10-bit filtered capacitance and 8-bit baseline per electrode. Bringing it up is a
11 * fixed sequence of register writes (soft reset, the NXP filter/AFE defaults, per-electrode
12 * touch/release thresholds, and the electrode-configuration register that starts it running).
13 *
14 * This codec is pure and host-tested: ::mpr121_touched / ::mpr121_word10 decode the reported
15 * words, and ::mpr121_build_init emits the whole bring-up sequence as `(register, value)` byte
16 * pairs (so the exact bytes are verifiable off-target). On an ESP32 the binding replays that
17 * sequence over I2C (Wire) and reads the status; only that touches hardware.
18 *
19 * A cheap solder-and-bench-test breakout for touch buttons / sliders: wire it up, touch a pad,
20 * watch the bit set.
21 *
22 * @author Douglas Quigg (dstroy0)
23 * @date 2026
24 */
25
26#ifndef DETERMINISTICESPASYNCWEBSERVER_MPR121_H
27#define DETERMINISTICESPASYNCWEBSERVER_MPR121_H
28
29#include <stddef.h>
30#include <stdint.h>
31
32/** @brief Sense electrodes on the MPR121 (ELE0..ELE11). */
33#define MPR121_ELECTRODES 12
34
35/** @brief Largest init sequence in bytes: (17 fixed + 2*12 threshold) pairs * 2 bytes. */
36#define MPR121_INIT_MAX 82
37
38/**
39 * @brief Decode the 12-electrode touch bitmask from the two status registers (0x00 low, 0x01
40 * high). Bit i (0..11) is set when electrode i is touched; proximity (bit 12) and the
41 * over-current flag are masked out (see ::mpr121_proximity / ::mpr121_overcurrent).
42 */
43uint16_t mpr121_touched(uint8_t status_lo, uint8_t status_hi);
44
45/** @brief True if electrode @p e (0..11) is touched in a mask from ::mpr121_touched. */
46bool mpr121_is_touched(uint16_t mask, uint8_t e);
47
48/** @brief True if the proximity electrode (status bit 12) is active. */
49bool mpr121_proximity(uint8_t status_hi);
50
51/** @brief True if the over-current flag (status bit 15) is set (wiring fault / short). */
52bool mpr121_overcurrent(uint8_t status_hi);
53
54/** @brief Combine a little-endian LSB/MSB register pair into a 10-bit value (filtered/baseline). */
55uint16_t mpr121_word10(uint8_t lsb, uint8_t msb);
56
57/**
58 * @brief Build the MPR121 bring-up sequence as consecutive `(register, value)` byte pairs.
59 *
60 * Emits: soft reset, ECR stop, the NXP rising/falling/touched filter defaults, per-electrode
61 * touch/release thresholds for @p n_electrodes, debounce, CONFIG1/CONFIG2, and finally the ECR
62 * that enables @p n_electrodes with baseline tracking. Replay each pair as an I2C register
63 * write, in order (the ECR-start pair must be written last).
64 * @return the number of bytes written (pairs * 2), or 0 if @p cap is too small / args invalid.
65 */
66size_t mpr121_build_init(uint8_t *buf, size_t cap, uint8_t n_electrodes, uint8_t touch_thr, uint8_t release_thr);
67
68// --- ESP32 binding (I2C via Wire; no-ops on a host build) ------------------------------------
69
70/** @brief Reset + configure the MPR121 at @p addr over I2C. @return true if it acknowledged. */
71bool mpr121_begin(uint8_t addr);
72
73/** @brief Read the current 12-electrode touch bitmask (0 if the device is absent). */
75
76/** @brief Read electrode @p e's 10-bit filtered capacitance value. */
77uint16_t mpr121_read_filtered(uint8_t e);
78
79#endif // DETERMINISTICESPASYNCWEBSERVER_MPR121_H
bool mpr121_overcurrent(uint8_t status_hi)
True if the over-current flag (status bit 15) is set (wiring fault / short).
uint16_t mpr121_read_filtered(uint8_t e)
Read electrode e's 10-bit filtered capacitance value.
uint16_t mpr121_read_touched()
Read the current 12-electrode touch bitmask (0 if the device is absent).
size_t mpr121_build_init(uint8_t *buf, size_t cap, uint8_t n_electrodes, uint8_t touch_thr, uint8_t release_thr)
Build the MPR121 bring-up sequence as consecutive (register, value) byte pairs.
bool mpr121_begin(uint8_t addr)
Reset + configure the MPR121 at addr over I2C.
bool mpr121_proximity(uint8_t status_hi)
True if the proximity electrode (status bit 12) is active.
bool mpr121_is_touched(uint16_t mask, uint8_t e)
True if electrode e (0..11) is touched in a mask from mpr121_touched.
uint16_t mpr121_word10(uint8_t lsb, uint8_t msb)
Combine a little-endian LSB/MSB register pair into a 10-bit value (filtered/baseline).
uint16_t mpr121_touched(uint8_t status_lo, uint8_t status_hi)
Decode the 12-electrode touch bitmask from the two status registers (0x00 low, 0x01 high)....