Skip to content

Document the I2C stall timeout in the contributor guide #102

Open

Description

@kammce

The contributor guide has no I2C page yet. When it gets one, or when the I2C guide in #50 is written, it should cover how libhal handles a stalled I2C bus, which libhal/libhal#263 defines in hal::i2c's class description.

For platform driver authors

  • Throw hal::timed_out when the bus makes no progress for longer than a stall timeout. The timeout counts time without progress, never the length of the whole transaction, so a long transfer at a slow clock rate never times out on its length alone.
  • Take the timeout at construction, never through hal::i2c. It must be longer than every device on the bus stretches the clock, and they all share it, so only the application can choose it.
  • Default to 100 ms, and document the default. 100 ms is longer than the SMBus clock-low timeout (25 to 35 ms) and than devices that stretch the clock while they measure, such as the Sensirion SHT21 (up to 85 ms).
  • Never give up sooner than the timeout. Round up to what the hardware can measure: a poll count, a peripheral's SCL-low timer, or the waiter's tick. Convert the duration once, at construction. If it can't be reached, throw hal::operation_not_supported from the constructor.
  • Report progress: hal::timed_out::progress is the number of bytes known to have been transferred, counting p_data_out first and then p_data_in, as a lower bound.
  • If the hardware can't detect a stall, or can't measure the timeout asked for, document what the driver does instead.

hal::stm32f1::polled_i2c and dma_i2c (libhal/libhal-arm-mcu#237 and libhal/libhal-arm-mcu#242) are examples: polls counted at construction, and the waiter's timeout for DMA transfers.

For device driver authors

  • Don't rely on the device stretching the clock for more than 25 ms, the SMBus limit.
  • If the device has a mode that doesn't stretch the clock, such as starting a measurement and reading the result later, use it.
  • Otherwise, document the stall timeout the driver needs, so the application can construct the bus with it.

For application developers

  • Choose the stall timeout when constructing the bus, longer than any device on it stretches the clock.
  • Tolerate a bus that can't time out. Some hardware can't detect a stall. Use a watchdog, for example.

Related

  • mkdocs/education/i2c.md still describes the old p_timeout parameter of transaction() and hal::never_timeout(), which v5's hal::i2c doesn't have.
  • References:

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions