# STMems Standard C drivers: platform-independent sensor code in plain C

> This repository holds STMicroelectronics' low-level C drivers for MEMS, environmental, infrared and biosensors, each with example integration code and STM32CubeMX demo projects. It suits an embedded developer who wants the sensor protocol handled without pulling in a vendor HAL.

**STMicroelectronics/STMems_Standard_C_drivers** — Platform-independent drivers for STMicroelectronics MEMS motion sensors, environmental sensors, infrared sensors and biosensors, based on standard C programming language.

- Repository: https://github.com/STMicroelectronics/STMems_Standard_C_drivers
- Stars: 886 · Forks: 538
- Language: C
- License: BSD-3-Clause
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/stmicroelectronics-stmems-standard-c-drivers

## Low-level drivers, and how they differ from the Cube ones

The repository describes itself as containing examples of low-level platform-independent drivers for STMicroelectronics sensors, with the sensor drivers and examples written in C. The distinction the documentation draws is between the two families of ST driver repositories, and it follows a naming convention. A repository named after the part number alone, with the hts221 repository given as the example, holds the low-level platform-independent driver, while one named with an stm32 prefix in front, such as stm32-hts221, holds the hardware-abstracted STM32Cube-compatible driver. The readme also tells you what to do if you are using STM32Cube packages, which is to evaluate the hardware abstraction drivers as well. So the choice is not a preference, it is a question of whether you want the whole vendor stack or just the part that speaks the sensor. The drivers here are the former choice: the sensor protocol, with the transport left to you.

## How the repository is laid out, and why the clone needs a flag

The folder structure is regular enough to navigate without reading any documentation. A folder whose name ends in _STdC, where the prefix identifies the sensor part number, contains the sensor driver, and a folder named _prj_XXXXXXX contains the demo project, where the name is the ST evaluation board. A third folder named _resources cannot be identified by either convention and holds other useful things such as libraries and predefined device configurations used in some examples. That folder is a git submodule, which is why the clone command in the readme uses the recursive flag, so that you get the submodules in one step:

```git
git clone --recursive https://github.com/STMicroelectronics/STMems_Standard_C_drivers
```

Inside a sensor driver folder there is a driver subfolder, which points at another repository containing the driver files, the .h and .c files, either to be included or linked directly as a git submodule, an examples subfolder showing how to integrate the driver into a project, and a README with information specific to that driver. The driver documentation can be generated with Doxygen, which is a small thing that saves time when you inherit a project with a dozen of these drivers in it. The top level of the repository shows the shape of the collection, with around sixty sensor folders spanning the accelerometer, gyroscope, magnetometer, pressure, humidity, temperature, microphone, image sensor, time of flight and biometric parts.

## Three functions is the whole integration

The integration contract is the part of the documentation that will save you the most time, and it is short. The driver is platform-independent, so you only need to define the two functions for read and write transactions from the sensor hardware bus, that is SPI or I2C or I3C, plus a platform dependent delay function which is sometimes required by the underlying driver. The signatures are given explicitly, and the return value convention on the first of them is the kind of detail that causes silent bugs if you miss it:

```c
int32_t platform_write(void *handle, uint8_t Reg, const uint8_t *Bufp, uint16_t len);
int32_t platform_read(void *handle, uint8_t Reg, uint8_t *Bufp, uint16_t len);
void platform_delay(uint32_t ms);
```

The return value convention is inverted relative to what most C APIs do, since zero means no error, and the documentation marks it as mandatory. The device interface struct then takes those three function pointers, and the driver holds them for its own use. The handle parameter is optional and only needs initialising if your platform functions require it, and any further platform setup belongs in a platform_init routine that the driver calls. The note about a few devices integrating an extra bit in the communication protocol to enable multi read and write access is the part to read before you write your bus functions, because that bit has to be managed inside the read and write functions you define, and the reference examples show how.

## The demo projects are CubeMX configurations, not build systems

The demo project folders each contain a single configuration file for the STM32CubeMX tool, named with the board identifier and an .ioc extension, and the workflow is to open that file with CubeMX configured with the related microcontroller package, generate the project, and then add the driver files and the example source file from the matching sensor driver folder. The documentation is clear that the examples are written for STM32 microcontrollers using CubeMX but can be used as a guideline for every platform, which is the whole point of a platform-independent driver. There are four board configurations in the repository, for the MKI109V3, the Nucleo F401RE, the Nucleo H503RB and the STEVAL MKI109D, and the readme maps them to the microcontroller packages you need, with STM32F4 for the NucleoF401 and the MKI109V3 and STM32H5 for the NucleoH503 and the MKI109D. When you are on a supported evaluation board, the example file runs without modification, and the only change needed is uncommenting the board definition in the section marked for STMicroelectronics evaluation boards and calling the example function from the main loop in the generated main.c. The rest of the steps are the usual toolchain selection, so the CubeMX file is the only unusual artefact.

## What the drivers cover, and the release history

The sensor list spans the MEMS range rather than one family, and the top level directory shows the shape of it. The accelerometer and gyroscope parts include the a3g4250d and i3g4250d gyroscopes, the asm330 series in its lh, lhh, lhhg1 and lhhx variants, the fxls8961, fxls8964, fxls8967, fxls8971 and fxls8974 accelerometer and magnetometer combos, the fxps7115, fxps7165, fxps7250 and fxps7400 pressure sensors in their a and d variants, and the fxps7550 pressure and temperature part. The magnetic parts cover the ais25ba, ais2dw12, ais2ih and ais3624dq magnetometers, the ism303dac, ism330bx, ism330dhcx, ism330dlc, ism330is and ism6hg256x inertial measurement units, the iis2dh, iis2dlpc, iis2dulpx, iis2iclx, iis2mdc and iis328dq accelerometers, the iis3dhhc and iis3dwb variants, the h3lis100dl and h3lis331dl magnetometers, the l3gd20h gyroscope, the ilps22qs and ilps28qsw pressure sensors and the hts221 humidity and temperature sensor. The release history is old and short, with v2.00 from 2021-05-31 adding const to a pointer parameter in the write function, v1.04 from 2021-03-05 adding big and little endianness management, and v1.03 from 2020-10-02 adding new devices. The last push was on 2026-10-09, so the code is being touched without a new tag.

## Conclusion

The STMems Standard C drivers are a good fit for an embedded developer who wants the sensor register map, calibration and conversion logic without a vendor-specific hardware abstraction, and who is willing to write three small platform functions. It is the wrong tool if you are on STM32Cube and want the whole stack from one vendor, because the documentation itself points you at the STM32Cube-compatible drivers in that case, and it is the wrong tool if you want something above the register level, since these are explicitly low-level drivers. It is also the wrong tool if you need a maintained release cadence to plan around, because the newest tagged release here is v2.00 from 2021 while the last push is more recent. Before using one of these drivers, read the integration section, because the multi read and write bit on some devices has to be handled inside your own read and write functions, and the return value convention for the write function is mandatory rather than advisory. The licence is BSD-3-Clause, the last push was on 2026-10-09, and the repository publishes no GitHub releases beyond the tags.

## FAQ

### What is the STMems Standard C drivers repository?

It contains low-level platform-independent drivers for STMicroelectronics MEMS, environmental, infrared and biosensors, written in C, along with example integration code and STM32CubeMX demo projects. The documentation points you at the STM32Cube-compatible hardware abstraction drivers as well if you are using STM32Cube packages.

### How do I integrate one of these sensor drivers?

You define three functions, a platform_write, a platform_read and a platform_delay for the SPI, I2C or I3C bus, and assign them into the device context struct alongside an optional handle. The write function must return 0 for no error, and a few devices need an extra protocol bit for multi read and write access managed inside your own functions.

### What is the difference between this repository and the STM32Cube-compatible drivers?

The naming convention marks the difference. A repository named after the part number alone, such as hts221, holds the low-level platform-independent driver, while one with an stm32 prefix, such as stm32-hts221, holds the hardware-abstracted STM32Cube-compatible driver. The readme suggests evaluating the Cube drivers as well if you use STM32Cube packages.

### How are the demo projects used?

Each demo project folder holds a single STM32CubeMX .ioc configuration file for the evaluation board. You open it in CubeMX with the matching MCU package, generate the project, add the driver files and the example source from the sensor driver folder, uncomment the board definition in the example, and call the example function from the generated main function.

### Why does cloning the STMems Standard C drivers repository need a recursive flag?

Because the _resources folder is a git submodule holding libraries and predefined device configurations used in some examples. The documented command is git clone --recursive against the repository URL, and each sensor driver folder points at another repository for the driver .h and .c files, also as a submodule.

## Sources

- [Issues](https://github.com/STMicroelectronics/STMems_Standard_C_drivers/issues)
- [License: BSD-3-Clause](https://github.com/STMicroelectronics/STMems_Standard_C_drivers/blob/master/LICENSE)
- [README](https://github.com/STMicroelectronics/STMems_Standard_C_drivers/blob/master/README.md)
- [Releases](https://github.com/STMicroelectronics/STMems_Standard_C_drivers/releases)
- [STMicroelectronics/STMems_Standard_C_drivers on GitHub](https://github.com/STMicroelectronics/STMems_Standard_C_drivers)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/stmicroelectronics-stmems-standard-c-drivers
