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);
}
Exemplo n.º 2
0
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;
}