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.

SRM driver in RM46 core with drv8301

Other Parts Discussed in Thread: MOTORWARE, RM46L852, DRV8301, HALCOGEN

First step is, disconnect the source pin of all high-side power transistors from the original full-bridge power stage and then connect to the input pins of stator coil of switched reluctance motors (SRMs). Also connect the other input pins of stator coil to the drain pin of all low-side power transistors in the phase sequence like A,B and C respectively.

Now I have migrated the sensorless control code in the TI document " Developing an SRM Drive System Using the TMS320F240 APPLICATION REPORT: SPRA420."

There are much inconsistent codes in the motorware as the following and which no any demo code for driving the stop, start buttons and speed control via Tach/Pot input.

And in the "drv830x_hwguide.pdf" included in the motorware DVD the most important feedback signals via ADC different channels as following:

59 ADC-A1 IA-FB Current sense phase A
61 ADC-A2 I-TOTAL DC Bus current sense 
63 ADC-A3 IC-FB Current sense phase C 
67 ADC-A5 IC-FB Current sense phase C 
71 ADC-A7 ADC-Vhb2 Phase Voltage sense B 
7 ADC-B0 TSI Tach/Pot input 
9 ADC-B1 IB-FB Current sense phase B 
11 ADC-B2 VDCBUS DC Bus voltage sense 
13 ADC-B3 IA-FB Current sense phase A 
15 ADC-B4 ADC-Vhb3 Phase Voltage sense C 
17 ADC-B5 IB-FB Current sense phase B 
21 ADC-B7 ADC-Vhb1 Phase Voltage sense A

But in the code section existing in the drv.h of the project of "RM46L852_sensored_speed_smo"

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

// Update ADC object

adcGetData(adcREG1, adcGROUP1, obj->AdcResults1);

//!13 ADC-B3 IA-FB Current sense phase A
//!59 ADC-A1 IA-FB Current sense phase A

obj->adcData.I.value[0] = ((obj->AdcResults1[0].value<<4)-obj->cal_offset_A)*obj->adc_current_gain_A; //ileg1.ImeasA_f;

//!9 ADC-B1 IB-FB Current sense phase B
//!17 ADC-B5 IB-FB Current sense phase B

obj->adcData.I.value[1] = ((obj->AdcResults1[2].value<<4)-obj->cal_offset_B)*obj->adc_current_gain_B; //ileg1.ImeasB_f;

//!63 ADC-A3 IC-FB Current sense phase C
//!67 ADC-A5 IC-FB Current sense phase C

obj->adcData.I.value[2] = 0;

Why is zero?

The adcData.I.value[2] is a non-zero value and has to be the form of "((obj->AdcResults1[0].value<<4)-obj->cal_offset_C)*obj->adc_current_gain_C;"

but changing AdcResults1[0] to AdcResults1[4], I guess maybe, where add the "cal_offset_C" and "adc_current_gain_C" to be the member of the structure _DRV_Obj_.

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

obj->currentAB.value[0] = obj->adcData.I.value[0];
obj->currentAB.value[1] = obj->adcData.I.value[1];

// Change the currentAB to be MATH_vec3 in the struct _DRV_Obj_ of drv.h

MATH_vec3 currentAB;

//Add the following line

obj->currentAB.value[2] = obj->adcData.I.value[2];

//DC bus voltage
obj->adcData.dcBusV = (obj->AdcResults1[1].value)*0.00024414;

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

In the code section existing in the drv.h of the project of "RM46L852_instaspin_bldc"

 //Get the DC Bus Volage 

obj->vDCBus = (((float32_t)obj->AdcResults1[2].value) * 0.00024414);

At different ADC channels but sampling the same DC bus value.

why?

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

//DC bus voltage

obj->adcData.dcBusV = (obj->AdcResults1[1].value)*0.00024414;

// Get B-phase BEMF Value

obj->iqVbIn = (((float32_t)obj->AdcResults1[1].value) * 0.00024414) - obj->instaHandle->vbOffset;

At the same ADC channel but sampling the different value.

why?

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

//!21 ADC-B7 ADC-Vhb1 Phase Voltage sense A
obj->iqVaIn = ((float32_t)obj->AdcResults1[5].value) * 0.00024414;
//!71 ADC-A7 ADC-Vhb2 Phase Voltage sense B
obj->iqVbIn = ((float32_t)obj->AdcResults1[1].value) * 0.00024414;
//!15 ADC-B4 ADC-Vhb3 Phase Voltage sense C
obj->iqVcIn = ((float32_t)obj->AdcResults1[3].value) * 0.00024414;

Why are the ADC channels not relative to the  AdcResults1[1,3,5]?

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

What situation is!

  • Hello Richard,

    I have forwarded your question/comments to our drv8301 expert and they should get back with you shortly.

  • Richard Dualmann said:

    First step is, disconnect the source pin of all high-side power transistors from the original full-bridge power stage and then connect to the input pins of stator coil of switched reluctance motors (SRMs). Also connect the other input pins of stator coil to the drain pin of all low-side power transistors in the phase sequence like A,B and C respectively.

    Now I have migrated the sensorless control code in the TI document " Developing an SRM Drive System Using the TMS320F240 APPLICATION REPORT: SPRA420."

    There are much inconsistent codes in the motorware as the following and which no any demo code for driving the stop, start buttons and speed control via Tach/Pot input.

    And in the "drv830x_hwguide.pdf" included in the motorware DVD the most important feedback signals via ADC different channels as following:

    59 ADC-A1 IA-FB Current sense phase A
    61 ADC-A2 I-TOTAL DC Bus current sense 
    63 ADC-A3 IC-FB Current sense phase C 
    67 ADC-A5 IC-FB Current sense phase C 
    71 ADC-A7 ADC-Vhb2 Phase Voltage sense B 
    7 ADC-B0 TSI Tach/Pot input 
    9 ADC-B1 IB-FB Current sense phase B 
    11 ADC-B2 VDCBUS DC Bus voltage sense 
    13 ADC-B3 IA-FB Current sense phase A 
    15 ADC-B4 ADC-Vhb3 Phase Voltage sense C 
    17 ADC-B5 IB-FB Current sense phase B 
    21 ADC-B7 ADC-Vhb1 Phase Voltage sense A

    But in the code section existing in the drv.h of the project of "RM46L852_sensored_speed_smo"

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

    // Update ADC object

    adcGetData(adcREG1, adcGROUP1, obj->AdcResults1);

    //!13 ADC-B3 IA-FB Current sense phase A
    //!59 ADC-A1 IA-FB Current sense phase A

    obj->adcData.I.value[0] = ((obj->AdcResults1[0].value<<4)-obj->cal_offset_A)*obj->adc_current_gain_A; //ileg1.ImeasA_f;

    //!9 ADC-B1 IB-FB Current sense phase B
    //!17 ADC-B5 IB-FB Current sense phase B

    obj->adcData.I.value[1] = ((obj->AdcResults1[2].value<<4)-obj->cal_offset_B)*obj->adc_current_gain_B; //ileg1.ImeasB_f;

    //!63 ADC-A3 IC-FB Current sense phase C
    //!67 ADC-A5 IC-FB Current sense phase C

    obj->adcData.I.value[2] = 0;

    Why is zero?

    HW: Here we just gve this channel an arbitrary number. It does not mean anything. In the firmware "RM46L852_sensored_speed_smo", we only sample three channels, Ia (ADC channel 9), Ib (ADC channel 21) and Vdc (ADC channel 18). So, the sequence of ADC result order is: 0 -Ia; 1-Vdc; and 2-Ib. We did not sample Ic because Ia+Ib+Ic are supposed to be zero and it is no needed in the sensorless control.

    Let's look at the "RM46L852_instaspin_bldc", the ADC sample channels are: 9 (Ia), 15(Vhb2), 18 (Vdc), 20(Vhb3), 21(Ib), 23(Vhb1). So in the ADC result, order is:  0 (Ia), 1(Vhb2), 2 (Vdc), 3(Vhb3), 4(Ib), 5(Vhb1).

    The ADC signal to be sample in each ADC group are store in the s_adcSelect[2U][3U] in adc.c. Please reference that variable.

    The adcData.I.value[2] is a non-zero value and has to be the form of "((obj->AdcResults1[0].value<<4)-obj->cal_offset_C)*obj->adc_current_gain_C;"

    but changing AdcResults1[0] to AdcResults1[4], I guess maybe, where add the "cal_offset_C" and "adc_current_gain_C" to be the member of the structure _DRV_Obj_.

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

    obj->currentAB.value[0] = obj->adcData.I.value[0];
    obj->currentAB.value[1] = obj->adcData.I.value[1];

    // Change the currentAB to be MATH_vec3 in the struct _DRV_Obj_ of drv.h

    MATH_vec3 currentAB;

    //Add the following line

    obj->currentAB.value[2] = obj->adcData.I.value[2];

    //DC bus voltage
    obj->adcData.dcBusV = (obj->AdcResults1[1].value)*0.00024414;

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

    In the code section existing in the drv.h of the project of "RM46L852_instaspin_bldc"

     //Get the DC Bus Volage 

    obj->vDCBus = (((float32_t)obj->AdcResults1[2].value) * 0.00024414);

    At different ADC channels but sampling the same DC bus value.

    why?

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

    //DC bus voltage

    obj->adcData.dcBusV = (obj->AdcResults1[1].value)*0.00024414;

    // Get B-phase BEMF Value

    obj->iqVbIn = (((float32_t)obj->AdcResults1[1].value) * 0.00024414) - obj->instaHandle->vbOffset;

    At the same ADC channel but sampling the different value.

    why?

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

    //!21 ADC-B7 ADC-Vhb1 Phase Voltage sense A
    obj->iqVaIn = ((float32_t)obj->AdcResults1[5].value) * 0.00024414;
    //!71 ADC-A7 ADC-Vhb2 Phase Voltage sense B
    obj->iqVbIn = ((float32_t)obj->AdcResults1[1].value) * 0.00024414;
    //!15 ADC-B4 ADC-Vhb3 Phase Voltage sense C
    obj->iqVcIn = ((float32_t)obj->AdcResults1[3].value) * 0.00024414;

    Why are the ADC channels not relative to the  AdcResults1[1,3,5]?

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

     

    What situation is!

  • //!13 ADC-B3 IA-FB Current sense phase A
    //!59 ADC-A1 IA-FB Current sense phase A

    Why is channel 9 (Ia)?

    ADC-B3 is euqal to ADC-A10, B0==A7, B1==A8, B2==A9, B3==A10 is right?

    //!9 ADC-B1 IB-FB Current sense phase B
    //!17 ADC-B5 IB-FB Current sense phase B

    21(Ib) B1==A8?

    //!63 ADC-A3 IC-FB Current sense phase C
    //!67 ADC-A5 IC-FB Current sense phase C

    I need this exact ADC channel for Ic sampling.


  • Richard Dualmann said:

    //!13 ADC-B3 IA-FB Current sense phase A
    //!59 ADC-A1 IA-FB Current sense phase A

    Why is channel 9 (Ia)?

    ADC-B3 is euqal to ADC-A10, B0==A7, B1==A8, B2==A9, B3==A10 is right?

    HW: ADC-A1(DIMM interface) = AD1IN9 (MCU channel). See below sreenshot from the schematic. ADC-B3 (DIMM interface) = AD2IN3 (MCU channel)=AD1IN19 (MCU channel).

    Similar,  ADC-B1 (DIMM interface) = AD2IN1 (MCU channel)=AD1IN17 (MCU channel). ADC-B5 (DIMM interface) = AD2IN5 (MCU channel)=AD1IN21 (MCU channel).

    //!9 ADC-B1 IB-FB Current sense phase B
    //!17 ADC-B5 IB-FB Current sense phase B

    21(Ib) B1==A8?

    //!63 ADC-A3 IC-FB Current sense phase C
    //!67 ADC-A5 IC-FB Current sense phase C

    I need this exact ADC channel for Ic sampling.


  • Where can I find this schematics?

    What is the exact channel number for the ADC-A3 for Ic-FB urrent sense phase C or ADC-A5 for Ic-FB Current sense phase C?

  • Richard Dualmann said:

    Where can I find this schematics?

    HW: It should be included in the DVD in the kits. You can download from the webside:
    search for "schematic"

  • DVD no this content.

    Just motorware only.

    I use the RM46 Core not RM48,

    I need to find something in the RM48 board,

    Why?

  • In my pc, it is located at:

    C:\ti\motorware_1_00_03_04\sw\boards\control\tmdxrm46cncd\

    The blue fonts is the installation directory.

    If this is not included in your DVD, we might did sth wrong when we check it out from our database and built the DVD.

    Regards,

    Haixiao

  • //!63 ADC-A3 IC-FB Current sense phase C
    //!67 ADC-A5 IC-FB Current sense phase C

    Could you please tell me the exact channel number for the ADC for Ic feedback?

  • Richard Dualmann said:

    //!63 ADC-A3 IC-FB Current sense phase C = MCU AD1IN11 = AD2IN11
    //!67 ADC-A5 IC-FB Current sense phase C = MCU AD1IN13 = AD2IN13

    Could you please tell me the exact channel number for the ADC for Ic feedback?

  • The changed ADC channels are

    9 (Ia), 10(iTotal), 11(Ic), 15(Vhb2), 18 (Vdc), 20(Vhb3), 21(Ib) and 23(Vhb1) respectively.

    So in the ADC result, order is:


    0 (Ia), 1(iTotal), 2(Ic), 3(Vhb2), 4 (Vdc), 5(Vhb3), 6(Ib) and 7(Vhb1).

    Corrected?

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

    More again,

    //!13 ADC-B3 IA-FB Current sense phase A
    //!59 ADC-A1 IA-FB Current sense phase A

    obj->adcData.I.value[0] = ((obj->AdcResults1[0].value<<4)-obj->cal_offset_A)*obj->adc_current_gain_A; //ileg1.ImeasA_f;

    has shifted to left 4 bits.

    //! DC bus voltage
    //!11 ADC-B2 VDCBUS DC Bus voltage sense

    obj->adcData.dcBusV = (obj->AdcResults1[4].value)*0.00024414;

    //!21 ADC-B7 ADC-Vhb1 Phase Voltage sense A


    obj->iqVaIn = ((float32_t)obj->AdcResults1[7].value) * 0.00024414;

    //!71 ADC-A7 ADC-Vhb2 Phase Voltage sense B

    obj->iqVbIn = ((float32_t)obj->AdcResults1[3].value) * 0.00024414;

    //!15 ADC-B4 ADC-Vhb3 Phase Voltage sense C

    obj->iqVcIn = ((float32_t)obj->AdcResults1[5].value) * 0.00024414;

    have no shifted operation,

    why?

  • Correct.

    What we try to do here is to normlize the ADC result.

    Since the maxium value of 12 bit ADC is 4096, one way is to normlize it to 4096 (*0.00024414).

    Due to some legecy reasons (fixed point is the 1st version), we use IQ15 to normlize it, which means left shift 3 bit. After that, we convert it to floating point in the future.

    Try to make it simple: by the end of the day, these two methods get the same result.

  • As the previous mentioned, the ADC signal to be sample in each ADC group are store in the s_adcSelect[2U][3U] in adc.c. Please reference that variable.

    static const uint32_t s_adcSelect[2U][3U] =
    {
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U,
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000200U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00008000U |
    0x00000000U |
    0x00000000U |
    0x00040000U |
    0x00000000U |
    0x00100000U |
    0x00200000U |
    0x00000000U |
    0x00800000U,
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U,
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U ,
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U,
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U |
    0x00000000U,
    };

    Now, 

    the changed ADC channels are 9 (Ia), 10(iTotal), 11(Ic), 15(Vhb2), 18 (Vdc), 20(Vhb3), 21(Ib) and 23(Vhb1) respectively.

    i.e., the active bits are as the following:

    0000, 0000, 0111, 0001, 0010, 1101, 0000, 0000

    How do I do this setting into the variable "s_adcSelect[2U][3U]"?

    Thanks.

  • In the motorware example, we use ADC1 (1st ADC core) group1 (2nd ADC group in the 1st core), which means we should set s_adcSelect[0U][1U].

    static const uint32_t s_adcSelect[2U][3U] =
    {0,(1<<9 | 1<<10 | 1<<11 | 1<<15 | 1<<18 | 1<<20 | 1<<21 | 1<<23),0,0,0,0};

    Or you can set the channels in the Halcogen and ask it to generate code. The example code ADC.C was generated by HalCogen in the motorware.

    Regards,

    Haixiao

  • I can not understand what you mean about s_adcSelect[0U][1U].

    The constant declaration static const uint32_t s_adcSelect[2U][3U] is found in the adc.c for RM46L852_instaspin_bldc.

    Do I need change this constant to be s_adcSelect[0U][1U]?


  • There are 2 ADC cores in RM46, each core has 3 ADC groups, this is why s_adcSelect[2U][3U].

    In our project, we use the 1st core's 2nd group, so the element in this 2-d array actually takes effect is s_adcSelect[0U][1U]. The example project does not use the other elements in this array. You do not need to change the defination/decaration of array.

  • Hello Richard,

    Did we sufficiently answer your question? If so, could you validate the answer so we may close the thread?

  • No, the ADC problem exists still.

    I can not get ADC data, up to now.

  • If you are new to CCS and Hercules MCU, I would like to recommend you to looking into those examples in http://processors.wiki.ti.com/index.php/Category:HerculesSWExamples. There are some simple ADC examples in this wiki.

    Regards,

    Haixiao