364 lines
7.0 KiB
C
364 lines
7.0 KiB
C
#include "FreeRTOS.h"
|
|
#include "board.h"
|
|
#include "chip.h"
|
|
|
|
#ifdef ADC_TOUCH
|
|
#include "touch.h"
|
|
#endif
|
|
|
|
#ifdef ADC_KEY
|
|
#include "keypad.h"
|
|
#endif
|
|
|
|
#define ADC_CTR 0x00
|
|
#define ADC_CFG 0x04
|
|
#define ADC_IMR 0x08
|
|
#define ADC_STA 0x0C
|
|
#define ADC_BAT 0x10
|
|
#define ADC_AUX0 0x14
|
|
#define ADC_AUX1 0x18
|
|
#define ADC_AUX2 0x1C
|
|
#define ADC_AUX3 0x20
|
|
#define ADC_AUX4 0x38
|
|
#define ADC_AUX5 0x40
|
|
#define ADC_AUX6 0x44
|
|
#define ADC_AUX7 0x4C
|
|
#define ADC_PANXZ1 0x24
|
|
#define ADC_PANXZ2 0x28
|
|
#define ADC_DBNCNT 0x2C
|
|
#define ADC_DETINTER 0x30
|
|
#define ADC_SCTR 0x34
|
|
|
|
#define ADC_CLK_FREQ 1000000
|
|
#define ADC_DEBOUNCE_CNT 0x10000
|
|
|
|
static void adc_set_deinter(uint32_t count)
|
|
{
|
|
/* dbncnt * freq_adc / (2 * freq_apb) */
|
|
int mincnt = ADC_DEBOUNCE_CNT * ulClkGetRate(CLK_ADC) / 2 / ulClkGetRate(CLK_APB);
|
|
|
|
writel(configMAX(mincnt, count), REGS_ADC_BASE + ADC_DETINTER);
|
|
}
|
|
|
|
void adc_channel_enable(eAdcChannel ch)
|
|
{
|
|
uint32_t ctr, imr;
|
|
|
|
configASSERT(ch >= ADC_CH_BAT && ch <= ADC_CH_AUX7);
|
|
|
|
ctr = readl(REGS_ADC_BASE + ADC_CTR);
|
|
imr = readl(REGS_ADC_BASE + ADC_IMR);
|
|
|
|
switch(ch) {
|
|
case ADC_CH_BAT:
|
|
ctr |= 1 << ADC_CH_BAT;
|
|
imr &= ~BAT_INT;
|
|
break;
|
|
|
|
case ADC_CH_TP:
|
|
ctr |= 1 << ADC_CH_TP;
|
|
imr &= ~(TP_START_INT | TP_STOP_INT | TP_VALUE_INT);
|
|
break;
|
|
|
|
case ADC_CH_AUX0:
|
|
ctr |= (1 << 8) | (1 << ADC_CH_AUX0);
|
|
imr &= ~(AUX0_START_INT | AUX0_STOP_INT | AUX0_VALUE_INT);
|
|
break;
|
|
|
|
case ADC_CH_AUX1:
|
|
ctr |= (1 << 9) | (1 << ADC_CH_AUX1);
|
|
imr &= ~(AUX1_START_INT | AUX1_STOP_INT | AUX1_VALUE_INT);
|
|
break;
|
|
|
|
case ADC_CH_AUX2:
|
|
ctr |= (1 << 10) | (1 << ADC_CH_AUX2);
|
|
imr &= ~(AUX2_START_INT | AUX2_STOP_INT | AUX2_VALUE_INT);
|
|
break;
|
|
|
|
case ADC_CH_AUX3:
|
|
ctr |= (1 << 11) | (1 << ADC_CH_AUX3);
|
|
imr &= ~(AUX3_START_INT | AUX3_STOP_INT | AUX3_VALUE_INT);
|
|
break;
|
|
case ADC_CH_AUX4:
|
|
ctr |= (1 << 24) | (1 << 20);
|
|
imr &= ~(AUX4_START_INT | AUX4_STOP_INT | AUX4_VALUE_INT);
|
|
break;
|
|
|
|
case ADC_CH_AUX5:
|
|
ctr |= (1 << 25) | (1 << 21);
|
|
imr &= ~(AUX5_START_INT | AUX5_STOP_INT | AUX5_VALUE_INT);
|
|
break;
|
|
|
|
case ADC_CH_AUX6:
|
|
ctr |= (1 << 26) | (1 << 22);
|
|
imr &= ~(AUX6_START_INT | AUX6_STOP_INT | AUX6_VALUE_INT);
|
|
break;
|
|
|
|
case ADC_CH_AUX7:
|
|
ctr |= (1 << 27) | (1 << 23);
|
|
imr &= ~(AUX7_START_INT | AUX7_STOP_INT | AUX7_VALUE_INT);
|
|
break;
|
|
}
|
|
|
|
writel(ctr, REGS_ADC_BASE + ADC_CTR);
|
|
writel(imr, REGS_ADC_BASE + ADC_IMR);
|
|
}
|
|
|
|
void adc_channel_disable(eAdcChannel ch)
|
|
{
|
|
uint32_t ctr, imr;
|
|
|
|
configASSERT(ch >= ADC_CH_BAT && ch <= ADC_CH_AUX7);
|
|
|
|
ctr = readl(REGS_ADC_BASE + ADC_CTR);
|
|
imr = readl(REGS_ADC_BASE + ADC_IMR);
|
|
|
|
switch(ch) {
|
|
case ADC_CH_BAT:
|
|
ctr &= ~(1 << ADC_CH_BAT);
|
|
imr |= BAT_INT;
|
|
break;
|
|
|
|
case ADC_CH_TP:
|
|
ctr &= ~(1 << ADC_CH_TP);
|
|
imr |= (TP_START_INT | TP_STOP_INT | TP_VALUE_INT);
|
|
break;
|
|
|
|
case ADC_CH_AUX0:
|
|
ctr &= ~((1 << 8) | (1 << ADC_CH_AUX0));
|
|
imr |= (AUX0_START_INT | AUX0_STOP_INT | AUX0_VALUE_INT);
|
|
break;
|
|
|
|
case ADC_CH_AUX1:
|
|
ctr &= ~((1 << 9) | (1 << ADC_CH_AUX1));
|
|
imr |= (AUX1_START_INT | AUX1_STOP_INT | AUX1_VALUE_INT);
|
|
break;
|
|
|
|
case ADC_CH_AUX2:
|
|
ctr &= ~((1 << 10) | (1 << ADC_CH_AUX2));
|
|
imr |= (AUX2_START_INT | AUX2_STOP_INT | AUX2_VALUE_INT);
|
|
break;
|
|
|
|
case ADC_CH_AUX3:
|
|
ctr &= ~((1 << 11) | (1 << ADC_CH_AUX3));
|
|
imr |= (AUX3_START_INT | AUX3_STOP_INT | AUX3_VALUE_INT);
|
|
break;
|
|
|
|
case ADC_CH_AUX4:
|
|
ctr &= ~((1 << 24) | (1 << 20));
|
|
imr |= (AUX4_START_INT | AUX4_STOP_INT | AUX4_VALUE_INT);
|
|
break;
|
|
|
|
case ADC_CH_AUX5:
|
|
ctr &= ~((1 << 25) | (1 << 21));
|
|
imr |= (AUX5_START_INT | AUX5_STOP_INT | AUX5_VALUE_INT);
|
|
break;
|
|
|
|
case ADC_CH_AUX6:
|
|
ctr &= ~((1 << 26) | (1 << 22));
|
|
imr |= (AUX6_START_INT | AUX6_STOP_INT | AUX6_VALUE_INT);
|
|
break;
|
|
|
|
case ADC_CH_AUX7:
|
|
ctr &= ~((1 << 27) | (1 << 23));
|
|
imr |= (AUX7_START_INT | AUX7_STOP_INT | AUX7_VALUE_INT);
|
|
break;
|
|
}
|
|
|
|
writel(ctr, REGS_ADC_BASE + ADC_CTR);
|
|
writel(imr, REGS_ADC_BASE + ADC_IMR);
|
|
|
|
}
|
|
|
|
static void adc_int_handler(void *para)
|
|
{
|
|
uint32_t status;
|
|
#ifdef ADC_TOUCH
|
|
uint32_t xpos, ypos;
|
|
#endif
|
|
//uint32_t value;
|
|
|
|
status = readl(REGS_ADC_BASE + ADC_STA);
|
|
writel(0, REGS_ADC_BASE + ADC_STA);
|
|
|
|
//printf("adc_int_handler status=0x%x.\n", status);
|
|
|
|
if (status & TP_START_INT) {
|
|
#ifdef ADC_TOUCH
|
|
TouchEventHandler(TOUCH_START_EVENT, 0, 0);
|
|
#endif
|
|
}
|
|
|
|
if (status & TP_STOP_INT) {
|
|
#ifdef ADC_TOUCH
|
|
TouchEventHandler(TOUCH_STOP_EVENT, 0, 0);
|
|
#endif
|
|
}
|
|
|
|
if (status & TP_VALUE_INT) {
|
|
#ifdef ADC_TOUCH
|
|
xpos = readl(REGS_ADC_BASE + ADC_PANXZ1);
|
|
ypos = readl(REGS_ADC_BASE + ADC_PANXZ2);
|
|
//printf("tp press %d, %d.\n", xpos, ypos);
|
|
TouchEventHandler(TOUCH_SAMPLE_EVENT, xpos, ypos);
|
|
#endif
|
|
}
|
|
|
|
if (status & AUX0_START_INT) {
|
|
#ifdef ADC_KEY
|
|
KeyEventHandler(KEY_START_EVENT, 0, 0);
|
|
#endif
|
|
}
|
|
|
|
if (status & AUX0_STOP_INT) {
|
|
#ifdef ADC_KEY
|
|
KeyEventHandler(KEY_STOP_EVENT, 0, 0);
|
|
#endif
|
|
}
|
|
|
|
if (status & AUX0_VALUE_INT) {
|
|
#ifdef ADC_KEY
|
|
uint32_t value = readl(REGS_ADC_BASE + ADC_AUX0);
|
|
KeyEventHandler(KEY_SAMPLE_EVENT, value, 0);
|
|
#endif
|
|
}
|
|
|
|
#if 0
|
|
if (status & AUX1_START_INT) {
|
|
|
|
}
|
|
|
|
if (status & AUX1_STOP_INT) {
|
|
|
|
}
|
|
|
|
if (status & AUX1_VALUE_INT) {
|
|
value = readl(REGS_ADC_BASE + ADC_AUX1);
|
|
}
|
|
|
|
if (status & AUX2_START_INT) {
|
|
|
|
}
|
|
|
|
if (status & AUX2_STOP_INT) {
|
|
|
|
}
|
|
|
|
if (status & AUX2_VALUE_INT) {
|
|
value = readl(REGS_ADC_BASE + ADC_AUX2);
|
|
}
|
|
|
|
if (status & AUX3_START_INT) {
|
|
|
|
}
|
|
|
|
if (status & AUX3_STOP_INT) {
|
|
|
|
}
|
|
|
|
if (status & AUX3_VALUE_INT) {
|
|
value = readl(REGS_ADC_BASE + ADC_AUX3);
|
|
}
|
|
|
|
if (status & AUX4_START_INT) {
|
|
|
|
}
|
|
|
|
if (status & AUX4_STOP_INT) {
|
|
|
|
}
|
|
|
|
if (status & AUX4_VALUE_INT) {
|
|
value = readl(REGS_ADC_BASE + ADC_AUX4);
|
|
}
|
|
|
|
if (status & AUX5_START_INT) {
|
|
|
|
}
|
|
|
|
if (status & AUX5_STOP_INT) {
|
|
|
|
}
|
|
|
|
if (status & AUX5_VALUE_INT) {
|
|
value = readl(REGS_ADC_BASE + ADC_AUX5);
|
|
}
|
|
|
|
if (status & AUX6_START_INT) {
|
|
|
|
}
|
|
|
|
if (status & AUX6_STOP_INT) {
|
|
|
|
}
|
|
|
|
if (status & AUX6_VALUE_INT) {
|
|
value = readl(REGS_ADC_BASE + ADC_AUX6);
|
|
}
|
|
|
|
if (status & AUX7_START_INT) {
|
|
|
|
}
|
|
|
|
if (status & AUX7_STOP_INT) {
|
|
|
|
}
|
|
|
|
if (status & AUX7_VALUE_INT) {
|
|
value = readl(REGS_ADC_BASE + ADC_AUX7);
|
|
}
|
|
|
|
if (status & BAT_INT) {
|
|
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void adc_init(void)
|
|
{
|
|
vSysctlConfigure(SYS_ANA1_CFG, 7, 1, 0); // ref : 3.3v
|
|
|
|
vClkSetRate(CLK_ADC, ADC_CLK_FREQ);
|
|
|
|
/* reset adc modulex */
|
|
writel(readl(REGS_ADC_BASE + ADC_CTR) | 1, REGS_ADC_BASE + ADC_CTR);
|
|
|
|
/* disable all adc channel */
|
|
writel(readl(REGS_ADC_BASE + ADC_CTR) & ~0x7e, REGS_ADC_BASE + ADC_CTR);
|
|
|
|
/* disable and clear irq */
|
|
writel(0xffffffff, REGS_ADC_BASE + ADC_IMR);
|
|
writel(0, REGS_ADC_BASE + ADC_STA);
|
|
|
|
/* set debounce count */
|
|
writel(ADC_DEBOUNCE_CNT, REGS_ADC_BASE + ADC_DBNCNT);
|
|
|
|
adc_set_deinter(50);
|
|
|
|
request_irq(ADC_IRQn, 0, adc_int_handler, NULL);
|
|
}
|
|
|
|
unsigned int adc_get_channel_value(int ch)
|
|
{
|
|
int i;
|
|
|
|
configASSERT(ch >= ADC_CH_AUX0 && ch <= ADC_CH_AUX7);
|
|
|
|
adc_channel_disable(ADC_CH_TP);
|
|
for (i = ADC_CH_AUX0; i <= ADC_CH_AUX7; i++) {
|
|
if (ch == i)
|
|
adc_channel_enable(i);
|
|
else
|
|
adc_channel_disable(i);
|
|
}
|
|
vTaskDelay(pdMS_TO_TICKS(10));
|
|
if(ch<=ADC_CH_AUX3)
|
|
{
|
|
return readl(REGS_ADC_BASE + ADC_AUX0 + 4 * (ch - ADC_CH_AUX0));
|
|
}
|
|
else
|
|
{
|
|
return readl(REGS_ADC_BASE + ADC_AUX4 + 4 * (ch - ADC_CH_AUX4));
|
|
}
|
|
}
|