DRV8323 and STM32G431 Prototype Schematic Review

Hello SimpleFOC Community,

I’m working on a new motor driver with the main goals of medium current capability without needing cooling, and small board size of 30x50mm. I also want to experiment with reducing power losses in the current sensing by using the MOSFET RDS(on) to measure the current, inspired by the DRV8316.

I’ve included a XT30 connector for power and MR30 for the motor, and everything else uses JST GH connectors for maximum user friendliness. The board includes 600uF of capacitance so no external ones are needed, and the total height of everything is 7mm. The input voltage range is 12-25V, and the maximum continuous output current is 15A.

I’d like someone to have a look over my schematic and calculations to make sure I haven’t made any silly mistakes, and any feedback would be appreciated.

Driver:

MCU:

Power & Communication (It’s a bit messy I know):

STM32CubeMX Pin Assignments:

The VCP and CPH-CPL capacitor values in the schematic are higher than values suggested by the datasheet, this is because of capacitor derating. The 2.2uF is a GRM155R61E225KE11D and 100nF is a GRM155R71H104KE14D. When you apply the derating due to DC bias at operating voltage (which you can find on the manufacturer website), the effective capacitances reduce to around 1uF and 47nF which is the recommended value in the datasheet.

The sensor I am using is a sin/cos encoder which is connected to the ADC, but I also want compatibility with incremental encoders, so the sensor pins also have comparators attached where the output will be internally redirected to TIM3 in encoder mode.

The MOSFET I am using is the BSZ0901NS. The RDS(on) varies between 1.7 milliohms at 25C and 2.7 milliohms at 150C. To compensate for this I will use the internal temperature sensor of the STM32 and a look up table to look up the effective gain of the amplifier based on the temperature. The PCB is 6 layers with 2oz copper on all layers, to improve heat transfer between the MOSFETs and the STM32 to ensure good accuracy of the temperature readings.

I will be running 50KHz PWM with Space Vector Modulation, pulled to GND to reduce switching losses. The current will be measured using 2 phases chosen on the fly (based on longest low side FET on time). Using center aligned PWM, I calculated the minimum on time of the low side FET to be 1.34us in the worst case where the MOSFET turns on immediately in the next switching cycle. The datasheet mentions that the current sense amplifier turns on after the 500ns Tdrive time when using RDS(on) sensing.

So the time is takes for the current sense output to become valid after the falling edge of the PWM is: 150ns (propagation delay) + 100ns (fall time of HS FET) + 50ns (dead time) + 500ns (Tdrive, including rise time of LS FET) + 600ns (CSA settling) = 1400ns. This means the current must be sampled 60ns after the start of the next PWM cycle. Since the propagation delay is 150ns, the low side FET will not turn off before then, and so the current will still be valid. This means the margin of error is only 90ns.

I will be using custom firmware for these advanced features so it is not a problem if they are not supported by SimpleFOC yet. But I still want to maintain compatibility with SimpleFOC where possible.

I’ve almost finished designing the PCB, so hopefully I haven’t make any mistakes or oversights that require a significant redesign.

Thanks,
Andrew

You can shift the sampling point with cc4.

What do you mean by cc4? I haven’t heard of that before. Would you be able to provide a link or explanation of how this works?

You can enable channel 4 of tim1 or tim8, set it’s duty cycle, and use it as a trigger for adc.
Here is an experiment I did:

I’ve finished the PCB design, and if anyone wants to have a look or give feedback the easyeda link is here.

Final PCB size including connectors is 29x46mm.


1 Like

Hey Andrew, this looks like a very nice design!

I’ll do my best! It looks quite well thought out on the whole.

Some quick comments on debugging and interfacing:

  • you have some free MCU pins. Why not include a couple of user-controllable LEDs? Cost is almost 0, and in my experience they are very valuable for debugging, especially once the controller is installed in its final home.

  • SWD programming: why not include a standard ARM-14 header? This connects directly to your ST-Link V3 (also V3 mini) using the standard cables supplied with it. it includes the NRST and TARGET_VCC lines which you also need, and it can carry a USART (serial port) signal which is then automatically available on the PC using the ST-Link’s VCP (virtual com port) feature.
    image

  • Which brings me to my next point: do yourself a favour and include a serial port. I2C is nice, as is CAN, but you’ll have a 1000x times easier time bringing this board up if you have serial for debugging. Since you don’t include USB in favour of CAN (a fine decision) I would use a normal USART and route it to the ST-Link header as described above.

  • I2C: the SCL signal is on BOOT0 - this is undesirable since you need to pull this line up for I2C but down for regular booting. Pulling it up will make the chip enter boot loader mode, and not run your code. You can fix it using fuses in the STM32’s low level configuration, but this can be inconvenient (if your code is crash-looping and you need the boatloader mode) and complicates board-bringup. Why not switch the SCL signal over to PA15, you’re not using it anyway, and leave BOOT0 to be used in the normal way?

  • I2C connector: why not change it to use a JST-SH 1.0 4 pin connector in the following configuration:
    image
    This would be compatible with the widely used Stemma/QT/Qwiik standard and open the door to 100s of I2C based peripherals you could just plug in.
    Connecting I2C_VCC directly to the connector from pin PF1 - I’d check into this very carefully. Not all the STM32 pins are equal, and the PF1 is normally for the oscillator. And powering the I2C device from a MCU pin doesn’t sound like the best idea to me. I’d either connect this pin to VDD, or connect it to VDD via a jumper (the idea being that when I2C is used for a device, then supply power, but when I2C is used in slave mode to control the motor driver, you can disconnect the power)

  • I2C: I don’t see the pull-ups? Generally I include I2C pull-ups, at least optionally via jumpers but usually just directly connected (you can always leave off the resistors if you don’t want them). Note: the internal pull-up are generally too weak for I2C.

  • SENSOR_VCC: same note as for I2C_VCC - personally I would never use a MCU pin to power anything, except maybe a small LED through a resistor I chose as part of the design. Certainly I wouldn’t supply an external port’s power from the MCU. Some sensors need quite a bit of power… For situations like this I use a small P-FET which I can switch from the MCU, but the question is whether the sensor actually needs to be switched at all?

  • CAN bus: the schematic is quite dense :slight_smile: but I don’t think you have termination for the CAN-bus? Nor the recommended common mode choke:

Including the termination with a resistor and a jumper costs next to nothing and makes the board more convenient to use. Of course you can also jam a 120Ω through hole resistor into the connector, but its not quite as elegant :slight_smile:

Some other comments:

  • VBUS sensing:

image

I generally put a small low pass filter here, you’re not using this signal for fast sensing, right?

image

It’s probably not needed, but just to give the MCU pin a little more protection from the input voltage.

  • Oscillator: not having an external oscillator makes your design subject to the timing inaccuracies of the internal clock. Personally, I haven’t tested the differences, but then I almost always include an external oscillator. Since I generally don’t implement sleep modes I don’t bother with the low speed oscillator, but I do include the HSE, usually in the form of a single pin clock-source rather than a crystal. Users who have compared the two have found performance (stability of measurements) to be improved by the external clock, which is generally more accurate by an order of magnitude or more.
    Since you mention needing very precise timings for your current sensing tests, it may be something to consider.

Ok, if I find time later on this evening I will look into the components a little more also and send some more comments :slight_smile:

1 Like

SWO pin can also be nice to have for debugging.

1 Like

Hi Runger,

Thanks for the feedback. I’ve already included 2 user controllable LEDs, they are in the bottom left corner of the board, when the XT30 connector is facing upwards. Regarding the SWD programming, the reason I don’t include a ARM-14 header is because it would be too tall (5.2mm) and too big when I am aiming for the smallest possible profile. Currently the tallest component on the board is the XT30 connector, with a height of 5mm.

Currently I find myself quite satisfied with the 2 wire SWD experience, I never find myself needing the functionality of the SWO pin or the Virtual COM port, being able to set breakpoints and having live expressions is enough for me. My previous motor driver also used only 2 wires for SWD, and I never had any issues developing custom FOC firmware on it. Regarding the nRST pin, it is actually connected to the onboard button, but it can be repurposed as a GPIO if needed.

The I2C port is reconfigurable for UART as well, it is just not labeled as a UART port because I hate UART, the TX and RX pin swapping is so confusing. The BOOT0 pin is always set to boot from flash using the option bytes, this is OK for me as the SWD pins are dedicated meaning I can always connect my debugger to fix any crash loop issues that pop up. It’s possible to switch the I2C signal to PA15 but I’d prefer to keep it on PB8 because it makes routing the PCB easier. The I2C pullups are obviously not here because of this, and I intend to have them on the master side anyway. Same goes for the CAN bus termination resistors, since there will be many motor drivers on the same bus, I plan to solder the resistor onto the cables and wrap them with heat shrink. This also means hot plugging will be possible.

Regarding the I2C connector, changing it to JST SH is a good option which I will need to carefully consider, but my experience with JST SH is that it is really hard to tell when it has been plugged in properly, and it is not a locking connector with that nice clicky feeling. STM32CubeMX tells me it is fine to use PF1 as a GPIO output. The I2C connector and the CAN bus connector are only intended for communication with the main controller which will send commands to the motor driver, so I’m not too concerned about the ecosystem, but it would be nice for it to work with I2C hubs.

Regarding jumpers, if you mean physical jumpers then there is no space, and if you mean solder bridges then I would prefer not having to get out the soldering iron to change board settings, and there is a durability concern as you could rip out a pad when trying to solder the jumper.

The BUS_VOLTAGE pin will be used for fast sensing, to ensure I don’t accidentally cause an overvoltage on the power supply when doing regen braking. It is connected to an onboard OPAMP (as buffer) which removes the need for a capacitor on the pin. It’s also connected to the onboard comparator in case I want to go that route. The 30V rating of the MOSFET will be exceeded (and it will go into breakdown, clamping the voltage) before the 4V max of the GPIO pin is exceeded, so I don’t feel that overvoltage on this pin is a big concern, and even if it somehow happens the internal ESD diodes will clamp it. I went looking for a random 3.3V TVS diode and found the PESD5Z3.3-Q, it seems to have a minimum breakdown voltage of 5V which is higher than the absolute maximum of the GPIO. Other diodes I’ve found seem to have similar ratings, therefore I don’t think a TVS will be very effective at protecting the GPIO.

The internal oscillator of the STM32 is rated for 1% accuracy, which I have found to be sufficient. I have used an external oscillator before and personally noticed no difference between the two. 1% oscillator accuracy is good enough for my current sensing timings and it leaves plenty of margin (max error on current sense timings due to oscillator inaccuracy is 13ns). I’m more concerned about the timings of the current sense amplifier in the gate driver. Also the oscillator pins have been used for another purpose so I can’t add it even if I wanted to due to routing constraints.

Regarding the common mode choke for CAN, I have not used then before and are not too familiar with them. Could you provide a part number?

I have added a MOSFET to the I2C_VCC and SENSOR_VCC so it will support higher current sensors, and possibly power an ESP32 through I2C_VCC, allowing for more use cases. Thanks for that suggestion. The sensor needs to be switched because it consumes 5mA, which is within the range supported by the GPIO but I want a low shut down current, in case I want to enable sleep mode, or for battery undervoltage shutdown.

Any chance you’d be willing to share the code you are using to communicate with the DRV8323S via SPI?