Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 17 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,12 @@ git clone --recurse-submodules --jobs 8 https://github.com/modm-io/modm.git

## Microcontrollers

modm can create a HAL for <!--allcount-->4003<!--/allcount--> devices of these vendors:
modm can create a HAL for <!--allcount-->3991<!--/allcount--> devices of these vendors:

- STMicroelectronics STM32: <!--stmcount-->3240<!--/stmcount--> devices.
- Microchip SAM: <!--samcount-->355<!--/samcount--> devices.
- Microchip AVR: <!--avrcount-->388<!--/avrcount--> devices.
- Nordic nRF: <!--nrfcount-->19<!--/nrfcount--> devices.
- Nordic nRF: <!--nrfcount-->7<!--/nrfcount--> devices.
- Raspberry Pi: <!--rpicount-->1<!--/rpicount--> device.

Here is a table with all device families and the peripheral drivers they support:
Expand Down Expand Up @@ -957,99 +957,100 @@ your specific needs.
<td align="center"><a href="https://modm.io/reference/module/modm-driver-block-device-spi-flash">SPI Flash</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-bme280">BME280</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-bmi088">BMI088</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-bmp085">BMP085</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-bmi270">BMI270</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-bmp085">BMP085</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-bmp581">BMP581</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-bno055">BNO055</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-cat24aa">CAT24AA</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-cycle_counter">CYCLE-COUNTER</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-drv832x_spi">DRV832X</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ds1302">DS1302</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ds1302">DS1302</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ds1631">DS1631</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ds18b20">DS18B20</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-dw3110">DW3110</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ea_dog">EA-DOG</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-encoder_input">Encoder Input</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-encoder_input-bitbang">Encoder Input BitBang</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-encoder_input-bitbang">Encoder Input BitBang</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-encoder_output-bitbang">Encoder Output BitBang</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ft245">FT245</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ft6x06">FT6x06</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-gpio_sampler">Gpio Sampler</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-hclax">HCLAx</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-hd44780">HD44780</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-hd44780">HD44780</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-hmc58x">HMC58x</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-hmc6343">HMC6343</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-hx711">HX711</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-i2c-eeprom">I2C-EEPROM</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ili9341">ILI9341</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-is31fl3733">IS31FL3733</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-is31fl3733">IS31FL3733</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-itg3200">ITG3200</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-iwr6843aop">IWR6843AOP</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ixm42xxx">IXM42XXX</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-l3gd20">L3GD20</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lan8720a">LAN8720A</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lawicel">LAWICEL</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lawicel">LAWICEL</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lis302dl">LIS302DL</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lis3dsh">LIS3DSH</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lis3mdl">LIS3MDL</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lm75">LM75</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lp503x">LP503x</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lsm303a">LSM303A</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lsm303a">LSM303A</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lsm6ds33">LSM6DS33</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lsm6dso">LSM6DSO</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ltc2984">LTC2984</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-max31855">MAX31855</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-max31865">MAX31865</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-max6966">MAX6966</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-max6966">MAX6966</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-max7219">MAX7219</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-mcp23x17">MCP23x17</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-mcp2515">MCP2515</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-mcp3008">MCP3008</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-mcp7941x">MCP7941x</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-mcp990x">MCP990X</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-mcp990x">MCP990X</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-mmc5603">MMC5603</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ms5611">MS5611</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ms5837">MS5837</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-nokia5110">NOKIA5110</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-nrf24">NRF24</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-parallel_tft_display">TFT-DISPLAY</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-parallel_tft_display">TFT-DISPLAY</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-pat9125el">PAT9125EL</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-pca8574">PCA8574</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-pca9535">PCA9535</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-pca9548a">PCA9548A</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-pca9685">PCA9685</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-qmc5883l">QMC5883L</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-qmc5883l">QMC5883L</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-sh1106">SH1106</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-siemens_s65">SIEMENS-S65</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-siemens_s75">SIEMENS-S75</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-sk6812">SK6812</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-sk9822">SK9822</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ssd1306">SSD1306</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ssd1306">SSD1306</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-st7586s">ST7586S</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-st7789">ST7789</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-stts22h">STTS22H</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-stusb4500">STUSB4500</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-sx1276">SX1276</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-sx128x">SX128X</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-sx128x">SX128X</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tcs3414">TCS3414</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tcs3472">TCS3472</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tlc594x">TLC594x</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tmp102">TMP102</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tmp12x">TMP12x</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tmp175">TMP175</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tmp175">TMP175</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-touch2046">TOUCH2046</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-vl53l0">VL53L0</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-vl6180">VL6180</a></td>
Expand Down
194 changes: 194 additions & 0 deletions examples/nucleo_h723zg/bmi270/calibration/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
/*
* Copyright (c) 2026, Henrik Hose
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#include <modm/board.hpp>
#include <modm/driver/inertial/bmi270.hpp>
#include <modm/processing.hpp>

using namespace Board;

using I2c = I2cMaster1;
using Scl = GpioB8; // D15
using Sda = GpioB9; // D14

using Transport = modm::Bmi270I2cTransport<I2c>;
using Imu = modm::Bmi270<Transport>;

Imu imu{Transport::I2cAddress::SdoLow};

namespace
{

struct CalibrationSnapshot
{
Imu::GyroUserGain gyroUserGainOut;
};

bool
initializeImu()
{
while (!imu.initialize())
{
MODM_LOG_ERROR << "Initialization failed, retrying..." << modm::endl;
modm::this_fiber::sleep_for(500ms);
}

bool ok = true;
ok &= imu.setAccRate(Imu::AccRate::Rate100Hz_Normal);
ok &= imu.setAccRange(Imu::AccRange::Range4g);
ok &= imu.setGyroRate(Imu::GyroRate::Rate100Hz_Normal);
ok &= imu.setGyroRange(Imu::GyroRange::Range2000dps);
ok &= imu.setPowerControl(Imu::PowerControl::Accelerometer | Imu::PowerControl::Gyroscope |
Imu::PowerControl::Temperature);
return ok;
}

void
printGyroUserGain(const char* label, const Imu::GyroUserGain& gain)
{
MODM_LOG_INFO << label << " x=" << int(gain.x) << " y=" << int(gain.y) << " z=" << int(gain.z)
<< modm::endl;
}

bool
equalGyroUserGain(const Imu::GyroUserGain& lhs, const Imu::GyroUserGain& rhs)
{
return (lhs.x == rhs.x) and (lhs.y == rhs.y) and (lhs.z == rhs.z);
}

} // namespace

int
main()
{
Board::initialize();
Leds::setOutput();
I2c::connect<Scl::Scl, Sda::Sda>(I2c::PullUps::External);
I2c::initialize<Board::SystemClock, 1_MHz, 10_pct>();

MODM_LOG_INFO << "BMI270 calibration example (CRT + gyro user gain restore)" << modm::endl;
MODM_LOG_INFO << "Keep sensor stable while CRT runs" << modm::endl;

if (!imu.reset()) { MODM_LOG_ERROR << "Initial soft reset command failed" << modm::endl; }
if (!initializeImu()) { MODM_LOG_ERROR << "Initial IMU configuration failed" << modm::endl; }

if (const auto userGain = imu.getGyroUserGain())
{
printGyroUserGain("Pre-CRT gyro user gain out", *userGain);
}

MODM_LOG_INFO << "Starting component retrim (CRT)..." << modm::endl;
if (!imu.doCrt())
{
MODM_LOG_ERROR << "CRT failed" << modm::endl;
} else
{
MODM_LOG_INFO << "CRT completed" << modm::endl;
}

const auto userGainOut = imu.getGyroUserGain();
if (!userGainOut)
{
MODM_LOG_ERROR << "Reading user gain out after CRT failed" << modm::endl;
return 1;
}

CalibrationSnapshot savedCalibration{};
savedCalibration.gyroUserGainOut = *userGainOut;

printGyroUserGain("Saved gyro user gain out", savedCalibration.gyroUserGainOut);

MODM_LOG_INFO << "Soft resetting sensor..." << modm::endl;
if (!imu.reset()) { MODM_LOG_ERROR << "Soft reset command failed" << modm::endl; }
if (!initializeImu())
{
MODM_LOG_ERROR << "Re-initialization after reset failed" << modm::endl;
}

if (const auto userGainBeforeRestore = imu.getGyroUserGain())
{
printGyroUserGain("After reset, before restore gyro user gain out", *userGainBeforeRestore);
}

MODM_LOG_INFO << "Restoring saved calibration values..." << modm::endl;
bool writeOk = true;
writeOk &= imu.setGyroUserGain(savedCalibration.gyroUserGainOut);
if (!writeOk) { MODM_LOG_ERROR << "Writing calibration values failed" << modm::endl; }

const auto restoredUserGain = imu.getGyroUserGain();

bool userGainMatch = false;
if (restoredUserGain)
{
userGainMatch = equalGyroUserGain(savedCalibration.gyroUserGainOut, *restoredUserGain);
printGyroUserGain("Restored gyro user gain out", *restoredUserGain);
}

MODM_LOG_INFO << "Verification: userGainOut=" << userGainMatch << modm::endl;

const bool restoreOk = writeOk and userGainMatch;
MODM_LOG_INFO << (restoreOk ? "Calibration restore PASSED" : "Calibration restore FAILED")
<< modm::endl;

static constexpr float LowPassAlpha{1e-3f};
bool filterInitialized = false;
modm::Vector3f filteredAcc{0.f, 0.f, 0.f};
modm::Vector3f filteredGyro{0.f, 0.f, 0.f};

modm::PeriodicTimer printTimer{1s};
while (true)
{
if (const auto data = imu.readData())
{
const auto acc = data->acc.getFloat();
const auto gyro = data->gyro.getFloat();

if (!filterInitialized)
{
filteredAcc = acc;
filteredGyro = gyro;
filterInitialized = true;
} else
{
filteredAcc[0] += LowPassAlpha * (acc[0] - filteredAcc[0]);
filteredAcc[1] += LowPassAlpha * (acc[1] - filteredAcc[1]);
filteredAcc[2] += LowPassAlpha * (acc[2] - filteredAcc[2]);
filteredGyro[0] += LowPassAlpha * (gyro[0] - filteredGyro[0]);
filteredGyro[1] += LowPassAlpha * (gyro[1] - filteredGyro[1]);
filteredGyro[2] += LowPassAlpha * (gyro[2] - filteredGyro[2]);
}
}

if (printTimer.execute())
{
if (filterInitialized)
{
MODM_LOG_INFO << "LPF (Bias) Acc [mg] x=" << filteredAcc[0]
<< " y=" << filteredAcc[1] << " z=" << filteredAcc[2] << modm::endl;
MODM_LOG_INFO << "LPF (Bias) Gyr [deg/s] x=" << filteredGyro[0]
<< " y=" << filteredGyro[1] << " z=" << filteredGyro[2] << modm::endl;
} else
{
MODM_LOG_ERROR << "No IMU sample received yet" << modm::endl;
}

if (restoreOk)
{
Board::LedGreen::toggle();
} else
{
Board::LedRed::toggle();
}
}
}

return 0;
}
11 changes: 11 additions & 0 deletions examples/nucleo_h723zg/bmi270/calibration/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<library>
<extends>modm:nucleo-h723zg</extends>
<options>
<option name="modm:build:build.path">../../../../build/nucleo_h723zg/bmi270_calibration</option>
</options>
<modules>
<module>modm:build:scons</module>
<module>modm:platform:i2c:1</module>
<module>modm:driver:bmi270</module>
</modules>
</library>
Loading
Loading