Grove driver, I2C migrations, bugfixes and docs (#532)
This commit is contained in:
committed by
GitHub
parent
8dabda2b5b
commit
a35c88c8fd
@@ -13,7 +13,6 @@
|
||||
#include <Tactility/LogMessages.h>
|
||||
#include <Tactility/Logger.h>
|
||||
#include <Tactility/MountPoints.h>
|
||||
#include <Tactility/Paths.h>
|
||||
#include <Tactility/app/AppManifestParsing.h>
|
||||
#include <Tactility/app/AppRegistration.h>
|
||||
#include <Tactility/file/File.h>
|
||||
@@ -27,6 +26,7 @@
|
||||
#include <Tactility/settings/TimePrivate.h>
|
||||
|
||||
#include <tactility/concurrent/thread.h>
|
||||
#include <tactility/drivers/grove.h>
|
||||
#include <tactility/drivers/uart_controller.h>
|
||||
#include <tactility/filesystem/file_system.h>
|
||||
#include <tactility/hal_device_module.h>
|
||||
@@ -94,6 +94,7 @@ namespace app {
|
||||
namespace files { extern const AppManifest manifest; }
|
||||
namespace fileselection { extern const AppManifest manifest; }
|
||||
namespace gpssettings { extern const AppManifest manifest; }
|
||||
namespace grovesettings { extern const AppManifest manifest; }
|
||||
namespace i2cscanner { extern const AppManifest manifest; }
|
||||
namespace imageviewer { extern const AppManifest manifest; }
|
||||
namespace inputdialog { extern const AppManifest manifest; }
|
||||
@@ -187,7 +188,11 @@ static void registerInternalApps() {
|
||||
addAppManifest(app::chat::manifest);
|
||||
#endif
|
||||
|
||||
if (device_exists_of_type(&UART_CONTROLLER_TYPE)) {
|
||||
if (device_exists_of_type(&GROVE_TYPE)) {
|
||||
addAppManifest(app::grovesettings::manifest);
|
||||
}
|
||||
|
||||
if (device_exists_of_type(&UART_CONTROLLER_TYPE) || device_exists_of_type(&GROVE_TYPE)) {
|
||||
addAppManifest(app::addgps::manifest);
|
||||
addAppManifest(app::gpssettings::manifest);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
#include <vector>
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
#include <tactility/device.h>
|
||||
#include <tactility/drivers/grove.h>
|
||||
#include <tactility/lvgl_icon_shared.h>
|
||||
|
||||
#include <Tactility/Tactility.h>
|
||||
#include <Tactility/lvgl/Toolbar.h>
|
||||
|
||||
namespace tt::app::grovesettings {
|
||||
|
||||
class GroveSettingsApp final : public App {
|
||||
|
||||
std::vector<::Device*> devices;
|
||||
|
||||
void collectDevices() {
|
||||
devices.clear();
|
||||
device_for_each_of_type(&GROVE_TYPE, &devices, [](auto* device, auto* context) {
|
||||
auto* vec = static_cast<std::vector<::Device*>*>(context);
|
||||
vec->push_back(device);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
static void onModeChanged(lv_event_t* e) {
|
||||
auto* device = static_cast<::Device*>(lv_event_get_user_data(e));
|
||||
auto* dropdown = static_cast<lv_obj_t*>(lv_event_get_target(e));
|
||||
auto mode = static_cast<GroveMode>(lv_dropdown_get_selected(dropdown));
|
||||
grove_set_mode(device, mode);
|
||||
}
|
||||
|
||||
public:
|
||||
void onShow(AppContext& app, lv_obj_t* parent) override {
|
||||
collectDevices();
|
||||
|
||||
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_style_pad_row(parent, 0, LV_STATE_DEFAULT);
|
||||
|
||||
lvgl::toolbar_create(parent, app);
|
||||
|
||||
auto* main_wrapper = lv_obj_create(parent);
|
||||
lv_obj_set_flex_flow(main_wrapper, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_width(main_wrapper, LV_PCT(100));
|
||||
lv_obj_set_flex_grow(main_wrapper, 1);
|
||||
|
||||
for (auto* device : devices) {
|
||||
auto* row = lv_obj_create(main_wrapper);
|
||||
lv_obj_set_size(row, LV_PCT(100), LV_SIZE_CONTENT);
|
||||
lv_obj_set_style_pad_all(row, 0, LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_border_width(row, 0, LV_STATE_DEFAULT);
|
||||
|
||||
auto* label = lv_label_create(row);
|
||||
lv_label_set_text(label, device->name);
|
||||
lv_obj_align(label, LV_ALIGN_LEFT_MID, 0, 0);
|
||||
|
||||
auto* dropdown = lv_dropdown_create(row);
|
||||
lv_dropdown_set_options(dropdown, "Disabled\nUART\nI2C");
|
||||
lv_obj_align(dropdown, LV_ALIGN_RIGHT_MID, 0, 0);
|
||||
|
||||
GroveMode current = GROVE_MODE_DISABLED;
|
||||
grove_get_mode(device, ¤t);
|
||||
lv_dropdown_set_selected(dropdown, static_cast<uint32_t>(current));
|
||||
|
||||
lv_obj_add_event_cb(dropdown, onModeChanged, LV_EVENT_VALUE_CHANGED, device);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
extern const AppManifest manifest = {
|
||||
.appId = "GroveSettings",
|
||||
.appName = "Grove",
|
||||
.appIcon = LVGL_ICON_SHARED_CABLE,
|
||||
.appCategory = Category::Settings,
|
||||
.createApp = create<GroveSettingsApp>
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
#include "Tactility/app/i2cscanner/I2cHelpers.h"
|
||||
|
||||
#include <Tactility/StringUtils.h>
|
||||
#include <Tactility/hal/i2c/I2c.h>
|
||||
|
||||
#include <tactility/drivers/i2c_controller.h>
|
||||
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
@@ -19,31 +20,36 @@ std::string getAddressText(uint8_t address) {
|
||||
|
||||
std::string getPortNamesForDropdown() {
|
||||
std::vector<std::string> config_names;
|
||||
for (int port = 0; port < I2C_NUM_MAX; ++port) {
|
||||
auto native_port = static_cast<i2c_port_t>(port);
|
||||
if (hal::i2c::isStarted(native_port)) {
|
||||
auto* name = hal::i2c::getName(native_port);
|
||||
if (name != nullptr) {
|
||||
config_names.push_back(name);
|
||||
}
|
||||
device_for_each_of_type(&I2C_CONTROLLER_TYPE, &config_names, [](auto* device, auto* context) {
|
||||
auto* names = static_cast<std::vector<std::string>*>(context);
|
||||
if (device_is_ready(device)) {
|
||||
names->push_back(device->name);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return string::join(config_names, "\n");
|
||||
}
|
||||
|
||||
bool getActivePortAtIndex(int32_t index, int32_t& out) {
|
||||
int current_index = -1;
|
||||
for (int port = 0; port < I2C_NUM_MAX; ++port) {
|
||||
auto native_port = static_cast<i2c_port_t>(port);
|
||||
if (hal::i2c::isStarted(native_port)) {
|
||||
current_index++;
|
||||
if (current_index == index) {
|
||||
out = port;
|
||||
return true;
|
||||
bool getActivePortAtIndex(int32_t index, struct Device** out) {
|
||||
struct Context {
|
||||
int32_t targetIndex;
|
||||
int32_t currentIndex;
|
||||
struct Device* foundDevice;
|
||||
} context = { index, 0, nullptr };
|
||||
|
||||
device_for_each_of_type(&I2C_CONTROLLER_TYPE, &context, [](auto* device, auto* ctx) {
|
||||
auto* c = static_cast<Context*>(ctx);
|
||||
if (device_is_ready(device)) {
|
||||
if (c->currentIndex == c->targetIndex) {
|
||||
c->foundDevice = device;
|
||||
return false;
|
||||
}
|
||||
c->currentIndex++;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
});
|
||||
*out = context.foundDevice;
|
||||
return context.foundDevice != nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
#include <Tactility/hal/i2c/I2c.h>
|
||||
|
||||
#include <Tactility/Logger.h>
|
||||
#include <Tactility/Mutex.h>
|
||||
|
||||
#include <tactility/check.h>
|
||||
#include <tactility/drivers/i2c_controller.h>
|
||||
#include <tactility/time.h>
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include <tactility/drivers/esp32_i2c.h>
|
||||
#endif
|
||||
|
||||
namespace tt::hal::i2c {
|
||||
|
||||
class NoLock final : public tt::Lock {
|
||||
bool lock(TickType_t timeout) const override { return true; }
|
||||
void unlock() const override { /* NO-OP */ }
|
||||
};
|
||||
|
||||
static NoLock NO_LOCK;
|
||||
|
||||
Device* findDevice(i2c_port_t port) {
|
||||
#ifdef ESP_PLATFORM
|
||||
struct Params {
|
||||
i2c_port_t port;
|
||||
Device* device;
|
||||
};
|
||||
|
||||
Params params = {
|
||||
.port = port,
|
||||
.device = nullptr
|
||||
};
|
||||
|
||||
device_for_each_of_type(&I2C_CONTROLLER_TYPE, ¶ms, [](auto* device, auto* context) {
|
||||
auto* params_ptr = (Params*)context;
|
||||
auto* driver = device_get_driver(device);
|
||||
if (driver == nullptr) return true;
|
||||
if (!driver_is_compatible(driver, "espressif,esp32-i2c")) return true;
|
||||
auto* config = static_cast<const Esp32I2cConfig*>(device->config);
|
||||
if (config->port != params_ptr->port) return true;
|
||||
// Found it, stop iterating
|
||||
params_ptr->device = device;
|
||||
return false;
|
||||
});
|
||||
|
||||
return params.device;
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isStarted(i2c_port_t port) {
|
||||
auto* device = findDevice(port);
|
||||
if (device == nullptr) return false;
|
||||
return device_is_ready(device);
|
||||
}
|
||||
|
||||
const char* getName(i2c_port_t port) {
|
||||
auto* device = findDevice(port);
|
||||
if (device == nullptr) return nullptr;
|
||||
return device->name;
|
||||
}
|
||||
|
||||
bool masterRead(i2c_port_t port, uint8_t address, uint8_t* data, size_t dataSize, TickType_t timeout) {
|
||||
auto* device = findDevice(port);
|
||||
if (device == nullptr) return false;
|
||||
return i2c_controller_read(device, address, data, dataSize, timeout) == ERROR_NONE;
|
||||
}
|
||||
|
||||
bool masterReadRegister(i2c_port_t port, uint8_t address, uint8_t reg, uint8_t* data, size_t dataSize, TickType_t timeout) {
|
||||
auto* device = findDevice(port);
|
||||
if (device == nullptr) return false;
|
||||
return i2c_controller_read_register(device, address, reg, data, dataSize, timeout) == ERROR_NONE;
|
||||
}
|
||||
|
||||
bool masterWrite(i2c_port_t port, uint8_t address, const uint8_t* data, uint16_t dataSize, TickType_t timeout) {
|
||||
auto* device = findDevice(port);
|
||||
if (device == nullptr) return false;
|
||||
return i2c_controller_write(device, address, data, dataSize, timeout) == ERROR_NONE;
|
||||
}
|
||||
|
||||
bool masterWriteRegister(i2c_port_t port, uint8_t address, uint8_t reg, const uint8_t* data, uint16_t dataSize, TickType_t timeout) {
|
||||
auto* device = findDevice(port);
|
||||
if (device == nullptr) return false;
|
||||
return i2c_controller_write_register(device, address, reg, data, dataSize, timeout) == ERROR_NONE;
|
||||
}
|
||||
|
||||
bool masterWriteRegisterArray(i2c_port_t port, uint8_t address, const uint8_t* data, uint16_t dataSize, TickType_t timeout) {
|
||||
auto* device = findDevice(port);
|
||||
if (device == nullptr) return false;
|
||||
return i2c_controller_write_register_array(device, address, data, dataSize, timeout) == ERROR_NONE;
|
||||
}
|
||||
|
||||
bool masterWriteRead(i2c_port_t port, uint8_t address, const uint8_t* writeData, size_t writeDataSize, uint8_t* readData, size_t readDataSize, TickType_t timeout) {
|
||||
auto* device = findDevice(port);
|
||||
if (device == nullptr) return false;
|
||||
return i2c_controller_write_read(device, address, writeData, writeDataSize, readData, readDataSize, timeout) == ERROR_NONE;
|
||||
}
|
||||
|
||||
bool masterHasDeviceAtAddress(i2c_port_t port, uint8_t address, TickType_t timeout) {
|
||||
auto* device = findDevice(port);
|
||||
if (device == nullptr) return false;
|
||||
return i2c_controller_has_device_at_address(device, address, timeout) == ERROR_NONE;
|
||||
}
|
||||
|
||||
Lock& getLock(i2c_port_t port) {
|
||||
return NO_LOCK;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -5,24 +5,24 @@
|
||||
namespace tt::hal::i2c {
|
||||
|
||||
bool I2cDevice::read(uint8_t* data, size_t dataSize, TickType_t timeout) {
|
||||
return masterRead(port, address, data, dataSize, timeout);
|
||||
return i2c_controller_read(controller, address, data, dataSize, timeout) == ERROR_NONE;
|
||||
}
|
||||
|
||||
bool I2cDevice::write(const uint8_t* data, uint16_t dataSize, TickType_t timeout) {
|
||||
return masterWrite(port, address, data, dataSize, timeout);
|
||||
return i2c_controller_write(controller, address, data, dataSize, timeout) == ERROR_NONE;
|
||||
}
|
||||
|
||||
bool I2cDevice::writeRead(const uint8_t* writeData, size_t writeDataSize, uint8_t* readData, size_t readDataSize, TickType_t timeout) {
|
||||
return masterWriteRead(port, address, writeData, writeDataSize, readData, readDataSize, timeout);
|
||||
return i2c_controller_write_read(controller, address, writeData, writeDataSize, readData, readDataSize, timeout) == ERROR_NONE;
|
||||
}
|
||||
|
||||
bool I2cDevice::writeRegister(uint8_t reg, const uint8_t* data, uint16_t dataSize, TickType_t timeout) {
|
||||
return masterWriteRegister(port, address, reg, data, dataSize, timeout);
|
||||
return i2c_controller_write_register(controller, address, reg, data, dataSize, timeout) == ERROR_NONE;
|
||||
}
|
||||
|
||||
bool I2cDevice::readRegister12(uint8_t reg, float& out) const {
|
||||
std::uint8_t data[2] = {0};
|
||||
if (masterReadRegister(port, address, reg, data, 2, DEFAULT_TIMEOUT)) {
|
||||
if (i2c_controller_read_register(controller, address, reg, data, 2, DEFAULT_TIMEOUT) == ERROR_NONE) {
|
||||
out = (data[0] & 0x0F) << 8 | data[1];
|
||||
return true;
|
||||
} else {
|
||||
@@ -32,7 +32,7 @@ bool I2cDevice::readRegister12(uint8_t reg, float& out) const {
|
||||
|
||||
bool I2cDevice::readRegister14(uint8_t reg, float& out) const {
|
||||
std::uint8_t data[2] = {0};
|
||||
if (masterReadRegister(port, address, reg, data, 2, DEFAULT_TIMEOUT)) {
|
||||
if (i2c_controller_read_register(controller, address, reg, data, 2, DEFAULT_TIMEOUT) == ERROR_NONE) {
|
||||
out = (data[0] & 0x3F) << 8 | data[1];
|
||||
return true;
|
||||
} else {
|
||||
@@ -42,7 +42,7 @@ bool I2cDevice::readRegister14(uint8_t reg, float& out) const {
|
||||
|
||||
bool I2cDevice::readRegister16(uint8_t reg, uint16_t& out) const {
|
||||
std::uint8_t data[2] = {0};
|
||||
if (masterReadRegister(port, address, reg, data, 2, DEFAULT_TIMEOUT)) {
|
||||
if (i2c_controller_read_register(controller, address, reg, data, 2, DEFAULT_TIMEOUT) == ERROR_NONE) {
|
||||
out = data[0] << 8 | data[1];
|
||||
return true;
|
||||
} else {
|
||||
@@ -51,11 +51,11 @@ bool I2cDevice::readRegister16(uint8_t reg, uint16_t& out) const {
|
||||
}
|
||||
|
||||
bool I2cDevice::readRegister8(uint8_t reg, uint8_t& result) const {
|
||||
return masterWriteRead(port, address, ®, 1, &result, 1, DEFAULT_TIMEOUT);
|
||||
return i2c_controller_write_read(controller, address, ®, 1, &result, 1, DEFAULT_TIMEOUT) == ERROR_NONE;
|
||||
}
|
||||
|
||||
bool I2cDevice::writeRegister8(uint8_t reg, uint8_t value) const {
|
||||
return masterWriteRegister(port, address, reg, &value, 1, DEFAULT_TIMEOUT);
|
||||
return i2c_controller_write_register(controller, address, reg, &value, 1, DEFAULT_TIMEOUT) == ERROR_NONE;
|
||||
}
|
||||
|
||||
bool I2cDevice::bitOn(uint8_t reg, uint8_t bitmask) const {
|
||||
|
||||
Reference in New Issue
Block a user