AXI Quad SPI读写Flash做远程升级

这篇具有很好参考价值的文章主要介绍了AXI Quad SPI读写Flash做远程升级。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

未经允许,本文禁止转载

目录

简介

AXI Quad SPI IP设置

寄存器说明

AXI Quad SPI支持的通用命令

读flash id

读flash 数据

擦除扇区

写flash 数据

注意事项


简介

        本文简要介绍xilinx 7系的AXI quad spi IP核的使用,主要用于读写boot用的flash(n25q128为例)做在线升级用。本文会略去很多细节,主要是因为我也没有搞得很懂,其次是很多细节可以在其他博客找到介绍。目前为止,我只尝试了使用axi lite接口配置寄存器,对flash读id,读数据,擦除扇区,写数据。后期会学习如何对flash进行分区管理,做升级备份以及针对不同flash加入quad的读写命令提高速率。

        串行flash通常指spi flash,有standard,dual,quad三种,flash的操作就是发送命令,发送地址(可选),写数据/读数据(可选)。各种模式间的区分主要在于传输数据在数据线上的分布。这里我描述不清楚,细节暂且略过。    AXI Quad SPI读写Flash做远程升级

AXI Quad SPI IP设置

         手册pg153介绍了该ip的寄存器含义,在第五章节Example Programming Sequence介绍了几种flash操作方式的寄存器写顺序。IP配置中,XIP(eXecute In Place)即芯片内执行,指应用程序可以直接在flash闪存内运行,就是说提供一个memory map的操作接口让CPU直接访问地址,就像访问内存一样,而不是发送flash的cmd命令,相当于是flash里再集成了一个控制器,把读地址命令转换为各种读时序。注意XIP只能读flash。这里我用不上不勾选。勾选performance Mode就能有AXI4接口支持突发,目前也不需要。配置IP为quad模式,只有1个slave设备,设备类型是混合的,支持winbond,micron,spansion,macronix共有的命令。如果勾选Micron,就能支持micron的特殊命令,否则发送它的特殊命令,IPISR状态寄存器就会报command error。FIFO深度只有16和256两种选择。STARTUP原语勾选上后指SPI的clk就会从FPGA专用的CCLK引脚输出时钟。

AXI Quad SPI读写Flash做远程升级

         axi lite和spi的时钟频率在手册上有说明。spi_clk是操作flash clk的2倍,这个频率也要受到flash器件的约束。STARTUP_IO不用接,SPI_IO输出后用IOBUF引出到inout管脚即可,也可以自己写三态控制,spi_io0_t = 1时输出高阻。

AXI Quad SPI读写Flash做远程升级

 AXI Quad SPI读写Flash做远程升级

寄存器说明

        寄存器说明在pg153的第二章节Register Space。主要寄存器如下。 

AXI Quad SPI读写Flash做远程升级

        该IP的操作原理就是,先配置SPI为master,配置相位/极性,复位fifo,禁止传输;再把命令和数据写到SPI_DTR寄存器里,再使能设备片选,使能传输,关闭片选,关闭传输;从SPI_DRR里读取出数据(可选)。此外可以配置中断,选择使能哪些中断,再打开全局中断使能,传输完后查询IPISR就知道当前传输有没有错误。

        40h:复位寄存器,写0xa复位整个IP,自动解复位。

        60h:控制寄存器,控制SPI的工作方式。

        64h:状态寄存器,查看fifo是否空满,用来判断是否传输结束。

        68h:发送fifo,往里面写数据,写满了会覆盖。所以不要写满。

        6ch:接收fifo,接收满了会自动丢弃后续数据。

        70h:片选,写0就表示0设备的cs拉低,某个设备片选结束后,写一个没有用的设备拉高cs。

        74h:发送fifo里有多少个数据。比如值5,表示里面有6个数据待发送。

        78h:接收fifo里有多少个数据。比如值5,表示里面有6个数据还没有读走。

AXI Quad SPI支持的通用命令

        查看flash手册可以发送,应该绝大多数flash都支持下命的这些命令。尤其是02/06/9f/d8,这也是我目前成功应用过的命令。

AXI Quad SPI读写Flash做远程升级

读flash id

        读flash id和普通读操作没有区别,先配置SPI,禁止发送,就是发送读cmd(9f),再写几个dummy(假的,没有意义的数据)用于交换数据出来,使能片选,使能发送,关闭片选,禁止发送,读数据。对应的手册描述如下所述。

AXI Quad SPI读写Flash做远程升级

具体代码如下所示。dummy的个数是可以自己控制的,要读多少数据就写几个dummy数据进去。

  REG_W(pstDev, 0x80040, 0xa);       //Software Reset Register
  REG_W(pstDev, 0x80028, 0x00003fff);//使能所有中断
  REG_W(pstDev, 0x8001c, 0x80000000);//打开全局中断使能
  REG_W(pstDev, 0x80060, 0x000001e6);//复位tx rx fifo,
  REG_W(pstDev, 0x80060, 0x00000186);//解复位fifo
  REG_W(pstDev, 0x80068, 0x0000009f);//cmd = 9f,读flash id
  REG_W(pstDev, 0x80068, 0x00000000);//dummy
  REG_W(pstDev, 0x80068, 0x00000000);//dummy
  REG_W(pstDev, 0x80068, 0x00000000);//dummy
  REG_W(pstDev, 0x80068, 0x00000000);//dummy
  REG_W(pstDev, 0x80068, 0x00000000);//dummy
  REG_W(pstDev, 0x80068, 0x00000000);//dummy
  REG_W(pstDev, 0x80068, 0x00000000);//dummy
  REG_W(pstDev, 0x80068, 0x00000000);//dummy
  REG_W(pstDev, 0x80068, 0x00000000);//dummy
  REG_W(pstDev, 0x80068, 0x00000000);//dummy
  printf("Reg[0x%04X] : 0x%08X\n", 0x80074, REG_R(pstDev, 0x80074));
  REG_W(pstDev, 0x80070, 0x00000000);//选择0通道cs
  REG_W(pstDev, 0x80060, 0x00000086);//使能master,开始发数据
  REG_W(pstDev, 0x80070, 0x00000001);//选择0通道cs拉高
  REG_W(pstDev, 0x80060, 0x00000186);//禁止master spe
  printf("Reg[0x%04X] : 0x%08X\n", 0x80078, REG_R(pstDev, 0x80078));
  for(i=0;i<11;i++){
    printf("data = 0x%08X\n", REG_R(pstDev, 0x8006c));
  }
  printf("Reg[0x%04X] : 0x%08X\n", 0x80020, REG_R(pstDev, 0x80020));
  REG_W(pstDev, 0x80020, REG_R(pstDev, 0x80020));//clear

读flash 数据

        手册描述和上面读id一致,只不过cmd = 03。并不是每次读需要复位0x40和设置中断。读数据时默认03命令后面需要3byte的addr,如果需要4byte的地址,命令根据flash不同会是不同的cmd,但一定不会是03。先发送高位地址。要注意,读回来的数据是4 + dummy 个数据。也就是说只要写一个数据到DTR里,就会有一个数据接收到写入DRR。所以读回来的数据会是FF FF FF FF xx xx......(真正数据)。要注意DRR fifo只有256深度,不要读太多数据。

  REG_W(pstDev, 0x80040, 0xa);       //Software Reset Register
  REG_W(pstDev, 0x80028, 0x00003fff);//使能所有中断
  REG_W(pstDev, 0x8001c, 0x80000000);//打开全局中断使能
  REG_W(pstDev, 0x80060, 0x000001e6);//复位tx rx fifo,
  REG_W(pstDev, 0x80060, 0x00000186);//解复位fifo
  REG_W(pstDev, 0x80068, 0x00000003);//cmd = 03,读flash data
  //write addr
  REG_W(pstDev, 0x80068, (nOffset>>16)&0xff);
  REG_W(pstDev, 0x80068, (nOffset>>8)&0xff);
  REG_W(pstDev, 0x80068, (nOffset&0xff));
  for(i=0;i<nCount;i++){
     REG_W(pstDev, 0x80068, 0);//dummy
  }
  REG_W(pstDev, 0x80070, 0x00000000);//选择0通道cs
  REG_W(pstDev, 0x80060, 0x00000086);//使能master,开始发数据
  REG_W(pstDev, 0x80070, 0x00000001);//选择0通道cs拉高
  REG_W(pstDev, 0x80060, 0x00000186);//禁止master spe
  for(i=0;i<nCount+4;i++){
    printf("data = 0x%08X\n", REG_R(pstDev, 0x8006c));
  }
  printf("Reg[0x%04X] : 0x%08X\n", 0x80020, REG_R(pstDev, 0x80020));
  REG_W(pstDev, 0x80020, REG_R(pstDev, 0x80020));//clear

擦除扇区

        每个flash都有自己的扇区,页写参数,d8命令是擦除1个扇区,但扇区的大小是不一样大的。例如n25q128手册上描述:

AXI Quad SPI读写Flash做远程升级

         可以看到,总共有16777216个字节,256个扇区(每个扇区64KB)有65536页(每页256字节)。所以执行一次擦除命令会擦除64KB的数据,把数据都写成0xFF,写数据只能把bit写成0。要注意的是,每一个擦除命令和写数据命令前都要有一个写使能命令(06)。擦除命令后面跟地址,就会擦除地址所在的地址对齐64KB。

AXI Quad SPI读写Flash做远程升级

 测试代码为:

  REG_W(pstDev, 0x80040, 0xa);       //Software Reset Register
  REG_W(pstDev, 0x80060, 0x000001e6);//复位tx rx fifo,
  REG_W(pstDev, 0x80060, 0x00000186);//解复位fifo
  REG_W(pstDev, 0x80068, 0x00000006);//cmd = 06,写使能
  REG_W(pstDev, 0x80070, 0x00000000);//选择0通道cs
  REG_W(pstDev, 0x80060, 0x00000086);//使能master,开始发数据
  REG_W(pstDev, 0x80070, 0x00000001);//选择0通道cs拉高
  REG_W(pstDev, 0x80060, 0x00000186);//禁止master spe
  REG_W(pstDev, 0x80060, 0x000001e6);//复位tx rx fifo,
  REG_W(pstDev, 0x80060, 0x00000186);//解复位fifo
  REG_W(pstDev, 0x80068, 0x000000d8);//cmd = d8,擦除扇区。
  //write addr
  REG_W(pstDev, 0x80068, (nOffset>>16)&0xff);
  REG_W(pstDev, 0x80068, (nOffset>>8)&0xff);
  REG_W(pstDev, 0x80068, (nOffset&0xff));
  REG_W(pstDev, 0x80070, 0x00000000);//选择0通道cs
  REG_W(pstDev, 0x80060, 0x00000086);//使能master,开始发数据
  REG_W(pstDev, 0x80070, 0x00000001);//选择0通道cs拉高
  REG_W(pstDev, 0x80060, 0x00000186);//禁止master spe

写flash 数据

        和擦除扇区是类似的,写使能,写命令,写地址,写数据。

AXI Quad SPI读写Flash做远程升级

AXI Quad SPI读写Flash做远程升级

      要注意写FIFO也只有256字节深度,虽然页写是256字节。页写的意思,写命令后面最多跟这么多个数据,多余的数据就重复写入了。所以可以从0开始写128个,再从128写128个字节。

测试代码如下:

  REG_W(pstDev, 0x80040, 0xa);       //Software Reset Register
  REG_W(pstDev, 0x80060, 0x000001e6);//复位tx rx fifo,
  REG_W(pstDev, 0x80060, 0x00000186);//解复位fifo
  REG_W(pstDev, 0x80068, 0x00000006);//cmd = 06,写使能
  REG_W(pstDev, 0x80070, 0x00000000);//选择0通道cs
  REG_W(pstDev, 0x80060, 0x00000086);//使能master,开始发数据
  REG_W(pstDev, 0x80070, 0x00000001);//选择0通道cs拉高
  REG_W(pstDev, 0x80060, 0x00000186);//禁止master spe
  REG_W(pstDev, 0x80060, 0x000001e6);//复位tx rx fifo,
  REG_W(pstDev, 0x80060, 0x00000186);//解复位fifo
  REG_W(pstDev, 0x80068, 0x00000002);//cmd = 02 页写,256字节每页
  //write addr
  REG_W(pstDev, 0x80068, (nOffset>>16)&0xff);
  REG_W(pstDev, 0x80068, (nOffset>>8)&0xff);
  REG_W(pstDev, 0x80068, (nOffset&0xff));
  for(i=0;i<128;i++){
     REG_W(pstDev, 0x80068, i);//固定写入递增的数据
  }
  REG_W(pstDev, 0x80070, 0x00000000);//选择0通道cs
  REG_W(pstDev, 0x80060, 0x00000086);//使能master,开始发数据
  REG_W(pstDev, 0x80070, 0x00000001);//选择0通道cs拉高
  REG_W(pstDev, 0x80060, 0x00000186);//禁止master spe

 远程升级

        对于mcs,bin,bit,hex文件的区别,可以查看ug470 7 Series FPGAsConfiguration.      AXI Quad SPI读写Flash做远程升级

         简单说就是bit文件,bit没有反序(每个字节的bit反序),是二进制文件。bin文件没有bit反序,二进制文件。MCS bit反序了,是ASCII文件,带有地址和校验。对于我们升级来说,bin文件就可以了。FPGA升级时从0开始读数据从到同步头aa 99 55 66,就表示一个有效的配置文件开始了。如下所示。

ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
0000 00bb 1122 0044 ffff ffff ffff ffff
aa99 5566 2000 0000 3003 e001 0000 026b
3000 8001 0000 0012 2000 0000 3002 2001
0000 0000 3002 0001 0000 0000 3000 8001
0000 0000 2000 0000 3000 8001 0000 0007

        所以在线升级的简单设计就是拿到bin文件后,先根据bin文件大小擦除扇区,擦除每个扇区是是需要时间的,在手册里也有说明,擦除命令之间留出间隔即可,再从0开始直接写bin文件就可以了,写完后再读出校验。

        后续会研究如何做备份,普通升级写镜像时只写user image区域,当启动时发现user image启动失败,会自动跳转factory image,保证有出厂镜像里有在线升级的代码,防止一次升级失败导致必须返厂使用JTAG的问题。

注意事项

         如果使用JTAG to AXI Master,可以用JTAG去发送axi lite读写命令。

        使用方法:

                1.在bd中添加jtag to axi master ip,连接axi lite端口,配置address;

                2.编译工程,下载。

                3.先建立axi lite读写操作,再在vivado tcl console里执行,建立一次就可以了。

create_hw_axi_txn reset_qspi         [get_hw_axis hw_axi_1] -address 0x00000040 -data 0x0000000a -type write -force
create_hw_axi_txn rd_txn_lite_read_60 [get_hw_axis hw_axi_1] -address 00000060 -type read -force
run_hw_axi rd_txn_lite_read_74

        我的测试是把xdma的bypas接口接到了SPI IP,访问寄存器时,会发现读写数据都在变化,增加操作寄存器之间的延时,增加一定时间,例如10us即可。

        目前已验证A7上使用pcie xdma烧写bin文件到n25q128 flash,新bin能正常加载。驱动源码支持按文件大小擦除,逐页写入,支持读出校验。有需要可通过CSDN私信我,有偿提供技术支持,详解文章中未提及的部分编码细节。

        本文是本人原创,禁止任何形式的转载。文章来源地址https://www.toymoban.com/news/detail-434854.html

到了这里,关于AXI Quad SPI读写Flash做远程升级的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 实验(三):SPI应用:读写串行FLASH 实验

    实验目的: 1. 学习对SPI的使用; 2. 掌握KEIL5的仿真与调试。 任务: 1. 根据要求编写程序,并写出原理性注释; 2. 将检查程序运行的结果,分析一下是否正确; 3. 完成所建工程的验证调试。 以一种使用SPI 通讯的串行FLASH 存储芯片的读写实验为大家讲解STM32 的SPI 使用方法。

    2024年01月21日
    浏览(38)
  • 【STM32】SPI初步使用 读写FLASH W25Q64

    (1) SS( Slave Select):从设备选择信号线,常称为片选信号线,每个从设备都有独立的这一条 NSS 信号线,当主机要选择从设备时,把该从设备的 NSS 信号线设置为低电平,该从设备即被选中,即片选有效,接着主机开始与被选中的从设备进行 SPI通讯。所以 SPI通讯以 NSS 线置低电

    2024年02月10日
    浏览(57)
  • STM32单片机初学8-SPI flash(W25Q128)数据读写

            当使用单片机进行项目开发,涉及大量数据需要储存时(例如使用了屏幕作为显示设备,常常需要存储图片、动画等数据),单靠单片机内部的Flash往往是不够用的。         如STM32F103系列,内部Flash最多只能达到512KByte,假设要储存240*240分辨率、64K彩色图片,

    2024年02月03日
    浏览(47)
  • SPI FLASH扇区擦除

    目录 一、扇区擦除  Sector Erase  指令 (20h)          1、步骤                 a、扇区擦除前,必须解锁FLASH,也就是写使能       (06h)                 b、FLASH进行扇区擦除,看第一个图                         (20h)                 c、检查是否擦除 状

    2024年02月09日
    浏览(37)
  • FPGA使用SPI控制FLASH

    通过控制FLASH芯片进一步熟悉SPI协议 Flash 存储器 : Flash 存储器是一种非易失性存储器,它具有 RAM 和 ROM 的一些特点。与 ROM 类似,Flash 存储器的内容在断电时不会丢失,但与 RAM 类似,它可以通过编程来修改存储的内容。Flash 存储器通常用于嵌入式系统中存储程序代码、配置

    2024年03月19日
    浏览(55)
  • SPI 及 NOR Flash 介绍

    1.SPI的含义 SPI:串行外设设备接口(Serial Peripheral Interface),是一种高速的,全双工,同步的通信总线。SPI接口主要应用在存储芯片、AD转换器以及LCD中。SPI接口主要应用在存储芯片、AD转换器以及LCD中。 SPI 的引脚信息: MISO(Master In / Slave Out)主设备数据输入,从设备数据

    2024年02月12日
    浏览(37)
  • 【FLASH存储器系列五】SPI NOR FLASH芯片使用指导之一

    👉个人主页: highman110 👉作者简介:一名硬件工程师,持续学习,不断记录,保持思考,输出干货内容   目录 1芯片简介 2引脚定义 3功能框图 4器件操作 4.1操作框图 4.2标准SPI 4.3DaulSPI 4.4QaudSPI 4.5QPI 4.6DTR(W25Q128不支持) 4.73-字节/4-字节地址模式(W25Q128只支持3字节) 4.8保持

    2023年04月19日
    浏览(48)
  • SPI FLASH Fatfs文件系统移植

    FATFS是面向小型嵌入式系统的FAT文件系统。他由C语言编写并且独立与底层I/O介质。支持的内核有:8051,PLC,ARV,ARM等。FATFS支持FAT12,FAT16,FAT32等文件系统格式。 官网链接 diskio.c:包含底层存储介质的操作函数,需要与硬件设备适配移植。主要是在这个文件里调用用户实现的底层驱

    2024年02月08日
    浏览(37)
  • SPI FLASH(W25Q128BV) 包含SPI工作原理

    目录   一、SPI简介         1、全双工与半双工          2、同步与异步         3、SPI通信方式 二、SPI工作模式 三、W25Q128BV         1、读ID Read Manufacturer/Device ID(90h)                   2、读ID代码实现(硬件SPI)          3、IO口模拟SPI时序图实现 (软件SPI)  模式

    2024年02月14日
    浏览(42)
  • 09_SPI-Flash 页写实验

    使用页写指令,向 Flash 中写入 N 字节数据,N 为整数,且大于 0 小于等于 256。在本 实 验 中 我 们 向 Flash 芯 片 中 写 入 0-99 , 共 100 字 节 数 据 , 数 据 初 始 地 址 为24’h00_04_25。 注意:在向 Flash 芯片写入数据之前,先要对芯片执行全擦除操作。 写满不支持跨页写,在这

    2024年02月16日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包