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

📄 flash.c

📁 flash驱动程序,Nor flash类型
💻 C
📖 第 1 页 / 共 5 页
字号:
#if !defined (BOOT_ROM) || !defined (NO_CONFIGINFO_FLASH)        /*        ** Can only read chip information when writing is permitted.        */        flash_display_chip_info (i);#endif    }    /*    ** Filing system information    */    printf ("Flash start offset: 0x%08x\n", FLASH_START_OFFSET);    printf ("Space for all FLASHFS partitions: 0x%08x\n", TOTAL_FLASH_SIZE - FLASH_START_OFFSET);#if defined (NUM_FIXED_FLASH_DEVICES) && (NUM_FIXED_FLASH_DEVICES > 0)    printf ("Emergency flash size: 0x%08x\n", flash_total_size (NUM_FLASH_DEVICES - NUM_FIXED_FLASH_DEVICES) - FLASH_START_OFFSET);#elif defined (EMERGENCY_FLASHFS_SIZE) && (EMERGENCY_FLASHFS_SIZE > 0)    printf ("Emergency flash size: 0x%08x\n", EMERGENCY_FLASHFS_SIZE);#endif}/*** A large amount of the following code is #ifdef'd out for BOOT ROMs which** don't require the ability to write to FLASH.*/#if !defined (BOOT_ROM) || !defined (NO_CONFIGINFO_FLASH)/*** Name:	flash_display_chip_info**** Purpose:	Display information about the specified chip.**** Arguments:**	device  0 ... (NUM_FLASH_DEVICES - 1): chip to be identified.**** Result:**	<Nothing>***/void flash_display_chip_info(U32 chip){    U32     protectMask;    U32     id;    U32     index = read_chip_id_info (chip, &id, &protectMask);    assert (initialised);    printf ("Chip %d ID is %x: (%s %s %ldk bytes), %slocked (%x)%s\n",        chip, id, flashTypes [index].manufacturer, flashTypes [index].partname, flashTypes [index].size / 1024UL,        (protectMask == 0) ? "un" : "" , protectMask,        (flashTypes [index].size != flashDevices [chip].size) ? " MISCONFIGURED SIZE" : ""    );}int flash_sector_bounds (U32 address, U32 *start, U32 *end){    int rc;    assert (initialised);    assert (NULL != start);    assert (NULL != end);    /*    ** Must know the chip types to determine sector limits.    */    if (!flashChipsChecked)    {        rc = flash_identify_chips ();    }    else if (flashChipsBad)    {        rc = EIO;    }    else    {        rc = ESUCCESS;    }    if (ESUCCESS == rc)    {        U32 device = FLASH_DEVICE(address);        U32 offset = address - flashDevices [device].logicalBase;        assert (device < NUM_FLASH_DEVICES);        assert (actualFlashTypes [device].typeIndex != NUMBER_FLASH_TYPES);        /*        ** Look through chip definition to find where the sector falls.        */        offset = flash_find_sector_size (actualFlashTypes [device].typeIndex, offset, start);        *start += flashDevices [device].logicalBase;        *end = *start + (offset - 1);    }    return  rc;}/*** Name:	flash_ready_for_update**** Purpose:	Determine if the flash system can handle writes.**** If it can't this is either because the system wasn't compiled as such or** because there is no memory for a sector cache buffer**** Arguments:**	<None>**** Result:**  ESUCCESS    Flash system can handle writes**  <>ESUCCESS  Other failure***/int flash_ready_for_update (void){    int     rc;    if (NULL == flashSectorCopy)    {        rc = ENOMEM;    }    else    {        rc = ESUCCESS;    }    return  rc;}/* the address is a logical flash one, *not* a flash filing system address. */inline static BYTE flash_write_byte(BYTE data, U32 addr){    U32 device = FLASH_DEVICE(addr);    U32 offset = addr - flashDevices [device].logicalBase;    assert(device < NUM_FLASH_DEVICES);    addr = offset * STRIDE;    /* use macro, allows for StrongArm platform (or not) */    SELECT_FLASH_DEVICE (device);    FLASH_WRITE_RAW(data, addr, device);    return data;} /* the address is a logical flash one, *not* a flash filing system address. */inline static U16 flash_write_16(U16 data, U32 addr){    U32 device = FLASH_DEVICE(addr);#if 0        U32 offset = addr - flashDevices [device].logicalBase;    assert(device < NUM_FLASH_DEVICES);     addr = offset * STRIDE;    /* use macro, allows for StrongArm platform (or not) */    SELECT_FLASH_DEVICE (device);#endif    /* Since the 'base' is used to determine which flash device to communicate     * with, it must be removed from the address when the address is passed      * into FLASH_WRITE_RAW16. FLASH_WRITE_RAW16 uses the device to get the      * real address of the flash part; this will already include the 'base'     * in the case     * of accessing any flash devices other that the first device.     * The base addresses of the flash devices must be defined in     * ascending order in the hardware file starting with FLASH0.     */    if (device > 0)      addr = addr - flashDevices [device].logicalBase;    FLASH_WRITE_RAW16(data, addr, device);          return data;} /*** Name:	flash_write_data**** Purpose:	Write data into flash device(s)**** This function is logically equivalent to 'fwrite'.  It hides all the detail** involved in programming the FLASH devices from the calling function.  No ** restrictions are placed on the calling function due to the architecture of** the FLASH devices (i.e. sector size) but the fastest operation will result** from calling this function in a rising address manner so that sector copies** and programs are minimised, the update code is designed to do this.** Due to the way a RAM sector copy is used, once all writes have been 'done'** the 'program_sector' function should be called to program the RAM sector into** FLASH if this has not already been done.**** Arguments:**	ps		Pointer to source data**	d		Desination address (FLASH address)**	n		Number of bytes to program**** Result:**	rc		ESUCCESS of OK, else errno***/int flash_write_data(BYTE *src, U32 dst, U32 num){    int rc = ESUCCESS;    /* sanity check assert before we proceed */    assert((dst + num) <= TOTAL_FLASH_SIZE);    TRACE4("%C: program src %6x dst %6x len %6d\n", (int)src, dst, num);    /* if we don't know what type of chips we have yet, we should ...       */    if (!flashChipsChecked)	{        /* check chips, keep result. */        if ((rc = check_flash_chips_writable()) != ESUCCESS)        {		    /* if bad, return fault */            return rc;        }    }    /* loop round programming bytes, sectors etc. until all done or ERROR     */    while ((num != 0) && (rc == ESUCCESS))    {        /* have we a current sector ? -1 is used as a 'NULL' as 0 is legit.   */        if (currentSector == (U32) ~0)        {            /* at this point we have no sector so start a new one */            rc = overwrite_flash_bytes (&src, &dst, &num);            if ((ESUCCESS == rc) && (num > 0))            {                set_new_sector(dst);            }        }        else        {            /* Is the address within the sector. */            if ((dst >= currentSector) && (dst < (currentSector + currentSectorSize)))            {                /* modify sector we have in ram. This might involve a sector write. */                rc = modify_sector(&src, &dst, &num);            }            else             {                /* address not in sector, write current sector, loop again for next */                rc = program_sector();            } /* we have a current sector */        }    } /* programming loop */      /* result */    return rc; } /* flash_write_fs_data */static U32 read_chip_id_info16(U32 device, U32 *pid, U32 *protectMask){    BOOL notFound = TRUE;    U32  j = 0;    BITS id   = 0;    U32  base = flashDevices [device].logicalBase;        /* WARNING: for this to work reliably (on certain ATMEL chips at least), it */    /*          appears to be important to do the whole read id operation       */    /*          atomically, otherwise the device can be left in the             */    /*          identification mode until the power is cycled.                  */    BITS crit = atmos_startfiqcritical();    assert (initialised);    assert (flashDevices[device].Is16);#ifndef SIMULATOR    /* Enter product id mode */    flash_write_16(0xaaaa, base + (0x5555 << 1));    flash_write_16(0x5555, base + (0x2aaa << 1));    flash_write_16(0x9090, base + (0x5555 << 1));		            timer_us_wait(10000);    /* Spin for 10ms, don't want to be interrupted */#else /* !SIMULATOR */    simulator_flash_change_mode(device, id_mode);#endif /* !SIMULATOR     */    /* manufacturer & device type, then lower and upper boot blocks locks.  */    id = flash_read_16(base) << 8 | flash_read_16(base + 2);        *pid = id;    /*    ** Try and match id against known devices    */    while (notFound && (j < NUMBER_FLASH_TYPES))    {        if ((id) == flashTypes [j].id)        {            notFound = FALSE;        }        else        {            j++;        }    }         /*    ** If not found set return code    */    if (notFound)    {        id = UNKNOWN_CHIP_ID;        j = NUMBER_FLASH_TYPES;    }    *protectMask = 0;    #ifndef SIMULATOR    /*    ** Protection depends upon chip type.    */    switch (id)    {    case AT29C1024_CHIP_ID:        break;    default:        printf("Not found\n");        break;    }    /* Exit from product identification mode (return to normal operation)   */    flash_write_16(0xaaaa, base + (0x5555 << 1));    flash_write_16(0x5555, base + (0x2aaa << 1));    flash_write_16(0xf0f0, base + (0x5555 << 1));    timer_us_wait(10000);    /* Spin for 10ms, don't want to be interrupted */#else /* SIMULATOR */    simulator_flash_change_mode(device, read_mode);#endif /* !SIMULATOR     */    atmos_endfiqcritical(crit);    TRACE3("%C: device %d  ID read: %04x protection: %0x %slocked\n", device, id, *protectMask, (*protectMask != 0) ? "" : "un");    return j;} /* read_chip_id_info16 */static U32 read_chip_id_info8(U32 device, U32 *pid, U32 *protectMask){    U32	 width = 1;	/* 1 = 8, 2 = 16 bits */    BOOL notFound = TRUE;    U32  j = 0;    BITS id   = 0;    U32  base = flashDevices [device].logicalBase;    /* WARNING: for this to work reliably (on AT29C040A chips at least), it */    /*          appears to be important to do the whole read id operation   */    /*          atomically, otherwise the device can be left in the         */    /*          identification mode until the power is cycled.              */    BITS crit = atmos_startfiqcritical();    assert (initialised);    do    {#ifndef SIMULATOR        /* Device unlock (ATMEL or AMD): note implication that devices > ~32k long */        flash_write_byte(0xaa, 0x5555 * width + base);        flash_write_byte(0x55, 0x2aaa * width + base + width - 1);        flash_write_byte(0x90, 0x5555 * width + base);        timer_us_wait(10000);    /* Spin for 10ms, don't want to be interrupted */#else /* !SIMULATOR */        simulator_flash_change_mode(device, id_mode);

⌨️ 快捷键说明

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