I've got a weird problem with an SPI triple half-bridge driver IC that I can't find the cause of. I'm talking to it with an Arduino (ATmega328P), but not using the Arduino SPI library (although the problem does occur when using that too).
The problem is this: when I have it hooked up using an I/O pin for Chip Select that's
not the AVR's SS pin (PB2), the first time (since reset) I try to talk to the chip I get seemingly nonsense status output that doesn't reflect what's actually happening (the chip actually performs as expected, regardless of what the status data says it's doing). All further communication with the chip works perfectly fine.
Some details on the chip: On each SPI transfer, the driver chip takes an input 16-bit control word, and outputs a 16-bit status word. The control word has bits for which outputs to enable, whether to shut down on error conditions, as well as a bit that instructs it clear any previous status flags. The output status word has bits indicating error conditions, the state of outputs, and an over-temp warning. Accordingly, my method of communication is as follows:
1. Transfer a control word with the 'status reset' flag on. Ignore the output status.
2. Wait a few hundred microseconds.
3. Transfer the same control word again, but with status reset flag unset.
4. Read the output status.
I have my code dumping some debug info showing what is being transmitted and received. Here's an example of what I see when the problem occurs:
===> Control input word: 1110000000001101
[15] Overvoltage Lockout: ON
[14] Underload Shutdown: ON
[13] Overcurrent Shutdown: ON
[6] HS Switch 3: OFF
[5] LS Switch 3: OFF
[4] HS Switch 2: OFF
[3] LS Switch 2: ON
[2] HS Switch 1: ON
[1] LS Switch 1: OFF
[0] Status Register Reset: ON
===> Control input word: 1110000000001100
[15] Overvoltage Lockout: ON
[14] Underload Shutdown: ON
[13] Overcurrent Shutdown: ON
[6] HS Switch 3: OFF
[5] LS Switch 3: OFF
[4] HS Switch 2: OFF
[3] LS Switch 2: ON
[2] HS Switch 1: ON
[1] LS Switch 1: OFF
[0] Status Register Reset: OFF
<=== Status output word: 1110000000001101
[15] Supply Voltage Fault: ON
[14] Underload / Open Circuit: ON
[13] Overload / Short Circuit: ON
[6] HS Switch 3: OFF
[5] LS Switch 3: OFF
[4] HS Switch 2: OFF
[3] LS Switch 2: ON
[2] HS Switch 1: ON
[1] LS Switch 1: OFF
[0] Overtemperature Prewarning: ON
As you can see, I get back status showing that all fault/warning flags are on, but also that the commanded outputs are still on, which should be impossible if those faults are really occurring. What also confirms that this is nonsense data is that if I have no power supply voltage (separate from logic supply) turned on, it normally flags a "supply voltage fault" and keeps all outputs off, but in the problem scenario, it still tells me that outputs are on as commanded, when it patently will
never do that!
I've eliminated the following as causes:
- My SPI code, as problem also occurs when using the Arduino SPI library.
- Bugs in the function I'm using to print out the output status.
- The specific chip - swapped for another one, same issue.
- The period between asserting the chip's 'enable' line before SPI communication (in case, I dunno, it's not 'waking up' properly) - added a few ms delay, still problem.
Another oddity I discovered is when I have two driver chips, A & B, hooked up in parallel on the SPI bus - with A's CS on SS/PB2 and B's CS on, say, PB0. If I communicate with B first followed by A, I get the problem with B's status output. But if I reverse that order - A then B - then B's status output is fine.
So, the problem appears to be related to whether the chip's CS line is on the AVR's SS/PB2 pin or not, but also whether first SPI communication is with a device that
does have CS controlled by SS/PB2.
I'm flummoxed.
And I wish I had a proper multi-channel scope with SPI serial decode, so that I could at least determine whether this problem is perhaps some kind of register/memory issue on the AVR only, by verifying what is actually going over the MISO wire is the same as what is presented on SPDR in the micro.