| 89 | // region Driver lifecycle |
| 90 | |
| 91 | static error_t start(Device* device) { |
| 92 | auto* i2c_controller = device_get_parent(device); |
| 93 | if (device_get_type(i2c_controller) != &I2C_CONTROLLER_TYPE) { |
| 94 | LOG_E(TAG, "Parent is not an I2C controller"); |
| 95 | return ERROR_RESOURCE; |
| 96 | } |
| 97 | |
| 98 | auto address = GET_CONFIG(device)->address; |
| 99 | |
| 100 | // Verify chip ID |
| 101 | uint8_t chip_id= 0; |
| 102 | if (i2c_controller_register8_get(i2c_controller, address, REG_CHIP_ID, &chip_id, I2C_TIMEOUT_TICKS) != ERROR_NONE || chip_id != 0x24) { |
| 103 | return ERROR_RESOURCE; |
| 104 | } |
| 105 | |
| 106 | // Soft reset — clears all registers; datasheet specifies 2 ms startup time. |
| 107 | // Use 20 ms to be safe and allow the chip to fully re-initialise before |
| 108 | // any further I2C traffic (a second chip-ID read immediately after reset |
| 109 | // is unreliable and not part of the Bosch SensorAPI init flow). |
| 110 | if (i2c_controller_register8_set(i2c_controller, address, REG_CMD, 0xB6, I2C_TIMEOUT_TICKS) != ERROR_NONE) return ERROR_RESOURCE; |
| 111 | vTaskDelay(pdMS_TO_TICKS(20)); |
| 112 | |
| 113 | // Upload 8KB configuration (enables internal feature engine) |
| 114 | if (!configure(i2c_controller, address)) { |
| 115 | return ERROR_RESOURCE; |
| 116 | } |
| 117 | |
| 118 | // Configure accelerometer: ODR=100Hz, normal filter, ±8g |
| 119 | if (i2c_controller_register8_set(i2c_controller, address, REG_ACC_CONF, ACC_CONF_VAL, I2C_TIMEOUT_TICKS) != ERROR_NONE) return ERROR_RESOURCE; |
| 120 | if (i2c_controller_register8_set(i2c_controller, address, REG_ACC_RANGE, ACC_RANGE_VAL, I2C_TIMEOUT_TICKS) != ERROR_NONE) return ERROR_RESOURCE; |
| 121 | |
| 122 | // Configure gyroscope: ODR=100Hz, normal filter, ±2000°/s |
| 123 | if (i2c_controller_register8_set(i2c_controller, address, REG_GYR_CONF, GYR_CONF_VAL, I2C_TIMEOUT_TICKS) != ERROR_NONE) return ERROR_RESOURCE; |
| 124 | if (i2c_controller_register8_set(i2c_controller, address, REG_GYR_RANGE, GYR_RANGE_VAL, I2C_TIMEOUT_TICKS) != ERROR_NONE) return ERROR_RESOURCE; |
| 125 | |
| 126 | // Enable accelerometer and gyroscope (bit1=gyr_en, bit2=acc_en) |
| 127 | if (i2c_controller_register8_set(i2c_controller, address, REG_PWR_CTRL, 0x06, I2C_TIMEOUT_TICKS) != ERROR_NONE) return ERROR_RESOURCE; |
| 128 | vTaskDelay(pdMS_TO_TICKS(2)); |
| 129 | |
| 130 | return ERROR_NONE; |
| 131 | } |
| 132 | |
| 133 | static error_t stop(Device* device) { |
| 134 | auto* i2c_controller = device_get_parent(device); |
nothing calls this directly
no test coverage detected