I2C frequencies below 100kbps

Due to board design flaws that led to insufficient rise time for 100kbps communication, I would like to configure my i2c node in the device tree with a baud rate of 10 kbps.  At build time I get the following build failure:

C:\ncs\v2.1.0\zephyr\include\zephyr\toolchain\gcc.h:77:36: error: static assertion failed: "Wrong I2C 1 frequency setting in dts"
   77 | #define BUILD_ASSERT(EXPR, MSG...) _Static_assert(EXPR, "" MSG)
      |                                    ^~~~~~~~~~~~~~

This is checked in `i2c_nrfx_twim.c`:

#define I2C_NRFX_TWIM_FREQUENCY(bitrate)				       \
	(bitrate == I2C_BITRATE_STANDARD  ? NRF_TWIM_FREQ_100K :	       \
	 bitrate == 250000                ? NRF_TWIM_FREQ_250K :	       \
	 bitrate == I2C_BITRATE_FAST      ? NRF_TWIM_FREQ_400K :	       \
	IF_ENABLED(NRF_TWIM_HAS_1000_KHZ_FREQ,				       \
	(bitrate == I2C_BITRATE_FAST_PLUS ? NRF_TWIM_FREQ_1000K :))	       \
					    I2C_NRFX_TWIM_INVALID_FREQUENCY)

I suspect the answer is no but just want to double check before I wait on building another board - Could the driver support a lower baud rate if I modified this section of code?

Details:
nRF Connect SDK - v2.1.0

nRF52840

  • Nope - if your read the PS, those constants are the only values that the hardware supports. The 100kBps is the minimum.

    However,  the hardware supports clock stretching. That could help you in some cases depending how much control you have over the slave.

  • I had read multiple forum posts looking for a solution to the same problem, before giving up. Later I stumbled onto this post, which explains a very easy hack to set the bitrate lower than 100kbps (Thank you !)

    Under `toolchainVersion > modules > hal > nordic > nrfx > mdk > nrf9160_bitfields.h` you can find the line

    #define TWIM_FREQUENCY_FREQUENCY_K100 (0x01980000UL) /*!< 100 kbps */

    Simply changing this value according this instruction was the solution to our problem. So I set the value to 10 kbps

    #define TWIM_FREQUENCY_FREQUENCY_K100 (0x0028F000UL) /*!< 100 kbps */

    and here you can see that the SCL ticks are 100 µs long and the sensor responds now.

    We are reading a sensor hanging on an 8 meter long cable, which is impossible without lowering the bitrate to a much lower value.

Related