📄 flash.c.orig
字号:
{ return g_flash_chips;}int flash_addr_found(unsigned int addr){ return (find_cfi(addr) != NULL) ? 1 : 0;}int flash_init(unsigned int base, int force){ int i, ret; struct cfi_private *pcfi; if (!g_flash_inited) { memset(&g_cfi, 0, sizeof g_cfi); for (i = 0; i < FLASH_MAX_CHIPSET; ++i) g_cfi[i].chip_state = FL_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) { PrintFormat("Flash is not exist at address 0x%08x\n", pcfi->base); return ret; } flash_list(pcfi); return 0;}//// erasing//int flash_erase_all(void){ int i, nchips; struct cfi_private *pcfi; for (i = 0, nchips = 0; i < FLASH_MAX_CHIPSET; ++i) { pcfi = &g_cfi[i]; if (!pcfi->exist) continue; if (pcfi->chip_state != FL_READY) return FLASH_NOTREADY; pcfi->chip_state = FL_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); do { PrintChar('.'); DELAY(150000); } while ((cfi_read(pcfi->base) & 0xff) != 0xff); pcfi->chip_state = FL_READY; ++nchips; } return (nchips == 0) ? FLASH_NOTEXIST : FLASH_OK;}int flash_erase_oneblock(unsigned int addr){ struct cfi_private *pcfi = find_cfi(addr); if (pcfi == NULL) return FLASH_NOTEXIST; if (pcfi->chip_state != FL_READY) return FLASH_NOTREADY; pcfi->chip_state = FL_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); do { PrintChar('.'); DELAY(100000); } while ((cfi_read(addr) & 0xff) != 0xff); pcfi->chip_state = FL_READY; return FLASH_OK;}int flash_erase_region(unsigned int addr, unsigned int len){ unsigned int start, blocksize; struct cfi_private *pcfi = find_cfi(addr); if (len == 0) return FLASH_OK; if (pcfi == NULL) return FLASH_NOTEXIST; if (pcfi->chip_state != FL_READY) return FLASH_NOTREADY; flash_calcblock(addr, &start, &blocksize); do { flash_erase_oneblock(start); start += blocksize; flash_calcblock(start, &start, &blocksize); } while (start < addr + len); return FLASH_OK;}//// read / writing//// suppose 16 bits writing//int flash_read_data(unsigned int addr, void *data, int len){ memcpy(data, (void *) addr, len); return FLASH_OK;}int flash_writable(unsigned int 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 int addr, unsigned int data){ unsigned int curdata; unsigned int olddata, newaddr, newdata; struct cfi_private *pcfi = find_cfi(addr);#if CFIDEV_BUSWIDTH != 2#error "Current code doesn't support other than 16-bits writing"#endif if (pcfi == NULL) return FLASH_NOTEXIST; if (pcfi->chip_state != FL_READY) return FLASH_NOTREADY; 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); } if (~olddata & data) return FLASH_WRITE_FAULT; pcfi->chip_state = FL_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); do { DELAY(1); } while (cfi_read(newaddr) != newdata); pcfi->chip_state = FL_READY; return FLASH_OK;}int flash_write_oneword(unsigned int addr, unsigned int data){ unsigned int olddata, newaddr; struct cfi_private *pcfi = find_cfi(addr);#if CFIDEV_BUSWIDTH != 2#error "Current code doesn't support other than 16-bits writing"#endif if (pcfi == NULL) return FLASH_NOTEXIST; if (pcfi->chip_state != FL_READY) return FLASH_NOTREADY; newaddr = addr & ~0x01; olddata = cfi_read(newaddr); if (~olddata & data) return FLASH_WRITE_FAULT; pcfi->chip_state = FL_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); do { DELAY(1); } while (cfi_read(newaddr) != data); pcfi->chip_state = FL_READY; return FLASH_OK;}int flash_write_data_internal(unsigned int addr, unsigned short *data, int nwords, struct cfi_private *pcfi){ int i; 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); for (i = 0; i < nwords; ++i) { cfi_send_cmd(0xa0, 0, pcfi->base); cfi_write(data[i], addr + (i << 1)); } cfi_send_cmd(0x90, 0, pcfi->base); cfi_send_cmd(0x00, 0, pcfi->base); return FLASH_OK;}int flash_write_data(unsigned int addr, unsigned char *data, int len){ int maxbufwords, nwords; int nloop = 0, nloop2 = 0; struct cfi_private *pcfi = find_cfi(addr);#if CFIDEV_BUSWIDTH != 2#error "Current code doesn't support other than 16-bits writing"#endif if (pcfi == NULL) return FLASH_NOTEXIST; if (pcfi->chip_state != FL_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 = FL_WRITING; if (pcfi->ident.MaxBufWriteSize == 0) maxbufwords = 1; else maxbufwords = 1 << (pcfi->ident.MaxBufWriteSize - 1); while (len > 1) { if ((nloop++ & 0x7ff) == 0) { if ((nloop2++ & 0x3f) == 0) if (nloop2 != 1) PrintUart("\r\n ", -1); PrintChar('.'); } nwords = (len >> 1); if (nwords > maxbufwords) nwords = maxbufwords; flash_write_data_internal(addr, (unsigned short *) data, nwords, pcfi); do { DELAY(1); } while (cfi_read(addr) != *(unsigned short *) data); nwords <<= 1; addr += nwords; data += nwords; len -= nwords; } pcfi->chip_state = FL_READY; if (len == 1) flash_write_onebyte(addr, *data); return FLASH_OK;}//// miscellaneous//char *cfi_vendorname(unsigned int vendor){ switch (vendor) { case P_ID_NONE: return "None"; case P_ID_INTEL_EXT: return "Intel/Sharp Extended"; case P_ID_AMD_STD: return "AMD/Fujitsu Standard"; case P_ID_INTEL_STD: return "Intel/Sharp Standard"; case P_ID_AMD_EXT: return "AMD/Fujitsu Extended"; case P_ID_MITSUBISHI_STD: return "Mitsubishi Standard"; case P_ID_MITSUBISHI_EXT: return "Mitsubishi Extended"; case P_ID_RESERVED: return "Not Allowed / Reserved for Future Use"; default: return "Unknown"; }}void flash_list(void *vpcfi){ int i, j; struct cfi_private *pcfi; for (i = 0; i < FLASH_MAX_CHIPSET; ++i) { pcfi = &g_cfi[i]; if (pcfi->exist && (vpcfi == NULL || i == (int) vpcfi || pcfi == vpcfi)) { PrintFormat("Flash %d at address 0x%08x\n", i, pcfi->base); PrintFormat(" ID : %s\n", cfi_vendorname(pcfi->ident.P_ID)); PrintFormat(" Size : %d KB\n", pcfi->size >> 10); PrintFormat(" Regions : %d\n", pcfi->ident.NumEraseRegions); for (j = 0; j < pcfi->ident.NumEraseRegions; ++j) PrintFormat(" %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 int addr, unsigned int *pstart, unsigned int *plen){ int i; struct cfi_private *pcfi = find_cfi(addr); *pstart = 0; *plen = 0; if (pcfi == NULL) return -1; for (i = pcfi->ident.NumEraseRegions - 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;}#endif // SUPPORT_FLASH
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -