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

📄 flash_v3.c

📁 1.under bootloader 1)cd your_dir/mrua_EM8620L_2.5.115.RC8_dev.arm.bootirq/MRUA_src/loader 2)将f
💻 C
📖 第 1 页 / 共 3 页
字号:
	if( ret == 1 ) {	    	if( (dq1 & status) == dq1 ) {		    	uart_printf( "Flash write to Buffer aborted @ 0x%lx = 0x%x\n", adr, status );			cfi_send_cmd(0xAA, pcfi->addr_unlock1, pcfi->base);			cfi_send_cmd(0x55, pcfi->addr_unlock2, pcfi->base);			cfi_send_cmd(0xF0, pcfi->addr_unlock1, pcfi->base);		} else {		    	uart_printf( "Flash write to buffer faileed @ 0x%lx = 0x%x\n", adr, status );			cfi_send_gen_cmd(0xF0, 0, pcfi->base);		}	}		return ret;//zxh-	}int flash_write_data_internal(unsigned long addr, unsigned short *data, int nwords, cfi_info_t *pcfi){    int i;    int chipnum;     int len = nwords << 1;    int ret = 0;    int wbufsize = CFIDEV_INTERLEAVE << 5; //cfi->cfiq->MaxBufWriteSize=0x5    unsigned long ofs;    unsigned char *buf = (unsigned char*)data;    #ifndef FLASH_USE_DQX    int cnt = 0;#endif    #if (CFIDEV_BUSWIDTH != 1 && CFIDEV_BUSWIDTH != 2)#error "Current code doesn't support other than 8-bits and 16-bits writing"#endif  #ifdef CFIDEV_UNLOCK_BYPASS       cfi_send_cmd(0xaa, pcfi->addr_unlock1, pcfi->base);   cfi_send_cmd(0x55, pcfi->addr_unlock2, pcfi->base);   cfi_send_cmd(0x20, pcfi->addr_unlock1, pcfi->base);#endif#if CFIDEV_BUSWIDTH == 1#if 0    for (i = 0; i < (nwords << 1); ++i) {#ifdef CFIDEV_UNLOCK_BYPASS        cfi_send_cmd(0xa0, 0x111, pcfi->base);//	uart_puts("bypass mode\n");#else        cfi_send_cmd(0xaa, pcfi->addr_unlock1, pcfi->base);        cfi_send_cmd(0x55, pcfi->addr_unlock2, pcfi->base);        cfi_send_cmd(0xa0, pcfi->addr_unlock1, pcfi->base);#endif        cfi_write(((unsigned char *) data)[i], addr + i);#ifdef FLASH_USE_DQX	dqx_wait(addr + i, ((unsigned char *)data)[i], 1<<pcfi->ident.timeout_single_write);#else	for (cnt = 0; cnt < FLASH_ERR_CNT; cnt++) {	    em86xx_usleep(1 << pcfi->ident.timeout_single_write);	    if (cfi_read(addr + i) == ((unsigned char *)data)[i])		break;	}#endif    }#else	//Buffer write method.	/* Write buffer is worth it only if more than one word to write... */	//zxh:Why 0x23? I don't know.	chipnum = addr >> 0x23; //cfi->chipshift=0x17 (0x800000 8MB)  	ofs = addr  - (chipnum << 0x23);	while(len > CFIDEV_BUSWIDTH)	{		/* We must not cross write block boundaries */		int size = wbufsize - (ofs & (wbufsize-1));		if (size > len)			size = len & ~(CFIDEV_BUSWIDTH-1);		ret = do_write_buffer(pcfi, ofs, buf, size);		if (ret)			return ret;		ofs += size;		buf += size;		len -= size;	}#endif#elif CFIDEV_BUSWIDTH == 2    for (i = 0; i < nwords; ++i) {#ifdef CFIDEV_UNLOCK_BYPASS        cfi_send_cmd(0xa0, 0, pcfi->base);//	uart_puts("bypass mode**************aaaaaaaaaaaaaaa");#else        cfi_send_cmd(0xaa, 0, pcfi->base);        cfi_send_cmd(0x55, 0, pcfi->base);        cfi_send_cmd(0xa0, 0, pcfi->base);#endif        cfi_write(data[i], addr + (i << 1));#ifdef FLASH_USE_DQX	dqx_wait(addr + (i << 1), data[i], 1<<pcfi->ident.timeout_single_write);#else	for (cnt = 0; cnt < FLASH_ERR_CNT; cnt++) {	    em86xx_usleep(1 << pcfi->ident.timeout_single_write);	    if (cfi_read(addr + (i << 1)) == data[i])		break;	}#endif    }#endif#ifdef CFIDEV_UNLOCK_BYPASS    cfi_send_cmd(0x90, 0, pcfi->base);    cfi_send_cmd(0x00, 0, pcfi->base);#endif    return FLASH_OK;}#define PROGRESS_UNIT                   0x1000  // prints '.' after this block is written #define UNLOCKBYPASSPROGRAM_UNITBITS    12      // 2^12 = 4KBint flash_write_data(unsigned long addr, unsigned char *data, int len){    int cnt = 0;	int times, p1, p2, t1, t2; //Kenlo    int maxbufwords, nwords;    cfi_info_t *pcfi = find_cfi(addr);    int nloop = 0, writtenlen = 0, nextwrittenlen = PROGRESS_UNIT;#if (CFIDEV_BUSWIDTH != 1 && CFIDEV_BUSWIDTH != 2)#error "Current code doesn't support other than 8-bits and 16-bits writing"#endif        if (pcfi == NULL)        return FLASH_NOTEXIST;    if (pcfi->chip_state != FLSTATE_READY)        return FLASH_NOTREADY;    if (!flash_writable(addr, len))        return FLASH_WRITE_FAULT;    if (addr & 0x01) {        flash_write_onebyte(addr++, *data++);        --len;    }    pcfi->chip_state = FLSTATE_WRITING;    if (pcfi->ident.max_multibyte_write == 0)        maxbufwords = 1 << (UNLOCKBYPASSPROGRAM_UNITBITS - 1);    else         maxbufwords = 1 << (pcfi->ident.max_multibyte_write - 1);        while (len > 1) {        if (writtenlen >= nextwrittenlen) {            if ((++nloop & 0x3f) == 0)                 uart_puts("\r\n          ");            uart_putc('.');            nextwrittenlen += PROGRESS_UNIT;        }        nwords = ((len + 1) >> 1);        if (nwords > maxbufwords)            nwords = maxbufwords;    flash_write_data_internal(addr, (unsigned short *) data, nwords, pcfi); 	for (cnt = 0; cnt < FLASH_ERR_CNT; cnt++) {            em86xx_usleep(1 << pcfi->ident.timeout_single_write);#if CFIDEV_BUSWIDTH == 1	    if (cfi_read(addr) == *(unsigned char *) data)		break;#elif CFIDEV_BUSWIDTH == 2	    if (cfi_read(addr) == *(unsigned short *) data)		break;#endif	}                                                                                	if (cnt >= FLASH_ERR_CNT)	    break;        nwords <<= 1;        writtenlen += nwords;        addr += nwords;        data += nwords;        len -= nwords;    }      pcfi->chip_state = FLSTATE_READY;    if (cnt >= FLASH_ERR_CNT)	return FLASH_WRITE_FAULT;    if (len == 1)        flash_write_onebyte(addr, *data);    return FLASH_OK;}//// miscellaneous//char *cfi_get_idname(unsigned int vendor){    switch (vendor) {    case CFI_PRIMARY_ID_NULL :        return "None";    case CFI_PRIMARY_ID_INTEL_EXT :        return "Intel/Sharp Extended";    case CFI_PRIMARY_ID_AMD_STD :        return "AMD/Fujitsu Standard";    case CFI_PRIMARY_ID_INTEL_STD :        return "Intel/Sharp Standard";    case CFI_PRIMARY_ID_AMD_EXT :        return "AMD/Fujitsu Extended";    case CFI_PRIMARY_ID_MITSUBISHI_STD :        return "Mitsubishi Standard";    case CFI_PRIMARY_ID_MITSUBISHI_EXT :        return "Mitsubishi Extended";    case CFI_PRIMARY_ID_SST :        return "Page Write Command Set";    case CFI_PRIMARY_ID_RESERVED :        return "Not Allowed / Reserved for Future Use";    default:        return "Unknown";    }}void flash_list(void *vpcfi){    int i, j;    cfi_info_t *pcfi;    for (i = 0; i < FLASH_MAX_CHIPSET; ++i) {        pcfi = &g_cfi[i];        if (pcfi->exist && (vpcfi == NULL || i == (int) vpcfi || pcfi == vpcfi)) {            uart_printf("Flash %d at 0x%08x\n", i, pcfi->base);            uart_printf("  ID : %s\n", cfi_get_idname(pcfi->ident.primary_id));            uart_printf("  Size : %d KB\n", pcfi->size >> 10);             uart_printf("  Buffer Size : %d\n", pcfi->ident.max_multibyte_write);            uart_printf("  Regions : %d\n", pcfi->ident.num_erase_regions);            for (j = 0; j < pcfi->ident.num_erase_regions; ++j)                 uart_printf("    %d : 0x%08x - 0x%08x * %2d\n", j,                     pcfi->erase_regions[j].start, pcfi->erase_regions[j].size, pcfi->erase_regions[j].blocks);        }    }}int flash_calcblock(unsigned long addr, unsigned int *pstart, unsigned int *plen){    int i;    cfi_info_t *pcfi = find_cfi(addr);    *pstart = 0;    *plen = 0;    if (pcfi == NULL)        return -1;    for (i = pcfi->ident.num_erase_regions - 1; i >= 0; --i) {        if (addr >= pcfi->base + pcfi->erase_regions[i].start) {            *pstart = pcfi->base + pcfi->erase_regions[i].start;            *plen = pcfi->erase_regions[i].size;            addr -= *pstart;            while (addr >= *plen) {                addr -= *plen;                *pstart += *plen;            }            return 0;        }    }    return -1;}//// Test// #define FLEX_ROM_SIZE           0x00200000  // 2MB#define FLEX_BLOCK_SIZE         0x100       // 256 bytes#define CALC_SEED(addr)         ((unsigned char) (((((addr) >> 8) & 0xff) + 3) * 5 + ((((addr) >> 16) & 0xff) + 5) * 7))#define CALC_SEED_NEXT(seed)    (++(seed))#define MISMATCH_THRESHOLD      10#ifdef CONFIG_ENABLE_FULLFUNCTIONvoid flash_test_flexrom(void){    int i, j, mismatch, bit, bitmask;    unsigned long addr, flexaddr = LOADER_FLASHBASE;    unsigned char seed, seedtable[FLEX_BLOCK_SIZE];        uart_puts("FlexROM Test :\n");    for (i = 0, addr = 0, mismatch = 0; i < FLEX_ROM_SIZE / FLEX_BLOCK_SIZE; ++i, addr += FLEX_BLOCK_SIZE, flexaddr += FLEX_BLOCK_SIZE) {        seed = CALC_SEED(addr);        for (j = 0; j < FLEX_BLOCK_SIZE; ++j, CALC_SEED_NEXT(seed))             seedtable[j] = seed;        for (j = 0; j < FLEX_BLOCK_SIZE; ++j) {            if (__raw_readb(flexaddr + j) != seedtable[j]) {                if (mismatch == 0) {                    if (addr == 0)                        bit = 0;                    else                         for (bit = 0, bitmask = 1; (addr & bitmask) == 0; ++bit, bitmask <<= 1)                            ;                    uart_printf("  Guess address line %d is wrong\n", bit);                }                uart_printf("  Data Mismatch at %08lx : %02x (orig = %02x)\n",                     flexaddr + j, __raw_readb(flexaddr + j), seedtable[j]);                if (++mismatch >= MISMATCH_THRESHOLD) {                    uart_puts("  Too many mismatches!\n");                    return;                }            }        }    }    if (mismatch == 0)        uart_puts("  OK\n");    else        uart_printf("  Mismatch = %d\n", mismatch);}void flash_test_checksum(void){    int i;    unsigned int *ptr, sum;        for (i = 0; i < FLASH_MAX_CHIPSET; ++i) {        if (g_cfi[i].exist) {            uart_printf(finfo_msg, i, g_cfi[i].base, g_cfi[i].size);            for (sum = 0, ptr = (unsigned int *) g_cfi[i].base; ptr < (unsigned int *) (g_cfi[i].base + g_cfi[i].size); ++ptr)                sum += *ptr;            uart_printf("  Checksum = %08x\n", sum);        }       }}void flash_test_write(void){    unsigned int len;    unsigned char buf[256], emptybuf[256];    int i, j, found, testlen = sizeof emptybuf;        uart_puts("Write test :\n");        if (len > sizeof buf)        len = sizeof buf;        for (i = 0; i < FLASH_MAX_CHIPSET; ++i) {        if (g_cfi[i].exist) {            uart_printf(finfo_msg, i, g_cfi[i].base, g_cfi[i].size);                        memset(emptybuf, 0xff, sizeof emptybuf);                for (len = g_cfi[i].size, found = 0; len > testlen; len -= testlen) {                flash_read_data(g_cfi[i].base + len, buf, testlen);                if (memcmp(buf, emptybuf, testlen) == 0) {                    found = 1;                    break;                }            }                if (!found) {                uart_puts("  No empty block found. Test failed\n");                return;            }            uart_printf("  Empty block is found at offset %04x\n", len);                        uart_puts("  Writing...\n");            for (j = 0; j < testlen; ++j)                emptybuf[j] = j;            flash_write_data(g_cfi[i].base + len, emptybuf, testlen);                        uart_puts("  Reading...\n");            flash_read_data(g_cfi[i].base + len, buf, testlen);                        uart_puts("  Verifying : ");            if (memcmp(buf, emptybuf, testlen) == 0)                uart_puts("OK\n");            else                uart_puts("Mismatch\n");        }       }}            void flash_test(int argc, char *argv[]){    int doall = (argv[0] && strcmp(argv[0], "all") == 0) ? 1 : 0;    if (argv[0] == NULL) {        uart_puts("Parallel Flash Test :\n");        uart_puts("  Available commands : "            "flexrom "            "checksum "            "write "            "\n");    } else {        if (strcmp(argv[0], "flexrom") == 0) {            flash_test_flexrom();        }                if (!flash_found()) {            uart_puts("Parallel Flash doesn't exist. Test failed\n");            return;         }                if (doall || strcmp(argv[0], "checksum") == 0) {            flash_test_checksum();        }                if (doall || strcmp(argv[0], "write") == 0) {            flash_test_write();        }    }}#endif#endif

⌨️ 快捷键说明

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