微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 手机设计讨论 > MTK手机平台交流 > UBOOT里IMM_GetOneChannelValue()这个函数为啥读出来为0?

UBOOT里IMM_GetOneChannelValue()这个函数为啥读出来为0?

时间:10-02 整理:3721RD 点击:
我在UBOOT里通过IMM_GetOneChannelValue()这个函数读取ADC2的值,结果所有的channel都为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

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top