cancel
Showing results for 
Search instead for 
Did you mean: 

Need to add an extra clock cycle to an I2C clock line

PDR
Associate III
Posted on December 01, 2017 at 04:55

I am writing a driver for an old Lego NXT ultrasonic sensor. It uses I2C, which is fine in itself, but the sensor has a well-known bug such that it does not always follow standard I2C protocol. Specifically, it requires an extra clock cycle at a certain point in the communication.This is widely known, and if you examine the various solutions people have adopted, eg on Arduino, you will see what I mean. I am using a third-party board for this purpose that provides the necessary circuitry supporting the sensor, and I can communicate with the sensor successfully, except for the specific case in which this extra pulse is required.This third-party board is designed to be an extension for an Arduino, but I am using it with an STM32F4 Discovery board. It also has an H-bridge for the NXT motors, etc, and all works well.

The third-party board has a digital I/O line physically tied directly to the SCL line so that the Arduino software can add the clock cycle when required. Without the STM32 I2C driver running I can drive that digital line to add what would be the extra clock cycle, and have verified it with a logic analyzer. However, when the I2C device is applied, I cannot affect the SCL via this backdoor I/O line. I tried disabling the I2C unit, driving the digital line for the pulse, and then re-enabling the unit, but without any observable effect.

Hence my first question: should this be possible with an I2C unit on the STM32F4 Disco board?

6 REPLIES 6
Posted on December 01, 2017 at 05:09

Would expect one could switch the GPIO in/out of AF mode, can say I've tried.

I think I'd just entirely bit-bang the I2C interface, the STM32 I2C peripheral is as complex as it is annoying.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on December 01, 2017 at 16:52

Reconfiguring the pin mode is certainly worth a try. I was hoping to avoid bit-banging it, but agree it may be the simplest approach in the long run.

Thanks Clive!

Posted on December 02, 2017 at 16:38

However, when the I2C device is applied, I cannot affect the SCL via this backdoor I/O line. I

That indicates something seriously broken, like the I2C pin not being set to open drain in GPIO_OTYPER.

Reconfiguring the pin is just one write to GPIO_AFRL/AFRH; however, that internally would set the I2C module's SCL to 'unconnected' (which in my experience is 0, although I'd lȭve to hear ST confirm this together with a great dozen of other similar details, one very nice day)and I wouldn't be surprised if this would upset the internals of I2C machine - it has its quirks and after

https://community.st.com/0D50X00009XkaUJSAZ

of using it I still did not grab it completely. Roughly the same may apply to pulling the clock externally by another pin.

So, in this particular case, I am with Clive: better bitbang.

JW

Posted on December 02, 2017 at 20:40

Agreed, and am working on bit-banging it now.

However I am new to doing so, and thus have a related question. I am not clear about the SCL and SDA GPIO configurations required so that both the the master and the slave can read/write them (eg for slave ack/nack and clock stretching). If I configure both GPIO lines as outputs with open drain (and enable the internal pull-ups) and actively drive them directly high and low, is it the use of open drain that allows the slaves to drive them also? I think so, but am uncertain. And don't I need to configure SDA as an input whenever I want to read it? (Side note: I have a 10K pull-up resistor on each of the SDA and SCL lines.)

Many thanks!

Posted on December 03, 2017 at 09:47

is it the use of open drain that allows the slaves to drive them also?

Yes. If GPIO_OTYPER set to Open-Drain, the upper output transistor is never switched on.

And don't I need to configure SDA as an input whenever I want to read it?

No. As long as it is not set to Analog in GPIO_MODER, the digital input works.

Read the GPIO chapter in RM.

JW

Posted on December 03, 2017 at 19:41

Excellent -- many thanks JW.