MAX_CARLINK_A270S/MXC_A27-PCB4.5-270T/ArkmicroFiles/libcpu-amt630hv100/source/adc.c

364 lines
7.0 KiB
C
Raw Normal View History

2025-01-21 16:49:37 +08:00
#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));
}
}