Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1303396
  • 博文数量: 92
  • 博客积分: 10389
  • 博客等级: 上将
  • 技术积分: 1918
  • 用 户 组: 普通用户
  • 注册时间: 2006-08-10 16:13
文章存档

2014年(1)

2012年(15)

2009年(6)

2008年(37)

2007年(72)

2006年(54)

我的朋友

分类: LINUX

2009-02-04 17:08:47

在系统启动中偶尔会遇到SDRAM数据线和地址线有短路或者没有焊接等情况
有必要提高一个测试手段来检测。
 
 
Object: MT48LC4M32B2
Configuration   1M*32*4bank
refresh count  4 k
Row addressing      4k[a0---a11]
Bank addressing      4[BA0,BA1]
Column addressing   256[A0--A7]
 
 
---------------------------------------------------------------------------------
 

/*--------------------------------------------------------------------------------------
Function Name        :测试SDRAM的数据线和地址线是否有短路等焊接问题。
input p                 :null
output p              :null
sdram configuration:
sdram: 16MB【字节】
MTSDRAM共32条数据线,SDRAMC_A【12:0】共用地址线,bank片选  BK【1:0】
32-bit data bus width
地址线分配:共24位
23--22   21-----10  9----------0 
Bk[1:0]      Row[11:0]  Column[7:0] 
检测方法:可以基本判定数据线与地址线是否有短路,具体那条线有问题的判定方法有局限性。
针对数据线:
1和0两次轮询的检测,
如  1轮询,对某一地址如0x1000,写入32次只有1个位为1 其他都为0的32位数【移位操作】,后再读此地址中数值与写入值比较,即可确定32位数据线中那条线有短路。
次数  需要写入的值   操作
0  0x1    1左移0
1  0x2    1左移1
2  0x4    1左移2
3  0x8    1左移3
4  0x10    1左移4
5  0x20    1左移5
6  0x40    1左移6
7  0x80    1左移7
。  。    。
。  。    。
。  。    。
31  0x80000000   1左移31
如  0轮询,对某一地址如0x1000,写入32次只有1个位为0其他都为1的32位数【移位操作后取反】,后再读此地址中数值与写入值比较,即可确定32位数据线中那条线有短路。
次数  需要写入的值   操作
0  ~0x1    1左移0取反
1  ~0x2    1左移1取反
2  ~0x4    1左移2取反
3  ~0x8    1左移3取反
4  ~0x10   1左移4取反
5  ~0x20   1左移5取反
6  ~0x40   1左移6取反
7  ~0x80   1左移7取反
。  。    。
。  。    。
。  。    。
31  ~0x80000000  1左移31取反

针对地址线:
因为地址线是Row[11:0]和Column[7:0]  共用
取Row来测试即21--10IO线和B1,B0
需要2个循环,循环1是写初始值,循环2是比较。
@从0x20000000开始16字节按照32存取即4字节一组进行写值操作。写入的值为对应地址。
@从0x20000000地址开始读值比较,可以初步确定地址线是否有问题,具体确定是那条线的算法见
程序部分,
--------------------------------------------------------------------------------------*/
void test_sdram_ok(void)
{
 unsigned long i,j;
 //unsigned  char data[1024];
 volatile unsigned long *ptadr=NULL; //需要volatile
 volatile unsigned long tval;   //需要volatile
 unsigned long gval;
 unsigned long  anddata;
 unsigned long flage[14];
 unsigned long *adrdes=(unsigned long *)(0x20400000);
 int addr_flag=0;
 /* test data bus */
 printf("###Test Sdram Data Bus -1###\n\r");
 
 ptadr=adrdes+0x40000; //随机一个地址
  
 for(j=0;j<32;j++) //32位数据线 
 {
  tval=(1<  *ptadr=tval; //写值
  gval=*ptadr; //读值
   
  if(tval!=gval) //比较
  {
   printf("Bad Data Line Is [%d](0~31)\n\r",j);
  }
 }
 
 printf("###Test Sdram Data Bus -0 ###\n\r");
 
 ptadr=adrdes+0x40000;
 
 for(j=0;j<32;j++)
 {
  tval=~(1<  *ptadr=tval;
  gval=*ptadr;
   
  if(tval!=gval)
  {
   printf("Bad Data Line Is [%d](0~31)\n\r",j);
  }
 } 
 
 
 printf("###Test Sdram Addr Bus###\n\r");
 
 for(i=0;i<14;i++)
 flage[i]=0;
 adrdes=(unsigned long *)(0x20000000);
 for(i=0;i<0x400000;i++)//0x400000  4字节寻址,所以共16M
 {
  tval=(unsigned long)adrdes;
  *adrdes=tval;
  adrdes++;
 }
 
 adrdes=(unsigned long *)(0x20000000);
 
 for(i=0;i<0x400000;i++)//0x400000
 {
  tval=(unsigned long)adrdes;
  gval=*adrdes;
  if(tval!=gval)
  {
   anddata=gval-tval;
   anddata=anddata&0xfffc00;
   //printf("anddata %x addr %x(unsigned long ) val of read this addr %x  \n\r",anddata,tval,gval);
   if(addr_flag==0)
   {
    addr_flag=1;
    printf("Sdram Addr Bus Bad\n");
   }
   
   if(anddata!=0)
   {
    switch(anddata)
    {
     case 0x400:
     if(flage[0]==0)
     {
      flage[0]=1;
      printf("sdram adr line 0\n\r");
     }
     break;
     case 0x800:
     if(flage[1]==0)
     {
      flage[1]=1;
      printf("sdram adr line 1\n\r");
     }
     break;
     case 0x1000:
     if(flage[2]==0)
     {
      flage[2]=1;
      printf("sdram adr line 2\n\r");
     }
     break;
     case 0x2000:
     if(flage[3]==0)
     {
      flage[3]=1;
      printf("sdram adr line 3\n\r");
     }
     break;
     case 0x4000:
     if(flage[4]==0)
     {
      flage[4]=1;
      printf("sdram adr line 4\n\r");
     }
     break;
     case 0x8000:
     if(flage[5]==0)
     {
      flage[5]=1;
      printf("sdram adr line 5\n\r");
     }
     break;
     case 0x10000:
     if(flage[6]==0)
     {
      flage[6]=1;
      printf("sdram adr line 6\n\r");
     }
     break; 
     case 0x20000:
     if(flage[7]==0)
     {
      flage[7]=1;
      printf("sdram adr line 7\n\r");
     }
     break;
     case 0x40000:
     if(flage[8]==0)
     {
      flage[8]=1;
      printf("sdram adr line 8\n\r");
     }
     break;
     case 0x80000:
     if(flage[9]==0)
     {
      flage[9]=1;
      printf("sdram adr line 9\n\r");
    
     }
     break;
     case 0x100000:
     if(flage[10]==0)
     {
      flage[10]=1;
      printf("sdram adr line 10\n\r");
     }
     break;
     case 0x200000:
     if(flage[11]==0)
     {
      flage[11]=1;
      printf("sdram adr line 11\n\r");
     }
     break;
     case 0x400000:
     if(flage[12]==0)
     {
      flage[12]=1;
      printf("sdram adr line BA0\n\r");
     }
     break;
     case 0x800000:
     if(flage[13]==0)
     {
      flage[13]=1;
      printf("sdram adr line BA1\n\r");
     }
     break;
   }
  }   
  //printf("addr  %x(unsigned long)   val of read this addr  %x\n\r",tval,gval);
  }
  adrdes++;
 }
 printf("Sdram test over\n");
}
 
 
 
 
 

 
阅读(4070) | 评论(1) | 转发(1) |
0

上一篇:USB模拟串口

下一篇:可重入函数列表

给主人留下些什么吧!~~

geekite82015-02-03 14:30:40

如  1轮询,对某一地址如0x1000,写入32次只有1个位为1 其他都为0的32位数【移位操作】,后再读此地址中数值与写入值比较。您好,请问下,是写入一次,就读出来与写入值比较,还是先写完32次,再读出来比较啊?如果是是先写完32次再读的话,读出来的数据就是最后一次写入的数据啊,那就不能测试全部数据线了