当前位置: 代码迷 >> 综合 >> Altera FPGA——使用NIOS控制Serial Flash 第二部分
  详细解决方案

Altera FPGA——使用NIOS控制Serial Flash 第二部分

热度:1   发布时间:2024-01-20 08:53:31.0

这一部分将介绍如何通过NIOS及相应的IP来操作Flash,我所使用的软件版本为:Quartus Prime 18.0 Standard Edition。

1. NIOS II中控制Serial Flash的不同IP核。


这几个IP的功能的区别到现在还是比较迷,从介绍上来看相差不多。但是根据最新的文档,Intel推荐使用Generic Serial Flash Controller Intel FPGA IP进行设计,所以这个IP的User Guide即本文的参考文档,已上传至 https://download.csdn.net/download/setul/10845563。

2. Generic Serial Flash Controller Intel FPGA IP介绍

2.1 概述及支持的设备

该IP支持单、双、四IP口模式,可通过Avalon Memory Mapped (Avalon-MM)总线直接操作Serial Flash。其支持的设备如下:

2.2 使用该IP需要设置的参数

需要设置的参数如下:

2.3 Register Map

该IP总共提供了14个寄存器供设置。偏移地址为0-D。不在这里详细介绍每个寄存器,简单概述几个比较重要的。

  • Flash Command Setting Register (0x7)

    [7:0]:放置操作码的,操作码的值请参考上一篇 "Altera FPGA——使用NIOS控制Serial Flash 第一部分"中的描述,是通过查看Flash的数据手册得知的,但是注意,并不是所有操作的操作码都是通过这个寄存器设置的,读/写内存的操作例外,读内存的操作码在Read Instruction Register (0x5)寄存器中设置,写内存的操作码在Write Instruction Register (0x6)中设置,除此之外的所有操作的操作码均在此寄存器设置。
    [10:8]:地址用多少个字节表示。可以是3字节(3字节的地址线一共可以表示128Mbits的内存空间)或是4字节,如果该值被设置为0则表示这个操作不需要输入地址。
    [11]: 代表[15:12]位存放的数据类型。如果该位是0,则[15:12]中放置的是要写的字节数;若是0,表示要读出的字节数
    [15:12]:代表要读出或写入的字节数,跟[11]位配合使用。如果该位是0则表示没有要读写的数据。
    [20:16]:dummy cycle的数量,dummy cycle也叫latency cycles,比如有时候传完指令和真正的操作之间会有一定的延时,这个延时就是指dummy cycle。

  • Control Register (0x1)

    寄存器的内容易懂,不做解释。

  • 寄存器0x8-0xD

    跟Flash Command Setting Register (0x7)寄存器一样,Flash Command Control Register (0x8)也是出了读/写内存操作之外必须使用的,将其最低位置1,将使Flash开始执行相应的操作。

3. NIOS II对Flash的一些操作命令

下面讲介绍如果通过NIOS II借助上面的寄存器对Flash进行的一些操作。

3.1 写使能(Write Enable Operation)
void write_enable(){IOWR(INTEL_GENERIC_SERIAL_FLASH_INTERFACE_TOP_0_AVL_CSR_BASE,0x7,0x00000006);IOWR(INTEL_GENERIC_SERIAL_FLASH_INTERFACE_TOP_0_AVL_CSR_BASE,0x8,0x1);
}

上述函数的主要操作就是:

  • 设置Flash Command Setting Register的[7:0]为0x6,因为写使能的操作码是0x6。
  • 设置Flash Command Control Register的最低位为1,开始该操作。
3.2 读设备ID(Read Device ID Operation)
int read_device_id(){IOWR(INTEL_GENERIC_SERIAL_FLASH_INTERFACE_TOP_0_AVL_CSR_BASE,0x7,0x0000489F);IOWR(INTEL_GENERIC_SERIAL_FLASH_INTERFACE_TOP_0_AVL_CSR_BASE,0x8,0x1);return IORD(INTEL_GENERIC_SERIAL_FLASH_INTERFACE_TOP_0_AVL_CSR_BASE,0xc);
}

其主要执行的操作为:

  • 设置Flash Command Setting Register的[7:0]为9F,因为该操作的操作码是9F.
  • 设置[10:8]为0,因为该操作不带任何地址数据。
  • 设置[11]为1,表示[15:12]中代表的是读出的数据字节数。
  • 设置[15:12]为4,表示要读出4个字节的设备ID。
  • 设置Flash Command Control Register的最低位为1,开始该操作。
  • 从Flash Command Read Data 0 Register中读出Device ID。
3.3 写状态寄存器实现扇区保护(Write Status Register Operation to Protect Sector of Flash)

下面这个函数是用于Cypress的Flash。对EPCS和Micron都是不同的。所以在这里不得不先说一下Cypress的相关寄存器及操作时序。

在这里插入图片描述

void write_register_for_sector_protect_cypress(){IOWR(INTEL_GENERIC_SERIAL_FLASH_INTERFACE_TOP_0_AVL_CSR_BASE,0x7,0x00002001);IOWR(INTEL_GENERIC_SERIAL_FLASH_INTERFACE_TOP_0_AVL_CSR_BASE,0xA,0x0000201c);IOWR(INTEL_GENERIC_SERIAL_FLASH_INTERFACE_TOP_0_AVL_CSR_BASE,0x8,0x1);
}
  相关解决方案