LPC824 - Chip_ADC_IsCalibrationDone - always = false

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

LPC824 - Chip_ADC_IsCalibrationDone - always = false

755 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by sanders7284 on Tue Apr 26 02:31:26 MST 2016
Hello, I am looking for some help.

On start up the following routine is called and 9 time out of 10 everything is ok, 1 time out of ten the code gets stuck in the while (!(Chip_ADC_IsCalibrationDone(LPC_ADC))) {}

which in turn calls from the NXP header file adc_8xx.h

STATIC INLINE bool Chip_ADC_IsCalibrationDone(LPC_ADC_T *pADC)
{
return (bool) ((pADC->CTRL & ADC_CR_CALMODEBIT) == 0);
}

on investigation the CAL_MODE bit is still set

What are the possible reasons for the for the CAL_MODE bit staying set?


//ADC INIT routine -------------------------------------------------------------
void ADC_INIT (void)
{
  PWM_Adj = 0;
  Chip_ADC_Init(LPC_ADC, 0);                                                    // Setup ADC for 12-bit mode and normal power
  Chip_ADC_StartCalibration(LPC_ADC);                                           // Need to do a calibration after initialization and trim
  while (!(Chip_ADC_IsCalibrationDone(LPC_ADC))) {}                            
  Chip_ADC_SetClockRate(LPC_ADC, ADC_MAX_SAMPLE_RATE);                          // Setup for maximum ADC clock rate using sycnchronous clocking
 
  /* Setup a sequencer to do the following:*/
  Chip_ADC_SetupSequencer(LPC_ADC, ADC_SEQA_IDX,                                // Setup the ADC sequencer, to take the following measurements
         (ADC_SEQ_CTRL_CHANSEL(ADC_SystemVoltage)                               // System Voltage
          | ADC_SEQ_CTRL_CHANSEL(ADC_BatteryVoltage)                            // Battery Voltage
          | ADC_SEQ_CTRL_CHANSEL(ADC_BatteryTemperature)                        // Battery Temperature
          | ADC_SEQ_CTRL_CHANSEL(ADC_PSUTemperature)                            // PSU Temperature
          | ADC_SEQ_CTRL_CHANSEL(ADC_ILoad)                                     // ILoad
          | ADC_SEQ_CTRL_CHANSEL(ADC_IBat)                                      // IBat
          | ADC_SEQ_CTRL_MODE_EOS));                                            // End of Sequence
   
  /* Enable the clock to the Switch Matrix */                                   // Configure the SWM, so that the relevant Pins may be used for ADC inputs
  Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM);                               // Enable the Peripheral clock, so that bits can be configured
  Chip_SWM_EnableFixedPin(SWM_FIXED_ADC2);                                      // System Voltage       = ADC 2
  Chip_SWM_EnableFixedPin(SWM_FIXED_ADC4);                                      // Battery Voltage      = ADC 4
  Chip_SWM_EnableFixedPin(SWM_FIXED_ADC7);                                      // Battery Temperature  = ADC 7
  Chip_SWM_EnableFixedPin(SWM_FIXED_ADC6);                                      // PSU Temperature      = ADC 6
  Chip_SWM_EnableFixedPin(SWM_FIXED_ADC5);                                      // ILoad                = ADC 5
  Chip_SWM_EnableFixedPin(SWM_FIXED_ADC3);                                      // IBat                 = ADC 3
  Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SWM);                              // Disable the clock to the Switch Matrix to save power
  
  /* Clear all pending interrupts */
  Chip_ADC_ClearFlags(LPC_ADC, Chip_ADC_GetFlags(LPC_ADC));
 
  /* Enable ADC overrun and sequence A completion interrupts */
  Chip_ADC_EnableInt(LPC_ADC, (ADC_INTEN_SEQA_ENABLE | ADC_INTEN_OVRRUN_ENABLE));
  
  /* Enable ADC NVIC interrupt */
  NVIC_EnableIRQ(ADC_SEQA_IRQn);
 
  /* Enable sequencer */
  Chip_ADC_EnableSequencer(LPC_ADC, ADC_SEQA_IDX);
}
//------------------------------------------------------------------------------
Labels (1)
0 Kudos
3 Replies

443 Views
ianbenton
Senior Contributor I

Did you fix this? My LPC1517 is doing the same thing - it seems that a slow-rising power supply bothers it.

0 Kudos

443 Views
lpcware
NXP Employee
NXP Employee
bump
0 Kudos

443 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by sanders7284 on Tue Apr 26 03:01:45 MST 2016
This is not the solution but I don;t think it is helping

The data sheet says

CALMODE Writing a 1 to this bit initiates a self-calibration cycle. This bit will be automatically
cleared by hardware after the calibration cycle is complete. To calibrate the ADC,
set the ADC clock to 500 kHz.
Remark: Other bits of this register may be written to concurrently with setting this
bit, however once this bit has been set no further writes to this register are
permitted until the full calibration cycle has ended.

The NXP header file ADC_8xx.h writes twice after the bit is set, this could do with updating.

/* Start ADC calibration */
void Chip_ADC_StartCalibration(LPC_ADC_T *pADC)
{
/* Set calibration mode */
pADC->CTRL |= ADC_CR_CALMODEBIT;

/* Clear ASYNC bit */
pADC->CTRL &= ~ADC_CR_ASYNMODE;

/* Setup ADC for about 500KHz (per UM) */
Chip_ADC_SetClockRate(pADC, 500000);

/* Clearn low power bit */
pADC->CTRL &= ~ADC_CR_LPWRMODEBIT;

/* Calibration is only complete when ADC_CR_CALMODEBIT bit has cleared */
}
0 Kudos