打印

44B0 读取flash am29lv160db的问题

[复制链接]
4456|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hero415|  楼主 | 2007-8-10 10:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
各位大虾,小弟在学习44b0,目前在调试在线编程flash am29lv160db的试验时,遇到一些问题,三四天了都没有办法解决,实在郁闷,望各位大虾指点,作为报酬,可以提供我刚刚调试好的以太网驱动程序,该程序在我的板子上已经运行良好,保证可以使用。
我的问题如下:
用c写的程序,每次读此flash的厂商id和设备id时都不正确,逼于无奈,嵌入了一段汇编代码,可以正确读出第一参数,但是第二个参数,即厂商id争取,设备id错误,把程序的次序调换一下,设备id又正确,厂商id 又错误,实在没辙。
具体代码如下:

int CMDam29lv160(int argc, char *argv[])
{
    U32 id;
    id=0xffffffff;
    rNCACHBE0=((0x2000000>>12)<<16 )|(0x0>12); //flash area must be non-cachable area.
    rNCACHBE1=(((U32)0xc000000>>12)<<16 )|(U32)(0x6000000>>12); //flash area must be non-cachable area.
    rSYSCFG=rSYSCFG&(~0x8); //write buffer has to be off for proper timing.    
    id=GetFlashId();
    Uart_Printf(" Flash id=0x%x",id);        
    return 0;
}

unsigned int GetFlashId (void) 
{
    unsigned short i,j;
    i=0;j=0;
   
        __asm {
mov      r0,#0xf0
mov      r4,#0x00
mov      r8,#0xaa
mov      r5,#0xa00
mov      r9,#0x55
mov      r10,#0x500
mov      r11,#0x90

strh     r0,[r4,#0]        

strh     r8,[r5,#0xaa]    
strh       r9,[r10,#0x54]
strh     r11,[r5,#0xaa]
ldrh     r2,[r4,#0]
ldrh     r3,[r4,#2]

mov     i,r2
mov     j,r3

        };
  return ((unsigned int)((i<<16) |j));  
}
至于c语言的代码,参考了三星的代码都不行。

请各位指点,先谢谢各位大虾了。

相关帖子

沙发
hero415|  楼主 | 2007-8-10 10:25 | 只看该作者

c 代码,读出都不正确

#define _WR(addr,data)    *(( unsigned short *)((addr)<<1))=(unsigned short)(data)
#define _RD(addr)    *((unsigned short *)((addr)<<1))
#define _RESET()    _WR(0x0,0xf0f0)         



   _RESET();
    
    _WR(0x555,0xaa);
    _WR(0x2aa,0x55);
    _WR(0x555,0x90);
    i=_RD(0x0);
    _RESET();
    
    _WR(0x555,0xaa);
    _WR(0x2aa,0x55);
    _WR(0x555,0x90);
    j=_RD(0x1);

    _RESET();

使用特权

评论回复
板凳
hero415|  楼主 | 2007-8-10 13:29 | 只看该作者

关闭cache和中断,还是不对。

rINTMSK= BIT_GLOBAL;
rNCACHBE0=((0x2000000>>12)<<16 )|(0x0>12); //flash area must be non-cachable area.
rNCACHBE1=(((U32)0xc000000>>12)<<16 )|(U32)(0x6000000>>12); //flash area must be non-cachable area.  
rSYSCFG=0x00;

c代码,
unsigned int GetFlashId (void) 
{
    unsigned short i,j;
    i=0;j=0;
  
    _RESET();
    
    _WR(0x555,0xaa);
    _WR(0x2aa,0x55);
    _WR(0x555,0x90);
    i=_RD(0x0);
    
    _WR(0x555,0xaa);
    _WR(0x2aa,0x55);
    _WR(0x555,0x90);
    j=_RD(0x1);

    _RESET();
 
  return ((unsigned int)((i<<16) |j));  // Wait until Erase completed
}

执行的结果是
Flash id=0xf0f0ea00

显然都不对。

使用特权

评论回复
地板
lishuanghua| | 2007-8-10 20:06 | 只看该作者

是否是在RAM里面运行?

不能在flash里面运行 编程flash本身 的代码

使用特权

评论回复
5
lishuanghua| | 2007-8-10 20:10 | 只看该作者

一个自己写的例子

///////////////////////////////////////////////////////////////
//    读取flash(MBM29LV160)厂商、器件代码和扇区保护信息:     //
//    输入:                                                  //
//        无。                                               //
//    输出:                                                  //
//        将厂商代码保存到manufacture_code;                  //
//        将器件代码保存到device_code;                       //
//        将扇区保护信息保存到Sector_Protection_status数组;  //
//                                            2003.05.28Li.SH//
///////////////////////////////////////////////////////////////
void    flash_get_device_inf(void)
{
unsigned char     *addr_aaa,*addr_555,*addr_sa,i;
unsigned long    rINTMSK_TEMP;

    rINTMSK_TEMP = rINTMSK;        //Save interrupt controller
    rINTMSK = 0x07ffffff;            //Masked all interrupt

    addr_aaa = 0xaaa;
    addr_555 = 0x555;                //command address
//    read manufacture code and device_code:
    *addr_aaa = 0xaa;
    *addr_555 = 0x55;
    *addr_aaa = 0x90;            //Autoselect command.
    
    addr_sa = 0x001fff00;
    manufacture_code = *addr_sa;
    
    addr_sa = 0x001fff02;
    device_code = *addr_sa;
    
    if(manufacture_code == 4)
    {
        if(device_code == 0x49)    //MBM29LV160BE
        {
            for(i = 0;i < 35;++i)
            {
                addr_sa = MBM29LV160BE_Sector_tab.SectorAddress;
                addr_sa += 4;
                Sector_Protection_status = *addr_sa;
            }
        }
        else if(device_code == 0xc4)    //MBM29LV160TE
        {
            for(i = 0;i < 35;++i)
            {
                addr_sa = MBM29LV160TE_Sector_tab.SectorAddress;
                addr_sa += 4;
                Sector_Protection_status = *addr_sa;
            }
        }
    }
    *addr_aaa = 0xaa;
    *addr_555 = 0x55;
    *addr_aaa = 0xf0;            //Read/Reset command.

    *(unsigned long*)0x1e0000c = rINTMSK_TEMP;        //recover interrupt controller
}

使用特权

评论回复
6
hero415|  楼主 | 2007-8-11 10:35 | 只看该作者

问题终于 解决,真是谁也想不到的问题。

经过反复的试验发现,am29lv160db-90,居然需要在复位指令后延时一段时间,然后再复位一次才可以。怪不得我们买的开发板带的例程也对,想必他们也没有调试出来,谁知居然问题出在这里。
全部代码如下:
int CMDam29lv160(int argc, char *argv[])
{
    U32 n,s,m;
    U16 flag;
    n=rNCACHBE0;
    s=rSYSCFG;
    m=rINTMSK;

    rNCACHBE0=((0xc000000>>12)<<16 )|(0x0>12);
    rSYSCFG=rSYSCFG&(~0x8); //write buffer has to be off for proper timing.    
     rINTMSK= BIT_GLOBAL;
    ProgramAM29F800();

    rNCACHBE0=n;
    rSYSCFG=s; //write buffer has to be off for proper timing.    
     rINTMSK= m;
     
    return 0;
}

.....
#define    moutportw(data,port)        (*(volatile unsigned short *)(port<<1) = (volatile unsigned int)(data))

#define    minportw(port)            *(volatile unsigned short *)(port<<1)





int AM29F800_CheckId(void)
{
    U16 manId,devId;
moutportw(0xf0f0,0x0);
Delay(100);
moutportw(0xf0f0,0x0);

moutportw(0xaaaa,0x555);
moutportw(0x5555,0x2aa);
moutportw(0x9090,0x555);
manId=minportw(0x0);

moutportw(0xf0f0,0x0);
Delay(100);
moutportw(0xf0f0,0x0);
moutportw(0xaaaa,0x555);
moutportw(0x5555,0x2aa);
moutportw(0x9090,0x555);
devId=minportw(0x1);
moutportw(0xf0f0,0x0);

    if(manId==0x0001 && devId==0x22bf) return 1; // AM29LV200B
    else if(manId==0x0001 && devId==0x22ba) return 2; // AM29LV400B
    else if(manId==0x0001 && devId==0x225b) return 3; // AM29LV800B
    else if(manId==0x0001 && devId==0x2249) return 4; // AM29LV160B        
    else if(manId==0x0004 && devId==0x2249) return 4; // 29LV160B fairchild        
    else return 0;
}



希望对其他兄弟们有点作用。。
谢谢各位大虾的指导。

使用特权

评论回复
7
jsheng| | 2007-8-11 11:15 | 只看该作者

厉害

楼上都是高手啊.

使用特权

评论回复
8
hero415|  楼主 | 2007-8-11 19:18 | 只看该作者

艾,感觉自己太菜了

费尽心机可以读出flash的id,但是随后却发现,无论如何都不能成功擦除,更别提写了。实在没辙,把44binit.s和三星的对比了一下,发现有点差异,改为和三星一样,还是不行,bank0的时序参数设定改为最大,也不行。郁闷!

于是,我想到了5楼的话,我是不是还在“flash”中运行阿?
由于编译设置ro=0,rw=0x0c000000,我用axd进行了方针跑一下,居然跑到主程序里时,pc=0000xxxx,郁闷,这不还在bank0吗。

然后我们把板子的程序烧成44bmon,还有将我的应用程序重新编译,ro=0xc000000,再下载到ram中运行,情况一下就好了,可以擦除和比较了。

请问大虾们,44binit.s中不是有一段代码是将ro copy 到rw的吗,怎么最后还是在flash中运行呢?

使用特权

评论回复
9
lishuanghua| | 2007-8-11 22:41 | 只看该作者

你编译设置ro=0当然是从0开始了

ro就是只读。仿真的时候不需要将代码"copy"到RAM里面,因为axd会直接奖代码下载到你设置的ro开始的地方。

使用特权

评论回复
10
raoxianbin| | 2014-3-19 20:31 | 只看该作者
借鉴了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

14

帖子

0

粉丝