cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G431 Isolated sensor ADC software problem

mckmk
Associate II

Using STM32G431, I designed a controller and inverter with different pin sequences for my needs.

I used ACS781 as a current sensor. I use the software of ST only in test. Apart from that, I develop my own software.

In MC SDK 5.4.4 version, some corrections have been made on regular transformations, but this arrangement causes the software not to work in drives with insulated current sensors.

For this, I did backwards corrections to version 5.4.3 and the engine worked.

Also when I extracted the codes in 5.4.3 version it worked without any problems.

The CubeG4 Firmware Package I used is V1.2.0.

When I convert the RCM_ExecRegularConv() function into V5.4.3 as below, it works fine.

uint16_t RCM_ExecRegularConv (uint8_t handle)
{
  uint16_t retVal;
 
  LL_ADC_REG_SetSequencerRanks( RCM_handle_array[handle]->regADC,
                                LL_ADC_REG_RANK_1,
                                __LL_ADC_DECIMAL_NB_TO_CHANNEL( RCM_handle_array[handle]->channel ) );
 
  LL_ADC_REG_ReadConversionData12( RCM_handle_array[handle]->regADC );
 
    LL_ADC_REG_StartConversion( RCM_handle_array[handle]->regADC );
  /* Wait until end of regular conversion */
  while ( LL_ADC_IsActiveFlag_EOC( RCM_handle_array[handle]->regADC ) == 0u ) {}
  retVal = LL_ADC_REG_ReadConversionData12( RCM_handle_array[handle]->regADC );   
return retVal;
}

The current version of V5.4.4 malfunctioning:

uint16_t RCM_ExecRegularConv (uint8_t handle)
{
  uint16_t retVal;
  uint8_t formerNext;
  uint8_t i=0;
  uint8_t LastEnable = RCM_MAX_CONV;
  
  if (RCM_NoInj_array [handle].enable == false)
  {
    /* find position in the list */    
    while (i < RCM_MAX_CONV)
    {
      if (RCM_NoInj_array [i].enable == true)
      {      
        if (RCM_NoInj_array [i].next > handle)
        /* We found a previous reg conv to link with */
        {          
          formerNext = RCM_NoInj_array [i].next;
          RCM_NoInj_array [handle].next = formerNext;
          RCM_NoInj_array [handle].prev = i;
          RCM_NoInj_array [i].next = handle;          
          RCM_NoInj_array [formerNext].prev = handle;
          i= RCM_MAX_CONV; /* stop the loop, handler inserted*/
        }
        else { /* We found an enabled regular conv, 
                * but do not know yet if it is the one we have to be linked to. */
          LastEnable = i;
        }
      }
      else
      { /* nothing to do */
      }
      i++;
      if (i == RCM_MAX_CONV) 
      /* We reach end of the array without handler inserted*/
      {
       if (LastEnable != RCM_MAX_CONV )
       /* we find a regular conversion with smaller position to be linked with */
       {
         formerNext = RCM_NoInj_array [LastEnable].next;
         RCM_NoInj_array [handle].next = formerNext; 
         RCM_NoInj_array [handle].prev = LastEnable;          
         RCM_NoInj_array [LastEnable].next = handle;
         RCM_NoInj_array [formerNext].prev = handle;      
       }
       else 
       { /* the current handle is the only one in the list */
         /* previous and next are already pointing to itself (done at registerRegConv) */
         RCM_currentHandle = handle; 
       }       
      }
      else 
      {
       /* Nothing to do we are parsing the array, nothing inserted yet*/
      }
    }
    /* The handle is now linked with others, we can set the enable flag */
    RCM_NoInj_array [handle].enable = true;
    RCM_NoInj_array [handle].status = notvalid;
    if (RCM_NoInj_array[RCM_currentHandle].status != ongoing )
    {/* select the new conversion to be the next scheduled only if a conversion is not ongoing*/
      RCM_currentHandle = handle; 
    } 
  }
  else
  {
  /* Nothing to do the current handle is already scheduled */
  }
  if (PWM_Handle_M1.ADCRegularLocked == false)  
  /* The ADC is free to be used asynchronously*/
  {
    LL_ADC_REG_SetSequencerRanks( RCM_handle_array[handle]->regADC,
                                LL_ADC_REG_RANK_1,
                                __LL_ADC_DECIMAL_NB_TO_CHANNEL( RCM_handle_array[handle]->channel ) );
 
    LL_ADC_REG_ReadConversionData12( RCM_handle_array[handle]->regADC );
    /* Start ADC conversion */
    LL_ADC_REG_StartConversion( RCM_handle_array[handle]->regADC );
  
    /* Wait EOC */
    while ( LL_ADC_IsActiveFlag_EOC( RCM_handle_array[handle]->regADC ) == RESET )
    {
    }
  
    /* Read the "Regular" conversion (Not related to current sampling) */
    RCM_NoInj_array [handle].value = LL_ADC_REG_ReadConversionData12( RCM_handle_array[handle]->regADC );
    RCM_currentHandle = RCM_NoInj_array [handle].next;
    RCM_NoInj_array [handle].status = valid;
  }
  retVal = RCM_NoInj_array [handle].value;
return retVal;
}

9 REPLIES 9
mckmk
Associate II

I found the problem. EOC Flag of ADC is not reset. Therefore, the software crashes in the following line.

In this case, the engine does not start at all and does not detect the stop command after starting. Deleting this line gets better.

However, I don't know if it will cause other problems!

  

while ( LL_ADC_IsActiveFlag_EOC( RCM_handle_array[handle]->regADC ) == RESET )
 
 {
 
 }

Also, when the "PWM_Handle_M1.ADCRegularLocked" line is compiled, "ADCRegularLocked" is reported to be undefined.

I found the problem. EOC Flag of ADC is not reset. Therefore, the software crashes in the following line.

In this case, the engine does not start at all and does not detect the stop command after starting. Deleting this line gets better.

However, I don't know if it will cause other problems!

while ( LL_ADC_IsActiveFlag_EOC( RCM_handle_array[handle]->regADC ) == RESET )
 
 {
 
 }

Also, when the "PWM_Handle_M1.ADCRegularLocked" line is compiled, "ADCRegularLocked" is reported to be undefined.

In the release note, it was stated that a software correction was made in the ADC for CUT 2.2. However, the software does not work successfully.

What is the problem with ADC in this CUT 2.2 version? I will change the MCU according to the situation because I cannot accommodate the error.

Gunnar Holm
Associate II

Regarding the "PWM_Handle_M1.ADCRegularLocked" line - this mechanism is implemented for the shunt sensor drivers. (I'm using G4 and ICS's myself so I have the same problem). When diff'ing the r1_g4xx_pwm_curr_fdbk.c from version 5.4.2 and 5.4.4 it can be seen that the ADCRegularLocked flag is set true at start of R1_SwitchOnPWM() function and set false at the end of the R1_SwitchOffPWM() function.

And in the corresponding .h file the ADCRegularLocked is defined as a part of the PWMC_R1_Handle_t structure.

I have implemented the same solution for the ICS driver (ICS_g4xx_pwm_curr_fdbk.[ch]) - it compiles now without faults.

I have not yet started testing - however if anyone have more input to this issue it would be appreciated.

mckmk
Associate II

Sorry but there is no such thing in 5.4.2.

Gunnar Holm
Associate II

Not sure what you refer to ('no such thing in 5.4.2') , but if it is the data structure element "ADCRegularLocked" and belonging functionality - it is the point that this does not exist in 5.4.2. And by comparing the file r1_g4xx_pwm_curr_fdbk.c from version 5.4.2 and 5.4.4, it is easy to see how the new functionality is implemented in 5.4.4.

My approache has then been to implement same data structure definition and control functions in the ICS_g4xx_pwm_curr_fdbk.[ch] files.

mckmk
Associate II

I'm talking about 5.4.2 MCSDK.

Is it possible for you to attach files?

There is also a situation like this: power measurements are inaccurate when the engine drops to 500 rpm. It shows that it exceeds 200W on the control interface.

mckmk
Associate II

I found the files as you said. I added the necessary lines. Nothing changed. I can get the torque I want at low revs on a driver board I made with a different MCU. However, this does not happen with the 32G431. Is the problem with the current sensor? I couldn't solve it.

I am afraid to run my own software due to this problem.

Laurent Ca...
Lead II

Dear @Mustafa ÇAKMAK​ 

Could you detail again what ST boards you use?

I did not well understand it.

Best regards

Laurent Ca...

mckmk
Associate II

I have board B-G431B-ESC1. I designed a driver board based on reference designs. The MOSFET drivers and MOSFETs I use are products of different companies.

I had no problem with Shunt resistant applications before. In this application I made a design with Hall effect current sensor (ACS781-8.8mV).

The software can start the engine but cannot apply the requested torque. I can easily stop the motor shaft with my hand. I think this problem is from ADC's reading technique configured for ICS.

I made the same ADC configuration and connected a heater as a load to the output for testing. I have observed a lot of changes even in the offset value read on the inverter output, whether there is a load or not. This difference can be as much as + -20mV.

I have software that I wrote with the same technique, but I haven't tried it yet.