All parts / LIS3DH
LIS3DH register map
3-axis MEMS accelerometer with FIFO, click and 4D detection — STMicroelectronics
40 registers
I2C, SPI
I²C 0x18, 0x19
8-bit reg addresses
80% bit coverage
not yet human-verified
Get it as a C header
pip install regforge
regforge gen LIS3DH --out ./src --driver --tests
Writes lis3dh_regs.h with every address, mask and shift below, a bus-agnostic driver skeleton, and a file of compile-time assertions that make your compiler check the bit arithmetic. No API key needed — this part ships inside the package.
Not yet human-verified. Transcribed and mechanically validated — no overlapping fields, no out-of-range bits, reset values consistent with their fields — but not yet checked line-by-line against the datasheet.
Verifying it is a useful half hour.
Registers
| Addr | Register | Access | Width | Reset | Description |
| 0x07 | STATUS_REG_AUX | RO | 8 | — | ADC data-ready and overrun flags |
| 0x08 | OUT_ADC1_L | RO | 8 | — | ADC channel 1, low byte |
| 0x09 | OUT_ADC1_H | RO | 8 | — | ADC channel 1, high byte |
| 0x0A | OUT_ADC2_L | RO | 8 | — | ADC channel 2, low byte |
| 0x0B | OUT_ADC2_H | RO | 8 | — | ADC channel 2, high byte |
| 0x0C | OUT_ADC3_L | RO | 8 | — | ADC channel 3, low byte |
| 0x0D | OUT_ADC3_H | RO | 8 | — | ADC channel 3, high byte |
| 0x0F | WHO_AM_I | RO | 8 | 0x33 | Device identification. Always reads 0x33. |
| 0x1E | CTRL_REG0 | RW | 8 | 0x10 | SDO/SA0 pull-up control. The reserved bits must be written as 0b0010000. |
| 0x1F | TEMP_CFG_REG | RW | 8 | 0x00 | Temperature sensor and ADC enable |
| 0x20 | CTRL_REG1 | RW | 8 | 0x07 | Output data rate, low-power mode and axis enables. Note the reset value: all three axes are enabled but ODR is power-down, so the part produces nothing until you set a rate. |
| 0x21 | CTRL_REG2 | RW | 8 | 0x00 | High-pass filter configuration |
| 0x22 | CTRL_REG3 | RW | 8 | 0x00 | INT1 pin routing |
| 0x23 | CTRL_REG4 | RW | 8 | 0x00 | Scale, resolution and SPI mode |
| 0x24 | CTRL_REG5 | RW | 8 | 0x00 | Memory reboot, FIFO and interrupt latching |
| 0x25 | CTRL_REG6 | RW | 8 | 0x00 | INT2 pin routing and interrupt polarity |
| 0x26 | REFERENCE | RW | 8 | 0x00 | Reference value for interrupt generation |
| 0x27 | STATUS_REG | RO | 8 | 0x00 | Acceleration data status |
| 0x28 | OUT_X_L | RO | 8 | — | X-axis acceleration, low byte |
| 0x29 | OUT_X_H | RO | 8 | — | X-axis acceleration, high byte |
| 0x2A | OUT_Y_L | RO | 8 | — | Y-axis acceleration, low byte |
| 0x2B | OUT_Y_H | RO | 8 | — | Y-axis acceleration, high byte |
| 0x2C | OUT_Z_L | RO | 8 | — | Z-axis acceleration, low byte |
| 0x2D | OUT_Z_H | RO | 8 | — | Z-axis acceleration, high byte |
| 0x2E | FIFO_CTRL_REG | RW | 8 | 0x00 | FIFO mode and threshold |
| 0x2F | FIFO_SRC_REG | RO | 8 | — | FIFO status |
| 0x30 | INT1_CFG | RW | 8 | 0x00 | Interrupt 1 configuration |
| 0x31 | INT1_SRC | RO | 8 | 0x00 | Interrupt 1 source. Cleared on read. |
| 0x32 | INT1_THS | RW | 8 | 0x00 | Interrupt 1 threshold |
| 0x33 | INT1_DURATION | RW | 8 | 0x00 | Interrupt 1 duration |
| 0x34 | INT2_CFG | RW | 8 | 0x00 | Interrupt 2 configuration |
| 0x35 | INT2_SRC | RO | 8 | 0x00 | Interrupt 2 source. Cleared on read. |
| 0x36 | INT2_THS | RW | 8 | 0x00 | Interrupt 2 threshold |
| 0x37 | INT2_DURATION | RW | 8 | 0x00 | Interrupt 2 duration |
| 0x38 | CLICK_CFG | RW | 8 | 0x00 | Click detection configuration |
| 0x39 | CLICK_SRC | RO | 8 | 0x00 | Click detection source |
| 0x3A | CLICK_THS | RW | 8 | 0x00 | Click threshold |
| 0x3B | TIME_LIMIT | RW | 8 | 0x00 | Click time limit |
| 0x3C | TIME_LATENCY | RW | 8 | 0x00 | Click time latency |
| 0x3D | TIME_WINDOW | RW | 8 | 0x00 | Click time window |
Bit layouts
Drawn MSB-first, the way the datasheet draws them. [7:5] means shift 5, width 3, mask 0xE0 — this is the notation that costs people a day when they read it backwards.
CTRL_REG0 @ 0x1E — 1 fields
SDO_PU_DISC[7]
—6
—5
—4
—3
—2
—1
—0
| Bits | Field | Access | Mask | Reset | Description |
| [7] | SDO_PU_DISC | RW | 0x80 | 0x00 | 1 disconnects the SDO/SA0 pull-up |
TEMP_CFG_REG @ 0x1F — 2 fields
ADC_EN[7]
TEMP_EN[6]
—5
—4
—3
—2
—1
—0
| Bits | Field | Access | Mask | Reset | Description |
| [7] | ADC_EN | RW | 0x80 | 0x00 | Enable the auxiliary ADC |
| [6] | TEMP_EN | RW | 0x40 | 0x00 | Enable the temperature sensor |
CTRL_REG1 @ 0x20 — 5 fields
ODR[7:4]
LPEN[3]
ZEN[2]
YEN[1]
XEN[0]
| Bits | Field | Access | Mask | Reset | Description |
| [7:4] | ODR | RW | 0xF0 | 0x00 | Output data rate |
| [3] | LPEN | RW | 0x08 | 0x00 | Low-power mode enable (8-bit data) |
| [2] | ZEN | RW | 0x04 | 0x01 | Z-axis enable |
| [1] | YEN | RW | 0x02 | 0x01 | Y-axis enable |
| [0] | XEN | RW | 0x01 | 0x01 | X-axis enable |
CTRL_REG1.ODR values
| Value | Name | Meaning |
| 0x00 | POWER_DOWN | Power down (default) |
| 0x01 | HZ_1 | 1 Hz |
| 0x02 | HZ_10 | 10 Hz |
| 0x03 | HZ_25 | 25 Hz |
| 0x04 | HZ_50 | 50 Hz |
| 0x05 | HZ_100 | 100 Hz |
| 0x06 | HZ_200 | 200 Hz |
| 0x07 | HZ_400 | 400 Hz |
| 0x08 | LP_1620 | 1.62 kHz, low-power mode only |
| 0x09 | HZ_5376 | 5.376 kHz low-power / 1.344 kHz normal |
CTRL_REG2 @ 0x21 — 6 fields
HPM[7:6]
HPCF[5:4]
FDS[3]
HPCLICK[2]
HP_IA2[1]
HP_IA1[0]
| Bits | Field | Access | Mask | Reset | Description |
| [7:6] | HPM | RW | 0xC0 | 0x00 | High-pass filter mode |
| [5:4] | HPCF | RW | 0x30 | 0x00 | High-pass filter cutoff frequency |
| [3] | FDS | RW | 0x08 | 0x00 | Filtered data selection |
| [2] | HPCLICK | RW | 0x04 | 0x00 | High-pass filter enabled for click |
| [1] | HP_IA2 | RW | 0x02 | 0x00 | High-pass filter enabled for interrupt 2 |
| [0] | HP_IA1 | RW | 0x01 | 0x00 | High-pass filter enabled for interrupt 1 |
CTRL_REG3 @ 0x22 — 7 fields
I1_CLICK[7]
I1_IA1[6]
I1_IA2[5]
I1_ZYXDA[4]
I1_321DA[3]
I1_WTM[2]
I1_OVERRUN[1]
—0
| Bits | Field | Access | Mask | Reset | Description |
| [7] | I1_CLICK | RW | 0x80 | 0x00 | Click interrupt on INT1 |
| [6] | I1_IA1 | RW | 0x40 | 0x00 | IA1 interrupt on INT1 |
| [5] | I1_IA2 | RW | 0x20 | 0x00 | IA2 interrupt on INT1 |
| [4] | I1_ZYXDA | RW | 0x10 | 0x00 | Data ready on INT1 |
| [3] | I1_321DA | RW | 0x08 | 0x00 | ADC data ready on INT1 |
| [2] | I1_WTM | RW | 0x04 | 0x00 | FIFO watermark on INT1 |
| [1] | I1_OVERRUN | RW | 0x02 | 0x00 | FIFO overrun on INT1 |
CTRL_REG4 @ 0x23 — 6 fields
BDU[7]
BLE[6]
FS[5:4]
HR[3]
ST[2:1]
SIM[0]
| Bits | Field | Access | Mask | Reset | Description |
| [7] | BDU | RW | 0x80 | 0x00 | Block data update. Set it, or the high and low bytes of a sample can come from different measurements. |
| [6] | BLE | RW | 0x40 | 0x00 | Big/little endian selection |
| [5:4] | FS | RW | 0x30 | 0x00 | Full-scale selection |
| [3] | HR | RW | 0x08 | 0x00 | High-resolution output mode (12-bit) |
| [2:1] | ST | RW | 0x06 | 0x00 | Self-test enable |
| [0] | SIM | RW | 0x01 | 0x00 | SPI serial interface mode. 1 = 3-wire. |
CTRL_REG4.FS values
| Value | Name | Meaning |
| 0x00 | G_2 | +/-2 g (default) |
| 0x01 | G_4 | +/-4 g |
| 0x02 | G_8 | +/-8 g |
| 0x03 | G_16 | +/-16 g |
CTRL_REG5 @ 0x24 — 6 fields
BOOT[7]
FIFO_EN[6]
—5
—4
LIR_INT1[3]
D4D_INT1[2]
LIR_INT2[1]
D4D_INT2[0]
| Bits | Field | Access | Mask | Reset | Description |
| [7] | BOOT | W1P | 0x80 | 0x00 | Reboot memory content; self-clearing |
| [6] | FIFO_EN | RW | 0x40 | 0x00 | FIFO enable |
| [3] | LIR_INT1 | RW | 0x08 | 0x00 | Latch interrupt request on INT1 |
| [2] | D4D_INT1 | RW | 0x04 | 0x00 | 4D detection enabled on INT1 |
| [1] | LIR_INT2 | RW | 0x02 | 0x00 | Latch interrupt request on INT2 |
| [0] | D4D_INT2 | RW | 0x01 | 0x00 | 4D detection enabled on INT2 |
CTRL_REG6 @ 0x25 — 6 fields
I2_CLICK[7]
I2_IA1[6]
I2_IA2[5]
I2_BOOT[4]
I2_ACT[3]
—2
INT_POLARITY[1]
—0
| Bits | Field | Access | Mask | Reset | Description |
| [7] | I2_CLICK | RW | 0x80 | 0x00 | Click interrupt on INT2 |
| [6] | I2_IA1 | RW | 0x40 | 0x00 | IA1 interrupt on INT2 |
| [5] | I2_IA2 | RW | 0x20 | 0x00 | IA2 interrupt on INT2 |
| [4] | I2_BOOT | RW | 0x10 | 0x00 | Boot status on INT2 |
| [3] | I2_ACT | RW | 0x08 | 0x00 | Activity interrupt on INT2 |
| [1] | INT_POLARITY | RW | 0x02 | 0x00 | 0 = active high, 1 = active low |
STATUS_REG @ 0x27 — 8 fields
ZYXOR[7]
ZOR[6]
YOR[5]
XOR_[4]
ZYXDA[3]
ZDA[2]
YDA[1]
XDA[0]
| Bits | Field | Access | Mask | Reset | Description |
| [7] | ZYXOR | RO | 0x80 | 0x00 | X, Y and Z data overrun |
| [6] | ZOR | RO | 0x40 | 0x00 | Z data overrun |
| [5] | YOR | RO | 0x20 | 0x00 | Y data overrun |
| [4] | XOR_ | RO | 0x10 | 0x00 | X data overrun |
| [3] | ZYXDA | RO | 0x08 | 0x00 | X, Y and Z new data available |
| [2] | ZDA | RO | 0x04 | 0x00 | Z new data available |
| [1] | YDA | RO | 0x02 | 0x00 | Y new data available |
| [0] | XDA | RO | 0x01 | 0x00 | X new data available |
FIFO_CTRL_REG @ 0x2E — 3 fields
| Bits | Field | Access | Mask | Reset | Description |
| [7:6] | FM | RW | 0xC0 | 0x00 | FIFO mode |
| [5] | TR | RW | 0x20 | 0x00 | Trigger selection. 0 = INT1, 1 = INT2. |
| [4:0] | FTH | RW | 0x1F | 0x00 | FIFO threshold |
FIFO_CTRL_REG.FM values
| Value | Name | Meaning |
| 0x00 | BYPASS | Bypass mode (default) |
| 0x01 | FIFO | FIFO mode |
| 0x02 | STREAM | Stream mode |
| 0x03 | STREAM_TO_FIFO | Stream-to-FIFO mode |
FIFO_SRC_REG @ 0x2F — 4 fields
WTM[7]
OVRN_FIFO[6]
EMPTY[5]
FSS[4:0]
| Bits | Field | Access | Mask | Reset | Description |
| [7] | WTM | RO | 0x80 | — | Watermark level reached |
| [6] | OVRN_FIFO | RO | 0x40 | — | FIFO overrun |
| [5] | EMPTY | RO | 0x20 | — | FIFO is empty |
| [4:0] | FSS | RO | 0x1F | — | Number of unread samples |
Generated C header
What regforge gen LIS3DH writes for STATUS_REG:
/* ------------------------------------------------------------------------ */
/* STATUS_REG @ 0x27u ro 8-bit reset 0x00u */
/* Acceleration data status */
/* ------------------------------------------------------------------------ */
#define LIS3DH_STATUS_REG 0x27u
#define LIS3DH_STATUS_REG_WIDTH 8u
#define LIS3DH_STATUS_REG_RESET 0x00u
/* ZYXOR bits [7] ro reset 0x00u -- X, Y and Z data overrun */
#define LIS3DH_STATUS_REG_ZYXOR_SHIFT 7u
#define LIS3DH_STATUS_REG_ZYXOR_WIDTH 1u
#define LIS3DH_STATUS_REG_ZYXOR_MASK 0x80u
#define LIS3DH_STATUS_REG_ZYXOR_GET(reg) (((uint8_t)(reg) & 0x80u) >> 7u)
#define LIS3DH_STATUS_REG_ZYXOR_SET(reg, val) (((uint8_t)(reg) & (uint8_t)~0x80u) | (((uint8_t)(val) << 7u) & 0x80u))
/* ZOR bits [6] ro reset 0x00u -- Z data overrun */
#define LIS3DH_STATUS_REG_ZOR_SHIFT 6u
#define LIS3DH_STATUS_REG_ZOR_WIDTH 1u
#define LIS3DH_STATUS_REG_ZOR_MASK 0x40u
#define LIS3DH_STATUS_REG_ZOR_GET(reg) (((uint8_t)(reg) & 0x40u) >> 6u)
#define LIS3DH_STATUS_REG_ZOR_SET(reg, val) (((uint8_t)(reg) & (uint8_t)~0x40u) | (((uint8_t)(val) << 6u) & 0x40u))
/* YOR bits [5] ro reset 0x00u -- Y data overrun */
#define LIS3DH_STATUS_REG_YOR_SHIFT 5u
#define LIS3DH_STATUS_REG_YOR_WIDTH 1u
#define LIS3DH_STATUS_REG_YOR_MASK 0x20u
#define LIS3DH_STATUS_REG_YOR_GET(reg) (((uint8_t)(reg) & 0x20u) >> 5u)
#define LIS3DH_STATUS_REG_YOR_SET(reg, val) (((uint8_t)(reg) & (uint8_t)~0x20u) | (((uint8_t)(val) << 5u) & 0x20u))
/* XOR_ bits [4] ro reset 0x00u -- X data overrun */
#define LIS3DH_STATUS_REG_XOR_SHIFT 4u
#define LIS3DH_STATUS_REG_XOR_WIDTH 1u
#define LIS3DH_STATUS_REG_XOR_MASK 0x10u
#define LIS3DH_STATUS_REG_XOR_GET(reg) (((uint8_t)(reg) & 0x10u) >> 4u)
#define LIS3DH_STATUS_REG_XOR_SET(reg, val) (((uint8_t)(reg) & (uint8_t)~0x10u) | (((uint8_t)(val) << 4u) & 0x10u))
/* ZYXDA bits [3] ro reset 0x00u -- X, Y and Z new data available */
#define LIS3DH_STATUS_REG_ZYXDA_SHIFT 3u
#define LIS3DH_STATUS_REG_ZYXDA_WIDTH 1u
#define LIS3DH_STATUS_REG_ZYXDA_MASK 0x08u
#define LIS3DH_STATUS_REG_ZYXDA_GET(reg) (((uint8_t)(reg) & 0x08u) >> 3u)
#define LIS3DH_STATUS_REG_ZYXDA_SET(reg, val) (((uint8_t)(reg) & (uint8_t)~0x08u) | (((uint8_t)(val) << 3u) & 0x08u))
Compared with
Related parts
Source
Transcribed from ST LIS3DH datasheet (hand-transcribed) (hand-transcribed). Hand-authored seed entry, not machine-extracted. Multi-byte reads require the MSB of the sub-address to be set for auto-increment; that is a bus-protocol detail rather than a register and is not modelled here. Check against the datasheet before trusting it, then mark it verified.
Raw JSON · Report an error