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.

How to drive the VR on DRV8301-RM46-KIT board

Other Parts Discussed in Thread: MOTORWARE, DRV8301

Hello, everyone,

I have a DRV8301-RM46-KIT board as the http://www.ti.com/tool/drv8301-rm46-kit,

Now there is no any information about the VR on this board for controlling motor speed.

Has anyone can help me or give me some-piece C codes to drive this VR?

Now I have migrate the SRM sensorless control codes in the old DSP TMS320F240, existing in title : "Developing an SRM Drive System Using the TMS320F240" or "http://www.ti.com/lit/an/spra282/spra420.pdf",

Can I post the source code on this forum?

I need the further support to develop this SRM driver.

Thanks.

  • Hi Richard,

    Sorry for the delay in responding.  I will ask one of our engineers with experience with this board to respond.  I am not aware of our motorware code controlling the VR.

  • The VR is connected to the AD1IN16 and AD2IN0 pin of the MCU. If you want to use VR to control speed, please add either this channel to the ADC conversion, normalize the ADC conversion result (e.g. x (1/4096)). Then, use the normalized result as the speed reference.

    In the software attached to the kit, we did not implement this feature.

    Regards,

    Haixiao

  • I have written the some pieces code as follow:

    First, modifying the sys_startup.c

    //Prototyping

    #pragma INTERRUPT(adc1Group0Interrupt, IRQ)
    void adc1Group0Interrupt(void);
    #pragma INTERRUPT(adc2Group0Interrupt, IRQ)
    void adc2Group0Interrupt(void);
    #pragma INTERRUPT(adc2Group1Interrupt, IRQ)
    void adc2Group1Interrupt(void);
    #pragma INTERRUPT(adc2Group2Interrupt, IRQ)
    void adc2Group2Interrupt(void);

    #pragma INTERRUPT(VRGetDataISR, IRQ)

    void VRGetDataISR(void);

    //Assign the 0-pin for capturing the VR data.

    WORD  VR_a2d_chan=0;

    //Add ISR functions into the table

    static const t_isrFuncPTR s_vim_init[] ={

    ...


    &VRGetDataISR,
    &adc1Group0Interrupt,
    &adc1Group1Interrupt,
    &adc1Group2Interrupt,
    &adc2Group0Interrupt,
    &adc2Group1Interrupt,
    &adc2Group2Interrupt,

    ...

    }

    //function body

    WORD VR_a2d(int a2d_chan)
    {
        adcData_t adc_data;
       adcData_t *adc_data_ptr = &adc_data;

    /** - Start Group0 ADC Conversion event trigger
    * Select Channel_B ADC-B0 -
    * adcStartConversion_selChn(adcREG1, Ambient_Light_Sensor, 1, adcGROUP1);
    */

        adcResetFiFo(adcREG2, adcGROUP0);


    //adcStartConversion_selChn(adcBASE_t *adc, unsigned channel, unsigned fifo_size, unsigned group);


        adcStartConversion_selChn(adcREG2, a2d_chan, 1, adcGROUP0);


        adcEnableNotification(adcREG2, adcGROUP0);
    /** - Wait for ADC Group0 conversion to complete */
      while(!adcIsConversionComplete(adcREG2, adcGROUP0));

    /** - Read the conversion result
    *
    */
        adcGetSingleData(adcREG2, adcGROUP0, adc_data_ptr);


       adcDisableNotification(adcREG2, adcGROUP0);


       return((WORD)adc_data_ptr->value);
    }

    void VRGetDataISR(void)
    {
       #define Scale 1/4096
       float tmp;
       tmp=VR_a2d(VR_a2d_chan);
      drv.VoltVR=(tmp)*(Scale);
    }

    //second, modifying the drv.h

    add the "float32_t VoltVR;" to "typedef struct _DRV_Obj_"

    //main function

    void start_background()
    {
        VRGetDataISR();


               while(1)

                {

                ...

               }

    }

    main()

    {

    //all initial conditions are defined here and  into background service.

    start_background();

    }

    /////////////////////////////////////////////////////////////////////////////////////////////////

    Will be worked?

  • About the normalized factor, has any datasheet appeared?

    Where can I find this information?

    Thanks.

  • adcEnableNotification(adcREG2, adcGROUP0); this function enables the interrupt of ADC2 Group0, I dont think you need that because you are polling the flags. And you dont need the  adcDisableNotification

    See the VR output will be [0 3.3v], that is exactly our control card ADC's Vrefhi and Vreflo, our ADC is a 12 bit ADC, the

    Digital Value = 4096 x (Vin - Vreflo)/(Vrefhi-Vrelo). Assume you want to normilize the speed to 1, 4096 is the factor.

    Regards,

    Haixiao

  • Here I need an external event trigger (Voltage is changed) to make one-shot ADC conversion, not implement to do a polling.

    I think that

    adcEnableNotification(adcREG2, adcGROUP0);  adcDisableNotification are the paired and 

    make this ADC start and stop by an external event trigger (VR changes).

    Is it right?

    Thanks.

    The codes have changed as the following: 

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    //In the sys_startup.c

    #pragma INTERRUPT(VRGetDataISR, IRQ)
    void VRGetDataISR(void);

    #pragma INTERRUPT(adc1Group0Interrupt, IRQ)

    void adc1Group0Interrupt(void);

    #pragma INTERRUPT(adc2Group0Interrupt, IRQ)
    void adc2Group0Interrupt(void);

    #pragma INTERRUPT(adc2Group1Interrupt, IRQ)
    void adc2Group1Interrupt(void);

    #pragma INTERRUPT(adc2Group2Interrupt, IRQ)
    void adc2Group2Interrupt(void);

    static const t_isrFuncPTR s_vim_init[] =
    {
    &phantomInterrupt,
    &esmHighInterrupt,
    &phantomInterrupt,
    &phantomInterrupt,
    &phantomInterrupt,
    &rtiCompare2Interrupt,
    &phantomInterrupt,
    &phantomInterrupt,
    &phantomInterrupt,
    &phantomInterrupt,
    &gioHighLevelInterrupt,
    &phantomInterrupt,
    &phantomInterrupt,
    &phantomInterrupt,
    &phantomInterrupt,
    &phantomInterrupt,
    &VRGetDataISR,

    &adc1Group0Interrupt,

    &adc1Group1Interrupt,
    &adc1Group2Interrupt,
    &adc2Group0Interrupt,
    &adc2Group1Interrupt,
    &adc2Group2Interrupt,

    ...

    }

    ////////////////////////////////////////////////////////////////////

    void IntMasterIRQEnable(void)
    {
    _enable_IRQ();
    return;
    }

    void IntMasterIRQDisable(void)
    {
    _disable_IRQ();
    return;
    }


    WORD VR_a2d(int a2d_chan)
    {

    //See the VR output will be [0 3.3v], that is exactly our control card ADC's Vrefhi and Vreflo, our ADC is a 12 bit ADC, the
    //Digital Value = 4096 x (Vin - Vreflo)/(Vrefhi-Vrelo). Assume you want to normilize the speed to 1, 4096 is the factor.
    adcData_t adc_data;
    adcData_t *adc_data_ptr = &adc_data;
    /** - Start Group0 ADC Conversion event trigger
    * Select Channel_B ADC-B0 -
    * adcStartConversion_selChn(adcREG1, Ambient_Light_Sensor, 1, adcGROUP1);
    */
    //adcEnableNotification has start up in the void eventmgr_init(), remark this function here
    //Event trigger mode : adcGROUP0
    //adcEnableNotification(adcREG2, adcGROUP0);
    adcResetFiFo(adcREG2, adcGROUP0);
    //adcStartConversion_selChn(adcBASE_t *adc, unsigned channel, unsigned fifo_size, unsigned group);
    adcStartConversion_selChn(adcREG2, a2d_chan, 1, adcGROUP0);

    /** - Wait for ADC Group0 conversion to complete */
    while(!adcIsConversionComplete(adcREG2, adcGROUP0));

    /** - Read the conversion result
    *
    */
    adcGetSingleData(adcREG2, adcGROUP0, adc_data_ptr);


    return((WORD)adc_data_ptr->value);
    }

    void VRGetDataISR(void)
    {
    //The VR is connected to the AD1IN16 and AD2IN0 pin of the MCU. If you want to use VR to control speed,
    //please add either this channel to the ADC conversion, normalize the ADC conversion result (e.g. x (1/4096)).
    //Then, use the normalized result as the speed reference from TI (Haixiao Weng)
    #define Scale 1/4096
    float32_t tmp;
    tmp=VR_a2d(VR_a2d_chan);
    DlogCh5=(tmp)*(Scale);
    drv.VoltVR=(tmp)*(Scale);
    }

    void eventmgr_init()
    {
    int i=0;
    IntMasterIRQDisable();
    swi_disable_irq();
    /*The following setting are for Hercules RM46 core* and moved from the sys_main.c*/
    _mpuInit_();
    systemInit();
    (*(volatile unsigned int *)(0xFFFFEA38))=0x83E70B13;
    (*(volatile unsigned int *)(0xFFFFEA3C))=0x95A4F1E0;
    (*(volatile unsigned int *)(0xFFFFEB88))=0x00000002;//ADC Alternate Trigger
    //enable all ePWM s + TZ + ECAP1,2,3,4 + EQEP1+EQEP2
    *(volatile unsigned int *) 0xFFFFEBA4 = 0x01010102; // Enable TBCLK 37[1]
    *(volatile unsigned int *) 0xFFFFEB10 = 0x08010801; // nTZ1 0[19], nTZ2 0[27],
    *(volatile unsigned int *) 0xFFFFEB18 = 0x04010110; // ETPWM1A 2[26], EQEP2I 2[4]
    *(volatile unsigned int *) 0xFFFFEB1C = 0x01040101; // ETPWM1B 3[18]
    *(volatile unsigned int *) 0xFFFFEB20 = 0x20200104; // ETPWM2A 4[2], EQEP2A 4[21], EQEP2B 4[29]
    *(volatile unsigned int *) 0xFFFFEB24 = 0x01080404; // ETPWM2B 5[2], ETPWM3A 5[10], ETPWM3B 5[19]
    *(volatile unsigned int *) 0xFFFFEB2C = 0x01040101; // ETPWM5A 7[18]
    *(volatile unsigned int *) 0xFFFFEB30 = 0x01040104; // ETPWM5B 8[2], ECAP1 8[18]
    *(volatile unsigned int *) 0xFFFFEB34 = 0x01010801; //EQEP1B 9[11], SPI3CS0/EQEP1I 9[16/19]
    *(volatile unsigned int *) 0xFFFFEB40 = 0x20100101; // ECAP4 12[20],ECAP5 12[29]
    *(volatile unsigned int *) 0xFFFFEB40 = 0x04010101; // ECAP6 13[26]
    *(volatile unsigned int *) 0xFFFFEB54 = 0x01010110; // nTZ3 17[4]
    *(volatile unsigned int *) 0xFFFFEB5C = 0x01010801; // EQEP2S 19[11]
    *(volatile unsigned int *) 0xFFFFEB60 = 0x01100101; // EQEP1S 20[20]
    *(volatile unsigned int *) 0xFFFFEB7C = 0x01010104; // ETPWM4A 27[2]
    *(volatile unsigned int *) 0xFFFFEB94 = 0x01010102; // ETPWM4B 33[1], SPI3SOMI/ECAP2 33[8/10], SPI3SIMO/ECAP3 33[16/18],SPI3CLK/EQEP1A 33[24/26]
    *(volatile unsigned int *) 0xFFFFEB98 = 0x01020201; // ETPWM6A 34[9], ETPWM6B 34[17]
    *(volatile unsigned int *) 0xFFFFEB8C =0x01010102;//SRC=110, A2 31[1]
    (*(volatile unsigned int *)(0xFFFFEA38))=0x0;
    (*(volatile unsigned int *)(0xFFFFEA3C))=0x0;
    /**Enable IRQ and FIQ interrupt in Cortex R4 */
    swi_enable_irq();
    IntMasterIRQEnable();// initialize the driver

    // Enable the peripheral interrupt notifications
    gioEnableNotification(0);
    gioEnableNotification(1);
    // @param[in] adc Pointer to ADC module:
    // * - adcREG1: ADC1 module pointer
    // * - adcREG2: ADC2 module pointer
    // * - adcREG3: ADC3 module pointer
    // @param[in] group Hardware group of ADC module:
    // * - adcGROUP0: ADC event group
    // * - adcGROUP1: ADC group 1
    // * - adcGROUP2: ADC group 2
    adcEnableNotification(adcREG1, adcGROUP0);
    adcEnableNotification(adcREG1, adcGROUP1);
    adcEnableNotification(adcREG1, adcGROUP2);
    adcEnableNotification(adcREG2, adcGROUP0);
    adcEnableNotification(adcREG2, adcGROUP1);
    adcEnableNotification(adcREG2, adcGROUP2);
    // Drop into main while loop
    drv.ADC_INT_ENA=1;
    /** - Configure NHET for PWM application */
    hetInit();
    /* - Stop all pwm (0- 7) channels */
    for(i=0; i<8; i++){
    pwmStop(hetRAM1,i);
    // enable pwm interrupts
    pwmEnableNotification(hetREG1,i,pwmEND_OF_PERIOD);
    }

    }//EOF eventmgr_init()

    //main function

    void start_background()
    {
        VRGetDataISR();


               while(1)

                {

                ...

               }

    }

    main()

    {

    eventmgr_init();

    start_background();

    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Further question1:

    The gate enable of the 8301 driver is located at GPIO35/51 and has to be set a high level logic (EN_GATE==High).

    #define gioREG ((gioBASE_t *)0xFFF7BC00U)

    #define gioPORTA ((gioPORT_t *)0xFFF7BC34U)

    #define gioPORTB ((gioPORT_t *)0xFFF7BC54U)

    Which port can I  enable this gate?

    Further question2:

    There are three LEDs on the board,

    GPIO-12 LED-1 User LED
    GPIO-15 LED-2 User LED
    GPIO-22 STATUS User LED

    How can I start and stop these LEDS?

    Thanks.

  • If you look into the adcEnableNotification, what it did "adc->GxINTENA[group] = notif;" is to enable the interrupt. That is all. In your case, since you have to use ADC to read some current or voltage feedback, suppose it is triggered by the the PWM. You can use the same PWM to trigger this VR ADC channel too. To do this:

    1) set up the hardware trigger (link the ADC group number to the pwm trigger, in the motorware release, part of this is done in main - pin mux, part is done in the adcInit)

    2) Write the channel into the channel select register (link the ADC channel to the ADC group, in the motorware release, it is done by calling adcStartConversion)

    3) enable the interrupt (call adcEnableNotification)

    Then, you can check the ADC value in the interrupt routine.

     

    GPIO 12 - MCU GIOA3

    GPIO15 - MCU GIOA0

    GPIO22 - EQEP2S, HET30

    YOu can control through these MCU pin.

    En_Gate is collected to GIOA4, so you can control it through the register 0xFFF7BC34 to 0xFFF7BC4C.

  • Thanks for your reply!

    My problem is how to translate your comments into the C code completely.

    Just you said above,

    1) set up the hardware trigger ...

    2) Write the channel into the channel select register...

    3) enable the interrupt...

    Could you please write an exact C code or a complete example for this case directly?

    I am a junior programmer for MCUs.

    I can not assure that the code is ok or not exactly.

    If you give me some complete examples, I will follow your steps and an example code easily. 

    For me, the motorware is not a complete software set for developing a real-time control system in Hercules.

    ////////////////////////////////////////

    GPIO 12 - MCU GIOA3

    The code is

    gioGetBit(gioPORTA, 3);

    GPIO15 - MCU GIOA0

    The code is

    gioGetBit(gioPORTA, 0);

    En_Gate is collected to GIOA4,

    its code is

    gioGetBit(gioPORTA, 4);

    //////////////////////////////////////////////////////////////

    GPIO22 - EQEP2S, HET30

    I  do not know what it is. 

  • "GPIO22 - EQEP2S, HET30, I  do not know what it is. "

    Why no answer to me?

    //////////////////////////////////////////////////////////////////////////////////////////

    In the drv.h, 

    // HET States for PWM logic
    #define ALL_PHASES_OFF 0x401BA000
    #define PHASE_A_OFF 0x401BA550
    #define PHASE_B_OFF 0x401BA505
    #define PHASE_C_OFF 0x401BA055

    I need to know the other PWM channels definition like above.

    #define PHASE_D_OFF  xxxxxxxxx

    #define PHASE_E_OFF  xxxxxxxxx
    #define PHASE_F_OFF  xxxxxxxxx

    Can you give me these defining constants of "xxxxxxxx"?

    Furthermore,

    I can not use this library "InstaSPIN_BLDC_Lib" in my project for developing a SRM driver.

    How can I re-build one cleaned project and which part of motorware is needed essentially?

  • Here is the schematic RM46_CNCD_Schematic.pdf downloaded from http://processors.wiki.ti.com/index.php/RM46_CNCD.

    If you search GPIO22, you will find it connected to EQEP2S pin, which is muxed wtih HET30.

    Those definations for PWMs are only valid for the HET module. I think you are using the ePwM to generate the PWMs.

    Can you use the DRV8301 board to drive a SRM? Sounds to to me that SRM requires 6 wires connection for 3 phases.

     

     

  • 2047.RM46L852SRM-30.rarYes, I use the DRV8301 board to drive a SRM.

    The power stage has modified, that is, the "Source" of high-side and "Drain" of low-side MOSFETs are disconnected.

    Mount on the SRM phase 1, 2, and 3 wires to the "Source" of high-side and "Drain" of low-side MOSFETs.

    Up to now, the mentioned above I have done.

    This driver needs the independent 6-channel PWM's signals to drive the 6 MOSFETs such that in drv.h

    I found the following defined constants

    /////////////////////////////////////////////////////////////////

    // HET States for PWM logic
    #define ALL_PHASES_OFF 0x401BA000
    #define PHASE_A_OFF 0x401BA550
    #define PHASE_B_OFF 0x401BA505
    #define PHASE_C_OFF 0x401BA055

    //////////////////////////////////////////////////////////////////

    Could you please give me the values of he following defined constants?

    I do not know what they are.

    #define PHASE_D_OFF 0xxxxxxxxxx

    #define PHASE_E_OFF 0xxxxxxxxxx
    #define PHASE_F_OFF 0xxxxxxxxxx

    ////////////////////////////////////////////////////////////////////

    Furthermore,

    I have migrated the sensorless control code existing in the document "Developing an SRM Drive System Using the TMS320F240, APPLICATION REPORT: SPRA420" and attached.

    But I do not know how to assure that code is ready or not, the more technical support needed.

    The sys_link.cmd has modified as the follow:

    VECTORS (X)  : origin=0xFF000000 length=0xFF000020 then the cgt compiling and linking are worked.