A brief explainer: This is a single bi-directional IO buffer that drives pin (BP)IO0 on the 10p connector.
DIR | A | B |
---|---|---|
High | Input/High | Output/High |
High | Input/Low | Output/Low |
Low | Output/High | Input/High |
Low | Output/Low | Input/Low |
BPIO0 to B pin is input and output from the “real world” on the 10p connector. It has a 1M pull down to ensure pins don’t float. It also has a 120R series resistor to protect devices and the buffer.
BUFDIR0 is the RP2350 pin that controls the buffer direction pin (DIR). When high, it outputs A->B, when low it outputs A<-B. It has a 100K pull-down so it starts as a safe input before the RP2350 is fully initialized.
BUFIO0 is the RP2350 pin that controls the buffer HIGH/low output level using the buffer A pin. It has a 330R series resistor to protect the rp2350 and buffer during accidental bus contention.This is key: It also has a 100K (1M in 5) pull-down resistor to hold it weak low when the rp2350 gpio pin is an input.
Open drain bus types (1-Wire, I2C, 2Wire, HDUART, etc) require a pull-up resistor to create the high level. Masters and Subs sharing a bus pull the wire low to ground, and then make the pin high-impedance (like an input on microcontrollers) to release the bus and let the pull-up yank it back high.
So, the meat of the issue: when driving open drain bus types from the PIO, we toggle the DIR pin of the IO buffer to make the B (real world side) output high-impedance (input, DIR low A<-B) or an output ground (output, DIR high A->B). The RP2350 GPIO pin, BUFIO, is always an input held low by the pull-down resistor. This creates a low on the bus without needing to somehow change the RP2350 GPIO (BUFIO) from input to output/ground in the PIO program (which while possible, is an absolute mess and IMHO not a workable solution). We depend on that 100K resistor to keep the bus low when we output.
E9 errata essentially means that once the pins are exposed to a high level, they latch up and stick at a high level (2.1volts). They latch up so hard the 100K resistor can’t pull them down (reportedly <9K works). When the buffer is high-impedance on the bus (input to the RP2350) the pin sees the external high level and latches up. When we change the buffer to output from the RP2350 to the bus, instead of a low/ground it outputs high. Basically, we can’t create a low level on the bus because there’s no way to output low once the pin has latched.