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

📄 flash.c

📁 em86xx 完整启动程序,支持网络下载与串通下载
💻 C
📖 第 1 页 / 共 3 页
字号:
}int cfi_chip_setup(cfi_info_t *pcfi){    int i;    int num_erase_regions = cfi_read(pcfi->base + cfi_build_cmd_addr(0x2c));    unsigned int start;    if (num_erase_regions == 0)        return FLASH_NOREGION;    for (i = 0; i < (sizeof pcfi->ident) - (sizeof pcfi->ident.erase_region_info) + (num_erase_regions * 4); ++i)        ((unsigned char *) &pcfi->ident)[i] = cfi_read(pcfi->base + cfi_build_cmd_addr(0x10 + i));    if (pcfi->ident.primary_id != 0x2) /* Not using command set 0002 */	uart_puts("Warning: not using command set 0002\n");    for (i = 0, start = 0; i < num_erase_regions; ++i) {        pcfi->erase_regions[i].start = start;        pcfi->erase_regions[i].size = 0x100 * ((pcfi->ident.erase_region_info[i] >> 16) & 0xffff);        pcfi->erase_regions[i].blocks = (pcfi->ident.erase_region_info[i] & 0xffff) + 1;        start += pcfi->erase_regions[i].size * pcfi->erase_regions[i].blocks;    }    pcfi->size = 1 << pcfi->ident.device_size;    return FLASH_OK;}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);	#ifdef SET_SERVER_IP_FOR_DOWNLOAD	unsigned long show=0;#endif     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_printf("  0x%08x be erased\n",start);	 uart_printf("  0x%08x blocksize\n",blocksize);	#ifdef SET_SERVER_IP_FOR_DOWNLOAD		if(show%2){			fip_display_character(10, '|');		}		else{			fip_display_character(10, '-');		}		 show++;	#endif 	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);

⌨️ 快捷键说明

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