Congratulations on your well written question loaded with information.
The answer to your question is in the opamp's datasheet:
MAX4352/MAX4353/MAX4354 are compensated for a minimum closed-loop gain of +5V/V
Your schematic sets the MAX4354 opamp for unity gain at HF via the feedback capacitors (C31 and the rest). Therefore it will oscillate, this is inevitable.
The fix is to remove all the 150pF caps.
Now, the amplifier will still be unstable, as explained in datasheet page 11 "Choosing resistor values". You really don't want a 10k feedback resistor on such a fast opamp, this will create a pole with the input capacitance, let's say 3pF or so including trace capacitance. This adds phase lag into the feedback, which will eat into the phase margin and either make it oscillate or screw up transient response and settling time, which I presume are important to you since you chose this fast opamp for a reason!
Considering the motor currents involved, you're not saving milliamps on the opamps' power supply, so you need lower feedback resistors. Try 1k/100R instead of 10k/1k.
Problem is, all the extra traces and pads for your unnecessary capacitors do add parasitic capacitance, so put the feedback resistors in whatever SMD footprint is closer to the IC (which will probably be the caps) and cut the traces to the unused footprint.
If it still gives you trouble, don't do another board revision yet. Just solder the feedback resistors across the MAX4354 pins, and cut more unnecessary traces to reduce capacitance. With 0402 resistors this should work just fine. If this gets your opamp rock stable, then you know your next board revision should have the resistors R33 and R24 (and their equivalents for the other opamps) as close to the pins as possible with minimum length traces.
But it will still suck on transient response, maybe ring, because the opamps are driving capacitive loads, which are the long traces to the microcontroller. I would add 15R to 33R resistors at the opamp outputs.
You could even use lower feedback resistor values, although the LM358 might start to bitch a little.
LM358 is a old piece of crap with crummy slow transient response. Your fast MAX4354 is drawing steep current pulses from its output. Output impedance of LM358 at high frequencies is "mmeeeehhhh" because it has 1MHz bandwidth.
Therefore ADC_MID is likely to move around. The fix is to have a look at the internal schematics of LM358 (datasheet page 13), notice how the compensation is wired, and stick a resistor between the output and ground (like 470R) to bias the output stage into class-A, which will lower its output impedance and make it faster.
If this is not enough and you notice transient variations on ADC_MID,
stick a big fat low-ESR cap right across the output of LM358, like 470µF 6.3V Panasonic FR which costs 9c and has 80 mOhms ESR. Or even a polymer cap. Opamps driving capacitive loads will be stable if the cap is large enough.
- Increase bypass cap values from 100nF to 1µF
- L2 will resonate with C42, download L2 spice model from murata simsurfing website, spice it, then replace C42 with cheap 105°C electrolytic with suitable ESR like Panasonic FC 100µF.
- Stick 1-2 MLCC in parallel with C26 right at the output of the switcher U4 to shunt HF noise at the source and reduce noise in your GND.
- Liberally spray the +24V rail with 100nF MLCCs, 1-2 per MOSFET, put them right next to the FET, you want to have a tight loop for the FET's HF switching currents.
- Bootstrap diodes D1 D3 D4 can be replaced by smaller cheaper and more important, lower capacitance models.
- I don't know how your micro handles its internal ADC reference, whether it needs to be bypassed by a cap, or if it has separate AVCC pin, you should check
- R20 is a problem as it prevents you from shrinking the high di/dt current loops by returning currents from the other sense resistors to the GND pin of the three big capacitors. Thus, EMI. Since R20 provides a measurement which is redundant (it is the sum of the three currents which are already measured) it can be removed along with associated circuitry.
- This frees up an opamp which can now be used instead of LM358. It is not stable at unity gain though, so a little trickery is needed in the feedback network.
- The FET driver should be in the center of the board (there is an empty space) next to the FETs, which reduces the length of the gate traces, which reduces LC oscillations, which allows you to get rid of the zeners, you save money. Also this cuts crosstalk between the MCU PWM traces and the analog current measurement traces. Also this removes the gate drive traces which cut a large swath of the bottom ground plane out.
- Remove ground pour under micro or tie it down to ground plane with many vias. The main use of ground pours on toplayer is to make you forget to put a dedicated GND via for a component that really needs one (like that AGND pin) and increase noise. Ground pours are evil since they connect that sensitive AGND pin to the noisy GND pin of a decoupling cap. Ground pours on toplayer need to die.
- Add more vias, 2 GND vias per decoupling cap reduces inductance.
- The 2 slot antennas in the ground plane may be a problem
- Your opamps are wired as differential, the GND side of the sense resistor should be taken at the resistor, not at whatever potential GND is under the opamp. Thus, route the sense lines as a differential pair. Your CAD software
will want to connect your "GND" trace to the rest of the GND, so use a net tie, which is a virtual component allowing you to do this.
- The micro's ADC measures voltage in proportion to its internal ADC reference (is it the power supply? a VREF pin? check datasheet on how to handle this).
- ADC_MID is generated from a +3V3 which is not really the same as the micro's, so there will be an offset. This is solved by sampling the currents in the MOSFETs which are not turned on, which gives you the offset, and substracting in software. Time your ADC sampling points with your PWM. Your micro should know how to do this.
- C37 is a MLCC thus piezoelectric, ADC_MID will respond proportional to vibration and board flex. Also C37 value 100nF is too low. Use electrolytic cap instead.
- and most important, your ADC measures voltage relative to ITS OWN GROUND. Which is why R20 is trouble, as it routes the motor current all over the ground, destroying its integrity. The bottom pins of R44/C37 should sample the GND at the micro's AGND pin to fix this. Capacitor at the output of LM358 (if any) should also be grounded near this point.
- You have no height restriction, so tantalum caps are not your friend, in fact they are expensive little firebombs, good thing you don't use any. But aluminium caps are not obsolete! There is nothing wrong with putting a few on your board to stiffen up your +5, +15, +3v3 supplies. I like Panasonic FC, FM, FR, they're 105°C, very tough, small, cheap, reliable, with ESR low enough to offer superb decoupling performance, but still high enough to make your LDOs stable and not ring with MLCCs. Polymer caps ESR is too low, which is problematic, as they will ring with MLCCs and do evil things to LDOs, polymer caps need to be handled with care.
FYI by following these rules I did a board with 4 switchers, 1 micro, 1 H-bridge, everything switching all over the place, and I got less than one ADC LSB noise on the current sense resistor.