Page 1 of 1

KSZ8863 driver sharing I2C with other chips

Posted: Tue Oct 01, 2024 10:02 pm
by twompark
I have a circuit using KSZ8863 designed many years ago, before the Espressif KSZ8863 driver was available, and put together my own driver, but would now like to switch to the supported driver. However, my circuit shares the I2C port with the KSZ8863 and another unrelated chip. I need to read the status of this chip often. Is there a way I can obtain the KSZ driver I2C bus-lock semaphore so that I can have other code use the same I2C port? Or any other way to do this? Any examples? thanks!

Re: KSZ8863 driver sharing I2C with other chips

Posted: Wed Oct 02, 2024 7:32 am
by nopnop2002
esp-idf does not have the ability to acquire an I2C bus lock semaphore.
It is necessary to construct a mechanism for exclusive control of the I2C bus by yourself.

All devices sharing an I2C port must be read and written within one task.

If you divide it into two tasks: reading the KSZ8863 and reading another unrelated chip, you will need exclusive control of the i2c bus.

Re: KSZ8863 driver sharing I2C with other chips

Posted: Wed Oct 02, 2024 8:52 am
by MicroController
twompark wrote:
Tue Oct 01, 2024 10:02 pm
Is there a way I can obtain the KSZ driver I2C bus-lock semaphore so that I can have other code use the same I2C port?
The IDF I2C driver takes care of that. You can talk to multiple devices from multiple tasks via the same I2C port without doing anything special.

Re: KSZ8863 driver sharing I2C with other chips

Posted: Wed Oct 02, 2024 1:30 pm
by nopnop2002
> You can talk to multiple devices from multiple tasks via the same I2C port without doing anything special.

This is incorrect.

Thread Safety
The factory function i2c_new_master_bus() and i2c_new_slave_device() are guaranteed to be thread safe by the driver, which means that the functions can be called from different RTOS tasks without protection by extra locks. Other public I2C APIs are not thread safe, which means the user should avoid calling them from multiple tasks, if it is necessary to call them in multiple tasks, please add extra locks.


It's written here.
https://docs.espressif.com/projects/esp ... ead-safety

Re: KSZ8863 driver sharing I2C with other chips

Posted: Wed Oct 02, 2024 2:31 pm
by twompark
The KSZ8863 driver has the following code snipits for internal access of the I2C control port:

Code: Select all

static inline bool bus_lock(uint32_t lock_timeout_ms)
{
    return xSemaphoreTake(s_ksz8863_ctrl_intf->bus_lock, pdMS_TO_TICKS(lock_timeout_ms)) == pdTRUE;
}

static inline bool bus_unlock(void)
{
    return xSemaphoreGive(s_ksz8863_ctrl_intf->bus_lock) == pdTRUE;
}
And when it wants to use I2C it does:

Code: Select all

   ESP_GOTO_ON_FALSE(bus_lock(KSZ8863_I2C_LOCK_TIMEOUT_MS), ESP_ERR_TIMEOUT, err, TAG, "I2C bus lock timeout");
    ESP_GOTO_ON_ERROR(i2c_master_cmd_begin(i2c_port, cmd, pdMS_TO_TICKS(KSZ8863_I2C_TIMEOUT_MS)), err_release, TAG,
                      "I2C master command begin error");
    bus_unlock();
But I don't see a way to be able to access these bus-lock functions externally, or access the semaphore itself from outside the driver.

Re: KSZ8863 driver sharing I2C with other chips

Posted: Wed Oct 02, 2024 4:06 pm
by MicroController
nopnop2002 wrote:
Wed Oct 02, 2024 1:30 pm
This is incorrect
Nope: https://github.com/espressif/esp-idf/bl ... ter.c#L897

Re: KSZ8863 driver sharing I2C with other chips

Posted: Wed Oct 02, 2024 4:10 pm
by twompark
It seems the KSZ8863 driver uses the older I2C routines that don't have the built-in locking. So maybe my solution is to update the KSZ drivers to the latest I2C functions.

Re: KSZ8863 driver sharing I2C with other chips

Posted: Wed Oct 02, 2024 9:46 pm
by nopnop2002
https://github.com/espressif/esp-idf/bl ... ter.c#L897

you are right.
ESP-IDF i2c documentation is incorrect.

Re: KSZ8863 driver sharing I2C with other chips

Posted: Thu Oct 03, 2024 1:59 pm
by MicroController
twompark wrote:
Wed Oct 02, 2024 4:10 pm
It seems the KSZ8863 driver uses the older I2C routines that don't have the built-in locking.
The "legacy" I2C driver also handles mutual exclusion for each I2C port: https://github.com/espressif/esp-idf/bl ... 2c.c#L1551