stm32f: Set ADC single read timeout

If an ADC read fails and EOC bit is somehow never set, we will be stuck
in the read function holding mutex lock forever, which is really bad.
Let's set a timeout for this.

BUG=chrome-os-partner:18997
TEST=Boot Spring. Check ADC works.
BRANCH=spring

Change-Id: I19b108326f34f380497606fe92eabfaf0a778bb4
Signed-off-by: Vic Yang <victoryang@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/50338
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
This commit is contained in:
Vic Yang
2013-05-08 02:43:59 +08:00
committed by ChromeBot
parent 0fe217c745
commit 235e6e1d0d

View File

@@ -14,6 +14,8 @@
#include "timer.h"
#include "util.h"
#define ADC_SINGLE_READ_TIMEOUT 3000 /* 3 ms */
struct mutex adc_lock;
static int watchdog_ain_id;
@@ -170,6 +172,7 @@ int adc_read_channel(enum adc_channel ch)
const struct adc_t *adc = adc_channels + ch;
int value;
int restore_watchdog = 0;
timestamp_t deadline;
if (!adc_powered())
return EC_ERROR_UNKNOWN;
@@ -190,15 +193,21 @@ int adc_read_channel(enum adc_channel ch)
STM32_ADC_CR2 |= (1 << 0); /* ADON */
/* Wait for EOC bit set */
while (!adc_conversion_ended())
;
value = STM32_ADC_DR & ADC_READ_MAX;
deadline.val = get_time().val + ADC_SINGLE_READ_TIMEOUT;
value = ADC_READ_ERROR;
do {
if (adc_conversion_ended()) {
value = STM32_ADC_DR & ADC_READ_MAX;
break;
}
} while (!timestamp_expired(deadline, NULL));
if (restore_watchdog)
adc_enable_watchdog_no_lock();
mutex_unlock(&adc_lock);
return value * adc->factor_mul / adc->factor_div + adc->shift;
return (value == ADC_READ_ERROR) ? ADC_READ_ERROR :
value * adc->factor_mul / adc->factor_div + adc->shift;
}
int adc_read_all_channels(int *data)