| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- /*
- As of the date of releasing this code, there is (seemingly) a bug in the FZ i2c library code
- It is described here: https://github.com/flipperdevices/flipperzero-firmware/issues/1670
- This is a short-term workaround so I can keep developing while we get to the bottom of the issue
- FYI. *something* in the following code is the fix
- void furi_hal_i2c_acquire (const FuriHalI2cBusHandle* handle)
- {
- // 1. Disable the power/backlight (it uses i2c)
- furi_hal_power_insomnia_enter();
- // 2. Lock bus access
- handle->bus->callback(handle->bus, FuriHalI2cBusEventLock);
- // 3. Ensuree that no active handle set
- furi_check(handle->bus->current_handle == NULL);
- // 4. Set current handle
- handle->bus->current_handle = handle;
- // 5. Activate bus
- handle->bus->callback(handle->bus, FuriHalI2cBusEventActivate);
- // 6. Activate handle
- handle->callback(handle, const FuriHalI2cBusHandleEventActivate);
- }
- void furi_hal_i2c_release (const FuriHalI2cBusHandle* handle)
- {
- // Ensure that current handle is our handle
- furi_check(handle->bus->current_handle == handle);
- // 6. Deactivate handle
- handle->callback(handle, const FuriHalI2cBusHandleEventDeactivate);
- // 5. Deactivate bus
- handle->bus->callback(handle->bus, FuriHalI2cBusEventDeactivate);
- // 3,4. Reset current handle
- handle->bus->current_handle = NULL;
- // 2. Unlock bus
- handle->bus->callback(handle->bus, FuriHalI2cBusEventUnlock);
- // 1. Re-enable the power system
- furi_hal_power_insomnia_exit();
- }
- */
- #ifndef I2C_WORKAROUND_H_
- #define I2C_WORKAROUND_H_
- #include <furi_hal.h>
- #define ENABLE_WORKAROUND 1
- #if ENABLE_WORKAROUND == 1
- //+============================================================================ ========================================
- static inline bool furi_hal_Wi2c_is_device_ready(
- const FuriHalI2cBusHandle* const bus,
- const uint8_t addr,
- const uint32_t tmo) {
- furi_hal_i2c_acquire(bus);
- bool rv = furi_hal_i2c_is_device_ready(bus, addr, tmo);
- furi_hal_i2c_release(bus);
- return rv;
- }
- //+============================================================================
- static inline bool furi_hal_Wi2c_tx(
- const FuriHalI2cBusHandle* const bus,
- const uint8_t addr,
- const void* buf,
- const size_t len,
- const uint32_t tmo) {
- furi_hal_i2c_acquire(bus);
- bool rv = furi_hal_i2c_tx(bus, addr, buf, len, tmo);
- furi_hal_i2c_release(bus);
- return rv;
- }
- //+============================================================================
- static inline bool furi_hal_Wi2c_rx(
- const FuriHalI2cBusHandle* const bus,
- const uint8_t addr,
- void* buf,
- const size_t len,
- const uint32_t tmo) {
- furi_hal_i2c_acquire(bus);
- bool rv = furi_hal_i2c_rx(bus, addr, buf, len, tmo);
- furi_hal_i2c_release(bus);
- return rv;
- }
- //+============================================================================
- static inline bool furi_hal_Wi2c_trx(
- const FuriHalI2cBusHandle* const bus,
- const uint8_t addr,
- const void* tx,
- const size_t txlen,
- void* rx,
- const size_t rxlen,
- const uint32_t tmo) {
- bool rv = furi_hal_Wi2c_tx(bus, addr, tx, txlen, tmo);
- if(rv) rv = furi_hal_Wi2c_rx(bus, addr, rx, rxlen, tmo);
- return rv;
- }
- //----------------------------------------------------------------------------- ----------------------------------------
- #define furi_hal_i2c_is_device_ready(...) furi_hal_Wi2c_is_device_ready(__VA_ARGS__)
- #define furi_hal_i2c_tx(...) furi_hal_Wi2c_tx(__VA_ARGS__)
- #define furi_hal_i2c_rx(...) furi_hal_Wi2c_rx(__VA_ARGS__)
- #define furi_hal_i2c_trx(...) furi_hal_Wi2c_trx(__VA_ARGS__)
- #endif //ENABLE_WORKAROUND
- //+============================================================================ ========================================
- // Some devices take a moment to respond to read requests
- // The puts a delay between the address being set and the data being read
- //
- static inline bool furi_hal_i2c_trxd(
- const FuriHalI2cBusHandle* const bus,
- const uint8_t addr,
- const void* tx,
- const size_t txlen,
- void* rx,
- const size_t rxlen,
- const uint32_t tmo,
- const uint32_t us) {
- bool rv = furi_hal_i2c_tx(bus, addr, tx, txlen, tmo);
- if(rv) {
- furi_delay_us(us);
- rv = furi_hal_i2c_rx(bus, addr, rx, rxlen, tmo);
- }
- return rv;
- }
- #endif //I2C_WORKAROUND_H_
|