Additionally, because the Am79C961A had every expectation of having to share its ISA bus with perhaps as many as half a dozen other plug-in ISA cards, a number of its control inputs and outputs (notably signals for "interrupt request" and "DMA handshake and flow control") were low-true open-drain pins that could be wired with other signals on the ISA bus. And the Net186 card's designer dutifully pulled all these open-drain lines up with 10K pull-ups.
What the customer base reported as a fault was that often the first processor-driven bus cycle immediately following the completion of a DMA transfer of data from the Ethernet controller into the processor's local memory would be erratic.
We had this problem reported to us as a software fault in which behavior could be unpredictable and that it somehow had something to do with byte alignments. The presumption was that there was a software driver problem primarily because the bus functioned perfectly at all other times, and problems manifested themselves differently depending on whether the cycle immediately following a DMA transfer was a read or write, was a 16-bit or 8-bit bus cycle, or (if 8-bit) accessed the high or low byte. All other cycles after that first one worked fine, and all other cycles (DMA or processor-driven) worked at all other times, as well.
When we dug into the problem, what we discovered, courtesy of a logic analyzer, was that odd forms of bus contention were occurring on that first post-DMA processor cycle.
The root cause of this was that the handshake wasn't completing properly, largely because two critical signals governing the handoff, /DACK and /MASTER were open drain signals pulled high with 10K resistors. And 10K was too high a resistor value given board capacitance for the signals to return to their legal high (deasserted) states in time to avoid a timing violation or the stumbling of the host processor as it tried to recover ownership of the bus. Usually what would happen was that the Ethernet controller would try to relinquish the bus and wouldn't get the "I've got it" signal back from the processor host.
Making matters more interesting was the fact that many of the write control and "bus high enable" signals were also open drain, so the errant behavior could be quite different if the next access were an access that were 8-bits wide or one that was 16-bits wide. Particularly maddening was the fact that some accesses would work perfectly and there'd be no apparent fumbling of the handoff if the next activity of the processor were just the right combination of read or write (or 8-bit action taken in a high or low byte lane) that it didn't happen to contend with what the DMA engine happened to be doing in that brief span of time where it had indicated it wanted to relinquish the bus but hadn't gotten the message that the handoff had been completed.
The solution was fairly straightforward, and for all the suspicions that one or another device driver was at fault, it was ultimately a hardware fix that got things working again. Yes, most of those 10K pull-ups became 1K pull-ups. The harder yank up to Vcc was all it took to overcome the slow RC time constant that was causing things to stumble.
The moral of the story? Remember that even single-ended signals can be inherently analog if you're asking them to transition quickly enough to meet some digital timing spec. Everything on a PCB has an RC time constant, after all. And it can be the least obvious signals sometimes that bite you.
This entry was submitted by Eric Overton and edited by Rob Spiegel.
Eric Overton is the CEO of Focus Embedded, an Austin, Texas, company dedicated to designing embedded control and instrumentation systems. His 25 years of experience spans the design of laser measurement systems, data communications test equipment, feedback control systems, microprocessor emulators, and development and video systems. He received his undergraduate and graduate degrees from the Thayer School of Engineering at Dartmouth College.
Tell us your experience in solving a knotty engineering problem. Send to Rob Spiegel for Sherlock Ohms.