New kernel drivers, filesystem API, and more (#513)
* **New Features** * BMI270 6-axis IMU driver added; new unified filesystem abstraction for mounted filesystems. * Public Wi‑Fi API surface (no implementation yet) * SDMMC driver added (kernel drive$) * expanded GPIO interrupt/callback support * **Improvements** * M5Stack Tab5: revamped GPIO/power initialization and IMU integration. * LVGL updates including device fontSize configuration. * Updated all code related to SD card device/fs handling * Rename LilyGO T-HMI S3 to LilyGO T-HMI * **Bug Fixes** * Simplified and consolidated SD card handling and mount discovery.
This commit is contained in:
committed by
GitHub
parent
2de35b2d2d
commit
aa7530e515
@@ -3,6 +3,8 @@
|
||||
#include <pi4ioe5v6408_module.h>
|
||||
#include <tactility/device.h>
|
||||
#include <tactility/driver.h>
|
||||
#include <tactility/drivers/gpio_controller.h>
|
||||
#include <tactility/drivers/gpio_descriptor.h>
|
||||
#include <tactility/drivers/i2c_controller.h>
|
||||
#include <tactility/log.h>
|
||||
|
||||
@@ -27,72 +29,181 @@ static error_t start(Device* device) {
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
LOG_I(TAG, "Started PI4IOE5V6408 device %s", device->name);
|
||||
return ERROR_NONE;
|
||||
|
||||
return gpio_controller_init_descriptors(device, 8, nullptr);
|
||||
}
|
||||
|
||||
static error_t stop(Device* device) {
|
||||
check(gpio_controller_deinit_descriptors(device) == ERROR_NONE);
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
error_t pi4ioe5v6408_set_direction(Device* device, uint8_t bits, TickType_t timeout) {
|
||||
|
||||
static error_t set_level(GpioDescriptor* descriptor, bool high) {
|
||||
auto* device = descriptor->controller;
|
||||
auto* parent = device_get_parent(device);
|
||||
return i2c_controller_register8_set(parent, GET_CONFIG(device)->address, PI4_REGISTER_DIRECTION, bits, timeout);
|
||||
auto address = GET_CONFIG(device)->address;
|
||||
uint8_t bit = 1 << descriptor->pin;
|
||||
|
||||
if (high) {
|
||||
return i2c_controller_register8_set_bits(parent, address, PI4_REGISTER_OUTPUT_LEVEL, bit, portMAX_DELAY);
|
||||
} else {
|
||||
return i2c_controller_register8_reset_bits(parent, address, PI4_REGISTER_OUTPUT_LEVEL, bit, portMAX_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
error_t pi4ioe5v6408_set_output_level(Device* device, uint8_t bits, TickType_t timeout) {
|
||||
static error_t get_level(GpioDescriptor* descriptor, bool* high) {
|
||||
auto* device = descriptor->controller;
|
||||
auto* parent = device_get_parent(device);
|
||||
return i2c_controller_register8_set(parent, GET_CONFIG(device)->address, PI4_REGISTER_OUTPUT_LEVEL, bits, timeout);
|
||||
auto address = GET_CONFIG(device)->address;
|
||||
uint8_t bits;
|
||||
|
||||
error_t err = i2c_controller_register8_get(parent, address, PI4_REGISTER_INPUT_LEVEL, &bits, portMAX_DELAY);
|
||||
if (err != ERROR_NONE) {
|
||||
return err;
|
||||
}
|
||||
|
||||
*high = (bits & (1 << descriptor->pin)) != 0;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
error_t pi4ioe5v6408_get_output_level(Device* device, uint8_t* bits, TickType_t timeout) {
|
||||
static error_t set_flags(GpioDescriptor* descriptor, gpio_flags_t flags) {
|
||||
auto* device = descriptor->controller;
|
||||
auto* parent = device_get_parent(device);
|
||||
return i2c_controller_register8_get(parent, GET_CONFIG(device)->address, PI4_REGISTER_OUTPUT_LEVEL, bits, timeout);
|
||||
auto address = GET_CONFIG(device)->address;
|
||||
uint8_t bit = 1 << descriptor->pin;
|
||||
|
||||
error_t err;
|
||||
|
||||
// Direction
|
||||
if (flags & GPIO_FLAG_DIRECTION_OUTPUT) {
|
||||
err = i2c_controller_register8_set_bits(parent, address, PI4_REGISTER_DIRECTION, bit, portMAX_DELAY);
|
||||
} else {
|
||||
err = i2c_controller_register8_reset_bits(parent, address, PI4_REGISTER_DIRECTION, bit, portMAX_DELAY);
|
||||
}
|
||||
|
||||
if (err != ERROR_NONE) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// High Impedance
|
||||
if (flags & GPIO_FLAG_HIGH_IMPEDANCE) {
|
||||
err = i2c_controller_register8_set_bits(parent, address, PI4_REGISTER_OUTPUT_HIGH_IMPEDANCE, bit, portMAX_DELAY);
|
||||
} else {
|
||||
err = i2c_controller_register8_reset_bits(parent, address, PI4_REGISTER_OUTPUT_HIGH_IMPEDANCE, bit, portMAX_DELAY);
|
||||
}
|
||||
|
||||
if (err != ERROR_NONE) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// Pull-up/down
|
||||
if (flags & (GPIO_FLAG_PULL_UP | GPIO_FLAG_PULL_DOWN)) {
|
||||
// Set pull up or pull down
|
||||
if (flags & GPIO_FLAG_PULL_UP) {
|
||||
err = i2c_controller_register8_set_bits(parent, address, PI4_REGISTER_PULL_SELECT, bit, portMAX_DELAY);
|
||||
} else {
|
||||
err = i2c_controller_register8_reset_bits(parent, address, PI4_REGISTER_PULL_SELECT, bit, portMAX_DELAY);
|
||||
}
|
||||
|
||||
if (err != ERROR_NONE) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// Enable pull-up/down
|
||||
err = i2c_controller_register8_set_bits(parent, address, PI4_REGISTER_PULL_ENABLE, bit, portMAX_DELAY);
|
||||
} else {
|
||||
// Disable pull-up/down
|
||||
err = i2c_controller_register8_reset_bits(parent, address, PI4_REGISTER_PULL_ENABLE, bit, portMAX_DELAY);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
error_t pi4ioe5v6408_set_output_high_impedance(struct Device* device, uint8_t bits, TickType_t timeout) {
|
||||
static error_t get_flags(GpioDescriptor* descriptor, gpio_flags_t* flags) {
|
||||
auto* device = descriptor->controller;
|
||||
auto* parent = device_get_parent(device);
|
||||
return i2c_controller_register8_set(parent, GET_CONFIG(device)->address, PI4_REGISTER_OUTPUT_HIGH_IMPEDANCE, bits, timeout);
|
||||
auto address = GET_CONFIG(device)->address;
|
||||
uint8_t bit = 1 << descriptor->pin;
|
||||
uint8_t val;
|
||||
error_t err;
|
||||
|
||||
gpio_flags_t f = GPIO_FLAG_NONE;
|
||||
|
||||
// Direction
|
||||
err = i2c_controller_register8_get(parent, address, PI4_REGISTER_DIRECTION, &val, portMAX_DELAY);
|
||||
if (err != ERROR_NONE) return err;
|
||||
if (val & bit) {
|
||||
f |= GPIO_FLAG_DIRECTION_OUTPUT;
|
||||
} else {
|
||||
f |= GPIO_FLAG_DIRECTION_INPUT;
|
||||
}
|
||||
|
||||
// Pull-up/down
|
||||
err = i2c_controller_register8_get(parent, address, PI4_REGISTER_PULL_ENABLE, &val, portMAX_DELAY);
|
||||
if (err != ERROR_NONE) return err;
|
||||
if (val & bit) {
|
||||
err = i2c_controller_register8_get(parent, address, PI4_REGISTER_PULL_SELECT, &val, portMAX_DELAY);
|
||||
if (err != ERROR_NONE) return err;
|
||||
if (val & bit) {
|
||||
f |= GPIO_FLAG_PULL_UP;
|
||||
} else {
|
||||
f |= GPIO_FLAG_PULL_DOWN;
|
||||
}
|
||||
}
|
||||
|
||||
// High Impedance
|
||||
err = i2c_controller_register8_get(parent, address, PI4_REGISTER_OUTPUT_HIGH_IMPEDANCE, &val, portMAX_DELAY);
|
||||
if (err != ERROR_NONE) return err;
|
||||
if (val & bit) {
|
||||
f |= GPIO_FLAG_HIGH_IMPEDANCE;
|
||||
}
|
||||
|
||||
*flags = f;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
error_t pi4ioe5v6408_set_input_default_level(struct Device* device, uint8_t bits, TickType_t timeout) {
|
||||
auto* parent = device_get_parent(device);
|
||||
return i2c_controller_register8_set(parent, GET_CONFIG(device)->address, PI4_REGISTER_INPUT_DEFAULT_LEVEL, bits, timeout);
|
||||
static error_t get_native_pin_number(GpioDescriptor* descriptor, void* pin_number) {
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
error_t pi4ioe5v6408_set_pull_enable(struct Device* device, uint8_t bits, TickType_t timeout) {
|
||||
auto* parent = device_get_parent(device);
|
||||
return i2c_controller_register8_set(parent, GET_CONFIG(device)->address, PI4_REGISTER_PULL_ENABLE, bits, timeout);
|
||||
static error_t add_callback(GpioDescriptor* descriptor, void (*callback)(void*), void* arg) {
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
error_t pi4ioe5v6408_set_pull_select(struct Device* device, uint8_t bits, TickType_t timeout) {
|
||||
auto* parent = device_get_parent(device);
|
||||
return i2c_controller_register8_set(parent, GET_CONFIG(device)->address, PI4_REGISTER_PULL_SELECT, bits, timeout);
|
||||
static error_t remove_callback(GpioDescriptor* descriptor) {
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
error_t pi4ioe5v6408_get_input_level(struct Device* device, uint8_t* bits, TickType_t timeout) {
|
||||
auto* parent = device_get_parent(device);
|
||||
return i2c_controller_register8_get(parent, GET_CONFIG(device)->address, PI4_REGISTER_INPUT_LEVEL, bits, timeout);
|
||||
static error_t enable_interrupt(GpioDescriptor* descriptor) {
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
error_t pi4ioe5v6408_set_interrupt_mask(struct Device* device, uint8_t bits, TickType_t timeout) {
|
||||
auto* parent = device_get_parent(device);
|
||||
return i2c_controller_register8_set(parent, GET_CONFIG(device)->address, PI4_REGISTER_INTERRUPT_MASK, bits, timeout);
|
||||
static error_t disable_interrupt(GpioDescriptor* descriptor) {
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
error_t pi4ioe5v6408_get_interrupt_level(struct Device* device, uint8_t* bits, TickType_t timeout) {
|
||||
auto* parent = device_get_parent(device);
|
||||
return i2c_controller_register8_get(parent, GET_CONFIG(device)->address, PI4_REGISTER_INTERRUPT_LEVEL, bits, timeout);
|
||||
}
|
||||
const static GpioControllerApi pi4_gpio_api = {
|
||||
.set_level = set_level,
|
||||
.get_level = get_level,
|
||||
.set_flags = set_flags,
|
||||
.get_flags = get_flags,
|
||||
.get_native_pin_number = get_native_pin_number,
|
||||
.add_callback = add_callback,
|
||||
.remove_callback = remove_callback,
|
||||
.enable_interrupt = enable_interrupt,
|
||||
.disable_interrupt = disable_interrupt
|
||||
};
|
||||
|
||||
Driver pi4ioe5v6408_driver = {
|
||||
.name = "pi4ioe5v6408",
|
||||
.compatible = (const char*[]) { "diodes,pi4ioe5v6408", nullptr},
|
||||
.start_device = start,
|
||||
.stop_device = stop,
|
||||
.api = nullptr,
|
||||
.device_type = nullptr,
|
||||
.api = static_cast<const void*>(&pi4_gpio_api),
|
||||
.device_type = &GPIO_CONTROLLER_TYPE,
|
||||
.owner = &pi4ioe5v6408_module,
|
||||
.internal = nullptr
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user