⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intel_c3_flash.c

📁 motorola 针对coldfire 5275 评估板的Dbug bootloader源程序
💻 C
字号:
/*
 * File:        intel_c3_flash.c
 * Purpose:     Flash driver for programming Intel Flash devices
 *
 * Notes:       This driver supports a single banks of Intel Flash.
 *              A bank is defined as one or more of the same Flash 
 *              device connected to a single chip-select.
 */

#include "src/include/dbug.h"

/*
 * Compiler specific code relocation section
 */
#ifdef __DCC__
#pragma section CODE    ".code_relocation"
#pragma section CONST   ".code_relocation"
#elif (defined(__ghs__))
#pragma ghs section text=".code_relocation"
#endif

#include "src/dev/flash/intel_c3_flash.h"

/********************************************************************/
/*
 * Global pointer to base of Intel Flash device
 */
#ifdef __MWERKS__
__relocate_data__
#endif
static INTEL_C3_FLASH_CELL *pFlash;

/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
void
intel_c3_flash_init(ADDRESS base)
{
    pFlash = (INTEL_C3_FLASH_CELL *)base;
}
/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
void
intel_c3_flash_unlock(ADDRESS start, int bytes)
{
    int i, unlocked = 0;

    if (bytes == 0)
        return;

    for (i = 0; i < INTEL_C3_FLASH_SECTORS; i++)
    {
        if (start >= (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i)) &&
            start <= (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i) + (C3_SSIZE(i) - 1)))
        {
            break;
        }
    }

    bytes += ((int)start - (int)((ADDRESS)pFlash + C3_SOFFSET(i)));

    while (unlocked < bytes)
    {
        /*
         * Unlock Block command
         */
        pFlash[C3_SADDR(i)] = INTEL_C3_FLASH_CMD_DATA(0x60);
        pFlash[C3_SADDR(i)] = INTEL_C3_FLASH_CMD_DATA(0xD0);
        unlocked += C3_SSIZE(i);
        i++;
    }
}
/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
void
intel_c3_flash_lock(ADDRESS start, int bytes)
{
    int i, locked = 0;

    if (bytes == 0)
        return;

    for (i = 0; i < INTEL_C3_FLASH_SECTORS; i++)
    {
        if (start >= (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i)) &&
            start <= (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i) + (C3_SSIZE(i) - 1)))
        {
            break;
        }
    }

    bytes += ((int)start - (int)((ADDRESS)pFlash + C3_SOFFSET(i)));

    while (locked < bytes)
    {
        /*
         * Lock Block command
         */
        pFlash[C3_SADDR(i)] = INTEL_C3_FLASH_CMD_DATA(0x60);
        pFlash[C3_SADDR(i)] = INTEL_C3_FLASH_CMD_DATA(0x01);
        locked += C3_SSIZE(i);
        i++;
    }
}
/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
void
intel_c3_flash_sector_erase(int n)
{
    INTEL_C3_FLASH_CELL status;

    /*
     * Erase Block command
     */
    pFlash[C3_SADDR(n)] = INTEL_C3_FLASH_CMD_DATA(0x20);
    pFlash[C3_SADDR(n)] = INTEL_C3_FLASH_CMD_DATA(0xD0);

    /*
     * Wait for the erase operation to finish
     */
    do
    {
        pFlash[C3_SADDR(n)] = INTEL_C3_FLASH_CMD_DATA(0x70);
        status = pFlash[C3_SADDR(n)];
    }
    while (!(status & INTEL_C3_FLASH_CMD_DATA(0x80)));

    /*
     * Place back in normal read mode
     */
    pFlash[C3_SADDR(n)] = INTEL_C3_FLASH_CMD_DATA(0xFF);
}
/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
int
intel_c3_flash_erase(ADDRESS start, int bytes, void (*putchar)(char))
{
    int i, ebytes = 0;

    if (bytes == 0)
        return 0;

    /*
     * Unlock the required blocks
     */
    intel_c3_flash_unlock(start, bytes);

    for (i = 0; i < INTEL_C3_FLASH_SECTORS; i++)
    {
        if (start >= (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i)) &&
            start <= (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i) + (C3_SSIZE(i) - 1)))
        {
            break;
        }
    }

    bytes += ((int)start - (int)((ADDRESS)pFlash + C3_SOFFSET(i)));

    while (ebytes < bytes)
    {
        if (putchar != NULL)
        {
            putchar('.');
        }
        intel_c3_flash_sector_erase(i);
        ebytes += C3_SSIZE(i);
        i++;
    }

    if (putchar != NULL)
    {
        putchar(10);    /* LF */
        putchar(13);    /* CR */
    }

    /*
     * Lock up
     */
    intel_c3_flash_lock(start, bytes);

    return ebytes;
}
/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
void
intel_c3_flash_program_cell(INTEL_C3_FLASH_CELL *dst, INTEL_C3_FLASH_CELL data)
{
    INTEL_C3_FLASH_CELL status;

    *dst = INTEL_C3_FLASH_CMD_DATA(0x40);
    *dst = data;

    /*
     * Wait for program operation to finish
     */
    do
    {
        *dst = INTEL_C3_FLASH_CMD_DATA(0x70);
        status = *dst;
    }
    while (!(status & INTEL_C3_FLASH_CMD_DATA(0x80)));

    /*
     * Place back in normal read mode
     */
    *dst = INTEL_C3_FLASH_CMD_DATA(0xFF);
}
/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
int
intel_c3_flash_program(ADDRESS dest, ADDRESS source,
                    int bytes, int erase,
                    void (*func)(void),
                    void (*putchar)(char))
{
    INTEL_C3_FLASH_CELL *src, *dst;
    int hashi=1,hashj=0;
    char hash[5];

    hash[0]=8;  /* Backspace */
    hash[1]=124;/* "|" */
    hash[2]=47; /* "/" */
    hash[3]=45; /* "-" */
    hash[4]=92; /* "\" */

    src = (INTEL_C3_FLASH_CELL *)source;
    dst = (INTEL_C3_FLASH_CELL *)dest;

    /*
     * Erase device if necessary
     */
    if (erase)
    {
        intel_c3_flash_erase(dest, bytes, putchar);
    }

    /*
     * Unlock the required blocks
     */
    intel_c3_flash_unlock(dest, bytes);

    /*
     * Program device
     */
    while (bytes > 0)
    {
        intel_c3_flash_program_cell(dst,*src);

        /* Verify Write */
        if (*dst == *src)
        {
            bytes -= INTEL_C3_FLASH_CELL_BYTES;
            *dst++, *src++;

            if ((putchar != NULL))
            {
                /* Hash marks to indicate progress */
                if (hashj == 0x1000)
                {
                    hashj = -1;
                    putchar(hash[0]);
                    putchar(hash[hashi]);

                    hashi++;
                    if (hashi == 5)
                    {
                        hashi=1;
                    }
                }
                hashj++;
            }
        }
        else
            break;
    }

    if (putchar != NULL)
    {
        putchar(hash[0]);
    }

    /*
     * Leaving now - lock up
     */
    intel_c3_flash_lock(dest, bytes);

    /*
     * If a function was passed in, call it now
     */
    if ((func != NULL))
    {
        func();
    }

    return ((int)src - (int)source);
}
/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
ADDRESS
intel_c3_flash_sector_start(ADDRESS addr)
{
    /*
     * Returns beginning of sector containing addr
     */
    int i;

    for (i = 0; i < INTEL_C3_FLASH_SECTORS; i++)
    {
        if (addr >= (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i)) &&
            addr <= (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i) + (C3_SSIZE(i) - 1)))
        {
            return (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i));
        }
    }
    return NULL;
}
/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
ADDRESS
intel_c3_flash_sector_end(ADDRESS addr)
{
    /* Returns end of sector containing ADDRESS */
    int i;

    for (i = 0; i < INTEL_C3_FLASH_SECTORS; i++)
    {
        if (addr >= (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i)) &&
            addr <= (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i) + (C3_SSIZE(i) - 1)))
        {
            return (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i) + (C3_SSIZE(i) - 1));
        }
    }
    return NULL;
}
/********************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -