rockbox/firmware/target/arm/tcc77x/adc-tcc77x.c
Daniel Stenberg 2acc0ac542 Updated our source code header to explicitly mention that we are GPL v2 or
later. We still need to hunt down snippets used that are not. 1324 modified
files...
http://www.rockbox.org/mail/archive/rockbox-dev-archive-2008-06/0060.shtml


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17847 a1c6a512-1295-4272-9138-f99709370657
2008-06-28 18:10:04 +00:00

118 lines
3.3 KiB
C

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 by Dave Chapman
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "cpu.h"
#include "system.h"
#include "kernel.h"
#include "thread.h"
#include "string.h"
#include "adc.h"
/**************************************************************************
** The A/D conversion is done every tick, in three steps:
**
** 1) On the tick interrupt, the conversion of channels 0-3 is started, and
** the A/D interrupt is enabled.
**
** 2) After the conversion is done, an interrupt
** is generated at level 1, which is the same level as the tick interrupt
** itself. This interrupt will be pending until the tick interrupt is
** finished.
** When the A/D interrupt is finally served, it will read the results
** from the first conversion and start the conversion of channels 4-7.
**
** 3) When the conversion of channels 4-7 is finished, the interrupt is
** triggered again, and the results are read. This time, no new
** conversion is started, it will be done in the next tick interrupt.
**
** Thus, each channel will be updated HZ times per second.
**
*************************************************************************/
static int channel_group;
static unsigned short adcdata[8];
/* Tick task */
static void adc_tick(void)
{
/* Start a conversion of channels 0-3. This will trigger an interrupt,
and the interrupt handler will take care of channels 4-7. */
int i;
PCLKCFG6 |= (1<<15); /* Enable ADC clock */
channel_group = 0;
/* Start converting the first 4 channels */
for (i = 0; i < 4; i++)
ADCCON = i;
}
/* IRQ handler */
void ADC(void)
{
int num;
int i;
uint32_t adc_status;
do
{
adc_status = ADCSTATUS;
num = (adc_status>>24) & 7;
if (num) adcdata[(adc_status >> 16) & 0x7] = adc_status & 0x3ff;
} while (num);
if (channel_group == 0)
{
/* Start conversion of channels 4-7 */
for (i = 4; i < 8; i++)
ADCCON = i;
channel_group = 1;
}
else
{
PCLKCFG6 &= ~(1<<15); /* Disable ADC clock */
}
}
unsigned short adc_read(int channel)
{
return adcdata[channel];
}
void adc_init(void)
{
ADCCON = (1<<4); /* Leave standby mode */
/* IRQ enable, auto power-down, single-mode */
ADCCFG |= (1<<3) | (1<<1) | (1<<0);
/* Unmask ADC IRQ */
IEN |= ADC_IRQ_MASK;
tick_add_task(adc_tick);
sleep(2); /* Ensure adc_data[] contains data before returning */
}