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

📄 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 页
字号:
void cfi_cmdset_0002(cfi_info_t *pcfi){    switch (CFIDEV_DEVTYPE) {    case 1 :         pcfi->addr_unlock1 = 0x555;        pcfi->addr_unlock2 = 0x2aa;        break;    case 2 :         pcfi->addr_unlock1 = 0xaaa;        pcfi->addr_unlock2 = 0x555;        break;    case 4 :        pcfi->addr_unlock1 = 0x1555;        pcfi->addr_unlock2 = 0xaaa;        break;    }}//// init & basic//int flash_found(void){    return g_flash_chips;}int flash_addr_found(unsigned long addr){    return (find_cfi(addr) != NULL) ? 1 : 0;}int flash_probe(unsigned int base, int force, int verbose){    int i, ret;    cfi_info_t *pcfi = NULL;    if (!g_flash_inited) {        for (i = 0; i < FLASH_MAX_CHIPSET; ++i)             g_cfi[i].chip_state = FLSTATE_READY;        g_flash_inited = 1;    }    if ((pcfi = find_cfi(base)) != NULL && !force)        return 0;        if (pcfi == NULL)        if ((pcfi = get_free_cfi()) == NULL)            return 0;    pcfi->base = base;    if ((ret = cfi_probe_chip(pcfi)) != 0) {        uart_printf("Flash does not exist at 0x%08x\n", pcfi->base);        return ret;    }    if (verbose)	flash_list(pcfi);    return 0;}unsigned int flash_getsize(void){    int i;    unsigned int size;    for (i = 0, size = 0; i < FLASH_MAX_CHIPSET; ++i) {        if (g_cfi[i].exist)            size += g_cfi[i].size;    }    return size;}//// erasing//#ifdef FLASH_USE_DQXstatic void dqx_wait(unsigned long addr, unsigned int datum, unsigned int wait){    unsigned int dq6, dq5;    unsigned int status, oldstatus, res;    dq6 = cfi_build_cmd(1<<6);    dq5 = cfi_build_cmd(1<<5);    if (flash_wait_div <= 1) {	if (wait > 1000) {		unsigned_divide(wait, 1000, &res, NULL);		em86xx_msleep(res);	} else {		em86xx_usleep(wait);	}	flash_wait_div = 1;    }    oldstatus = cfi_read(addr);    status = cfi_read(addr);    while ((status != datum) || 	(((status & dq6) != (oldstatus & dq6)) && ((status & dq5) != dq5))) {			if (wait > 1000) {		unsigned_divide(wait, 1000 * flash_wait_div, &res, NULL);		em86xx_msleep(res);	} else {		unsigned_divide(wait, flash_wait_div, &res, NULL);		em86xx_msleep(res);	}	    	oldstatus = cfi_read(addr);    	status = cfi_read(addr);    }}#endifint flash_erase_all(void){    int i, nchips, cnt = 0;    cfi_info_t *pcfi;    for (i = 0, nchips = 0; i < FLASH_MAX_CHIPSET; ++i) {        pcfi = &g_cfi[i];        if (!pcfi->exist)            continue;        if (pcfi->chip_state != FLSTATE_READY)            return FLASH_NOTREADY;            pcfi->chip_state = FLSTATE_ERASING;            cfi_send_cmd(0xaa, pcfi->addr_unlock1, pcfi->base);        cfi_send_cmd(0x55, pcfi->addr_unlock2, pcfi->base);        cfi_send_cmd(0x80, pcfi->addr_unlock1, pcfi->base);        cfi_send_cmd(0xaa, pcfi->addr_unlock1, pcfi->base);        cfi_send_cmd(0x55, pcfi->addr_unlock2, pcfi->base);        cfi_send_cmd(0x10, pcfi->addr_unlock1, pcfi->base);#ifdef FLASH_USE_DQX	dqx_wait(pcfi->base, 0xff, 1000*(1<<pcfi->ident.timeout_chip_erase));#else	for (cnt = 0; cnt < FLASH_ERR_CNT; cnt++) {	    uart_putc('.');	    if (pcfi->ident.timeout_chip_erase != 0)		em86xx_msleep(1<<pcfi->ident.timeout_chip_erase);	    else		em86xx_msleep(100);	    if ((cfi_read(pcfi->base) & 0xff) == 0xff)		break;	}                                                                                	if (cnt >= FLASH_ERR_CNT)	    break;#endif            pcfi->chip_state = FLSTATE_READY;        ++nchips;    }        if (cnt >= FLASH_ERR_CNT)	return FLASH_VERIFY_FAIL;    return (nchips == 0) ? FLASH_NOTEXIST : FLASH_OK;}int flash_erase_oneblock(unsigned long addr){    int cnt = 0;    cfi_info_t *pcfi = find_cfi(addr);    if (pcfi == NULL)        return FLASH_NOTEXIST;    if (pcfi->chip_state != FLSTATE_READY)        return FLASH_NOTREADY;    pcfi->chip_state = FLSTATE_ERASING;    cfi_send_cmd(0xaa, pcfi->addr_unlock1, pcfi->base);    cfi_send_cmd(0x55, pcfi->addr_unlock2, pcfi->base);    cfi_send_cmd(0x80, pcfi->addr_unlock1, pcfi->base);    cfi_send_cmd(0xaa, pcfi->addr_unlock1, pcfi->base);    cfi_send_cmd(0x55, pcfi->addr_unlock2, pcfi->base);    cfi_send_cmd(0x30, addr - pcfi->base, pcfi->base);#ifdef FLASH_USE_DQX    dqx_wait(addr, 0xff, 1000*(1<<pcfi->ident.timeout_block_erase));#else    for (cnt = 0; cnt < FLASH_ERR_CNT; cnt++) {        em86xx_msleep(1 << pcfi->ident.timeout_block_erase);	if ((cfi_read(addr) & 0xff) == 0xff)	    break;    }#endif    pcfi->chip_state = FLSTATE_READY;    return (cnt >= FLASH_ERR_CNT) ? FLASH_VERIFY_FAIL : FLASH_OK;}int flash_erase_region(unsigned long addr, unsigned int len){    unsigned int start, blocksize;    cfi_info_t *pcfi = find_cfi(addr);    if (len == 0)        return FLASH_OK;    if (pcfi == NULL)        return FLASH_NOTEXIST;    if (pcfi->chip_state != FLSTATE_READY)        return FLASH_NOTREADY;    if (flash_calcblock(addr, &start, &blocksize) < 0)	return FLASH_NOTEXIST;    do {	uart_putc('.');        flash_erase_oneblock(start);        start += blocksize;        if (flash_calcblock(start, &start, &blocksize) < 0)	    break;    } while (start < addr + len);    return FLASH_OK;}//// read / writing//// suppose 16 bits writing//int flash_read_data(unsigned long addr, void *data, int len){    memcpy(data, (void *) addr, len);    return FLASH_OK;}int flash_writable(unsigned long addr, int len){    int i;    for (i = 0; i < len; ++i) {        if (((unsigned char *) (addr))[i] != 0xff)            return 0;    }    return 1;}int flash_write_onebyte(unsigned long addr, unsigned int data){    int cnt = 0;    unsigned int curdata;    unsigned int olddata, newaddr, newdata;    cfi_info_t *pcfi = find_cfi(addr);#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 CFIDEV_BUSWIDTH == 1    newaddr = addr;    olddata = curdata = cfi_read(newaddr);    newdata = data;#elif CFIDEV_BUSWIDTH == 2    newaddr = addr & ~0x01;    curdata = cfi_read(newaddr);    if (addr & 0x01) {        olddata = (curdata & 0xff00) >> 8;        newdata = (curdata & 0x00ff) | ((data & 0xff) << 8);    } else {        olddata = (curdata & 0x00ff);        newdata = (curdata & 0xff00) | (data & 0xff);    }#endif    if (~olddata & data)         return FLASH_WRITE_FAULT;    pcfi->chip_state = FLSTATE_WRITING;    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);    cfi_write(newdata, newaddr);#ifdef FLASH_USE_DQX    dqx_wait(newaddr, newdata, 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(newaddr) == newdata)	    break;    }#endif    pcfi->chip_state = FLSTATE_READY;    return (cnt >= FLASH_ERR_CNT) ? FLASH_WRITE_FAULT : FLASH_OK;}int flash_write_oneword(unsigned long addr, unsigned int data){#if (CFIDEV_BUSWIDTH != 1 && CFIDEV_BUSWIDTH != 2)#error "Current code doesn't support other than 8-bits and 16-bits writing"#endif#if CFIDEV_BUSWIDTH == 1    int ret;        if ((ret = flash_write_onebyte(addr, data & 0xff)) == FLASH_OK)        ret = flash_write_onebyte(addr + 1, (data >> 8) & 0xff);        return ret;#elif CFIDEV_BUSWIDTH == 2    int ret;    int cnt = 0;    unsigned int olddata, newaddr;    cfi_info_t *pcfi = find_cfi(addr);    // if the address is not aligned    if ((addr & 0x01) != 0) {        if ((ret = flash_write_onebyte(addr, data & 0xff)) == FLASH_OK)            ret = flash_write_onebyte(addr + 1, (data >> 8) & 0xff);            return ret;    }    if (pcfi == NULL)         return FLASH_NOTEXIST;    if (pcfi->chip_state != FLSTATE_READY)        return FLASH_NOTREADY;    newaddr = addr & ~0x01;    olddata = cfi_read(newaddr);    if (~olddata & data)         return FLASH_WRITE_FAULT;    pcfi->chip_state = FLSTATE_WRITING;    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);    cfi_write(data, newaddr);#ifdef FLASH_USE_DQX    dqx_wait(newaddr, data, 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(newaddr) == data)	    break;    }#endif    pcfi->chip_state = FLSTATE_READY;    return (cnt >= FLASH_ERR_CNT) ? FLASH_WRITE_FAULT : FLASH_OK;#endif}int do_write_buffer(cfi_info_t *pcfi, unsigned long adr, const unsigned char *buf, int len){	int wbufsize, z,ret=0, cnt=0;	unsigned char datum=0;		unsigned int dq1,dq7, dq5;        unsigned int status, oldstatus, res;	unsigned int wait = 1<<pcfi->ident.timeout_single_write;	wbufsize = CFIDEV_INTERLEAVE << 5; //cfi->cfiq->MaxBufWriteSize=0x5	adr += 0; //chip->start=0x0;			/* write buffers algorithm taken from S29GL064M90 manual */	cfi_send_cmd(0xAA, pcfi->addr_unlock1, pcfi->base);	cfi_send_cmd(0x55, pcfi->addr_unlock2, pcfi->base);	cfi_write(0x25, adr);	cfi_write((len/CFIDEV_BUSWIDTH-1), adr); /* word count */	/* Write data */	for (z = 0; z < len; z += CFIDEV_BUSWIDTH) {		cfi_write( datum=*((unsigned char*)buf)++, adr+z);	}		/* start program */	cfi_write(0x29, adr);	//zxh+		/* use data polling algorithm */	dq1 = cfi_build_cmd(1<<1);	dq5 = cfi_build_cmd(1<<5);	dq7 = cfi_build_cmd(1<<7);	z -= CFIDEV_BUSWIDTH;	/* go to last written address */	do {	    	status = cfi_read(adr+z);	    	if( (dq7 & status) == (dq7 & datum) )			break;	    	if( ((dq5 & status) == dq5) || ((dq1 & status) == dq1) ) {			status = cfi_read( adr+z );			if( (dq7 & status) != (dq7 & datum) )			{		    		ret = 1;				break;			} else 				break;	    	}				cnt++;	} while( cnt<1000 );	if( !ret && !(cnt<1000) )	{	    	uart_puts("Waiting for write to complete timed out in do_write_buffer.\n");        	    	ret = 1;	}

⌨️ 快捷键说明

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