您尚未登录。

楼主 #1 2019-01-30 11:09:10

Quotation
会员
注册时间: 2018-10-04
已发帖子: 296
积分: 264.5

SPI Flash不能写入问题解决

F1C100s,XBoot下调用block和spi-flash驱动操作SPI Flash,能读,不能擦除不能写。

断断续续调了几天终于调通了,问题出在Flash CS时序。XBoot spi-flash驱动里的CS时序不满足我用的Flash的要求。
我用的Puya普冉的Flash(很便宜),数据手册里特意说了,某些操作必须在字节边界处置CS为高,这是出于数据保护的目的,检查命令长度,如果长度错了就不执行命令。

For the following instructions: WREN, WRDI, WRSR, PE, SE, BE32K, BE, CE, PP, DPP, QPP, DP, ERSCUR, PRSCUR, SUSPEND, RESUME, RSTEN, RST, the CS# must go high exactly at the byte boundary; otherwise, the instruction will be rejected and not executed.

也就是说SPI在发送完这几个命令和数据后,需要马上拉高CS。但XBoot里的Flash驱动是按照别的Flash写的,时序不满足这个要求。因此在spi-flash.c加入一些spi_device_select()和spi_device_deselect(),就能够擦除写入了!代码改动如下。

static void spi_flash_sector_erase(struct spi_device_t * dev, u64_t addr)
{
	u8_t tx[4];

	spi_device_select(dev);
	spi_flash_write_enable(dev);
	spi_device_deselect(dev);

	tx[0] = OPCODE_SE;
	tx[1] = (u8_t)(addr >> 16);
	tx[2] = (u8_t)(addr >> 8);
	tx[3] = (u8_t)(addr >> 0);
	spi_device_select(dev);
	spi_device_write_then_read(dev, tx, 4, 0, 0);
	spi_device_deselect(dev);

	spi_device_select(dev);
	spi_flash_wait_for_busy(dev);
	spi_device_deselect(dev);
}

static void spi_flash_sector_erase_4k(struct spi_device_t * dev, u64_t addr)
{
	u8_t tx[4];

	spi_device_select(dev);
	spi_flash_write_enable(dev);
	spi_device_deselect(dev);

	tx[0] = OPCODE_BE_4K;
	tx[1] = (u8_t)(addr >> 16);
	tx[2] = (u8_t)(addr >> 8);
	tx[3] = (u8_t)(addr >> 0);
	spi_device_select(dev);
	spi_device_write_then_read(dev, tx, 4, 0, 0);
	spi_device_deselect(dev);

	spi_device_select(dev);
	spi_flash_wait_for_busy(dev);
	spi_device_deselect(dev);
}

static void spi_flash_write_one_page(struct spi_device_t * dev, u64_t addr, u8_t * buf)
{
	u8_t tx[4];

	spi_device_select(dev);
	spi_flash_write_enable(dev);
	spi_device_deselect(dev);

	tx[0] = OPCODE_PP;
	tx[1] = (u8_t)(addr >> 16);
	tx[2] = (u8_t)(addr >> 8);
	tx[3] = (u8_t)(addr >> 0);
	spi_device_select(dev);
	spi_device_write_then_read(dev, tx, 4, 0, 0);
	spi_device_write_then_read(dev, buf, 256, 0, 0);
	spi_device_deselect(dev);

	spi_device_select(dev);
	spi_flash_wait_for_busy(dev);
	spi_device_deselect(dev);
}

按理说,可以用SPI硬件自动控制CS。sunxi-tools里就是这样做的,没有操作CS的代码,也能正确写入。但我还没调出来,目前仍然用软件控制CS。

最近编辑记录 Quotation (2019-01-30 11:09:54)

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn