2017-11-30 07:55 PM
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?
2017-11-30 08:09 PM
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.
2017-12-01 08:52 AM
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!
2017-12-02 08:38 AM
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
2017-12-02 12:40 PM
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!
2017-12-03 01:47 AM
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
2017-12-03 11:41 AM
Excellent -- many thanks JW.