AllWinner全志V3s荔枝派zero板子用W25Q256,
发现我烧文件系统之后,串口无输出, 
直接进入芯片内部的fel,
感觉spi flash被擦掉了, 这是什么情况?
-----------------------------------------
新鲜出炉 windows 版本 32M spi nor flash 版本烧录软件: sunxi-tools-win32-support_f1c100s_32M.7z
测试OK!
离线
转载看云的文章: sunxi-fel增加对16M以上Flash的支持
由于SPI flash 的地址是24bit,也就是最大16M 地址空间,所以对于32M flash,需要增加bank切换支持。
uboot中有CONFIG_SPI_FLASH_BAR选项可以使能bank切换。
但是sunxi-fel中尚未支持,所以下载的时候超出16M会循环覆盖掉。
这里介绍对sunxi-fel增加16M以上flash支持的方法。
u-boot的支持
drivers/mtd/spi/spi_flash.c
static int write_bar(struct spi_flash *flash, u32 offset)
{
	u8 cmd, bank_sel;
	int ret;
	bank_sel = offset / (SPI_FLASH_16MB_BOUN << flash->shift);
	if (bank_sel == flash->bank_curr)
		goto bar_end;
	cmd = flash->bank_write_cmd;
	ret = spi_flash_write_common(flash, &cmd, 1, &bank_sel, 1);
	if (ret < 0) {
		debug("SF: fail to write bank register\n");
		return ret;
	}
bar_end:
	flash->bank_curr = bank_sel;
	return flash->bank_curr;
}sunxi-fel的支持
fel-spiflash.c
#define CMD_WRITE_ENABLE 0x06
#define SPI_FLASH_16MB_BOUN  0x1000000
# define CMD_BANKADDR_BRWR              0x17	//only SPANSION flash use it
# define CMD_BANKADDR_BRRD              0x16
# define CMD_EXTNADDR_WREAR             0xC5
# define CMD_EXTNADDR_RDEAR             0xC8
size_t bank_curr = 0;
void aw_fel_spiflash_write_helper(feldev_handle *dev,
				  uint32_t offset, void *buf, size_t len,
				  size_t erase_size, uint8_t erase_cmd,
				  size_t program_size, uint8_t program_cmd)
{
	uint8_t *buf8 = (uint8_t *)buf;
	size_t max_chunk_size = dev->soc_info->scratch_addr - dev->soc_info->spl_addr;
	size_t cmd_idx, bank_sel;
	if (max_chunk_size > 0x1000)
		max_chunk_size = 0x1000;
	uint8_t *cmdbuf = malloc(max_chunk_size);
	cmd_idx = 0;
	prepare_spi_batch_data_transfer(dev, dev->soc_info->spl_addr);
	//add bank support
	{
	cmd_idx = 0;
	bank_sel = offset /SPI_FLASH_16MB_BOUN;
	if (bank_sel == bank_curr)
		goto bar_end;
	/* Emit write enable command */
	cmdbuf[cmd_idx++] = 0;
	cmdbuf[cmd_idx++] = 1;
	cmdbuf[cmd_idx++] = CMD_WRITE_ENABLE;
	/* Emit write bank */
	cmdbuf[cmd_idx++] = 0;
	cmdbuf[cmd_idx++] = 2;
	cmdbuf[cmd_idx++] = CMD_EXTNADDR_WREAR;
	cmdbuf[cmd_idx++] = offset >> 24;
	/* Emit wait for completion */
	cmdbuf[cmd_idx++] = 0xFF;
	cmdbuf[cmd_idx++] = 0xFF;
	/* Emit the end marker */
	cmdbuf[cmd_idx++] = 0;
	cmdbuf[cmd_idx++] = 0;
	aw_fel_write(dev, cmdbuf, dev->soc_info->spl_addr, cmd_idx);
	aw_fel_remotefunc_execute(dev, NULL);
	bar_end:
		bank_curr = bank_sel;
	}
	
	cmd_idx = 0;重新编译sunxi-fel后就可以烧录32M flash了~
离线
看看对你有没有帮助, 
我估计你写到后面的16MiB位置了,
而没有切换bank,
所以绕回头擦除了 uboot, 
导致系统无法启动进入了fel
离线
太好了,谢谢。
按上面的代码改了 aw_fel_spiflash_write_helper( ) 之后果然可以烧录32MiB flash了.
离线
呼叫沉鱼大神 能不能让sunxi-fel支持a33
离线
奇怪我按照这样改动,还是无法烧写32MB 文件,但烧写16MB文件正常。不知道哪里出问题了
离线
离线
我是V3S。我刷新了一下磁盘cache重新编译然后似乎是烧成功了,uboot跑起来了说明没有绕回去把头擦了。但是后来linux加载jffs时候全是错误,跑不起来。我烧写的是网盘V3s_W25Q256_Qt5.9.1.bin和V3s_W25Q256_mplayer.bin, 同样的问题
离线
离线
你flash是 W25Q256 ?
是的,就怕不兼容,专门去买的W25Q256
离线
离线
正好有个W25Q256开发板,我来试一试:
hexing@ubuntu:/tmp/ccc$ sudo sunxi-fel spiflash-info
Manufacturer: Winbond (EFh), model: 40h, size: 33554432 bytes.hexing@ubuntu:/tmp/ccc$ sudo sunxi-fel -p spiflash-write 0 /mnt/hgfs/E/V3s_W25Q256_Qt5.9.1.bin
2% [ ] 49.8 kB/s, ETA 11:03
离线
能发下改过的c文件吗?
改动很简单,我实在想不出为什么会出错,我都检查了几遍了
另外,问一下QT在V3S上跑的速度如何?
离线
当时没有备份,也忘记改了什么,关键你现在读出来的和写入的是否一致?
sudo ./sunxi-fel -p spiflash-read 0 33554432 ./dump.bin
读出来和原文件对比很大差异,第一个字节就错位相差一个00,过了uboot后差得更多
离线
离线
这是一个关于sunxi fel 无法烧录16m spi flash的故事
离线
转载看云的文章: sunxi-fel增加对16M以上Flash的支持
由于SPI flash 的地址是24bit,也就是最大16M 地址空间,所以对于32M flash,需要增加bank切换支持。
uboot中有CONFIG_SPI_FLASH_BAR选项可以使能bank切换。
但是sunxi-fel中尚未支持,所以下载的时候超出16M会循环覆盖掉。
这里介绍对sunxi-fel增加16M以上flash支持的方法。
u-boot的支持
drivers/mtd/spi/spi_flash.cstatic int write_bar(struct spi_flash *flash, u32 offset) { u8 cmd, bank_sel; int ret; bank_sel = offset / (SPI_FLASH_16MB_BOUN << flash->shift); if (bank_sel == flash->bank_curr) goto bar_end; cmd = flash->bank_write_cmd; ret = spi_flash_write_common(flash, &cmd, 1, &bank_sel, 1); if (ret < 0) { debug("SF: fail to write bank register\n"); return ret; } bar_end: flash->bank_curr = bank_sel; return flash->bank_curr; }sunxi-fel的支持
fel-spiflash.c#define CMD_WRITE_ENABLE 0x06 #define SPI_FLASH_16MB_BOUN 0x1000000 # define CMD_BANKADDR_BRWR 0x17 //only SPANSION flash use it # define CMD_BANKADDR_BRRD 0x16 # define CMD_EXTNADDR_WREAR 0xC5 # define CMD_EXTNADDR_RDEAR 0xC8 size_t bank_curr = 0; void aw_fel_spiflash_write_helper(feldev_handle *dev, uint32_t offset, void *buf, size_t len, size_t erase_size, uint8_t erase_cmd, size_t program_size, uint8_t program_cmd) { uint8_t *buf8 = (uint8_t *)buf; size_t max_chunk_size = dev->soc_info->scratch_addr - dev->soc_info->spl_addr; size_t cmd_idx, bank_sel; if (max_chunk_size > 0x1000) max_chunk_size = 0x1000; uint8_t *cmdbuf = malloc(max_chunk_size); cmd_idx = 0; prepare_spi_batch_data_transfer(dev, dev->soc_info->spl_addr); //add bank support { cmd_idx = 0; bank_sel = offset /SPI_FLASH_16MB_BOUN; if (bank_sel == bank_curr) goto bar_end; /* Emit write enable command */ cmdbuf[cmd_idx++] = 0; cmdbuf[cmd_idx++] = 1; cmdbuf[cmd_idx++] = CMD_WRITE_ENABLE; /* Emit write bank */ cmdbuf[cmd_idx++] = 0; cmdbuf[cmd_idx++] = 2; cmdbuf[cmd_idx++] = CMD_EXTNADDR_WREAR; cmdbuf[cmd_idx++] = offset >> 24; /* Emit wait for completion */ cmdbuf[cmd_idx++] = 0xFF; cmdbuf[cmd_idx++] = 0xFF; /* Emit the end marker */ cmdbuf[cmd_idx++] = 0; cmdbuf[cmd_idx++] = 0; aw_fel_write(dev, cmdbuf, dev->soc_info->spl_addr, cmd_idx); aw_fel_remotefunc_execute(dev, NULL); bar_end: bank_curr = bank_sel; } cmd_idx = 0;重新编译sunxi-fel后就可以烧录32M flash了~
你这里是修改了深哦哦就32M的可以了哦哦
离线
zero flash使用w25q256fv,刚开始偶尔能烧写固件,串口无输出直接进入fel,对比写入数据发现写入无效。解决方法:每次烧写或重新上电前对zero进行短接放点即可。
离线
多谢分享,搞半天一直32M有问题
离线
感谢分享,感觉这个工具很麻烦
离线
按照这个方法修改了Sunxi tools, 晚上试试, 谢谢分享!
离线
Can someone please post the first file(sunxi-tools-win32-support_f1c100s_32M.7z), so I can download it? Thank you.
离线
Can someone please post the first file(sunxi-tools-win32-support_f1c100s_32M.7z), so I can download it? Thank you.
You can recharge your account and then you can download it Ha Ha.
This is a tutorial to become a VIP.
离线
GD25Q256能不能用呢?站内下了好几个都不行
离线
用工具烧录进去,再读出来数据都不对了
离线
https://whycan.cn/files/members/3/QQ20180315142018.png
按这个修改, 可以通过编译。
Why don't you commit to the main repository?
离线
FW1330的spiflash芯片能用这个工具吗?
离线
/*
 * Write data to the SPI flash. Use the first 4KiB of SRAM as the data buffer.
 */
#define CMD_WRITE_ENABLE 0x06
#define SPI_FLASH_16MB_BOUN  0x1000000
# define CMD_BANKADDR_BRWR              0x17    //only SPANSION flash use it
# define CMD_BANKADDR_BRRD              0x16
# define CMD_EXTNADDR_WREAR             0xC5
# define CMD_EXTNADDR_RDEAR             0xC8
size_t bank_curr = 0;
void aw_fel_spiflash_write_helper(feldev_handle *dev,
                  uint32_t offset, void *buf, size_t len,
                  size_t erase_size, uint8_t erase_cmd,
                  size_t program_size, uint8_t program_cmd)
{
    soc_info_t *soc_info = dev->soc_info;
    uint8_t *buf8 = (uint8_t *)buf;
    size_t max_chunk_size = soc_info->scratch_addr - soc_info->spl_addr;
    size_t cmd_idx,bank_sel;
    if (max_chunk_size > 0x1000)
        max_chunk_size = 0x1000;
    uint8_t *cmdbuf = malloc(max_chunk_size);
    
    //补丁代码
    
    prepare_spi_batch_data_transfer(dev, dev->soc_info->spl_addr);
    //add bank support
    {
        cmd_idx = 0;
        bank_sel = offset /SPI_FLASH_16MB_BOUN;
        if (bank_sel == bank_curr)
            goto bar_end;
        /* Emit write enable command */
        cmdbuf[cmd_idx++] = 0;
        cmdbuf[cmd_idx++] = 1;
        cmdbuf[cmd_idx++] = CMD_WRITE_ENABLE;
        /* Emit write bank */
        cmdbuf[cmd_idx++] = 0;
        cmdbuf[cmd_idx++] = 2;
        cmdbuf[cmd_idx++] = CMD_EXTNADDR_WREAR;
        cmdbuf[cmd_idx++] = offset >> 24;
        /* Emit wait for completion */
        cmdbuf[cmd_idx++] = 0xFF;
        cmdbuf[cmd_idx++] = 0xFF;
        /* Emit the end marker */
        cmdbuf[cmd_idx++] = 0;
        cmdbuf[cmd_idx++] = 0;
        aw_fel_write(dev, cmdbuf, dev->soc_info->spl_addr, cmd_idx);
        aw_fel_remotefunc_execute(dev, NULL);
    bar_end:
        bank_curr = bank_sel;
    }
    
    
    
    
    cmd_idx = 0;
    prepare_spi_batch_data_transfer(dev, soc_info->spl_addr);
    while (len > 0) {
        while (len > 0 && max_chunk_size - cmd_idx > program_size + 64) {
            if (offset % erase_size == 0) {
                /* Emit write enable command */
                cmdbuf[cmd_idx++] = 0;
                cmdbuf[cmd_idx++] = 1;
                cmdbuf[cmd_idx++] = CMD_WRITE_ENABLE;
                /* Emit erase command */
                cmdbuf[cmd_idx++] = 0;
                cmdbuf[cmd_idx++] = 4;
                cmdbuf[cmd_idx++] = erase_cmd;
                cmdbuf[cmd_idx++] = offset >> 16;
                cmdbuf[cmd_idx++] = offset >> 8;
                cmdbuf[cmd_idx++] = offset;
                /* Emit wait for completion */
                cmdbuf[cmd_idx++] = 0xFF;
                cmdbuf[cmd_idx++] = 0xFF;
            }
            /* Emit write enable command */
            cmdbuf[cmd_idx++] = 0;
            cmdbuf[cmd_idx++] = 1;
            cmdbuf[cmd_idx++] = CMD_WRITE_ENABLE;
            /* Emit page program command */
            size_t write_count = program_size;
            if (write_count > len)
                write_count = len;
            cmdbuf[cmd_idx++] = (4 + write_count) >> 8;
            cmdbuf[cmd_idx++] = 4 + write_count;
            cmdbuf[cmd_idx++] = program_cmd;
            cmdbuf[cmd_idx++] = offset >> 16;
            cmdbuf[cmd_idx++] = offset >> 8;
            cmdbuf[cmd_idx++] = offset;
            memcpy(cmdbuf + cmd_idx, buf8, write_count);
            cmd_idx += write_count;
            buf8    += write_count;
            len     -= write_count;
            offset  += write_count;
            /* Emit wait for completion */
            cmdbuf[cmd_idx++] = 0xFF;
            cmdbuf[cmd_idx++] = 0xFF;
        }
        /* Emit the end marker */
        cmdbuf[cmd_idx++] = 0;
        cmdbuf[cmd_idx++] = 0;
        /* Flush */
        aw_fel_write(dev, cmdbuf, soc_info->spl_addr, cmd_idx);
        aw_fel_remotefunc_execute(dev, NULL);
        cmd_idx = 0;
    }
    free(cmdbuf);
}参照代码改了后,与原来的结果一样, 不知道是不是我改的有问题。
离线