This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DM642的flash烧写问题



各位大神,能否为小弟解答一个问题?我现在仿照合众达seed642自己做了一块基于DM642的板子,

没有使用cpld,flash用的是Am29LV033C,4M的,22根地址线,DM642只有20根地址线,所以我用

了两个GPIO口来扩充。现在想实现flash的烧写,但手中的例程都是基于cpld的,而且看不太明白,

请大神帮我看看,万分感谢。我是DSP新手,还望诸位见谅~

  • 你好,首先CPLD和FLASH并没关系,对FLASH的读写不受CPLD的影响,因为访问FLASH走的EMIF总线。那个例程的CPLD是意在读取存储在FLASH里的程序到CPLD里运行。所以你只用分析\evmdm642\evmdm642\flashburn\FBTC642里面的代码就可以了。至少FLASH低位空间访问是没有问题的。高位需要GPIO来模拟,这时候需要改这部分代码了。

  • 首先,谢谢您抽出时间来回复我。我先看看您说的这个代码,有问题我再向您请教。

  • 您好,我最近研读了一下有关seed开发板上有关flash烧写的程序,理解了七七八八吧,但是有一个地方我有点不明白,请您帮我看看行吗?

    下面是我感到困惑的地方:

    for(page = 0;page<8;page++)
    {
    /*取FLASh的首址*/
    addr = SEEDDM642_FLASH_BASE;
    /* Set Flash page*/
    SEEDDM642_rset(SEEDDM642_FLASHPAGE, page);
    /*等待延时*/
    SEEDDM642_waitusec(1);
    /*将数据写入第0页,每页512K*/
    limit = 8;
    for (i = 0; i < limit; i++)
    {
    for (j = 0; j < 128; j++)
    {
    startaddr = addr;
    /*每次写入512个字节,以16位的数据为基数*/
    for (k = 0; k < 256; k++)
    {
    buffer[k] = (addr + i + page) & 0xffff;
    addr += 2;
    }
    SEEDDM642_FLASH_write((Uint32)buffer, startaddr, 512);
    }
    }

    以上是我摘录了其中一段,我明白seed642开发板个是利用19位地址线来连接flash(AMD29LV033C),

    合众达的处理是运用cpld扩展例外三根地址线,将flash分成8页,每页有512k的大小,

    我了解到该款flash的扇区大小为64K,因此上面程序中分别套用的两个循环,for (j = 0; j < 128; j++)和for (k = 0; k < 256; k++)

    就能解释的通了。

    我的问题是buffer[k] = (addr + i + page) & 0xffff;是怎么回事呢?合众达定义的这个数组是个int型说明以16位来进行赋值,

    但是这样的问题就在于i和page的作用是什么呢?如当i和page取1时,这个数组取的数又是什么呢?因为这样按位求出的结果

    貌似有误,还请大神指教

  • 您好,我最近研读了一下有关seed开发板上有关flash烧写的程序,理解了七七八八吧,但是有一个地方我有点不明白,请您帮我看看行吗?

    下面是我感到困惑的地方:

    for(page = 0;page<8;page++)
    {
    /*取FLASh的首址*/
    addr = SEEDDM642_FLASH_BASE;
    /* Set Flash page*/
    SEEDDM642_rset(SEEDDM642_FLASHPAGE, page); 
    /*等待延时*/
    SEEDDM642_waitusec(1);
    /*将数据写入第0页,每页512K*/
    limit = 8;
    for (i = 0; i < limit; i++)
    {
    for (j = 0; j < 128; j++)
    {
    startaddr = addr;
    /*每次写入512个字节,以16位的数据为基数*/
    for (k = 0; k < 256; k++)
    {
    buffer[k] = (addr + i + page) & 0xffff;
    addr += 2;
    }
    SEEDDM642_FLASH_write((Uint32)buffer, startaddr, 512);
    }
    }

    以上是我摘录了其中一段,我明白seed642开发板个是利用19位地址线来连接flash(AMD29LV033C),

    合众达的处理是运用cpld扩展例外三根地址线,将flash分成8页,每页有512k的大小,

    我了解到该款flash的扇区大小为64K,因此上面程序中分别套用的两个循环,for (j = 0; j < 128; j++)和for (k = 0; k < 256; k++)

    就能解释的通了。

    我的问题是buffer[k] = (addr + i + page) & 0xffff;是怎么回事呢?合众达定义的这个数组是个int型说明以16位来进行赋值,

    但是这样的问题就在于i和page的作用是什么呢?如当i和page取1时,这个数组取的数又是什么呢?因为这样按位求出的结果

    貌似有误,还请大神指教

  • 你好,我现在也是在调试一个DM642的板子,现在遇见问题了,是不能擦除FLASH,flash的型号是AM29LV033C。我的硬件连接没有问题,请问你知道这个可能是什么原因么?

  • 请问你的不能擦除是什么意思?我不是很明白,你可以先看看内存相应位置的数据是否改变,比如0x90000000以后的区域,你的硬件是怎么连接的?用的FPGA选通?还是I/O口模拟啊?

  • 使用CPLD选通的。就是说FLASH的扇区擦除指令,dsp是正常发送出去了的。六个周期的指令序列嘛。可是貌似flash貌似没有正确接收到指令。导致flash的扇区内嵌擦除程序不工作。我吧我的程序给你看看。

    FLASH型号:Am29LV033C

    我用一个合纵达提供的flash擦除和烧写的例程的时候,一直会死在擦除和写FLASH的函数的While循环那



    以下是擦除函数和写函数,麻烦大家看看,一块讨论讨论,我会关注本帖的,谢谢大家


    void SEEDDM642_FLASH_erase(Uint32 start, Uint32 length)
    {
        Int16 i;
        Uint8 *pdata;
        Uint32 sector_base, end;
        
        /* Calculate extents of range to erase */
        end = start + length - 1;
        
        /* Walk through each sector, erase any sectors within range */
        sector_base = SEEDDM642_FLASH_BASE;
        for (i = 0; i < SEEDDM642_FLASH_SECTORS; i++)
        {
            if ((start <= sector_base) && (sector_end[i] <= end))
            {
                /* Start sector erase sequence */
                *((Uint8 *)SEEDDM642_FLASH_BASE) = 0xAA;
              //  SEEDDM642_wait(1000);
                *((Uint8 *)SEEDDM642_FLASH_BASE) = 0x55;
                    //        SEEDDM642_wait(1000);
                *((Uint8 *)SEEDDM642_FLASH_BASE) = 0x80;
                            //SEEDDM642_wait(1000);
                *((Uint8 *)SEEDDM642_FLASH_BASE) = 0xAA;
                    //        SEEDDM642_wait(1000);
                *((Uint8 *)SEEDDM642_FLASH_BASE) = 0x55;
                    //        SEEDDM642_wait(1000);
               // *((Uint8 *)SEEDDM642_FLASH_BASE) = 0x10;
                /* Start erase at sector address */
                pdata = (Uint8 *)sector_base;
               *pdata = 0x30;
                SEEDDM642_wait(1000);

                /* Wait for erase to complete */
                while (1)
                {
                    if (*pdata & 0xff)//程序死在这个while循环中
                    {
                        break;
                    }
                }       
                /* Put back in read mode */
            
                *((Uint8 *)SEEDDM642_FLASH_BASE) = 0xf0;                    
            }
            
            /* Advance to next sector */
            sector_base = sector_end[i] + 1;
        }
    }

    烧写函数

    void SEEDDM642_FLASH_write(Uint32 src, Uint32 dst, Uint32 length)
    {
        Uint8 *psrc, *pdst;
        Uint32 i;

        /* Establish source and destination */
        psrc = (Uint8 *)src;
        pdst = (Uint8 *)dst; 
        for (i = 0; i < length; i++)
        {
            // Program one 8-bit word
            *((Uint8 *)SEEDDM642_FLASH_BASE) = 0xaa;
            *((Uint8 *)SEEDDM642_FLASH_BASE) = 0x55;
            *((Uint8 *)SEEDDM642_FLASH_BASE) = 0xa0;
            *pdst = *psrc;
            
            // Wait for operation to complete
            while(1)///这个循环也死
            {
                if (*pdst == *psrc)
                {
                    break;
               }
           }       
            //  SEEDDM642_waitusec(10000);
            pdst++;
            psrc++;
        }
        
        /* Put back in read mode */
        *((Uint16 *)SEEDDM642_FLASH_BASE) = 0xf0;    
    }

  • 你好,你这个程序就是合众达给的例程吧?有几个问题,你可以参考一下。据我的经验(不一定对哈),分页执行的话,只能每次操作512K的数据,如果大于512K则不行,但是你说的是一直死在那个循环里,这个就有几种解释了,第一,你的flash工作了,但是你没有注意到,这个问题你可以通过查看寄存器是否为FFFFFFFF,即查看是否进行了擦除来验证,如果flash工作了,这个是最理想的情况,那么说明你的CPLD确实配置上有误,可能是分页不对等等。第二,你的flash没有工作,那么可能是你的片子坏了,或者是有其他什么原因导致了你的硬件出错,这两天我也是被这个问题所困,我通过用示波器测量发现,SDRAM的低八位工作不正常,导致flash的八位数据位有误,也是死在那些循环里。

  • 是的,是合纵达的例程。我知道分页的,而且我的CPLD的分页是正确的,我觉得是我的flash在我的的DSP发送完6个周期的擦除指令后没有自动调用其内部的擦除程序进行擦除。而我能保证的是我的六个周期的擦除指令时正确的发送了过去的。擦看寄存器的时候寄出去全部是0x00000000.换了几个片子了,感觉也不是片子坏了。

  • 我的QQ 405211631 有时间的话我们一起聊一聊吧,我最近在用他的EMIF读取FIFO,感觉也遇到了一些问题,你看我们能互相学习一下么?

  •         大家好,我现在也被FLASH烧写这个问题困扰了,我现在也是用DSP的三根IO来控制FLASH分页,是不是要改FBTC这个源文件,好像还有一个二级引导程序boot.asm要改吧,就算两个程序改好了,是不是用官方提供的flashburn就可以烧写了呢,有的又说flashburn不支持分页。现在有点迷茫了,烧写程序的过程到底是怎么样的呢?