Ok, Truce.
What drove most of my comments in this thread about the 3 function sets is that
I've seen over the years that many people have a lack of or even misunderstanding of how the 3 function sets really work and assume that this sequence is being looked for by the LCD to cause some sort of internal reset.
I've seen many monitoring / snooping / decoding code implementations that have made incorrect assumptions about this sequence and they will have issues as it isn't emulating how the the chip set actually processes the instructions.
This included several logic analyzer decoders like the Saleae LCD decoder as well as your early implementation.
The sad part is that the reality of how the chip works is actually much simpler than what some of these implementations have done.
One of the reasons that I pushed so hard is that any implementation that is looking for this function set sequence will not be robust enough to work in many situations including with my Arduino hd44780 library when used on LCD backpacks due to the probing the hd44780 library does through the PCF8574 chip.
--- bill
After this post, I'll stop.
more detailed stuff below
"initialize by reset" vs "initialize by instruction"
An implementer that truly understands the datasheet and the chip instructions should be able to infer both "initialize by reset" and "initialize by instruction" sequences.
"initialize by reset" simply assumes 8 bit mode is active and thus skips over any steps of reliably forcing the LCD into 8 bit mode because it relies on the LCD already being in 8 bit mode from a fresh power up cycle. ("internal reset") and starts sending instructions for initialization.
That is the only difference between "initialize by reset" and "initialize by instruction".
And then the initial sequence of "initialize by instruction" to force the LCD into 8 bit mode so communication can commence can be inferred if taking into consideration the instruction set bit patterns, the 8bit/4bit state the LCD could be in when the sequence starts, and the potential for a garbage instruction being executed. The timing of the steps along the way can be inferred by assuming a worst case timing of using 100kHz LCD clock instead of the standard 270kHz, and assuming the longest instruction was executed as the garbage instruction.
If you do all that, you end up with the force to 8 bit mode instruction sequence and timing you see in figures 23 and 24 that is just above the sequence in the box at the bottom which is the actual initialization.
About the examples in tables 11, 12, and 13
Technically those 3 examples in tables 11, 12, & 13 are not really alternate initialization sequences.
They are examples that use and depend on the LCD "internal reset" that happens when the LCD powers up.
They do more than just initialize the LCD, they print a message.
The LCD initialization in those examples is
Table 11 steps 2,3, 4 (8 bit mode)
Table 12 steps, 2,3,4,5 (4 bit mode)
Table 13, steps, 2,3,4 (8 bit mode)
But as you mentioned, using "initialize by reset" is a short cut that can work but can have issues if the host ever does warm start initialization to the LCD without power cycling the LCD.
For example, attempting to do the initialization used in Tables 11, 12, and 13 when the LCD is in 4 bit mode expecting a high nibble will fail every other time.
This can cause a situation where every other warm start/reset "works" and I have seen this in some host implementations out in the wild.
What I have noticed over the years in conversations with various people is that some people (not saying this is you) have misinterpreted the phrase "with internal reset" mentioned in a few places in the datasheet and come to the mistaken belief that some of these instruction sequences are causing the LCD to do an internal reset vs the instruction sequence is depending on the LCD to have previously done an internal reset by just powering up.
And I believe that this is what has caused some host libraries to not properly implement a fully robust initialization sequence as the author has mistakenly believed that the instruction sequence he is doing is internally resetting the LCD so it should always work.
more details on the table 11-13 examples below
The table 11,12, and 13 examples are also incomplete or misleading at best in that they left off or failed to mention a critical step that if not done will cause the initialization to fail.
They failed to mention a step between 1 and 2.
The host must ensure that the "internal reset" has completed. It takes time for the internal LCD processor to complete the "internal reset" which is shown on page 23.
The "internal reset" done at powerup actually does a bit more than what is shown, it also initializes DDRAM which is what causes the boxes to show up.
While the host can poll BF to determine when "internal reset" is complete, the datasheet never mentions when BF can be polled to check for completion of the "internal reset".
If you assume that their step 1 includes this time until BF can be looked at, then they still left off a step of either waiting enough time for the "internal reset" to complete or polling BF to ensure that it has completed.
The datasheet is not clear on how soon before BF shows up or how long "internal reset" really takes.
The only mentions of this is on page 23 where it describes "initialization by internal reset"
The busy state lasts for 10 ms after VCC rises to 4.5 V.
which is odd since the LCD is specified to run all the way down to 2.7v
But no mention of how long before BF is valid after power up.
Also, that 10ms time could vary from that if the clock used is not the standard 270 kHz.
The "initialization by instruction" also has some information on this as it is more detailed and complete.
The "initialize by instruction" sequences in figures 23 and 24 specify:
Wait for more than 40 ms after VCC rises to 2.7 V
and
Wait for more than 15 ms after V CC rises to 4.5 V
Since these are not using BF at this point, These indicate that it takes more than 10ms
But then these sequences also assume a 100kHz clock for a 270kHz clock for their non BF timing.
Either way, the examples in tables 11 and 12 are incomplete in that they don't mention to wait for the "internal reset" to complete before sending any instructions.
-- bill