This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

BOOSTXL-DRV8301: Phase Current measurement issue

Part Number: BOOSTXL-DRV8301
Other Parts Discussed in Thread: DRV8301, DRV8316, MOTORWARE, DRV8323
I have a BOOSTXL-DRV8301_REVB being used in a FOC project to drive a BLDC motor @ 7A max.  For some reason, it appears that phase currents sampled using ADC are dissimilar
It appears that current waveforms A, B, C have a time-varying and dis-similar DC offset (Different offset for 3 phases)
Even though the motor is running at a constant speed, the peak magnitudes of the phase currents keep changing along with the DC offset
 
The driver is configured with the CSA gain of 20V/V (A & B phases, internal) and 10V/V (hardware design for C phase, external). The Gain mismatch is compensated on the software side.  Current sense ADC sampling is conducted at the centre of the TOP FET OFF duration / Bottom FET ON duration. Formulae "Vout = (Vref/2) – G x Vshunt"  (from DRV8301 datasheet Pg. No. 16) is used to obtain phase currents with a Rshunt value of 10mOhm.

What could be the reason for this behaviour(like Vref ripple, Internal resistance drift due to ambient/onboard temperature, internal opamp offset/impedance drift or anything else) and solution to overcome this issue?. 
  • Madhan,

    Could you provide some waveforms showing the differences between the three CSA outputs highlighting the issues you mention above?

    Regards,

    -Adam

  • Hi Madhan,

    Are you running any sort of calibration routine before spinning the motor? Sometimes a calibration routine can reduce CSA offsets due to board variation, VREF ripple, temperature drift, etc. 

    Thanks,
    Aaron

  • Hi Adam,

    Thank you for the response!

    SOA, SOB, SOC(external) are sampled with ADC as mentioned previously and values are visualized using DAC output (2 channels).Yellow Trace - "Ia" & Green Trace - "Ib"

    Fig1. Yellow Trace - "Ia" & Green Trace - "Ib"

    Yellow Trace - "Ib" & Green Trace - "Ic"

    Fig2. Yellow Trace - "Ib" & Green Trace - "Ic"

    Yellow Trace - "Ic" & Green Trace - "Ia"

    Fig3. Yellow Trace - "Ic" & Green Trace - "Ia" 

    Regards,

    Madhan.

  • Hi Aaron,

    Thank you for the response!

    Initially, I wasn't performing any calibration procedure (both Hardware and Software). But as I encountered this issue, I wrote a "software" based offset and Gain correction routine which doesn't seem to provide good results. Yet to work on DRV8301's Hardware calibration procedure.

    Could you please provide brief or resource links, on how to exactly perform the Hardware calibration sequence (DRV8301 via SPI)? It would be a great help.

    Regards,

    Madhan.

  • Hi Madhan,

    You can use the DRV8301's hardware calibration method by either setting the DC_CAL pin high or setting Control Register 2 (Address 0x03) bits D5 and D4 to "1". (pg. 23 of DRV8301 datasheet).

    The calibration routine shorts the CSA's input pins and disconnects them from the load. It is best to run calibration when the MOSFETs are not switching. 

    Also, what is the nominal voltage of the motor? If the motor is 24V or less and is 7-A max peak current, we also recommend an integrated MOSFET + FOC solution currently out for evaluation called the DRV8316. It is an integrated FET BLDC driver up to 40-V max, 8-A peak current. 

    Thanks,
    Aaron

  • I have used SPI based driver for DRV8301 and tried to perform the calibration as a startup procedure (when there is no switching performed on inverter legs). But still, I can see similar results as mentioned earlier with varying offsets and DC shifts in all three phases (slightly different from previously mentioned results)

    Following is the code snippet being used to perform the startup calibration sequence.

    #define CSA_GAIN 10.0f
    #define R_SHUNT 0.01f
    #define CS_CAL_SAMPLES 100
    #define CS_CAL_ITERATION 30000

    enum {
    CS_CAL_INIT = 0,
    CS_CAL_RUN,
    CS_CAL_DEINIT,
    CS_CAL_COMPLETE
    };

    struct{
    uint8_t CsCalState;
    SWA_t csCal_Swa[3];
    uint16_t csADCraw[3];
    uint16_t CsCalOffset[3];
    uint16_t CsCalIteration;
    } adcStruct_t;

    adcStruct_t adcData;

    void ADC_init(){
    adc123Init();
    DRV8301 = DRV8301_Init(SPI2_Handle, GPIOC, GPIO_PIN_15);
    adcData.CsCalState = CS_CAL_INIT;

    }

    void CS_GetCurrent() {
    for (int i = 0; i < 3; i++) {
    adcData.VShunt_abc[i] = GET_V_MEASURED((float)(adcData.csADCraw[i] - adcData.CsCalOffset[i]))/(float)CSA_GAIN;
    adcData.Iabc[i] = adcData.VShunt_abc[i] / (float)R_SHUNT;
    }
    }

    void compute() { //function call from DMA transfer complete IRQHandler
    if (adcData.adc_complete[0] == 1 && adcData.adc_complete[1] == 1 && adcData.adc_complete[2] == 1) {

    if (adcData.CsCalState != CS_CAL_COMPLETE)
    CS_Cal();
    else{
    CS_GetCurrent();
    pwmIRQ(); //function call to perform High level code execution
    }

    adcData.adc_complete[0] = 0;
    adcData.adc_complete[1] = 0;
    adcData.adc_complete[2] = 0;
    }
    }


    void CS_Cal_Init(){
    for (int i = 0; i < 3; i++) {
    slidingWindowAverageInit(&adcData.csCal_Swa[i], CS_CAL_SAMPLES);
    adcData.CsCalOffset[i] = 0;
    }
    DRV8301_setDcCalMode(DRV8301, DRV8301_ShuntAmpNumber_1, DRV8301_DcCalMode_Ch1_NoLoad);
    DRV8301_setDcCalMode(DRV8301, DRV8301_ShuntAmpNumber_2, DRV8301_DcCalMode_Ch2_NoLoad);
    adcData.CsCalIteration = 0;
    adcData.CsCalState = CS_CAL_RUN;
    }

    void CS_Cal_Run(){ //continuously called from timer interrupt
    if (adcData.CsCalIteration < CS_CAL_ITERATION) {
    for (int i = 0; i < 3; i++)
    adcData.CsCalOffset[i] = (uint16_t)slidingWindowAverage(&adcData.csCal_Swa[i], (uint32_t)adcData.csADCraw[i]);
    } else if (adcData.CsCalIteration > CS_CAL_ITERATION)
    adcData.CsCalState = CS_CAL_DEINIT;
    adcData.CsCalIteration++;
    }

    void CS_Cal_Deinit(){
    DRV8301_setDcCalMode(DRV8301, DRV8301_ShuntAmpNumber_1, DRV8301_DcCalMode_Ch1_Load);
    DRV8301_setDcCalMode(DRV8301, DRV8301_ShuntAmpNumber_2, DRV8301_DcCalMode_Ch2_Load);
    adcData.CsCalState = CS_CAL_COMPLETE;
    }

    void CS_Cal() {
    switch (adcData.CsCalState){
    case CS_CAL_INIT: CS_Cal_Init(); break;
    case CS_CAL_RUN: CS_Cal_Run(); break;
    case CS_CAL_DEINIT: CS_Cal_Deinit(); break;
    }
    }

    (Sorry couldn't insert as Code snippet due to plugin access error)

    Scope Shots after performing Calibration:

    Fig1. Yellow Trace - "Ia" & Green Trace - "Ib"

    Fig2. Yellow Trace - "Ib" & Green Trace - "Ic"

    Fig3. Yellow Trace - "Ic" & Green Trace - "Ia" 

    PS: I came across some strange lines of codes in drv8301.c. (file from C:\ti\motorware\motorware_1_01_00_18\sw\drivers\drvic\drv8301\src\32b\f28x\f2806x) , Instead of masking the bits, they are cleared which always returned default/0 state values.

    After replacing these lines from

    // clear the bits
    data &= (~DRV8301_.............);

    to this

    // mask bits
    data &= DRV8301_...............;

    I got the return value, that I assigned through SPI.

    Suspected code lines: 102,168,183,198,213,228,243,258 and seems to be correct in line154

    Please correct me if I have understood wrongly.

    Also due to a change in the usage of motors to be tested, trying to avoid FET integrated type driver, rather planning to make use of DRV8323RS boost-xl as an alternative if this issue persists.

    But still, for your reference, current motor specifications are Vnom:16V | Imax: 7A | PolePair: 14.

    Thanks and Regards,

    Madhan.

  • Madhan,

    Unfortunately we cannot review code snippets on the forum.

    Alternatively we would be happy to support your transition to DRV8323 since this is a much newer and fully featured device which should be much easier for you to use.

    Regards,

    -Adam

  • Hello Madhan,

    Do you have any additional feedback on this thread?

    Thanks,

    Matt

  • Hello Madhan,

    I'm going to close this topic, feel free to come back and ask a new question!

    Thanks,

    Matt