-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Closed
Labels
Description
Describe the bug.
EVERY transaction on the i2c bus MUST be wrapped with
furi_hal_i2c_acquire();
furi_hal_i2c_ACTION();
furi_hal_i2c_release();
Where ACTION = {device_ready, tx, rx, trx}
If you attempt a second transaction without this wrapping, it will timeout and fail.
This is especially bad for furi_hal_i2c_trx(); which performs TWO transactions {Tx(), Rx()}, and therefore ALWAYS fails. The workaround for this is trivial, just call Tx() and Rx() yourself - do NOT use the TRx() wrapper.
Reproduction
Write a plugin that will call a function when the OK button is pressed
Run the plugin and press the OK button
The function may be:
FuriHalI2cBusHandle* bus = &furi_hal_i2c_handle_external;
uint8_t addr = 0x52 <<1;
uint32_t timeout = 1000;
uint8_t cmd[] = {0xf0, 0x00};
uint8_t res;
void fail_tx (void) {
furi_hal_i2c_acquire(bus);
furi_hal_i2c_tx(bus, addr, cmd, sizeof(cmd), timeout);
furi_hal_i2c_tx(bus, addr, cmd, sizeof(cmd), timeout);
furi_hal_i2c_release(bus);
}
void pass_tx (void) {
furi_hal_i2c_acquire(bus);
furi_hal_i2c_tx(bus, addr, cmd, sizeof(cmd), timeout);
furi_hal_i2c_release(bus);
furi_hal_i2c_acquire(bus);
furi_hal_i2c_tx(bus, addr, cmd, sizeof(cmd), timeout);
furi_hal_i2c_release(bus);
}
void fail_trx (void) {
furi_hal_i2c_acquire(bus);
furi_hal_i2c_trx(bus, addr, cmd, sizeof(cmd), &res, sizeof(res), timeout);
furi_hal_i2c_release(bus);
}
void pass_trx (void) {
furi_hal_i2c_acquire(bus);
furi_hal_i2c_tx(bus, addr, cmd, sizeof(cmd), timeout);
furi_hal_i2c_release(bus);
furi_hal_i2c_acquire(bus);
furi_hal_i2c_rx(bus, addr, &res, sizeof(res), timeout);
furi_hal_i2c_release(bus);
}
Target
Flipper git head as of posting
Logs
n/a
Anything else?
There is clearly something missing in firmware/targets/f7/furi_hal/furi_hal_i2c.c ...I've found a workaround, but I'm stumped how to fix this properly :(