static int nand_erase_block(uffs_Device *dev, u32 block) { u8 val = 0; struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private; CHIP_CLR_NCS(chip); CHIP_SET_CLE(chip); WRITE_COMMAND(chip, NAND_CMD_ERASE1); CHIP_CLR_CLE(chip); CHIP_SET_ALE(chip); WRITE_ERASE_ADDR(chip, blcok); CHIP_CLR_ALE(chip); CHIP_SET_CLE(chip); WRITE_COMMAND(chip, NAND_CMD_ERASE2); WRITE_COMMAND(chip, NAND_CMD_STATUS); CHIP_CLR_CLE(chip); CHIP_READY(chip); READ_DATA(chip, &val, 1); CHIP_SET_NCS(chip); val = val; // just for eliminating warning return PARSE_STATUS(val); }
static int nand_write_page(uffs_Device *dev, u32 block, u32 page, const u8 *data, int data_len, const u8 *spare, int spare_len) { u8 val = 0; int ret = UFFS_FLASH_NO_ERR; UBOOL fall_through = FALSE; struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private; CHIP_CLR_NCS(chip); if (data && data_len > 0) { CHIP_SET_CLE(chip); WRITE_COMMAND(chip, NAND_CMD_READ0); WRITE_COMMAND(chip, NAND_CMD_SEQIN); CHIP_CLR_CLE(chip); CHIP_SET_ALE(chip); WRITE_DATA_ADDR(chip, block, page, 0); CHIP_CLR_ALE(chip); CHIP_BUSY(chip); WRITE_DATA(chip, data, data_len); if (data_len == dev->attr->page_data_size) fall_through = U_TRUE; else { CHIP_SET_CLE(chip); WRITE_COMMAND(chip, NAND_CMD_PAGEPROG); WRITE_COMMAND(chip, NAND_CMD_STATUS); CHIP_CLR_CLE(chip); CHIP_READY(chip); READ_DATA(chip, &val, 1); ret = PARSE_STATUS(val); } } if (ret != UFFS_FLASH_NO_ERR) goto ext; if (spare && spare_len > 0) { if (!fall_through) { CHIP_SET_CLE(chip); WRITE_COMMAND(chip, NAND_CMD_READOOB); WRITE_COMMAND(chip, NAND_CMD_SEQIN); CHIP_CLR_CLE(chip); CHIP_SET_ALE(chip); WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size); CHIP_CLR_ALE(chip); CHIP_BUSY(chip); } WRITE_DATA(chip, spare, spare_len); CHIP_SET_CLE(chip); WRITE_COMMAND(chip, NAND_CMD_PAGEPROG); WRITE_COMMAND(chip, NAND_CMD_STATUS); CHIP_CLR_CLE(chip); CHIP_READY(chip); READ_DATA(chip, &val, 1); ret = PARSE_STATUS(val); } if (data == NULL && spare == NULL) { // mark bad block CHIP_SET_CLE(chip); WRITE_COMMAND(chip, NAND_CMD_READOOB); WRITE_COMMAND(chip, NAND_CMD_SEQIN); CHIP_CLR_CLE(chip); CHIP_SET_ALE(chip); WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size + attr->block_status_offs); CHIP_CLR_ALE(chip); CHIP_BUSY(chip); val = 0; WRITE_DATA(chip, &val, 1); CHIP_SET_CLE(chip); WRITE_COMMAND(chip, NAND_CMD_PAGEPROG); WRITE_COMMAND(chip, NAND_CMD_STATUS); CHIP_CLR_CLE(chip); CHIP_READY(chip); READ_DATA(chip, &val, 1); ret = PARSE_STATUS(val); } ext: CHIP_SET_NCS(chip); return ret; }