mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-04-18 17:35:05 +00:00
Cleanup
This commit is contained in:
parent
10ab4dded8
commit
4f1d9e5360
@ -24,31 +24,11 @@
|
||||
pin-sda = <&gpio0 31 GPIO_FLAG_NONE>;
|
||||
pin-scl = <&gpio0 32 GPIO_FLAG_NONE>;
|
||||
|
||||
/*
|
||||
- Bit 0: RF internal/external switch
|
||||
- Bit 1: Speaker enable
|
||||
- Bit 2: External 5V bus enable
|
||||
- Bit 3: /
|
||||
- Bit 4: LCD reset
|
||||
- Bit 5: Touch reset
|
||||
- Bit 6: Camera reset
|
||||
- Bit 7: Headphone detect
|
||||
*/
|
||||
io_expander0 {
|
||||
compatible = "diodes,pi4ioe5v6408";
|
||||
reg = <0x43>;
|
||||
};
|
||||
|
||||
/*
|
||||
- Bit 0: C6 WLAN enable
|
||||
- Bit 1: /
|
||||
- Bit 2: /
|
||||
- Bit 3: USB-A 5V enable
|
||||
- Bit 4: Device power: PWROFF_PLUSE
|
||||
- Bit 5: IP2326: nCHG_QC_EN
|
||||
- Bit 6: IP2326: CHG_STAT_LED
|
||||
- Bit 7: IP2326: CHG_EN
|
||||
*/
|
||||
io_expander1 {
|
||||
compatible = "diodes,pi4ioe5v6408";
|
||||
reg = <0x44>;
|
||||
|
||||
@ -44,51 +44,43 @@ static constexpr TickType_t I2C_TIMEOUT_TICKS = pdMS_TO_TICKS(10);
|
||||
|
||||
// region Helpers
|
||||
|
||||
static bool write_register(Device* i2c_controller, uint8_t address, uint8_t reg, uint8_t val) {
|
||||
return i2c_controller_register8_set(i2c_controller, address, reg, val, I2C_TIMEOUT_TICKS) == ERROR_NONE;
|
||||
}
|
||||
|
||||
static bool read_register(Device* i2c_controller, uint8_t address, uint8_t reg, uint8_t* buf) {
|
||||
return i2c_controller_register8_get(i2c_controller, address, reg, buf, I2C_TIMEOUT_TICKS) == ERROR_NONE;
|
||||
}
|
||||
|
||||
static bool configure(Device* i2c_controller, uint8_t address) {
|
||||
// Disable advanced power save before uploading
|
||||
if (!write_register(i2c_controller, address, REG_PWR_CONF, 0x00)) return false;
|
||||
if (i2c_controller_register8_set(i2c_controller, address, REG_PWR_CONF, 0x00, I2C_TIMEOUT_TICKS) != ERROR_NONE) return false;
|
||||
vTaskDelay(pdMS_TO_TICKS(1));
|
||||
|
||||
// Signal start of config upload
|
||||
if (!write_register(i2c_controller, address, REG_INIT_CTRL, 0x00)) return false;
|
||||
if (i2c_controller_register8_set(i2c_controller, address, REG_INIT_CTRL, 0x00, I2C_TIMEOUT_TICKS) != ERROR_NONE) return false;
|
||||
|
||||
// Upload config in CHUNK_SIZE-byte bursts
|
||||
// The half-word address (hwAddr) increments by CHUNK_SIZE/2 per chunk
|
||||
const size_t totalSize = sizeof(bmi270_config_data);
|
||||
for (size_t offset = 0; offset < totalSize; offset += CHUNK_SIZE) {
|
||||
constexpr size_t config_data_size = sizeof(bmi270_config_data);
|
||||
for (size_t offset = 0; offset < config_data_size; offset += CHUNK_SIZE) {
|
||||
// Set INIT_ADDR_0 and INIT_ADDR_1 (consecutive registers 0x5B/0x5C)
|
||||
uint16_t hwAddr = static_cast<uint16_t>(offset / 2);
|
||||
uint8_t addrBuf[2] = {
|
||||
static_cast<uint8_t>(hwAddr & 0x0Fu), // INIT_ADDR_0: bits [3:0]
|
||||
static_cast<uint8_t>((hwAddr >> 4) & 0xFFu) // INIT_ADDR_1: bits [11:4]
|
||||
auto hardware_address = static_cast<uint16_t>(offset / 2);
|
||||
uint8_t address_buffer[2] = {
|
||||
static_cast<uint8_t>(hardware_address & 0x0Fu), // INIT_ADDR_0: bits [3:0]
|
||||
static_cast<uint8_t>((hardware_address >> 4) & 0xFFu) // INIT_ADDR_1: bits [11:4]
|
||||
};
|
||||
|
||||
if (i2c_controller_write_register(i2c_controller, address, REG_INIT_ADDR_0, addrBuf, 2, I2C_TIMEOUT_TICKS) != ERROR_NONE) return false;
|
||||
if (i2c_controller_write_register(i2c_controller, address, REG_INIT_ADDR_0, address_buffer, 2, I2C_TIMEOUT_TICKS) != ERROR_NONE) return false;
|
||||
|
||||
// Write chunk to INIT_DATA register.
|
||||
// Copy to a stack buffer first: the config array may live in DROM (SPI flash)
|
||||
// which is not DMA-accessible; the I2C driver requires DRAM-backed buffers.
|
||||
size_t chunkLen = (offset + CHUNK_SIZE <= totalSize) ? CHUNK_SIZE : (totalSize - offset);
|
||||
uint8_t chunkBuf[CHUNK_SIZE];
|
||||
memcpy(chunkBuf, bmi270_config_data + offset, chunkLen);
|
||||
if (i2c_controller_write_register(i2c_controller, address, REG_INIT_DATA, chunkBuf, static_cast<uint16_t>(chunkLen), I2C_TIMEOUT_TICKS) != ERROR_NONE) return false;
|
||||
size_t chunk_length = (offset + CHUNK_SIZE <= config_data_size) ? CHUNK_SIZE : (config_data_size - offset);
|
||||
uint8_t chunk_buffer[CHUNK_SIZE];
|
||||
memcpy(chunk_buffer, bmi270_config_data + offset, chunk_length);
|
||||
if (i2c_controller_write_register(i2c_controller, address, REG_INIT_DATA, chunk_buffer, static_cast<uint16_t>(chunk_length), I2C_TIMEOUT_TICKS) != ERROR_NONE) return false;
|
||||
}
|
||||
|
||||
// Signal end of config upload
|
||||
if (!write_register(i2c_controller, address, REG_INIT_CTRL, 0x01)) return false;
|
||||
if (i2c_controller_register8_set(i2c_controller, address, REG_INIT_CTRL, 0x01, I2C_TIMEOUT_TICKS) != ERROR_NONE) return false;
|
||||
vTaskDelay(pdMS_TO_TICKS(20));
|
||||
|
||||
// Verify initialization
|
||||
uint8_t status = 0;
|
||||
if (!read_register(i2c_controller, address, REG_INTERNAL_ST, &status)) return false;
|
||||
if (i2c_controller_register8_get(i2c_controller, address, REG_INTERNAL_ST, &status, I2C_TIMEOUT_TICKS) != ERROR_NONE) return false;
|
||||
return (status & 0x01u) != 0; // bit 0 = init_ok
|
||||
}
|
||||
|
||||
@ -98,37 +90,41 @@ static bool configure(Device* i2c_controller, uint8_t address) {
|
||||
|
||||
static error_t start(Device* device) {
|
||||
auto* i2c_controller = device_get_parent(device);
|
||||
if (device_get_type(i2c_controller) != &I2C_CONTROLLER_TYPE) {
|
||||
LOG_E(TAG, "Parent is not an I2C controller");
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
|
||||
auto address = GET_CONFIG(device)->address;
|
||||
|
||||
// Verify chip ID
|
||||
uint8_t chip_id= 0;
|
||||
if (!read_register(i2c_controller, address, REG_CHIP_ID, &chip_id) || chip_id != 0x24) {
|
||||
return false;
|
||||
if (i2c_controller_register8_get(i2c_controller, address, REG_CHIP_ID, &chip_id, I2C_TIMEOUT_TICKS) != ERROR_NONE || chip_id != 0x24) {
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
|
||||
// Soft reset — clears all registers; datasheet specifies 2 ms startup time.
|
||||
// Use 20 ms to be safe and allow the chip to fully re-initialise before
|
||||
// any further I2C traffic (a second chip-ID read immediately after reset
|
||||
// is unreliable and not part of the Bosch SensorAPI init flow).
|
||||
if (!write_register(i2c_controller, address, REG_CMD, 0xB6)) return false;
|
||||
if (i2c_controller_register8_set(i2c_controller, address, REG_CMD, 0xB6, I2C_TIMEOUT_TICKS) != ERROR_NONE) return ERROR_RESOURCE;
|
||||
vTaskDelay(pdMS_TO_TICKS(20));
|
||||
|
||||
// Upload 8KB configuration (enables internal feature engine)
|
||||
if (!configure(i2c_controller, address)) {
|
||||
return false;
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
|
||||
// Configure accelerometer: ODR=100Hz, normal filter, ±8g
|
||||
if (!write_register(i2c_controller, address, REG_ACC_CONF, ACC_CONF_VAL)) { return false; }
|
||||
if (!write_register(i2c_controller, address, REG_ACC_RANGE, ACC_RANGE_VAL)) { return false; }
|
||||
if (i2c_controller_register8_set(i2c_controller, address, REG_ACC_CONF, ACC_CONF_VAL, I2C_TIMEOUT_TICKS) != ERROR_NONE) return ERROR_RESOURCE;
|
||||
if (i2c_controller_register8_set(i2c_controller, address, REG_ACC_RANGE, ACC_RANGE_VAL, I2C_TIMEOUT_TICKS) != ERROR_NONE) return ERROR_RESOURCE;
|
||||
|
||||
// Configure gyroscope: ODR=100Hz, normal filter, ±2000°/s
|
||||
if (!write_register(i2c_controller, address, REG_GYR_CONF, GYR_CONF_VAL)) { return false; }
|
||||
if (!write_register(i2c_controller, address, REG_GYR_RANGE, GYR_RANGE_VAL)) { return false; }
|
||||
if (i2c_controller_register8_set(i2c_controller, address, REG_GYR_CONF, GYR_CONF_VAL, I2C_TIMEOUT_TICKS) != ERROR_NONE) return ERROR_RESOURCE;
|
||||
if (i2c_controller_register8_set(i2c_controller, address, REG_GYR_RANGE, GYR_RANGE_VAL, I2C_TIMEOUT_TICKS) != ERROR_NONE) return ERROR_RESOURCE;
|
||||
|
||||
// Enable accelerometer and gyroscope
|
||||
if (!write_register(i2c_controller, address, REG_PWR_CTRL, 0x06)) { return false; } // bit1=gyr_en, bit2=acc_en
|
||||
// Enable accelerometer and gyroscope (bit1=gyr_en, bit2=acc_en)
|
||||
if (i2c_controller_register8_set(i2c_controller, address, REG_PWR_CTRL, 0x06, I2C_TIMEOUT_TICKS) != ERROR_NONE) return ERROR_RESOURCE;
|
||||
vTaskDelay(pdMS_TO_TICKS(2));
|
||||
|
||||
return ERROR_NONE;
|
||||
@ -167,8 +163,6 @@ error_t bmi270_read(Device* device, Bmi270Data* data) {
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
extern Module bmi270_module;
|
||||
|
||||
Driver bmi270_driver = {
|
||||
.name = "bmi270",
|
||||
.compatible = (const char*[]) { "bosch,bmi270", nullptr},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user