📄 dev_flash_intel.c
字号:
io->progbuf_latch_addr = addr; if (io->pb_count > INTEL_WRITEBUFFER_SIZE) { io->program_setlb_error = io->erase_clearlb_error = 1; io->wsm_mode = WSM_READY; printf ("\nFlash: buffer program count too large: %d", io->pb_count); break; } if (SECTOR_ADDR (addr) != SECTOR_ADDR (addr + io->pb_count - 1)) { io->program_setlb_error = io->erase_clearlb_error = 1; io->wsm_mode = WSM_READY; printf ("\nFlash: buffer program address range across sectors: 0x%x-0x%x", addr, addr + io->pb_count - 1); break; } break; } if (io->pb_loaded < io->pb_count) { /* step 2: load data */ if (SECTOR_ADDR (addr) != SECTOR_ADDR (io->progbuf_latch_addr)) { io->program_setlb_error = io->erase_clearlb_error = 1; io->wsm_mode = WSM_READY; printf ("\nFlash: buffer program address across sectors: 0x%x", addr); break; } if (io->pb_loaded == 0) io->pb_start = addr; io->pb_buf[WORD_ADDR (addr) & INTEL_WRITEBUFFER_MASK] = data; io->pb_loaded++; break; } if ((data & 0xff) == WSM_CONFIRM) { /* step 3: confirm the program */ io->progbuf_busy = 1; io->read_mode = WSM_READ_STATUS; /* copy buffer to flash */ if (ISLOCKED (io->progbuf_latch_addr)) { printf ("\nFlash: buffer program locked address [0x%x]", io->progbuf_latch_addr); io->program_setlb_error = io->protection_error = 1; } else if (DEVICE_SUSPENDED) { printf ("\nFlash: buffer program suspended device"); io->program_setlb_error = 1; } else if (io->vpen != 1) { printf ("\nFlash: can't buffer program when VPEN low"); io->program_setlb_error = io->program_volt_error = 1; } else { for (j = WORD_ADDR (io->pb_start); j < WORD_ADDR (io->pb_start) + INTEL_WRITEBUFFER_SIZE; j++) //mem[j] &= io->pb_buf[j & INTEL_WRITEBUFFER_MASK]; real_write_word (state, j, real_read_word (state, j) & io->pb_buf[j & INTEL_WRITEBUFFER_MASK]); } io->wsm_mode = WSM_READY; io->progbuf_busy = 0; break; } else { printf ("\nFlash: buffer program with wrong cmd sequence: 0x%x", data); io->program_setlb_error = io->erase_clearlb_error = 1; io->wsm_mode = WSM_READY; break; } break; case WSM_PROGRAM: case WSM_PROGRAM2: io->program_busy = 1; io->program_latch_addr = addr; io->program_latch_data = data; io->read_mode = WSM_READ_STATUS; if (ISLOCKED (io->program_latch_addr)) { printf ("\nFlash: program locked address [0x%x]=0x%x", addr, data); io->program_setlb_error = io->protection_error = 1; } else if (ADDR_SUSPENDED (io->program_latch_addr)) { printf ("\nFlash: program suspended address [0x%x]=0x%x", addr, data); io->program_setlb_error = 1; } else if (io->vpen != 1) { printf ("\nFlash: can't program when VPEN low"); io->program_setlb_error = io->program_volt_error = 1; } else { //mem[WORD_ADDR(io->program_latch_addr)] &= data; real_write_word (state, io->program_latch_addr, real_read_word (state, io-> program_latch_addr) & data); } io->program_busy = 0; io->wsm_mode = WSM_READY; break; case WSM_BLOCK_ERASE: if ((data & 0xff) == WSM_CONFIRM) { io->erase_busy = 1; io->erase_latch_addr = addr & FLASH_SECTOR_MASK; io->read_mode = WSM_READ_STATUS; if (ISLOCKED (io->erase_latch_addr)) { printf ("\nFlash: erase locked address [0x%x]", io->erase_latch_addr); io->erase_clearlb_error = io->protection_error = 1; } else if (DEVICE_SUSPENDED) { printf ("\nFlash: erase suspended device"); io->erase_clearlb_error = 1; } else if (io->vpen != 1) { printf ("\nFlash: can't erase when VPEN low\n"); io->erase_clearlb_error = io->program_volt_error = 1; } else { for (i = 0; i < WORD_ADDR (FLASH_SECTOR_SIZE); i++) { //mem[WORD_ADDR(io->erase_latch_addr)+i] = 0xffffffff; real_write_word (state, io-> erase_latch_addr + i * 4, 0xffffffff); } } io->erase_busy = 0; io->wsm_mode = WSM_READY; break; } else { printf ("\nFlash: erase with wrong cmd sequence: 0x%x", data); io->wsm_mode = WSM_READY; break; } break; case WSM_LOCK_ACCESS: if ((data & 0xff) == 0x01) { /* set lock bit */ io->lock_busy = 1; io->read_mode = WSM_READ_STATUS; if (DEVICE_SUSPENDED) { printf ("\nFlash: set lock on suspended device"); io->program_setlb_error = 1; } else if (io->vpen != 1) { printf ("\nFlash: can't set lock when VPEN low"); io->program_setlb_error = io->program_volt_error = 1; } else { io->lock[SECTOR_ADDR (addr)] = 1; } io->lock_busy = 0; io->wsm_mode = WSM_READY; break; } else if ((data & 0xff) == WSM_CONFIRM) { /* clear all lock bits */ io->lock_busy = 1; io->read_mode = WSM_READ_STATUS; if (DEVICE_SUSPENDED) { printf ("\nFlash: clear locks on suspended device"); io->erase_clearlb_error = 1; } else if (io->vpen != 1) { printf ("\nFlash: can't clear locks when VPEN low"); io->erase_clearlb_error = io->program_volt_error = 1; } else { for (i = 0; i < io->size / FLASH_SECTOR_SIZE; i++) io->lock[i] = 0; } io->lock_busy = 0; io->wsm_mode = WSM_READY; break; } else { printf ("\nFlash: lock access with wrong cmd sequence: 0x%x", data); io->wsm_mode = WSM_READY; break; } break; default: printf ("\nFlash: Can't recognize WSM mode: 0x%x", io->wsm_mode); break; } return ret;}voidinit_querytable (){ int i; for (i = 0; i < INTEL_QUERYTABLE_SIZE; i++) { query[i] = 0; } /* * This is a dump of a real 28F128J3A flash query table * Lines with a "*": different from Verilog model (Ref.2) * Lines with a "+": different from the spec (Ref.1) */ query[0x00] = 0x00890089; //manu. ID //query[0x01] = 0x00170017; //device ID query[0x01] = 0x00180018; //device ID query[0x02] = 0x00010001; //? query[0x10] = 0x00510051; //"Q" query[0x11] = 0x00520052; //"R" query[0x12] = 0x00590059; //"Y" query[0x13] = 0x00010001; query[0x15] = 0x00310031; query[0x1b] = 0x00270027; query[0x1c] = 0x00360036; query[0x1f] = 0x00070007; query[0x20] = 0x00070007; query[0x21] = 0x000A000A; query[0x23] = 0x00040004; query[0x24] = 0x00040004; query[0x25] = 0x00040004; query[0x27] = 0x00180018; //2^(0x18) = 2^24 = 16MByte 28F128 flash chip size //query[0x27] = 0x00170017; query[0x28] = 0x00020002; query[0x2a] = 0x00050005; //2^5 = 32 write buffer size query[0x2c] = 0x00010001; //symmetrically-blocked query[0x2d] = 0x007F007F; //[31,16]=?(128KByte) ;[15,0]=block number query[0x30] = 0x00020002; query[0x31] = 0x00500050; //"P" query[0x32] = 0x00520052; //"R" query[0x33] = 0x00490049; //"I" query[0x34] = 0x00310031; query[0x35] = 0x00320032; // * query[0x36] = 0x00CE00CE; // * query[0x3a] = 0x00010001; query[0x3b] = 0x00010001; query[0x3c] = 0x00010001; query[0x3d] = 0x00330033; query[0x3f] = 0x00010001; query[0x40] = 0x00000000; // + query[0x41] = 0x00010001; // + query[0x42] = 0x00030003; query[0x43] = 0x00030003; query[0x44] = 0x00030003;}static intflash_intel_setup (struct device_desc *dev){ int i; struct flash_intel_io *io; struct device_interrupt *intr = &dev->intr; dev->fini = flash_intel_fini; dev->reset = flash_intel_reset; //dev->update = flash_intel_update; dev->read_byte = flash_intel_read_byte; dev->write_byte = flash_intel_write_byte; dev->read_halfword = flash_intel_read_halfword; dev->write_halfword = flash_intel_write_halfword; dev->read_word = flash_intel_read_word; dev->write_word = flash_intel_write_word; io = (struct flash_intel_io *) malloc (sizeof (struct flash_intel_io)); memset (io, 0, sizeof (struct flash_intel_io)); if (io == NULL) return 1; dev->data = (void *) io; flash_intel_reset (dev); /* see if we need to set default values. * */ //set_device_default (dev, intel_flash_def); return 0;}voidflash_intel_init (struct device_module_set *mod_set){ int i; register_device_module ("28F128J3A", mod_set, &flash_intel_setup);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -