Grove driver, I2C migrations, bugfixes and docs (#532)

This commit is contained in:
Ken Van Hoeylandt
2026-06-19 00:52:31 +02:00
committed by GitHub
parent 8dabda2b5b
commit a35c88c8fd
74 changed files with 937 additions and 483 deletions
+16 -34
View File
@@ -1,9 +1,8 @@
#include <Tactility/app/i2cscanner/I2cScannerPrivate.h>
#include <Tactility/app/i2cscanner/I2cHelpers.h>
#include <Tactility/Assets.h>
#include <Tactility/app/AppContext.h>
#include <Tactility/hal/i2c/I2cDevice.h>
#include <tactility/drivers/i2c_controller.h>
#include <Tactility/Logger.h>
#include <Tactility/LogMessages.h>
#include <Tactility/lvgl/LvglSync.h>
@@ -33,7 +32,7 @@ class I2cScannerApp final : public App {
std::unique_ptr<Timer> scanTimer = nullptr;
// State
ScanState scanState = ScanStateInitial;
i2c_port_t port = I2C_NUM_0;
struct Device* portDevice = nullptr;
std::vector<uint8_t> scannedAddresses;
// Widgets
lv_obj_t* scanButtonLabelWidget = nullptr;
@@ -47,14 +46,13 @@ class I2cScannerApp final : public App {
static void onSelectBusCallback(lv_event_t* event);
static void onPressScanCallback(lv_event_t* event);
static void onScanTimerCallback();
void onSelectBus(lv_event_t* event);
void onPressScan(lv_event_t* event);
void onScanTimer();
bool shouldStopScanTimer();
bool getPort(i2c_port_t* outPort);
bool getPort(struct Device** outPort);
bool addAddressToList(uint8_t address);
bool hasScanThread();
void startScanning();
@@ -140,8 +138,10 @@ void I2cScannerApp::onShow(AppContext& app, lv_obj_t* parent) {
lv_obj_add_flag(scan_list, LV_OBJ_FLAG_HIDDEN);
scanListWidget = scan_list;
int32_t first_port;
if (getActivePortAtIndex(0, first_port)) {
struct Device* dummy;
if (getActivePortAtIndex(selected_bus, &dummy)) {
selectBus(selected_bus);
} else if (getActivePortAtIndex(0, &dummy)) {
lv_dropdown_set_selected(port_dropdown, 0);
selectBus(0);
}
@@ -184,9 +184,9 @@ void I2cScannerApp::onPressScanCallback(lv_event_t* event) {
// endregion Callbacks
bool I2cScannerApp::getPort(i2c_port_t* outPort) {
bool I2cScannerApp::getPort(struct Device** outPort) {
if (mutex.lock(100 / portTICK_PERIOD_MS)) {
*outPort = this->port;
*outPort = this->portDevice;
mutex.unlock();
return true;
} else {
@@ -219,21 +219,21 @@ bool I2cScannerApp::shouldStopScanTimer() {
void I2cScannerApp::onScanTimer() {
logger.info("Scan thread started");
i2c_port_t safe_port;
Device* safe_port;
if (!getPort(&safe_port)) {
logger.error("Failed to get I2C port");
onScanTimerFinished();
return;
}
if (!hal::i2c::isStarted(safe_port)) {
if (!device_is_ready(safe_port)) {
logger.error("I2C port not started");
onScanTimerFinished();
return;
}
for (uint8_t address = 0; address < 128; ++address) {
if (hal::i2c::masterHasDeviceAtAddress(safe_port, address, 10 / portTICK_PERIOD_MS)) {
if (i2c_controller_has_device_at_address(safe_port, address, 10 / portTICK_PERIOD_MS) == ERROR_NONE) {
logger.info("Found device at address 0x{:02X}", address);
if (!shouldStopScanTimer()) {
addAddressToList(address);
@@ -305,14 +305,14 @@ void I2cScannerApp::onSelectBus(lv_event_t* event) {
}
void I2cScannerApp::selectBus(int32_t selected) {
int32_t found_port;
if (!getActivePortAtIndex(selected, found_port)) {
struct Device* found_device;
if (!getActivePortAtIndex(selected, &found_device)) {
return;
}
if (mutex.lock(100 / portTICK_PERIOD_MS)) {
scannedAddresses.clear();
port = static_cast<i2c_port_t>(found_port);
portDevice = found_device;
scanState = ScanStateInitial;
mutex.unlock();
}
@@ -334,16 +334,6 @@ void I2cScannerApp::onPressScan(lv_event_t* event) {
updateViews();
}
static bool findDeviceName(const std::vector<std::shared_ptr<hal::i2c::I2cDevice>>& devices, i2c_port_t port, uint8_t address, std::string& outName) {
for (auto& device : devices) {
if (device->getPort() == port && device->getAddress() == address) {
outName = device->getName();
return true;
}
}
return false;
}
void I2cScannerApp::updateViews() {
if (mutex.lock(100 / portTICK_PERIOD_MS)) {
if (scanState == ScanStateScanning) {
@@ -358,18 +348,10 @@ void I2cScannerApp::updateViews() {
if (scanState == ScanStateStopped) {
lv_obj_remove_flag(scanListWidget, LV_OBJ_FLAG_HIDDEN);
auto devices = hal::findDevices<hal::i2c::I2cDevice>(hal::Device::Type::I2c);
if (!scannedAddresses.empty()) {
for (auto address: scannedAddresses) {
std::string address_text = getAddressText(address);
std::string device_name;
if (findDeviceName(devices, port, address, device_name)) {
auto text = std::format("{} - {}", address_text, device_name);
lv_list_add_text(scanListWidget, text.c_str());
} else {
lv_list_add_text(scanListWidget, address_text.c_str());
}
lv_list_add_text(scanListWidget, address_text.c_str());
}
} else {
lv_list_add_text(scanListWidget, "No devices found");