UBOOT里IMM_GetOneChannelValue()这个函数为啥读出来为0?
什么平台啊
MT6575平台
之前做15时,要改寄存器的,75不是很清楚
改哪里?能否发下代码?
Uboot AUXADC讀取說明:
1. Register base address 的定義 mediatek\platform\mt6575\uboot\inc\asm\arch\mt6575_auxadc_hw.h
#define AUXADC_BASE 0xC1006000 // modify(differ with kernel auxadc base address)
#define AUXADC_CON0 (AUXADC_BASE + 0x000)
#define AUXADC_CON1 (AUXADC_BASE + 0x004)
#define AUXADC_CON1_SET (AUXADC_BASE + 0x008)l
#define AUXADC_CON1_CLR (AUXADC_BASE + 0x00C)
#define AUXADC_CON2 (AUXADC_BASE + 0x010)
#define AUXADC_CON3 (AUXADC_BASE + 0x014)
#define AUXADC_DAT0 (AUXADC_BASE + 0x018)
#define AUXADC_DAT1 (AUXADC_BASE + 0x01C)
#define AUXADC_DAT2 (AUXADC_BASE + 0x020)
#define AUXADC_DAT3 (AUXADC_BASE + 0x024)
#define AUXADC_DAT4 (AUXADC_BASE + 0x028)
#define AUXADC_DAT5 (AUXADC_BASE + 0x024+0x008)
#define AUXADC_DAT6 (AUXADC_BASE + 0x028+0x008)
#define AUXADC_DAT7 (AUXADC_BASE + 0x02C+0x008)
#define AUXADC_DAT8 (AUXADC_BASE + 0x030+0x008)
#define AUXADC_DAT9 (AUXADC_BASE + 0x034+0x008)
#define AUXADC_DAT10 (AUXADC_BASE + 0x038+0x008)
#define AUXADC_DAT11 (AUXADC_BASE + 0x03C+0x008)
#define AUXADC_DAT12 (AUXADC_BASE + 0x040+0x008)
#define AUXADC_DAT13 (AUXADC_BASE + 0x044+0x008)
#define AUXADC_DET_VOLT (AUXADC_BASE + 0x084)
#define AUXADC_DET_SEL (AUXADC_BASE + 0x088)
#define AUXADC_DET_PERIOD (AUXADC_BASE + 0x08C)
#define AUXADC_DET_DEBT (AUXADC_BASE + 0x090)
#define AUXADC_MISC (AUXADC_BASE + 0x094)
#define AUXADC_ECC (AUXADC_BASE + 0x098)
#define AUXADC_SAMPLE_LIST (AUXADC_BASE + 0x09c)
#define AUXADC_ABIST_PERIOD (AUXADC_BASE + 0x0A0)
2. IMM_GetOneChannelValue API的實現mediatek\platform\mt6575\uboot\mt6575_auxadc.c
static int adc_auto_set =0;
int IMM_GetOneChannelValue(int dwChannel, int data[4], int* rawdata)
{
unsigned int channel[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int idle_count =0;
int data_ready_count=0;
// unsigned int i = 0, data = 0;
// unsigned int poweron, poweroff;
// Polling until bit STA = 0
while ((*(volatile u16 *)AUXADC_CON3) & 0x01)
{
printf("[adc_api]: wait for module idle\n");
// msleep(100);
udelay(100000);
idle_count++;
if(idle_count>30)
{
//wait for idle time out
printf("[adc_api]: wait for aux/adc idle time out\n");
return -1;
}
}
while ((*(volatile u16 *)(AUXADC_DAT0 + dwChannel * 0x04)) & (1<<12))
{
printf("[adc_api]: wait for channel[%d] data ready\n",dwChannel);
// msleep(100);
udelay(100000);
data_ready_count++;
if(data_ready_count>30)
{
//wait for idle time out
printf("[adc_api]: wait for channel[%d] data ready time out\n",dwChannel);
return -2;
}
}
//read data
if(0==adc_auto_set)
{
//clear bit
*(volatile u16 *)AUXADC_CON1 = *(volatile u16 *)AUXADC_CON1 & (~(1 << dwChannel));
// msleep(20);
udelay(20000);
//set bit
*(volatile u16 *)AUXADC_CON1 = *(volatile u16 *)AUXADC_CON1 | (1 << dwChannel);
}
// msleep(20);
udelay(20000);
//read data
channel[dwChannel] = (*(volatile u16 *)(AUXADC_DAT0 + dwChannel * 0x04)) & 0x0FFF;
if(NULL != rawdata)
{
*rawdata = channel[dwChannel];
}
//printk("[adc_api: imm mode raw data => channel[%d] = %d\n",dwChannel, channel[dwChannel]);
//printk("[adc_api]: imm mode => channel[%d] = %d.%d\n", dwChannel, (channel[dwChannel] * 250 / 4096 / 100), ((channel[dwChannel] * 250 / 4096) % 100));
data[0] = (channel[dwChannel] * 250 / 4096 / 100);
data[1] = ((channel[dwChannel] * 250 / 4096) % 100);
// msleep(20);
udelay(20000);
if(0 == adc_auto_set)
{
//clear bit
*(volatile u16 *)AUXADC_CON1 = *(volatile u16 *)AUXADC_CON1 & (~(1 << dwChannel));
}
return 0;
}
3. Test whether it can work normally--- API call
void mt6575_adc_test()
{
int i = 0, data[4] = {0,0,0,0};
int res =0;
int rawdata=0;
long tmo1;
for (i = 0; i < 14; i++)
{
printf("[adc_driver]: i=%d\n",i);
res = IMM_GetOneChannelValue(i,data,&rawdata);
if(res < 0)
{
printf("[adc_driver]: get data error\n");
break;
}
else
{
printf("[adc_driver]: channel[%d]raw =%d\n",i,rawdata);
printf("[adc_driver]: channel[%d]=%d.%d \n",i,data[0],data[1]);
}
tmo1 = get_timer(0);
while(get_timer(tmo1) <= 500 /* ms */);
}
}
我照着这份代码,读出来的数值和电表上量出来的还是有点差异
自己调整咯,75、15内部ADC最高电压是2.5V