Merge pull request #522 from neilt6/master

HAL: Better ADC self-calibration for LPC11U6X & LPC15XX
pull/527/merge
Martin Kojtal 2014-10-06 09:05:49 +01:00
commit 8601be3b1e
2 changed files with 16 additions and 12 deletions

View File

@ -66,13 +66,15 @@ void analogin_init(analogin_t *obj, PinName pin) {
// Enable clock for ADC // Enable clock for ADC
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 13); LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 13);
// Start ADC self-calibration // Determine the clock divider for a 500kHz ADC clock during calibration
LPC_ADC->CTRL = (1UL << 30); uint32_t clkdiv = (SystemCoreClock / 500000) - 1;
do {
tmp = LPC_ADC->CTRL;
} while ((tmp & (1UL << 30)) != 0);
LPC_ADC->CTRL = 1; // Sampling clock: SystemClock divided by 1 // Perform a self-calibration
LPC_ADC->CTRL = (1UL << 30) | (clkdiv & 0xFF);
while ((LPC_ADC->CTRL & (1UL << 30)) != 0);
// Sampling clock: SystemClock divided by 1
LPC_ADC->CTRL = 0;
} }
static inline uint32_t adc_read(analogin_t *obj) { static inline uint32_t adc_read(analogin_t *obj) {

View File

@ -77,19 +77,21 @@ void analogin_init(analogin_t *obj, PinName pin) {
LPC_SYSCON->SYSAHBCLKCTRL0 |= (1 << 28); LPC_SYSCON->SYSAHBCLKCTRL0 |= (1 << 28);
} }
// select IRC as async. clock, divided by 1 // select IRC as asynchronous clock, divided by 1
LPC_SYSCON->ADCASYNCCLKSEL = 0; LPC_SYSCON->ADCASYNCCLKSEL = 0;
LPC_SYSCON->ADCASYNCCLKDIV = 1; LPC_SYSCON->ADCASYNCCLKDIV = 1;
__IO LPC_ADC0_Type *adc_reg = (obj->adc < ADC1_0) ? (__IO LPC_ADC0_Type*)(LPC_ADC0) : (__IO LPC_ADC0_Type*)(LPC_ADC1); __IO LPC_ADC0_Type *adc_reg = (obj->adc < ADC1_0) ? (__IO LPC_ADC0_Type*)(LPC_ADC0) : (__IO LPC_ADC0_Type*)(LPC_ADC1);
// start calibration // determine the system clock divider for a 500kHz ADC clock during calibration
adc_reg->CTRL |= (1UL << 30); uint32_t clkdiv = (SystemCoreClock / 500000) - 1;
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
// asynchronous mode // perform a self-calibration
adc_reg->CTRL = (1UL << 30) | (clkdiv & 0xFF);
while ((adc_reg->CTRL & (1UL << 30)) != 0);
// switch to asynchronous mode
adc_reg->CTRL = (1UL << 8); adc_reg->CTRL = (1UL << 8);
} }
static inline uint32_t adc_read(analogin_t *obj) { static inline uint32_t adc_read(analogin_t *obj) {