ESC MK 2: F303 DRV8323SR Motor Controller

In last week’s post, I showed the design of a new motor controller I’ve been working on. This motor controller is better than my last one mostly just due to its elegant simplicity. It uses the DRV8323SR, a recently released chip by TI, which contains all six gate drives,  three shunt amplifiers, and even a buck converter into one 7mm square chip.

1. schematic

my 5-board 3pcb order came from china in a bigger 3pcb box than usual. Guess its not that big for 50 boards.


I sampled the 8323 from TI and also a ton of FETs from Nexperia. Both arrived speedily.


So, Thursday afternoon, it was time to start assembling! This board turned out to be the most painless board I’ve assembled in a long time. First I soldered on the micro. The 32 pin LQFP was super, super easy to solder on the reflow thing. I soldered on the caps on the back of the board and flashed an LED blink program. The micro programmed on the first try! Then I soldered on the DRV8323 chip as well as its associated passives. The 8323 is a 0.5mm pitch QFN package which sounds bad but turned out to be quite nice to solder. I nailed the amount of solder paste and the chip wicked into center. A few pins bridged and I touched those up with a normal iron under the microscope.


With the 8323 installed it was time to see if the chip would turn on. I opted to use the ‘S’ version of the chip, which programs over SPI. I’ve never used SPI before, so this part was a bit of an adventure. All of the guides on sparkfun show you a diagram of the levels on sck, miso, and mosi, but don’t show you how to actually program your own interface (ie, what do you do if there is no library for your chip). I started with just the mbed basic SPI master code which spit out pretty much garbage. I was very confused by the addresses and data of when which data was sent. I was able to read the fault register 1 (at address 0x00) and could trigger low voltage faults by simply turning down the power supply voltage. But I wasn’t able to read the status register 2 or any of the other registers. How do I SPI bayley??


After a while I figured out how everything works. All data is compacted into one 16 bit word. The master sends the first bit which is a read/write command, then send the next four which are address bits, then the next 11 bits are data which the master sends if writing or the DRV responds with if reading.

Here I am reading the status register 1: first bit is 1 for read, next four are 0001 for status register 1, then the DRV responds 11100000000 indicating overcurrent on the three current sensors, which made sense as the shunt resistors were not installed. Some other errors I ran into was that I needed to bring the CS high between words, and decrease the size of the pullup resistor on the MISO pin from 10K to 5K ohms as the rise time was really slow on 10K.

All running. Yellow is sck, blue is CS, and purple is MOSI.


mbed code:

void Init_DRV8323() {

drv_cs = 1;

spi.format(16, 1);
 en_gate = 1;
 en_gate = 0; //clear residual faults
 en_gate = 1;

 drv_cs = 1; wait_us(1); drv_cs = 0;
 int fault1 = 0;
 fault1 = spi.write((0x01<<15) + (0x00<<11)); //status register 1
 drv_cs = 1; wait_us(1); drv_cs = 0;

while ((fault1>>10) > 0) {
 fault1 = spi.write((0x01<<15) + (0x00<<11)); //status register 1
 pc.printf("Fault Detected!! 0x00=0x%X ", fault1);wait(2);
 drv_cs = 1; wait_us(1); drv_cs = 0;
 drv_cs = 1; wait_us(1); drv_cs = 0;
 spi.write((0x00<<15) + (0x02<<11) + (0x01<<5)); //set control register for 3x PWM
 //drv_cs = 1; wait_us(1); drv_cs = 0;
 //fault1 = spi.write((0x01<<15) + (0x02<<11));
 //pc.printf("DRV Setup 0x00=0x%X ",fault1);
 drv_cs = 1;
 //spi.write((0x00<<15) + (0x05<<11) + (0x03)); //set OCP register for 0.26v OCP
 //drv_cs = 1; wait_us(1); drv_cs = 0; //enable once bridge is working.


With the SPI running I soldered on the rest of the components. I accidentally put the wrong resistor divider on the buck converter and caught it by just turning up the power supply very slowly to see if it would hit 5v, which it did not, so then I realized I put the 12v resistors on and fixed my fault.


The layout worked out great: fets on the top, huge array of ceramic caps on the bottom. I also populated the power and indicator LEDs.


With all this guk installed I scoped the phases and a clock pin. Surprisingly, it even worked. The clock pin going high while the phase is low is good, it means that the current sensors will function. I also found the setting to bump up TIM1 to 144mHz, double the micro clock speed. I think the micro resonator is a bit off because the loop time is 17.7kHz instead of 20kHz. Guess I will have to install a crystal.


With this going I wrote some quick block commutation code and hooked her up to a good ol NTM prop drive. I installed some series resistors to keep the smoke at bay. AND IT EVEN WORKED.



Now for installation on the Version 9 skateboard.


The hall sensor wire had to be jumped directly to the 5v rail, in this case the input to the 3.3v linear regulator as I forgot to break out 5v anywhere else on this board. Also note the nice block of ceramics, and the nice busbar made by having long wires soldered to the pads.


Next up was restructuring a bit of code I wrote some time last month, really late at night. The Version 9 skateboard has only one hall sensor, designed to be used with an interpolator. I tested this one-hall-sensor-interpolator concept on my motor test rig and it worked beautifully. I programmed it to switch between encoder and interpolator at two second intervals and could not tell the difference between the two modes. Obviously the interpolator does not work when the motor is not rotating, but that is fine for skateboard duty. Guess some of the velocity estimator saga code was useful. Here is my one hall sensor setup on the old motor controller.


When I tested this on the skateboard, I got a lot of weird results. One weird thing was the timer would either be constantly held at either 0, 14, or just run freely. After a bunch of messing around I realized that the effects were a function of rotor position. Upon probing the hall sensor I realized that when the hall sensor went into high mode (open drain) my weak pullup resistor could not hold off the switching noise, especially because the hall sensor was inside the motors and the hall wires ran right along the motor wires. The switching noise was pulling the pin low and resetting the counter. Yellow is phase voltage, blue is hall output. You can see the switches bumping the output.


The solution was to turn on digital filtering, which removes noise spikes less than a specified width. This completely solved the problem.

Next up, spinning the skateboard motor. I was able to get the motor to spin just fine open loop voltage mode, but current mode refused to work for a couple days. It turned out that the scaling factor between ADC counts and amps had to be reversed- although both the DRV and my previous shunt amplifiers had a gain of 20, I had hooked them up backwards on my previous controller as mechanically they fit better that way. On this new correctly wired controller the negative constant caused the current loop to be completely unstable as effectively the feedback was positive instead of negative. Just changed this constant from -0.2 to +0.2 and got torque mode working just like that.


Next up, there really wasn’t that much else than to try and ride it. I installed a JST pin header and and wired it to a limit switch. I ran into some problems where the sudden application of torque would cause the DRV to fault, so I installed the electrolytic which helped the problem. However the problem did not completely fix itself so I used an averaging filter on the throttle. I took one last controller pic in case the controller exploded itself.


Time to ride it. I estimated the percent chance of explosion to be 20%.

I tested it in the hallway. Results? It works. And, it works really well.

Phase current 5 amps: I thought it was doing nothing until I realized I wasn’t slowing down. No painful jerk like Kimmy.

Phase current 10 amps: noticeable acceleration. Still very tame.

Phase current 25 amps: good acceleration. Tame at low speed but not slow: takes maybe 5-10 seconds to accelerate to at least 10mph (then I ran out of hallway). The torque curve is flat! It accelerates like a dream! I’ve never felt a nicer accelerating skateboard. Kimmy is rough, threatening to throw you off, but this thing just works great.

8 months of motor control work used for something real, and man does it feel good.

Next up: heat sinks, wireless control, faster switching, headlights!