Files
OpenCellular/chip/mec1322/adc.c
Nick Sanders 5cc3cac589 servo_v4: Fix ADC console command
The console adc command prints adc values in the
order they appear in hardware, however they are lableled
in the order they are enumerated in board.h, which is not
necessarily the same.

This prints the correct name and value pairs, and removes
the adc_read_all_channels function which is not otherwise
used.

BUG=chromium:571476
BRANCH=None
TEST="adc" command associates correct values with names now.

Change-Id: I688641953d20082224b4120eaefe0d634ad4c74c
Signed-off-by: Nick Sanders <nsanders@google.com>
Reviewed-on: https://chromium-review.googlesource.com/340892
Commit-Ready: Nick Sanders <nsanders@chromium.org>
Tested-by: Nick Sanders <nsanders@chromium.org>
Reviewed-by: Shawn N <shawnn@chromium.org>
2016-05-26 16:17:26 -07:00

82 lines
1.7 KiB
C

/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "adc.h"
#include "adc_chip.h"
#include "common.h"
#include "console.h"
#include "hooks.h"
#include "registers.h"
#include "task.h"
#include "timer.h"
#include "util.h"
/*
* Conversion on a single channel takes less than 12 ms. Set timeout to
* 15 ms so that we have a 3-ms margin.
*/
#define ADC_SINGLE_READ_TIME 15000
struct mutex adc_lock;
static volatile task_id_t task_waiting;
static int start_single_and_wait(int timeout)
{
int event;
task_waiting = task_get_current();
/* Start conversion */
MEC1322_ADC_CTRL |= 1 << 1;
/* Wait for interrupt */
event = task_wait_event(timeout);
task_waiting = TASK_ID_INVALID;
return event != TASK_EVENT_TIMER;
}
int adc_read_channel(enum adc_channel ch)
{
const struct adc_t *adc = adc_channels + ch;
int value;
mutex_lock(&adc_lock);
MEC1322_ADC_SINGLE = 1 << adc->channel;
if (start_single_and_wait(ADC_SINGLE_READ_TIME))
value = MEC1322_ADC_READ(adc->channel) * adc->factor_mul /
adc->factor_div + adc->shift;
else
value = ADC_READ_ERROR;
mutex_unlock(&adc_lock);
return value;
}
static void adc_init(void)
{
/* Activate ADC module */
MEC1322_ADC_CTRL |= 1 << 0;
/* Enable interrupt */
task_waiting = TASK_ID_INVALID;
MEC1322_INT_ENABLE(17) |= 1 << 10;
MEC1322_INT_BLK_EN |= 1 << 17;
task_enable_irq(MEC1322_IRQ_ADC_SNGL);
}
DECLARE_HOOK(HOOK_INIT, adc_init, HOOK_PRIO_INIT_ADC);
void adc_interrupt(void)
{
/* Clear interrupt status bit */
MEC1322_ADC_CTRL |= 1 << 7;
if (task_waiting != TASK_ID_INVALID)
task_wake(task_waiting);
}
DECLARE_IRQ(MEC1322_IRQ_ADC_SNGL, adc_interrupt, 2);