Has anybody ever used the code in BLDC demo?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Has anybody ever used the code in BLDC demo?

416 Views
robotjosh
Contributor IV

I've been trying to get this BLDC demo to work using the 3PH tower module.  It blew up fets when I turned it on so I'm auditing every line of code here.  The part that inits the adcs raises questions-

  calib = ADC1_CLP0;

  calib =+ ADC1_CLP1;

  calib =+ ADC1_CLP2;

  calib =+ ADC1_CLP3;

  calib =+ ADC1_CLP4;

  calib =+ ADC1_CLPS;

  calib = calib >> 1;

  calib = calib | 0x8000; // set the MSB

  ADC1_PG = calib; // set the plus side gain register

I have not been able to find any information on a "=+" operator, it seems this operator does not exist in C or any language.  Stepping through the code it appears to be setting calib equal to the positive value of ADC1_CLPx.  This is odd because all of these registers are cast to unsigned ints, you should not have to specify a positive value, and all of it but the last line should be optimized out.  I thought maybe whoever wrote this meant "+=", and the calibration section of the datasheet says you need to sum these calibration registers.  But after downloading the current BLDC code for the KV chips, it contains the same code with "=+" in it.  I also noticed a lot of spelling errors, redundant code, and code mechanisms that are not implemented correctly.  Like, why demand that clock defines be set and then hard code all the timing based values?  Maybe I'm wrong and the "=+" is supposed to do something that I don't understand since it is still in the code after several years of people using it, surely it would be fixed by now if it were a bug.  Maybe I'm the first person ever to use it?  Someone from freescale should audit or at least spell check this code.  And, if you are going to make us use a precompiled library for the motor driver, at least fix it so it doesn't have main() compiled into it and generates errors out of the box since almost all applications are going to have their own main().  I could be wrong about all this but it appears that an intern started this code and a different intern finished it and nobody at freescale proof read, audited or tested the code.

Labels (1)
0 Kudos
1 Reply

287 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Josh,

Related source code is for KV10 product ADC module calibration process.

To complete calibration, the user must generate the gain calibration values using the

following procedure:

1. Initialize or clear a 16-bit variable in RAM.

2. Add the plus-side calibration results CLP0, CLP1, CLP2, CLP3, CLP4, and CLPS to

the variable.

3. Divide the variable by two.

4. Set the MSB of the variable.

5. The previous two steps can be achieved by setting the carry bit, rotating to the right

through the carry bit on the high byte and again on the low byte.

6. Store the value in the plus-side gain calibration register PG.

7. Repeat the procedure for the minus-side gain calibration value.

More detailed info, please check KV10 product reference manual chapter 32.4.6 Calibration function at KV10 reference manual.

Below is a typical code for Kinetis ADC module calibration:

/* ADC - Peripheral instance base addresses */

/** Peripheral ADC0 base pointer */

#define ADC0_BASE_PTR                            ((ADC_MemMapPtr)0x4003B000u)

// Calibrate the ADC in the configuration in which it will be used:

ADC_Cal(ADC0_BASE_PTR);                    // do the calibration

/******************************************************************************

Function 1. Name    AUTO CAL ROUTINE 

Parameters        ADC module pointer points to adc0 or adc1 register map

                         base address.

Returns            Zero indicates success.

Notes                 Calibrates the ADC16. Required to meet specifications

                        after reset and before a conversion is initiated.

******************************************************************************/

uint8 ADC_Cal(ADC_MemMapPtr adcmap)

{

  unsigned short cal_var;

  ADC_SC2_REG(adcmap) &=  ~ADC_SC2_ADTRG_MASK ; // Enable Software Conversion Trigger for Calibration Process    - ADC0_SC2 = ADC0_SC2 | ADC_SC2_ADTRGW(0); 

  ADC_SC3_REG(adcmap) &= ( ~ADC_SC3_ADCO_MASK & ~ADC_SC3_AVGS_MASK ); // set single conversion, clear avgs bitfield for next writing

  ADC_SC3_REG(adcmap) |= ( ADC_SC3_AVGE_MASK | ADC_SC3_AVGS(AVGS_32) );  // Turn averaging ON and set at max value ( 32 )

  ADC_SC3_REG(adcmap) |= ADC_SC3_CAL_MASK ;      // Start CAL

  while ( (ADC_SC1_REG(adcmap,A) & ADC_SC1_COCO_MASK ) == COCO_NOT ); // Wait calibration end

    

  if ((ADC_SC3_REG(adcmap)& ADC_SC3_CALF_MASK) == CALF_FAIL )

  {

   return(1);    // Check for Calibration fail error and return

  }

  // Calculate plus-side calibration

  cal_var = 0x00;

  cal_var =  ADC_CLP0_REG(adcmap);

  cal_var += ADC_CLP1_REG(adcmap);

  cal_var += ADC_CLP2_REG(adcmap);

  cal_var += ADC_CLP3_REG(adcmap);

  cal_var += ADC_CLP4_REG(adcmap);

  cal_var += ADC_CLPS_REG(adcmap);

  cal_var = cal_var/2;

  cal_var |= 0x8000; // Set MSB

  ADC_PG_REG(adcmap) = ADC_PG_PG(cal_var);

  // Calculate minus-side calibration

  cal_var = 0x00;

  cal_var =  ADC_CLM0_REG(adcmap);

  cal_var += ADC_CLM1_REG(adcmap);

  cal_var += ADC_CLM2_REG(adcmap);

  cal_var += ADC_CLM3_REG(adcmap);

  cal_var += ADC_CLM4_REG(adcmap);

  cal_var += ADC_CLMS_REG(adcmap);

  cal_var = cal_var/2;

  cal_var |= 0x8000; // Set MSB

  ADC_MG_REG(adcmap) = ADC_MG_MG(cal_var);

  ADC_SC3_REG(adcmap) &= ~ADC_SC3_CAL_MASK ; /* Clear CAL bit */

  return(0);

}


Have a great day,
best regards,

Ma Hui

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos