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

📄 flash.c

📁 flash驱动程序,Nor flash类型
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif /* !SIMULATOR     */    	/* manufacturer & device type, then lower and upper boot blocks locks.  */    	id = (flash_read_byte (base) << 8) | flash_read_byte (base + width);    	*pid = id;    	/*    	** Try and match id against known devices    	*/        while (notFound && (j < NUMBER_FLASH_TYPES))        {            if ((id) == flashTypes [j].id)      	    {       	        notFound = FALSE;            }            else            {                j++;            }         }                 /*        ** Ensure that the id found, if any, is appropriate to the device.        */        if (notFound        || ((width == 1) &&  flashTypes [j].is16Bit)        || ((width == 2) && !flashTypes [j].is16Bit))        {            notFound = TRUE;            width *= 2;            j = 0;        }    } while (notFound && (width <= 2));    /*    ** 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)    {#ifndef FLASH_NO_ATMEL_SUPPORT    case AT29C040_CHIP_ID:    case AT29C040A_CHIP_ID:    case W29C040_CHIP_ID:        /* The data book says ffff2 for the  upper boot block lock, however */        /* ATMEL, when rung, say it should be 7fff2.                        */        if (flash_read_byte(base + 0x00002) == 0xff)        {            /* Lower */            *protectMask |= 1;        }        if (flash_read_byte(base + 0x7fff2) == 0xff)        {            /* Upper */            *protectMask |= 2;        }        /* Exit from product identification mode (return to normal operation)   */        flash_write_byte(0xaa, 0x5555 + base);        flash_write_byte(0x55, 0x2aaa + base);        flash_write_byte(0xf0, 0x5555 + base);        break;#endif#ifndef FLASH_NO_AMD_SUPPORT    case AM29LV017B_CHIP_ID:    case AM29LV081B_CHIP_ID:    case AM29F040_CHIP_ID:    case AM29LV116BB_CHIP_ID:    case AM29LV116BT_CHIP_ID:    case AM29LV040B_CHIP_ID:    case M29W008T_CHIP_ID:    case M29W008B_CHIP_ID:    case M29W040B_CHIP_ID:    case BM29F040_CHIP_ID:     case MX29F040_CHIP_ID:     case EN29F040_CHIP_ID:     case AC29F040_CHIP_ID:     case MX29F800B_CHIP_ID:    case M29W800AT_CHIP_ID:    case M29W800AB_CHIP_ID:    case AM29LV800BT_CHIP_ID:    case AM29LV800BB_CHIP_ID:    case AM29LV160BT_CHIP_ID:    case AM29LV160BB_CHIP_ID:            case AT49BV1614_CHIP_ID:                /*        ** AMD chips have hardware protection on sectors this cannot be        ** removed by software command.        */        {            U32     i;            U32     s;            U32     sector = 0;            for (s = 0; s < NUMBER_DIFFERENT_SECTOR_SIZES; s++)            {                for (i = 0; i < flashTypes [j].sectors [s].numberSectors; i++)                {                    /*                    ** Returns 0 for unprotected, 1 for protected                    */                    *protectMask |= (flash_read_byte(base + sector + 0x00002 * width) << i);                    sector += flashTypes [j].sectors [s].size;                }            }        }        /* Exit from product identification mode (return to normal operation)   */        flash_write_byte(0xaa, 0x5555 * width + base);        flash_write_byte(0x55, 0x2aaa * width + base + width - 1);        flash_write_byte(0xf0, 0x5555 * width + base);        break;#endif#ifndef FLASH_NO_INTEL_SUPPORT    case MT28F008B3B_CHIP_ID:    case MT28F008B3T_CHIP_ID:    case INT28F800B5B_CHIP_ID:    case INT28F320J5_CHIP_ID:    case LH28F160BVE_CHIP_ID:        /* No software readable protection */        /* Exit from product identification mode (return to normal operation)   */        flash_write_byte(0xff, base);        break;#endif#ifndef FLASH_NO_INTEL_SUPPORT    case MX29L1611B_CHIP_ID:        assert (flashTypes [j].is16Bit);        /* Exit from product identification mode (return to normal operation)   */        flash_write_byte(0xaa, 0xAAAA + base);        flash_write_byte(0x55, 0x5555 + base);        flash_write_byte(0xf0, 0xAAAA + base);	break;#endif#ifndef  FLASH_NO_SST_SUPPORT    case SST28SF040A_CHIP_ID:            /* Exit from product identification mode (return to normal operation)   */         flash_write_byte(0xff, 0x5555 + base);         /* Remove software protection */         flash_read_byte (base + 0x1823);         flash_read_byte (base + 0x1820);         flash_read_byte (base + 0x1822);         flash_read_byte (base + 0x0418);         flash_read_byte (base + 0x041b);         flash_read_byte (base + 0x0419);         flash_read_byte (base + 0x041a); 	break; #endif    case SST39VF080Q_CHIP_ID:     case SST39VF016Q_CHIP_ID:         /* Exit from product identification mode (return to normal operation)   */        flash_write_byte(0xaa, 0x5555 + base);        flash_write_byte(0x55, 0x2aaa + base);        flash_write_byte(0xf0, 0x5555 + base);        break;    default:        /* Exit from product identification mode (return to normal operation)   */        flash_write_byte(0xaa, 0x5555 + base);        flash_write_byte(0x55, 0x2aaa + base);        flash_write_byte(0xf0, 0x5555 + base);        break;    }    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_info8 *//*** Name:	read_chip_id_info**** Purpose:	Read FLASH chip ID from specified device**** This function is called by the console 'id' command and allows the user to** find out what type of FLASH devices are installed in the system.**** Arguments:**	chip	        Device number (starting from 0)**  pid             Device id value (16 bit)**	protectMask     Which sectors are protected (bit set indicates a protected sector)**** Result:**	index           Into internal table***/static U32 read_chip_id_info(U32 device, U32 *pid, U32 *protectMask){    if (flashDevices[device].Is16 == 1)    {        return read_chip_id_info16(device, pid, protectMask);    }    else    {         return read_chip_id_info8(device, pid, protectMask);    }}/*** Name:    flash_identify_chips**** Determine what type of chips are installed in the system.**** Result:**  ESUCCESS    All chips identified.**  ENOTFOUND   Unable to identify a chip. */int flash_identify_chips (void){    U32     protectMask;    U32     device;    U32     id;    int     rc = ESUCCESS;    assert (initialised);    /* loop round checking all chips ... */    for (device = 0; device < NUM_FLASH_DEVICES; device++)    {        /* find what type of device(s) we have in the system.               */        U32     j = read_chip_id_info (device, &id, &protectMask);        if (NUMBER_FLASH_TYPES == j)        {            printf("%C: FLASH device %d unknown (id: %x)\n", device, id);            rc = ENOTFOUND;        }        else if (flashTypes [j].size != flashDevices [device].size)		{			/* Configuration error */			printf ("%C: FLASH device %d incorrect size configured\n", device);			rc = EIO;		}		else        {            actualFlashTypes [device].typeIndex = j;            actualFlashTypes [device].writeMask = protectMask;        }    } /* check each device */    /* mark the chips as read, possibly not for the first time */    flashChipsChecked = TRUE;    flashChipsBad = (rc != ESUCCESS);    return  rc;}/*** Name:    flash_find_sector_size**** Purpose: Determine the size of a (FLASH) sector at the specified offset within the device**** Arguments:**  typeIndex   Index into table of device types.**  chipOffset  Offset within the device.**** Result:**  0           Illegal offset**  <>0         Sector size.*/static U32 flash_find_sector_size (U32 typeIndex, U32 chipOffset, U32 *sectorStartOffset){    U32                 i;    U32                 sectorSize;    U32                 sectorStart;    const FlashType *   deviceType;        assert (typeIndex < NUMBER_FLASH_TYPES);    assert (chipOffset < flashTypes [typeIndex].size);        deviceType = &flashTypes [typeIndex];    i = 0;    sectorSize = 0;    sectorStart = 0;    while ((0 == sectorSize) && (i < NUMBER_DIFFERENT_SECTOR_SIZES) && (deviceType->sectors [i].size != 0))    {        if (chipOffset >= (deviceType->sectors [i].size * deviceType->sectors [i].numberSectors))        {            sectorStart += deviceType->sectors [i].size * deviceType->sectors [i].numberSectors;            chipOffset -= deviceType->sectors [i].size * deviceType->sectors [i].numberSectors;            i++;        }        else        {            sectorStart += deviceType->sectors [i].size * (chipOffset / deviceType->sectors [i].size);            sectorSize = deviceType->sectors [i].size;        }    }    assert (0 != sectorSize);      /* Can't happen. */    if (NULL != sectorStartOffset)    {        *sectorStartOffset = sectorStart;    }    return  sectorSize;}/*** A small enhancement allows AMD devices to be** programmed if the 'write more zeros' is appropriate.  This is useful** when writing the checksum word after an update - it saves 1 sector program** and ditto when re-writing the 'volroot' stucture if it didn't change.*/static int  overwrite_flash_bytes (BYTE **srcp, U32 *dstp, U32 *nump){    int     rc = ESUCCESS;    U32     device = FLASH_DEVICE(*dstp);    U32     typeIndex = actualFlashTypes [device].typeIndex;    /* Does the chip support individual writes? */    if (NULL != flashTypes [typeIndex].program_byte)    {        int (*byte_program) (U32 logicalAddress, BYTE value) = flashTypes [typeIndex].program_byte;        /* arbitary length check - if not many bytes to program ...     */        if (*nump < SMALL_WRITE_LIMIT) /* header structs etc. are smaller than this    */         {            /* loop while bytes to program checking for "write more     */            /* zero's" type operation with AMD.  Decrement number and   */            /* increment source & destination pointers.                 */            for (; *nump != 0; (*nump)--, (*srcp)++, (*dstp)++)            {                 /* if the byte is the same - don't program it */                if (flash_read_byte(*dstp) == **srcp)                {                    continue;                }                /* check if new byte has any 1's where there are 0's    */                /* if so, we can't make 0->1 without erase, give up     */                else if (~flash_read_byte(*dstp) & **srcp)                {                    break;                }                /* program the byte, check return code */                else if ((rc = byte_program (*dstp, **srcp)) != ESUCCESS)                {                    return rc;                }            } /* program 'write more zeros' a byte at a time */            /* see if we were able to program all the bytes ? */            if (*nump == 0)            {               /* all done, return */               return rc;            }        } /* small amount of data to program */        /* too much data for byte program OR write more 0's not applicable. */    }    return  rc;}/*** Gets a new secto

⌨️ 快捷键说明

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