Skip to content

Conversation

@meithecatte
Copy link

@meithecatte meithecatte commented Nov 27, 2025

Due to the particular example used by the documentation of the HAL I'm using, I first tried using this library with an I²C clock of 50 kHz (I'm using an adapter based on a PCF8574). Although I didn't know the cause at the time, this was preventing my LCD from working. I eventually perturbed it into working by switching to 100 kHz, but the mystery was getting to me – why would a slower I²C clock break things?

After some experiments, things got weirder – if I inserted some delay into write_bits_to_gpio, making things even slower, it started working again!

The mystery was getting to me, and eventually, I narrowed it down to the init sequence, and how it doesn't wait for the CLEAR and HOME commands to finish executing. I believe that for a 100 kHz I²C clock, things just happened to align in such a way, that one of these commands would get skipped completely. Slowing things down made it catch some of the writes again, which probably misaligned the phase of the 4-bit-wide bus – and slowing things down even more made everything work as written in the code.

While I'm at it, I'm also including a fix to make sure that the address set up time is observed – see t_AS on the figure below, which Hitachi have helpfully buried at the very end of the datasheet:

image

Admittedly, I couldn't find an experimental setup in which this particular issue prevented my LCD from working – but complying with the spec is always a good idea ;3

The first of these delays was necessary in my experiments with a 50 kHz
I²C clock, while the second one – for a 400 kHz I²C clock.
I couldn't create an experimental setup in which this particular
issue prevents my LCD unit from working, but the datasheet does
ask for a setup time.
Copy link
Owner

@michaelkamprath michaelkamprath left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much for your improvement! I do have a request for change though. Thanks!

Comment on lines +149 to +151
// first write value without the enable strobe
// to ensure that the address set-up time t_AS = 40 ns is observed
self.write_bits_to_gpio()?;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding the pre-enable write_bits_to_gpio changes every nibble write from two I²C transactions to three, but the mock expectations (e.g. test_generic_hd44780_pcf8574t_init in src/driver/hd44780.rs) still expect two. As written, the test suite will fail and the behavior change isn’t covered. Update the mocks to include the new writes and add a test that captures the t_AS setup write.

Please update the unit tests to reflect your change here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, do you have some kind of automation for updating these tests? I feel like they kind of have the vibe of snapshot tests a la insta...

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Run:

cargo test

To see what tests are failing (there are a few), and then figure out why. If you used codex or claude, note that there is a AGENTS.md already in the repo.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants