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);
}
参照代码改了后,与原来的结果一样, 不知道是不是我改的有问题。
离线