Are S08QG8 pins (when configured for general I/O) totem pole or open collector?
I've searched the QG8 data sheet and the forum for this info, but came up with nothing.
Thanks for a great forum
You need to be aware of one little gotcha before you use a port bit as an open drain output.
Yes, setting the output register bit to a "permanent low" and then toggling the direction register bit will do the trick, right up until you set one of the OTHER port bits high or low while your open drain bit is high. Here's why:
When you use a BSET or BCLR instruction on the output register, the instruction first reads the port data byte, makes the specified bit high or low, then writes the byte back to the port address. Only thing is, when it reads the port it is reading the input state on any bit set as an input, which would be a logic high on the open drain bit if it is currently set as an input (assuming a pullup of some kind is present, which it usually is). When the instruction writes the byte back to the port it will write a one into the open drain bit in the output register, since it read that bit as a one. What you thought was your permanent low is now high. You'll get the same results if you did a LOAD-OR-STORE or a LOAD-AND-STORE for the port operation. You have to always reset the open drain port bit to a zero every time you tinker with the port, and do so with a LOAD-OR-STORE or LOAD-AND-STORE to avoid any glitches by using BSET/BCLR and then fixing the port with another BCLR on your pin.
When a GPIO pin is set as output, the pin will be actively driven both high and low, in accordance with the state of the output latch. (The expression "totem-pole" I think was more applicable to TTL than CMOS logic.) Note that an "open drain" connection can be simulated by setting the output latch permanently low, and then switching the data direction bit - a logic high would be represented by a (high-Z) input state.
I guess another way to do this which is perhaps easier, is to ignore the fact that the output value can get corrupted and just do a BCLR before you make it an output.
This behavior could be quite a "gotcha", especially since most datasheets make the following recommendation, without any specific mention of the side effect under discussion.
It is a good programming practice to write to the port data register before changing the direction of a port pin to become an output. This ensures that the pin will not be driven momentarily with an old data value that happened to be in the port data register.
What if ISR code writes to any other pin from the same port? It is then possible for an infrequent, and very difficult to track down, bug to occur on occasions when the interrupt routine splits the two instructions. In this case, a solution is to temporarily disable interrupts while the port pin is being set. But this requirement has not normally been associated with simple GPIO manipulations - but I guess it will now come to mind in the future.
The other solution is to write to the output register after setting the direction, but this will potentially cause a short glitch, the very thing we are attempting to avoid in the first instance. For the simulated open drain configuration used in a wire_OR situation, any glitch may potentially cause a conflict at the pin, maybe requiring inclusion of an extra current limiting resistor.
With C programming, where the relationship between the various GPIO pins tends to be "hidden" inside macros, whether there is a need to disable interrupts or not, will never be obvious. With C programming, it may not even be obvious to the programmer that manipulating a GPIO pin is in fact a read-modify-write operation, but may possibly be seen as a write operation.
Maybe it would be a good idea if the potential port corruption mechanism were to get a mention in a revised datasheet and/or be covered by an application note. I wonder how many previous threads on this forum, that reported I/O problems, might be due to this cause.
Retrieving data ...